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)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
24 #include "qemu/osdep.h"
27 #include "tcg/tcg-op.h"
28 #include "exec/cpu_ldst.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 #include "hw/semihosting/semihost.h"
33 #include "target/mips/trace.h"
34 #include "trace-tcg.h"
35 #include "exec/translator.h"
37 #include "qemu/qemu-print.h"
38 #include "fpu_helper.h"
39 #include "translate.h"
42 /* indirect opcode tables */
43 OPC_SPECIAL
= (0x00 << 26),
44 OPC_REGIMM
= (0x01 << 26),
45 OPC_CP0
= (0x10 << 26),
46 OPC_CP1
= (0x11 << 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 /* MSA ASE, same as MDMX */
141 /* Cache and prefetch */
142 OPC_CACHE
= (0x2F << 26),
143 OPC_PREF
= (0x33 << 26),
144 /* PC-relative address computation / loads */
145 OPC_PCREL
= (0x3B << 26),
148 /* PC-relative address computation / loads */
149 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
150 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
152 /* Instructions determined by bits 19 and 20 */
153 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
154 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
155 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
157 /* Instructions determined by bits 16 ... 20 */
158 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
159 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
162 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
165 /* MIPS special opcodes */
166 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
170 OPC_SLL
= 0x00 | OPC_SPECIAL
,
171 /* NOP is SLL r0, r0, 0 */
172 /* SSNOP is SLL r0, r0, 1 */
173 /* EHB is SLL r0, r0, 3 */
174 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
175 OPC_ROTR
= OPC_SRL
| (1 << 21),
176 OPC_SRA
= 0x03 | OPC_SPECIAL
,
177 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
178 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
179 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
180 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
181 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
182 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
183 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
184 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
185 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
186 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
187 OPC_DROTR
= OPC_DSRL
| (1 << 21),
188 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
189 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
190 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
191 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
192 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
193 /* Multiplication / division */
194 OPC_MULT
= 0x18 | OPC_SPECIAL
,
195 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
196 OPC_DIV
= 0x1A | OPC_SPECIAL
,
197 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
198 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
199 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
200 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
201 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
203 /* 2 registers arithmetic / logic */
204 OPC_ADD
= 0x20 | OPC_SPECIAL
,
205 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
206 OPC_SUB
= 0x22 | OPC_SPECIAL
,
207 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
208 OPC_AND
= 0x24 | OPC_SPECIAL
,
209 OPC_OR
= 0x25 | OPC_SPECIAL
,
210 OPC_XOR
= 0x26 | OPC_SPECIAL
,
211 OPC_NOR
= 0x27 | OPC_SPECIAL
,
212 OPC_SLT
= 0x2A | OPC_SPECIAL
,
213 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
214 OPC_DADD
= 0x2C | OPC_SPECIAL
,
215 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
216 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
217 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
219 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
220 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
222 OPC_TGE
= 0x30 | OPC_SPECIAL
,
223 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
224 OPC_TLT
= 0x32 | OPC_SPECIAL
,
225 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
226 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
227 OPC_TNE
= 0x36 | OPC_SPECIAL
,
228 /* HI / LO registers load & stores */
229 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
230 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
231 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
232 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
233 /* Conditional moves */
234 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
235 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
237 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
238 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
240 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
243 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
244 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
245 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
246 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
247 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
249 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
250 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
251 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
252 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
256 * R6 Multiply and Divide instructions have the same opcode
257 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
259 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
262 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
263 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
264 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
265 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
266 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
267 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
268 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
269 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
271 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
272 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
273 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
274 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
275 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
276 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
277 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
278 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
280 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
281 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
282 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
283 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
284 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
286 OPC_LSA
= 0x05 | OPC_SPECIAL
,
287 OPC_DLSA
= 0x15 | OPC_SPECIAL
,
290 /* Multiplication variants of the vr54xx. */
291 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
294 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
295 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
296 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
297 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
298 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
299 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
300 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
301 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
302 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
303 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
304 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
305 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
306 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
307 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
310 /* REGIMM (rt field) opcodes */
311 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
314 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
315 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
316 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
317 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
318 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
319 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
320 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
321 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
322 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
323 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
324 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
325 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
326 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
327 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
328 OPC_SIGRIE
= (0x17 << 16) | OPC_REGIMM
,
329 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
331 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
332 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
335 /* Special2 opcodes */
336 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
339 /* Multiply & xxx operations */
340 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
341 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
342 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
343 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
344 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
346 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
347 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
348 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
349 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
350 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
351 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
352 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
353 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
354 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
355 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
356 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
357 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
359 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
360 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
361 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
362 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
364 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
367 /* Special3 opcodes */
368 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
371 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
372 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
373 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
374 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
375 OPC_INS
= 0x04 | OPC_SPECIAL3
,
376 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
377 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
378 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
379 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
380 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
381 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
382 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
383 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
384 OPC_GINV
= 0x3D | OPC_SPECIAL3
,
387 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
388 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
389 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
390 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
391 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
392 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
393 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
394 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
395 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
396 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
397 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
398 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
401 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
402 /* MIPS DSP Arithmetic */
403 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
404 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
405 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
406 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
407 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
408 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
409 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
410 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
411 /* MIPS DSP GPR-Based Shift Sub-class */
412 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
413 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
414 /* MIPS DSP Multiply Sub-class insns */
415 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
416 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
417 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
418 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
419 /* DSP Bit/Manipulation Sub-class */
420 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
421 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
422 /* MIPS DSP Append Sub-class */
423 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
424 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
425 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
426 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
427 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
430 OPC_LWLE
= 0x19 | OPC_SPECIAL3
,
431 OPC_LWRE
= 0x1A | OPC_SPECIAL3
,
432 OPC_CACHEE
= 0x1B | OPC_SPECIAL3
,
433 OPC_SBE
= 0x1C | OPC_SPECIAL3
,
434 OPC_SHE
= 0x1D | OPC_SPECIAL3
,
435 OPC_SCE
= 0x1E | OPC_SPECIAL3
,
436 OPC_SWE
= 0x1F | OPC_SPECIAL3
,
437 OPC_SWLE
= 0x21 | OPC_SPECIAL3
,
438 OPC_SWRE
= 0x22 | OPC_SPECIAL3
,
439 OPC_PREFE
= 0x23 | OPC_SPECIAL3
,
440 OPC_LBUE
= 0x28 | OPC_SPECIAL3
,
441 OPC_LHUE
= 0x29 | OPC_SPECIAL3
,
442 OPC_LBE
= 0x2C | OPC_SPECIAL3
,
443 OPC_LHE
= 0x2D | OPC_SPECIAL3
,
444 OPC_LLE
= 0x2E | OPC_SPECIAL3
,
445 OPC_LWE
= 0x2F | OPC_SPECIAL3
,
448 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
449 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
450 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
451 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
452 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
453 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
456 /* Loongson EXT load/store quad word opcodes */
457 #define MASK_LOONGSON_GSLSQ(op) (MASK_OP_MAJOR(op) | (op & 0x8020))
459 OPC_GSLQ
= 0x0020 | OPC_LWC2
,
460 OPC_GSLQC1
= 0x8020 | OPC_LWC2
,
461 OPC_GSSHFL
= OPC_LWC2
,
462 OPC_GSSQ
= 0x0020 | OPC_SWC2
,
463 OPC_GSSQC1
= 0x8020 | OPC_SWC2
,
464 OPC_GSSHFS
= OPC_SWC2
,
467 /* Loongson EXT shifted load/store opcodes */
468 #define MASK_LOONGSON_GSSHFLS(op) (MASK_OP_MAJOR(op) | (op & 0xc03f))
470 OPC_GSLWLC1
= 0x4 | OPC_GSSHFL
,
471 OPC_GSLWRC1
= 0x5 | OPC_GSSHFL
,
472 OPC_GSLDLC1
= 0x6 | OPC_GSSHFL
,
473 OPC_GSLDRC1
= 0x7 | OPC_GSSHFL
,
474 OPC_GSSWLC1
= 0x4 | OPC_GSSHFS
,
475 OPC_GSSWRC1
= 0x5 | OPC_GSSHFS
,
476 OPC_GSSDLC1
= 0x6 | OPC_GSSHFS
,
477 OPC_GSSDRC1
= 0x7 | OPC_GSSHFS
,
480 /* Loongson EXT LDC2/SDC2 opcodes */
481 #define MASK_LOONGSON_LSDC2(op) (MASK_OP_MAJOR(op) | (op & 0x7))
484 OPC_GSLBX
= 0x0 | OPC_LDC2
,
485 OPC_GSLHX
= 0x1 | OPC_LDC2
,
486 OPC_GSLWX
= 0x2 | OPC_LDC2
,
487 OPC_GSLDX
= 0x3 | OPC_LDC2
,
488 OPC_GSLWXC1
= 0x6 | OPC_LDC2
,
489 OPC_GSLDXC1
= 0x7 | OPC_LDC2
,
490 OPC_GSSBX
= 0x0 | OPC_SDC2
,
491 OPC_GSSHX
= 0x1 | OPC_SDC2
,
492 OPC_GSSWX
= 0x2 | OPC_SDC2
,
493 OPC_GSSDX
= 0x3 | OPC_SDC2
,
494 OPC_GSSWXC1
= 0x6 | OPC_SDC2
,
495 OPC_GSSDXC1
= 0x7 | OPC_SDC2
,
499 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
502 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
503 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
504 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
505 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp (010.00 to 010.11) */
506 OPC_ALIGN_1
= (0x09 << 6) | OPC_BSHFL
,
507 OPC_ALIGN_2
= (0x0A << 6) | OPC_BSHFL
,
508 OPC_ALIGN_3
= (0x0B << 6) | OPC_BSHFL
,
509 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
513 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
516 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
517 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
518 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp (01.000 to 01.111) */
519 OPC_DALIGN_1
= (0x09 << 6) | OPC_DBSHFL
,
520 OPC_DALIGN_2
= (0x0A << 6) | OPC_DBSHFL
,
521 OPC_DALIGN_3
= (0x0B << 6) | OPC_DBSHFL
,
522 OPC_DALIGN_4
= (0x0C << 6) | OPC_DBSHFL
,
523 OPC_DALIGN_5
= (0x0D << 6) | OPC_DBSHFL
,
524 OPC_DALIGN_6
= (0x0E << 6) | OPC_DBSHFL
,
525 OPC_DALIGN_7
= (0x0F << 6) | OPC_DBSHFL
,
526 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
529 /* MIPS DSP REGIMM opcodes */
531 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
532 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
535 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
538 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
539 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
540 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
541 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
544 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Arithmetic Sub-class */
547 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
548 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
549 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
550 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
551 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
552 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
553 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
554 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
555 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
556 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
557 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
558 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
559 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
560 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
561 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
562 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
563 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
564 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
565 /* MIPS DSP Multiply Sub-class insns */
566 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
567 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
568 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
569 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
570 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
571 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
574 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
575 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
577 /* MIPS DSP Arithmetic Sub-class */
578 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
579 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
580 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
581 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
582 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
583 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
584 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
585 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
586 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
587 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
588 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
589 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
590 /* MIPS DSP Multiply Sub-class insns */
591 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
592 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
593 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
594 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
597 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
599 /* MIPS DSP Arithmetic Sub-class */
600 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
601 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
602 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
603 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
604 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
605 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
606 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
607 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
608 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
609 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
610 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
611 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
612 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
613 /* DSP Bit/Manipulation Sub-class */
614 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
615 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
616 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
617 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
618 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
621 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
623 /* MIPS DSP Arithmetic Sub-class */
624 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
625 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
626 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
627 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
628 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
629 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
630 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
631 /* DSP Compare-Pick Sub-class */
632 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
633 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
634 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
635 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
636 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
637 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
638 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
639 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
640 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
641 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
642 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
643 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
644 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
645 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
646 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
649 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
651 /* MIPS DSP GPR-Based Shift Sub-class */
652 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
653 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
654 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
655 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
656 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
657 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
658 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
659 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
660 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
661 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
662 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
663 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
664 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
665 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
666 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
667 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
668 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
669 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
670 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
671 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
672 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
673 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
676 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678 /* MIPS DSP Multiply Sub-class insns */
679 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
680 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
681 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
682 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
683 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
684 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
685 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
686 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
687 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
688 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
689 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
690 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
691 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
692 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
693 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
694 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
695 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
696 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
697 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
698 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
699 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
700 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
703 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
709 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Append Sub-class */
712 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
713 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
714 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
717 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
719 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
720 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
721 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
722 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
723 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
724 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
725 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
726 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
727 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
728 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
729 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
730 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
731 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
732 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
733 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
734 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
735 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
736 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
739 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741 /* MIPS DSP Arithmetic Sub-class */
742 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
743 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
744 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
745 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
746 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
747 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
748 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
749 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
750 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
751 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
752 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
753 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
754 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
755 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
756 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
757 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
758 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
759 /* DSP Bit/Manipulation Sub-class */
760 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
761 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
762 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
763 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
764 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
765 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
768 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
770 /* MIPS DSP Multiply Sub-class insns */
771 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
772 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
773 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
774 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
775 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
776 /* MIPS DSP Arithmetic Sub-class */
777 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
778 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
779 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
780 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
781 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
782 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
783 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
784 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
785 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
786 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
787 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
788 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
789 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
790 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
791 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
792 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
793 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
794 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
795 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
796 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
797 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
800 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
802 /* DSP Compare-Pick Sub-class */
803 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
804 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
805 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
806 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
807 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
808 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
809 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
810 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
811 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
812 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
813 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
814 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
815 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
816 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
817 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
818 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
819 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
820 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
821 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
822 /* MIPS DSP Arithmetic Sub-class */
823 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
824 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
825 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
826 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
827 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
828 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
829 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
830 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
833 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
835 /* DSP Append Sub-class */
836 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
837 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
838 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
839 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
842 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
844 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
845 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
846 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
847 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
848 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
849 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
850 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
851 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
852 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
853 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
854 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
855 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
856 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
857 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
858 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
859 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
860 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
861 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
862 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
863 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
864 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
865 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
868 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
870 /* DSP Bit/Manipulation Sub-class */
871 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
874 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
876 /* MIPS DSP Multiply Sub-class insns */
877 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
878 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
879 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
880 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
881 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
882 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
883 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
884 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
885 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
886 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
887 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
888 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
889 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
890 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
891 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
892 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
893 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
894 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
895 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
896 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
897 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
898 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
899 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
900 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
901 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
902 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
905 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
907 /* MIPS DSP GPR-Based Shift Sub-class */
908 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
909 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
910 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
911 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
912 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
913 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
914 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
915 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
916 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
917 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
918 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
919 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
920 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
921 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
922 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
923 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
924 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
925 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
926 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
927 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
928 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
929 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
930 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
931 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
932 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
933 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
936 /* Coprocessor 0 (rs field) */
937 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
940 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
941 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
942 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
943 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
944 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
945 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
946 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
947 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
948 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
949 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
950 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
951 OPC_C0
= (0x10 << 21) | OPC_CP0
,
952 OPC_C0_1
= (0x11 << 21) | OPC_CP0
,
953 OPC_C0_2
= (0x12 << 21) | OPC_CP0
,
954 OPC_C0_3
= (0x13 << 21) | OPC_CP0
,
955 OPC_C0_4
= (0x14 << 21) | OPC_CP0
,
956 OPC_C0_5
= (0x15 << 21) | OPC_CP0
,
957 OPC_C0_6
= (0x16 << 21) | OPC_CP0
,
958 OPC_C0_7
= (0x17 << 21) | OPC_CP0
,
959 OPC_C0_8
= (0x18 << 21) | OPC_CP0
,
960 OPC_C0_9
= (0x19 << 21) | OPC_CP0
,
961 OPC_C0_A
= (0x1A << 21) | OPC_CP0
,
962 OPC_C0_B
= (0x1B << 21) | OPC_CP0
,
963 OPC_C0_C
= (0x1C << 21) | OPC_CP0
,
964 OPC_C0_D
= (0x1D << 21) | OPC_CP0
,
965 OPC_C0_E
= (0x1E << 21) | OPC_CP0
,
966 OPC_C0_F
= (0x1F << 21) | OPC_CP0
,
970 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
973 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
974 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
975 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
976 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
977 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
978 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
979 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
980 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
983 /* Coprocessor 0 (with rs == C0) */
984 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
987 OPC_TLBR
= 0x01 | OPC_C0
,
988 OPC_TLBWI
= 0x02 | OPC_C0
,
989 OPC_TLBINV
= 0x03 | OPC_C0
,
990 OPC_TLBINVF
= 0x04 | OPC_C0
,
991 OPC_TLBWR
= 0x06 | OPC_C0
,
992 OPC_TLBP
= 0x08 | OPC_C0
,
993 OPC_RFE
= 0x10 | OPC_C0
,
994 OPC_ERET
= 0x18 | OPC_C0
,
995 OPC_DERET
= 0x1F | OPC_C0
,
996 OPC_WAIT
= 0x20 | OPC_C0
,
999 /* Coprocessor 1 (rs field) */
1000 #define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1002 /* Values for the fmt field in FP instructions */
1004 /* 0 - 15 are reserved */
1005 FMT_S
= 16, /* single fp */
1006 FMT_D
= 17, /* double fp */
1007 FMT_E
= 18, /* extended fp */
1008 FMT_Q
= 19, /* quad fp */
1009 FMT_W
= 20, /* 32-bit fixed */
1010 FMT_L
= 21, /* 64-bit fixed */
1011 FMT_PS
= 22, /* paired single fp */
1012 /* 23 - 31 are reserved */
1016 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
1017 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
1018 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
1019 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
1020 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
1021 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
1022 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
1023 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
1024 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
1025 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
1026 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
1027 OPC_BZ_V
= (0x0B << 21) | OPC_CP1
,
1028 OPC_BNZ_V
= (0x0F << 21) | OPC_CP1
,
1029 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
1030 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
1031 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
1032 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
1033 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
1034 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
1035 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
1036 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
1037 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
1038 OPC_BZ_B
= (0x18 << 21) | OPC_CP1
,
1039 OPC_BZ_H
= (0x19 << 21) | OPC_CP1
,
1040 OPC_BZ_W
= (0x1A << 21) | OPC_CP1
,
1041 OPC_BZ_D
= (0x1B << 21) | OPC_CP1
,
1042 OPC_BNZ_B
= (0x1C << 21) | OPC_CP1
,
1043 OPC_BNZ_H
= (0x1D << 21) | OPC_CP1
,
1044 OPC_BNZ_W
= (0x1E << 21) | OPC_CP1
,
1045 OPC_BNZ_D
= (0x1F << 21) | OPC_CP1
,
1048 #define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F))
1049 #define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16)))
1052 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
1053 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
1054 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
1055 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
1059 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
1060 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
1064 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
1065 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
1068 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1071 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
1072 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
1073 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
1074 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
1075 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
1076 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
1077 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
1078 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
1079 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
1080 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1081 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1084 #define MASK_LMMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1087 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1088 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1089 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1090 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1091 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1092 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1093 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1094 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1096 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1097 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1098 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1099 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1100 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1101 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1102 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1103 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1105 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1106 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1107 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1108 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1109 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1110 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1111 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1112 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1114 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1115 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1116 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1117 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1118 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1119 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1120 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1121 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1123 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1124 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1125 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1126 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1127 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1128 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1130 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1131 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1132 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1133 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1134 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1135 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1137 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1138 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1139 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1140 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1141 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1142 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1144 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1145 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1146 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1147 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1148 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1149 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1151 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1152 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1153 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1154 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1155 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1156 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1158 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1159 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1160 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1161 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1162 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1163 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1165 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1166 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1167 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1168 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1169 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1170 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1172 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1173 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1174 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1175 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1176 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1177 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1181 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1184 OPC_LWXC1
= 0x00 | OPC_CP3
,
1185 OPC_LDXC1
= 0x01 | OPC_CP3
,
1186 OPC_LUXC1
= 0x05 | OPC_CP3
,
1187 OPC_SWXC1
= 0x08 | OPC_CP3
,
1188 OPC_SDXC1
= 0x09 | OPC_CP3
,
1189 OPC_SUXC1
= 0x0D | OPC_CP3
,
1190 OPC_PREFX
= 0x0F | OPC_CP3
,
1191 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1192 OPC_MADD_S
= 0x20 | OPC_CP3
,
1193 OPC_MADD_D
= 0x21 | OPC_CP3
,
1194 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1195 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1196 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1197 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1198 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1199 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1200 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1201 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1202 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1203 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1207 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1209 OPC_MSA_I8_00
= 0x00 | OPC_MSA
,
1210 OPC_MSA_I8_01
= 0x01 | OPC_MSA
,
1211 OPC_MSA_I8_02
= 0x02 | OPC_MSA
,
1212 OPC_MSA_I5_06
= 0x06 | OPC_MSA
,
1213 OPC_MSA_I5_07
= 0x07 | OPC_MSA
,
1214 OPC_MSA_BIT_09
= 0x09 | OPC_MSA
,
1215 OPC_MSA_BIT_0A
= 0x0A | OPC_MSA
,
1216 OPC_MSA_3R_0D
= 0x0D | OPC_MSA
,
1217 OPC_MSA_3R_0E
= 0x0E | OPC_MSA
,
1218 OPC_MSA_3R_0F
= 0x0F | OPC_MSA
,
1219 OPC_MSA_3R_10
= 0x10 | OPC_MSA
,
1220 OPC_MSA_3R_11
= 0x11 | OPC_MSA
,
1221 OPC_MSA_3R_12
= 0x12 | OPC_MSA
,
1222 OPC_MSA_3R_13
= 0x13 | OPC_MSA
,
1223 OPC_MSA_3R_14
= 0x14 | OPC_MSA
,
1224 OPC_MSA_3R_15
= 0x15 | OPC_MSA
,
1225 OPC_MSA_ELM
= 0x19 | OPC_MSA
,
1226 OPC_MSA_3RF_1A
= 0x1A | OPC_MSA
,
1227 OPC_MSA_3RF_1B
= 0x1B | OPC_MSA
,
1228 OPC_MSA_3RF_1C
= 0x1C | OPC_MSA
,
1229 OPC_MSA_VEC
= 0x1E | OPC_MSA
,
1231 /* MI10 instruction */
1232 OPC_LD_B
= (0x20) | OPC_MSA
,
1233 OPC_LD_H
= (0x21) | OPC_MSA
,
1234 OPC_LD_W
= (0x22) | OPC_MSA
,
1235 OPC_LD_D
= (0x23) | OPC_MSA
,
1236 OPC_ST_B
= (0x24) | OPC_MSA
,
1237 OPC_ST_H
= (0x25) | OPC_MSA
,
1238 OPC_ST_W
= (0x26) | OPC_MSA
,
1239 OPC_ST_D
= (0x27) | OPC_MSA
,
1243 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1244 OPC_ADDVI_df
= (0x0 << 23) | OPC_MSA_I5_06
,
1245 OPC_CEQI_df
= (0x0 << 23) | OPC_MSA_I5_07
,
1246 OPC_SUBVI_df
= (0x1 << 23) | OPC_MSA_I5_06
,
1247 OPC_MAXI_S_df
= (0x2 << 23) | OPC_MSA_I5_06
,
1248 OPC_CLTI_S_df
= (0x2 << 23) | OPC_MSA_I5_07
,
1249 OPC_MAXI_U_df
= (0x3 << 23) | OPC_MSA_I5_06
,
1250 OPC_CLTI_U_df
= (0x3 << 23) | OPC_MSA_I5_07
,
1251 OPC_MINI_S_df
= (0x4 << 23) | OPC_MSA_I5_06
,
1252 OPC_CLEI_S_df
= (0x4 << 23) | OPC_MSA_I5_07
,
1253 OPC_MINI_U_df
= (0x5 << 23) | OPC_MSA_I5_06
,
1254 OPC_CLEI_U_df
= (0x5 << 23) | OPC_MSA_I5_07
,
1255 OPC_LDI_df
= (0x6 << 23) | OPC_MSA_I5_07
,
1257 /* I8 instruction */
1258 OPC_ANDI_B
= (0x0 << 24) | OPC_MSA_I8_00
,
1259 OPC_BMNZI_B
= (0x0 << 24) | OPC_MSA_I8_01
,
1260 OPC_SHF_B
= (0x0 << 24) | OPC_MSA_I8_02
,
1261 OPC_ORI_B
= (0x1 << 24) | OPC_MSA_I8_00
,
1262 OPC_BMZI_B
= (0x1 << 24) | OPC_MSA_I8_01
,
1263 OPC_SHF_H
= (0x1 << 24) | OPC_MSA_I8_02
,
1264 OPC_NORI_B
= (0x2 << 24) | OPC_MSA_I8_00
,
1265 OPC_BSELI_B
= (0x2 << 24) | OPC_MSA_I8_01
,
1266 OPC_SHF_W
= (0x2 << 24) | OPC_MSA_I8_02
,
1267 OPC_XORI_B
= (0x3 << 24) | OPC_MSA_I8_00
,
1269 /* VEC/2R/2RF instruction */
1270 OPC_AND_V
= (0x00 << 21) | OPC_MSA_VEC
,
1271 OPC_OR_V
= (0x01 << 21) | OPC_MSA_VEC
,
1272 OPC_NOR_V
= (0x02 << 21) | OPC_MSA_VEC
,
1273 OPC_XOR_V
= (0x03 << 21) | OPC_MSA_VEC
,
1274 OPC_BMNZ_V
= (0x04 << 21) | OPC_MSA_VEC
,
1275 OPC_BMZ_V
= (0x05 << 21) | OPC_MSA_VEC
,
1276 OPC_BSEL_V
= (0x06 << 21) | OPC_MSA_VEC
,
1278 OPC_MSA_2R
= (0x18 << 21) | OPC_MSA_VEC
,
1279 OPC_MSA_2RF
= (0x19 << 21) | OPC_MSA_VEC
,
1281 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1282 OPC_FILL_df
= (0x00 << 18) | OPC_MSA_2R
,
1283 OPC_PCNT_df
= (0x01 << 18) | OPC_MSA_2R
,
1284 OPC_NLOC_df
= (0x02 << 18) | OPC_MSA_2R
,
1285 OPC_NLZC_df
= (0x03 << 18) | OPC_MSA_2R
,
1287 /* 2RF instruction df(bit 16) = _w, _d */
1288 OPC_FCLASS_df
= (0x00 << 17) | OPC_MSA_2RF
,
1289 OPC_FTRUNC_S_df
= (0x01 << 17) | OPC_MSA_2RF
,
1290 OPC_FTRUNC_U_df
= (0x02 << 17) | OPC_MSA_2RF
,
1291 OPC_FSQRT_df
= (0x03 << 17) | OPC_MSA_2RF
,
1292 OPC_FRSQRT_df
= (0x04 << 17) | OPC_MSA_2RF
,
1293 OPC_FRCP_df
= (0x05 << 17) | OPC_MSA_2RF
,
1294 OPC_FRINT_df
= (0x06 << 17) | OPC_MSA_2RF
,
1295 OPC_FLOG2_df
= (0x07 << 17) | OPC_MSA_2RF
,
1296 OPC_FEXUPL_df
= (0x08 << 17) | OPC_MSA_2RF
,
1297 OPC_FEXUPR_df
= (0x09 << 17) | OPC_MSA_2RF
,
1298 OPC_FFQL_df
= (0x0A << 17) | OPC_MSA_2RF
,
1299 OPC_FFQR_df
= (0x0B << 17) | OPC_MSA_2RF
,
1300 OPC_FTINT_S_df
= (0x0C << 17) | OPC_MSA_2RF
,
1301 OPC_FTINT_U_df
= (0x0D << 17) | OPC_MSA_2RF
,
1302 OPC_FFINT_S_df
= (0x0E << 17) | OPC_MSA_2RF
,
1303 OPC_FFINT_U_df
= (0x0F << 17) | OPC_MSA_2RF
,
1305 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1306 OPC_SLL_df
= (0x0 << 23) | OPC_MSA_3R_0D
,
1307 OPC_ADDV_df
= (0x0 << 23) | OPC_MSA_3R_0E
,
1308 OPC_CEQ_df
= (0x0 << 23) | OPC_MSA_3R_0F
,
1309 OPC_ADD_A_df
= (0x0 << 23) | OPC_MSA_3R_10
,
1310 OPC_SUBS_S_df
= (0x0 << 23) | OPC_MSA_3R_11
,
1311 OPC_MULV_df
= (0x0 << 23) | OPC_MSA_3R_12
,
1312 OPC_DOTP_S_df
= (0x0 << 23) | OPC_MSA_3R_13
,
1313 OPC_SLD_df
= (0x0 << 23) | OPC_MSA_3R_14
,
1314 OPC_VSHF_df
= (0x0 << 23) | OPC_MSA_3R_15
,
1315 OPC_SRA_df
= (0x1 << 23) | OPC_MSA_3R_0D
,
1316 OPC_SUBV_df
= (0x1 << 23) | OPC_MSA_3R_0E
,
1317 OPC_ADDS_A_df
= (0x1 << 23) | OPC_MSA_3R_10
,
1318 OPC_SUBS_U_df
= (0x1 << 23) | OPC_MSA_3R_11
,
1319 OPC_MADDV_df
= (0x1 << 23) | OPC_MSA_3R_12
,
1320 OPC_DOTP_U_df
= (0x1 << 23) | OPC_MSA_3R_13
,
1321 OPC_SPLAT_df
= (0x1 << 23) | OPC_MSA_3R_14
,
1322 OPC_SRAR_df
= (0x1 << 23) | OPC_MSA_3R_15
,
1323 OPC_SRL_df
= (0x2 << 23) | OPC_MSA_3R_0D
,
1324 OPC_MAX_S_df
= (0x2 << 23) | OPC_MSA_3R_0E
,
1325 OPC_CLT_S_df
= (0x2 << 23) | OPC_MSA_3R_0F
,
1326 OPC_ADDS_S_df
= (0x2 << 23) | OPC_MSA_3R_10
,
1327 OPC_SUBSUS_U_df
= (0x2 << 23) | OPC_MSA_3R_11
,
1328 OPC_MSUBV_df
= (0x2 << 23) | OPC_MSA_3R_12
,
1329 OPC_DPADD_S_df
= (0x2 << 23) | OPC_MSA_3R_13
,
1330 OPC_PCKEV_df
= (0x2 << 23) | OPC_MSA_3R_14
,
1331 OPC_SRLR_df
= (0x2 << 23) | OPC_MSA_3R_15
,
1332 OPC_BCLR_df
= (0x3 << 23) | OPC_MSA_3R_0D
,
1333 OPC_MAX_U_df
= (0x3 << 23) | OPC_MSA_3R_0E
,
1334 OPC_CLT_U_df
= (0x3 << 23) | OPC_MSA_3R_0F
,
1335 OPC_ADDS_U_df
= (0x3 << 23) | OPC_MSA_3R_10
,
1336 OPC_SUBSUU_S_df
= (0x3 << 23) | OPC_MSA_3R_11
,
1337 OPC_DPADD_U_df
= (0x3 << 23) | OPC_MSA_3R_13
,
1338 OPC_PCKOD_df
= (0x3 << 23) | OPC_MSA_3R_14
,
1339 OPC_BSET_df
= (0x4 << 23) | OPC_MSA_3R_0D
,
1340 OPC_MIN_S_df
= (0x4 << 23) | OPC_MSA_3R_0E
,
1341 OPC_CLE_S_df
= (0x4 << 23) | OPC_MSA_3R_0F
,
1342 OPC_AVE_S_df
= (0x4 << 23) | OPC_MSA_3R_10
,
1343 OPC_ASUB_S_df
= (0x4 << 23) | OPC_MSA_3R_11
,
1344 OPC_DIV_S_df
= (0x4 << 23) | OPC_MSA_3R_12
,
1345 OPC_DPSUB_S_df
= (0x4 << 23) | OPC_MSA_3R_13
,
1346 OPC_ILVL_df
= (0x4 << 23) | OPC_MSA_3R_14
,
1347 OPC_HADD_S_df
= (0x4 << 23) | OPC_MSA_3R_15
,
1348 OPC_BNEG_df
= (0x5 << 23) | OPC_MSA_3R_0D
,
1349 OPC_MIN_U_df
= (0x5 << 23) | OPC_MSA_3R_0E
,
1350 OPC_CLE_U_df
= (0x5 << 23) | OPC_MSA_3R_0F
,
1351 OPC_AVE_U_df
= (0x5 << 23) | OPC_MSA_3R_10
,
1352 OPC_ASUB_U_df
= (0x5 << 23) | OPC_MSA_3R_11
,
1353 OPC_DIV_U_df
= (0x5 << 23) | OPC_MSA_3R_12
,
1354 OPC_DPSUB_U_df
= (0x5 << 23) | OPC_MSA_3R_13
,
1355 OPC_ILVR_df
= (0x5 << 23) | OPC_MSA_3R_14
,
1356 OPC_HADD_U_df
= (0x5 << 23) | OPC_MSA_3R_15
,
1357 OPC_BINSL_df
= (0x6 << 23) | OPC_MSA_3R_0D
,
1358 OPC_MAX_A_df
= (0x6 << 23) | OPC_MSA_3R_0E
,
1359 OPC_AVER_S_df
= (0x6 << 23) | OPC_MSA_3R_10
,
1360 OPC_MOD_S_df
= (0x6 << 23) | OPC_MSA_3R_12
,
1361 OPC_ILVEV_df
= (0x6 << 23) | OPC_MSA_3R_14
,
1362 OPC_HSUB_S_df
= (0x6 << 23) | OPC_MSA_3R_15
,
1363 OPC_BINSR_df
= (0x7 << 23) | OPC_MSA_3R_0D
,
1364 OPC_MIN_A_df
= (0x7 << 23) | OPC_MSA_3R_0E
,
1365 OPC_AVER_U_df
= (0x7 << 23) | OPC_MSA_3R_10
,
1366 OPC_MOD_U_df
= (0x7 << 23) | OPC_MSA_3R_12
,
1367 OPC_ILVOD_df
= (0x7 << 23) | OPC_MSA_3R_14
,
1368 OPC_HSUB_U_df
= (0x7 << 23) | OPC_MSA_3R_15
,
1370 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1371 OPC_SLDI_df
= (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1372 OPC_CTCMSA
= (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1373 OPC_SPLATI_df
= (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1374 OPC_CFCMSA
= (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1375 OPC_COPY_S_df
= (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1376 OPC_MOVE_V
= (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1377 OPC_COPY_U_df
= (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1378 OPC_INSERT_df
= (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1379 OPC_INSVE_df
= (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1381 /* 3RF instruction _df(bit 21) = _w, _d */
1382 OPC_FCAF_df
= (0x0 << 22) | OPC_MSA_3RF_1A
,
1383 OPC_FADD_df
= (0x0 << 22) | OPC_MSA_3RF_1B
,
1384 OPC_FCUN_df
= (0x1 << 22) | OPC_MSA_3RF_1A
,
1385 OPC_FSUB_df
= (0x1 << 22) | OPC_MSA_3RF_1B
,
1386 OPC_FCOR_df
= (0x1 << 22) | OPC_MSA_3RF_1C
,
1387 OPC_FCEQ_df
= (0x2 << 22) | OPC_MSA_3RF_1A
,
1388 OPC_FMUL_df
= (0x2 << 22) | OPC_MSA_3RF_1B
,
1389 OPC_FCUNE_df
= (0x2 << 22) | OPC_MSA_3RF_1C
,
1390 OPC_FCUEQ_df
= (0x3 << 22) | OPC_MSA_3RF_1A
,
1391 OPC_FDIV_df
= (0x3 << 22) | OPC_MSA_3RF_1B
,
1392 OPC_FCNE_df
= (0x3 << 22) | OPC_MSA_3RF_1C
,
1393 OPC_FCLT_df
= (0x4 << 22) | OPC_MSA_3RF_1A
,
1394 OPC_FMADD_df
= (0x4 << 22) | OPC_MSA_3RF_1B
,
1395 OPC_MUL_Q_df
= (0x4 << 22) | OPC_MSA_3RF_1C
,
1396 OPC_FCULT_df
= (0x5 << 22) | OPC_MSA_3RF_1A
,
1397 OPC_FMSUB_df
= (0x5 << 22) | OPC_MSA_3RF_1B
,
1398 OPC_MADD_Q_df
= (0x5 << 22) | OPC_MSA_3RF_1C
,
1399 OPC_FCLE_df
= (0x6 << 22) | OPC_MSA_3RF_1A
,
1400 OPC_MSUB_Q_df
= (0x6 << 22) | OPC_MSA_3RF_1C
,
1401 OPC_FCULE_df
= (0x7 << 22) | OPC_MSA_3RF_1A
,
1402 OPC_FEXP2_df
= (0x7 << 22) | OPC_MSA_3RF_1B
,
1403 OPC_FSAF_df
= (0x8 << 22) | OPC_MSA_3RF_1A
,
1404 OPC_FEXDO_df
= (0x8 << 22) | OPC_MSA_3RF_1B
,
1405 OPC_FSUN_df
= (0x9 << 22) | OPC_MSA_3RF_1A
,
1406 OPC_FSOR_df
= (0x9 << 22) | OPC_MSA_3RF_1C
,
1407 OPC_FSEQ_df
= (0xA << 22) | OPC_MSA_3RF_1A
,
1408 OPC_FTQ_df
= (0xA << 22) | OPC_MSA_3RF_1B
,
1409 OPC_FSUNE_df
= (0xA << 22) | OPC_MSA_3RF_1C
,
1410 OPC_FSUEQ_df
= (0xB << 22) | OPC_MSA_3RF_1A
,
1411 OPC_FSNE_df
= (0xB << 22) | OPC_MSA_3RF_1C
,
1412 OPC_FSLT_df
= (0xC << 22) | OPC_MSA_3RF_1A
,
1413 OPC_FMIN_df
= (0xC << 22) | OPC_MSA_3RF_1B
,
1414 OPC_MULR_Q_df
= (0xC << 22) | OPC_MSA_3RF_1C
,
1415 OPC_FSULT_df
= (0xD << 22) | OPC_MSA_3RF_1A
,
1416 OPC_FMIN_A_df
= (0xD << 22) | OPC_MSA_3RF_1B
,
1417 OPC_MADDR_Q_df
= (0xD << 22) | OPC_MSA_3RF_1C
,
1418 OPC_FSLE_df
= (0xE << 22) | OPC_MSA_3RF_1A
,
1419 OPC_FMAX_df
= (0xE << 22) | OPC_MSA_3RF_1B
,
1420 OPC_MSUBR_Q_df
= (0xE << 22) | OPC_MSA_3RF_1C
,
1421 OPC_FSULE_df
= (0xF << 22) | OPC_MSA_3RF_1A
,
1422 OPC_FMAX_A_df
= (0xF << 22) | OPC_MSA_3RF_1B
,
1424 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1425 OPC_SLLI_df
= (0x0 << 23) | OPC_MSA_BIT_09
,
1426 OPC_SAT_S_df
= (0x0 << 23) | OPC_MSA_BIT_0A
,
1427 OPC_SRAI_df
= (0x1 << 23) | OPC_MSA_BIT_09
,
1428 OPC_SAT_U_df
= (0x1 << 23) | OPC_MSA_BIT_0A
,
1429 OPC_SRLI_df
= (0x2 << 23) | OPC_MSA_BIT_09
,
1430 OPC_SRARI_df
= (0x2 << 23) | OPC_MSA_BIT_0A
,
1431 OPC_BCLRI_df
= (0x3 << 23) | OPC_MSA_BIT_09
,
1432 OPC_SRLRI_df
= (0x3 << 23) | OPC_MSA_BIT_0A
,
1433 OPC_BSETI_df
= (0x4 << 23) | OPC_MSA_BIT_09
,
1434 OPC_BNEGI_df
= (0x5 << 23) | OPC_MSA_BIT_09
,
1435 OPC_BINSLI_df
= (0x6 << 23) | OPC_MSA_BIT_09
,
1436 OPC_BINSRI_df
= (0x7 << 23) | OPC_MSA_BIT_09
,
1442 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1443 * ============================================
1446 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1447 * instructions set. It is designed to fit the needs of signal, graphical and
1448 * video processing applications. MXU instruction set is used in Xburst family
1449 * of microprocessors by Ingenic.
1451 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1452 * the control register.
1455 * The notation used in MXU assembler mnemonics
1456 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1458 * Register operands:
1460 * XRa, XRb, XRc, XRd - MXU registers
1461 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1463 * Non-register operands:
1465 * aptn1 - 1-bit accumulate add/subtract pattern
1466 * aptn2 - 2-bit accumulate add/subtract pattern
1467 * eptn2 - 2-bit execute add/subtract pattern
1468 * optn2 - 2-bit operand pattern
1469 * optn3 - 3-bit operand pattern
1470 * sft4 - 4-bit shift amount
1471 * strd2 - 2-bit stride amount
1475 * Level of parallelism: Operand size:
1476 * S - single operation at a time 32 - word
1477 * D - two operations in parallel 16 - half word
1478 * Q - four operations in parallel 8 - byte
1482 * ADD - Add or subtract
1483 * ADDC - Add with carry-in
1485 * ASUM - Sum together then accumulate (add or subtract)
1486 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1487 * AVG - Average between 2 operands
1488 * ABD - Absolute difference
1490 * AND - Logical bitwise 'and' operation
1492 * EXTR - Extract bits
1493 * I2M - Move from GPR register to MXU register
1494 * LDD - Load data from memory to XRF
1495 * LDI - Load data from memory to XRF (and increase the address base)
1496 * LUI - Load unsigned immediate
1498 * MULU - Unsigned multiply
1499 * MADD - 64-bit operand add 32x32 product
1500 * MSUB - 64-bit operand subtract 32x32 product
1501 * MAC - Multiply and accumulate (add or subtract)
1502 * MAD - Multiply and add or subtract
1503 * MAX - Maximum between 2 operands
1504 * MIN - Minimum between 2 operands
1505 * M2I - Move from MXU register to GPR register
1506 * MOVZ - Move if zero
1507 * MOVN - Move if non-zero
1508 * NOR - Logical bitwise 'nor' operation
1509 * OR - Logical bitwise 'or' operation
1510 * STD - Store data from XRF to memory
1511 * SDI - Store data from XRF to memory (and increase the address base)
1512 * SLT - Set of less than comparison
1513 * SAD - Sum of absolute differences
1514 * SLL - Logical shift left
1515 * SLR - Logical shift right
1516 * SAR - Arithmetic shift right
1519 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1520 * XOR - Logical bitwise 'exclusive or' operation
1524 * E - Expand results
1525 * F - Fixed point multiplication
1526 * L - Low part result
1527 * R - Doing rounding
1528 * V - Variable instead of immediate
1529 * W - Combine above L and V
1532 * The list of MXU instructions grouped by functionality
1533 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1535 * Load/Store instructions Multiplication instructions
1536 * ----------------------- ---------------------------
1538 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1539 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1540 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1541 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1542 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1543 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1544 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1545 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1546 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1547 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1548 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1549 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1550 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1551 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1552 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1553 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1554 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1555 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1556 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1557 * S16SDI XRa, Rb, s10, eptn2
1558 * S8LDD XRa, Rb, s8, eptn3
1559 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1560 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1561 * S8SDI XRa, Rb, s8, eptn3
1562 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1563 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1564 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1565 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1566 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1567 * S32CPS XRa, XRb, XRc
1568 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1569 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1570 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1571 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1572 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1573 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1574 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1575 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1576 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1577 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1578 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1579 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1580 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1581 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1582 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1583 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1584 * Q8SLT XRa, XRb, XRc
1585 * Q8SLTU XRa, XRb, XRc
1586 * Q8MOVZ XRa, XRb, XRc Shift instructions
1587 * Q8MOVN XRa, XRb, XRc ------------------
1589 * D32SLL XRa, XRb, XRc, XRd, sft4
1590 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1591 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1592 * D32SARL XRa, XRb, XRc, sft4
1593 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1594 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1595 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1596 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1597 * Q16SLL XRa, XRb, XRc, XRd, sft4
1598 * Q16SLR XRa, XRb, XRc, XRd, sft4
1599 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1600 * ------------------------- Q16SLLV XRa, XRb, Rb
1601 * Q16SLRV XRa, XRb, Rb
1602 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1603 * S32ALN XRa, XRb, XRc, Rb
1604 * S32ALNI XRa, XRb, XRc, s3
1605 * S32LUI XRa, s8, optn3 Move instructions
1606 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1607 * S32EXTRV XRa, XRb, Rs, Rt
1608 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1609 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1612 * The opcode organization of MXU instructions
1613 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1615 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1616 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1617 * other bits up to the instruction level is as follows:
1622 * ┌─ 000000 ─ OPC_MXU_S32MADD
1623 * ├─ 000001 ─ OPC_MXU_S32MADDU
1624 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1627 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1628 * │ ├─ 001 ─ OPC_MXU_S32MIN
1629 * │ ├─ 010 ─ OPC_MXU_D16MAX
1630 * │ ├─ 011 ─ OPC_MXU_D16MIN
1631 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1632 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1633 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1634 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1635 * ├─ 000100 ─ OPC_MXU_S32MSUB
1636 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1637 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1638 * │ ├─ 001 ─ OPC_MXU_D16SLT
1639 * │ ├─ 010 ─ OPC_MXU_D16AVG
1640 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1641 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1642 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1643 * │ └─ 111 ─ OPC_MXU_Q8ADD
1646 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1647 * │ ├─ 010 ─ OPC_MXU_D16CPS
1648 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1649 * │ └─ 110 ─ OPC_MXU_Q16SAT
1650 * ├─ 001000 ─ OPC_MXU_D16MUL
1652 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1653 * │ └─ 01 ─ OPC_MXU_D16MULE
1654 * ├─ 001010 ─ OPC_MXU_D16MAC
1655 * ├─ 001011 ─ OPC_MXU_D16MACF
1656 * ├─ 001100 ─ OPC_MXU_D16MADL
1657 * ├─ 001101 ─ OPC_MXU_S16MAD
1658 * ├─ 001110 ─ OPC_MXU_Q16ADD
1659 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1660 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1661 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1664 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1665 * │ └─ 1 ─ OPC_MXU_S32STDR
1668 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1669 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1672 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1673 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1676 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1677 * │ └─ 1 ─ OPC_MXU_S32LDIR
1680 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1681 * │ └─ 1 ─ OPC_MXU_S32SDIR
1684 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1685 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1688 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1689 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1690 * ├─ 011000 ─ OPC_MXU_D32ADD
1692 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1693 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1694 * │ └─ 10 ─ OPC_MXU_D32ASUM
1695 * ├─ 011010 ─ <not assigned>
1697 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1698 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1699 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1702 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1703 * │ ├─ 01 ─ OPC_MXU_D8SUM
1704 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1705 * ├─ 011110 ─ <not assigned>
1706 * ├─ 011111 ─ <not assigned>
1707 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1708 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1709 * ├─ 100010 ─ OPC_MXU_S8LDD
1710 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1711 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1712 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1713 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1714 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1717 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1718 * │ ├─ 001 ─ OPC_MXU_S32ALN
1719 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1720 * │ ├─ 011 ─ OPC_MXU_S32LUI
1721 * │ ├─ 100 ─ OPC_MXU_S32NOR
1722 * │ ├─ 101 ─ OPC_MXU_S32AND
1723 * │ ├─ 110 ─ OPC_MXU_S32OR
1724 * │ └─ 111 ─ OPC_MXU_S32XOR
1727 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1728 * │ ├─ 001 ─ OPC_MXU_LXH
1729 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1730 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1731 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1732 * ├─ 101100 ─ OPC_MXU_S16LDI
1733 * ├─ 101101 ─ OPC_MXU_S16SDI
1734 * ├─ 101110 ─ OPC_MXU_S32M2I
1735 * ├─ 101111 ─ OPC_MXU_S32I2M
1736 * ├─ 110000 ─ OPC_MXU_D32SLL
1737 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1738 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1739 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1740 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1741 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1742 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1743 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1745 * ├─ 110111 ─ OPC_MXU_Q16SAR
1747 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1748 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1751 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1752 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1753 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1754 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1755 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1756 * │ └─ 101 ─ OPC_MXU_S32MOVN
1759 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1760 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1761 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1762 * ├─ 111100 ─ OPC_MXU_Q8MADL
1763 * ├─ 111101 ─ OPC_MXU_S32SFL
1764 * ├─ 111110 ─ OPC_MXU_Q8SAD
1765 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1770 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1771 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1775 OPC_MXU_S32MADD
= 0x00,
1776 OPC_MXU_S32MADDU
= 0x01,
1777 OPC__MXU_MUL
= 0x02,
1778 OPC_MXU__POOL00
= 0x03,
1779 OPC_MXU_S32MSUB
= 0x04,
1780 OPC_MXU_S32MSUBU
= 0x05,
1781 OPC_MXU__POOL01
= 0x06,
1782 OPC_MXU__POOL02
= 0x07,
1783 OPC_MXU_D16MUL
= 0x08,
1784 OPC_MXU__POOL03
= 0x09,
1785 OPC_MXU_D16MAC
= 0x0A,
1786 OPC_MXU_D16MACF
= 0x0B,
1787 OPC_MXU_D16MADL
= 0x0C,
1788 OPC_MXU_S16MAD
= 0x0D,
1789 OPC_MXU_Q16ADD
= 0x0E,
1790 OPC_MXU_D16MACE
= 0x0F,
1791 OPC_MXU__POOL04
= 0x10,
1792 OPC_MXU__POOL05
= 0x11,
1793 OPC_MXU__POOL06
= 0x12,
1794 OPC_MXU__POOL07
= 0x13,
1795 OPC_MXU__POOL08
= 0x14,
1796 OPC_MXU__POOL09
= 0x15,
1797 OPC_MXU__POOL10
= 0x16,
1798 OPC_MXU__POOL11
= 0x17,
1799 OPC_MXU_D32ADD
= 0x18,
1800 OPC_MXU__POOL12
= 0x19,
1801 /* not assigned 0x1A */
1802 OPC_MXU__POOL13
= 0x1B,
1803 OPC_MXU__POOL14
= 0x1C,
1804 OPC_MXU_Q8ACCE
= 0x1D,
1805 /* not assigned 0x1E */
1806 /* not assigned 0x1F */
1807 /* not assigned 0x20 */
1808 /* not assigned 0x21 */
1809 OPC_MXU_S8LDD
= 0x22,
1810 OPC_MXU_S8STD
= 0x23,
1811 OPC_MXU_S8LDI
= 0x24,
1812 OPC_MXU_S8SDI
= 0x25,
1813 OPC_MXU__POOL15
= 0x26,
1814 OPC_MXU__POOL16
= 0x27,
1815 OPC_MXU__POOL17
= 0x28,
1816 /* not assigned 0x29 */
1817 OPC_MXU_S16LDD
= 0x2A,
1818 OPC_MXU_S16STD
= 0x2B,
1819 OPC_MXU_S16LDI
= 0x2C,
1820 OPC_MXU_S16SDI
= 0x2D,
1821 OPC_MXU_S32M2I
= 0x2E,
1822 OPC_MXU_S32I2M
= 0x2F,
1823 OPC_MXU_D32SLL
= 0x30,
1824 OPC_MXU_D32SLR
= 0x31,
1825 OPC_MXU_D32SARL
= 0x32,
1826 OPC_MXU_D32SAR
= 0x33,
1827 OPC_MXU_Q16SLL
= 0x34,
1828 OPC_MXU_Q16SLR
= 0x35,
1829 OPC_MXU__POOL18
= 0x36,
1830 OPC_MXU_Q16SAR
= 0x37,
1831 OPC_MXU__POOL19
= 0x38,
1832 OPC_MXU__POOL20
= 0x39,
1833 OPC_MXU__POOL21
= 0x3A,
1834 OPC_MXU_Q16SCOP
= 0x3B,
1835 OPC_MXU_Q8MADL
= 0x3C,
1836 OPC_MXU_S32SFL
= 0x3D,
1837 OPC_MXU_Q8SAD
= 0x3E,
1838 /* not assigned 0x3F */
1846 OPC_MXU_S32MAX
= 0x00,
1847 OPC_MXU_S32MIN
= 0x01,
1848 OPC_MXU_D16MAX
= 0x02,
1849 OPC_MXU_D16MIN
= 0x03,
1850 OPC_MXU_Q8MAX
= 0x04,
1851 OPC_MXU_Q8MIN
= 0x05,
1852 OPC_MXU_Q8SLT
= 0x06,
1853 OPC_MXU_Q8SLTU
= 0x07,
1860 OPC_MXU_S32SLT
= 0x00,
1861 OPC_MXU_D16SLT
= 0x01,
1862 OPC_MXU_D16AVG
= 0x02,
1863 OPC_MXU_D16AVGR
= 0x03,
1864 OPC_MXU_Q8AVG
= 0x04,
1865 OPC_MXU_Q8AVGR
= 0x05,
1866 OPC_MXU_Q8ADD
= 0x07,
1873 OPC_MXU_S32CPS
= 0x00,
1874 OPC_MXU_D16CPS
= 0x02,
1875 OPC_MXU_Q8ABD
= 0x04,
1876 OPC_MXU_Q16SAT
= 0x06,
1883 OPC_MXU_D16MULF
= 0x00,
1884 OPC_MXU_D16MULE
= 0x01,
1891 OPC_MXU_S32LDD
= 0x00,
1892 OPC_MXU_S32LDDR
= 0x01,
1899 OPC_MXU_S32STD
= 0x00,
1900 OPC_MXU_S32STDR
= 0x01,
1907 OPC_MXU_S32LDDV
= 0x00,
1908 OPC_MXU_S32LDDVR
= 0x01,
1915 OPC_MXU_S32STDV
= 0x00,
1916 OPC_MXU_S32STDVR
= 0x01,
1923 OPC_MXU_S32LDI
= 0x00,
1924 OPC_MXU_S32LDIR
= 0x01,
1931 OPC_MXU_S32SDI
= 0x00,
1932 OPC_MXU_S32SDIR
= 0x01,
1939 OPC_MXU_S32LDIV
= 0x00,
1940 OPC_MXU_S32LDIVR
= 0x01,
1947 OPC_MXU_S32SDIV
= 0x00,
1948 OPC_MXU_S32SDIVR
= 0x01,
1955 OPC_MXU_D32ACC
= 0x00,
1956 OPC_MXU_D32ACCM
= 0x01,
1957 OPC_MXU_D32ASUM
= 0x02,
1964 OPC_MXU_Q16ACC
= 0x00,
1965 OPC_MXU_Q16ACCM
= 0x01,
1966 OPC_MXU_Q16ASUM
= 0x02,
1973 OPC_MXU_Q8ADDE
= 0x00,
1974 OPC_MXU_D8SUM
= 0x01,
1975 OPC_MXU_D8SUMC
= 0x02,
1982 OPC_MXU_S32MUL
= 0x00,
1983 OPC_MXU_S32MULU
= 0x01,
1984 OPC_MXU_S32EXTR
= 0x02,
1985 OPC_MXU_S32EXTRV
= 0x03,
1992 OPC_MXU_D32SARW
= 0x00,
1993 OPC_MXU_S32ALN
= 0x01,
1994 OPC_MXU_S32ALNI
= 0x02,
1995 OPC_MXU_S32LUI
= 0x03,
1996 OPC_MXU_S32NOR
= 0x04,
1997 OPC_MXU_S32AND
= 0x05,
1998 OPC_MXU_S32OR
= 0x06,
1999 OPC_MXU_S32XOR
= 0x07,
2009 OPC_MXU_LXBU
= 0x04,
2010 OPC_MXU_LXHU
= 0x05,
2017 OPC_MXU_D32SLLV
= 0x00,
2018 OPC_MXU_D32SLRV
= 0x01,
2019 OPC_MXU_D32SARV
= 0x03,
2020 OPC_MXU_Q16SLLV
= 0x04,
2021 OPC_MXU_Q16SLRV
= 0x05,
2022 OPC_MXU_Q16SARV
= 0x07,
2029 OPC_MXU_Q8MUL
= 0x00,
2030 OPC_MXU_Q8MULSU
= 0x01,
2037 OPC_MXU_Q8MOVZ
= 0x00,
2038 OPC_MXU_Q8MOVN
= 0x01,
2039 OPC_MXU_D16MOVZ
= 0x02,
2040 OPC_MXU_D16MOVN
= 0x03,
2041 OPC_MXU_S32MOVZ
= 0x04,
2042 OPC_MXU_S32MOVN
= 0x05,
2049 OPC_MXU_Q8MAC
= 0x00,
2050 OPC_MXU_Q8MACSU
= 0x01,
2054 * Overview of the TX79-specific instruction set
2055 * =============================================
2057 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2058 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2059 * instructions and certain multimedia instructions (MMIs). These MMIs
2060 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2061 * or sixteen 8-bit paths.
2065 * The Toshiba TX System RISC TX79 Core Architecture manual,
2066 * https://wiki.qemu.org/File:C790.pdf
2068 * Three-Operand Multiply and Multiply-Add (4 instructions)
2069 * --------------------------------------------------------
2070 * MADD [rd,] rs, rt Multiply/Add
2071 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2072 * MULT [rd,] rs, rt Multiply (3-operand)
2073 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2075 * Multiply Instructions for Pipeline 1 (10 instructions)
2076 * ------------------------------------------------------
2077 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2078 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2079 * DIV1 rs, rt Divide Pipeline 1
2080 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2081 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2082 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2083 * MFHI1 rd Move From HI1 Register
2084 * MFLO1 rd Move From LO1 Register
2085 * MTHI1 rs Move To HI1 Register
2086 * MTLO1 rs Move To LO1 Register
2088 * Arithmetic (19 instructions)
2089 * ----------------------------
2090 * PADDB rd, rs, rt Parallel Add Byte
2091 * PSUBB rd, rs, rt Parallel Subtract Byte
2092 * PADDH rd, rs, rt Parallel Add Halfword
2093 * PSUBH rd, rs, rt Parallel Subtract Halfword
2094 * PADDW rd, rs, rt Parallel Add Word
2095 * PSUBW rd, rs, rt Parallel Subtract Word
2096 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2097 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2098 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2099 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2100 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2101 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2102 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2103 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2104 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2105 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2106 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2107 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2108 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2110 * Min/Max (4 instructions)
2111 * ------------------------
2112 * PMAXH rd, rs, rt Parallel Maximum Halfword
2113 * PMINH rd, rs, rt Parallel Minimum Halfword
2114 * PMAXW rd, rs, rt Parallel Maximum Word
2115 * PMINW rd, rs, rt Parallel Minimum Word
2117 * Absolute (2 instructions)
2118 * -------------------------
2119 * PABSH rd, rt Parallel Absolute Halfword
2120 * PABSW rd, rt Parallel Absolute Word
2122 * Logical (4 instructions)
2123 * ------------------------
2124 * PAND rd, rs, rt Parallel AND
2125 * POR rd, rs, rt Parallel OR
2126 * PXOR rd, rs, rt Parallel XOR
2127 * PNOR rd, rs, rt Parallel NOR
2129 * Shift (9 instructions)
2130 * ----------------------
2131 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2132 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2133 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2134 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2135 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2136 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2137 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2138 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2139 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2141 * Compare (6 instructions)
2142 * ------------------------
2143 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2144 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2145 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2146 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2147 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2148 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2150 * LZC (1 instruction)
2151 * -------------------
2152 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2154 * Quadword Load and Store (2 instructions)
2155 * ----------------------------------------
2156 * LQ rt, offset(base) Load Quadword
2157 * SQ rt, offset(base) Store Quadword
2159 * Multiply and Divide (19 instructions)
2160 * -------------------------------------
2161 * PMULTW rd, rs, rt Parallel Multiply Word
2162 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2163 * PDIVW rs, rt Parallel Divide Word
2164 * PDIVUW rs, rt Parallel Divide Unsigned Word
2165 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2166 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2167 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2168 * PMULTH rd, rs, rt Parallel Multiply Halfword
2169 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2170 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2171 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2172 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2173 * PDIVBW rs, rt Parallel Divide Broadcast Word
2174 * PMFHI rd Parallel Move From HI Register
2175 * PMFLO rd Parallel Move From LO Register
2176 * PMTHI rs Parallel Move To HI Register
2177 * PMTLO rs Parallel Move To LO Register
2178 * PMFHL rd Parallel Move From HI/LO Register
2179 * PMTHL rs Parallel Move To HI/LO Register
2181 * Pack/Extend (11 instructions)
2182 * -----------------------------
2183 * PPAC5 rd, rt Parallel Pack to 5 bits
2184 * PPACB rd, rs, rt Parallel Pack to Byte
2185 * PPACH rd, rs, rt Parallel Pack to Halfword
2186 * PPACW rd, rs, rt Parallel Pack to Word
2187 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2188 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2189 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2190 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2191 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2192 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2193 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2195 * Others (16 instructions)
2196 * ------------------------
2197 * PCPYH rd, rt Parallel Copy Halfword
2198 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2199 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2200 * PREVH rd, rt Parallel Reverse Halfword
2201 * PINTH rd, rs, rt Parallel Interleave Halfword
2202 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2203 * PEXEH rd, rt Parallel Exchange Even Halfword
2204 * PEXCH rd, rt Parallel Exchange Center Halfword
2205 * PEXEW rd, rt Parallel Exchange Even Word
2206 * PEXCW rd, rt Parallel Exchange Center Word
2207 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2208 * MFSA rd Move from Shift Amount Register
2209 * MTSA rs Move to Shift Amount Register
2210 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2211 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2212 * PROT3W rd, rt Parallel Rotate 3 Words
2214 * MMI (MultiMedia Instruction) encodings
2215 * ======================================
2217 * MMI instructions encoding table keys:
2219 * * This code is reserved for future use. An attempt to execute it
2220 * causes a Reserved Instruction exception.
2221 * % This code indicates an instruction class. The instruction word
2222 * must be further decoded by examining additional tables that show
2223 * the values for other instruction fields.
2224 * # This code is reserved for the unsupported instructions DMULT,
2225 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2226 * to execute it causes a Reserved Instruction exception.
2228 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2231 * +--------+----------------------------------------+
2233 * +--------+----------------------------------------+
2235 * opcode bits 28..26
2236 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2237 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2238 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2239 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2240 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2241 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2242 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2243 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2244 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2245 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2246 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2250 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
2251 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
2252 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
2256 * MMI instructions with opcode field = MMI:
2259 * +--------+-------------------------------+--------+
2260 * | MMI | |function|
2261 * +--------+-------------------------------+--------+
2263 * function bits 2..0
2264 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2265 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2266 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2267 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2268 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2269 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2270 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2271 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2272 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2273 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2274 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2277 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2279 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
2280 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
2281 MMI_OPC_PLZCW
= 0x04 | MMI_OPC_CLASS_MMI
,
2282 MMI_OPC_CLASS_MMI0
= 0x08 | MMI_OPC_CLASS_MMI
,
2283 MMI_OPC_CLASS_MMI2
= 0x09 | MMI_OPC_CLASS_MMI
,
2284 MMI_OPC_MFHI1
= 0x10 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFHI */
2285 MMI_OPC_MTHI1
= 0x11 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTHI */
2286 MMI_OPC_MFLO1
= 0x12 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFLO */
2287 MMI_OPC_MTLO1
= 0x13 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTLO */
2288 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
2289 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
2290 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
2291 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
2292 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
2293 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
2294 MMI_OPC_CLASS_MMI1
= 0x28 | MMI_OPC_CLASS_MMI
,
2295 MMI_OPC_CLASS_MMI3
= 0x29 | MMI_OPC_CLASS_MMI
,
2296 MMI_OPC_PMFHL
= 0x30 | MMI_OPC_CLASS_MMI
,
2297 MMI_OPC_PMTHL
= 0x31 | MMI_OPC_CLASS_MMI
,
2298 MMI_OPC_PSLLH
= 0x34 | MMI_OPC_CLASS_MMI
,
2299 MMI_OPC_PSRLH
= 0x36 | MMI_OPC_CLASS_MMI
,
2300 MMI_OPC_PSRAH
= 0x37 | MMI_OPC_CLASS_MMI
,
2301 MMI_OPC_PSLLW
= 0x3C | MMI_OPC_CLASS_MMI
,
2302 MMI_OPC_PSRLW
= 0x3E | MMI_OPC_CLASS_MMI
,
2303 MMI_OPC_PSRAW
= 0x3F | MMI_OPC_CLASS_MMI
,
2307 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2310 * +--------+----------------------+--------+--------+
2311 * | MMI | |function| MMI0 |
2312 * +--------+----------------------+--------+--------+
2314 * function bits 7..6
2315 * bits | 0 | 1 | 2 | 3
2316 * 10..8 | 00 | 01 | 10 | 11
2317 * -------+-------+-------+-------+-------
2318 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2319 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2320 * 2 010 | PADDB | PSUBB | PCGTB | *
2321 * 3 011 | * | * | * | *
2322 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2323 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2324 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2325 * 7 111 | * | * | PEXT5 | PPAC5
2328 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2330 MMI_OPC_0_PADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI0
,
2331 MMI_OPC_0_PSUBW
= (0x01 << 6) | MMI_OPC_CLASS_MMI0
,
2332 MMI_OPC_0_PCGTW
= (0x02 << 6) | MMI_OPC_CLASS_MMI0
,
2333 MMI_OPC_0_PMAXW
= (0x03 << 6) | MMI_OPC_CLASS_MMI0
,
2334 MMI_OPC_0_PADDH
= (0x04 << 6) | MMI_OPC_CLASS_MMI0
,
2335 MMI_OPC_0_PSUBH
= (0x05 << 6) | MMI_OPC_CLASS_MMI0
,
2336 MMI_OPC_0_PCGTH
= (0x06 << 6) | MMI_OPC_CLASS_MMI0
,
2337 MMI_OPC_0_PMAXH
= (0x07 << 6) | MMI_OPC_CLASS_MMI0
,
2338 MMI_OPC_0_PADDB
= (0x08 << 6) | MMI_OPC_CLASS_MMI0
,
2339 MMI_OPC_0_PSUBB
= (0x09 << 6) | MMI_OPC_CLASS_MMI0
,
2340 MMI_OPC_0_PCGTB
= (0x0A << 6) | MMI_OPC_CLASS_MMI0
,
2341 MMI_OPC_0_PADDSW
= (0x10 << 6) | MMI_OPC_CLASS_MMI0
,
2342 MMI_OPC_0_PSUBSW
= (0x11 << 6) | MMI_OPC_CLASS_MMI0
,
2343 MMI_OPC_0_PEXTLW
= (0x12 << 6) | MMI_OPC_CLASS_MMI0
,
2344 MMI_OPC_0_PPACW
= (0x13 << 6) | MMI_OPC_CLASS_MMI0
,
2345 MMI_OPC_0_PADDSH
= (0x14 << 6) | MMI_OPC_CLASS_MMI0
,
2346 MMI_OPC_0_PSUBSH
= (0x15 << 6) | MMI_OPC_CLASS_MMI0
,
2347 MMI_OPC_0_PEXTLH
= (0x16 << 6) | MMI_OPC_CLASS_MMI0
,
2348 MMI_OPC_0_PPACH
= (0x17 << 6) | MMI_OPC_CLASS_MMI0
,
2349 MMI_OPC_0_PADDSB
= (0x18 << 6) | MMI_OPC_CLASS_MMI0
,
2350 MMI_OPC_0_PSUBSB
= (0x19 << 6) | MMI_OPC_CLASS_MMI0
,
2351 MMI_OPC_0_PEXTLB
= (0x1A << 6) | MMI_OPC_CLASS_MMI0
,
2352 MMI_OPC_0_PPACB
= (0x1B << 6) | MMI_OPC_CLASS_MMI0
,
2353 MMI_OPC_0_PEXT5
= (0x1E << 6) | MMI_OPC_CLASS_MMI0
,
2354 MMI_OPC_0_PPAC5
= (0x1F << 6) | MMI_OPC_CLASS_MMI0
,
2358 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2361 * +--------+----------------------+--------+--------+
2362 * | MMI | |function| MMI1 |
2363 * +--------+----------------------+--------+--------+
2365 * function bits 7..6
2366 * bits | 0 | 1 | 2 | 3
2367 * 10..8 | 00 | 01 | 10 | 11
2368 * -------+-------+-------+-------+-------
2369 * 0 000 | * | PABSW | PCEQW | PMINW
2370 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2371 * 2 010 | * | * | PCEQB | *
2372 * 3 011 | * | * | * | *
2373 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2374 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2375 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2376 * 7 111 | * | * | * | *
2379 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2381 MMI_OPC_1_PABSW
= (0x01 << 6) | MMI_OPC_CLASS_MMI1
,
2382 MMI_OPC_1_PCEQW
= (0x02 << 6) | MMI_OPC_CLASS_MMI1
,
2383 MMI_OPC_1_PMINW
= (0x03 << 6) | MMI_OPC_CLASS_MMI1
,
2384 MMI_OPC_1_PADSBH
= (0x04 << 6) | MMI_OPC_CLASS_MMI1
,
2385 MMI_OPC_1_PABSH
= (0x05 << 6) | MMI_OPC_CLASS_MMI1
,
2386 MMI_OPC_1_PCEQH
= (0x06 << 6) | MMI_OPC_CLASS_MMI1
,
2387 MMI_OPC_1_PMINH
= (0x07 << 6) | MMI_OPC_CLASS_MMI1
,
2388 MMI_OPC_1_PCEQB
= (0x0A << 6) | MMI_OPC_CLASS_MMI1
,
2389 MMI_OPC_1_PADDUW
= (0x10 << 6) | MMI_OPC_CLASS_MMI1
,
2390 MMI_OPC_1_PSUBUW
= (0x11 << 6) | MMI_OPC_CLASS_MMI1
,
2391 MMI_OPC_1_PEXTUW
= (0x12 << 6) | MMI_OPC_CLASS_MMI1
,
2392 MMI_OPC_1_PADDUH
= (0x14 << 6) | MMI_OPC_CLASS_MMI1
,
2393 MMI_OPC_1_PSUBUH
= (0x15 << 6) | MMI_OPC_CLASS_MMI1
,
2394 MMI_OPC_1_PEXTUH
= (0x16 << 6) | MMI_OPC_CLASS_MMI1
,
2395 MMI_OPC_1_PADDUB
= (0x18 << 6) | MMI_OPC_CLASS_MMI1
,
2396 MMI_OPC_1_PSUBUB
= (0x19 << 6) | MMI_OPC_CLASS_MMI1
,
2397 MMI_OPC_1_PEXTUB
= (0x1A << 6) | MMI_OPC_CLASS_MMI1
,
2398 MMI_OPC_1_QFSRV
= (0x1B << 6) | MMI_OPC_CLASS_MMI1
,
2402 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2405 * +--------+----------------------+--------+--------+
2406 * | MMI | |function| MMI2 |
2407 * +--------+----------------------+--------+--------+
2409 * function bits 7..6
2410 * bits | 0 | 1 | 2 | 3
2411 * 10..8 | 00 | 01 | 10 | 11
2412 * -------+-------+-------+-------+-------
2413 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2414 * 1 001 | PMSUBW| * | * | *
2415 * 2 010 | PMFHI | PMFLO | PINTH | *
2416 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2417 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2418 * 5 101 | PMSUBH| PHMSBH| * | *
2419 * 6 110 | * | * | PEXEH | PREVH
2420 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2423 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2425 MMI_OPC_2_PMADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI2
,
2426 MMI_OPC_2_PSLLVW
= (0x02 << 6) | MMI_OPC_CLASS_MMI2
,
2427 MMI_OPC_2_PSRLVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI2
,
2428 MMI_OPC_2_PMSUBW
= (0x04 << 6) | MMI_OPC_CLASS_MMI2
,
2429 MMI_OPC_2_PMFHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI2
,
2430 MMI_OPC_2_PMFLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI2
,
2431 MMI_OPC_2_PINTH
= (0x0A << 6) | MMI_OPC_CLASS_MMI2
,
2432 MMI_OPC_2_PMULTW
= (0x0C << 6) | MMI_OPC_CLASS_MMI2
,
2433 MMI_OPC_2_PDIVW
= (0x0D << 6) | MMI_OPC_CLASS_MMI2
,
2434 MMI_OPC_2_PCPYLD
= (0x0E << 6) | MMI_OPC_CLASS_MMI2
,
2435 MMI_OPC_2_PMADDH
= (0x10 << 6) | MMI_OPC_CLASS_MMI2
,
2436 MMI_OPC_2_PHMADH
= (0x11 << 6) | MMI_OPC_CLASS_MMI2
,
2437 MMI_OPC_2_PAND
= (0x12 << 6) | MMI_OPC_CLASS_MMI2
,
2438 MMI_OPC_2_PXOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI2
,
2439 MMI_OPC_2_PMSUBH
= (0x14 << 6) | MMI_OPC_CLASS_MMI2
,
2440 MMI_OPC_2_PHMSBH
= (0x15 << 6) | MMI_OPC_CLASS_MMI2
,
2441 MMI_OPC_2_PEXEH
= (0x1A << 6) | MMI_OPC_CLASS_MMI2
,
2442 MMI_OPC_2_PREVH
= (0x1B << 6) | MMI_OPC_CLASS_MMI2
,
2443 MMI_OPC_2_PMULTH
= (0x1C << 6) | MMI_OPC_CLASS_MMI2
,
2444 MMI_OPC_2_PDIVBW
= (0x1D << 6) | MMI_OPC_CLASS_MMI2
,
2445 MMI_OPC_2_PEXEW
= (0x1E << 6) | MMI_OPC_CLASS_MMI2
,
2446 MMI_OPC_2_PROT3W
= (0x1F << 6) | MMI_OPC_CLASS_MMI2
,
2450 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2453 * +--------+----------------------+--------+--------+
2454 * | MMI | |function| MMI3 |
2455 * +--------+----------------------+--------+--------+
2457 * function bits 7..6
2458 * bits | 0 | 1 | 2 | 3
2459 * 10..8 | 00 | 01 | 10 | 11
2460 * -------+-------+-------+-------+-------
2461 * 0 000 |PMADDUW| * | * | PSRAVW
2462 * 1 001 | * | * | * | *
2463 * 2 010 | PMTHI | PMTLO | PINTEH| *
2464 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2465 * 4 100 | * | * | POR | PNOR
2466 * 5 101 | * | * | * | *
2467 * 6 110 | * | * | PEXCH | PCPYH
2468 * 7 111 | * | * | PEXCW | *
2471 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2473 MMI_OPC_3_PMADDUW
= (0x00 << 6) | MMI_OPC_CLASS_MMI3
,
2474 MMI_OPC_3_PSRAVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI3
,
2475 MMI_OPC_3_PMTHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI3
,
2476 MMI_OPC_3_PMTLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI3
,
2477 MMI_OPC_3_PINTEH
= (0x0A << 6) | MMI_OPC_CLASS_MMI3
,
2478 MMI_OPC_3_PMULTUW
= (0x0C << 6) | MMI_OPC_CLASS_MMI3
,
2479 MMI_OPC_3_PDIVUW
= (0x0D << 6) | MMI_OPC_CLASS_MMI3
,
2480 MMI_OPC_3_PCPYUD
= (0x0E << 6) | MMI_OPC_CLASS_MMI3
,
2481 MMI_OPC_3_POR
= (0x12 << 6) | MMI_OPC_CLASS_MMI3
,
2482 MMI_OPC_3_PNOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI3
,
2483 MMI_OPC_3_PEXCH
= (0x1A << 6) | MMI_OPC_CLASS_MMI3
,
2484 MMI_OPC_3_PCPYH
= (0x1B << 6) | MMI_OPC_CLASS_MMI3
,
2485 MMI_OPC_3_PEXCW
= (0x1E << 6) | MMI_OPC_CLASS_MMI3
,
2488 /* global register indices */
2489 TCGv cpu_gpr
[32], cpu_PC
;
2490 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
2491 static TCGv cpu_dspctrl
, btarget
;
2493 static TCGv cpu_lladdr
, cpu_llval
;
2494 static TCGv_i32 hflags
;
2495 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
2496 static TCGv_i64 fpu_f64
[32];
2497 static TCGv_i64 msa_wr_d
[64];
2499 #if defined(TARGET_MIPS64)
2500 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2501 static TCGv_i64 cpu_mmr
[32];
2504 #if !defined(TARGET_MIPS64)
2506 static TCGv mxu_gpr
[NUMBER_OF_MXU_REGISTERS
- 1];
2510 #include "exec/gen-icount.h"
2512 #define gen_helper_0e0i(name, arg) do { \
2513 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2514 gen_helper_##name(cpu_env, helper_tmp); \
2515 tcg_temp_free_i32(helper_tmp); \
2518 #define gen_helper_0e1i(name, arg1, arg2) do { \
2519 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2520 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2521 tcg_temp_free_i32(helper_tmp); \
2524 #define gen_helper_1e0i(name, ret, arg1) do { \
2525 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2526 gen_helper_##name(ret, cpu_env, helper_tmp); \
2527 tcg_temp_free_i32(helper_tmp); \
2530 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2531 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2532 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2533 tcg_temp_free_i32(helper_tmp); \
2536 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2537 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2538 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2539 tcg_temp_free_i32(helper_tmp); \
2542 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2543 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2544 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2545 tcg_temp_free_i32(helper_tmp); \
2548 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2549 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2550 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2551 tcg_temp_free_i32(helper_tmp); \
2554 #define DISAS_STOP DISAS_TARGET_0
2555 #define DISAS_EXIT DISAS_TARGET_1
2557 static const char * const regnames
[] = {
2558 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2559 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2560 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2561 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2564 static const char * const regnames_HI
[] = {
2565 "HI0", "HI1", "HI2", "HI3",
2568 static const char * const regnames_LO
[] = {
2569 "LO0", "LO1", "LO2", "LO3",
2572 static const char * const fregnames
[] = {
2573 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2574 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2575 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2576 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2579 static const char * const msaregnames
[] = {
2580 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2581 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2582 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2583 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2584 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2585 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2586 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2587 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2588 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2589 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2590 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2591 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2592 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2593 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2594 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2595 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2598 #if !defined(TARGET_MIPS64)
2599 static const char * const mxuregnames
[] = {
2600 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2601 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2605 /* General purpose registers moves. */
2606 void gen_load_gpr(TCGv t
, int reg
)
2609 tcg_gen_movi_tl(t
, 0);
2611 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
2615 void gen_store_gpr(TCGv t
, int reg
)
2618 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
2622 /* Moves to/from shadow registers. */
2623 static inline void gen_load_srsgpr(int from
, int to
)
2625 TCGv t0
= tcg_temp_new();
2628 tcg_gen_movi_tl(t0
, 0);
2630 TCGv_i32 t2
= tcg_temp_new_i32();
2631 TCGv_ptr addr
= tcg_temp_new_ptr();
2633 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2634 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2635 tcg_gen_andi_i32(t2
, t2
, 0xf);
2636 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2637 tcg_gen_ext_i32_ptr(addr
, t2
);
2638 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2640 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
2641 tcg_temp_free_ptr(addr
);
2642 tcg_temp_free_i32(t2
);
2644 gen_store_gpr(t0
, to
);
2648 static inline void gen_store_srsgpr(int from
, int to
)
2651 TCGv t0
= tcg_temp_new();
2652 TCGv_i32 t2
= tcg_temp_new_i32();
2653 TCGv_ptr addr
= tcg_temp_new_ptr();
2655 gen_load_gpr(t0
, from
);
2656 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2657 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2658 tcg_gen_andi_i32(t2
, t2
, 0xf);
2659 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2660 tcg_gen_ext_i32_ptr(addr
, t2
);
2661 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2663 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
2664 tcg_temp_free_ptr(addr
);
2665 tcg_temp_free_i32(t2
);
2670 #if !defined(TARGET_MIPS64)
2671 /* MXU General purpose registers moves. */
2672 static inline void gen_load_mxu_gpr(TCGv t
, unsigned int reg
)
2675 tcg_gen_movi_tl(t
, 0);
2676 } else if (reg
<= 15) {
2677 tcg_gen_mov_tl(t
, mxu_gpr
[reg
- 1]);
2681 static inline void gen_store_mxu_gpr(TCGv t
, unsigned int reg
)
2683 if (reg
> 0 && reg
<= 15) {
2684 tcg_gen_mov_tl(mxu_gpr
[reg
- 1], t
);
2688 /* MXU control register moves. */
2689 static inline void gen_load_mxu_cr(TCGv t
)
2691 tcg_gen_mov_tl(t
, mxu_CR
);
2694 static inline void gen_store_mxu_cr(TCGv t
)
2696 /* TODO: Add handling of RW rules for MXU_CR. */
2697 tcg_gen_mov_tl(mxu_CR
, t
);
2703 static inline void gen_save_pc(target_ulong pc
)
2705 tcg_gen_movi_tl(cpu_PC
, pc
);
2708 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
2710 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
2711 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
2712 gen_save_pc(ctx
->base
.pc_next
);
2713 ctx
->saved_pc
= ctx
->base
.pc_next
;
2715 if (ctx
->hflags
!= ctx
->saved_hflags
) {
2716 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
2717 ctx
->saved_hflags
= ctx
->hflags
;
2718 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2724 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
2730 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
2732 ctx
->saved_hflags
= ctx
->hflags
;
2733 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2739 ctx
->btarget
= env
->btarget
;
2744 void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
2746 TCGv_i32 texcp
= tcg_const_i32(excp
);
2747 TCGv_i32 terr
= tcg_const_i32(err
);
2748 save_cpu_state(ctx
, 1);
2749 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
2750 tcg_temp_free_i32(terr
);
2751 tcg_temp_free_i32(texcp
);
2752 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2755 void generate_exception(DisasContext
*ctx
, int excp
)
2757 gen_helper_0e0i(raise_exception
, excp
);
2760 void generate_exception_end(DisasContext
*ctx
, int excp
)
2762 generate_exception_err(ctx
, excp
, 0);
2765 void gen_reserved_instruction(DisasContext
*ctx
)
2767 generate_exception_end(ctx
, EXCP_RI
);
2770 /* Floating point register moves. */
2771 static void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2773 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2774 generate_exception(ctx
, EXCP_RI
);
2776 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
2779 static void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2782 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2783 generate_exception(ctx
, EXCP_RI
);
2785 t64
= tcg_temp_new_i64();
2786 tcg_gen_extu_i32_i64(t64
, t
);
2787 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
2788 tcg_temp_free_i64(t64
);
2791 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2793 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2794 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
2796 gen_load_fpr32(ctx
, t
, reg
| 1);
2800 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2802 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2803 TCGv_i64 t64
= tcg_temp_new_i64();
2804 tcg_gen_extu_i32_i64(t64
, t
);
2805 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
2806 tcg_temp_free_i64(t64
);
2808 gen_store_fpr32(ctx
, t
, reg
| 1);
2812 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2814 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2815 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
2817 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
2821 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2823 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2824 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
2827 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
2828 t0
= tcg_temp_new_i64();
2829 tcg_gen_shri_i64(t0
, t
, 32);
2830 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
2831 tcg_temp_free_i64(t0
);
2835 static inline int get_fp_bit(int cc
)
2844 /* Addresses computation */
2845 void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
2847 tcg_gen_add_tl(ret
, arg0
, arg1
);
2849 #if defined(TARGET_MIPS64)
2850 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2851 tcg_gen_ext32s_i64(ret
, ret
);
2856 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
2859 tcg_gen_addi_tl(ret
, base
, ofs
);
2861 #if defined(TARGET_MIPS64)
2862 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2863 tcg_gen_ext32s_i64(ret
, ret
);
2868 /* Addresses computation (translation time) */
2869 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
2872 target_long sum
= base
+ offset
;
2874 #if defined(TARGET_MIPS64)
2875 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2882 /* Sign-extract the low 32-bits to a target_long. */
2883 void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
2885 #if defined(TARGET_MIPS64)
2886 tcg_gen_ext32s_i64(ret
, arg
);
2888 tcg_gen_extrl_i64_i32(ret
, arg
);
2892 /* Sign-extract the high 32-bits to a target_long. */
2893 void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
2895 #if defined(TARGET_MIPS64)
2896 tcg_gen_sari_i64(ret
, arg
, 32);
2898 tcg_gen_extrh_i64_i32(ret
, arg
);
2902 static inline void check_cp0_enabled(DisasContext
*ctx
)
2904 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2905 generate_exception_end(ctx
, EXCP_CpU
);
2909 static inline void check_cp1_enabled(DisasContext
*ctx
)
2911 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
2912 generate_exception_err(ctx
, EXCP_CpU
, 1);
2917 * Verify that the processor is running with COP1X instructions enabled.
2918 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2921 static inline void check_cop1x(DisasContext
*ctx
)
2923 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
2924 gen_reserved_instruction(ctx
);
2929 * Verify that the processor is running with 64-bit floating-point
2930 * operations enabled.
2932 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
2934 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
2935 gen_reserved_instruction(ctx
);
2940 * Verify if floating point register is valid; an operation is not defined
2941 * if bit 0 of any register specification is set and the FR bit in the
2942 * Status register equals zero, since the register numbers specify an
2943 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2944 * in the Status register equals one, both even and odd register numbers
2945 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2947 * Multiple 64 bit wide registers can be checked by calling
2948 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2950 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
2952 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
2953 gen_reserved_instruction(ctx
);
2958 * Verify that the processor is running with DSP instructions enabled.
2959 * This is enabled by CP0 Status register MX(24) bit.
2961 static inline void check_dsp(DisasContext
*ctx
)
2963 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
2964 if (ctx
->insn_flags
& ASE_DSP
) {
2965 generate_exception_end(ctx
, EXCP_DSPDIS
);
2967 gen_reserved_instruction(ctx
);
2972 static inline void check_dsp_r2(DisasContext
*ctx
)
2974 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
2975 if (ctx
->insn_flags
& ASE_DSP
) {
2976 generate_exception_end(ctx
, EXCP_DSPDIS
);
2978 gen_reserved_instruction(ctx
);
2983 static inline void check_dsp_r3(DisasContext
*ctx
)
2985 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
2986 if (ctx
->insn_flags
& ASE_DSP
) {
2987 generate_exception_end(ctx
, EXCP_DSPDIS
);
2989 gen_reserved_instruction(ctx
);
2995 * This code generates a "reserved instruction" exception if the
2996 * CPU does not support the instruction set corresponding to flags.
2998 void check_insn(DisasContext
*ctx
, uint64_t flags
)
3000 if (unlikely(!(ctx
->insn_flags
& flags
))) {
3001 gen_reserved_instruction(ctx
);
3006 * This code generates a "reserved instruction" exception if the
3007 * CPU has corresponding flag set which indicates that the instruction
3010 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
3012 if (unlikely(ctx
->insn_flags
& flags
)) {
3013 gen_reserved_instruction(ctx
);
3018 * The Linux kernel traps certain reserved instruction exceptions to
3019 * emulate the corresponding instructions. QEMU is the kernel in user
3020 * mode, so those traps are emulated by accepting the instructions.
3022 * A reserved instruction exception is generated for flagged CPUs if
3023 * QEMU runs in system mode.
3025 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
3027 #ifndef CONFIG_USER_ONLY
3028 check_insn_opc_removed(ctx
, flags
);
3033 * This code generates a "reserved instruction" exception if the
3034 * CPU does not support 64-bit paired-single (PS) floating point data type.
3036 static inline void check_ps(DisasContext
*ctx
)
3038 if (unlikely(!ctx
->ps
)) {
3039 generate_exception(ctx
, EXCP_RI
);
3041 check_cp1_64bitmode(ctx
);
3044 #ifdef TARGET_MIPS64
3046 * This code generates a "reserved instruction" exception if 64-bit
3047 * instructions are not enabled.
3049 void check_mips_64(DisasContext
*ctx
)
3051 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
))) {
3052 gen_reserved_instruction(ctx
);
3057 #ifndef CONFIG_USER_ONLY
3058 static inline void check_mvh(DisasContext
*ctx
)
3060 if (unlikely(!ctx
->mvh
)) {
3061 generate_exception(ctx
, EXCP_RI
);
3067 * This code generates a "reserved instruction" exception if the
3068 * Config5 XNP bit is set.
3070 static inline void check_xnp(DisasContext
*ctx
)
3072 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
3073 gen_reserved_instruction(ctx
);
3077 #ifndef CONFIG_USER_ONLY
3079 * This code generates a "reserved instruction" exception if the
3080 * Config3 PW bit is NOT set.
3082 static inline void check_pw(DisasContext
*ctx
)
3084 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
3085 gen_reserved_instruction(ctx
);
3091 * This code generates a "reserved instruction" exception if the
3092 * Config3 MT bit is NOT set.
3094 static inline void check_mt(DisasContext
*ctx
)
3096 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3097 gen_reserved_instruction(ctx
);
3101 #ifndef CONFIG_USER_ONLY
3103 * This code generates a "coprocessor unusable" exception if CP0 is not
3104 * available, and, if that is not the case, generates a "reserved instruction"
3105 * exception if the Config5 MT bit is NOT set. This is needed for availability
3106 * control of some of MT ASE instructions.
3108 static inline void check_cp0_mt(DisasContext
*ctx
)
3110 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
3111 generate_exception_end(ctx
, EXCP_CpU
);
3113 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3114 gen_reserved_instruction(ctx
);
3121 * This code generates a "reserved instruction" exception if the
3122 * Config5 NMS bit is set.
3124 static inline void check_nms(DisasContext
*ctx
)
3126 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
3127 gen_reserved_instruction(ctx
);
3132 * This code generates a "reserved instruction" exception if the
3133 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3134 * Config2 TL, and Config5 L2C are unset.
3136 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
3138 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
3139 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
3140 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
3141 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
3142 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
3143 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
3144 gen_reserved_instruction(ctx
);
3149 * This code generates a "reserved instruction" exception if the
3150 * Config5 EVA bit is NOT set.
3152 static inline void check_eva(DisasContext
*ctx
)
3154 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
3155 gen_reserved_instruction(ctx
);
3161 * Define small wrappers for gen_load_fpr* so that we have a uniform
3162 * calling interface for 32 and 64-bit FPRs. No sense in changing
3163 * all callers for gen_load_fpr32 when we need the CTX parameter for
3166 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3167 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3168 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3169 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3170 int ft, int fs, int cc) \
3172 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
3173 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
3182 check_cp1_registers(ctx, fs | ft); \
3190 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
3191 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
3194 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
3197 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
3200 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
3203 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
3206 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
3209 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
3212 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
3215 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
3218 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
3221 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
3224 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
3227 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
3230 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
3233 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
3236 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
3239 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
3244 tcg_temp_free_i##bits(fp0); \
3245 tcg_temp_free_i##bits(fp1); \
3248 FOP_CONDS(, 0, d
, FMT_D
, 64)
3249 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
3250 FOP_CONDS(, 0, s
, FMT_S
, 32)
3251 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
3252 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
3253 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
3256 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3257 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
3258 int ft, int fs, int fd) \
3260 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3261 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3262 if (ifmt == FMT_D) { \
3263 check_cp1_registers(ctx, fs | ft | fd); \
3265 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3266 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3269 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3272 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3275 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3278 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3281 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3284 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3287 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3290 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3293 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3296 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3299 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3302 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3305 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3308 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3311 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3314 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3317 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3320 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3323 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3326 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3329 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3332 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3338 tcg_temp_free_i ## bits(fp0); \
3339 tcg_temp_free_i ## bits(fp1); \
3342 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
3343 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
3345 #undef gen_ldcmp_fpr32
3346 #undef gen_ldcmp_fpr64
3348 /* load/store instructions. */
3349 #ifdef CONFIG_USER_ONLY
3350 #define OP_LD_ATOMIC(insn, fname) \
3351 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3352 DisasContext *ctx) \
3354 TCGv t0 = tcg_temp_new(); \
3355 tcg_gen_mov_tl(t0, arg1); \
3356 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3357 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3358 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3359 tcg_temp_free(t0); \
3362 #define OP_LD_ATOMIC(insn, fname) \
3363 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3364 DisasContext *ctx) \
3366 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3369 OP_LD_ATOMIC(ll
, ld32s
);
3370 #if defined(TARGET_MIPS64)
3371 OP_LD_ATOMIC(lld
, ld64
);
3375 void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
, int base
, int offset
)
3378 tcg_gen_movi_tl(addr
, offset
);
3379 } else if (offset
== 0) {
3380 gen_load_gpr(addr
, base
);
3382 tcg_gen_movi_tl(addr
, offset
);
3383 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
3387 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
3389 target_ulong pc
= ctx
->base
.pc_next
;
3391 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3392 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
3397 pc
&= ~(target_ulong
)3;
3402 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
3403 int rt
, int base
, int offset
)
3406 int mem_idx
= ctx
->mem_idx
;
3408 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
|
3411 * Loongson CPU uses a load to zero register for prefetch.
3412 * We emulate it as a NOP. On other CPU we must perform the
3413 * actual memory access.
3418 t0
= tcg_temp_new();
3419 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3422 #if defined(TARGET_MIPS64)
3424 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
3425 ctx
->default_tcg_memop_mask
);
3426 gen_store_gpr(t0
, rt
);
3429 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
3430 ctx
->default_tcg_memop_mask
);
3431 gen_store_gpr(t0
, rt
);
3435 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
3436 gen_store_gpr(t0
, rt
);
3439 t1
= tcg_temp_new();
3441 * Do a byte access to possibly trigger a page
3442 * fault with the unaligned address.
3444 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3445 tcg_gen_andi_tl(t1
, t0
, 7);
3446 #ifndef TARGET_WORDS_BIGENDIAN
3447 tcg_gen_xori_tl(t1
, t1
, 7);
3449 tcg_gen_shli_tl(t1
, t1
, 3);
3450 tcg_gen_andi_tl(t0
, t0
, ~7);
3451 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3452 tcg_gen_shl_tl(t0
, t0
, t1
);
3453 t2
= tcg_const_tl(-1);
3454 tcg_gen_shl_tl(t2
, t2
, t1
);
3455 gen_load_gpr(t1
, rt
);
3456 tcg_gen_andc_tl(t1
, t1
, t2
);
3458 tcg_gen_or_tl(t0
, t0
, t1
);
3460 gen_store_gpr(t0
, rt
);
3463 t1
= tcg_temp_new();
3465 * Do a byte access to possibly trigger a page
3466 * fault with the unaligned address.
3468 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3469 tcg_gen_andi_tl(t1
, t0
, 7);
3470 #ifdef TARGET_WORDS_BIGENDIAN
3471 tcg_gen_xori_tl(t1
, t1
, 7);
3473 tcg_gen_shli_tl(t1
, t1
, 3);
3474 tcg_gen_andi_tl(t0
, t0
, ~7);
3475 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3476 tcg_gen_shr_tl(t0
, t0
, t1
);
3477 tcg_gen_xori_tl(t1
, t1
, 63);
3478 t2
= tcg_const_tl(0xfffffffffffffffeull
);
3479 tcg_gen_shl_tl(t2
, t2
, t1
);
3480 gen_load_gpr(t1
, rt
);
3481 tcg_gen_and_tl(t1
, t1
, t2
);
3483 tcg_gen_or_tl(t0
, t0
, t1
);
3485 gen_store_gpr(t0
, rt
);
3488 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3489 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3491 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3492 gen_store_gpr(t0
, rt
);
3496 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3497 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3499 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
3500 gen_store_gpr(t0
, rt
);
3503 mem_idx
= MIPS_HFLAG_UM
;
3506 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
3507 ctx
->default_tcg_memop_mask
);
3508 gen_store_gpr(t0
, rt
);
3511 mem_idx
= MIPS_HFLAG_UM
;
3514 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
3515 ctx
->default_tcg_memop_mask
);
3516 gen_store_gpr(t0
, rt
);
3519 mem_idx
= MIPS_HFLAG_UM
;
3522 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
3523 ctx
->default_tcg_memop_mask
);
3524 gen_store_gpr(t0
, rt
);
3527 mem_idx
= MIPS_HFLAG_UM
;
3530 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3531 gen_store_gpr(t0
, rt
);
3534 mem_idx
= MIPS_HFLAG_UM
;
3537 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3538 gen_store_gpr(t0
, rt
);
3541 mem_idx
= MIPS_HFLAG_UM
;
3544 t1
= tcg_temp_new();
3546 * Do a byte access to possibly trigger a page
3547 * fault with the unaligned address.
3549 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3550 tcg_gen_andi_tl(t1
, t0
, 3);
3551 #ifndef TARGET_WORDS_BIGENDIAN
3552 tcg_gen_xori_tl(t1
, t1
, 3);
3554 tcg_gen_shli_tl(t1
, t1
, 3);
3555 tcg_gen_andi_tl(t0
, t0
, ~3);
3556 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3557 tcg_gen_shl_tl(t0
, t0
, t1
);
3558 t2
= tcg_const_tl(-1);
3559 tcg_gen_shl_tl(t2
, t2
, t1
);
3560 gen_load_gpr(t1
, rt
);
3561 tcg_gen_andc_tl(t1
, t1
, t2
);
3563 tcg_gen_or_tl(t0
, t0
, t1
);
3565 tcg_gen_ext32s_tl(t0
, t0
);
3566 gen_store_gpr(t0
, rt
);
3569 mem_idx
= MIPS_HFLAG_UM
;
3572 t1
= tcg_temp_new();
3574 * Do a byte access to possibly trigger a page
3575 * fault with the unaligned address.
3577 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3578 tcg_gen_andi_tl(t1
, t0
, 3);
3579 #ifdef TARGET_WORDS_BIGENDIAN
3580 tcg_gen_xori_tl(t1
, t1
, 3);
3582 tcg_gen_shli_tl(t1
, t1
, 3);
3583 tcg_gen_andi_tl(t0
, t0
, ~3);
3584 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3585 tcg_gen_shr_tl(t0
, t0
, t1
);
3586 tcg_gen_xori_tl(t1
, t1
, 31);
3587 t2
= tcg_const_tl(0xfffffffeull
);
3588 tcg_gen_shl_tl(t2
, t2
, t1
);
3589 gen_load_gpr(t1
, rt
);
3590 tcg_gen_and_tl(t1
, t1
, t2
);
3592 tcg_gen_or_tl(t0
, t0
, t1
);
3594 tcg_gen_ext32s_tl(t0
, t0
);
3595 gen_store_gpr(t0
, rt
);
3598 mem_idx
= MIPS_HFLAG_UM
;
3602 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3603 gen_store_gpr(t0
, rt
);
3609 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3610 uint32_t reg1
, uint32_t reg2
)
3612 TCGv taddr
= tcg_temp_new();
3613 TCGv_i64 tval
= tcg_temp_new_i64();
3614 TCGv tmp1
= tcg_temp_new();
3615 TCGv tmp2
= tcg_temp_new();
3617 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3618 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3619 #ifdef TARGET_WORDS_BIGENDIAN
3620 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3622 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3624 gen_store_gpr(tmp1
, reg1
);
3625 tcg_temp_free(tmp1
);
3626 gen_store_gpr(tmp2
, reg2
);
3627 tcg_temp_free(tmp2
);
3628 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3629 tcg_temp_free_i64(tval
);
3630 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3631 tcg_temp_free(taddr
);
3635 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3636 int base
, int offset
)
3638 TCGv t0
= tcg_temp_new();
3639 TCGv t1
= tcg_temp_new();
3640 int mem_idx
= ctx
->mem_idx
;
3642 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3643 gen_load_gpr(t1
, rt
);
3645 #if defined(TARGET_MIPS64)
3647 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3648 ctx
->default_tcg_memop_mask
);
3651 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3654 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3658 mem_idx
= MIPS_HFLAG_UM
;
3661 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3662 ctx
->default_tcg_memop_mask
);
3665 mem_idx
= MIPS_HFLAG_UM
;
3668 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3669 ctx
->default_tcg_memop_mask
);
3672 mem_idx
= MIPS_HFLAG_UM
;
3675 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3678 mem_idx
= MIPS_HFLAG_UM
;
3681 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3684 mem_idx
= MIPS_HFLAG_UM
;
3687 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3695 /* Store conditional */
3696 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3697 MemOp tcg_mo
, bool eva
)
3700 TCGLabel
*l1
= gen_new_label();
3701 TCGLabel
*done
= gen_new_label();
3703 t0
= tcg_temp_new();
3704 addr
= tcg_temp_new();
3705 /* compare the address against that of the preceding LL */
3706 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3707 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3708 tcg_temp_free(addr
);
3709 tcg_gen_movi_tl(t0
, 0);
3710 gen_store_gpr(t0
, rt
);
3714 /* generate cmpxchg */
3715 val
= tcg_temp_new();
3716 gen_load_gpr(val
, rt
);
3717 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3718 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3719 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3720 gen_store_gpr(t0
, rt
);
3723 gen_set_label(done
);
3728 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3729 uint32_t reg1
, uint32_t reg2
, bool eva
)
3731 TCGv taddr
= tcg_temp_local_new();
3732 TCGv lladdr
= tcg_temp_local_new();
3733 TCGv_i64 tval
= tcg_temp_new_i64();
3734 TCGv_i64 llval
= tcg_temp_new_i64();
3735 TCGv_i64 val
= tcg_temp_new_i64();
3736 TCGv tmp1
= tcg_temp_new();
3737 TCGv tmp2
= tcg_temp_new();
3738 TCGLabel
*lab_fail
= gen_new_label();
3739 TCGLabel
*lab_done
= gen_new_label();
3741 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3743 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3744 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3746 gen_load_gpr(tmp1
, reg1
);
3747 gen_load_gpr(tmp2
, reg2
);
3749 #ifdef TARGET_WORDS_BIGENDIAN
3750 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3752 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3755 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3756 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3757 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3759 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3761 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3763 gen_set_label(lab_fail
);
3766 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3768 gen_set_label(lab_done
);
3769 tcg_gen_movi_tl(lladdr
, -1);
3770 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3773 /* Load and store */
3774 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3778 * Don't do NOP if destination is zero: we must perform the actual
3784 TCGv_i32 fp0
= tcg_temp_new_i32();
3785 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3786 ctx
->default_tcg_memop_mask
);
3787 gen_store_fpr32(ctx
, fp0
, ft
);
3788 tcg_temp_free_i32(fp0
);
3793 TCGv_i32 fp0
= tcg_temp_new_i32();
3794 gen_load_fpr32(ctx
, fp0
, ft
);
3795 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3796 ctx
->default_tcg_memop_mask
);
3797 tcg_temp_free_i32(fp0
);
3802 TCGv_i64 fp0
= tcg_temp_new_i64();
3803 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3804 ctx
->default_tcg_memop_mask
);
3805 gen_store_fpr64(ctx
, fp0
, ft
);
3806 tcg_temp_free_i64(fp0
);
3811 TCGv_i64 fp0
= tcg_temp_new_i64();
3812 gen_load_fpr64(ctx
, fp0
, ft
);
3813 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3814 ctx
->default_tcg_memop_mask
);
3815 tcg_temp_free_i64(fp0
);
3819 MIPS_INVAL("flt_ldst");
3820 gen_reserved_instruction(ctx
);
3825 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3826 int rs
, int16_t imm
)
3828 TCGv t0
= tcg_temp_new();
3830 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3831 check_cp1_enabled(ctx
);
3835 check_insn(ctx
, ISA_MIPS2
);
3838 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3839 gen_flt_ldst(ctx
, op
, rt
, t0
);
3842 generate_exception_err(ctx
, EXCP_CpU
, 1);
3847 /* Arithmetic with immediate operand */
3848 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3849 int rt
, int rs
, int imm
)
3851 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3853 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3855 * If no destination, treat it as a NOP.
3856 * For addi, we must generate the overflow exception when needed.
3863 TCGv t0
= tcg_temp_local_new();
3864 TCGv t1
= tcg_temp_new();
3865 TCGv t2
= tcg_temp_new();
3866 TCGLabel
*l1
= gen_new_label();
3868 gen_load_gpr(t1
, rs
);
3869 tcg_gen_addi_tl(t0
, t1
, uimm
);
3870 tcg_gen_ext32s_tl(t0
, t0
);
3872 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3873 tcg_gen_xori_tl(t2
, t0
, uimm
);
3874 tcg_gen_and_tl(t1
, t1
, t2
);
3876 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3878 /* operands of same sign, result different sign */
3879 generate_exception(ctx
, EXCP_OVERFLOW
);
3881 tcg_gen_ext32s_tl(t0
, t0
);
3882 gen_store_gpr(t0
, rt
);
3888 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3889 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3891 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3894 #if defined(TARGET_MIPS64)
3897 TCGv t0
= tcg_temp_local_new();
3898 TCGv t1
= tcg_temp_new();
3899 TCGv t2
= tcg_temp_new();
3900 TCGLabel
*l1
= gen_new_label();
3902 gen_load_gpr(t1
, rs
);
3903 tcg_gen_addi_tl(t0
, t1
, uimm
);
3905 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3906 tcg_gen_xori_tl(t2
, t0
, uimm
);
3907 tcg_gen_and_tl(t1
, t1
, t2
);
3909 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3911 /* operands of same sign, result different sign */
3912 generate_exception(ctx
, EXCP_OVERFLOW
);
3914 gen_store_gpr(t0
, rt
);
3920 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3922 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3929 /* Logic with immediate operand */
3930 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3931 int rt
, int rs
, int16_t imm
)
3936 /* If no destination, treat it as a NOP. */
3939 uimm
= (uint16_t)imm
;
3942 if (likely(rs
!= 0)) {
3943 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3945 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
3950 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3952 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3956 if (likely(rs
!= 0)) {
3957 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3959 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3963 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS_R6
)) {
3965 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
3966 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3968 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
3977 /* Set on less than with immediate operand */
3978 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
3979 int rt
, int rs
, int16_t imm
)
3981 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3985 /* If no destination, treat it as a NOP. */
3988 t0
= tcg_temp_new();
3989 gen_load_gpr(t0
, rs
);
3992 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
3995 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
4001 /* Shifts with immediate operand */
4002 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
4003 int rt
, int rs
, int16_t imm
)
4005 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
4009 /* If no destination, treat it as a NOP. */
4013 t0
= tcg_temp_new();
4014 gen_load_gpr(t0
, rs
);
4017 tcg_gen_shli_tl(t0
, t0
, uimm
);
4018 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4021 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4025 tcg_gen_ext32u_tl(t0
, t0
);
4026 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4028 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4033 TCGv_i32 t1
= tcg_temp_new_i32();
4035 tcg_gen_trunc_tl_i32(t1
, t0
);
4036 tcg_gen_rotri_i32(t1
, t1
, uimm
);
4037 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
4038 tcg_temp_free_i32(t1
);
4040 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4043 #if defined(TARGET_MIPS64)
4045 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
4048 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4051 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4055 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
4057 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
4061 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4064 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4067 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4070 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4078 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
4079 int rd
, int rs
, int rt
)
4081 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
4082 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
4084 * If no destination, treat it as a NOP.
4085 * For add & sub, we must generate the overflow exception when needed.
4093 TCGv t0
= tcg_temp_local_new();
4094 TCGv t1
= tcg_temp_new();
4095 TCGv t2
= tcg_temp_new();
4096 TCGLabel
*l1
= gen_new_label();
4098 gen_load_gpr(t1
, rs
);
4099 gen_load_gpr(t2
, rt
);
4100 tcg_gen_add_tl(t0
, t1
, t2
);
4101 tcg_gen_ext32s_tl(t0
, t0
);
4102 tcg_gen_xor_tl(t1
, t1
, t2
);
4103 tcg_gen_xor_tl(t2
, t0
, t2
);
4104 tcg_gen_andc_tl(t1
, t2
, t1
);
4106 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4108 /* operands of same sign, result different sign */
4109 generate_exception(ctx
, EXCP_OVERFLOW
);
4111 gen_store_gpr(t0
, rd
);
4116 if (rs
!= 0 && rt
!= 0) {
4117 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4118 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4119 } else if (rs
== 0 && rt
!= 0) {
4120 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4121 } else if (rs
!= 0 && rt
== 0) {
4122 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4124 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4129 TCGv t0
= tcg_temp_local_new();
4130 TCGv t1
= tcg_temp_new();
4131 TCGv t2
= tcg_temp_new();
4132 TCGLabel
*l1
= gen_new_label();
4134 gen_load_gpr(t1
, rs
);
4135 gen_load_gpr(t2
, rt
);
4136 tcg_gen_sub_tl(t0
, t1
, t2
);
4137 tcg_gen_ext32s_tl(t0
, t0
);
4138 tcg_gen_xor_tl(t2
, t1
, t2
);
4139 tcg_gen_xor_tl(t1
, t0
, t1
);
4140 tcg_gen_and_tl(t1
, t1
, t2
);
4142 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4145 * operands of different sign, first operand and the result
4148 generate_exception(ctx
, EXCP_OVERFLOW
);
4150 gen_store_gpr(t0
, rd
);
4155 if (rs
!= 0 && rt
!= 0) {
4156 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4157 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4158 } else if (rs
== 0 && rt
!= 0) {
4159 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4160 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4161 } else if (rs
!= 0 && rt
== 0) {
4162 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4164 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4167 #if defined(TARGET_MIPS64)
4170 TCGv t0
= tcg_temp_local_new();
4171 TCGv t1
= tcg_temp_new();
4172 TCGv t2
= tcg_temp_new();
4173 TCGLabel
*l1
= gen_new_label();
4175 gen_load_gpr(t1
, rs
);
4176 gen_load_gpr(t2
, rt
);
4177 tcg_gen_add_tl(t0
, t1
, t2
);
4178 tcg_gen_xor_tl(t1
, t1
, t2
);
4179 tcg_gen_xor_tl(t2
, t0
, t2
);
4180 tcg_gen_andc_tl(t1
, t2
, t1
);
4182 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4184 /* operands of same sign, result different sign */
4185 generate_exception(ctx
, EXCP_OVERFLOW
);
4187 gen_store_gpr(t0
, rd
);
4192 if (rs
!= 0 && rt
!= 0) {
4193 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4194 } else if (rs
== 0 && rt
!= 0) {
4195 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4196 } else if (rs
!= 0 && rt
== 0) {
4197 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4199 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4204 TCGv t0
= tcg_temp_local_new();
4205 TCGv t1
= tcg_temp_new();
4206 TCGv t2
= tcg_temp_new();
4207 TCGLabel
*l1
= gen_new_label();
4209 gen_load_gpr(t1
, rs
);
4210 gen_load_gpr(t2
, rt
);
4211 tcg_gen_sub_tl(t0
, t1
, t2
);
4212 tcg_gen_xor_tl(t2
, t1
, t2
);
4213 tcg_gen_xor_tl(t1
, t0
, t1
);
4214 tcg_gen_and_tl(t1
, t1
, t2
);
4216 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4219 * Operands of different sign, first operand and result different
4222 generate_exception(ctx
, EXCP_OVERFLOW
);
4224 gen_store_gpr(t0
, rd
);
4229 if (rs
!= 0 && rt
!= 0) {
4230 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4231 } else if (rs
== 0 && rt
!= 0) {
4232 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4233 } else if (rs
!= 0 && rt
== 0) {
4234 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4236 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4241 if (likely(rs
!= 0 && rt
!= 0)) {
4242 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4243 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4245 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4251 /* Conditional move */
4252 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
4253 int rd
, int rs
, int rt
)
4258 /* If no destination, treat it as a NOP. */
4262 t0
= tcg_temp_new();
4263 gen_load_gpr(t0
, rt
);
4264 t1
= tcg_const_tl(0);
4265 t2
= tcg_temp_new();
4266 gen_load_gpr(t2
, rs
);
4269 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4272 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4275 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4278 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4287 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
4288 int rd
, int rs
, int rt
)
4291 /* If no destination, treat it as a NOP. */
4297 if (likely(rs
!= 0 && rt
!= 0)) {
4298 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4300 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4304 if (rs
!= 0 && rt
!= 0) {
4305 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4306 } else if (rs
== 0 && rt
!= 0) {
4307 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4308 } else if (rs
!= 0 && rt
== 0) {
4309 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4311 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
4315 if (likely(rs
!= 0 && rt
!= 0)) {
4316 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4317 } else if (rs
== 0 && rt
!= 0) {
4318 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4319 } else if (rs
!= 0 && rt
== 0) {
4320 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4322 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4326 if (likely(rs
!= 0 && rt
!= 0)) {
4327 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4328 } else if (rs
== 0 && rt
!= 0) {
4329 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4330 } else if (rs
!= 0 && rt
== 0) {
4331 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4333 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4339 /* Set on lower than */
4340 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
4341 int rd
, int rs
, int rt
)
4346 /* If no destination, treat it as a NOP. */
4350 t0
= tcg_temp_new();
4351 t1
= tcg_temp_new();
4352 gen_load_gpr(t0
, rs
);
4353 gen_load_gpr(t1
, rt
);
4356 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
4359 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
4367 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
4368 int rd
, int rs
, int rt
)
4374 * If no destination, treat it as a NOP.
4375 * For add & sub, we must generate the overflow exception when needed.
4380 t0
= tcg_temp_new();
4381 t1
= tcg_temp_new();
4382 gen_load_gpr(t0
, rs
);
4383 gen_load_gpr(t1
, rt
);
4386 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4387 tcg_gen_shl_tl(t0
, t1
, t0
);
4388 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4391 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4392 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4395 tcg_gen_ext32u_tl(t1
, t1
);
4396 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4397 tcg_gen_shr_tl(t0
, t1
, t0
);
4398 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4402 TCGv_i32 t2
= tcg_temp_new_i32();
4403 TCGv_i32 t3
= tcg_temp_new_i32();
4405 tcg_gen_trunc_tl_i32(t2
, t0
);
4406 tcg_gen_trunc_tl_i32(t3
, t1
);
4407 tcg_gen_andi_i32(t2
, t2
, 0x1f);
4408 tcg_gen_rotr_i32(t2
, t3
, t2
);
4409 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4410 tcg_temp_free_i32(t2
);
4411 tcg_temp_free_i32(t3
);
4414 #if defined(TARGET_MIPS64)
4416 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4417 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
4420 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4421 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4424 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4425 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
4428 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4429 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
4437 #if defined(TARGET_MIPS64)
4438 /* Copy GPR to and from TX79 HI1/LO1 register. */
4439 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
4441 if (reg
== 0 && (opc
== MMI_OPC_MFHI1
|| opc
== MMI_OPC_MFLO1
)) {
4448 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[1]);
4451 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[1]);
4455 tcg_gen_mov_tl(cpu_HI
[1], cpu_gpr
[reg
]);
4457 tcg_gen_movi_tl(cpu_HI
[1], 0);
4462 tcg_gen_mov_tl(cpu_LO
[1], cpu_gpr
[reg
]);
4464 tcg_gen_movi_tl(cpu_LO
[1], 0);
4468 MIPS_INVAL("mfthilo1 TX79");
4469 gen_reserved_instruction(ctx
);
4475 /* Arithmetic on HI/LO registers */
4476 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
4478 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
4489 #if defined(TARGET_MIPS64)
4491 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4495 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4499 #if defined(TARGET_MIPS64)
4501 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4505 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4510 #if defined(TARGET_MIPS64)
4512 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4516 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4519 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
4524 #if defined(TARGET_MIPS64)
4526 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4530 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4533 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4539 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4542 TCGv t0
= tcg_const_tl(addr
);
4543 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4544 gen_store_gpr(t0
, reg
);
4548 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4554 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4557 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4558 addr
= addr_add(ctx
, pc
, offset
);
4559 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4563 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4564 addr
= addr_add(ctx
, pc
, offset
);
4565 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4567 #if defined(TARGET_MIPS64)
4570 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4571 addr
= addr_add(ctx
, pc
, offset
);
4572 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4576 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4579 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4580 addr
= addr_add(ctx
, pc
, offset
);
4581 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4586 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4587 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4588 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4591 #if defined(TARGET_MIPS64)
4592 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4593 case R6_OPC_LDPC
+ (1 << 16):
4594 case R6_OPC_LDPC
+ (2 << 16):
4595 case R6_OPC_LDPC
+ (3 << 16):
4597 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4598 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4599 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4603 MIPS_INVAL("OPC_PCREL");
4604 gen_reserved_instruction(ctx
);
4611 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4620 t0
= tcg_temp_new();
4621 t1
= tcg_temp_new();
4623 gen_load_gpr(t0
, rs
);
4624 gen_load_gpr(t1
, rt
);
4629 TCGv t2
= tcg_temp_new();
4630 TCGv t3
= tcg_temp_new();
4631 tcg_gen_ext32s_tl(t0
, t0
);
4632 tcg_gen_ext32s_tl(t1
, t1
);
4633 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4634 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4635 tcg_gen_and_tl(t2
, t2
, t3
);
4636 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4637 tcg_gen_or_tl(t2
, t2
, t3
);
4638 tcg_gen_movi_tl(t3
, 0);
4639 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4640 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4641 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4648 TCGv t2
= tcg_temp_new();
4649 TCGv t3
= tcg_temp_new();
4650 tcg_gen_ext32s_tl(t0
, t0
);
4651 tcg_gen_ext32s_tl(t1
, t1
);
4652 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4653 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4654 tcg_gen_and_tl(t2
, t2
, t3
);
4655 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4656 tcg_gen_or_tl(t2
, t2
, t3
);
4657 tcg_gen_movi_tl(t3
, 0);
4658 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4659 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4660 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4667 TCGv t2
= tcg_const_tl(0);
4668 TCGv t3
= tcg_const_tl(1);
4669 tcg_gen_ext32u_tl(t0
, t0
);
4670 tcg_gen_ext32u_tl(t1
, t1
);
4671 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4672 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4673 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4680 TCGv t2
= tcg_const_tl(0);
4681 TCGv t3
= tcg_const_tl(1);
4682 tcg_gen_ext32u_tl(t0
, t0
);
4683 tcg_gen_ext32u_tl(t1
, t1
);
4684 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4685 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4686 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4693 TCGv_i32 t2
= tcg_temp_new_i32();
4694 TCGv_i32 t3
= tcg_temp_new_i32();
4695 tcg_gen_trunc_tl_i32(t2
, t0
);
4696 tcg_gen_trunc_tl_i32(t3
, t1
);
4697 tcg_gen_mul_i32(t2
, t2
, t3
);
4698 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4699 tcg_temp_free_i32(t2
);
4700 tcg_temp_free_i32(t3
);
4705 TCGv_i32 t2
= tcg_temp_new_i32();
4706 TCGv_i32 t3
= tcg_temp_new_i32();
4707 tcg_gen_trunc_tl_i32(t2
, t0
);
4708 tcg_gen_trunc_tl_i32(t3
, t1
);
4709 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4710 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4711 tcg_temp_free_i32(t2
);
4712 tcg_temp_free_i32(t3
);
4717 TCGv_i32 t2
= tcg_temp_new_i32();
4718 TCGv_i32 t3
= tcg_temp_new_i32();
4719 tcg_gen_trunc_tl_i32(t2
, t0
);
4720 tcg_gen_trunc_tl_i32(t3
, t1
);
4721 tcg_gen_mul_i32(t2
, t2
, t3
);
4722 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4723 tcg_temp_free_i32(t2
);
4724 tcg_temp_free_i32(t3
);
4729 TCGv_i32 t2
= tcg_temp_new_i32();
4730 TCGv_i32 t3
= tcg_temp_new_i32();
4731 tcg_gen_trunc_tl_i32(t2
, t0
);
4732 tcg_gen_trunc_tl_i32(t3
, t1
);
4733 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4734 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4735 tcg_temp_free_i32(t2
);
4736 tcg_temp_free_i32(t3
);
4739 #if defined(TARGET_MIPS64)
4742 TCGv t2
= tcg_temp_new();
4743 TCGv t3
= tcg_temp_new();
4744 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4745 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4746 tcg_gen_and_tl(t2
, t2
, t3
);
4747 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4748 tcg_gen_or_tl(t2
, t2
, t3
);
4749 tcg_gen_movi_tl(t3
, 0);
4750 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4751 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4758 TCGv t2
= tcg_temp_new();
4759 TCGv t3
= tcg_temp_new();
4760 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4761 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4762 tcg_gen_and_tl(t2
, t2
, t3
);
4763 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4764 tcg_gen_or_tl(t2
, t2
, t3
);
4765 tcg_gen_movi_tl(t3
, 0);
4766 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4767 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4774 TCGv t2
= tcg_const_tl(0);
4775 TCGv t3
= tcg_const_tl(1);
4776 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4777 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4784 TCGv t2
= tcg_const_tl(0);
4785 TCGv t3
= tcg_const_tl(1);
4786 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4787 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4793 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4797 TCGv t2
= tcg_temp_new();
4798 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4803 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4807 TCGv t2
= tcg_temp_new();
4808 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4814 MIPS_INVAL("r6 mul/div");
4815 gen_reserved_instruction(ctx
);
4823 #if defined(TARGET_MIPS64)
4824 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4828 t0
= tcg_temp_new();
4829 t1
= tcg_temp_new();
4831 gen_load_gpr(t0
, rs
);
4832 gen_load_gpr(t1
, rt
);
4837 TCGv t2
= tcg_temp_new();
4838 TCGv t3
= tcg_temp_new();
4839 tcg_gen_ext32s_tl(t0
, t0
);
4840 tcg_gen_ext32s_tl(t1
, t1
);
4841 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4842 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4843 tcg_gen_and_tl(t2
, t2
, t3
);
4844 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4845 tcg_gen_or_tl(t2
, t2
, t3
);
4846 tcg_gen_movi_tl(t3
, 0);
4847 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4848 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4849 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4850 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4851 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4858 TCGv t2
= tcg_const_tl(0);
4859 TCGv t3
= tcg_const_tl(1);
4860 tcg_gen_ext32u_tl(t0
, t0
);
4861 tcg_gen_ext32u_tl(t1
, t1
);
4862 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4863 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4864 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4865 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4866 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4872 MIPS_INVAL("div1 TX79");
4873 gen_reserved_instruction(ctx
);
4882 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4883 int acc
, int rs
, int rt
)
4887 t0
= tcg_temp_new();
4888 t1
= tcg_temp_new();
4890 gen_load_gpr(t0
, rs
);
4891 gen_load_gpr(t1
, rt
);
4900 TCGv t2
= tcg_temp_new();
4901 TCGv t3
= tcg_temp_new();
4902 tcg_gen_ext32s_tl(t0
, t0
);
4903 tcg_gen_ext32s_tl(t1
, t1
);
4904 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4905 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4906 tcg_gen_and_tl(t2
, t2
, t3
);
4907 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4908 tcg_gen_or_tl(t2
, t2
, t3
);
4909 tcg_gen_movi_tl(t3
, 0);
4910 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4911 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4912 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4913 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4914 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4921 TCGv t2
= tcg_const_tl(0);
4922 TCGv t3
= tcg_const_tl(1);
4923 tcg_gen_ext32u_tl(t0
, t0
);
4924 tcg_gen_ext32u_tl(t1
, t1
);
4925 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4926 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4927 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4928 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4929 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4936 TCGv_i32 t2
= tcg_temp_new_i32();
4937 TCGv_i32 t3
= tcg_temp_new_i32();
4938 tcg_gen_trunc_tl_i32(t2
, t0
);
4939 tcg_gen_trunc_tl_i32(t3
, t1
);
4940 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4941 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4942 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4943 tcg_temp_free_i32(t2
);
4944 tcg_temp_free_i32(t3
);
4949 TCGv_i32 t2
= tcg_temp_new_i32();
4950 TCGv_i32 t3
= tcg_temp_new_i32();
4951 tcg_gen_trunc_tl_i32(t2
, t0
);
4952 tcg_gen_trunc_tl_i32(t3
, t1
);
4953 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4954 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4955 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4956 tcg_temp_free_i32(t2
);
4957 tcg_temp_free_i32(t3
);
4960 #if defined(TARGET_MIPS64)
4963 TCGv t2
= tcg_temp_new();
4964 TCGv t3
= tcg_temp_new();
4965 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4966 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4967 tcg_gen_and_tl(t2
, t2
, t3
);
4968 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4969 tcg_gen_or_tl(t2
, t2
, t3
);
4970 tcg_gen_movi_tl(t3
, 0);
4971 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4972 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4973 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4980 TCGv t2
= tcg_const_tl(0);
4981 TCGv t3
= tcg_const_tl(1);
4982 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4983 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
4984 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
4990 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4993 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
4998 TCGv_i64 t2
= tcg_temp_new_i64();
4999 TCGv_i64 t3
= tcg_temp_new_i64();
5001 tcg_gen_ext_tl_i64(t2
, t0
);
5002 tcg_gen_ext_tl_i64(t3
, t1
);
5003 tcg_gen_mul_i64(t2
, t2
, t3
);
5004 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5005 tcg_gen_add_i64(t2
, t2
, t3
);
5006 tcg_temp_free_i64(t3
);
5007 gen_move_low32(cpu_LO
[acc
], t2
);
5008 gen_move_high32(cpu_HI
[acc
], t2
);
5009 tcg_temp_free_i64(t2
);
5014 TCGv_i64 t2
= tcg_temp_new_i64();
5015 TCGv_i64 t3
= tcg_temp_new_i64();
5017 tcg_gen_ext32u_tl(t0
, t0
);
5018 tcg_gen_ext32u_tl(t1
, t1
);
5019 tcg_gen_extu_tl_i64(t2
, t0
);
5020 tcg_gen_extu_tl_i64(t3
, t1
);
5021 tcg_gen_mul_i64(t2
, t2
, t3
);
5022 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5023 tcg_gen_add_i64(t2
, t2
, t3
);
5024 tcg_temp_free_i64(t3
);
5025 gen_move_low32(cpu_LO
[acc
], t2
);
5026 gen_move_high32(cpu_HI
[acc
], t2
);
5027 tcg_temp_free_i64(t2
);
5032 TCGv_i64 t2
= tcg_temp_new_i64();
5033 TCGv_i64 t3
= tcg_temp_new_i64();
5035 tcg_gen_ext_tl_i64(t2
, t0
);
5036 tcg_gen_ext_tl_i64(t3
, t1
);
5037 tcg_gen_mul_i64(t2
, t2
, t3
);
5038 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5039 tcg_gen_sub_i64(t2
, t3
, t2
);
5040 tcg_temp_free_i64(t3
);
5041 gen_move_low32(cpu_LO
[acc
], t2
);
5042 gen_move_high32(cpu_HI
[acc
], t2
);
5043 tcg_temp_free_i64(t2
);
5048 TCGv_i64 t2
= tcg_temp_new_i64();
5049 TCGv_i64 t3
= tcg_temp_new_i64();
5051 tcg_gen_ext32u_tl(t0
, t0
);
5052 tcg_gen_ext32u_tl(t1
, t1
);
5053 tcg_gen_extu_tl_i64(t2
, t0
);
5054 tcg_gen_extu_tl_i64(t3
, t1
);
5055 tcg_gen_mul_i64(t2
, t2
, t3
);
5056 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5057 tcg_gen_sub_i64(t2
, t3
, t2
);
5058 tcg_temp_free_i64(t3
);
5059 gen_move_low32(cpu_LO
[acc
], t2
);
5060 gen_move_high32(cpu_HI
[acc
], t2
);
5061 tcg_temp_free_i64(t2
);
5065 MIPS_INVAL("mul/div");
5066 gen_reserved_instruction(ctx
);
5075 * These MULT[U] and MADD[U] instructions implemented in for example
5076 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5077 * architectures are special three-operand variants with the syntax
5079 * MULT[U][1] rd, rs, rt
5083 * (rd, LO, HI) <- rs * rt
5087 * MADD[U][1] rd, rs, rt
5091 * (rd, LO, HI) <- (LO, HI) + rs * rt
5093 * where the low-order 32-bits of the result is placed into both the
5094 * GPR rd and the special register LO. The high-order 32-bits of the
5095 * result is placed into the special register HI.
5097 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5098 * which is the zero register that always reads as 0.
5100 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
5101 int rd
, int rs
, int rt
)
5103 TCGv t0
= tcg_temp_new();
5104 TCGv t1
= tcg_temp_new();
5107 gen_load_gpr(t0
, rs
);
5108 gen_load_gpr(t1
, rt
);
5116 TCGv_i32 t2
= tcg_temp_new_i32();
5117 TCGv_i32 t3
= tcg_temp_new_i32();
5118 tcg_gen_trunc_tl_i32(t2
, t0
);
5119 tcg_gen_trunc_tl_i32(t3
, t1
);
5120 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
5122 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5124 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5125 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5126 tcg_temp_free_i32(t2
);
5127 tcg_temp_free_i32(t3
);
5130 case MMI_OPC_MULTU1
:
5135 TCGv_i32 t2
= tcg_temp_new_i32();
5136 TCGv_i32 t3
= tcg_temp_new_i32();
5137 tcg_gen_trunc_tl_i32(t2
, t0
);
5138 tcg_gen_trunc_tl_i32(t3
, t1
);
5139 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
5141 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5143 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5144 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5145 tcg_temp_free_i32(t2
);
5146 tcg_temp_free_i32(t3
);
5154 TCGv_i64 t2
= tcg_temp_new_i64();
5155 TCGv_i64 t3
= tcg_temp_new_i64();
5157 tcg_gen_ext_tl_i64(t2
, t0
);
5158 tcg_gen_ext_tl_i64(t3
, t1
);
5159 tcg_gen_mul_i64(t2
, t2
, t3
);
5160 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5161 tcg_gen_add_i64(t2
, t2
, t3
);
5162 tcg_temp_free_i64(t3
);
5163 gen_move_low32(cpu_LO
[acc
], t2
);
5164 gen_move_high32(cpu_HI
[acc
], t2
);
5166 gen_move_low32(cpu_gpr
[rd
], t2
);
5168 tcg_temp_free_i64(t2
);
5171 case MMI_OPC_MADDU1
:
5176 TCGv_i64 t2
= tcg_temp_new_i64();
5177 TCGv_i64 t3
= tcg_temp_new_i64();
5179 tcg_gen_ext32u_tl(t0
, t0
);
5180 tcg_gen_ext32u_tl(t1
, t1
);
5181 tcg_gen_extu_tl_i64(t2
, t0
);
5182 tcg_gen_extu_tl_i64(t3
, t1
);
5183 tcg_gen_mul_i64(t2
, t2
, t3
);
5184 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5185 tcg_gen_add_i64(t2
, t2
, t3
);
5186 tcg_temp_free_i64(t3
);
5187 gen_move_low32(cpu_LO
[acc
], t2
);
5188 gen_move_high32(cpu_HI
[acc
], t2
);
5190 gen_move_low32(cpu_gpr
[rd
], t2
);
5192 tcg_temp_free_i64(t2
);
5196 MIPS_INVAL("mul/madd TXx9");
5197 gen_reserved_instruction(ctx
);
5206 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
5207 int rd
, int rs
, int rt
)
5209 TCGv t0
= tcg_temp_new();
5210 TCGv t1
= tcg_temp_new();
5212 gen_load_gpr(t0
, rs
);
5213 gen_load_gpr(t1
, rt
);
5216 case OPC_VR54XX_MULS
:
5217 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
5219 case OPC_VR54XX_MULSU
:
5220 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
5222 case OPC_VR54XX_MACC
:
5223 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
5225 case OPC_VR54XX_MACCU
:
5226 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
5228 case OPC_VR54XX_MSAC
:
5229 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
5231 case OPC_VR54XX_MSACU
:
5232 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
5234 case OPC_VR54XX_MULHI
:
5235 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
5237 case OPC_VR54XX_MULHIU
:
5238 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
5240 case OPC_VR54XX_MULSHI
:
5241 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
5243 case OPC_VR54XX_MULSHIU
:
5244 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
5246 case OPC_VR54XX_MACCHI
:
5247 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
5249 case OPC_VR54XX_MACCHIU
:
5250 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
5252 case OPC_VR54XX_MSACHI
:
5253 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
5255 case OPC_VR54XX_MSACHIU
:
5256 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
5259 MIPS_INVAL("mul vr54xx");
5260 gen_reserved_instruction(ctx
);
5263 gen_store_gpr(t0
, rd
);
5270 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
5280 gen_load_gpr(t0
, rs
);
5285 #if defined(TARGET_MIPS64)
5289 tcg_gen_not_tl(t0
, t0
);
5298 tcg_gen_ext32u_tl(t0
, t0
);
5299 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
5300 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
5302 #if defined(TARGET_MIPS64)
5307 tcg_gen_clzi_i64(t0
, t0
, 64);
5313 /* Godson integer instructions */
5314 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
5315 int rd
, int rs
, int rt
)
5327 case OPC_MULTU_G_2E
:
5328 case OPC_MULTU_G_2F
:
5329 #if defined(TARGET_MIPS64)
5330 case OPC_DMULT_G_2E
:
5331 case OPC_DMULT_G_2F
:
5332 case OPC_DMULTU_G_2E
:
5333 case OPC_DMULTU_G_2F
:
5335 t0
= tcg_temp_new();
5336 t1
= tcg_temp_new();
5339 t0
= tcg_temp_local_new();
5340 t1
= tcg_temp_local_new();
5344 gen_load_gpr(t0
, rs
);
5345 gen_load_gpr(t1
, rt
);
5350 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5351 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5353 case OPC_MULTU_G_2E
:
5354 case OPC_MULTU_G_2F
:
5355 tcg_gen_ext32u_tl(t0
, t0
);
5356 tcg_gen_ext32u_tl(t1
, t1
);
5357 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5358 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5363 TCGLabel
*l1
= gen_new_label();
5364 TCGLabel
*l2
= gen_new_label();
5365 TCGLabel
*l3
= gen_new_label();
5366 tcg_gen_ext32s_tl(t0
, t0
);
5367 tcg_gen_ext32s_tl(t1
, t1
);
5368 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5369 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5372 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5373 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5374 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5377 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5378 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5385 TCGLabel
*l1
= gen_new_label();
5386 TCGLabel
*l2
= gen_new_label();
5387 tcg_gen_ext32u_tl(t0
, t0
);
5388 tcg_gen_ext32u_tl(t1
, t1
);
5389 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5390 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5393 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5394 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5401 TCGLabel
*l1
= gen_new_label();
5402 TCGLabel
*l2
= gen_new_label();
5403 TCGLabel
*l3
= gen_new_label();
5404 tcg_gen_ext32u_tl(t0
, t0
);
5405 tcg_gen_ext32u_tl(t1
, t1
);
5406 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5407 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5408 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5410 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5413 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5414 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5421 TCGLabel
*l1
= gen_new_label();
5422 TCGLabel
*l2
= gen_new_label();
5423 tcg_gen_ext32u_tl(t0
, t0
);
5424 tcg_gen_ext32u_tl(t1
, t1
);
5425 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5426 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5429 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5430 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5434 #if defined(TARGET_MIPS64)
5435 case OPC_DMULT_G_2E
:
5436 case OPC_DMULT_G_2F
:
5437 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5439 case OPC_DMULTU_G_2E
:
5440 case OPC_DMULTU_G_2F
:
5441 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5446 TCGLabel
*l1
= gen_new_label();
5447 TCGLabel
*l2
= gen_new_label();
5448 TCGLabel
*l3
= gen_new_label();
5449 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5450 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5453 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5454 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5455 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5458 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5462 case OPC_DDIVU_G_2E
:
5463 case OPC_DDIVU_G_2F
:
5465 TCGLabel
*l1
= gen_new_label();
5466 TCGLabel
*l2
= gen_new_label();
5467 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5468 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5471 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5478 TCGLabel
*l1
= gen_new_label();
5479 TCGLabel
*l2
= gen_new_label();
5480 TCGLabel
*l3
= gen_new_label();
5481 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5482 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5483 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5485 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5488 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5492 case OPC_DMODU_G_2E
:
5493 case OPC_DMODU_G_2F
:
5495 TCGLabel
*l1
= gen_new_label();
5496 TCGLabel
*l2
= gen_new_label();
5497 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5498 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5501 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5512 /* Loongson multimedia instructions */
5513 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
5515 uint32_t opc
, shift_max
;
5519 opc
= MASK_LMMI(ctx
->opcode
);
5525 t0
= tcg_temp_local_new_i64();
5526 t1
= tcg_temp_local_new_i64();
5529 t0
= tcg_temp_new_i64();
5530 t1
= tcg_temp_new_i64();
5534 check_cp1_enabled(ctx
);
5535 gen_load_fpr64(ctx
, t0
, rs
);
5536 gen_load_fpr64(ctx
, t1
, rt
);
5540 gen_helper_paddsh(t0
, t0
, t1
);
5543 gen_helper_paddush(t0
, t0
, t1
);
5546 gen_helper_paddh(t0
, t0
, t1
);
5549 gen_helper_paddw(t0
, t0
, t1
);
5552 gen_helper_paddsb(t0
, t0
, t1
);
5555 gen_helper_paddusb(t0
, t0
, t1
);
5558 gen_helper_paddb(t0
, t0
, t1
);
5562 gen_helper_psubsh(t0
, t0
, t1
);
5565 gen_helper_psubush(t0
, t0
, t1
);
5568 gen_helper_psubh(t0
, t0
, t1
);
5571 gen_helper_psubw(t0
, t0
, t1
);
5574 gen_helper_psubsb(t0
, t0
, t1
);
5577 gen_helper_psubusb(t0
, t0
, t1
);
5580 gen_helper_psubb(t0
, t0
, t1
);
5584 gen_helper_pshufh(t0
, t0
, t1
);
5587 gen_helper_packsswh(t0
, t0
, t1
);
5590 gen_helper_packsshb(t0
, t0
, t1
);
5593 gen_helper_packushb(t0
, t0
, t1
);
5597 gen_helper_punpcklhw(t0
, t0
, t1
);
5600 gen_helper_punpckhhw(t0
, t0
, t1
);
5603 gen_helper_punpcklbh(t0
, t0
, t1
);
5606 gen_helper_punpckhbh(t0
, t0
, t1
);
5609 gen_helper_punpcklwd(t0
, t0
, t1
);
5612 gen_helper_punpckhwd(t0
, t0
, t1
);
5616 gen_helper_pavgh(t0
, t0
, t1
);
5619 gen_helper_pavgb(t0
, t0
, t1
);
5622 gen_helper_pmaxsh(t0
, t0
, t1
);
5625 gen_helper_pminsh(t0
, t0
, t1
);
5628 gen_helper_pmaxub(t0
, t0
, t1
);
5631 gen_helper_pminub(t0
, t0
, t1
);
5635 gen_helper_pcmpeqw(t0
, t0
, t1
);
5638 gen_helper_pcmpgtw(t0
, t0
, t1
);
5641 gen_helper_pcmpeqh(t0
, t0
, t1
);
5644 gen_helper_pcmpgth(t0
, t0
, t1
);
5647 gen_helper_pcmpeqb(t0
, t0
, t1
);
5650 gen_helper_pcmpgtb(t0
, t0
, t1
);
5654 gen_helper_psllw(t0
, t0
, t1
);
5657 gen_helper_psllh(t0
, t0
, t1
);
5660 gen_helper_psrlw(t0
, t0
, t1
);
5663 gen_helper_psrlh(t0
, t0
, t1
);
5666 gen_helper_psraw(t0
, t0
, t1
);
5669 gen_helper_psrah(t0
, t0
, t1
);
5673 gen_helper_pmullh(t0
, t0
, t1
);
5676 gen_helper_pmulhh(t0
, t0
, t1
);
5679 gen_helper_pmulhuh(t0
, t0
, t1
);
5682 gen_helper_pmaddhw(t0
, t0
, t1
);
5686 gen_helper_pasubub(t0
, t0
, t1
);
5689 gen_helper_biadd(t0
, t0
);
5692 gen_helper_pmovmskb(t0
, t0
);
5696 tcg_gen_add_i64(t0
, t0
, t1
);
5699 tcg_gen_sub_i64(t0
, t0
, t1
);
5702 tcg_gen_xor_i64(t0
, t0
, t1
);
5705 tcg_gen_nor_i64(t0
, t0
, t1
);
5708 tcg_gen_and_i64(t0
, t0
, t1
);
5711 tcg_gen_or_i64(t0
, t0
, t1
);
5715 tcg_gen_andc_i64(t0
, t1
, t0
);
5719 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5722 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5725 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5728 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5732 tcg_gen_andi_i64(t1
, t1
, 3);
5733 tcg_gen_shli_i64(t1
, t1
, 4);
5734 tcg_gen_shr_i64(t0
, t0
, t1
);
5735 tcg_gen_ext16u_i64(t0
, t0
);
5739 tcg_gen_add_i64(t0
, t0
, t1
);
5740 tcg_gen_ext32s_i64(t0
, t0
);
5743 tcg_gen_sub_i64(t0
, t0
, t1
);
5744 tcg_gen_ext32s_i64(t0
, t0
);
5766 /* Make sure shift count isn't TCG undefined behaviour. */
5767 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5772 tcg_gen_shl_i64(t0
, t0
, t1
);
5777 * Since SRA is UndefinedResult without sign-extended inputs,
5778 * we can treat SRA and DSRA the same.
5780 tcg_gen_sar_i64(t0
, t0
, t1
);
5783 /* We want to shift in zeros for SRL; zero-extend first. */
5784 tcg_gen_ext32u_i64(t0
, t0
);
5787 tcg_gen_shr_i64(t0
, t0
, t1
);
5791 if (shift_max
== 32) {
5792 tcg_gen_ext32s_i64(t0
, t0
);
5795 /* Shifts larger than MAX produce zero. */
5796 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5797 tcg_gen_neg_i64(t1
, t1
);
5798 tcg_gen_and_i64(t0
, t0
, t1
);
5804 TCGv_i64 t2
= tcg_temp_new_i64();
5805 TCGLabel
*lab
= gen_new_label();
5807 tcg_gen_mov_i64(t2
, t0
);
5808 tcg_gen_add_i64(t0
, t1
, t2
);
5809 if (opc
== OPC_ADD_CP2
) {
5810 tcg_gen_ext32s_i64(t0
, t0
);
5812 tcg_gen_xor_i64(t1
, t1
, t2
);
5813 tcg_gen_xor_i64(t2
, t2
, t0
);
5814 tcg_gen_andc_i64(t1
, t2
, t1
);
5815 tcg_temp_free_i64(t2
);
5816 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5817 generate_exception(ctx
, EXCP_OVERFLOW
);
5825 TCGv_i64 t2
= tcg_temp_new_i64();
5826 TCGLabel
*lab
= gen_new_label();
5828 tcg_gen_mov_i64(t2
, t0
);
5829 tcg_gen_sub_i64(t0
, t1
, t2
);
5830 if (opc
== OPC_SUB_CP2
) {
5831 tcg_gen_ext32s_i64(t0
, t0
);
5833 tcg_gen_xor_i64(t1
, t1
, t2
);
5834 tcg_gen_xor_i64(t2
, t2
, t0
);
5835 tcg_gen_and_i64(t1
, t1
, t2
);
5836 tcg_temp_free_i64(t2
);
5837 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5838 generate_exception(ctx
, EXCP_OVERFLOW
);
5844 tcg_gen_ext32u_i64(t0
, t0
);
5845 tcg_gen_ext32u_i64(t1
, t1
);
5846 tcg_gen_mul_i64(t0
, t0
, t1
);
5855 cond
= TCG_COND_LTU
;
5863 cond
= TCG_COND_LEU
;
5870 int cc
= (ctx
->opcode
>> 8) & 0x7;
5871 TCGv_i64 t64
= tcg_temp_new_i64();
5872 TCGv_i32 t32
= tcg_temp_new_i32();
5874 tcg_gen_setcond_i64(cond
, t64
, t0
, t1
);
5875 tcg_gen_extrl_i64_i32(t32
, t64
);
5876 tcg_gen_deposit_i32(fpu_fcr31
, fpu_fcr31
, t32
,
5879 tcg_temp_free_i32(t32
);
5880 tcg_temp_free_i64(t64
);
5885 MIPS_INVAL("loongson_cp2");
5886 gen_reserved_instruction(ctx
);
5890 gen_store_fpr64(ctx
, t0
, rd
);
5893 tcg_temp_free_i64(t0
);
5894 tcg_temp_free_i64(t1
);
5897 static void gen_loongson_lswc2(DisasContext
*ctx
, int rt
,
5902 #if defined(TARGET_MIPS64)
5903 int lsq_rt1
= ctx
->opcode
& 0x1f;
5904 int lsq_offset
= sextract32(ctx
->opcode
, 6, 9) << 4;
5906 int shf_offset
= sextract32(ctx
->opcode
, 6, 8);
5908 t0
= tcg_temp_new();
5910 switch (MASK_LOONGSON_GSLSQ(ctx
->opcode
)) {
5911 #if defined(TARGET_MIPS64)
5913 t1
= tcg_temp_new();
5914 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5915 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5916 ctx
->default_tcg_memop_mask
);
5917 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5918 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5919 ctx
->default_tcg_memop_mask
);
5920 gen_store_gpr(t1
, rt
);
5921 gen_store_gpr(t0
, lsq_rt1
);
5925 check_cp1_enabled(ctx
);
5926 t1
= tcg_temp_new();
5927 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5928 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5929 ctx
->default_tcg_memop_mask
);
5930 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5931 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
5932 ctx
->default_tcg_memop_mask
);
5933 gen_store_fpr64(ctx
, t1
, rt
);
5934 gen_store_fpr64(ctx
, t0
, lsq_rt1
);
5938 t1
= tcg_temp_new();
5939 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
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
);
5943 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5944 gen_load_gpr(t1
, lsq_rt1
);
5945 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5946 ctx
->default_tcg_memop_mask
);
5950 check_cp1_enabled(ctx
);
5951 t1
= tcg_temp_new();
5952 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
);
5953 gen_load_fpr64(ctx
, t1
, rt
);
5954 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5955 ctx
->default_tcg_memop_mask
);
5956 gen_base_offset_addr(ctx
, t0
, rs
, lsq_offset
+ 8);
5957 gen_load_fpr64(ctx
, t1
, lsq_rt1
);
5958 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
5959 ctx
->default_tcg_memop_mask
);
5964 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
5966 check_cp1_enabled(ctx
);
5967 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5968 t1
= tcg_temp_new();
5969 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
5970 tcg_gen_andi_tl(t1
, t0
, 3);
5971 #ifndef TARGET_WORDS_BIGENDIAN
5972 tcg_gen_xori_tl(t1
, t1
, 3);
5974 tcg_gen_shli_tl(t1
, t1
, 3);
5975 tcg_gen_andi_tl(t0
, t0
, ~3);
5976 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
5977 tcg_gen_shl_tl(t0
, t0
, t1
);
5978 t2
= tcg_const_tl(-1);
5979 tcg_gen_shl_tl(t2
, t2
, t1
);
5980 fp0
= tcg_temp_new_i32();
5981 gen_load_fpr32(ctx
, fp0
, rt
);
5982 tcg_gen_ext_i32_tl(t1
, fp0
);
5983 tcg_gen_andc_tl(t1
, t1
, t2
);
5985 tcg_gen_or_tl(t0
, t0
, t1
);
5987 #if defined(TARGET_MIPS64)
5988 tcg_gen_extrl_i64_i32(fp0
, t0
);
5990 tcg_gen_ext32s_tl(fp0
, t0
);
5992 gen_store_fpr32(ctx
, fp0
, rt
);
5993 tcg_temp_free_i32(fp0
);
5996 check_cp1_enabled(ctx
);
5997 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
5998 t1
= tcg_temp_new();
5999 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6000 tcg_gen_andi_tl(t1
, t0
, 3);
6001 #ifdef TARGET_WORDS_BIGENDIAN
6002 tcg_gen_xori_tl(t1
, t1
, 3);
6004 tcg_gen_shli_tl(t1
, t1
, 3);
6005 tcg_gen_andi_tl(t0
, t0
, ~3);
6006 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
6007 tcg_gen_shr_tl(t0
, t0
, t1
);
6008 tcg_gen_xori_tl(t1
, t1
, 31);
6009 t2
= tcg_const_tl(0xfffffffeull
);
6010 tcg_gen_shl_tl(t2
, t2
, t1
);
6011 fp0
= tcg_temp_new_i32();
6012 gen_load_fpr32(ctx
, fp0
, rt
);
6013 tcg_gen_ext_i32_tl(t1
, fp0
);
6014 tcg_gen_and_tl(t1
, t1
, t2
);
6016 tcg_gen_or_tl(t0
, t0
, t1
);
6018 #if defined(TARGET_MIPS64)
6019 tcg_gen_extrl_i64_i32(fp0
, t0
);
6021 tcg_gen_ext32s_tl(fp0
, t0
);
6023 gen_store_fpr32(ctx
, fp0
, rt
);
6024 tcg_temp_free_i32(fp0
);
6026 #if defined(TARGET_MIPS64)
6028 check_cp1_enabled(ctx
);
6029 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6030 t1
= tcg_temp_new();
6031 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6032 tcg_gen_andi_tl(t1
, t0
, 7);
6033 #ifndef TARGET_WORDS_BIGENDIAN
6034 tcg_gen_xori_tl(t1
, t1
, 7);
6036 tcg_gen_shli_tl(t1
, t1
, 3);
6037 tcg_gen_andi_tl(t0
, t0
, ~7);
6038 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
6039 tcg_gen_shl_tl(t0
, t0
, t1
);
6040 t2
= tcg_const_tl(-1);
6041 tcg_gen_shl_tl(t2
, t2
, t1
);
6042 gen_load_fpr64(ctx
, t1
, rt
);
6043 tcg_gen_andc_tl(t1
, t1
, t2
);
6045 tcg_gen_or_tl(t0
, t0
, t1
);
6047 gen_store_fpr64(ctx
, t0
, rt
);
6050 check_cp1_enabled(ctx
);
6051 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6052 t1
= tcg_temp_new();
6053 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
6054 tcg_gen_andi_tl(t1
, t0
, 7);
6055 #ifdef TARGET_WORDS_BIGENDIAN
6056 tcg_gen_xori_tl(t1
, t1
, 7);
6058 tcg_gen_shli_tl(t1
, t1
, 3);
6059 tcg_gen_andi_tl(t0
, t0
, ~7);
6060 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
6061 tcg_gen_shr_tl(t0
, t0
, t1
);
6062 tcg_gen_xori_tl(t1
, t1
, 63);
6063 t2
= tcg_const_tl(0xfffffffffffffffeull
);
6064 tcg_gen_shl_tl(t2
, t2
, t1
);
6065 gen_load_fpr64(ctx
, t1
, rt
);
6066 tcg_gen_and_tl(t1
, t1
, t2
);
6068 tcg_gen_or_tl(t0
, t0
, t1
);
6070 gen_store_fpr64(ctx
, t0
, rt
);
6074 MIPS_INVAL("loongson_gsshfl");
6075 gen_reserved_instruction(ctx
);
6080 switch (MASK_LOONGSON_GSSHFLS(ctx
->opcode
)) {
6082 check_cp1_enabled(ctx
);
6083 t1
= tcg_temp_new();
6084 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6085 fp0
= tcg_temp_new_i32();
6086 gen_load_fpr32(ctx
, fp0
, rt
);
6087 tcg_gen_ext_i32_tl(t1
, fp0
);
6088 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
6089 tcg_temp_free_i32(fp0
);
6093 check_cp1_enabled(ctx
);
6094 t1
= tcg_temp_new();
6095 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6096 fp0
= tcg_temp_new_i32();
6097 gen_load_fpr32(ctx
, fp0
, rt
);
6098 tcg_gen_ext_i32_tl(t1
, fp0
);
6099 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
6100 tcg_temp_free_i32(fp0
);
6103 #if defined(TARGET_MIPS64)
6105 check_cp1_enabled(ctx
);
6106 t1
= tcg_temp_new();
6107 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6108 gen_load_fpr64(ctx
, t1
, rt
);
6109 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
6113 check_cp1_enabled(ctx
);
6114 t1
= tcg_temp_new();
6115 gen_base_offset_addr(ctx
, t0
, rs
, shf_offset
);
6116 gen_load_fpr64(ctx
, t1
, rt
);
6117 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
6122 MIPS_INVAL("loongson_gsshfs");
6123 gen_reserved_instruction(ctx
);
6128 MIPS_INVAL("loongson_gslsq");
6129 gen_reserved_instruction(ctx
);
6135 /* Loongson EXT LDC2/SDC2 */
6136 static void gen_loongson_lsdc2(DisasContext
*ctx
, int rt
,
6139 int offset
= sextract32(ctx
->opcode
, 3, 8);
6140 uint32_t opc
= MASK_LOONGSON_LSDC2(ctx
->opcode
);
6144 /* Pre-conditions */
6150 /* prefetch, implement as NOP */
6161 #if defined(TARGET_MIPS64)
6164 check_cp1_enabled(ctx
);
6165 /* prefetch, implement as NOP */
6171 #if defined(TARGET_MIPS64)
6174 check_cp1_enabled(ctx
);
6177 MIPS_INVAL("loongson_lsdc2");
6178 gen_reserved_instruction(ctx
);
6183 t0
= tcg_temp_new();
6185 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6186 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6190 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
6191 gen_store_gpr(t0
, rt
);
6194 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
6195 ctx
->default_tcg_memop_mask
);
6196 gen_store_gpr(t0
, rt
);
6199 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6201 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6203 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
6204 ctx
->default_tcg_memop_mask
);
6205 gen_store_gpr(t0
, rt
);
6207 #if defined(TARGET_MIPS64)
6209 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6211 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6213 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
6214 ctx
->default_tcg_memop_mask
);
6215 gen_store_gpr(t0
, rt
);
6219 check_cp1_enabled(ctx
);
6220 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6222 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6224 fp0
= tcg_temp_new_i32();
6225 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
6226 ctx
->default_tcg_memop_mask
);
6227 gen_store_fpr32(ctx
, fp0
, rt
);
6228 tcg_temp_free_i32(fp0
);
6230 #if defined(TARGET_MIPS64)
6232 check_cp1_enabled(ctx
);
6233 gen_base_offset_addr(ctx
, t0
, rs
, offset
);
6235 gen_op_addr_add(ctx
, t0
, cpu_gpr
[rd
], t0
);
6237 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
6238 ctx
->default_tcg_memop_mask
);
6239 gen_store_fpr64(ctx
, t0
, rt
);
6243 t1
= tcg_temp_new();
6244 gen_load_gpr(t1
, rt
);
6245 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
6249 t1
= tcg_temp_new();
6250 gen_load_gpr(t1
, rt
);
6251 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
6252 ctx
->default_tcg_memop_mask
);
6256 t1
= tcg_temp_new();
6257 gen_load_gpr(t1
, rt
);
6258 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
6259 ctx
->default_tcg_memop_mask
);
6262 #if defined(TARGET_MIPS64)
6264 t1
= tcg_temp_new();
6265 gen_load_gpr(t1
, rt
);
6266 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6267 ctx
->default_tcg_memop_mask
);
6272 fp0
= tcg_temp_new_i32();
6273 gen_load_fpr32(ctx
, fp0
, rt
);
6274 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
6275 ctx
->default_tcg_memop_mask
);
6276 tcg_temp_free_i32(fp0
);
6278 #if defined(TARGET_MIPS64)
6280 t1
= tcg_temp_new();
6281 gen_load_fpr64(ctx
, t1
, rt
);
6282 tcg_gen_qemu_st_i64(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
6283 ctx
->default_tcg_memop_mask
);
6295 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
6296 int rs
, int rt
, int16_t imm
)
6299 TCGv t0
= tcg_temp_new();
6300 TCGv t1
= tcg_temp_new();
6303 /* Load needed operands */
6311 /* Compare two registers */
6313 gen_load_gpr(t0
, rs
);
6314 gen_load_gpr(t1
, rt
);
6324 /* Compare register to immediate */
6325 if (rs
!= 0 || imm
!= 0) {
6326 gen_load_gpr(t0
, rs
);
6327 tcg_gen_movi_tl(t1
, (int32_t)imm
);
6334 case OPC_TEQ
: /* rs == rs */
6335 case OPC_TEQI
: /* r0 == 0 */
6336 case OPC_TGE
: /* rs >= rs */
6337 case OPC_TGEI
: /* r0 >= 0 */
6338 case OPC_TGEU
: /* rs >= rs unsigned */
6339 case OPC_TGEIU
: /* r0 >= 0 unsigned */
6341 generate_exception_end(ctx
, EXCP_TRAP
);
6343 case OPC_TLT
: /* rs < rs */
6344 case OPC_TLTI
: /* r0 < 0 */
6345 case OPC_TLTU
: /* rs < rs unsigned */
6346 case OPC_TLTIU
: /* r0 < 0 unsigned */
6347 case OPC_TNE
: /* rs != rs */
6348 case OPC_TNEI
: /* r0 != 0 */
6349 /* Never trap: treat as NOP. */
6353 TCGLabel
*l1
= gen_new_label();
6358 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
6362 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
6366 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
6370 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
6374 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
6378 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
6381 generate_exception(ctx
, EXCP_TRAP
);
6388 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
6390 if (unlikely(ctx
->base
.singlestep_enabled
)) {
6394 #ifndef CONFIG_USER_ONLY
6395 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
6401 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
6403 if (use_goto_tb(ctx
, dest
)) {
6406 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
6409 if (ctx
->base
.singlestep_enabled
) {
6410 save_cpu_state(ctx
, 0);
6411 gen_helper_raise_exception_debug(cpu_env
);
6413 tcg_gen_lookup_and_goto_ptr();
6417 /* Branches (before delay slot) */
6418 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
6420 int rs
, int rt
, int32_t offset
,
6423 target_ulong btgt
= -1;
6425 int bcond_compute
= 0;
6426 TCGv t0
= tcg_temp_new();
6427 TCGv t1
= tcg_temp_new();
6429 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
6430 #ifdef MIPS_DEBUG_DISAS
6431 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
6432 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
6434 gen_reserved_instruction(ctx
);
6438 /* Load needed operands */
6444 /* Compare two registers */
6446 gen_load_gpr(t0
, rs
);
6447 gen_load_gpr(t1
, rt
);
6450 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6464 /* Compare to zero */
6466 gen_load_gpr(t0
, rs
);
6469 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6472 #if defined(TARGET_MIPS64)
6474 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
6476 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6479 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6484 /* Jump to immediate */
6485 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
6490 /* Jump to register */
6491 if (offset
!= 0 && offset
!= 16) {
6493 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6494 * others are reserved.
6496 MIPS_INVAL("jump hint");
6497 gen_reserved_instruction(ctx
);
6500 gen_load_gpr(btarget
, rs
);
6503 MIPS_INVAL("branch/jump");
6504 gen_reserved_instruction(ctx
);
6507 if (bcond_compute
== 0) {
6508 /* No condition to be computed */
6510 case OPC_BEQ
: /* rx == rx */
6511 case OPC_BEQL
: /* rx == rx likely */
6512 case OPC_BGEZ
: /* 0 >= 0 */
6513 case OPC_BGEZL
: /* 0 >= 0 likely */
6514 case OPC_BLEZ
: /* 0 <= 0 */
6515 case OPC_BLEZL
: /* 0 <= 0 likely */
6517 ctx
->hflags
|= MIPS_HFLAG_B
;
6519 case OPC_BGEZAL
: /* 0 >= 0 */
6520 case OPC_BGEZALL
: /* 0 >= 0 likely */
6521 /* Always take and link */
6523 ctx
->hflags
|= MIPS_HFLAG_B
;
6525 case OPC_BNE
: /* rx != rx */
6526 case OPC_BGTZ
: /* 0 > 0 */
6527 case OPC_BLTZ
: /* 0 < 0 */
6530 case OPC_BLTZAL
: /* 0 < 0 */
6532 * Handle as an unconditional branch to get correct delay
6536 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6537 ctx
->hflags
|= MIPS_HFLAG_B
;
6539 case OPC_BLTZALL
: /* 0 < 0 likely */
6540 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6541 /* Skip the instruction in the delay slot */
6542 ctx
->base
.pc_next
+= 4;
6544 case OPC_BNEL
: /* rx != rx likely */
6545 case OPC_BGTZL
: /* 0 > 0 likely */
6546 case OPC_BLTZL
: /* 0 < 0 likely */
6547 /* Skip the instruction in the delay slot */
6548 ctx
->base
.pc_next
+= 4;
6551 ctx
->hflags
|= MIPS_HFLAG_B
;
6554 ctx
->hflags
|= MIPS_HFLAG_BX
;
6558 ctx
->hflags
|= MIPS_HFLAG_B
;
6561 ctx
->hflags
|= MIPS_HFLAG_BR
;
6565 ctx
->hflags
|= MIPS_HFLAG_BR
;
6568 MIPS_INVAL("branch/jump");
6569 gen_reserved_instruction(ctx
);
6575 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6578 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6581 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6584 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6587 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6590 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6593 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6597 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6601 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6604 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6607 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6610 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6613 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6616 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6619 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6621 #if defined(TARGET_MIPS64)
6623 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6627 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6630 ctx
->hflags
|= MIPS_HFLAG_BC
;
6633 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6636 ctx
->hflags
|= MIPS_HFLAG_BL
;
6639 MIPS_INVAL("conditional branch/jump");
6640 gen_reserved_instruction(ctx
);
6645 ctx
->btarget
= btgt
;
6647 switch (delayslot_size
) {
6649 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6652 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6657 int post_delay
= insn_bytes
+ delayslot_size
;
6658 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6660 tcg_gen_movi_tl(cpu_gpr
[blink
],
6661 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6665 if (insn_bytes
== 2) {
6666 ctx
->hflags
|= MIPS_HFLAG_B16
;
6673 /* nanoMIPS Branches */
6674 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6676 int rs
, int rt
, int32_t offset
)
6678 target_ulong btgt
= -1;
6679 int bcond_compute
= 0;
6680 TCGv t0
= tcg_temp_new();
6681 TCGv t1
= tcg_temp_new();
6683 /* Load needed operands */
6687 /* Compare two registers */
6689 gen_load_gpr(t0
, rs
);
6690 gen_load_gpr(t1
, rt
);
6693 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6696 /* Compare to zero */
6698 gen_load_gpr(t0
, rs
);
6701 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6704 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6706 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6710 /* Jump to register */
6711 if (offset
!= 0 && offset
!= 16) {
6713 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6714 * others are reserved.
6716 MIPS_INVAL("jump hint");
6717 gen_reserved_instruction(ctx
);
6720 gen_load_gpr(btarget
, rs
);
6723 MIPS_INVAL("branch/jump");
6724 gen_reserved_instruction(ctx
);
6727 if (bcond_compute
== 0) {
6728 /* No condition to be computed */
6730 case OPC_BEQ
: /* rx == rx */
6732 ctx
->hflags
|= MIPS_HFLAG_B
;
6734 case OPC_BGEZAL
: /* 0 >= 0 */
6735 /* Always take and link */
6736 tcg_gen_movi_tl(cpu_gpr
[31],
6737 ctx
->base
.pc_next
+ insn_bytes
);
6738 ctx
->hflags
|= MIPS_HFLAG_B
;
6740 case OPC_BNE
: /* rx != rx */
6741 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6742 /* Skip the instruction in the delay slot */
6743 ctx
->base
.pc_next
+= 4;
6746 ctx
->hflags
|= MIPS_HFLAG_BR
;
6750 tcg_gen_movi_tl(cpu_gpr
[rt
],
6751 ctx
->base
.pc_next
+ insn_bytes
);
6753 ctx
->hflags
|= MIPS_HFLAG_BR
;
6756 MIPS_INVAL("branch/jump");
6757 gen_reserved_instruction(ctx
);
6763 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6766 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6769 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6770 tcg_gen_movi_tl(cpu_gpr
[31],
6771 ctx
->base
.pc_next
+ insn_bytes
);
6774 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6776 ctx
->hflags
|= MIPS_HFLAG_BC
;
6779 MIPS_INVAL("conditional branch/jump");
6780 gen_reserved_instruction(ctx
);
6785 ctx
->btarget
= btgt
;
6788 if (insn_bytes
== 2) {
6789 ctx
->hflags
|= MIPS_HFLAG_B16
;
6796 /* special3 bitfield operations */
6797 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6798 int rs
, int lsb
, int msb
)
6800 TCGv t0
= tcg_temp_new();
6801 TCGv t1
= tcg_temp_new();
6803 gen_load_gpr(t1
, rs
);
6806 if (lsb
+ msb
> 31) {
6810 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6813 * The two checks together imply that lsb == 0,
6814 * so this is a simple sign-extension.
6816 tcg_gen_ext32s_tl(t0
, t1
);
6819 #if defined(TARGET_MIPS64)
6828 if (lsb
+ msb
> 63) {
6831 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6838 gen_load_gpr(t0
, rt
);
6839 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6840 tcg_gen_ext32s_tl(t0
, t0
);
6842 #if defined(TARGET_MIPS64)
6853 gen_load_gpr(t0
, rt
);
6854 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6859 MIPS_INVAL("bitops");
6860 gen_reserved_instruction(ctx
);
6865 gen_store_gpr(t0
, rt
);
6870 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6875 /* If no destination, treat it as a NOP. */
6879 t0
= tcg_temp_new();
6880 gen_load_gpr(t0
, rt
);
6884 TCGv t1
= tcg_temp_new();
6885 TCGv t2
= tcg_const_tl(0x00FF00FF);
6887 tcg_gen_shri_tl(t1
, t0
, 8);
6888 tcg_gen_and_tl(t1
, t1
, t2
);
6889 tcg_gen_and_tl(t0
, t0
, t2
);
6890 tcg_gen_shli_tl(t0
, t0
, 8);
6891 tcg_gen_or_tl(t0
, t0
, t1
);
6894 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6898 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6901 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6903 #if defined(TARGET_MIPS64)
6906 TCGv t1
= tcg_temp_new();
6907 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6909 tcg_gen_shri_tl(t1
, t0
, 8);
6910 tcg_gen_and_tl(t1
, t1
, t2
);
6911 tcg_gen_and_tl(t0
, t0
, t2
);
6912 tcg_gen_shli_tl(t0
, t0
, 8);
6913 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6920 TCGv t1
= tcg_temp_new();
6921 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6923 tcg_gen_shri_tl(t1
, t0
, 16);
6924 tcg_gen_and_tl(t1
, t1
, t2
);
6925 tcg_gen_and_tl(t0
, t0
, t2
);
6926 tcg_gen_shli_tl(t0
, t0
, 16);
6927 tcg_gen_or_tl(t0
, t0
, t1
);
6928 tcg_gen_shri_tl(t1
, t0
, 32);
6929 tcg_gen_shli_tl(t0
, t0
, 32);
6930 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6937 MIPS_INVAL("bsfhl");
6938 gen_reserved_instruction(ctx
);
6945 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
6954 t0
= tcg_temp_new();
6955 t1
= tcg_temp_new();
6956 gen_load_gpr(t0
, rs
);
6957 gen_load_gpr(t1
, rt
);
6958 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
6959 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
6960 if (opc
== OPC_LSA
) {
6961 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
6970 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
6978 t0
= tcg_temp_new();
6979 if (bits
== 0 || bits
== wordsz
) {
6981 gen_load_gpr(t0
, rt
);
6983 gen_load_gpr(t0
, rs
);
6987 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6989 #if defined(TARGET_MIPS64)
6991 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
6996 TCGv t1
= tcg_temp_new();
6997 gen_load_gpr(t0
, rt
);
6998 gen_load_gpr(t1
, rs
);
7002 TCGv_i64 t2
= tcg_temp_new_i64();
7003 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
7004 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
7005 gen_move_low32(cpu_gpr
[rd
], t2
);
7006 tcg_temp_free_i64(t2
);
7009 #if defined(TARGET_MIPS64)
7011 tcg_gen_shli_tl(t0
, t0
, bits
);
7012 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
7013 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
7023 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
7026 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
7029 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
7032 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
7035 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
7042 t0
= tcg_temp_new();
7043 gen_load_gpr(t0
, rt
);
7046 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
7048 #if defined(TARGET_MIPS64)
7050 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
7057 #ifndef CONFIG_USER_ONLY
7058 /* CP0 (MMU and control) */
7059 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
7061 TCGv_i64 t0
= tcg_temp_new_i64();
7062 TCGv_i64 t1
= tcg_temp_new_i64();
7064 tcg_gen_ext_tl_i64(t0
, arg
);
7065 tcg_gen_ld_i64(t1
, cpu_env
, off
);
7066 #if defined(TARGET_MIPS64)
7067 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
7069 tcg_gen_concat32_i64(t1
, t1
, t0
);
7071 tcg_gen_st_i64(t1
, cpu_env
, off
);
7072 tcg_temp_free_i64(t1
);
7073 tcg_temp_free_i64(t0
);
7076 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
7078 TCGv_i64 t0
= tcg_temp_new_i64();
7079 TCGv_i64 t1
= tcg_temp_new_i64();
7081 tcg_gen_ext_tl_i64(t0
, arg
);
7082 tcg_gen_ld_i64(t1
, cpu_env
, off
);
7083 tcg_gen_concat32_i64(t1
, t1
, t0
);
7084 tcg_gen_st_i64(t1
, cpu_env
, off
);
7085 tcg_temp_free_i64(t1
);
7086 tcg_temp_free_i64(t0
);
7089 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
7091 TCGv_i64 t0
= tcg_temp_new_i64();
7093 tcg_gen_ld_i64(t0
, cpu_env
, off
);
7094 #if defined(TARGET_MIPS64)
7095 tcg_gen_shri_i64(t0
, t0
, 30);
7097 tcg_gen_shri_i64(t0
, t0
, 32);
7099 gen_move_low32(arg
, t0
);
7100 tcg_temp_free_i64(t0
);
7103 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
7105 TCGv_i64 t0
= tcg_temp_new_i64();
7107 tcg_gen_ld_i64(t0
, cpu_env
, off
);
7108 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
7109 gen_move_low32(arg
, t0
);
7110 tcg_temp_free_i64(t0
);
7113 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
7115 TCGv_i32 t0
= tcg_temp_new_i32();
7117 tcg_gen_ld_i32(t0
, cpu_env
, off
);
7118 tcg_gen_ext_i32_tl(arg
, t0
);
7119 tcg_temp_free_i32(t0
);
7122 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
7124 tcg_gen_ld_tl(arg
, cpu_env
, off
);
7125 tcg_gen_ext32s_tl(arg
, arg
);
7128 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
7130 TCGv_i32 t0
= tcg_temp_new_i32();
7132 tcg_gen_trunc_tl_i32(t0
, arg
);
7133 tcg_gen_st_i32(t0
, cpu_env
, off
);
7134 tcg_temp_free_i32(t0
);
7137 #define CP0_CHECK(c) \
7140 goto cp0_unimplemented; \
7144 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7146 const char *register_name
= "invalid";
7149 case CP0_REGISTER_02
:
7152 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7153 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
7154 register_name
= "EntryLo0";
7157 goto cp0_unimplemented
;
7160 case CP0_REGISTER_03
:
7162 case CP0_REG03__ENTRYLO1
:
7163 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7164 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7165 register_name
= "EntryLo1";
7168 goto cp0_unimplemented
;
7171 case CP0_REGISTER_09
:
7173 case CP0_REG09__SAAR
:
7174 CP0_CHECK(ctx
->saar
);
7175 gen_helper_mfhc0_saar(arg
, cpu_env
);
7176 register_name
= "SAAR";
7179 goto cp0_unimplemented
;
7182 case CP0_REGISTER_17
:
7184 case CP0_REG17__LLADDR
:
7185 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
7186 ctx
->CP0_LLAddr_shift
);
7187 register_name
= "LLAddr";
7189 case CP0_REG17__MAAR
:
7190 CP0_CHECK(ctx
->mrp
);
7191 gen_helper_mfhc0_maar(arg
, cpu_env
);
7192 register_name
= "MAAR";
7195 goto cp0_unimplemented
;
7198 case CP0_REGISTER_19
:
7200 case CP0_REG19__WATCHHI0
:
7201 case CP0_REG19__WATCHHI1
:
7202 case CP0_REG19__WATCHHI2
:
7203 case CP0_REG19__WATCHHI3
:
7204 case CP0_REG19__WATCHHI4
:
7205 case CP0_REG19__WATCHHI5
:
7206 case CP0_REG19__WATCHHI6
:
7207 case CP0_REG19__WATCHHI7
:
7208 /* upper 32 bits are only available when Config5MI != 0 */
7210 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_WatchHi
[sel
]), 0);
7211 register_name
= "WatchHi";
7214 goto cp0_unimplemented
;
7217 case CP0_REGISTER_28
:
7223 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
7224 register_name
= "TagLo";
7227 goto cp0_unimplemented
;
7231 goto cp0_unimplemented
;
7233 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
7237 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
7238 register_name
, reg
, sel
);
7239 tcg_gen_movi_tl(arg
, 0);
7242 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7244 const char *register_name
= "invalid";
7245 uint64_t mask
= ctx
->PAMask
>> 36;
7248 case CP0_REGISTER_02
:
7251 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7252 tcg_gen_andi_tl(arg
, arg
, mask
);
7253 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
7254 register_name
= "EntryLo0";
7257 goto cp0_unimplemented
;
7260 case CP0_REGISTER_03
:
7262 case CP0_REG03__ENTRYLO1
:
7263 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
7264 tcg_gen_andi_tl(arg
, arg
, mask
);
7265 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
7266 register_name
= "EntryLo1";
7269 goto cp0_unimplemented
;
7272 case CP0_REGISTER_09
:
7274 case CP0_REG09__SAAR
:
7275 CP0_CHECK(ctx
->saar
);
7276 gen_helper_mthc0_saar(cpu_env
, arg
);
7277 register_name
= "SAAR";
7280 goto cp0_unimplemented
;
7283 case CP0_REGISTER_17
:
7285 case CP0_REG17__LLADDR
:
7287 * LLAddr is read-only (the only exception is bit 0 if LLB is
7288 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
7289 * relevant for modern MIPS cores supporting MTHC0, therefore
7290 * treating MTHC0 to LLAddr as NOP.
7292 register_name
= "LLAddr";
7294 case CP0_REG17__MAAR
:
7295 CP0_CHECK(ctx
->mrp
);
7296 gen_helper_mthc0_maar(cpu_env
, arg
);
7297 register_name
= "MAAR";
7300 goto cp0_unimplemented
;
7303 case CP0_REGISTER_19
:
7305 case CP0_REG19__WATCHHI0
:
7306 case CP0_REG19__WATCHHI1
:
7307 case CP0_REG19__WATCHHI2
:
7308 case CP0_REG19__WATCHHI3
:
7309 case CP0_REG19__WATCHHI4
:
7310 case CP0_REG19__WATCHHI5
:
7311 case CP0_REG19__WATCHHI6
:
7312 case CP0_REG19__WATCHHI7
:
7313 /* upper 32 bits are only available when Config5MI != 0 */
7315 gen_helper_0e1i(mthc0_watchhi
, arg
, sel
);
7316 register_name
= "WatchHi";
7319 goto cp0_unimplemented
;
7322 case CP0_REGISTER_28
:
7328 tcg_gen_andi_tl(arg
, arg
, mask
);
7329 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
7330 register_name
= "TagLo";
7333 goto cp0_unimplemented
;
7337 goto cp0_unimplemented
;
7339 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
7342 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
7343 register_name
, reg
, sel
);
7346 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
7348 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
7349 tcg_gen_movi_tl(arg
, 0);
7351 tcg_gen_movi_tl(arg
, ~0);
7355 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7357 const char *register_name
= "invalid";
7360 check_insn(ctx
, ISA_MIPS_R1
);
7364 case CP0_REGISTER_00
:
7366 case CP0_REG00__INDEX
:
7367 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
7368 register_name
= "Index";
7370 case CP0_REG00__MVPCONTROL
:
7371 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7372 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
7373 register_name
= "MVPControl";
7375 case CP0_REG00__MVPCONF0
:
7376 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7377 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
7378 register_name
= "MVPConf0";
7380 case CP0_REG00__MVPCONF1
:
7381 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7382 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
7383 register_name
= "MVPConf1";
7385 case CP0_REG00__VPCONTROL
:
7387 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
7388 register_name
= "VPControl";
7391 goto cp0_unimplemented
;
7394 case CP0_REGISTER_01
:
7396 case CP0_REG01__RANDOM
:
7397 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7398 gen_helper_mfc0_random(arg
, cpu_env
);
7399 register_name
= "Random";
7401 case CP0_REG01__VPECONTROL
:
7402 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7403 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
7404 register_name
= "VPEControl";
7406 case CP0_REG01__VPECONF0
:
7407 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7408 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
7409 register_name
= "VPEConf0";
7411 case CP0_REG01__VPECONF1
:
7412 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7413 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
7414 register_name
= "VPEConf1";
7416 case CP0_REG01__YQMASK
:
7417 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7418 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
7419 register_name
= "YQMask";
7421 case CP0_REG01__VPESCHEDULE
:
7422 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7423 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7424 register_name
= "VPESchedule";
7426 case CP0_REG01__VPESCHEFBACK
:
7427 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7428 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7429 register_name
= "VPEScheFBack";
7431 case CP0_REG01__VPEOPT
:
7432 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7433 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
7434 register_name
= "VPEOpt";
7437 goto cp0_unimplemented
;
7440 case CP0_REGISTER_02
:
7442 case CP0_REG02__ENTRYLO0
:
7444 TCGv_i64 tmp
= tcg_temp_new_i64();
7445 tcg_gen_ld_i64(tmp
, cpu_env
,
7446 offsetof(CPUMIPSState
, CP0_EntryLo0
));
7447 #if defined(TARGET_MIPS64)
7449 /* Move RI/XI fields to bits 31:30 */
7450 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7451 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7454 gen_move_low32(arg
, tmp
);
7455 tcg_temp_free_i64(tmp
);
7457 register_name
= "EntryLo0";
7459 case CP0_REG02__TCSTATUS
:
7460 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7461 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
7462 register_name
= "TCStatus";
7464 case CP0_REG02__TCBIND
:
7465 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7466 gen_helper_mfc0_tcbind(arg
, cpu_env
);
7467 register_name
= "TCBind";
7469 case CP0_REG02__TCRESTART
:
7470 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7471 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
7472 register_name
= "TCRestart";
7474 case CP0_REG02__TCHALT
:
7475 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7476 gen_helper_mfc0_tchalt(arg
, cpu_env
);
7477 register_name
= "TCHalt";
7479 case CP0_REG02__TCCONTEXT
:
7480 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7481 gen_helper_mfc0_tccontext(arg
, cpu_env
);
7482 register_name
= "TCContext";
7484 case CP0_REG02__TCSCHEDULE
:
7485 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7486 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
7487 register_name
= "TCSchedule";
7489 case CP0_REG02__TCSCHEFBACK
:
7490 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7491 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
7492 register_name
= "TCScheFBack";
7495 goto cp0_unimplemented
;
7498 case CP0_REGISTER_03
:
7500 case CP0_REG03__ENTRYLO1
:
7502 TCGv_i64 tmp
= tcg_temp_new_i64();
7503 tcg_gen_ld_i64(tmp
, cpu_env
,
7504 offsetof(CPUMIPSState
, CP0_EntryLo1
));
7505 #if defined(TARGET_MIPS64)
7507 /* Move RI/XI fields to bits 31:30 */
7508 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
7509 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
7512 gen_move_low32(arg
, tmp
);
7513 tcg_temp_free_i64(tmp
);
7515 register_name
= "EntryLo1";
7517 case CP0_REG03__GLOBALNUM
:
7519 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
7520 register_name
= "GlobalNumber";
7523 goto cp0_unimplemented
;
7526 case CP0_REGISTER_04
:
7528 case CP0_REG04__CONTEXT
:
7529 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
7530 tcg_gen_ext32s_tl(arg
, arg
);
7531 register_name
= "Context";
7533 case CP0_REG04__CONTEXTCONFIG
:
7535 /* gen_helper_mfc0_contextconfig(arg); */
7536 register_name
= "ContextConfig";
7537 goto cp0_unimplemented
;
7538 case CP0_REG04__USERLOCAL
:
7539 CP0_CHECK(ctx
->ulri
);
7540 tcg_gen_ld_tl(arg
, cpu_env
,
7541 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7542 tcg_gen_ext32s_tl(arg
, arg
);
7543 register_name
= "UserLocal";
7545 case CP0_REG04__MMID
:
7547 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
7548 register_name
= "MMID";
7551 goto cp0_unimplemented
;
7554 case CP0_REGISTER_05
:
7556 case CP0_REG05__PAGEMASK
:
7557 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7558 register_name
= "PageMask";
7560 case CP0_REG05__PAGEGRAIN
:
7561 check_insn(ctx
, ISA_MIPS_R2
);
7562 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7563 register_name
= "PageGrain";
7565 case CP0_REG05__SEGCTL0
:
7567 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7568 tcg_gen_ext32s_tl(arg
, arg
);
7569 register_name
= "SegCtl0";
7571 case CP0_REG05__SEGCTL1
:
7573 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7574 tcg_gen_ext32s_tl(arg
, arg
);
7575 register_name
= "SegCtl1";
7577 case CP0_REG05__SEGCTL2
:
7579 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7580 tcg_gen_ext32s_tl(arg
, arg
);
7581 register_name
= "SegCtl2";
7583 case CP0_REG05__PWBASE
:
7585 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7586 register_name
= "PWBase";
7588 case CP0_REG05__PWFIELD
:
7590 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7591 register_name
= "PWField";
7593 case CP0_REG05__PWSIZE
:
7595 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7596 register_name
= "PWSize";
7599 goto cp0_unimplemented
;
7602 case CP0_REGISTER_06
:
7604 case CP0_REG06__WIRED
:
7605 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7606 register_name
= "Wired";
7608 case CP0_REG06__SRSCONF0
:
7609 check_insn(ctx
, ISA_MIPS_R2
);
7610 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7611 register_name
= "SRSConf0";
7613 case CP0_REG06__SRSCONF1
:
7614 check_insn(ctx
, ISA_MIPS_R2
);
7615 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7616 register_name
= "SRSConf1";
7618 case CP0_REG06__SRSCONF2
:
7619 check_insn(ctx
, ISA_MIPS_R2
);
7620 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7621 register_name
= "SRSConf2";
7623 case CP0_REG06__SRSCONF3
:
7624 check_insn(ctx
, ISA_MIPS_R2
);
7625 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7626 register_name
= "SRSConf3";
7628 case CP0_REG06__SRSCONF4
:
7629 check_insn(ctx
, ISA_MIPS_R2
);
7630 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7631 register_name
= "SRSConf4";
7633 case CP0_REG06__PWCTL
:
7635 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7636 register_name
= "PWCtl";
7639 goto cp0_unimplemented
;
7642 case CP0_REGISTER_07
:
7644 case CP0_REG07__HWRENA
:
7645 check_insn(ctx
, ISA_MIPS_R2
);
7646 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7647 register_name
= "HWREna";
7650 goto cp0_unimplemented
;
7653 case CP0_REGISTER_08
:
7655 case CP0_REG08__BADVADDR
:
7656 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7657 tcg_gen_ext32s_tl(arg
, arg
);
7658 register_name
= "BadVAddr";
7660 case CP0_REG08__BADINSTR
:
7662 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7663 register_name
= "BadInstr";
7665 case CP0_REG08__BADINSTRP
:
7667 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7668 register_name
= "BadInstrP";
7670 case CP0_REG08__BADINSTRX
:
7672 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7673 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7674 register_name
= "BadInstrX";
7677 goto cp0_unimplemented
;
7680 case CP0_REGISTER_09
:
7682 case CP0_REG09__COUNT
:
7683 /* Mark as an IO operation because we read the time. */
7684 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7687 gen_helper_mfc0_count(arg
, cpu_env
);
7689 * Break the TB to be able to take timer interrupts immediately
7690 * after reading count. DISAS_STOP isn't sufficient, we need to
7691 * ensure we break completely out of translated code.
7693 gen_save_pc(ctx
->base
.pc_next
+ 4);
7694 ctx
->base
.is_jmp
= DISAS_EXIT
;
7695 register_name
= "Count";
7697 case CP0_REG09__SAARI
:
7698 CP0_CHECK(ctx
->saar
);
7699 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7700 register_name
= "SAARI";
7702 case CP0_REG09__SAAR
:
7703 CP0_CHECK(ctx
->saar
);
7704 gen_helper_mfc0_saar(arg
, cpu_env
);
7705 register_name
= "SAAR";
7708 goto cp0_unimplemented
;
7711 case CP0_REGISTER_10
:
7713 case CP0_REG10__ENTRYHI
:
7714 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7715 tcg_gen_ext32s_tl(arg
, arg
);
7716 register_name
= "EntryHi";
7719 goto cp0_unimplemented
;
7722 case CP0_REGISTER_11
:
7724 case CP0_REG11__COMPARE
:
7725 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7726 register_name
= "Compare";
7728 /* 6,7 are implementation dependent */
7730 goto cp0_unimplemented
;
7733 case CP0_REGISTER_12
:
7735 case CP0_REG12__STATUS
:
7736 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7737 register_name
= "Status";
7739 case CP0_REG12__INTCTL
:
7740 check_insn(ctx
, ISA_MIPS_R2
);
7741 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7742 register_name
= "IntCtl";
7744 case CP0_REG12__SRSCTL
:
7745 check_insn(ctx
, ISA_MIPS_R2
);
7746 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7747 register_name
= "SRSCtl";
7749 case CP0_REG12__SRSMAP
:
7750 check_insn(ctx
, ISA_MIPS_R2
);
7751 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7752 register_name
= "SRSMap";
7755 goto cp0_unimplemented
;
7758 case CP0_REGISTER_13
:
7760 case CP0_REG13__CAUSE
:
7761 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7762 register_name
= "Cause";
7765 goto cp0_unimplemented
;
7768 case CP0_REGISTER_14
:
7770 case CP0_REG14__EPC
:
7771 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7772 tcg_gen_ext32s_tl(arg
, arg
);
7773 register_name
= "EPC";
7776 goto cp0_unimplemented
;
7779 case CP0_REGISTER_15
:
7781 case CP0_REG15__PRID
:
7782 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7783 register_name
= "PRid";
7785 case CP0_REG15__EBASE
:
7786 check_insn(ctx
, ISA_MIPS_R2
);
7787 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7788 tcg_gen_ext32s_tl(arg
, arg
);
7789 register_name
= "EBase";
7791 case CP0_REG15__CMGCRBASE
:
7792 check_insn(ctx
, ISA_MIPS_R2
);
7793 CP0_CHECK(ctx
->cmgcr
);
7794 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7795 tcg_gen_ext32s_tl(arg
, arg
);
7796 register_name
= "CMGCRBase";
7799 goto cp0_unimplemented
;
7802 case CP0_REGISTER_16
:
7804 case CP0_REG16__CONFIG
:
7805 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7806 register_name
= "Config";
7808 case CP0_REG16__CONFIG1
:
7809 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7810 register_name
= "Config1";
7812 case CP0_REG16__CONFIG2
:
7813 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7814 register_name
= "Config2";
7816 case CP0_REG16__CONFIG3
:
7817 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7818 register_name
= "Config3";
7820 case CP0_REG16__CONFIG4
:
7821 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7822 register_name
= "Config4";
7824 case CP0_REG16__CONFIG5
:
7825 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7826 register_name
= "Config5";
7828 /* 6,7 are implementation dependent */
7829 case CP0_REG16__CONFIG6
:
7830 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7831 register_name
= "Config6";
7833 case CP0_REG16__CONFIG7
:
7834 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7835 register_name
= "Config7";
7838 goto cp0_unimplemented
;
7841 case CP0_REGISTER_17
:
7843 case CP0_REG17__LLADDR
:
7844 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7845 register_name
= "LLAddr";
7847 case CP0_REG17__MAAR
:
7848 CP0_CHECK(ctx
->mrp
);
7849 gen_helper_mfc0_maar(arg
, cpu_env
);
7850 register_name
= "MAAR";
7852 case CP0_REG17__MAARI
:
7853 CP0_CHECK(ctx
->mrp
);
7854 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7855 register_name
= "MAARI";
7858 goto cp0_unimplemented
;
7861 case CP0_REGISTER_18
:
7863 case CP0_REG18__WATCHLO0
:
7864 case CP0_REG18__WATCHLO1
:
7865 case CP0_REG18__WATCHLO2
:
7866 case CP0_REG18__WATCHLO3
:
7867 case CP0_REG18__WATCHLO4
:
7868 case CP0_REG18__WATCHLO5
:
7869 case CP0_REG18__WATCHLO6
:
7870 case CP0_REG18__WATCHLO7
:
7871 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7872 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7873 register_name
= "WatchLo";
7876 goto cp0_unimplemented
;
7879 case CP0_REGISTER_19
:
7881 case CP0_REG19__WATCHHI0
:
7882 case CP0_REG19__WATCHHI1
:
7883 case CP0_REG19__WATCHHI2
:
7884 case CP0_REG19__WATCHHI3
:
7885 case CP0_REG19__WATCHHI4
:
7886 case CP0_REG19__WATCHHI5
:
7887 case CP0_REG19__WATCHHI6
:
7888 case CP0_REG19__WATCHHI7
:
7889 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7890 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7891 register_name
= "WatchHi";
7894 goto cp0_unimplemented
;
7897 case CP0_REGISTER_20
:
7899 case CP0_REG20__XCONTEXT
:
7900 #if defined(TARGET_MIPS64)
7901 check_insn(ctx
, ISA_MIPS3
);
7902 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7903 tcg_gen_ext32s_tl(arg
, arg
);
7904 register_name
= "XContext";
7908 goto cp0_unimplemented
;
7911 case CP0_REGISTER_21
:
7912 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7913 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
7916 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7917 register_name
= "Framemask";
7920 goto cp0_unimplemented
;
7923 case CP0_REGISTER_22
:
7924 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7925 register_name
= "'Diagnostic"; /* implementation dependent */
7927 case CP0_REGISTER_23
:
7929 case CP0_REG23__DEBUG
:
7930 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7931 register_name
= "Debug";
7933 case CP0_REG23__TRACECONTROL
:
7934 /* PDtrace support */
7935 /* gen_helper_mfc0_tracecontrol(arg); */
7936 register_name
= "TraceControl";
7937 goto cp0_unimplemented
;
7938 case CP0_REG23__TRACECONTROL2
:
7939 /* PDtrace support */
7940 /* gen_helper_mfc0_tracecontrol2(arg); */
7941 register_name
= "TraceControl2";
7942 goto cp0_unimplemented
;
7943 case CP0_REG23__USERTRACEDATA1
:
7944 /* PDtrace support */
7945 /* gen_helper_mfc0_usertracedata1(arg);*/
7946 register_name
= "UserTraceData1";
7947 goto cp0_unimplemented
;
7948 case CP0_REG23__TRACEIBPC
:
7949 /* PDtrace support */
7950 /* gen_helper_mfc0_traceibpc(arg); */
7951 register_name
= "TraceIBPC";
7952 goto cp0_unimplemented
;
7953 case CP0_REG23__TRACEDBPC
:
7954 /* PDtrace support */
7955 /* gen_helper_mfc0_tracedbpc(arg); */
7956 register_name
= "TraceDBPC";
7957 goto cp0_unimplemented
;
7959 goto cp0_unimplemented
;
7962 case CP0_REGISTER_24
:
7964 case CP0_REG24__DEPC
:
7966 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7967 tcg_gen_ext32s_tl(arg
, arg
);
7968 register_name
= "DEPC";
7971 goto cp0_unimplemented
;
7974 case CP0_REGISTER_25
:
7976 case CP0_REG25__PERFCTL0
:
7977 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
7978 register_name
= "Performance0";
7980 case CP0_REG25__PERFCNT0
:
7981 /* gen_helper_mfc0_performance1(arg); */
7982 register_name
= "Performance1";
7983 goto cp0_unimplemented
;
7984 case CP0_REG25__PERFCTL1
:
7985 /* gen_helper_mfc0_performance2(arg); */
7986 register_name
= "Performance2";
7987 goto cp0_unimplemented
;
7988 case CP0_REG25__PERFCNT1
:
7989 /* gen_helper_mfc0_performance3(arg); */
7990 register_name
= "Performance3";
7991 goto cp0_unimplemented
;
7992 case CP0_REG25__PERFCTL2
:
7993 /* gen_helper_mfc0_performance4(arg); */
7994 register_name
= "Performance4";
7995 goto cp0_unimplemented
;
7996 case CP0_REG25__PERFCNT2
:
7997 /* gen_helper_mfc0_performance5(arg); */
7998 register_name
= "Performance5";
7999 goto cp0_unimplemented
;
8000 case CP0_REG25__PERFCTL3
:
8001 /* gen_helper_mfc0_performance6(arg); */
8002 register_name
= "Performance6";
8003 goto cp0_unimplemented
;
8004 case CP0_REG25__PERFCNT3
:
8005 /* gen_helper_mfc0_performance7(arg); */
8006 register_name
= "Performance7";
8007 goto cp0_unimplemented
;
8009 goto cp0_unimplemented
;
8012 case CP0_REGISTER_26
:
8014 case CP0_REG26__ERRCTL
:
8015 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8016 register_name
= "ErrCtl";
8019 goto cp0_unimplemented
;
8022 case CP0_REGISTER_27
:
8024 case CP0_REG27__CACHERR
:
8025 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8026 register_name
= "CacheErr";
8029 goto cp0_unimplemented
;
8032 case CP0_REGISTER_28
:
8034 case CP0_REG28__TAGLO
:
8035 case CP0_REG28__TAGLO1
:
8036 case CP0_REG28__TAGLO2
:
8037 case CP0_REG28__TAGLO3
:
8039 TCGv_i64 tmp
= tcg_temp_new_i64();
8040 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
8041 gen_move_low32(arg
, tmp
);
8042 tcg_temp_free_i64(tmp
);
8044 register_name
= "TagLo";
8046 case CP0_REG28__DATALO
:
8047 case CP0_REG28__DATALO1
:
8048 case CP0_REG28__DATALO2
:
8049 case CP0_REG28__DATALO3
:
8050 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8051 register_name
= "DataLo";
8054 goto cp0_unimplemented
;
8057 case CP0_REGISTER_29
:
8059 case CP0_REG29__TAGHI
:
8060 case CP0_REG29__TAGHI1
:
8061 case CP0_REG29__TAGHI2
:
8062 case CP0_REG29__TAGHI3
:
8063 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8064 register_name
= "TagHi";
8066 case CP0_REG29__DATAHI
:
8067 case CP0_REG29__DATAHI1
:
8068 case CP0_REG29__DATAHI2
:
8069 case CP0_REG29__DATAHI3
:
8070 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8071 register_name
= "DataHi";
8074 goto cp0_unimplemented
;
8077 case CP0_REGISTER_30
:
8079 case CP0_REG30__ERROREPC
:
8080 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8081 tcg_gen_ext32s_tl(arg
, arg
);
8082 register_name
= "ErrorEPC";
8085 goto cp0_unimplemented
;
8088 case CP0_REGISTER_31
:
8090 case CP0_REG31__DESAVE
:
8092 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8093 register_name
= "DESAVE";
8095 case CP0_REG31__KSCRATCH1
:
8096 case CP0_REG31__KSCRATCH2
:
8097 case CP0_REG31__KSCRATCH3
:
8098 case CP0_REG31__KSCRATCH4
:
8099 case CP0_REG31__KSCRATCH5
:
8100 case CP0_REG31__KSCRATCH6
:
8101 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8102 tcg_gen_ld_tl(arg
, cpu_env
,
8103 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8104 tcg_gen_ext32s_tl(arg
, arg
);
8105 register_name
= "KScratch";
8108 goto cp0_unimplemented
;
8112 goto cp0_unimplemented
;
8114 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
8118 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
8119 register_name
, reg
, sel
);
8120 gen_mfc0_unimplemented(ctx
, arg
);
8123 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8125 const char *register_name
= "invalid";
8128 check_insn(ctx
, ISA_MIPS_R1
);
8131 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8136 case CP0_REGISTER_00
:
8138 case CP0_REG00__INDEX
:
8139 gen_helper_mtc0_index(cpu_env
, arg
);
8140 register_name
= "Index";
8142 case CP0_REG00__MVPCONTROL
:
8143 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8144 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
8145 register_name
= "MVPControl";
8147 case CP0_REG00__MVPCONF0
:
8148 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8150 register_name
= "MVPConf0";
8152 case CP0_REG00__MVPCONF1
:
8153 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8155 register_name
= "MVPConf1";
8157 case CP0_REG00__VPCONTROL
:
8160 register_name
= "VPControl";
8163 goto cp0_unimplemented
;
8166 case CP0_REGISTER_01
:
8168 case CP0_REG01__RANDOM
:
8170 register_name
= "Random";
8172 case CP0_REG01__VPECONTROL
:
8173 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8174 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
8175 register_name
= "VPEControl";
8177 case CP0_REG01__VPECONF0
:
8178 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8179 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
8180 register_name
= "VPEConf0";
8182 case CP0_REG01__VPECONF1
:
8183 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8184 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
8185 register_name
= "VPEConf1";
8187 case CP0_REG01__YQMASK
:
8188 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8189 gen_helper_mtc0_yqmask(cpu_env
, arg
);
8190 register_name
= "YQMask";
8192 case CP0_REG01__VPESCHEDULE
:
8193 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8194 tcg_gen_st_tl(arg
, cpu_env
,
8195 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8196 register_name
= "VPESchedule";
8198 case CP0_REG01__VPESCHEFBACK
:
8199 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8200 tcg_gen_st_tl(arg
, cpu_env
,
8201 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8202 register_name
= "VPEScheFBack";
8204 case CP0_REG01__VPEOPT
:
8205 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8206 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
8207 register_name
= "VPEOpt";
8210 goto cp0_unimplemented
;
8213 case CP0_REGISTER_02
:
8215 case CP0_REG02__ENTRYLO0
:
8216 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
8217 register_name
= "EntryLo0";
8219 case CP0_REG02__TCSTATUS
:
8220 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8221 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
8222 register_name
= "TCStatus";
8224 case CP0_REG02__TCBIND
:
8225 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8226 gen_helper_mtc0_tcbind(cpu_env
, arg
);
8227 register_name
= "TCBind";
8229 case CP0_REG02__TCRESTART
:
8230 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8231 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
8232 register_name
= "TCRestart";
8234 case CP0_REG02__TCHALT
:
8235 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8236 gen_helper_mtc0_tchalt(cpu_env
, arg
);
8237 register_name
= "TCHalt";
8239 case CP0_REG02__TCCONTEXT
:
8240 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8241 gen_helper_mtc0_tccontext(cpu_env
, arg
);
8242 register_name
= "TCContext";
8244 case CP0_REG02__TCSCHEDULE
:
8245 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8246 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
8247 register_name
= "TCSchedule";
8249 case CP0_REG02__TCSCHEFBACK
:
8250 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8251 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
8252 register_name
= "TCScheFBack";
8255 goto cp0_unimplemented
;
8258 case CP0_REGISTER_03
:
8260 case CP0_REG03__ENTRYLO1
:
8261 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
8262 register_name
= "EntryLo1";
8264 case CP0_REG03__GLOBALNUM
:
8267 register_name
= "GlobalNumber";
8270 goto cp0_unimplemented
;
8273 case CP0_REGISTER_04
:
8275 case CP0_REG04__CONTEXT
:
8276 gen_helper_mtc0_context(cpu_env
, arg
);
8277 register_name
= "Context";
8279 case CP0_REG04__CONTEXTCONFIG
:
8281 /* gen_helper_mtc0_contextconfig(arg); */
8282 register_name
= "ContextConfig";
8283 goto cp0_unimplemented
;
8284 case CP0_REG04__USERLOCAL
:
8285 CP0_CHECK(ctx
->ulri
);
8286 tcg_gen_st_tl(arg
, cpu_env
,
8287 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8288 register_name
= "UserLocal";
8290 case CP0_REG04__MMID
:
8292 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
8293 register_name
= "MMID";
8296 goto cp0_unimplemented
;
8299 case CP0_REGISTER_05
:
8301 case CP0_REG05__PAGEMASK
:
8302 gen_helper_mtc0_pagemask(cpu_env
, arg
);
8303 register_name
= "PageMask";
8305 case CP0_REG05__PAGEGRAIN
:
8306 check_insn(ctx
, ISA_MIPS_R2
);
8307 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
8308 register_name
= "PageGrain";
8309 ctx
->base
.is_jmp
= DISAS_STOP
;
8311 case CP0_REG05__SEGCTL0
:
8313 gen_helper_mtc0_segctl0(cpu_env
, arg
);
8314 register_name
= "SegCtl0";
8316 case CP0_REG05__SEGCTL1
:
8318 gen_helper_mtc0_segctl1(cpu_env
, arg
);
8319 register_name
= "SegCtl1";
8321 case CP0_REG05__SEGCTL2
:
8323 gen_helper_mtc0_segctl2(cpu_env
, arg
);
8324 register_name
= "SegCtl2";
8326 case CP0_REG05__PWBASE
:
8328 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
8329 register_name
= "PWBase";
8331 case CP0_REG05__PWFIELD
:
8333 gen_helper_mtc0_pwfield(cpu_env
, arg
);
8334 register_name
= "PWField";
8336 case CP0_REG05__PWSIZE
:
8338 gen_helper_mtc0_pwsize(cpu_env
, arg
);
8339 register_name
= "PWSize";
8342 goto cp0_unimplemented
;
8345 case CP0_REGISTER_06
:
8347 case CP0_REG06__WIRED
:
8348 gen_helper_mtc0_wired(cpu_env
, arg
);
8349 register_name
= "Wired";
8351 case CP0_REG06__SRSCONF0
:
8352 check_insn(ctx
, ISA_MIPS_R2
);
8353 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
8354 register_name
= "SRSConf0";
8356 case CP0_REG06__SRSCONF1
:
8357 check_insn(ctx
, ISA_MIPS_R2
);
8358 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
8359 register_name
= "SRSConf1";
8361 case CP0_REG06__SRSCONF2
:
8362 check_insn(ctx
, ISA_MIPS_R2
);
8363 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
8364 register_name
= "SRSConf2";
8366 case CP0_REG06__SRSCONF3
:
8367 check_insn(ctx
, ISA_MIPS_R2
);
8368 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
8369 register_name
= "SRSConf3";
8371 case CP0_REG06__SRSCONF4
:
8372 check_insn(ctx
, ISA_MIPS_R2
);
8373 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
8374 register_name
= "SRSConf4";
8376 case CP0_REG06__PWCTL
:
8378 gen_helper_mtc0_pwctl(cpu_env
, arg
);
8379 register_name
= "PWCtl";
8382 goto cp0_unimplemented
;
8385 case CP0_REGISTER_07
:
8387 case CP0_REG07__HWRENA
:
8388 check_insn(ctx
, ISA_MIPS_R2
);
8389 gen_helper_mtc0_hwrena(cpu_env
, arg
);
8390 ctx
->base
.is_jmp
= DISAS_STOP
;
8391 register_name
= "HWREna";
8394 goto cp0_unimplemented
;
8397 case CP0_REGISTER_08
:
8399 case CP0_REG08__BADVADDR
:
8401 register_name
= "BadVAddr";
8403 case CP0_REG08__BADINSTR
:
8405 register_name
= "BadInstr";
8407 case CP0_REG08__BADINSTRP
:
8409 register_name
= "BadInstrP";
8411 case CP0_REG08__BADINSTRX
:
8413 register_name
= "BadInstrX";
8416 goto cp0_unimplemented
;
8419 case CP0_REGISTER_09
:
8421 case CP0_REG09__COUNT
:
8422 gen_helper_mtc0_count(cpu_env
, arg
);
8423 register_name
= "Count";
8425 case CP0_REG09__SAARI
:
8426 CP0_CHECK(ctx
->saar
);
8427 gen_helper_mtc0_saari(cpu_env
, arg
);
8428 register_name
= "SAARI";
8430 case CP0_REG09__SAAR
:
8431 CP0_CHECK(ctx
->saar
);
8432 gen_helper_mtc0_saar(cpu_env
, arg
);
8433 register_name
= "SAAR";
8436 goto cp0_unimplemented
;
8439 case CP0_REGISTER_10
:
8441 case CP0_REG10__ENTRYHI
:
8442 gen_helper_mtc0_entryhi(cpu_env
, arg
);
8443 register_name
= "EntryHi";
8446 goto cp0_unimplemented
;
8449 case CP0_REGISTER_11
:
8451 case CP0_REG11__COMPARE
:
8452 gen_helper_mtc0_compare(cpu_env
, arg
);
8453 register_name
= "Compare";
8455 /* 6,7 are implementation dependent */
8457 goto cp0_unimplemented
;
8460 case CP0_REGISTER_12
:
8462 case CP0_REG12__STATUS
:
8463 save_cpu_state(ctx
, 1);
8464 gen_helper_mtc0_status(cpu_env
, arg
);
8465 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8466 gen_save_pc(ctx
->base
.pc_next
+ 4);
8467 ctx
->base
.is_jmp
= DISAS_EXIT
;
8468 register_name
= "Status";
8470 case CP0_REG12__INTCTL
:
8471 check_insn(ctx
, ISA_MIPS_R2
);
8472 gen_helper_mtc0_intctl(cpu_env
, arg
);
8473 /* Stop translation as we may have switched the execution mode */
8474 ctx
->base
.is_jmp
= DISAS_STOP
;
8475 register_name
= "IntCtl";
8477 case CP0_REG12__SRSCTL
:
8478 check_insn(ctx
, ISA_MIPS_R2
);
8479 gen_helper_mtc0_srsctl(cpu_env
, arg
);
8480 /* Stop translation as we may have switched the execution mode */
8481 ctx
->base
.is_jmp
= DISAS_STOP
;
8482 register_name
= "SRSCtl";
8484 case CP0_REG12__SRSMAP
:
8485 check_insn(ctx
, ISA_MIPS_R2
);
8486 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8487 /* Stop translation as we may have switched the execution mode */
8488 ctx
->base
.is_jmp
= DISAS_STOP
;
8489 register_name
= "SRSMap";
8492 goto cp0_unimplemented
;
8495 case CP0_REGISTER_13
:
8497 case CP0_REG13__CAUSE
:
8498 save_cpu_state(ctx
, 1);
8499 gen_helper_mtc0_cause(cpu_env
, arg
);
8501 * Stop translation as we may have triggered an interrupt.
8502 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8503 * translated code to check for pending interrupts.
8505 gen_save_pc(ctx
->base
.pc_next
+ 4);
8506 ctx
->base
.is_jmp
= DISAS_EXIT
;
8507 register_name
= "Cause";
8510 goto cp0_unimplemented
;
8513 case CP0_REGISTER_14
:
8515 case CP0_REG14__EPC
:
8516 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8517 register_name
= "EPC";
8520 goto cp0_unimplemented
;
8523 case CP0_REGISTER_15
:
8525 case CP0_REG15__PRID
:
8527 register_name
= "PRid";
8529 case CP0_REG15__EBASE
:
8530 check_insn(ctx
, ISA_MIPS_R2
);
8531 gen_helper_mtc0_ebase(cpu_env
, arg
);
8532 register_name
= "EBase";
8535 goto cp0_unimplemented
;
8538 case CP0_REGISTER_16
:
8540 case CP0_REG16__CONFIG
:
8541 gen_helper_mtc0_config0(cpu_env
, arg
);
8542 register_name
= "Config";
8543 /* Stop translation as we may have switched the execution mode */
8544 ctx
->base
.is_jmp
= DISAS_STOP
;
8546 case CP0_REG16__CONFIG1
:
8547 /* ignored, read only */
8548 register_name
= "Config1";
8550 case CP0_REG16__CONFIG2
:
8551 gen_helper_mtc0_config2(cpu_env
, arg
);
8552 register_name
= "Config2";
8553 /* Stop translation as we may have switched the execution mode */
8554 ctx
->base
.is_jmp
= DISAS_STOP
;
8556 case CP0_REG16__CONFIG3
:
8557 gen_helper_mtc0_config3(cpu_env
, arg
);
8558 register_name
= "Config3";
8559 /* Stop translation as we may have switched the execution mode */
8560 ctx
->base
.is_jmp
= DISAS_STOP
;
8562 case CP0_REG16__CONFIG4
:
8563 gen_helper_mtc0_config4(cpu_env
, arg
);
8564 register_name
= "Config4";
8565 ctx
->base
.is_jmp
= DISAS_STOP
;
8567 case CP0_REG16__CONFIG5
:
8568 gen_helper_mtc0_config5(cpu_env
, arg
);
8569 register_name
= "Config5";
8570 /* Stop translation as we may have switched the execution mode */
8571 ctx
->base
.is_jmp
= DISAS_STOP
;
8573 /* 6,7 are implementation dependent */
8574 case CP0_REG16__CONFIG6
:
8576 register_name
= "Config6";
8578 case CP0_REG16__CONFIG7
:
8580 register_name
= "Config7";
8583 register_name
= "Invalid config selector";
8584 goto cp0_unimplemented
;
8587 case CP0_REGISTER_17
:
8589 case CP0_REG17__LLADDR
:
8590 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8591 register_name
= "LLAddr";
8593 case CP0_REG17__MAAR
:
8594 CP0_CHECK(ctx
->mrp
);
8595 gen_helper_mtc0_maar(cpu_env
, arg
);
8596 register_name
= "MAAR";
8598 case CP0_REG17__MAARI
:
8599 CP0_CHECK(ctx
->mrp
);
8600 gen_helper_mtc0_maari(cpu_env
, arg
);
8601 register_name
= "MAARI";
8604 goto cp0_unimplemented
;
8607 case CP0_REGISTER_18
:
8609 case CP0_REG18__WATCHLO0
:
8610 case CP0_REG18__WATCHLO1
:
8611 case CP0_REG18__WATCHLO2
:
8612 case CP0_REG18__WATCHLO3
:
8613 case CP0_REG18__WATCHLO4
:
8614 case CP0_REG18__WATCHLO5
:
8615 case CP0_REG18__WATCHLO6
:
8616 case CP0_REG18__WATCHLO7
:
8617 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8618 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8619 register_name
= "WatchLo";
8622 goto cp0_unimplemented
;
8625 case CP0_REGISTER_19
:
8627 case CP0_REG19__WATCHHI0
:
8628 case CP0_REG19__WATCHHI1
:
8629 case CP0_REG19__WATCHHI2
:
8630 case CP0_REG19__WATCHHI3
:
8631 case CP0_REG19__WATCHHI4
:
8632 case CP0_REG19__WATCHHI5
:
8633 case CP0_REG19__WATCHHI6
:
8634 case CP0_REG19__WATCHHI7
:
8635 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8636 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8637 register_name
= "WatchHi";
8640 goto cp0_unimplemented
;
8643 case CP0_REGISTER_20
:
8645 case CP0_REG20__XCONTEXT
:
8646 #if defined(TARGET_MIPS64)
8647 check_insn(ctx
, ISA_MIPS3
);
8648 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8649 register_name
= "XContext";
8653 goto cp0_unimplemented
;
8656 case CP0_REGISTER_21
:
8657 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8658 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8661 gen_helper_mtc0_framemask(cpu_env
, arg
);
8662 register_name
= "Framemask";
8665 goto cp0_unimplemented
;
8668 case CP0_REGISTER_22
:
8670 register_name
= "Diagnostic"; /* implementation dependent */
8672 case CP0_REGISTER_23
:
8674 case CP0_REG23__DEBUG
:
8675 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8676 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8677 gen_save_pc(ctx
->base
.pc_next
+ 4);
8678 ctx
->base
.is_jmp
= DISAS_EXIT
;
8679 register_name
= "Debug";
8681 case CP0_REG23__TRACECONTROL
:
8682 /* PDtrace support */
8683 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8684 register_name
= "TraceControl";
8685 /* Stop translation as we may have switched the execution mode */
8686 ctx
->base
.is_jmp
= DISAS_STOP
;
8687 goto cp0_unimplemented
;
8688 case CP0_REG23__TRACECONTROL2
:
8689 /* PDtrace support */
8690 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8691 register_name
= "TraceControl2";
8692 /* Stop translation as we may have switched the execution mode */
8693 ctx
->base
.is_jmp
= DISAS_STOP
;
8694 goto cp0_unimplemented
;
8695 case CP0_REG23__USERTRACEDATA1
:
8696 /* Stop translation as we may have switched the execution mode */
8697 ctx
->base
.is_jmp
= DISAS_STOP
;
8698 /* PDtrace support */
8699 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8700 register_name
= "UserTraceData";
8701 /* Stop translation as we may have switched the execution mode */
8702 ctx
->base
.is_jmp
= DISAS_STOP
;
8703 goto cp0_unimplemented
;
8704 case CP0_REG23__TRACEIBPC
:
8705 /* PDtrace support */
8706 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8707 /* Stop translation as we may have switched the execution mode */
8708 ctx
->base
.is_jmp
= DISAS_STOP
;
8709 register_name
= "TraceIBPC";
8710 goto cp0_unimplemented
;
8711 case CP0_REG23__TRACEDBPC
:
8712 /* PDtrace support */
8713 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8714 /* Stop translation as we may have switched the execution mode */
8715 ctx
->base
.is_jmp
= DISAS_STOP
;
8716 register_name
= "TraceDBPC";
8717 goto cp0_unimplemented
;
8719 goto cp0_unimplemented
;
8722 case CP0_REGISTER_24
:
8724 case CP0_REG24__DEPC
:
8726 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8727 register_name
= "DEPC";
8730 goto cp0_unimplemented
;
8733 case CP0_REGISTER_25
:
8735 case CP0_REG25__PERFCTL0
:
8736 gen_helper_mtc0_performance0(cpu_env
, arg
);
8737 register_name
= "Performance0";
8739 case CP0_REG25__PERFCNT0
:
8740 /* gen_helper_mtc0_performance1(arg); */
8741 register_name
= "Performance1";
8742 goto cp0_unimplemented
;
8743 case CP0_REG25__PERFCTL1
:
8744 /* gen_helper_mtc0_performance2(arg); */
8745 register_name
= "Performance2";
8746 goto cp0_unimplemented
;
8747 case CP0_REG25__PERFCNT1
:
8748 /* gen_helper_mtc0_performance3(arg); */
8749 register_name
= "Performance3";
8750 goto cp0_unimplemented
;
8751 case CP0_REG25__PERFCTL2
:
8752 /* gen_helper_mtc0_performance4(arg); */
8753 register_name
= "Performance4";
8754 goto cp0_unimplemented
;
8755 case CP0_REG25__PERFCNT2
:
8756 /* gen_helper_mtc0_performance5(arg); */
8757 register_name
= "Performance5";
8758 goto cp0_unimplemented
;
8759 case CP0_REG25__PERFCTL3
:
8760 /* gen_helper_mtc0_performance6(arg); */
8761 register_name
= "Performance6";
8762 goto cp0_unimplemented
;
8763 case CP0_REG25__PERFCNT3
:
8764 /* gen_helper_mtc0_performance7(arg); */
8765 register_name
= "Performance7";
8766 goto cp0_unimplemented
;
8768 goto cp0_unimplemented
;
8771 case CP0_REGISTER_26
:
8773 case CP0_REG26__ERRCTL
:
8774 gen_helper_mtc0_errctl(cpu_env
, arg
);
8775 ctx
->base
.is_jmp
= DISAS_STOP
;
8776 register_name
= "ErrCtl";
8779 goto cp0_unimplemented
;
8782 case CP0_REGISTER_27
:
8784 case CP0_REG27__CACHERR
:
8786 register_name
= "CacheErr";
8789 goto cp0_unimplemented
;
8792 case CP0_REGISTER_28
:
8794 case CP0_REG28__TAGLO
:
8795 case CP0_REG28__TAGLO1
:
8796 case CP0_REG28__TAGLO2
:
8797 case CP0_REG28__TAGLO3
:
8798 gen_helper_mtc0_taglo(cpu_env
, arg
);
8799 register_name
= "TagLo";
8801 case CP0_REG28__DATALO
:
8802 case CP0_REG28__DATALO1
:
8803 case CP0_REG28__DATALO2
:
8804 case CP0_REG28__DATALO3
:
8805 gen_helper_mtc0_datalo(cpu_env
, arg
);
8806 register_name
= "DataLo";
8809 goto cp0_unimplemented
;
8812 case CP0_REGISTER_29
:
8814 case CP0_REG29__TAGHI
:
8815 case CP0_REG29__TAGHI1
:
8816 case CP0_REG29__TAGHI2
:
8817 case CP0_REG29__TAGHI3
:
8818 gen_helper_mtc0_taghi(cpu_env
, arg
);
8819 register_name
= "TagHi";
8821 case CP0_REG29__DATAHI
:
8822 case CP0_REG29__DATAHI1
:
8823 case CP0_REG29__DATAHI2
:
8824 case CP0_REG29__DATAHI3
:
8825 gen_helper_mtc0_datahi(cpu_env
, arg
);
8826 register_name
= "DataHi";
8829 register_name
= "invalid sel";
8830 goto cp0_unimplemented
;
8833 case CP0_REGISTER_30
:
8835 case CP0_REG30__ERROREPC
:
8836 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8837 register_name
= "ErrorEPC";
8840 goto cp0_unimplemented
;
8843 case CP0_REGISTER_31
:
8845 case CP0_REG31__DESAVE
:
8847 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8848 register_name
= "DESAVE";
8850 case CP0_REG31__KSCRATCH1
:
8851 case CP0_REG31__KSCRATCH2
:
8852 case CP0_REG31__KSCRATCH3
:
8853 case CP0_REG31__KSCRATCH4
:
8854 case CP0_REG31__KSCRATCH5
:
8855 case CP0_REG31__KSCRATCH6
:
8856 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8857 tcg_gen_st_tl(arg
, cpu_env
,
8858 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8859 register_name
= "KScratch";
8862 goto cp0_unimplemented
;
8866 goto cp0_unimplemented
;
8868 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8870 /* For simplicity assume that all writes can cause interrupts. */
8871 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8873 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8874 * translated code to check for pending interrupts.
8876 gen_save_pc(ctx
->base
.pc_next
+ 4);
8877 ctx
->base
.is_jmp
= DISAS_EXIT
;
8882 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8883 register_name
, reg
, sel
);
8886 #if defined(TARGET_MIPS64)
8887 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8889 const char *register_name
= "invalid";
8892 check_insn(ctx
, ISA_MIPS_R1
);
8896 case CP0_REGISTER_00
:
8898 case CP0_REG00__INDEX
:
8899 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8900 register_name
= "Index";
8902 case CP0_REG00__MVPCONTROL
:
8903 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8904 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8905 register_name
= "MVPControl";
8907 case CP0_REG00__MVPCONF0
:
8908 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8909 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8910 register_name
= "MVPConf0";
8912 case CP0_REG00__MVPCONF1
:
8913 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8914 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8915 register_name
= "MVPConf1";
8917 case CP0_REG00__VPCONTROL
:
8919 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8920 register_name
= "VPControl";
8923 goto cp0_unimplemented
;
8926 case CP0_REGISTER_01
:
8928 case CP0_REG01__RANDOM
:
8929 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
8930 gen_helper_mfc0_random(arg
, cpu_env
);
8931 register_name
= "Random";
8933 case CP0_REG01__VPECONTROL
:
8934 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8935 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8936 register_name
= "VPEControl";
8938 case CP0_REG01__VPECONF0
:
8939 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8940 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8941 register_name
= "VPEConf0";
8943 case CP0_REG01__VPECONF1
:
8944 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8945 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
8946 register_name
= "VPEConf1";
8948 case CP0_REG01__YQMASK
:
8949 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8950 tcg_gen_ld_tl(arg
, cpu_env
,
8951 offsetof(CPUMIPSState
, CP0_YQMask
));
8952 register_name
= "YQMask";
8954 case CP0_REG01__VPESCHEDULE
:
8955 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8956 tcg_gen_ld_tl(arg
, cpu_env
,
8957 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8958 register_name
= "VPESchedule";
8960 case CP0_REG01__VPESCHEFBACK
:
8961 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8962 tcg_gen_ld_tl(arg
, cpu_env
,
8963 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8964 register_name
= "VPEScheFBack";
8966 case CP0_REG01__VPEOPT
:
8967 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8968 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
8969 register_name
= "VPEOpt";
8972 goto cp0_unimplemented
;
8975 case CP0_REGISTER_02
:
8977 case CP0_REG02__ENTRYLO0
:
8978 tcg_gen_ld_tl(arg
, cpu_env
,
8979 offsetof(CPUMIPSState
, CP0_EntryLo0
));
8980 register_name
= "EntryLo0";
8982 case CP0_REG02__TCSTATUS
:
8983 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8984 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
8985 register_name
= "TCStatus";
8987 case CP0_REG02__TCBIND
:
8988 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8989 gen_helper_mfc0_tcbind(arg
, cpu_env
);
8990 register_name
= "TCBind";
8992 case CP0_REG02__TCRESTART
:
8993 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8994 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
8995 register_name
= "TCRestart";
8997 case CP0_REG02__TCHALT
:
8998 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8999 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
9000 register_name
= "TCHalt";
9002 case CP0_REG02__TCCONTEXT
:
9003 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9004 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
9005 register_name
= "TCContext";
9007 case CP0_REG02__TCSCHEDULE
:
9008 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9009 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
9010 register_name
= "TCSchedule";
9012 case CP0_REG02__TCSCHEFBACK
:
9013 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9014 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
9015 register_name
= "TCScheFBack";
9018 goto cp0_unimplemented
;
9021 case CP0_REGISTER_03
:
9023 case CP0_REG03__ENTRYLO1
:
9024 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
9025 register_name
= "EntryLo1";
9027 case CP0_REG03__GLOBALNUM
:
9029 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
9030 register_name
= "GlobalNumber";
9033 goto cp0_unimplemented
;
9036 case CP0_REGISTER_04
:
9038 case CP0_REG04__CONTEXT
:
9039 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
9040 register_name
= "Context";
9042 case CP0_REG04__CONTEXTCONFIG
:
9044 /* gen_helper_dmfc0_contextconfig(arg); */
9045 register_name
= "ContextConfig";
9046 goto cp0_unimplemented
;
9047 case CP0_REG04__USERLOCAL
:
9048 CP0_CHECK(ctx
->ulri
);
9049 tcg_gen_ld_tl(arg
, cpu_env
,
9050 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9051 register_name
= "UserLocal";
9053 case CP0_REG04__MMID
:
9055 gen_helper_mtc0_memorymapid(cpu_env
, arg
);
9056 register_name
= "MMID";
9059 goto cp0_unimplemented
;
9062 case CP0_REGISTER_05
:
9064 case CP0_REG05__PAGEMASK
:
9065 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
9066 register_name
= "PageMask";
9068 case CP0_REG05__PAGEGRAIN
:
9069 check_insn(ctx
, ISA_MIPS_R2
);
9070 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
9071 register_name
= "PageGrain";
9073 case CP0_REG05__SEGCTL0
:
9075 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
9076 register_name
= "SegCtl0";
9078 case CP0_REG05__SEGCTL1
:
9080 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
9081 register_name
= "SegCtl1";
9083 case CP0_REG05__SEGCTL2
:
9085 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
9086 register_name
= "SegCtl2";
9088 case CP0_REG05__PWBASE
:
9090 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9091 register_name
= "PWBase";
9093 case CP0_REG05__PWFIELD
:
9095 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
9096 register_name
= "PWField";
9098 case CP0_REG05__PWSIZE
:
9100 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
9101 register_name
= "PWSize";
9104 goto cp0_unimplemented
;
9107 case CP0_REGISTER_06
:
9109 case CP0_REG06__WIRED
:
9110 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
9111 register_name
= "Wired";
9113 case CP0_REG06__SRSCONF0
:
9114 check_insn(ctx
, ISA_MIPS_R2
);
9115 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
9116 register_name
= "SRSConf0";
9118 case CP0_REG06__SRSCONF1
:
9119 check_insn(ctx
, ISA_MIPS_R2
);
9120 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
9121 register_name
= "SRSConf1";
9123 case CP0_REG06__SRSCONF2
:
9124 check_insn(ctx
, ISA_MIPS_R2
);
9125 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
9126 register_name
= "SRSConf2";
9128 case CP0_REG06__SRSCONF3
:
9129 check_insn(ctx
, ISA_MIPS_R2
);
9130 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
9131 register_name
= "SRSConf3";
9133 case CP0_REG06__SRSCONF4
:
9134 check_insn(ctx
, ISA_MIPS_R2
);
9135 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
9136 register_name
= "SRSConf4";
9138 case CP0_REG06__PWCTL
:
9140 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
9141 register_name
= "PWCtl";
9144 goto cp0_unimplemented
;
9147 case CP0_REGISTER_07
:
9149 case CP0_REG07__HWRENA
:
9150 check_insn(ctx
, ISA_MIPS_R2
);
9151 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
9152 register_name
= "HWREna";
9155 goto cp0_unimplemented
;
9158 case CP0_REGISTER_08
:
9160 case CP0_REG08__BADVADDR
:
9161 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
9162 register_name
= "BadVAddr";
9164 case CP0_REG08__BADINSTR
:
9166 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
9167 register_name
= "BadInstr";
9169 case CP0_REG08__BADINSTRP
:
9171 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
9172 register_name
= "BadInstrP";
9174 case CP0_REG08__BADINSTRX
:
9176 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
9177 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
9178 register_name
= "BadInstrX";
9181 goto cp0_unimplemented
;
9184 case CP0_REGISTER_09
:
9186 case CP0_REG09__COUNT
:
9187 /* Mark as an IO operation because we read the time. */
9188 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9191 gen_helper_mfc0_count(arg
, cpu_env
);
9193 * Break the TB to be able to take timer interrupts immediately
9194 * after reading count. DISAS_STOP isn't sufficient, we need to
9195 * ensure we break completely out of translated code.
9197 gen_save_pc(ctx
->base
.pc_next
+ 4);
9198 ctx
->base
.is_jmp
= DISAS_EXIT
;
9199 register_name
= "Count";
9201 case CP0_REG09__SAARI
:
9202 CP0_CHECK(ctx
->saar
);
9203 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
9204 register_name
= "SAARI";
9206 case CP0_REG09__SAAR
:
9207 CP0_CHECK(ctx
->saar
);
9208 gen_helper_dmfc0_saar(arg
, cpu_env
);
9209 register_name
= "SAAR";
9212 goto cp0_unimplemented
;
9215 case CP0_REGISTER_10
:
9217 case CP0_REG10__ENTRYHI
:
9218 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
9219 register_name
= "EntryHi";
9222 goto cp0_unimplemented
;
9225 case CP0_REGISTER_11
:
9227 case CP0_REG11__COMPARE
:
9228 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
9229 register_name
= "Compare";
9231 /* 6,7 are implementation dependent */
9233 goto cp0_unimplemented
;
9236 case CP0_REGISTER_12
:
9238 case CP0_REG12__STATUS
:
9239 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
9240 register_name
= "Status";
9242 case CP0_REG12__INTCTL
:
9243 check_insn(ctx
, ISA_MIPS_R2
);
9244 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
9245 register_name
= "IntCtl";
9247 case CP0_REG12__SRSCTL
:
9248 check_insn(ctx
, ISA_MIPS_R2
);
9249 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
9250 register_name
= "SRSCtl";
9252 case CP0_REG12__SRSMAP
:
9253 check_insn(ctx
, ISA_MIPS_R2
);
9254 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9255 register_name
= "SRSMap";
9258 goto cp0_unimplemented
;
9261 case CP0_REGISTER_13
:
9263 case CP0_REG13__CAUSE
:
9264 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
9265 register_name
= "Cause";
9268 goto cp0_unimplemented
;
9271 case CP0_REGISTER_14
:
9273 case CP0_REG14__EPC
:
9274 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9275 register_name
= "EPC";
9278 goto cp0_unimplemented
;
9281 case CP0_REGISTER_15
:
9283 case CP0_REG15__PRID
:
9284 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
9285 register_name
= "PRid";
9287 case CP0_REG15__EBASE
:
9288 check_insn(ctx
, ISA_MIPS_R2
);
9289 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
9290 register_name
= "EBase";
9292 case CP0_REG15__CMGCRBASE
:
9293 check_insn(ctx
, ISA_MIPS_R2
);
9294 CP0_CHECK(ctx
->cmgcr
);
9295 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
9296 register_name
= "CMGCRBase";
9299 goto cp0_unimplemented
;
9302 case CP0_REGISTER_16
:
9304 case CP0_REG16__CONFIG
:
9305 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
9306 register_name
= "Config";
9308 case CP0_REG16__CONFIG1
:
9309 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
9310 register_name
= "Config1";
9312 case CP0_REG16__CONFIG2
:
9313 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
9314 register_name
= "Config2";
9316 case CP0_REG16__CONFIG3
:
9317 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
9318 register_name
= "Config3";
9320 case CP0_REG16__CONFIG4
:
9321 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
9322 register_name
= "Config4";
9324 case CP0_REG16__CONFIG5
:
9325 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
9326 register_name
= "Config5";
9328 /* 6,7 are implementation dependent */
9329 case CP0_REG16__CONFIG6
:
9330 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
9331 register_name
= "Config6";
9333 case CP0_REG16__CONFIG7
:
9334 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
9335 register_name
= "Config7";
9338 goto cp0_unimplemented
;
9341 case CP0_REGISTER_17
:
9343 case CP0_REG17__LLADDR
:
9344 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
9345 register_name
= "LLAddr";
9347 case CP0_REG17__MAAR
:
9348 CP0_CHECK(ctx
->mrp
);
9349 gen_helper_dmfc0_maar(arg
, cpu_env
);
9350 register_name
= "MAAR";
9352 case CP0_REG17__MAARI
:
9353 CP0_CHECK(ctx
->mrp
);
9354 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
9355 register_name
= "MAARI";
9358 goto cp0_unimplemented
;
9361 case CP0_REGISTER_18
:
9363 case CP0_REG18__WATCHLO0
:
9364 case CP0_REG18__WATCHLO1
:
9365 case CP0_REG18__WATCHLO2
:
9366 case CP0_REG18__WATCHLO3
:
9367 case CP0_REG18__WATCHLO4
:
9368 case CP0_REG18__WATCHLO5
:
9369 case CP0_REG18__WATCHLO6
:
9370 case CP0_REG18__WATCHLO7
:
9371 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9372 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
9373 register_name
= "WatchLo";
9376 goto cp0_unimplemented
;
9379 case CP0_REGISTER_19
:
9381 case CP0_REG19__WATCHHI0
:
9382 case CP0_REG19__WATCHHI1
:
9383 case CP0_REG19__WATCHHI2
:
9384 case CP0_REG19__WATCHHI3
:
9385 case CP0_REG19__WATCHHI4
:
9386 case CP0_REG19__WATCHHI5
:
9387 case CP0_REG19__WATCHHI6
:
9388 case CP0_REG19__WATCHHI7
:
9389 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9390 gen_helper_1e0i(dmfc0_watchhi
, arg
, sel
);
9391 register_name
= "WatchHi";
9394 goto cp0_unimplemented
;
9397 case CP0_REGISTER_20
:
9399 case CP0_REG20__XCONTEXT
:
9400 check_insn(ctx
, ISA_MIPS3
);
9401 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
9402 register_name
= "XContext";
9405 goto cp0_unimplemented
;
9408 case CP0_REGISTER_21
:
9409 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9410 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
9413 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
9414 register_name
= "Framemask";
9417 goto cp0_unimplemented
;
9420 case CP0_REGISTER_22
:
9421 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9422 register_name
= "'Diagnostic"; /* implementation dependent */
9424 case CP0_REGISTER_23
:
9426 case CP0_REG23__DEBUG
:
9427 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
9428 register_name
= "Debug";
9430 case CP0_REG23__TRACECONTROL
:
9431 /* PDtrace support */
9432 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
9433 register_name
= "TraceControl";
9434 goto cp0_unimplemented
;
9435 case CP0_REG23__TRACECONTROL2
:
9436 /* PDtrace support */
9437 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
9438 register_name
= "TraceControl2";
9439 goto cp0_unimplemented
;
9440 case CP0_REG23__USERTRACEDATA1
:
9441 /* PDtrace support */
9442 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
9443 register_name
= "UserTraceData1";
9444 goto cp0_unimplemented
;
9445 case CP0_REG23__TRACEIBPC
:
9446 /* PDtrace support */
9447 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
9448 register_name
= "TraceIBPC";
9449 goto cp0_unimplemented
;
9450 case CP0_REG23__TRACEDBPC
:
9451 /* PDtrace support */
9452 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
9453 register_name
= "TraceDBPC";
9454 goto cp0_unimplemented
;
9456 goto cp0_unimplemented
;
9459 case CP0_REGISTER_24
:
9461 case CP0_REG24__DEPC
:
9463 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9464 register_name
= "DEPC";
9467 goto cp0_unimplemented
;
9470 case CP0_REGISTER_25
:
9472 case CP0_REG25__PERFCTL0
:
9473 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
9474 register_name
= "Performance0";
9476 case CP0_REG25__PERFCNT0
:
9477 /* gen_helper_dmfc0_performance1(arg); */
9478 register_name
= "Performance1";
9479 goto cp0_unimplemented
;
9480 case CP0_REG25__PERFCTL1
:
9481 /* gen_helper_dmfc0_performance2(arg); */
9482 register_name
= "Performance2";
9483 goto cp0_unimplemented
;
9484 case CP0_REG25__PERFCNT1
:
9485 /* gen_helper_dmfc0_performance3(arg); */
9486 register_name
= "Performance3";
9487 goto cp0_unimplemented
;
9488 case CP0_REG25__PERFCTL2
:
9489 /* gen_helper_dmfc0_performance4(arg); */
9490 register_name
= "Performance4";
9491 goto cp0_unimplemented
;
9492 case CP0_REG25__PERFCNT2
:
9493 /* gen_helper_dmfc0_performance5(arg); */
9494 register_name
= "Performance5";
9495 goto cp0_unimplemented
;
9496 case CP0_REG25__PERFCTL3
:
9497 /* gen_helper_dmfc0_performance6(arg); */
9498 register_name
= "Performance6";
9499 goto cp0_unimplemented
;
9500 case CP0_REG25__PERFCNT3
:
9501 /* gen_helper_dmfc0_performance7(arg); */
9502 register_name
= "Performance7";
9503 goto cp0_unimplemented
;
9505 goto cp0_unimplemented
;
9508 case CP0_REGISTER_26
:
9510 case CP0_REG26__ERRCTL
:
9511 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
9512 register_name
= "ErrCtl";
9515 goto cp0_unimplemented
;
9518 case CP0_REGISTER_27
:
9521 case CP0_REG27__CACHERR
:
9522 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
9523 register_name
= "CacheErr";
9526 goto cp0_unimplemented
;
9529 case CP0_REGISTER_28
:
9531 case CP0_REG28__TAGLO
:
9532 case CP0_REG28__TAGLO1
:
9533 case CP0_REG28__TAGLO2
:
9534 case CP0_REG28__TAGLO3
:
9535 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
9536 register_name
= "TagLo";
9538 case CP0_REG28__DATALO
:
9539 case CP0_REG28__DATALO1
:
9540 case CP0_REG28__DATALO2
:
9541 case CP0_REG28__DATALO3
:
9542 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
9543 register_name
= "DataLo";
9546 goto cp0_unimplemented
;
9549 case CP0_REGISTER_29
:
9551 case CP0_REG29__TAGHI
:
9552 case CP0_REG29__TAGHI1
:
9553 case CP0_REG29__TAGHI2
:
9554 case CP0_REG29__TAGHI3
:
9555 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
9556 register_name
= "TagHi";
9558 case CP0_REG29__DATAHI
:
9559 case CP0_REG29__DATAHI1
:
9560 case CP0_REG29__DATAHI2
:
9561 case CP0_REG29__DATAHI3
:
9562 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
9563 register_name
= "DataHi";
9566 goto cp0_unimplemented
;
9569 case CP0_REGISTER_30
:
9571 case CP0_REG30__ERROREPC
:
9572 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9573 register_name
= "ErrorEPC";
9576 goto cp0_unimplemented
;
9579 case CP0_REGISTER_31
:
9581 case CP0_REG31__DESAVE
:
9583 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9584 register_name
= "DESAVE";
9586 case CP0_REG31__KSCRATCH1
:
9587 case CP0_REG31__KSCRATCH2
:
9588 case CP0_REG31__KSCRATCH3
:
9589 case CP0_REG31__KSCRATCH4
:
9590 case CP0_REG31__KSCRATCH5
:
9591 case CP0_REG31__KSCRATCH6
:
9592 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9593 tcg_gen_ld_tl(arg
, cpu_env
,
9594 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9595 register_name
= "KScratch";
9598 goto cp0_unimplemented
;
9602 goto cp0_unimplemented
;
9604 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9608 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9609 register_name
, reg
, sel
);
9610 gen_mfc0_unimplemented(ctx
, arg
);
9613 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9615 const char *register_name
= "invalid";
9618 check_insn(ctx
, ISA_MIPS_R1
);
9621 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9626 case CP0_REGISTER_00
:
9628 case CP0_REG00__INDEX
:
9629 gen_helper_mtc0_index(cpu_env
, arg
);
9630 register_name
= "Index";
9632 case CP0_REG00__MVPCONTROL
:
9633 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9634 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9635 register_name
= "MVPControl";
9637 case CP0_REG00__MVPCONF0
:
9638 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9640 register_name
= "MVPConf0";
9642 case CP0_REG00__MVPCONF1
:
9643 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9645 register_name
= "MVPConf1";
9647 case CP0_REG00__VPCONTROL
:
9650 register_name
= "VPControl";
9653 goto cp0_unimplemented
;
9656 case CP0_REGISTER_01
:
9658 case CP0_REG01__RANDOM
:
9660 register_name
= "Random";
9662 case CP0_REG01__VPECONTROL
:
9663 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9664 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9665 register_name
= "VPEControl";
9667 case CP0_REG01__VPECONF0
:
9668 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9669 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9670 register_name
= "VPEConf0";
9672 case CP0_REG01__VPECONF1
:
9673 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9674 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9675 register_name
= "VPEConf1";
9677 case CP0_REG01__YQMASK
:
9678 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9679 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9680 register_name
= "YQMask";
9682 case CP0_REG01__VPESCHEDULE
:
9683 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9684 tcg_gen_st_tl(arg
, cpu_env
,
9685 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9686 register_name
= "VPESchedule";
9688 case CP0_REG01__VPESCHEFBACK
:
9689 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9690 tcg_gen_st_tl(arg
, cpu_env
,
9691 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9692 register_name
= "VPEScheFBack";
9694 case CP0_REG01__VPEOPT
:
9695 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9696 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9697 register_name
= "VPEOpt";
9700 goto cp0_unimplemented
;
9703 case CP0_REGISTER_02
:
9705 case CP0_REG02__ENTRYLO0
:
9706 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9707 register_name
= "EntryLo0";
9709 case CP0_REG02__TCSTATUS
:
9710 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9711 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9712 register_name
= "TCStatus";
9714 case CP0_REG02__TCBIND
:
9715 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9716 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9717 register_name
= "TCBind";
9719 case CP0_REG02__TCRESTART
:
9720 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9721 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9722 register_name
= "TCRestart";
9724 case CP0_REG02__TCHALT
:
9725 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9726 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9727 register_name
= "TCHalt";
9729 case CP0_REG02__TCCONTEXT
:
9730 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9731 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9732 register_name
= "TCContext";
9734 case CP0_REG02__TCSCHEDULE
:
9735 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9736 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9737 register_name
= "TCSchedule";
9739 case CP0_REG02__TCSCHEFBACK
:
9740 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9741 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9742 register_name
= "TCScheFBack";
9745 goto cp0_unimplemented
;
9748 case CP0_REGISTER_03
:
9750 case CP0_REG03__ENTRYLO1
:
9751 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9752 register_name
= "EntryLo1";
9754 case CP0_REG03__GLOBALNUM
:
9757 register_name
= "GlobalNumber";
9760 goto cp0_unimplemented
;
9763 case CP0_REGISTER_04
:
9765 case CP0_REG04__CONTEXT
:
9766 gen_helper_mtc0_context(cpu_env
, arg
);
9767 register_name
= "Context";
9769 case CP0_REG04__CONTEXTCONFIG
:
9771 /* gen_helper_dmtc0_contextconfig(arg); */
9772 register_name
= "ContextConfig";
9773 goto cp0_unimplemented
;
9774 case CP0_REG04__USERLOCAL
:
9775 CP0_CHECK(ctx
->ulri
);
9776 tcg_gen_st_tl(arg
, cpu_env
,
9777 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9778 register_name
= "UserLocal";
9780 case CP0_REG04__MMID
:
9782 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MemoryMapID
));
9783 register_name
= "MMID";
9786 goto cp0_unimplemented
;
9789 case CP0_REGISTER_05
:
9791 case CP0_REG05__PAGEMASK
:
9792 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9793 register_name
= "PageMask";
9795 case CP0_REG05__PAGEGRAIN
:
9796 check_insn(ctx
, ISA_MIPS_R2
);
9797 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9798 register_name
= "PageGrain";
9800 case CP0_REG05__SEGCTL0
:
9802 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9803 register_name
= "SegCtl0";
9805 case CP0_REG05__SEGCTL1
:
9807 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9808 register_name
= "SegCtl1";
9810 case CP0_REG05__SEGCTL2
:
9812 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9813 register_name
= "SegCtl2";
9815 case CP0_REG05__PWBASE
:
9817 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9818 register_name
= "PWBase";
9820 case CP0_REG05__PWFIELD
:
9822 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9823 register_name
= "PWField";
9825 case CP0_REG05__PWSIZE
:
9827 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9828 register_name
= "PWSize";
9831 goto cp0_unimplemented
;
9834 case CP0_REGISTER_06
:
9836 case CP0_REG06__WIRED
:
9837 gen_helper_mtc0_wired(cpu_env
, arg
);
9838 register_name
= "Wired";
9840 case CP0_REG06__SRSCONF0
:
9841 check_insn(ctx
, ISA_MIPS_R2
);
9842 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9843 register_name
= "SRSConf0";
9845 case CP0_REG06__SRSCONF1
:
9846 check_insn(ctx
, ISA_MIPS_R2
);
9847 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9848 register_name
= "SRSConf1";
9850 case CP0_REG06__SRSCONF2
:
9851 check_insn(ctx
, ISA_MIPS_R2
);
9852 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9853 register_name
= "SRSConf2";
9855 case CP0_REG06__SRSCONF3
:
9856 check_insn(ctx
, ISA_MIPS_R2
);
9857 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9858 register_name
= "SRSConf3";
9860 case CP0_REG06__SRSCONF4
:
9861 check_insn(ctx
, ISA_MIPS_R2
);
9862 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9863 register_name
= "SRSConf4";
9865 case CP0_REG06__PWCTL
:
9867 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9868 register_name
= "PWCtl";
9871 goto cp0_unimplemented
;
9874 case CP0_REGISTER_07
:
9876 case CP0_REG07__HWRENA
:
9877 check_insn(ctx
, ISA_MIPS_R2
);
9878 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9879 ctx
->base
.is_jmp
= DISAS_STOP
;
9880 register_name
= "HWREna";
9883 goto cp0_unimplemented
;
9886 case CP0_REGISTER_08
:
9888 case CP0_REG08__BADVADDR
:
9890 register_name
= "BadVAddr";
9892 case CP0_REG08__BADINSTR
:
9894 register_name
= "BadInstr";
9896 case CP0_REG08__BADINSTRP
:
9898 register_name
= "BadInstrP";
9900 case CP0_REG08__BADINSTRX
:
9902 register_name
= "BadInstrX";
9905 goto cp0_unimplemented
;
9908 case CP0_REGISTER_09
:
9910 case CP0_REG09__COUNT
:
9911 gen_helper_mtc0_count(cpu_env
, arg
);
9912 register_name
= "Count";
9914 case CP0_REG09__SAARI
:
9915 CP0_CHECK(ctx
->saar
);
9916 gen_helper_mtc0_saari(cpu_env
, arg
);
9917 register_name
= "SAARI";
9919 case CP0_REG09__SAAR
:
9920 CP0_CHECK(ctx
->saar
);
9921 gen_helper_mtc0_saar(cpu_env
, arg
);
9922 register_name
= "SAAR";
9925 goto cp0_unimplemented
;
9927 /* Stop translation as we may have switched the execution mode */
9928 ctx
->base
.is_jmp
= DISAS_STOP
;
9930 case CP0_REGISTER_10
:
9932 case CP0_REG10__ENTRYHI
:
9933 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9934 register_name
= "EntryHi";
9937 goto cp0_unimplemented
;
9940 case CP0_REGISTER_11
:
9942 case CP0_REG11__COMPARE
:
9943 gen_helper_mtc0_compare(cpu_env
, arg
);
9944 register_name
= "Compare";
9946 /* 6,7 are implementation dependent */
9948 goto cp0_unimplemented
;
9950 /* Stop translation as we may have switched the execution mode */
9951 ctx
->base
.is_jmp
= DISAS_STOP
;
9953 case CP0_REGISTER_12
:
9955 case CP0_REG12__STATUS
:
9956 save_cpu_state(ctx
, 1);
9957 gen_helper_mtc0_status(cpu_env
, arg
);
9958 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9959 gen_save_pc(ctx
->base
.pc_next
+ 4);
9960 ctx
->base
.is_jmp
= DISAS_EXIT
;
9961 register_name
= "Status";
9963 case CP0_REG12__INTCTL
:
9964 check_insn(ctx
, ISA_MIPS_R2
);
9965 gen_helper_mtc0_intctl(cpu_env
, arg
);
9966 /* Stop translation as we may have switched the execution mode */
9967 ctx
->base
.is_jmp
= DISAS_STOP
;
9968 register_name
= "IntCtl";
9970 case CP0_REG12__SRSCTL
:
9971 check_insn(ctx
, ISA_MIPS_R2
);
9972 gen_helper_mtc0_srsctl(cpu_env
, arg
);
9973 /* Stop translation as we may have switched the execution mode */
9974 ctx
->base
.is_jmp
= DISAS_STOP
;
9975 register_name
= "SRSCtl";
9977 case CP0_REG12__SRSMAP
:
9978 check_insn(ctx
, ISA_MIPS_R2
);
9979 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9980 /* Stop translation as we may have switched the execution mode */
9981 ctx
->base
.is_jmp
= DISAS_STOP
;
9982 register_name
= "SRSMap";
9985 goto cp0_unimplemented
;
9988 case CP0_REGISTER_13
:
9990 case CP0_REG13__CAUSE
:
9991 save_cpu_state(ctx
, 1);
9992 gen_helper_mtc0_cause(cpu_env
, arg
);
9994 * Stop translation as we may have triggered an interrupt.
9995 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9996 * translated code to check for pending interrupts.
9998 gen_save_pc(ctx
->base
.pc_next
+ 4);
9999 ctx
->base
.is_jmp
= DISAS_EXIT
;
10000 register_name
= "Cause";
10003 goto cp0_unimplemented
;
10006 case CP0_REGISTER_14
:
10008 case CP0_REG14__EPC
:
10009 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
10010 register_name
= "EPC";
10013 goto cp0_unimplemented
;
10016 case CP0_REGISTER_15
:
10018 case CP0_REG15__PRID
:
10020 register_name
= "PRid";
10022 case CP0_REG15__EBASE
:
10023 check_insn(ctx
, ISA_MIPS_R2
);
10024 gen_helper_mtc0_ebase(cpu_env
, arg
);
10025 register_name
= "EBase";
10028 goto cp0_unimplemented
;
10031 case CP0_REGISTER_16
:
10033 case CP0_REG16__CONFIG
:
10034 gen_helper_mtc0_config0(cpu_env
, arg
);
10035 register_name
= "Config";
10036 /* Stop translation as we may have switched the execution mode */
10037 ctx
->base
.is_jmp
= DISAS_STOP
;
10039 case CP0_REG16__CONFIG1
:
10040 /* ignored, read only */
10041 register_name
= "Config1";
10043 case CP0_REG16__CONFIG2
:
10044 gen_helper_mtc0_config2(cpu_env
, arg
);
10045 register_name
= "Config2";
10046 /* Stop translation as we may have switched the execution mode */
10047 ctx
->base
.is_jmp
= DISAS_STOP
;
10049 case CP0_REG16__CONFIG3
:
10050 gen_helper_mtc0_config3(cpu_env
, arg
);
10051 register_name
= "Config3";
10052 /* Stop translation as we may have switched the execution mode */
10053 ctx
->base
.is_jmp
= DISAS_STOP
;
10055 case CP0_REG16__CONFIG4
:
10056 /* currently ignored */
10057 register_name
= "Config4";
10059 case CP0_REG16__CONFIG5
:
10060 gen_helper_mtc0_config5(cpu_env
, arg
);
10061 register_name
= "Config5";
10062 /* Stop translation as we may have switched the execution mode */
10063 ctx
->base
.is_jmp
= DISAS_STOP
;
10065 /* 6,7 are implementation dependent */
10067 register_name
= "Invalid config selector";
10068 goto cp0_unimplemented
;
10071 case CP0_REGISTER_17
:
10073 case CP0_REG17__LLADDR
:
10074 gen_helper_mtc0_lladdr(cpu_env
, arg
);
10075 register_name
= "LLAddr";
10077 case CP0_REG17__MAAR
:
10078 CP0_CHECK(ctx
->mrp
);
10079 gen_helper_mtc0_maar(cpu_env
, arg
);
10080 register_name
= "MAAR";
10082 case CP0_REG17__MAARI
:
10083 CP0_CHECK(ctx
->mrp
);
10084 gen_helper_mtc0_maari(cpu_env
, arg
);
10085 register_name
= "MAARI";
10088 goto cp0_unimplemented
;
10091 case CP0_REGISTER_18
:
10093 case CP0_REG18__WATCHLO0
:
10094 case CP0_REG18__WATCHLO1
:
10095 case CP0_REG18__WATCHLO2
:
10096 case CP0_REG18__WATCHLO3
:
10097 case CP0_REG18__WATCHLO4
:
10098 case CP0_REG18__WATCHLO5
:
10099 case CP0_REG18__WATCHLO6
:
10100 case CP0_REG18__WATCHLO7
:
10101 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
10102 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
10103 register_name
= "WatchLo";
10106 goto cp0_unimplemented
;
10109 case CP0_REGISTER_19
:
10111 case CP0_REG19__WATCHHI0
:
10112 case CP0_REG19__WATCHHI1
:
10113 case CP0_REG19__WATCHHI2
:
10114 case CP0_REG19__WATCHHI3
:
10115 case CP0_REG19__WATCHHI4
:
10116 case CP0_REG19__WATCHHI5
:
10117 case CP0_REG19__WATCHHI6
:
10118 case CP0_REG19__WATCHHI7
:
10119 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
10120 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
10121 register_name
= "WatchHi";
10124 goto cp0_unimplemented
;
10127 case CP0_REGISTER_20
:
10129 case CP0_REG20__XCONTEXT
:
10130 check_insn(ctx
, ISA_MIPS3
);
10131 gen_helper_mtc0_xcontext(cpu_env
, arg
);
10132 register_name
= "XContext";
10135 goto cp0_unimplemented
;
10138 case CP0_REGISTER_21
:
10139 /* Officially reserved, but sel 0 is used for R1x000 framemask */
10140 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS_R6
));
10143 gen_helper_mtc0_framemask(cpu_env
, arg
);
10144 register_name
= "Framemask";
10147 goto cp0_unimplemented
;
10150 case CP0_REGISTER_22
:
10152 register_name
= "Diagnostic"; /* implementation dependent */
10154 case CP0_REGISTER_23
:
10156 case CP0_REG23__DEBUG
:
10157 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
10158 /* DISAS_STOP isn't good enough here, hflags may have changed. */
10159 gen_save_pc(ctx
->base
.pc_next
+ 4);
10160 ctx
->base
.is_jmp
= DISAS_EXIT
;
10161 register_name
= "Debug";
10163 case CP0_REG23__TRACECONTROL
:
10164 /* PDtrace support */
10165 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
10166 /* Stop translation as we may have switched the execution mode */
10167 ctx
->base
.is_jmp
= DISAS_STOP
;
10168 register_name
= "TraceControl";
10169 goto cp0_unimplemented
;
10170 case CP0_REG23__TRACECONTROL2
:
10171 /* PDtrace support */
10172 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
10173 /* Stop translation as we may have switched the execution mode */
10174 ctx
->base
.is_jmp
= DISAS_STOP
;
10175 register_name
= "TraceControl2";
10176 goto cp0_unimplemented
;
10177 case CP0_REG23__USERTRACEDATA1
:
10178 /* PDtrace support */
10179 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
10180 /* Stop translation as we may have switched the execution mode */
10181 ctx
->base
.is_jmp
= DISAS_STOP
;
10182 register_name
= "UserTraceData1";
10183 goto cp0_unimplemented
;
10184 case CP0_REG23__TRACEIBPC
:
10185 /* PDtrace support */
10186 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
10187 /* Stop translation as we may have switched the execution mode */
10188 ctx
->base
.is_jmp
= DISAS_STOP
;
10189 register_name
= "TraceIBPC";
10190 goto cp0_unimplemented
;
10191 case CP0_REG23__TRACEDBPC
:
10192 /* PDtrace support */
10193 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
10194 /* Stop translation as we may have switched the execution mode */
10195 ctx
->base
.is_jmp
= DISAS_STOP
;
10196 register_name
= "TraceDBPC";
10197 goto cp0_unimplemented
;
10199 goto cp0_unimplemented
;
10202 case CP0_REGISTER_24
:
10204 case CP0_REG24__DEPC
:
10205 /* EJTAG support */
10206 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
10207 register_name
= "DEPC";
10210 goto cp0_unimplemented
;
10213 case CP0_REGISTER_25
:
10215 case CP0_REG25__PERFCTL0
:
10216 gen_helper_mtc0_performance0(cpu_env
, arg
);
10217 register_name
= "Performance0";
10219 case CP0_REG25__PERFCNT0
:
10220 /* gen_helper_mtc0_performance1(cpu_env, arg); */
10221 register_name
= "Performance1";
10222 goto cp0_unimplemented
;
10223 case CP0_REG25__PERFCTL1
:
10224 /* gen_helper_mtc0_performance2(cpu_env, arg); */
10225 register_name
= "Performance2";
10226 goto cp0_unimplemented
;
10227 case CP0_REG25__PERFCNT1
:
10228 /* gen_helper_mtc0_performance3(cpu_env, arg); */
10229 register_name
= "Performance3";
10230 goto cp0_unimplemented
;
10231 case CP0_REG25__PERFCTL2
:
10232 /* gen_helper_mtc0_performance4(cpu_env, arg); */
10233 register_name
= "Performance4";
10234 goto cp0_unimplemented
;
10235 case CP0_REG25__PERFCNT2
:
10236 /* gen_helper_mtc0_performance5(cpu_env, arg); */
10237 register_name
= "Performance5";
10238 goto cp0_unimplemented
;
10239 case CP0_REG25__PERFCTL3
:
10240 /* gen_helper_mtc0_performance6(cpu_env, arg); */
10241 register_name
= "Performance6";
10242 goto cp0_unimplemented
;
10243 case CP0_REG25__PERFCNT3
:
10244 /* gen_helper_mtc0_performance7(cpu_env, arg); */
10245 register_name
= "Performance7";
10246 goto cp0_unimplemented
;
10248 goto cp0_unimplemented
;
10251 case CP0_REGISTER_26
:
10253 case CP0_REG26__ERRCTL
:
10254 gen_helper_mtc0_errctl(cpu_env
, arg
);
10255 ctx
->base
.is_jmp
= DISAS_STOP
;
10256 register_name
= "ErrCtl";
10259 goto cp0_unimplemented
;
10262 case CP0_REGISTER_27
:
10264 case CP0_REG27__CACHERR
:
10266 register_name
= "CacheErr";
10269 goto cp0_unimplemented
;
10272 case CP0_REGISTER_28
:
10274 case CP0_REG28__TAGLO
:
10275 case CP0_REG28__TAGLO1
:
10276 case CP0_REG28__TAGLO2
:
10277 case CP0_REG28__TAGLO3
:
10278 gen_helper_mtc0_taglo(cpu_env
, arg
);
10279 register_name
= "TagLo";
10281 case CP0_REG28__DATALO
:
10282 case CP0_REG28__DATALO1
:
10283 case CP0_REG28__DATALO2
:
10284 case CP0_REG28__DATALO3
:
10285 gen_helper_mtc0_datalo(cpu_env
, arg
);
10286 register_name
= "DataLo";
10289 goto cp0_unimplemented
;
10292 case CP0_REGISTER_29
:
10294 case CP0_REG29__TAGHI
:
10295 case CP0_REG29__TAGHI1
:
10296 case CP0_REG29__TAGHI2
:
10297 case CP0_REG29__TAGHI3
:
10298 gen_helper_mtc0_taghi(cpu_env
, arg
);
10299 register_name
= "TagHi";
10301 case CP0_REG29__DATAHI
:
10302 case CP0_REG29__DATAHI1
:
10303 case CP0_REG29__DATAHI2
:
10304 case CP0_REG29__DATAHI3
:
10305 gen_helper_mtc0_datahi(cpu_env
, arg
);
10306 register_name
= "DataHi";
10309 register_name
= "invalid sel";
10310 goto cp0_unimplemented
;
10313 case CP0_REGISTER_30
:
10315 case CP0_REG30__ERROREPC
:
10316 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
10317 register_name
= "ErrorEPC";
10320 goto cp0_unimplemented
;
10323 case CP0_REGISTER_31
:
10325 case CP0_REG31__DESAVE
:
10326 /* EJTAG support */
10327 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
10328 register_name
= "DESAVE";
10330 case CP0_REG31__KSCRATCH1
:
10331 case CP0_REG31__KSCRATCH2
:
10332 case CP0_REG31__KSCRATCH3
:
10333 case CP0_REG31__KSCRATCH4
:
10334 case CP0_REG31__KSCRATCH5
:
10335 case CP0_REG31__KSCRATCH6
:
10336 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
10337 tcg_gen_st_tl(arg
, cpu_env
,
10338 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
10339 register_name
= "KScratch";
10342 goto cp0_unimplemented
;
10346 goto cp0_unimplemented
;
10348 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
10350 /* For simplicity assume that all writes can cause interrupts. */
10351 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
10353 * DISAS_STOP isn't sufficient, we need to ensure we break out of
10354 * translated code to check for pending interrupts.
10356 gen_save_pc(ctx
->base
.pc_next
+ 4);
10357 ctx
->base
.is_jmp
= DISAS_EXIT
;
10362 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
10363 register_name
, reg
, sel
);
10365 #endif /* TARGET_MIPS64 */
10367 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
10368 int u
, int sel
, int h
)
10370 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10371 TCGv t0
= tcg_temp_local_new();
10373 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10374 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10375 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10376 tcg_gen_movi_tl(t0
, -1);
10377 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10378 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10379 tcg_gen_movi_tl(t0
, -1);
10380 } else if (u
== 0) {
10385 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
10388 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
10398 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
10401 gen_helper_mftc0_tcbind(t0
, cpu_env
);
10404 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
10407 gen_helper_mftc0_tchalt(t0
, cpu_env
);
10410 gen_helper_mftc0_tccontext(t0
, cpu_env
);
10413 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
10416 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
10419 gen_mfc0(ctx
, t0
, rt
, sel
);
10426 gen_helper_mftc0_entryhi(t0
, cpu_env
);
10429 gen_mfc0(ctx
, t0
, rt
, sel
);
10436 gen_helper_mftc0_status(t0
, cpu_env
);
10439 gen_mfc0(ctx
, t0
, rt
, sel
);
10446 gen_helper_mftc0_cause(t0
, cpu_env
);
10456 gen_helper_mftc0_epc(t0
, cpu_env
);
10466 gen_helper_mftc0_ebase(t0
, cpu_env
);
10483 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
10493 gen_helper_mftc0_debug(t0
, cpu_env
);
10496 gen_mfc0(ctx
, t0
, rt
, sel
);
10501 gen_mfc0(ctx
, t0
, rt
, sel
);
10505 /* GPR registers. */
10507 gen_helper_1e0i(mftgpr
, t0
, rt
);
10509 /* Auxiliary CPU registers */
10513 gen_helper_1e0i(mftlo
, t0
, 0);
10516 gen_helper_1e0i(mfthi
, t0
, 0);
10519 gen_helper_1e0i(mftacx
, t0
, 0);
10522 gen_helper_1e0i(mftlo
, t0
, 1);
10525 gen_helper_1e0i(mfthi
, t0
, 1);
10528 gen_helper_1e0i(mftacx
, t0
, 1);
10531 gen_helper_1e0i(mftlo
, t0
, 2);
10534 gen_helper_1e0i(mfthi
, t0
, 2);
10537 gen_helper_1e0i(mftacx
, t0
, 2);
10540 gen_helper_1e0i(mftlo
, t0
, 3);
10543 gen_helper_1e0i(mfthi
, t0
, 3);
10546 gen_helper_1e0i(mftacx
, t0
, 3);
10549 gen_helper_mftdsp(t0
, cpu_env
);
10555 /* Floating point (COP1). */
10557 /* XXX: For now we support only a single FPU context. */
10559 TCGv_i32 fp0
= tcg_temp_new_i32();
10561 gen_load_fpr32(ctx
, fp0
, rt
);
10562 tcg_gen_ext_i32_tl(t0
, fp0
);
10563 tcg_temp_free_i32(fp0
);
10565 TCGv_i32 fp0
= tcg_temp_new_i32();
10567 gen_load_fpr32h(ctx
, fp0
, rt
);
10568 tcg_gen_ext_i32_tl(t0
, fp0
);
10569 tcg_temp_free_i32(fp0
);
10573 /* XXX: For now we support only a single FPU context. */
10574 gen_helper_1e0i(cfc1
, t0
, rt
);
10576 /* COP2: Not implemented. */
10584 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10585 gen_store_gpr(t0
, rd
);
10591 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10592 gen_reserved_instruction(ctx
);
10595 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10596 int u
, int sel
, int h
)
10598 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10599 TCGv t0
= tcg_temp_local_new();
10601 gen_load_gpr(t0
, rt
);
10602 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10603 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10604 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10607 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10608 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10611 } else if (u
== 0) {
10616 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10619 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10629 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10632 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10635 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10638 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10641 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10644 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10647 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10650 gen_mtc0(ctx
, t0
, rd
, sel
);
10657 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10660 gen_mtc0(ctx
, t0
, rd
, sel
);
10667 gen_helper_mttc0_status(cpu_env
, t0
);
10670 gen_mtc0(ctx
, t0
, rd
, sel
);
10677 gen_helper_mttc0_cause(cpu_env
, t0
);
10687 gen_helper_mttc0_ebase(cpu_env
, t0
);
10697 gen_helper_mttc0_debug(cpu_env
, t0
);
10700 gen_mtc0(ctx
, t0
, rd
, sel
);
10705 gen_mtc0(ctx
, t0
, rd
, sel
);
10709 /* GPR registers. */
10711 gen_helper_0e1i(mttgpr
, t0
, rd
);
10713 /* Auxiliary CPU registers */
10717 gen_helper_0e1i(mttlo
, t0
, 0);
10720 gen_helper_0e1i(mtthi
, t0
, 0);
10723 gen_helper_0e1i(mttacx
, t0
, 0);
10726 gen_helper_0e1i(mttlo
, t0
, 1);
10729 gen_helper_0e1i(mtthi
, t0
, 1);
10732 gen_helper_0e1i(mttacx
, t0
, 1);
10735 gen_helper_0e1i(mttlo
, t0
, 2);
10738 gen_helper_0e1i(mtthi
, t0
, 2);
10741 gen_helper_0e1i(mttacx
, t0
, 2);
10744 gen_helper_0e1i(mttlo
, t0
, 3);
10747 gen_helper_0e1i(mtthi
, t0
, 3);
10750 gen_helper_0e1i(mttacx
, t0
, 3);
10753 gen_helper_mttdsp(cpu_env
, t0
);
10759 /* Floating point (COP1). */
10761 /* XXX: For now we support only a single FPU context. */
10763 TCGv_i32 fp0
= tcg_temp_new_i32();
10765 tcg_gen_trunc_tl_i32(fp0
, t0
);
10766 gen_store_fpr32(ctx
, fp0
, rd
);
10767 tcg_temp_free_i32(fp0
);
10769 TCGv_i32 fp0
= tcg_temp_new_i32();
10771 tcg_gen_trunc_tl_i32(fp0
, t0
);
10772 gen_store_fpr32h(ctx
, fp0
, rd
);
10773 tcg_temp_free_i32(fp0
);
10777 /* XXX: For now we support only a single FPU context. */
10779 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10781 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10782 tcg_temp_free_i32(fs_tmp
);
10784 /* Stop translation as we may have changed hflags */
10785 ctx
->base
.is_jmp
= DISAS_STOP
;
10787 /* COP2: Not implemented. */
10795 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10801 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10802 gen_reserved_instruction(ctx
);
10805 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10808 const char *opn
= "ldst";
10810 check_cp0_enabled(ctx
);
10814 /* Treat as NOP. */
10817 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10822 TCGv t0
= tcg_temp_new();
10824 gen_load_gpr(t0
, rt
);
10825 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10830 #if defined(TARGET_MIPS64)
10832 check_insn(ctx
, ISA_MIPS3
);
10834 /* Treat as NOP. */
10837 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10841 check_insn(ctx
, ISA_MIPS3
);
10843 TCGv t0
= tcg_temp_new();
10845 gen_load_gpr(t0
, rt
);
10846 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10855 /* Treat as NOP. */
10858 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10864 TCGv t0
= tcg_temp_new();
10865 gen_load_gpr(t0
, rt
);
10866 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10872 check_cp0_enabled(ctx
);
10874 /* Treat as NOP. */
10877 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10878 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10882 check_cp0_enabled(ctx
);
10883 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10884 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10889 if (!env
->tlb
->helper_tlbwi
) {
10892 gen_helper_tlbwi(cpu_env
);
10896 if (ctx
->ie
>= 2) {
10897 if (!env
->tlb
->helper_tlbinv
) {
10900 gen_helper_tlbinv(cpu_env
);
10901 } /* treat as nop if TLBINV not supported */
10905 if (ctx
->ie
>= 2) {
10906 if (!env
->tlb
->helper_tlbinvf
) {
10909 gen_helper_tlbinvf(cpu_env
);
10910 } /* treat as nop if TLBINV not supported */
10914 if (!env
->tlb
->helper_tlbwr
) {
10917 gen_helper_tlbwr(cpu_env
);
10921 if (!env
->tlb
->helper_tlbp
) {
10924 gen_helper_tlbp(cpu_env
);
10928 if (!env
->tlb
->helper_tlbr
) {
10931 gen_helper_tlbr(cpu_env
);
10933 case OPC_ERET
: /* OPC_ERETNC */
10934 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10935 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10938 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10939 if (ctx
->opcode
& (1 << bit_shift
)) {
10942 check_insn(ctx
, ISA_MIPS_R5
);
10943 gen_helper_eretnc(cpu_env
);
10947 check_insn(ctx
, ISA_MIPS2
);
10948 gen_helper_eret(cpu_env
);
10950 ctx
->base
.is_jmp
= DISAS_EXIT
;
10955 check_insn(ctx
, ISA_MIPS_R1
);
10956 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10957 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10960 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10962 gen_reserved_instruction(ctx
);
10964 gen_helper_deret(cpu_env
);
10965 ctx
->base
.is_jmp
= DISAS_EXIT
;
10970 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
10971 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
10972 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10975 /* If we get an exception, we want to restart at next instruction */
10976 ctx
->base
.pc_next
+= 4;
10977 save_cpu_state(ctx
, 1);
10978 ctx
->base
.pc_next
-= 4;
10979 gen_helper_wait(cpu_env
);
10980 ctx
->base
.is_jmp
= DISAS_NORETURN
;
10985 gen_reserved_instruction(ctx
);
10988 (void)opn
; /* avoid a compiler warning */
10990 #endif /* !CONFIG_USER_ONLY */
10992 /* CP1 Branches (before delay slot) */
10993 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
10994 int32_t cc
, int32_t offset
)
10996 target_ulong btarget
;
10997 TCGv_i32 t0
= tcg_temp_new_i32();
10999 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11000 gen_reserved_instruction(ctx
);
11005 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
11008 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
11012 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11013 tcg_gen_not_i32(t0
, t0
);
11014 tcg_gen_andi_i32(t0
, t0
, 1);
11015 tcg_gen_extu_i32_tl(bcond
, t0
);
11018 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11019 tcg_gen_not_i32(t0
, t0
);
11020 tcg_gen_andi_i32(t0
, t0
, 1);
11021 tcg_gen_extu_i32_tl(bcond
, t0
);
11024 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11025 tcg_gen_andi_i32(t0
, t0
, 1);
11026 tcg_gen_extu_i32_tl(bcond
, t0
);
11029 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11030 tcg_gen_andi_i32(t0
, t0
, 1);
11031 tcg_gen_extu_i32_tl(bcond
, t0
);
11033 ctx
->hflags
|= MIPS_HFLAG_BL
;
11037 TCGv_i32 t1
= tcg_temp_new_i32();
11038 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11039 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11040 tcg_gen_nand_i32(t0
, t0
, t1
);
11041 tcg_temp_free_i32(t1
);
11042 tcg_gen_andi_i32(t0
, t0
, 1);
11043 tcg_gen_extu_i32_tl(bcond
, t0
);
11048 TCGv_i32 t1
= tcg_temp_new_i32();
11049 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11050 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11051 tcg_gen_or_i32(t0
, t0
, t1
);
11052 tcg_temp_free_i32(t1
);
11053 tcg_gen_andi_i32(t0
, t0
, 1);
11054 tcg_gen_extu_i32_tl(bcond
, t0
);
11059 TCGv_i32 t1
= tcg_temp_new_i32();
11060 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11061 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11062 tcg_gen_and_i32(t0
, t0
, t1
);
11063 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
11064 tcg_gen_and_i32(t0
, t0
, t1
);
11065 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
11066 tcg_gen_nand_i32(t0
, t0
, t1
);
11067 tcg_temp_free_i32(t1
);
11068 tcg_gen_andi_i32(t0
, t0
, 1);
11069 tcg_gen_extu_i32_tl(bcond
, t0
);
11074 TCGv_i32 t1
= tcg_temp_new_i32();
11075 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
11076 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
11077 tcg_gen_or_i32(t0
, t0
, t1
);
11078 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
11079 tcg_gen_or_i32(t0
, t0
, t1
);
11080 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
11081 tcg_gen_or_i32(t0
, t0
, t1
);
11082 tcg_temp_free_i32(t1
);
11083 tcg_gen_andi_i32(t0
, t0
, 1);
11084 tcg_gen_extu_i32_tl(bcond
, t0
);
11087 ctx
->hflags
|= MIPS_HFLAG_BC
;
11090 MIPS_INVAL("cp1 cond branch");
11091 gen_reserved_instruction(ctx
);
11094 ctx
->btarget
= btarget
;
11095 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
11097 tcg_temp_free_i32(t0
);
11100 /* R6 CP1 Branches */
11101 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
11102 int32_t ft
, int32_t offset
,
11103 int delayslot_size
)
11105 target_ulong btarget
;
11106 TCGv_i64 t0
= tcg_temp_new_i64();
11108 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11109 #ifdef MIPS_DEBUG_DISAS
11110 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11111 "\n", ctx
->base
.pc_next
);
11113 gen_reserved_instruction(ctx
);
11117 gen_load_fpr64(ctx
, t0
, ft
);
11118 tcg_gen_andi_i64(t0
, t0
, 1);
11120 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
11124 tcg_gen_xori_i64(t0
, t0
, 1);
11125 ctx
->hflags
|= MIPS_HFLAG_BC
;
11128 /* t0 already set */
11129 ctx
->hflags
|= MIPS_HFLAG_BC
;
11132 MIPS_INVAL("cp1 cond branch");
11133 gen_reserved_instruction(ctx
);
11137 tcg_gen_trunc_i64_tl(bcond
, t0
);
11139 ctx
->btarget
= btarget
;
11141 switch (delayslot_size
) {
11143 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
11146 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
11151 tcg_temp_free_i64(t0
);
11154 /* Coprocessor 1 (FPU) */
11156 #define FOP(func, fmt) (((fmt) << 21) | (func))
11159 OPC_ADD_S
= FOP(0, FMT_S
),
11160 OPC_SUB_S
= FOP(1, FMT_S
),
11161 OPC_MUL_S
= FOP(2, FMT_S
),
11162 OPC_DIV_S
= FOP(3, FMT_S
),
11163 OPC_SQRT_S
= FOP(4, FMT_S
),
11164 OPC_ABS_S
= FOP(5, FMT_S
),
11165 OPC_MOV_S
= FOP(6, FMT_S
),
11166 OPC_NEG_S
= FOP(7, FMT_S
),
11167 OPC_ROUND_L_S
= FOP(8, FMT_S
),
11168 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
11169 OPC_CEIL_L_S
= FOP(10, FMT_S
),
11170 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
11171 OPC_ROUND_W_S
= FOP(12, FMT_S
),
11172 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
11173 OPC_CEIL_W_S
= FOP(14, FMT_S
),
11174 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
11175 OPC_SEL_S
= FOP(16, FMT_S
),
11176 OPC_MOVCF_S
= FOP(17, FMT_S
),
11177 OPC_MOVZ_S
= FOP(18, FMT_S
),
11178 OPC_MOVN_S
= FOP(19, FMT_S
),
11179 OPC_SELEQZ_S
= FOP(20, FMT_S
),
11180 OPC_RECIP_S
= FOP(21, FMT_S
),
11181 OPC_RSQRT_S
= FOP(22, FMT_S
),
11182 OPC_SELNEZ_S
= FOP(23, FMT_S
),
11183 OPC_MADDF_S
= FOP(24, FMT_S
),
11184 OPC_MSUBF_S
= FOP(25, FMT_S
),
11185 OPC_RINT_S
= FOP(26, FMT_S
),
11186 OPC_CLASS_S
= FOP(27, FMT_S
),
11187 OPC_MIN_S
= FOP(28, FMT_S
),
11188 OPC_RECIP2_S
= FOP(28, FMT_S
),
11189 OPC_MINA_S
= FOP(29, FMT_S
),
11190 OPC_RECIP1_S
= FOP(29, FMT_S
),
11191 OPC_MAX_S
= FOP(30, FMT_S
),
11192 OPC_RSQRT1_S
= FOP(30, FMT_S
),
11193 OPC_MAXA_S
= FOP(31, FMT_S
),
11194 OPC_RSQRT2_S
= FOP(31, FMT_S
),
11195 OPC_CVT_D_S
= FOP(33, FMT_S
),
11196 OPC_CVT_W_S
= FOP(36, FMT_S
),
11197 OPC_CVT_L_S
= FOP(37, FMT_S
),
11198 OPC_CVT_PS_S
= FOP(38, FMT_S
),
11199 OPC_CMP_F_S
= FOP(48, FMT_S
),
11200 OPC_CMP_UN_S
= FOP(49, FMT_S
),
11201 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
11202 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
11203 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
11204 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
11205 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
11206 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
11207 OPC_CMP_SF_S
= FOP(56, FMT_S
),
11208 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
11209 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
11210 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
11211 OPC_CMP_LT_S
= FOP(60, FMT_S
),
11212 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
11213 OPC_CMP_LE_S
= FOP(62, FMT_S
),
11214 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
11216 OPC_ADD_D
= FOP(0, FMT_D
),
11217 OPC_SUB_D
= FOP(1, FMT_D
),
11218 OPC_MUL_D
= FOP(2, FMT_D
),
11219 OPC_DIV_D
= FOP(3, FMT_D
),
11220 OPC_SQRT_D
= FOP(4, FMT_D
),
11221 OPC_ABS_D
= FOP(5, FMT_D
),
11222 OPC_MOV_D
= FOP(6, FMT_D
),
11223 OPC_NEG_D
= FOP(7, FMT_D
),
11224 OPC_ROUND_L_D
= FOP(8, FMT_D
),
11225 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
11226 OPC_CEIL_L_D
= FOP(10, FMT_D
),
11227 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
11228 OPC_ROUND_W_D
= FOP(12, FMT_D
),
11229 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
11230 OPC_CEIL_W_D
= FOP(14, FMT_D
),
11231 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
11232 OPC_SEL_D
= FOP(16, FMT_D
),
11233 OPC_MOVCF_D
= FOP(17, FMT_D
),
11234 OPC_MOVZ_D
= FOP(18, FMT_D
),
11235 OPC_MOVN_D
= FOP(19, FMT_D
),
11236 OPC_SELEQZ_D
= FOP(20, FMT_D
),
11237 OPC_RECIP_D
= FOP(21, FMT_D
),
11238 OPC_RSQRT_D
= FOP(22, FMT_D
),
11239 OPC_SELNEZ_D
= FOP(23, FMT_D
),
11240 OPC_MADDF_D
= FOP(24, FMT_D
),
11241 OPC_MSUBF_D
= FOP(25, FMT_D
),
11242 OPC_RINT_D
= FOP(26, FMT_D
),
11243 OPC_CLASS_D
= FOP(27, FMT_D
),
11244 OPC_MIN_D
= FOP(28, FMT_D
),
11245 OPC_RECIP2_D
= FOP(28, FMT_D
),
11246 OPC_MINA_D
= FOP(29, FMT_D
),
11247 OPC_RECIP1_D
= FOP(29, FMT_D
),
11248 OPC_MAX_D
= FOP(30, FMT_D
),
11249 OPC_RSQRT1_D
= FOP(30, FMT_D
),
11250 OPC_MAXA_D
= FOP(31, FMT_D
),
11251 OPC_RSQRT2_D
= FOP(31, FMT_D
),
11252 OPC_CVT_S_D
= FOP(32, FMT_D
),
11253 OPC_CVT_W_D
= FOP(36, FMT_D
),
11254 OPC_CVT_L_D
= FOP(37, FMT_D
),
11255 OPC_CMP_F_D
= FOP(48, FMT_D
),
11256 OPC_CMP_UN_D
= FOP(49, FMT_D
),
11257 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
11258 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
11259 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
11260 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
11261 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
11262 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
11263 OPC_CMP_SF_D
= FOP(56, FMT_D
),
11264 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
11265 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
11266 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
11267 OPC_CMP_LT_D
= FOP(60, FMT_D
),
11268 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
11269 OPC_CMP_LE_D
= FOP(62, FMT_D
),
11270 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
11272 OPC_CVT_S_W
= FOP(32, FMT_W
),
11273 OPC_CVT_D_W
= FOP(33, FMT_W
),
11274 OPC_CVT_S_L
= FOP(32, FMT_L
),
11275 OPC_CVT_D_L
= FOP(33, FMT_L
),
11276 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
11278 OPC_ADD_PS
= FOP(0, FMT_PS
),
11279 OPC_SUB_PS
= FOP(1, FMT_PS
),
11280 OPC_MUL_PS
= FOP(2, FMT_PS
),
11281 OPC_DIV_PS
= FOP(3, FMT_PS
),
11282 OPC_ABS_PS
= FOP(5, FMT_PS
),
11283 OPC_MOV_PS
= FOP(6, FMT_PS
),
11284 OPC_NEG_PS
= FOP(7, FMT_PS
),
11285 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
11286 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
11287 OPC_MOVN_PS
= FOP(19, FMT_PS
),
11288 OPC_ADDR_PS
= FOP(24, FMT_PS
),
11289 OPC_MULR_PS
= FOP(26, FMT_PS
),
11290 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
11291 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
11292 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
11293 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
11295 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
11296 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
11297 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
11298 OPC_PLL_PS
= FOP(44, FMT_PS
),
11299 OPC_PLU_PS
= FOP(45, FMT_PS
),
11300 OPC_PUL_PS
= FOP(46, FMT_PS
),
11301 OPC_PUU_PS
= FOP(47, FMT_PS
),
11302 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
11303 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
11304 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
11305 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
11306 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
11307 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
11308 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
11309 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
11310 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
11311 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
11312 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
11313 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
11314 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
11315 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
11316 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
11317 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
11321 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
11322 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
11323 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
11324 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
11325 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
11326 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
11327 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
11328 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
11329 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
11330 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
11331 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
11332 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
11333 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
11334 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
11335 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
11336 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
11337 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
11338 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
11339 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
11340 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
11341 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
11342 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
11344 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
11345 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
11346 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
11347 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
11348 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
11349 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
11350 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
11351 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
11352 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
11353 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
11354 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
11355 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
11356 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
11357 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
11358 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
11359 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
11360 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
11361 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
11362 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
11363 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
11364 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
11365 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
11368 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
11370 TCGv t0
= tcg_temp_new();
11375 TCGv_i32 fp0
= tcg_temp_new_i32();
11377 gen_load_fpr32(ctx
, fp0
, fs
);
11378 tcg_gen_ext_i32_tl(t0
, fp0
);
11379 tcg_temp_free_i32(fp0
);
11381 gen_store_gpr(t0
, rt
);
11384 gen_load_gpr(t0
, rt
);
11386 TCGv_i32 fp0
= tcg_temp_new_i32();
11388 tcg_gen_trunc_tl_i32(fp0
, t0
);
11389 gen_store_fpr32(ctx
, fp0
, fs
);
11390 tcg_temp_free_i32(fp0
);
11394 gen_helper_1e0i(cfc1
, t0
, fs
);
11395 gen_store_gpr(t0
, rt
);
11398 gen_load_gpr(t0
, rt
);
11399 save_cpu_state(ctx
, 0);
11401 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
11403 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
11404 tcg_temp_free_i32(fs_tmp
);
11406 /* Stop translation as we may have changed hflags */
11407 ctx
->base
.is_jmp
= DISAS_STOP
;
11409 #if defined(TARGET_MIPS64)
11411 gen_load_fpr64(ctx
, t0
, fs
);
11412 gen_store_gpr(t0
, rt
);
11415 gen_load_gpr(t0
, rt
);
11416 gen_store_fpr64(ctx
, t0
, fs
);
11421 TCGv_i32 fp0
= tcg_temp_new_i32();
11423 gen_load_fpr32h(ctx
, fp0
, fs
);
11424 tcg_gen_ext_i32_tl(t0
, fp0
);
11425 tcg_temp_free_i32(fp0
);
11427 gen_store_gpr(t0
, rt
);
11430 gen_load_gpr(t0
, rt
);
11432 TCGv_i32 fp0
= tcg_temp_new_i32();
11434 tcg_gen_trunc_tl_i32(fp0
, t0
);
11435 gen_store_fpr32h(ctx
, fp0
, fs
);
11436 tcg_temp_free_i32(fp0
);
11440 MIPS_INVAL("cp1 move");
11441 gen_reserved_instruction(ctx
);
11449 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
11456 /* Treat as NOP. */
11461 cond
= TCG_COND_EQ
;
11463 cond
= TCG_COND_NE
;
11466 l1
= gen_new_label();
11467 t0
= tcg_temp_new_i32();
11468 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11469 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11470 tcg_temp_free_i32(t0
);
11472 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
11474 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
11479 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11483 TCGv_i32 t0
= tcg_temp_new_i32();
11484 TCGLabel
*l1
= gen_new_label();
11487 cond
= TCG_COND_EQ
;
11489 cond
= TCG_COND_NE
;
11492 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11493 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11494 gen_load_fpr32(ctx
, t0
, fs
);
11495 gen_store_fpr32(ctx
, t0
, fd
);
11497 tcg_temp_free_i32(t0
);
11500 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
11504 TCGv_i32 t0
= tcg_temp_new_i32();
11506 TCGLabel
*l1
= gen_new_label();
11509 cond
= TCG_COND_EQ
;
11511 cond
= TCG_COND_NE
;
11514 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11515 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11516 tcg_temp_free_i32(t0
);
11517 fp0
= tcg_temp_new_i64();
11518 gen_load_fpr64(ctx
, fp0
, fs
);
11519 gen_store_fpr64(ctx
, fp0
, fd
);
11520 tcg_temp_free_i64(fp0
);
11524 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
11528 TCGv_i32 t0
= tcg_temp_new_i32();
11529 TCGLabel
*l1
= gen_new_label();
11530 TCGLabel
*l2
= gen_new_label();
11533 cond
= TCG_COND_EQ
;
11535 cond
= TCG_COND_NE
;
11538 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
11539 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
11540 gen_load_fpr32(ctx
, t0
, fs
);
11541 gen_store_fpr32(ctx
, t0
, fd
);
11544 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
11545 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
11546 gen_load_fpr32h(ctx
, t0
, fs
);
11547 gen_store_fpr32h(ctx
, t0
, fd
);
11548 tcg_temp_free_i32(t0
);
11552 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11555 TCGv_i32 t1
= tcg_const_i32(0);
11556 TCGv_i32 fp0
= tcg_temp_new_i32();
11557 TCGv_i32 fp1
= tcg_temp_new_i32();
11558 TCGv_i32 fp2
= tcg_temp_new_i32();
11559 gen_load_fpr32(ctx
, fp0
, fd
);
11560 gen_load_fpr32(ctx
, fp1
, ft
);
11561 gen_load_fpr32(ctx
, fp2
, fs
);
11565 tcg_gen_andi_i32(fp0
, fp0
, 1);
11566 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11569 tcg_gen_andi_i32(fp1
, fp1
, 1);
11570 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11573 tcg_gen_andi_i32(fp1
, fp1
, 1);
11574 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11577 MIPS_INVAL("gen_sel_s");
11578 gen_reserved_instruction(ctx
);
11582 gen_store_fpr32(ctx
, fp0
, fd
);
11583 tcg_temp_free_i32(fp2
);
11584 tcg_temp_free_i32(fp1
);
11585 tcg_temp_free_i32(fp0
);
11586 tcg_temp_free_i32(t1
);
11589 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11592 TCGv_i64 t1
= tcg_const_i64(0);
11593 TCGv_i64 fp0
= tcg_temp_new_i64();
11594 TCGv_i64 fp1
= tcg_temp_new_i64();
11595 TCGv_i64 fp2
= tcg_temp_new_i64();
11596 gen_load_fpr64(ctx
, fp0
, fd
);
11597 gen_load_fpr64(ctx
, fp1
, ft
);
11598 gen_load_fpr64(ctx
, fp2
, fs
);
11602 tcg_gen_andi_i64(fp0
, fp0
, 1);
11603 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11606 tcg_gen_andi_i64(fp1
, fp1
, 1);
11607 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11610 tcg_gen_andi_i64(fp1
, fp1
, 1);
11611 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11614 MIPS_INVAL("gen_sel_d");
11615 gen_reserved_instruction(ctx
);
11619 gen_store_fpr64(ctx
, fp0
, fd
);
11620 tcg_temp_free_i64(fp2
);
11621 tcg_temp_free_i64(fp1
);
11622 tcg_temp_free_i64(fp0
);
11623 tcg_temp_free_i64(t1
);
11626 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11627 int ft
, int fs
, int fd
, int cc
)
11629 uint32_t func
= ctx
->opcode
& 0x3f;
11633 TCGv_i32 fp0
= tcg_temp_new_i32();
11634 TCGv_i32 fp1
= tcg_temp_new_i32();
11636 gen_load_fpr32(ctx
, fp0
, fs
);
11637 gen_load_fpr32(ctx
, fp1
, ft
);
11638 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11639 tcg_temp_free_i32(fp1
);
11640 gen_store_fpr32(ctx
, fp0
, fd
);
11641 tcg_temp_free_i32(fp0
);
11646 TCGv_i32 fp0
= tcg_temp_new_i32();
11647 TCGv_i32 fp1
= tcg_temp_new_i32();
11649 gen_load_fpr32(ctx
, fp0
, fs
);
11650 gen_load_fpr32(ctx
, fp1
, ft
);
11651 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11652 tcg_temp_free_i32(fp1
);
11653 gen_store_fpr32(ctx
, fp0
, fd
);
11654 tcg_temp_free_i32(fp0
);
11659 TCGv_i32 fp0
= tcg_temp_new_i32();
11660 TCGv_i32 fp1
= tcg_temp_new_i32();
11662 gen_load_fpr32(ctx
, fp0
, fs
);
11663 gen_load_fpr32(ctx
, fp1
, ft
);
11664 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11665 tcg_temp_free_i32(fp1
);
11666 gen_store_fpr32(ctx
, fp0
, fd
);
11667 tcg_temp_free_i32(fp0
);
11672 TCGv_i32 fp0
= tcg_temp_new_i32();
11673 TCGv_i32 fp1
= tcg_temp_new_i32();
11675 gen_load_fpr32(ctx
, fp0
, fs
);
11676 gen_load_fpr32(ctx
, fp1
, ft
);
11677 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11678 tcg_temp_free_i32(fp1
);
11679 gen_store_fpr32(ctx
, fp0
, fd
);
11680 tcg_temp_free_i32(fp0
);
11685 TCGv_i32 fp0
= tcg_temp_new_i32();
11687 gen_load_fpr32(ctx
, fp0
, fs
);
11688 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11689 gen_store_fpr32(ctx
, fp0
, fd
);
11690 tcg_temp_free_i32(fp0
);
11695 TCGv_i32 fp0
= tcg_temp_new_i32();
11697 gen_load_fpr32(ctx
, fp0
, fs
);
11698 if (ctx
->abs2008
) {
11699 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11701 gen_helper_float_abs_s(fp0
, fp0
);
11703 gen_store_fpr32(ctx
, fp0
, fd
);
11704 tcg_temp_free_i32(fp0
);
11709 TCGv_i32 fp0
= tcg_temp_new_i32();
11711 gen_load_fpr32(ctx
, fp0
, fs
);
11712 gen_store_fpr32(ctx
, fp0
, fd
);
11713 tcg_temp_free_i32(fp0
);
11718 TCGv_i32 fp0
= tcg_temp_new_i32();
11720 gen_load_fpr32(ctx
, fp0
, fs
);
11721 if (ctx
->abs2008
) {
11722 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11724 gen_helper_float_chs_s(fp0
, fp0
);
11726 gen_store_fpr32(ctx
, fp0
, fd
);
11727 tcg_temp_free_i32(fp0
);
11730 case OPC_ROUND_L_S
:
11731 check_cp1_64bitmode(ctx
);
11733 TCGv_i32 fp32
= tcg_temp_new_i32();
11734 TCGv_i64 fp64
= tcg_temp_new_i64();
11736 gen_load_fpr32(ctx
, fp32
, fs
);
11737 if (ctx
->nan2008
) {
11738 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11740 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11742 tcg_temp_free_i32(fp32
);
11743 gen_store_fpr64(ctx
, fp64
, fd
);
11744 tcg_temp_free_i64(fp64
);
11747 case OPC_TRUNC_L_S
:
11748 check_cp1_64bitmode(ctx
);
11750 TCGv_i32 fp32
= tcg_temp_new_i32();
11751 TCGv_i64 fp64
= tcg_temp_new_i64();
11753 gen_load_fpr32(ctx
, fp32
, fs
);
11754 if (ctx
->nan2008
) {
11755 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11757 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11759 tcg_temp_free_i32(fp32
);
11760 gen_store_fpr64(ctx
, fp64
, fd
);
11761 tcg_temp_free_i64(fp64
);
11765 check_cp1_64bitmode(ctx
);
11767 TCGv_i32 fp32
= tcg_temp_new_i32();
11768 TCGv_i64 fp64
= tcg_temp_new_i64();
11770 gen_load_fpr32(ctx
, fp32
, fs
);
11771 if (ctx
->nan2008
) {
11772 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11774 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11776 tcg_temp_free_i32(fp32
);
11777 gen_store_fpr64(ctx
, fp64
, fd
);
11778 tcg_temp_free_i64(fp64
);
11781 case OPC_FLOOR_L_S
:
11782 check_cp1_64bitmode(ctx
);
11784 TCGv_i32 fp32
= tcg_temp_new_i32();
11785 TCGv_i64 fp64
= tcg_temp_new_i64();
11787 gen_load_fpr32(ctx
, fp32
, fs
);
11788 if (ctx
->nan2008
) {
11789 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11791 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11793 tcg_temp_free_i32(fp32
);
11794 gen_store_fpr64(ctx
, fp64
, fd
);
11795 tcg_temp_free_i64(fp64
);
11798 case OPC_ROUND_W_S
:
11800 TCGv_i32 fp0
= tcg_temp_new_i32();
11802 gen_load_fpr32(ctx
, fp0
, fs
);
11803 if (ctx
->nan2008
) {
11804 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11806 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11808 gen_store_fpr32(ctx
, fp0
, fd
);
11809 tcg_temp_free_i32(fp0
);
11812 case OPC_TRUNC_W_S
:
11814 TCGv_i32 fp0
= tcg_temp_new_i32();
11816 gen_load_fpr32(ctx
, fp0
, fs
);
11817 if (ctx
->nan2008
) {
11818 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11820 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11822 gen_store_fpr32(ctx
, fp0
, fd
);
11823 tcg_temp_free_i32(fp0
);
11828 TCGv_i32 fp0
= tcg_temp_new_i32();
11830 gen_load_fpr32(ctx
, fp0
, fs
);
11831 if (ctx
->nan2008
) {
11832 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11834 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11836 gen_store_fpr32(ctx
, fp0
, fd
);
11837 tcg_temp_free_i32(fp0
);
11840 case OPC_FLOOR_W_S
:
11842 TCGv_i32 fp0
= tcg_temp_new_i32();
11844 gen_load_fpr32(ctx
, fp0
, fs
);
11845 if (ctx
->nan2008
) {
11846 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11848 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11850 gen_store_fpr32(ctx
, fp0
, fd
);
11851 tcg_temp_free_i32(fp0
);
11855 check_insn(ctx
, ISA_MIPS_R6
);
11856 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11859 check_insn(ctx
, ISA_MIPS_R6
);
11860 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11863 check_insn(ctx
, ISA_MIPS_R6
);
11864 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11867 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11868 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11871 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11873 TCGLabel
*l1
= gen_new_label();
11877 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11879 fp0
= tcg_temp_new_i32();
11880 gen_load_fpr32(ctx
, fp0
, fs
);
11881 gen_store_fpr32(ctx
, fp0
, fd
);
11882 tcg_temp_free_i32(fp0
);
11887 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
11889 TCGLabel
*l1
= gen_new_label();
11893 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11894 fp0
= tcg_temp_new_i32();
11895 gen_load_fpr32(ctx
, fp0
, fs
);
11896 gen_store_fpr32(ctx
, fp0
, fd
);
11897 tcg_temp_free_i32(fp0
);
11904 TCGv_i32 fp0
= tcg_temp_new_i32();
11906 gen_load_fpr32(ctx
, fp0
, fs
);
11907 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11908 gen_store_fpr32(ctx
, fp0
, fd
);
11909 tcg_temp_free_i32(fp0
);
11914 TCGv_i32 fp0
= tcg_temp_new_i32();
11916 gen_load_fpr32(ctx
, fp0
, fs
);
11917 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11918 gen_store_fpr32(ctx
, fp0
, fd
);
11919 tcg_temp_free_i32(fp0
);
11923 check_insn(ctx
, ISA_MIPS_R6
);
11925 TCGv_i32 fp0
= tcg_temp_new_i32();
11926 TCGv_i32 fp1
= tcg_temp_new_i32();
11927 TCGv_i32 fp2
= tcg_temp_new_i32();
11928 gen_load_fpr32(ctx
, fp0
, fs
);
11929 gen_load_fpr32(ctx
, fp1
, ft
);
11930 gen_load_fpr32(ctx
, fp2
, fd
);
11931 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11932 gen_store_fpr32(ctx
, fp2
, fd
);
11933 tcg_temp_free_i32(fp2
);
11934 tcg_temp_free_i32(fp1
);
11935 tcg_temp_free_i32(fp0
);
11939 check_insn(ctx
, ISA_MIPS_R6
);
11941 TCGv_i32 fp0
= tcg_temp_new_i32();
11942 TCGv_i32 fp1
= tcg_temp_new_i32();
11943 TCGv_i32 fp2
= tcg_temp_new_i32();
11944 gen_load_fpr32(ctx
, fp0
, fs
);
11945 gen_load_fpr32(ctx
, fp1
, ft
);
11946 gen_load_fpr32(ctx
, fp2
, fd
);
11947 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11948 gen_store_fpr32(ctx
, fp2
, fd
);
11949 tcg_temp_free_i32(fp2
);
11950 tcg_temp_free_i32(fp1
);
11951 tcg_temp_free_i32(fp0
);
11955 check_insn(ctx
, ISA_MIPS_R6
);
11957 TCGv_i32 fp0
= tcg_temp_new_i32();
11958 gen_load_fpr32(ctx
, fp0
, fs
);
11959 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
11960 gen_store_fpr32(ctx
, fp0
, fd
);
11961 tcg_temp_free_i32(fp0
);
11965 check_insn(ctx
, ISA_MIPS_R6
);
11967 TCGv_i32 fp0
= tcg_temp_new_i32();
11968 gen_load_fpr32(ctx
, fp0
, fs
);
11969 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
11970 gen_store_fpr32(ctx
, fp0
, fd
);
11971 tcg_temp_free_i32(fp0
);
11974 case OPC_MIN_S
: /* OPC_RECIP2_S */
11975 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
11977 TCGv_i32 fp0
= tcg_temp_new_i32();
11978 TCGv_i32 fp1
= tcg_temp_new_i32();
11979 TCGv_i32 fp2
= tcg_temp_new_i32();
11980 gen_load_fpr32(ctx
, fp0
, fs
);
11981 gen_load_fpr32(ctx
, fp1
, ft
);
11982 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
11983 gen_store_fpr32(ctx
, fp2
, fd
);
11984 tcg_temp_free_i32(fp2
);
11985 tcg_temp_free_i32(fp1
);
11986 tcg_temp_free_i32(fp0
);
11989 check_cp1_64bitmode(ctx
);
11991 TCGv_i32 fp0
= tcg_temp_new_i32();
11992 TCGv_i32 fp1
= tcg_temp_new_i32();
11994 gen_load_fpr32(ctx
, fp0
, fs
);
11995 gen_load_fpr32(ctx
, fp1
, ft
);
11996 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
11997 tcg_temp_free_i32(fp1
);
11998 gen_store_fpr32(ctx
, fp0
, fd
);
11999 tcg_temp_free_i32(fp0
);
12003 case OPC_MINA_S
: /* OPC_RECIP1_S */
12004 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12006 TCGv_i32 fp0
= tcg_temp_new_i32();
12007 TCGv_i32 fp1
= tcg_temp_new_i32();
12008 TCGv_i32 fp2
= tcg_temp_new_i32();
12009 gen_load_fpr32(ctx
, fp0
, fs
);
12010 gen_load_fpr32(ctx
, fp1
, ft
);
12011 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
12012 gen_store_fpr32(ctx
, fp2
, fd
);
12013 tcg_temp_free_i32(fp2
);
12014 tcg_temp_free_i32(fp1
);
12015 tcg_temp_free_i32(fp0
);
12018 check_cp1_64bitmode(ctx
);
12020 TCGv_i32 fp0
= tcg_temp_new_i32();
12022 gen_load_fpr32(ctx
, fp0
, fs
);
12023 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
12024 gen_store_fpr32(ctx
, fp0
, fd
);
12025 tcg_temp_free_i32(fp0
);
12029 case OPC_MAX_S
: /* OPC_RSQRT1_S */
12030 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12032 TCGv_i32 fp0
= tcg_temp_new_i32();
12033 TCGv_i32 fp1
= tcg_temp_new_i32();
12034 gen_load_fpr32(ctx
, fp0
, fs
);
12035 gen_load_fpr32(ctx
, fp1
, ft
);
12036 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
12037 gen_store_fpr32(ctx
, fp1
, fd
);
12038 tcg_temp_free_i32(fp1
);
12039 tcg_temp_free_i32(fp0
);
12042 check_cp1_64bitmode(ctx
);
12044 TCGv_i32 fp0
= tcg_temp_new_i32();
12046 gen_load_fpr32(ctx
, fp0
, fs
);
12047 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
12048 gen_store_fpr32(ctx
, fp0
, fd
);
12049 tcg_temp_free_i32(fp0
);
12053 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
12054 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12056 TCGv_i32 fp0
= tcg_temp_new_i32();
12057 TCGv_i32 fp1
= tcg_temp_new_i32();
12058 gen_load_fpr32(ctx
, fp0
, fs
);
12059 gen_load_fpr32(ctx
, fp1
, ft
);
12060 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
12061 gen_store_fpr32(ctx
, fp1
, fd
);
12062 tcg_temp_free_i32(fp1
);
12063 tcg_temp_free_i32(fp0
);
12066 check_cp1_64bitmode(ctx
);
12068 TCGv_i32 fp0
= tcg_temp_new_i32();
12069 TCGv_i32 fp1
= tcg_temp_new_i32();
12071 gen_load_fpr32(ctx
, fp0
, fs
);
12072 gen_load_fpr32(ctx
, fp1
, ft
);
12073 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
12074 tcg_temp_free_i32(fp1
);
12075 gen_store_fpr32(ctx
, fp0
, fd
);
12076 tcg_temp_free_i32(fp0
);
12081 check_cp1_registers(ctx
, fd
);
12083 TCGv_i32 fp32
= tcg_temp_new_i32();
12084 TCGv_i64 fp64
= tcg_temp_new_i64();
12086 gen_load_fpr32(ctx
, fp32
, fs
);
12087 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
12088 tcg_temp_free_i32(fp32
);
12089 gen_store_fpr64(ctx
, fp64
, fd
);
12090 tcg_temp_free_i64(fp64
);
12095 TCGv_i32 fp0
= tcg_temp_new_i32();
12097 gen_load_fpr32(ctx
, fp0
, fs
);
12098 if (ctx
->nan2008
) {
12099 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
12101 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
12103 gen_store_fpr32(ctx
, fp0
, fd
);
12104 tcg_temp_free_i32(fp0
);
12108 check_cp1_64bitmode(ctx
);
12110 TCGv_i32 fp32
= tcg_temp_new_i32();
12111 TCGv_i64 fp64
= tcg_temp_new_i64();
12113 gen_load_fpr32(ctx
, fp32
, fs
);
12114 if (ctx
->nan2008
) {
12115 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
12117 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
12119 tcg_temp_free_i32(fp32
);
12120 gen_store_fpr64(ctx
, fp64
, fd
);
12121 tcg_temp_free_i64(fp64
);
12127 TCGv_i64 fp64
= tcg_temp_new_i64();
12128 TCGv_i32 fp32_0
= tcg_temp_new_i32();
12129 TCGv_i32 fp32_1
= tcg_temp_new_i32();
12131 gen_load_fpr32(ctx
, fp32_0
, fs
);
12132 gen_load_fpr32(ctx
, fp32_1
, ft
);
12133 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
12134 tcg_temp_free_i32(fp32_1
);
12135 tcg_temp_free_i32(fp32_0
);
12136 gen_store_fpr64(ctx
, fp64
, fd
);
12137 tcg_temp_free_i64(fp64
);
12143 case OPC_CMP_UEQ_S
:
12144 case OPC_CMP_OLT_S
:
12145 case OPC_CMP_ULT_S
:
12146 case OPC_CMP_OLE_S
:
12147 case OPC_CMP_ULE_S
:
12149 case OPC_CMP_NGLE_S
:
12150 case OPC_CMP_SEQ_S
:
12151 case OPC_CMP_NGL_S
:
12153 case OPC_CMP_NGE_S
:
12155 case OPC_CMP_NGT_S
:
12156 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12157 if (ctx
->opcode
& (1 << 6)) {
12158 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
12160 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
12164 check_cp1_registers(ctx
, fs
| ft
| fd
);
12166 TCGv_i64 fp0
= tcg_temp_new_i64();
12167 TCGv_i64 fp1
= tcg_temp_new_i64();
12169 gen_load_fpr64(ctx
, fp0
, fs
);
12170 gen_load_fpr64(ctx
, fp1
, ft
);
12171 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
12172 tcg_temp_free_i64(fp1
);
12173 gen_store_fpr64(ctx
, fp0
, fd
);
12174 tcg_temp_free_i64(fp0
);
12178 check_cp1_registers(ctx
, fs
| ft
| fd
);
12180 TCGv_i64 fp0
= tcg_temp_new_i64();
12181 TCGv_i64 fp1
= tcg_temp_new_i64();
12183 gen_load_fpr64(ctx
, fp0
, fs
);
12184 gen_load_fpr64(ctx
, fp1
, ft
);
12185 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
12186 tcg_temp_free_i64(fp1
);
12187 gen_store_fpr64(ctx
, fp0
, fd
);
12188 tcg_temp_free_i64(fp0
);
12192 check_cp1_registers(ctx
, fs
| ft
| fd
);
12194 TCGv_i64 fp0
= tcg_temp_new_i64();
12195 TCGv_i64 fp1
= tcg_temp_new_i64();
12197 gen_load_fpr64(ctx
, fp0
, fs
);
12198 gen_load_fpr64(ctx
, fp1
, ft
);
12199 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
12200 tcg_temp_free_i64(fp1
);
12201 gen_store_fpr64(ctx
, fp0
, fd
);
12202 tcg_temp_free_i64(fp0
);
12206 check_cp1_registers(ctx
, fs
| ft
| fd
);
12208 TCGv_i64 fp0
= tcg_temp_new_i64();
12209 TCGv_i64 fp1
= tcg_temp_new_i64();
12211 gen_load_fpr64(ctx
, fp0
, fs
);
12212 gen_load_fpr64(ctx
, fp1
, ft
);
12213 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
12214 tcg_temp_free_i64(fp1
);
12215 gen_store_fpr64(ctx
, fp0
, fd
);
12216 tcg_temp_free_i64(fp0
);
12220 check_cp1_registers(ctx
, fs
| fd
);
12222 TCGv_i64 fp0
= tcg_temp_new_i64();
12224 gen_load_fpr64(ctx
, fp0
, fs
);
12225 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
12226 gen_store_fpr64(ctx
, fp0
, fd
);
12227 tcg_temp_free_i64(fp0
);
12231 check_cp1_registers(ctx
, fs
| fd
);
12233 TCGv_i64 fp0
= tcg_temp_new_i64();
12235 gen_load_fpr64(ctx
, fp0
, fs
);
12236 if (ctx
->abs2008
) {
12237 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
12239 gen_helper_float_abs_d(fp0
, fp0
);
12241 gen_store_fpr64(ctx
, fp0
, fd
);
12242 tcg_temp_free_i64(fp0
);
12246 check_cp1_registers(ctx
, fs
| fd
);
12248 TCGv_i64 fp0
= tcg_temp_new_i64();
12250 gen_load_fpr64(ctx
, fp0
, fs
);
12251 gen_store_fpr64(ctx
, fp0
, fd
);
12252 tcg_temp_free_i64(fp0
);
12256 check_cp1_registers(ctx
, fs
| fd
);
12258 TCGv_i64 fp0
= tcg_temp_new_i64();
12260 gen_load_fpr64(ctx
, fp0
, fs
);
12261 if (ctx
->abs2008
) {
12262 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
12264 gen_helper_float_chs_d(fp0
, fp0
);
12266 gen_store_fpr64(ctx
, fp0
, fd
);
12267 tcg_temp_free_i64(fp0
);
12270 case OPC_ROUND_L_D
:
12271 check_cp1_64bitmode(ctx
);
12273 TCGv_i64 fp0
= tcg_temp_new_i64();
12275 gen_load_fpr64(ctx
, fp0
, fs
);
12276 if (ctx
->nan2008
) {
12277 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
12279 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
12281 gen_store_fpr64(ctx
, fp0
, fd
);
12282 tcg_temp_free_i64(fp0
);
12285 case OPC_TRUNC_L_D
:
12286 check_cp1_64bitmode(ctx
);
12288 TCGv_i64 fp0
= tcg_temp_new_i64();
12290 gen_load_fpr64(ctx
, fp0
, fs
);
12291 if (ctx
->nan2008
) {
12292 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
12294 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
12296 gen_store_fpr64(ctx
, fp0
, fd
);
12297 tcg_temp_free_i64(fp0
);
12301 check_cp1_64bitmode(ctx
);
12303 TCGv_i64 fp0
= tcg_temp_new_i64();
12305 gen_load_fpr64(ctx
, fp0
, fs
);
12306 if (ctx
->nan2008
) {
12307 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
12309 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
12311 gen_store_fpr64(ctx
, fp0
, fd
);
12312 tcg_temp_free_i64(fp0
);
12315 case OPC_FLOOR_L_D
:
12316 check_cp1_64bitmode(ctx
);
12318 TCGv_i64 fp0
= tcg_temp_new_i64();
12320 gen_load_fpr64(ctx
, fp0
, fs
);
12321 if (ctx
->nan2008
) {
12322 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
12324 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
12326 gen_store_fpr64(ctx
, fp0
, fd
);
12327 tcg_temp_free_i64(fp0
);
12330 case OPC_ROUND_W_D
:
12331 check_cp1_registers(ctx
, fs
);
12333 TCGv_i32 fp32
= tcg_temp_new_i32();
12334 TCGv_i64 fp64
= tcg_temp_new_i64();
12336 gen_load_fpr64(ctx
, fp64
, fs
);
12337 if (ctx
->nan2008
) {
12338 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
12340 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
12342 tcg_temp_free_i64(fp64
);
12343 gen_store_fpr32(ctx
, fp32
, fd
);
12344 tcg_temp_free_i32(fp32
);
12347 case OPC_TRUNC_W_D
:
12348 check_cp1_registers(ctx
, fs
);
12350 TCGv_i32 fp32
= tcg_temp_new_i32();
12351 TCGv_i64 fp64
= tcg_temp_new_i64();
12353 gen_load_fpr64(ctx
, fp64
, fs
);
12354 if (ctx
->nan2008
) {
12355 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
12357 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
12359 tcg_temp_free_i64(fp64
);
12360 gen_store_fpr32(ctx
, fp32
, fd
);
12361 tcg_temp_free_i32(fp32
);
12365 check_cp1_registers(ctx
, fs
);
12367 TCGv_i32 fp32
= tcg_temp_new_i32();
12368 TCGv_i64 fp64
= tcg_temp_new_i64();
12370 gen_load_fpr64(ctx
, fp64
, fs
);
12371 if (ctx
->nan2008
) {
12372 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
12374 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
12376 tcg_temp_free_i64(fp64
);
12377 gen_store_fpr32(ctx
, fp32
, fd
);
12378 tcg_temp_free_i32(fp32
);
12381 case OPC_FLOOR_W_D
:
12382 check_cp1_registers(ctx
, fs
);
12384 TCGv_i32 fp32
= tcg_temp_new_i32();
12385 TCGv_i64 fp64
= tcg_temp_new_i64();
12387 gen_load_fpr64(ctx
, fp64
, fs
);
12388 if (ctx
->nan2008
) {
12389 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
12391 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
12393 tcg_temp_free_i64(fp64
);
12394 gen_store_fpr32(ctx
, fp32
, fd
);
12395 tcg_temp_free_i32(fp32
);
12399 check_insn(ctx
, ISA_MIPS_R6
);
12400 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12403 check_insn(ctx
, ISA_MIPS_R6
);
12404 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12407 check_insn(ctx
, ISA_MIPS_R6
);
12408 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
12411 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12412 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12415 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12417 TCGLabel
*l1
= gen_new_label();
12421 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12423 fp0
= tcg_temp_new_i64();
12424 gen_load_fpr64(ctx
, fp0
, fs
);
12425 gen_store_fpr64(ctx
, fp0
, fd
);
12426 tcg_temp_free_i64(fp0
);
12431 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12433 TCGLabel
*l1
= gen_new_label();
12437 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12438 fp0
= tcg_temp_new_i64();
12439 gen_load_fpr64(ctx
, fp0
, fs
);
12440 gen_store_fpr64(ctx
, fp0
, fd
);
12441 tcg_temp_free_i64(fp0
);
12447 check_cp1_registers(ctx
, fs
| fd
);
12449 TCGv_i64 fp0
= tcg_temp_new_i64();
12451 gen_load_fpr64(ctx
, fp0
, fs
);
12452 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
12453 gen_store_fpr64(ctx
, fp0
, fd
);
12454 tcg_temp_free_i64(fp0
);
12458 check_cp1_registers(ctx
, fs
| fd
);
12460 TCGv_i64 fp0
= tcg_temp_new_i64();
12462 gen_load_fpr64(ctx
, fp0
, fs
);
12463 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
12464 gen_store_fpr64(ctx
, fp0
, fd
);
12465 tcg_temp_free_i64(fp0
);
12469 check_insn(ctx
, ISA_MIPS_R6
);
12471 TCGv_i64 fp0
= tcg_temp_new_i64();
12472 TCGv_i64 fp1
= tcg_temp_new_i64();
12473 TCGv_i64 fp2
= tcg_temp_new_i64();
12474 gen_load_fpr64(ctx
, fp0
, fs
);
12475 gen_load_fpr64(ctx
, fp1
, ft
);
12476 gen_load_fpr64(ctx
, fp2
, fd
);
12477 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12478 gen_store_fpr64(ctx
, fp2
, fd
);
12479 tcg_temp_free_i64(fp2
);
12480 tcg_temp_free_i64(fp1
);
12481 tcg_temp_free_i64(fp0
);
12485 check_insn(ctx
, ISA_MIPS_R6
);
12487 TCGv_i64 fp0
= tcg_temp_new_i64();
12488 TCGv_i64 fp1
= tcg_temp_new_i64();
12489 TCGv_i64 fp2
= tcg_temp_new_i64();
12490 gen_load_fpr64(ctx
, fp0
, fs
);
12491 gen_load_fpr64(ctx
, fp1
, ft
);
12492 gen_load_fpr64(ctx
, fp2
, fd
);
12493 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12494 gen_store_fpr64(ctx
, fp2
, fd
);
12495 tcg_temp_free_i64(fp2
);
12496 tcg_temp_free_i64(fp1
);
12497 tcg_temp_free_i64(fp0
);
12501 check_insn(ctx
, ISA_MIPS_R6
);
12503 TCGv_i64 fp0
= tcg_temp_new_i64();
12504 gen_load_fpr64(ctx
, fp0
, fs
);
12505 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
12506 gen_store_fpr64(ctx
, fp0
, fd
);
12507 tcg_temp_free_i64(fp0
);
12511 check_insn(ctx
, ISA_MIPS_R6
);
12513 TCGv_i64 fp0
= tcg_temp_new_i64();
12514 gen_load_fpr64(ctx
, fp0
, fs
);
12515 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
12516 gen_store_fpr64(ctx
, fp0
, fd
);
12517 tcg_temp_free_i64(fp0
);
12520 case OPC_MIN_D
: /* OPC_RECIP2_D */
12521 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12523 TCGv_i64 fp0
= tcg_temp_new_i64();
12524 TCGv_i64 fp1
= tcg_temp_new_i64();
12525 gen_load_fpr64(ctx
, fp0
, fs
);
12526 gen_load_fpr64(ctx
, fp1
, ft
);
12527 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
12528 gen_store_fpr64(ctx
, fp1
, fd
);
12529 tcg_temp_free_i64(fp1
);
12530 tcg_temp_free_i64(fp0
);
12533 check_cp1_64bitmode(ctx
);
12535 TCGv_i64 fp0
= tcg_temp_new_i64();
12536 TCGv_i64 fp1
= tcg_temp_new_i64();
12538 gen_load_fpr64(ctx
, fp0
, fs
);
12539 gen_load_fpr64(ctx
, fp1
, ft
);
12540 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
12541 tcg_temp_free_i64(fp1
);
12542 gen_store_fpr64(ctx
, fp0
, fd
);
12543 tcg_temp_free_i64(fp0
);
12547 case OPC_MINA_D
: /* OPC_RECIP1_D */
12548 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12550 TCGv_i64 fp0
= tcg_temp_new_i64();
12551 TCGv_i64 fp1
= tcg_temp_new_i64();
12552 gen_load_fpr64(ctx
, fp0
, fs
);
12553 gen_load_fpr64(ctx
, fp1
, ft
);
12554 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
12555 gen_store_fpr64(ctx
, fp1
, fd
);
12556 tcg_temp_free_i64(fp1
);
12557 tcg_temp_free_i64(fp0
);
12560 check_cp1_64bitmode(ctx
);
12562 TCGv_i64 fp0
= tcg_temp_new_i64();
12564 gen_load_fpr64(ctx
, fp0
, fs
);
12565 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
12566 gen_store_fpr64(ctx
, fp0
, fd
);
12567 tcg_temp_free_i64(fp0
);
12571 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12572 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12574 TCGv_i64 fp0
= tcg_temp_new_i64();
12575 TCGv_i64 fp1
= tcg_temp_new_i64();
12576 gen_load_fpr64(ctx
, fp0
, fs
);
12577 gen_load_fpr64(ctx
, fp1
, ft
);
12578 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12579 gen_store_fpr64(ctx
, fp1
, fd
);
12580 tcg_temp_free_i64(fp1
);
12581 tcg_temp_free_i64(fp0
);
12584 check_cp1_64bitmode(ctx
);
12586 TCGv_i64 fp0
= tcg_temp_new_i64();
12588 gen_load_fpr64(ctx
, fp0
, fs
);
12589 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12590 gen_store_fpr64(ctx
, fp0
, fd
);
12591 tcg_temp_free_i64(fp0
);
12595 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12596 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
12598 TCGv_i64 fp0
= tcg_temp_new_i64();
12599 TCGv_i64 fp1
= tcg_temp_new_i64();
12600 gen_load_fpr64(ctx
, fp0
, fs
);
12601 gen_load_fpr64(ctx
, fp1
, ft
);
12602 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12603 gen_store_fpr64(ctx
, fp1
, fd
);
12604 tcg_temp_free_i64(fp1
);
12605 tcg_temp_free_i64(fp0
);
12608 check_cp1_64bitmode(ctx
);
12610 TCGv_i64 fp0
= tcg_temp_new_i64();
12611 TCGv_i64 fp1
= tcg_temp_new_i64();
12613 gen_load_fpr64(ctx
, fp0
, fs
);
12614 gen_load_fpr64(ctx
, fp1
, ft
);
12615 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12616 tcg_temp_free_i64(fp1
);
12617 gen_store_fpr64(ctx
, fp0
, fd
);
12618 tcg_temp_free_i64(fp0
);
12625 case OPC_CMP_UEQ_D
:
12626 case OPC_CMP_OLT_D
:
12627 case OPC_CMP_ULT_D
:
12628 case OPC_CMP_OLE_D
:
12629 case OPC_CMP_ULE_D
:
12631 case OPC_CMP_NGLE_D
:
12632 case OPC_CMP_SEQ_D
:
12633 case OPC_CMP_NGL_D
:
12635 case OPC_CMP_NGE_D
:
12637 case OPC_CMP_NGT_D
:
12638 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
12639 if (ctx
->opcode
& (1 << 6)) {
12640 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12642 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12646 check_cp1_registers(ctx
, fs
);
12648 TCGv_i32 fp32
= tcg_temp_new_i32();
12649 TCGv_i64 fp64
= tcg_temp_new_i64();
12651 gen_load_fpr64(ctx
, fp64
, fs
);
12652 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12653 tcg_temp_free_i64(fp64
);
12654 gen_store_fpr32(ctx
, fp32
, fd
);
12655 tcg_temp_free_i32(fp32
);
12659 check_cp1_registers(ctx
, fs
);
12661 TCGv_i32 fp32
= tcg_temp_new_i32();
12662 TCGv_i64 fp64
= tcg_temp_new_i64();
12664 gen_load_fpr64(ctx
, fp64
, fs
);
12665 if (ctx
->nan2008
) {
12666 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12668 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12670 tcg_temp_free_i64(fp64
);
12671 gen_store_fpr32(ctx
, fp32
, fd
);
12672 tcg_temp_free_i32(fp32
);
12676 check_cp1_64bitmode(ctx
);
12678 TCGv_i64 fp0
= tcg_temp_new_i64();
12680 gen_load_fpr64(ctx
, fp0
, fs
);
12681 if (ctx
->nan2008
) {
12682 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12684 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12686 gen_store_fpr64(ctx
, fp0
, fd
);
12687 tcg_temp_free_i64(fp0
);
12692 TCGv_i32 fp0
= tcg_temp_new_i32();
12694 gen_load_fpr32(ctx
, fp0
, fs
);
12695 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12696 gen_store_fpr32(ctx
, fp0
, fd
);
12697 tcg_temp_free_i32(fp0
);
12701 check_cp1_registers(ctx
, fd
);
12703 TCGv_i32 fp32
= tcg_temp_new_i32();
12704 TCGv_i64 fp64
= tcg_temp_new_i64();
12706 gen_load_fpr32(ctx
, fp32
, fs
);
12707 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12708 tcg_temp_free_i32(fp32
);
12709 gen_store_fpr64(ctx
, fp64
, fd
);
12710 tcg_temp_free_i64(fp64
);
12714 check_cp1_64bitmode(ctx
);
12716 TCGv_i32 fp32
= tcg_temp_new_i32();
12717 TCGv_i64 fp64
= tcg_temp_new_i64();
12719 gen_load_fpr64(ctx
, fp64
, fs
);
12720 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12721 tcg_temp_free_i64(fp64
);
12722 gen_store_fpr32(ctx
, fp32
, fd
);
12723 tcg_temp_free_i32(fp32
);
12727 check_cp1_64bitmode(ctx
);
12729 TCGv_i64 fp0
= tcg_temp_new_i64();
12731 gen_load_fpr64(ctx
, fp0
, fs
);
12732 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12733 gen_store_fpr64(ctx
, fp0
, fd
);
12734 tcg_temp_free_i64(fp0
);
12737 case OPC_CVT_PS_PW
:
12740 TCGv_i64 fp0
= tcg_temp_new_i64();
12742 gen_load_fpr64(ctx
, fp0
, fs
);
12743 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12744 gen_store_fpr64(ctx
, fp0
, fd
);
12745 tcg_temp_free_i64(fp0
);
12751 TCGv_i64 fp0
= tcg_temp_new_i64();
12752 TCGv_i64 fp1
= tcg_temp_new_i64();
12754 gen_load_fpr64(ctx
, fp0
, fs
);
12755 gen_load_fpr64(ctx
, fp1
, ft
);
12756 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12757 tcg_temp_free_i64(fp1
);
12758 gen_store_fpr64(ctx
, fp0
, fd
);
12759 tcg_temp_free_i64(fp0
);
12765 TCGv_i64 fp0
= tcg_temp_new_i64();
12766 TCGv_i64 fp1
= tcg_temp_new_i64();
12768 gen_load_fpr64(ctx
, fp0
, fs
);
12769 gen_load_fpr64(ctx
, fp1
, ft
);
12770 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12771 tcg_temp_free_i64(fp1
);
12772 gen_store_fpr64(ctx
, fp0
, fd
);
12773 tcg_temp_free_i64(fp0
);
12779 TCGv_i64 fp0
= tcg_temp_new_i64();
12780 TCGv_i64 fp1
= tcg_temp_new_i64();
12782 gen_load_fpr64(ctx
, fp0
, fs
);
12783 gen_load_fpr64(ctx
, fp1
, ft
);
12784 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12785 tcg_temp_free_i64(fp1
);
12786 gen_store_fpr64(ctx
, fp0
, fd
);
12787 tcg_temp_free_i64(fp0
);
12793 TCGv_i64 fp0
= tcg_temp_new_i64();
12795 gen_load_fpr64(ctx
, fp0
, fs
);
12796 gen_helper_float_abs_ps(fp0
, fp0
);
12797 gen_store_fpr64(ctx
, fp0
, fd
);
12798 tcg_temp_free_i64(fp0
);
12804 TCGv_i64 fp0
= tcg_temp_new_i64();
12806 gen_load_fpr64(ctx
, fp0
, fs
);
12807 gen_store_fpr64(ctx
, fp0
, fd
);
12808 tcg_temp_free_i64(fp0
);
12814 TCGv_i64 fp0
= tcg_temp_new_i64();
12816 gen_load_fpr64(ctx
, fp0
, fs
);
12817 gen_helper_float_chs_ps(fp0
, fp0
);
12818 gen_store_fpr64(ctx
, fp0
, fd
);
12819 tcg_temp_free_i64(fp0
);
12824 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12829 TCGLabel
*l1
= gen_new_label();
12833 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12835 fp0
= tcg_temp_new_i64();
12836 gen_load_fpr64(ctx
, fp0
, fs
);
12837 gen_store_fpr64(ctx
, fp0
, fd
);
12838 tcg_temp_free_i64(fp0
);
12845 TCGLabel
*l1
= gen_new_label();
12849 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12850 fp0
= tcg_temp_new_i64();
12851 gen_load_fpr64(ctx
, fp0
, fs
);
12852 gen_store_fpr64(ctx
, fp0
, fd
);
12853 tcg_temp_free_i64(fp0
);
12861 TCGv_i64 fp0
= tcg_temp_new_i64();
12862 TCGv_i64 fp1
= tcg_temp_new_i64();
12864 gen_load_fpr64(ctx
, fp0
, ft
);
12865 gen_load_fpr64(ctx
, fp1
, fs
);
12866 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12867 tcg_temp_free_i64(fp1
);
12868 gen_store_fpr64(ctx
, fp0
, fd
);
12869 tcg_temp_free_i64(fp0
);
12875 TCGv_i64 fp0
= tcg_temp_new_i64();
12876 TCGv_i64 fp1
= tcg_temp_new_i64();
12878 gen_load_fpr64(ctx
, fp0
, ft
);
12879 gen_load_fpr64(ctx
, fp1
, fs
);
12880 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12881 tcg_temp_free_i64(fp1
);
12882 gen_store_fpr64(ctx
, fp0
, fd
);
12883 tcg_temp_free_i64(fp0
);
12886 case OPC_RECIP2_PS
:
12889 TCGv_i64 fp0
= tcg_temp_new_i64();
12890 TCGv_i64 fp1
= tcg_temp_new_i64();
12892 gen_load_fpr64(ctx
, fp0
, fs
);
12893 gen_load_fpr64(ctx
, fp1
, ft
);
12894 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12895 tcg_temp_free_i64(fp1
);
12896 gen_store_fpr64(ctx
, fp0
, fd
);
12897 tcg_temp_free_i64(fp0
);
12900 case OPC_RECIP1_PS
:
12903 TCGv_i64 fp0
= tcg_temp_new_i64();
12905 gen_load_fpr64(ctx
, fp0
, fs
);
12906 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12907 gen_store_fpr64(ctx
, fp0
, fd
);
12908 tcg_temp_free_i64(fp0
);
12911 case OPC_RSQRT1_PS
:
12914 TCGv_i64 fp0
= tcg_temp_new_i64();
12916 gen_load_fpr64(ctx
, fp0
, fs
);
12917 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12918 gen_store_fpr64(ctx
, fp0
, fd
);
12919 tcg_temp_free_i64(fp0
);
12922 case OPC_RSQRT2_PS
:
12925 TCGv_i64 fp0
= tcg_temp_new_i64();
12926 TCGv_i64 fp1
= tcg_temp_new_i64();
12928 gen_load_fpr64(ctx
, fp0
, fs
);
12929 gen_load_fpr64(ctx
, fp1
, ft
);
12930 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12931 tcg_temp_free_i64(fp1
);
12932 gen_store_fpr64(ctx
, fp0
, fd
);
12933 tcg_temp_free_i64(fp0
);
12937 check_cp1_64bitmode(ctx
);
12939 TCGv_i32 fp0
= tcg_temp_new_i32();
12941 gen_load_fpr32h(ctx
, fp0
, fs
);
12942 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12943 gen_store_fpr32(ctx
, fp0
, fd
);
12944 tcg_temp_free_i32(fp0
);
12947 case OPC_CVT_PW_PS
:
12950 TCGv_i64 fp0
= tcg_temp_new_i64();
12952 gen_load_fpr64(ctx
, fp0
, fs
);
12953 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
12954 gen_store_fpr64(ctx
, fp0
, fd
);
12955 tcg_temp_free_i64(fp0
);
12959 check_cp1_64bitmode(ctx
);
12961 TCGv_i32 fp0
= tcg_temp_new_i32();
12963 gen_load_fpr32(ctx
, fp0
, fs
);
12964 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
12965 gen_store_fpr32(ctx
, fp0
, fd
);
12966 tcg_temp_free_i32(fp0
);
12972 TCGv_i32 fp0
= tcg_temp_new_i32();
12973 TCGv_i32 fp1
= tcg_temp_new_i32();
12975 gen_load_fpr32(ctx
, fp0
, fs
);
12976 gen_load_fpr32(ctx
, fp1
, ft
);
12977 gen_store_fpr32h(ctx
, fp0
, fd
);
12978 gen_store_fpr32(ctx
, fp1
, fd
);
12979 tcg_temp_free_i32(fp0
);
12980 tcg_temp_free_i32(fp1
);
12986 TCGv_i32 fp0
= tcg_temp_new_i32();
12987 TCGv_i32 fp1
= tcg_temp_new_i32();
12989 gen_load_fpr32(ctx
, fp0
, fs
);
12990 gen_load_fpr32h(ctx
, fp1
, ft
);
12991 gen_store_fpr32(ctx
, fp1
, fd
);
12992 gen_store_fpr32h(ctx
, fp0
, fd
);
12993 tcg_temp_free_i32(fp0
);
12994 tcg_temp_free_i32(fp1
);
13000 TCGv_i32 fp0
= tcg_temp_new_i32();
13001 TCGv_i32 fp1
= tcg_temp_new_i32();
13003 gen_load_fpr32h(ctx
, fp0
, fs
);
13004 gen_load_fpr32(ctx
, fp1
, ft
);
13005 gen_store_fpr32(ctx
, fp1
, fd
);
13006 gen_store_fpr32h(ctx
, fp0
, fd
);
13007 tcg_temp_free_i32(fp0
);
13008 tcg_temp_free_i32(fp1
);
13014 TCGv_i32 fp0
= tcg_temp_new_i32();
13015 TCGv_i32 fp1
= tcg_temp_new_i32();
13017 gen_load_fpr32h(ctx
, fp0
, fs
);
13018 gen_load_fpr32h(ctx
, fp1
, ft
);
13019 gen_store_fpr32(ctx
, fp1
, fd
);
13020 gen_store_fpr32h(ctx
, fp0
, fd
);
13021 tcg_temp_free_i32(fp0
);
13022 tcg_temp_free_i32(fp1
);
13026 case OPC_CMP_UN_PS
:
13027 case OPC_CMP_EQ_PS
:
13028 case OPC_CMP_UEQ_PS
:
13029 case OPC_CMP_OLT_PS
:
13030 case OPC_CMP_ULT_PS
:
13031 case OPC_CMP_OLE_PS
:
13032 case OPC_CMP_ULE_PS
:
13033 case OPC_CMP_SF_PS
:
13034 case OPC_CMP_NGLE_PS
:
13035 case OPC_CMP_SEQ_PS
:
13036 case OPC_CMP_NGL_PS
:
13037 case OPC_CMP_LT_PS
:
13038 case OPC_CMP_NGE_PS
:
13039 case OPC_CMP_LE_PS
:
13040 case OPC_CMP_NGT_PS
:
13041 if (ctx
->opcode
& (1 << 6)) {
13042 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
13044 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
13048 MIPS_INVAL("farith");
13049 gen_reserved_instruction(ctx
);
13054 /* Coprocessor 3 (FPU) */
13055 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
13056 int fd
, int fs
, int base
, int index
)
13058 TCGv t0
= tcg_temp_new();
13061 gen_load_gpr(t0
, index
);
13062 } else if (index
== 0) {
13063 gen_load_gpr(t0
, base
);
13065 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
13068 * Don't do NOP if destination is zero: we must perform the actual
13075 TCGv_i32 fp0
= tcg_temp_new_i32();
13077 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
13078 tcg_gen_trunc_tl_i32(fp0
, t0
);
13079 gen_store_fpr32(ctx
, fp0
, fd
);
13080 tcg_temp_free_i32(fp0
);
13085 check_cp1_registers(ctx
, fd
);
13087 TCGv_i64 fp0
= tcg_temp_new_i64();
13088 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13089 gen_store_fpr64(ctx
, fp0
, fd
);
13090 tcg_temp_free_i64(fp0
);
13094 check_cp1_64bitmode(ctx
);
13095 tcg_gen_andi_tl(t0
, t0
, ~0x7);
13097 TCGv_i64 fp0
= tcg_temp_new_i64();
13099 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13100 gen_store_fpr64(ctx
, fp0
, fd
);
13101 tcg_temp_free_i64(fp0
);
13107 TCGv_i32 fp0
= tcg_temp_new_i32();
13108 gen_load_fpr32(ctx
, fp0
, fs
);
13109 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
13110 tcg_temp_free_i32(fp0
);
13115 check_cp1_registers(ctx
, fs
);
13117 TCGv_i64 fp0
= tcg_temp_new_i64();
13118 gen_load_fpr64(ctx
, fp0
, fs
);
13119 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13120 tcg_temp_free_i64(fp0
);
13124 check_cp1_64bitmode(ctx
);
13125 tcg_gen_andi_tl(t0
, t0
, ~0x7);
13127 TCGv_i64 fp0
= tcg_temp_new_i64();
13128 gen_load_fpr64(ctx
, fp0
, fs
);
13129 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13130 tcg_temp_free_i64(fp0
);
13137 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
13138 int fd
, int fr
, int fs
, int ft
)
13144 TCGv t0
= tcg_temp_local_new();
13145 TCGv_i32 fp
= tcg_temp_new_i32();
13146 TCGv_i32 fph
= tcg_temp_new_i32();
13147 TCGLabel
*l1
= gen_new_label();
13148 TCGLabel
*l2
= gen_new_label();
13150 gen_load_gpr(t0
, fr
);
13151 tcg_gen_andi_tl(t0
, t0
, 0x7);
13153 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
13154 gen_load_fpr32(ctx
, fp
, fs
);
13155 gen_load_fpr32h(ctx
, fph
, fs
);
13156 gen_store_fpr32(ctx
, fp
, fd
);
13157 gen_store_fpr32h(ctx
, fph
, fd
);
13160 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
13162 #ifdef TARGET_WORDS_BIGENDIAN
13163 gen_load_fpr32(ctx
, fp
, fs
);
13164 gen_load_fpr32h(ctx
, fph
, ft
);
13165 gen_store_fpr32h(ctx
, fp
, fd
);
13166 gen_store_fpr32(ctx
, fph
, fd
);
13168 gen_load_fpr32h(ctx
, fph
, fs
);
13169 gen_load_fpr32(ctx
, fp
, ft
);
13170 gen_store_fpr32(ctx
, fph
, fd
);
13171 gen_store_fpr32h(ctx
, fp
, fd
);
13174 tcg_temp_free_i32(fp
);
13175 tcg_temp_free_i32(fph
);
13181 TCGv_i32 fp0
= tcg_temp_new_i32();
13182 TCGv_i32 fp1
= tcg_temp_new_i32();
13183 TCGv_i32 fp2
= tcg_temp_new_i32();
13185 gen_load_fpr32(ctx
, fp0
, fs
);
13186 gen_load_fpr32(ctx
, fp1
, ft
);
13187 gen_load_fpr32(ctx
, fp2
, fr
);
13188 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13189 tcg_temp_free_i32(fp0
);
13190 tcg_temp_free_i32(fp1
);
13191 gen_store_fpr32(ctx
, fp2
, fd
);
13192 tcg_temp_free_i32(fp2
);
13197 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13199 TCGv_i64 fp0
= tcg_temp_new_i64();
13200 TCGv_i64 fp1
= tcg_temp_new_i64();
13201 TCGv_i64 fp2
= tcg_temp_new_i64();
13203 gen_load_fpr64(ctx
, fp0
, fs
);
13204 gen_load_fpr64(ctx
, fp1
, ft
);
13205 gen_load_fpr64(ctx
, fp2
, fr
);
13206 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13207 tcg_temp_free_i64(fp0
);
13208 tcg_temp_free_i64(fp1
);
13209 gen_store_fpr64(ctx
, fp2
, fd
);
13210 tcg_temp_free_i64(fp2
);
13216 TCGv_i64 fp0
= tcg_temp_new_i64();
13217 TCGv_i64 fp1
= tcg_temp_new_i64();
13218 TCGv_i64 fp2
= tcg_temp_new_i64();
13220 gen_load_fpr64(ctx
, fp0
, fs
);
13221 gen_load_fpr64(ctx
, fp1
, ft
);
13222 gen_load_fpr64(ctx
, fp2
, fr
);
13223 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13224 tcg_temp_free_i64(fp0
);
13225 tcg_temp_free_i64(fp1
);
13226 gen_store_fpr64(ctx
, fp2
, fd
);
13227 tcg_temp_free_i64(fp2
);
13233 TCGv_i32 fp0
= tcg_temp_new_i32();
13234 TCGv_i32 fp1
= tcg_temp_new_i32();
13235 TCGv_i32 fp2
= tcg_temp_new_i32();
13237 gen_load_fpr32(ctx
, fp0
, fs
);
13238 gen_load_fpr32(ctx
, fp1
, ft
);
13239 gen_load_fpr32(ctx
, fp2
, fr
);
13240 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13241 tcg_temp_free_i32(fp0
);
13242 tcg_temp_free_i32(fp1
);
13243 gen_store_fpr32(ctx
, fp2
, fd
);
13244 tcg_temp_free_i32(fp2
);
13249 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13251 TCGv_i64 fp0
= tcg_temp_new_i64();
13252 TCGv_i64 fp1
= tcg_temp_new_i64();
13253 TCGv_i64 fp2
= tcg_temp_new_i64();
13255 gen_load_fpr64(ctx
, fp0
, fs
);
13256 gen_load_fpr64(ctx
, fp1
, ft
);
13257 gen_load_fpr64(ctx
, fp2
, fr
);
13258 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13259 tcg_temp_free_i64(fp0
);
13260 tcg_temp_free_i64(fp1
);
13261 gen_store_fpr64(ctx
, fp2
, fd
);
13262 tcg_temp_free_i64(fp2
);
13268 TCGv_i64 fp0
= tcg_temp_new_i64();
13269 TCGv_i64 fp1
= tcg_temp_new_i64();
13270 TCGv_i64 fp2
= tcg_temp_new_i64();
13272 gen_load_fpr64(ctx
, fp0
, fs
);
13273 gen_load_fpr64(ctx
, fp1
, ft
);
13274 gen_load_fpr64(ctx
, fp2
, fr
);
13275 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13276 tcg_temp_free_i64(fp0
);
13277 tcg_temp_free_i64(fp1
);
13278 gen_store_fpr64(ctx
, fp2
, fd
);
13279 tcg_temp_free_i64(fp2
);
13285 TCGv_i32 fp0
= tcg_temp_new_i32();
13286 TCGv_i32 fp1
= tcg_temp_new_i32();
13287 TCGv_i32 fp2
= tcg_temp_new_i32();
13289 gen_load_fpr32(ctx
, fp0
, fs
);
13290 gen_load_fpr32(ctx
, fp1
, ft
);
13291 gen_load_fpr32(ctx
, fp2
, fr
);
13292 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13293 tcg_temp_free_i32(fp0
);
13294 tcg_temp_free_i32(fp1
);
13295 gen_store_fpr32(ctx
, fp2
, fd
);
13296 tcg_temp_free_i32(fp2
);
13301 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13303 TCGv_i64 fp0
= tcg_temp_new_i64();
13304 TCGv_i64 fp1
= tcg_temp_new_i64();
13305 TCGv_i64 fp2
= tcg_temp_new_i64();
13307 gen_load_fpr64(ctx
, fp0
, fs
);
13308 gen_load_fpr64(ctx
, fp1
, ft
);
13309 gen_load_fpr64(ctx
, fp2
, fr
);
13310 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13311 tcg_temp_free_i64(fp0
);
13312 tcg_temp_free_i64(fp1
);
13313 gen_store_fpr64(ctx
, fp2
, fd
);
13314 tcg_temp_free_i64(fp2
);
13320 TCGv_i64 fp0
= tcg_temp_new_i64();
13321 TCGv_i64 fp1
= tcg_temp_new_i64();
13322 TCGv_i64 fp2
= tcg_temp_new_i64();
13324 gen_load_fpr64(ctx
, fp0
, fs
);
13325 gen_load_fpr64(ctx
, fp1
, ft
);
13326 gen_load_fpr64(ctx
, fp2
, fr
);
13327 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13328 tcg_temp_free_i64(fp0
);
13329 tcg_temp_free_i64(fp1
);
13330 gen_store_fpr64(ctx
, fp2
, fd
);
13331 tcg_temp_free_i64(fp2
);
13337 TCGv_i32 fp0
= tcg_temp_new_i32();
13338 TCGv_i32 fp1
= tcg_temp_new_i32();
13339 TCGv_i32 fp2
= tcg_temp_new_i32();
13341 gen_load_fpr32(ctx
, fp0
, fs
);
13342 gen_load_fpr32(ctx
, fp1
, ft
);
13343 gen_load_fpr32(ctx
, fp2
, fr
);
13344 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13345 tcg_temp_free_i32(fp0
);
13346 tcg_temp_free_i32(fp1
);
13347 gen_store_fpr32(ctx
, fp2
, fd
);
13348 tcg_temp_free_i32(fp2
);
13353 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
13355 TCGv_i64 fp0
= tcg_temp_new_i64();
13356 TCGv_i64 fp1
= tcg_temp_new_i64();
13357 TCGv_i64 fp2
= tcg_temp_new_i64();
13359 gen_load_fpr64(ctx
, fp0
, fs
);
13360 gen_load_fpr64(ctx
, fp1
, ft
);
13361 gen_load_fpr64(ctx
, fp2
, fr
);
13362 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13363 tcg_temp_free_i64(fp0
);
13364 tcg_temp_free_i64(fp1
);
13365 gen_store_fpr64(ctx
, fp2
, fd
);
13366 tcg_temp_free_i64(fp2
);
13372 TCGv_i64 fp0
= tcg_temp_new_i64();
13373 TCGv_i64 fp1
= tcg_temp_new_i64();
13374 TCGv_i64 fp2
= tcg_temp_new_i64();
13376 gen_load_fpr64(ctx
, fp0
, fs
);
13377 gen_load_fpr64(ctx
, fp1
, ft
);
13378 gen_load_fpr64(ctx
, fp2
, fr
);
13379 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
13380 tcg_temp_free_i64(fp0
);
13381 tcg_temp_free_i64(fp1
);
13382 gen_store_fpr64(ctx
, fp2
, fd
);
13383 tcg_temp_free_i64(fp2
);
13387 MIPS_INVAL("flt3_arith");
13388 gen_reserved_instruction(ctx
);
13393 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
13397 #if !defined(CONFIG_USER_ONLY)
13399 * The Linux kernel will emulate rdhwr if it's not supported natively.
13400 * Therefore only check the ISA in system mode.
13402 check_insn(ctx
, ISA_MIPS_R2
);
13404 t0
= tcg_temp_new();
13408 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
13409 gen_store_gpr(t0
, rt
);
13412 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
13413 gen_store_gpr(t0
, rt
);
13416 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
13419 gen_helper_rdhwr_cc(t0
, cpu_env
);
13420 gen_store_gpr(t0
, rt
);
13422 * Break the TB to be able to take timer interrupts immediately
13423 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
13424 * we break completely out of translated code.
13426 gen_save_pc(ctx
->base
.pc_next
+ 4);
13427 ctx
->base
.is_jmp
= DISAS_EXIT
;
13430 gen_helper_rdhwr_ccres(t0
, cpu_env
);
13431 gen_store_gpr(t0
, rt
);
13434 check_insn(ctx
, ISA_MIPS_R6
);
13437 * Performance counter registers are not implemented other than
13438 * control register 0.
13440 generate_exception(ctx
, EXCP_RI
);
13442 gen_helper_rdhwr_performance(t0
, cpu_env
);
13443 gen_store_gpr(t0
, rt
);
13446 check_insn(ctx
, ISA_MIPS_R6
);
13447 gen_helper_rdhwr_xnp(t0
, cpu_env
);
13448 gen_store_gpr(t0
, rt
);
13451 #if defined(CONFIG_USER_ONLY)
13452 tcg_gen_ld_tl(t0
, cpu_env
,
13453 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13454 gen_store_gpr(t0
, rt
);
13457 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
13458 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
13459 tcg_gen_ld_tl(t0
, cpu_env
,
13460 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
13461 gen_store_gpr(t0
, rt
);
13463 gen_reserved_instruction(ctx
);
13467 default: /* Invalid */
13468 MIPS_INVAL("rdhwr");
13469 gen_reserved_instruction(ctx
);
13475 static inline void clear_branch_hflags(DisasContext
*ctx
)
13477 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
13478 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
13479 save_cpu_state(ctx
, 0);
13482 * It is not safe to save ctx->hflags as hflags may be changed
13483 * in execution time by the instruction in delay / forbidden slot.
13485 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
13489 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
13491 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13492 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
13493 /* Branches completion */
13494 clear_branch_hflags(ctx
);
13495 ctx
->base
.is_jmp
= DISAS_NORETURN
;
13496 /* FIXME: Need to clear can_do_io. */
13497 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
13498 case MIPS_HFLAG_FBNSLOT
:
13499 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
13502 /* unconditional branch */
13503 if (proc_hflags
& MIPS_HFLAG_BX
) {
13504 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
13506 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13508 case MIPS_HFLAG_BL
:
13509 /* blikely taken case */
13510 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13512 case MIPS_HFLAG_BC
:
13513 /* Conditional branch */
13515 TCGLabel
*l1
= gen_new_label();
13517 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
13518 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
13520 gen_goto_tb(ctx
, 0, ctx
->btarget
);
13523 case MIPS_HFLAG_BR
:
13524 /* unconditional branch to register */
13525 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
13526 TCGv t0
= tcg_temp_new();
13527 TCGv_i32 t1
= tcg_temp_new_i32();
13529 tcg_gen_andi_tl(t0
, btarget
, 0x1);
13530 tcg_gen_trunc_tl_i32(t1
, t0
);
13532 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
13533 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
13534 tcg_gen_or_i32(hflags
, hflags
, t1
);
13535 tcg_temp_free_i32(t1
);
13537 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
13539 tcg_gen_mov_tl(cpu_PC
, btarget
);
13541 if (ctx
->base
.singlestep_enabled
) {
13542 save_cpu_state(ctx
, 0);
13543 gen_helper_raise_exception_debug(cpu_env
);
13545 tcg_gen_lookup_and_goto_ptr();
13548 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
13554 /* Compact Branches */
13555 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
13556 int rs
, int rt
, int32_t offset
)
13558 int bcond_compute
= 0;
13559 TCGv t0
= tcg_temp_new();
13560 TCGv t1
= tcg_temp_new();
13561 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
13563 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13564 #ifdef MIPS_DEBUG_DISAS
13565 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
13566 "\n", ctx
->base
.pc_next
);
13568 gen_reserved_instruction(ctx
);
13572 /* Load needed operands and calculate btarget */
13574 /* compact branch */
13575 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13576 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13577 gen_load_gpr(t0
, rs
);
13578 gen_load_gpr(t1
, rt
);
13580 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13581 if (rs
<= rt
&& rs
== 0) {
13582 /* OPC_BEQZALC, OPC_BNEZALC */
13583 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13586 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13587 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13588 gen_load_gpr(t0
, rs
);
13589 gen_load_gpr(t1
, rt
);
13591 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13593 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13594 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13595 if (rs
== 0 || rs
== rt
) {
13596 /* OPC_BLEZALC, OPC_BGEZALC */
13597 /* OPC_BGTZALC, OPC_BLTZALC */
13598 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13600 gen_load_gpr(t0
, rs
);
13601 gen_load_gpr(t1
, rt
);
13603 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13607 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13612 /* OPC_BEQZC, OPC_BNEZC */
13613 gen_load_gpr(t0
, rs
);
13615 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13617 /* OPC_JIC, OPC_JIALC */
13618 TCGv tbase
= tcg_temp_new();
13619 TCGv toffset
= tcg_temp_new();
13621 gen_load_gpr(tbase
, rt
);
13622 tcg_gen_movi_tl(toffset
, offset
);
13623 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13624 tcg_temp_free(tbase
);
13625 tcg_temp_free(toffset
);
13629 MIPS_INVAL("Compact branch/jump");
13630 gen_reserved_instruction(ctx
);
13634 if (bcond_compute
== 0) {
13635 /* Uncoditional compact branch */
13638 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13641 ctx
->hflags
|= MIPS_HFLAG_BR
;
13644 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13647 ctx
->hflags
|= MIPS_HFLAG_B
;
13650 MIPS_INVAL("Compact branch/jump");
13651 gen_reserved_instruction(ctx
);
13655 /* Generating branch here as compact branches don't have delay slot */
13656 gen_branch(ctx
, 4);
13658 /* Conditional compact branch */
13659 TCGLabel
*fs
= gen_new_label();
13660 save_cpu_state(ctx
, 0);
13663 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13664 if (rs
== 0 && rt
!= 0) {
13666 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13667 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13669 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13672 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13675 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13676 if (rs
== 0 && rt
!= 0) {
13678 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13679 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13681 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13684 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13687 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13688 if (rs
== 0 && rt
!= 0) {
13690 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13691 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13693 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13696 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13699 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13700 if (rs
== 0 && rt
!= 0) {
13702 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13703 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13705 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13708 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13711 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13712 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13714 /* OPC_BOVC, OPC_BNVC */
13715 TCGv t2
= tcg_temp_new();
13716 TCGv t3
= tcg_temp_new();
13717 TCGv t4
= tcg_temp_new();
13718 TCGv input_overflow
= tcg_temp_new();
13720 gen_load_gpr(t0
, rs
);
13721 gen_load_gpr(t1
, rt
);
13722 tcg_gen_ext32s_tl(t2
, t0
);
13723 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13724 tcg_gen_ext32s_tl(t3
, t1
);
13725 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13726 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13728 tcg_gen_add_tl(t4
, t2
, t3
);
13729 tcg_gen_ext32s_tl(t4
, t4
);
13730 tcg_gen_xor_tl(t2
, t2
, t3
);
13731 tcg_gen_xor_tl(t3
, t4
, t3
);
13732 tcg_gen_andc_tl(t2
, t3
, t2
);
13733 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13734 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13735 if (opc
== OPC_BOVC
) {
13737 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13740 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13742 tcg_temp_free(input_overflow
);
13746 } else if (rs
< rt
&& rs
== 0) {
13747 /* OPC_BEQZALC, OPC_BNEZALC */
13748 if (opc
== OPC_BEQZALC
) {
13750 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13753 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13756 /* OPC_BEQC, OPC_BNEC */
13757 if (opc
== OPC_BEQC
) {
13759 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13762 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13767 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13770 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13773 MIPS_INVAL("Compact conditional branch/jump");
13774 gen_reserved_instruction(ctx
);
13778 /* Generating branch here as compact branches don't have delay slot */
13779 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13782 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13790 /* ISA extensions (ASEs) */
13791 /* MIPS16 extension to MIPS32 */
13793 /* MIPS16 major opcodes */
13795 M16_OPC_ADDIUSP
= 0x00,
13796 M16_OPC_ADDIUPC
= 0x01,
13798 M16_OPC_JAL
= 0x03,
13799 M16_OPC_BEQZ
= 0x04,
13800 M16_OPC_BNEQZ
= 0x05,
13801 M16_OPC_SHIFT
= 0x06,
13803 M16_OPC_RRIA
= 0x08,
13804 M16_OPC_ADDIU8
= 0x09,
13805 M16_OPC_SLTI
= 0x0a,
13806 M16_OPC_SLTIU
= 0x0b,
13809 M16_OPC_CMPI
= 0x0e,
13813 M16_OPC_LWSP
= 0x12,
13815 M16_OPC_LBU
= 0x14,
13816 M16_OPC_LHU
= 0x15,
13817 M16_OPC_LWPC
= 0x16,
13818 M16_OPC_LWU
= 0x17,
13821 M16_OPC_SWSP
= 0x1a,
13823 M16_OPC_RRR
= 0x1c,
13825 M16_OPC_EXTEND
= 0x1e,
13829 /* I8 funct field */
13848 /* RR funct field */
13882 /* I64 funct field */
13890 I64_DADDIUPC
= 0x6,
13894 /* RR ry field for CNVT */
13896 RR_RY_CNVT_ZEB
= 0x0,
13897 RR_RY_CNVT_ZEH
= 0x1,
13898 RR_RY_CNVT_ZEW
= 0x2,
13899 RR_RY_CNVT_SEB
= 0x4,
13900 RR_RY_CNVT_SEH
= 0x5,
13901 RR_RY_CNVT_SEW
= 0x6,
13904 static int xlat(int r
)
13906 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13911 static void gen_mips16_save(DisasContext
*ctx
,
13912 int xsregs
, int aregs
,
13913 int do_ra
, int do_s0
, int do_s1
,
13916 TCGv t0
= tcg_temp_new();
13917 TCGv t1
= tcg_temp_new();
13918 TCGv t2
= tcg_temp_new();
13948 gen_reserved_instruction(ctx
);
13954 gen_base_offset_addr(ctx
, t0
, 29, 12);
13955 gen_load_gpr(t1
, 7);
13956 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13959 gen_base_offset_addr(ctx
, t0
, 29, 8);
13960 gen_load_gpr(t1
, 6);
13961 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13964 gen_base_offset_addr(ctx
, t0
, 29, 4);
13965 gen_load_gpr(t1
, 5);
13966 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13969 gen_base_offset_addr(ctx
, t0
, 29, 0);
13970 gen_load_gpr(t1
, 4);
13971 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13974 gen_load_gpr(t0
, 29);
13976 #define DECR_AND_STORE(reg) do { \
13977 tcg_gen_movi_tl(t2, -4); \
13978 gen_op_addr_add(ctx, t0, t0, t2); \
13979 gen_load_gpr(t1, reg); \
13980 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13984 DECR_AND_STORE(31);
13989 DECR_AND_STORE(30);
13992 DECR_AND_STORE(23);
13995 DECR_AND_STORE(22);
13998 DECR_AND_STORE(21);
14001 DECR_AND_STORE(20);
14004 DECR_AND_STORE(19);
14007 DECR_AND_STORE(18);
14011 DECR_AND_STORE(17);
14014 DECR_AND_STORE(16);
14044 gen_reserved_instruction(ctx
);
14060 #undef DECR_AND_STORE
14062 tcg_gen_movi_tl(t2
, -framesize
);
14063 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
14069 static void gen_mips16_restore(DisasContext
*ctx
,
14070 int xsregs
, int aregs
,
14071 int do_ra
, int do_s0
, int do_s1
,
14075 TCGv t0
= tcg_temp_new();
14076 TCGv t1
= tcg_temp_new();
14077 TCGv t2
= tcg_temp_new();
14079 tcg_gen_movi_tl(t2
, framesize
);
14080 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
14082 #define DECR_AND_LOAD(reg) do { \
14083 tcg_gen_movi_tl(t2, -4); \
14084 gen_op_addr_add(ctx, t0, t0, t2); \
14085 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
14086 gen_store_gpr(t1, reg); \
14150 gen_reserved_instruction(ctx
);
14166 #undef DECR_AND_LOAD
14168 tcg_gen_movi_tl(t2
, framesize
);
14169 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
14175 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
14176 int is_64_bit
, int extended
)
14180 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
14181 gen_reserved_instruction(ctx
);
14185 t0
= tcg_temp_new();
14187 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
14188 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
14190 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14196 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
14199 TCGv_i32 t0
= tcg_const_i32(op
);
14200 TCGv t1
= tcg_temp_new();
14201 gen_base_offset_addr(ctx
, t1
, base
, offset
);
14202 gen_helper_cache(cpu_env
, t1
, t0
);
14205 #if defined(TARGET_MIPS64)
14206 static void decode_i64_mips16(DisasContext
*ctx
,
14207 int ry
, int funct
, int16_t offset
,
14212 check_insn(ctx
, ISA_MIPS3
);
14213 check_mips_64(ctx
);
14214 offset
= extended
? offset
: offset
<< 3;
14215 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
14218 check_insn(ctx
, ISA_MIPS3
);
14219 check_mips_64(ctx
);
14220 offset
= extended
? offset
: offset
<< 3;
14221 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
14224 check_insn(ctx
, ISA_MIPS3
);
14225 check_mips_64(ctx
);
14226 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
14227 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
14230 check_insn(ctx
, ISA_MIPS3
);
14231 check_mips_64(ctx
);
14232 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
14233 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
14236 check_insn(ctx
, ISA_MIPS3
);
14237 check_mips_64(ctx
);
14238 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
14239 gen_reserved_instruction(ctx
);
14241 offset
= extended
? offset
: offset
<< 3;
14242 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
14246 check_insn(ctx
, ISA_MIPS3
);
14247 check_mips_64(ctx
);
14248 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
14249 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
14252 check_insn(ctx
, ISA_MIPS3
);
14253 check_mips_64(ctx
);
14254 offset
= extended
? offset
: offset
<< 2;
14255 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
14258 check_insn(ctx
, ISA_MIPS3
);
14259 check_mips_64(ctx
);
14260 offset
= extended
? offset
: offset
<< 2;
14261 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
14267 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14269 int extend
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14270 int op
, rx
, ry
, funct
, sa
;
14271 int16_t imm
, offset
;
14273 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
14274 op
= (ctx
->opcode
>> 11) & 0x1f;
14275 sa
= (ctx
->opcode
>> 22) & 0x1f;
14276 funct
= (ctx
->opcode
>> 8) & 0x7;
14277 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14278 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14279 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
14280 | ((ctx
->opcode
>> 21) & 0x3f) << 5
14281 | (ctx
->opcode
& 0x1f));
14284 * The extended opcodes cleverly reuse the opcodes from their 16-bit
14288 case M16_OPC_ADDIUSP
:
14289 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14291 case M16_OPC_ADDIUPC
:
14292 gen_addiupc(ctx
, rx
, imm
, 0, 1);
14295 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
14296 /* No delay slot, so just process as a normal instruction */
14299 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
14300 /* No delay slot, so just process as a normal instruction */
14302 case M16_OPC_BNEQZ
:
14303 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
14304 /* No delay slot, so just process as a normal instruction */
14306 case M16_OPC_SHIFT
:
14307 switch (ctx
->opcode
& 0x3) {
14309 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14312 #if defined(TARGET_MIPS64)
14313 check_mips_64(ctx
);
14314 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14316 gen_reserved_instruction(ctx
);
14320 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14323 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14327 #if defined(TARGET_MIPS64)
14329 check_insn(ctx
, ISA_MIPS3
);
14330 check_mips_64(ctx
);
14331 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
14335 imm
= ctx
->opcode
& 0xf;
14336 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
14337 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
14338 imm
= (int16_t) (imm
<< 1) >> 1;
14339 if ((ctx
->opcode
>> 4) & 0x1) {
14340 #if defined(TARGET_MIPS64)
14341 check_mips_64(ctx
);
14342 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14344 gen_reserved_instruction(ctx
);
14347 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14350 case M16_OPC_ADDIU8
:
14351 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14354 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14356 case M16_OPC_SLTIU
:
14357 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14362 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
14365 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
14368 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
14371 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
14374 check_insn(ctx
, ISA_MIPS_R1
);
14376 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
14377 int aregs
= (ctx
->opcode
>> 16) & 0xf;
14378 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
14379 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
14380 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
14381 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
14382 | (ctx
->opcode
& 0xf)) << 3;
14384 if (ctx
->opcode
& (1 << 7)) {
14385 gen_mips16_save(ctx
, xsregs
, aregs
,
14386 do_ra
, do_s0
, do_s1
,
14389 gen_mips16_restore(ctx
, xsregs
, aregs
,
14390 do_ra
, do_s0
, do_s1
,
14396 gen_reserved_instruction(ctx
);
14401 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
14404 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
14406 #if defined(TARGET_MIPS64)
14408 check_insn(ctx
, ISA_MIPS3
);
14409 check_mips_64(ctx
);
14410 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
14414 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14417 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
14420 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
14423 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
14426 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14429 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
14432 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
14434 #if defined(TARGET_MIPS64)
14436 check_insn(ctx
, ISA_MIPS3
);
14437 check_mips_64(ctx
);
14438 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
14442 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14445 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
14448 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
14451 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
14453 #if defined(TARGET_MIPS64)
14455 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
14459 gen_reserved_instruction(ctx
);
14466 static inline bool is_uhi(int sdbbp_code
)
14468 #ifdef CONFIG_USER_ONLY
14471 return semihosting_enabled() && sdbbp_code
== 1;
14475 #ifdef CONFIG_USER_ONLY
14476 /* The above should dead-code away any calls to this..*/
14477 static inline void gen_helper_do_semihosting(void *env
)
14479 g_assert_not_reached();
14483 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14487 int op
, cnvt_op
, op1
, offset
;
14491 op
= (ctx
->opcode
>> 11) & 0x1f;
14492 sa
= (ctx
->opcode
>> 2) & 0x7;
14493 sa
= sa
== 0 ? 8 : sa
;
14494 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
14495 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
14496 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
14497 op1
= offset
= ctx
->opcode
& 0x1f;
14502 case M16_OPC_ADDIUSP
:
14504 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
14506 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
14509 case M16_OPC_ADDIUPC
:
14510 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
14513 offset
= (ctx
->opcode
& 0x7ff) << 1;
14514 offset
= (int16_t)(offset
<< 4) >> 4;
14515 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
14516 /* No delay slot, so just process as a normal instruction */
14519 offset
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
14520 offset
= (((ctx
->opcode
& 0x1f) << 21)
14521 | ((ctx
->opcode
>> 5) & 0x1f) << 16
14523 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
14524 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
14528 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
14529 ((int8_t)ctx
->opcode
) << 1, 0);
14530 /* No delay slot, so just process as a normal instruction */
14532 case M16_OPC_BNEQZ
:
14533 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
14534 ((int8_t)ctx
->opcode
) << 1, 0);
14535 /* No delay slot, so just process as a normal instruction */
14537 case M16_OPC_SHIFT
:
14538 switch (ctx
->opcode
& 0x3) {
14540 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
14543 #if defined(TARGET_MIPS64)
14544 check_insn(ctx
, ISA_MIPS3
);
14545 check_mips_64(ctx
);
14546 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
14548 gen_reserved_instruction(ctx
);
14552 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
14555 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
14559 #if defined(TARGET_MIPS64)
14561 check_insn(ctx
, ISA_MIPS3
);
14562 check_mips_64(ctx
);
14563 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
14568 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14570 if ((ctx
->opcode
>> 4) & 1) {
14571 #if defined(TARGET_MIPS64)
14572 check_insn(ctx
, ISA_MIPS3
);
14573 check_mips_64(ctx
);
14574 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14576 gen_reserved_instruction(ctx
);
14579 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14583 case M16_OPC_ADDIU8
:
14585 int16_t imm
= (int8_t) ctx
->opcode
;
14587 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14592 int16_t imm
= (uint8_t) ctx
->opcode
;
14593 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14596 case M16_OPC_SLTIU
:
14598 int16_t imm
= (uint8_t) ctx
->opcode
;
14599 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14606 funct
= (ctx
->opcode
>> 8) & 0x7;
14609 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14610 ((int8_t)ctx
->opcode
) << 1, 0);
14613 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14614 ((int8_t)ctx
->opcode
) << 1, 0);
14617 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14620 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14621 ((int8_t)ctx
->opcode
) << 3);
14624 check_insn(ctx
, ISA_MIPS_R1
);
14626 int do_ra
= ctx
->opcode
& (1 << 6);
14627 int do_s0
= ctx
->opcode
& (1 << 5);
14628 int do_s1
= ctx
->opcode
& (1 << 4);
14629 int framesize
= ctx
->opcode
& 0xf;
14631 if (framesize
== 0) {
14634 framesize
= framesize
<< 3;
14637 if (ctx
->opcode
& (1 << 7)) {
14638 gen_mips16_save(ctx
, 0, 0,
14639 do_ra
, do_s0
, do_s1
, framesize
);
14641 gen_mips16_restore(ctx
, 0, 0,
14642 do_ra
, do_s0
, do_s1
, framesize
);
14648 int rz
= xlat(ctx
->opcode
& 0x7);
14650 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14651 ((ctx
->opcode
>> 5) & 0x7);
14652 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14656 reg32
= ctx
->opcode
& 0x1f;
14657 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14660 gen_reserved_instruction(ctx
);
14667 int16_t imm
= (uint8_t) ctx
->opcode
;
14669 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14674 int16_t imm
= (uint8_t) ctx
->opcode
;
14675 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14678 #if defined(TARGET_MIPS64)
14680 check_insn(ctx
, ISA_MIPS3
);
14681 check_mips_64(ctx
);
14682 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14686 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14689 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14692 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14695 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14698 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14701 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14704 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14706 #if defined(TARGET_MIPS64)
14708 check_insn(ctx
, ISA_MIPS3
);
14709 check_mips_64(ctx
);
14710 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14714 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14717 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14720 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14723 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14727 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14730 switch (ctx
->opcode
& 0x3) {
14732 mips32_op
= OPC_ADDU
;
14735 mips32_op
= OPC_SUBU
;
14737 #if defined(TARGET_MIPS64)
14739 mips32_op
= OPC_DADDU
;
14740 check_insn(ctx
, ISA_MIPS3
);
14741 check_mips_64(ctx
);
14744 mips32_op
= OPC_DSUBU
;
14745 check_insn(ctx
, ISA_MIPS3
);
14746 check_mips_64(ctx
);
14750 gen_reserved_instruction(ctx
);
14754 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14763 int nd
= (ctx
->opcode
>> 7) & 0x1;
14764 int link
= (ctx
->opcode
>> 6) & 0x1;
14765 int ra
= (ctx
->opcode
>> 5) & 0x1;
14768 check_insn(ctx
, ISA_MIPS_R1
);
14777 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14782 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14783 gen_helper_do_semihosting(cpu_env
);
14786 * XXX: not clear which exception should be raised
14787 * when in debug mode...
14789 check_insn(ctx
, ISA_MIPS_R1
);
14790 generate_exception_end(ctx
, EXCP_DBp
);
14794 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14797 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14800 generate_exception_end(ctx
, EXCP_BREAK
);
14803 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14806 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14809 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14811 #if defined(TARGET_MIPS64)
14813 check_insn(ctx
, ISA_MIPS3
);
14814 check_mips_64(ctx
);
14815 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14819 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14822 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14825 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14828 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14831 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14834 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14837 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14840 check_insn(ctx
, ISA_MIPS_R1
);
14842 case RR_RY_CNVT_ZEB
:
14843 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14845 case RR_RY_CNVT_ZEH
:
14846 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14848 case RR_RY_CNVT_SEB
:
14849 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14851 case RR_RY_CNVT_SEH
:
14852 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14854 #if defined(TARGET_MIPS64)
14855 case RR_RY_CNVT_ZEW
:
14856 check_insn(ctx
, ISA_MIPS_R1
);
14857 check_mips_64(ctx
);
14858 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14860 case RR_RY_CNVT_SEW
:
14861 check_insn(ctx
, ISA_MIPS_R1
);
14862 check_mips_64(ctx
);
14863 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14867 gen_reserved_instruction(ctx
);
14872 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14874 #if defined(TARGET_MIPS64)
14876 check_insn(ctx
, ISA_MIPS3
);
14877 check_mips_64(ctx
);
14878 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14881 check_insn(ctx
, ISA_MIPS3
);
14882 check_mips_64(ctx
);
14883 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14886 check_insn(ctx
, ISA_MIPS3
);
14887 check_mips_64(ctx
);
14888 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14891 check_insn(ctx
, ISA_MIPS3
);
14892 check_mips_64(ctx
);
14893 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14897 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14900 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14903 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14906 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14908 #if defined(TARGET_MIPS64)
14910 check_insn(ctx
, ISA_MIPS3
);
14911 check_mips_64(ctx
);
14912 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14915 check_insn(ctx
, ISA_MIPS3
);
14916 check_mips_64(ctx
);
14917 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14920 check_insn(ctx
, ISA_MIPS3
);
14921 check_mips_64(ctx
);
14922 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14925 check_insn(ctx
, ISA_MIPS3
);
14926 check_mips_64(ctx
);
14927 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14931 gen_reserved_instruction(ctx
);
14935 case M16_OPC_EXTEND
:
14936 decode_extended_mips16_opc(env
, ctx
);
14939 #if defined(TARGET_MIPS64)
14941 funct
= (ctx
->opcode
>> 8) & 0x7;
14942 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
14946 gen_reserved_instruction(ctx
);
14953 /* microMIPS extension to MIPS32/MIPS64 */
14956 * microMIPS32/microMIPS64 major opcodes
14958 * 1. MIPS Architecture for Programmers Volume II-B:
14959 * The microMIPS32 Instruction Set (Revision 3.05)
14961 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14963 * 2. MIPS Architecture For Programmers Volume II-A:
14964 * The MIPS64 Instruction Set (Revision 3.51)
14994 POOL32S
= 0x16, /* MIPS64 */
14995 DADDIU32
= 0x17, /* MIPS64 */
15024 /* 0x29 is reserved */
15037 /* 0x31 is reserved */
15050 SD32
= 0x36, /* MIPS64 */
15051 LD32
= 0x37, /* MIPS64 */
15053 /* 0x39 is reserved */
15069 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
15091 /* POOL32A encoding of minor opcode field */
15095 * These opcodes are distinguished only by bits 9..6; those bits are
15096 * what are recorded below.
15134 /* The following can be distinguished by their lower 6 bits. */
15144 /* POOL32AXF encoding of minor opcode field extension */
15147 * 1. MIPS Architecture for Programmers Volume II-B:
15148 * The microMIPS32 Instruction Set (Revision 3.05)
15150 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
15152 * 2. MIPS Architecture for Programmers VolumeIV-e:
15153 * The MIPS DSP Application-Specific Extension
15154 * to the microMIPS32 Architecture (Revision 2.34)
15156 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
15171 /* begin of microMIPS32 DSP */
15173 /* bits 13..12 for 0x01 */
15179 /* bits 13..12 for 0x2a */
15185 /* bits 13..12 for 0x32 */
15189 /* end of microMIPS32 DSP */
15191 /* bits 15..12 for 0x2c */
15208 /* bits 15..12 for 0x34 */
15216 /* bits 15..12 for 0x3c */
15218 JR
= 0x0, /* alias */
15226 /* bits 15..12 for 0x05 */
15230 /* bits 15..12 for 0x0d */
15242 /* bits 15..12 for 0x15 */
15248 /* bits 15..12 for 0x1d */
15252 /* bits 15..12 for 0x2d */
15257 /* bits 15..12 for 0x35 */
15264 /* POOL32B encoding of minor opcode field (bits 15..12) */
15280 /* POOL32C encoding of minor opcode field (bits 15..12) */
15301 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
15314 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
15327 /* POOL32F encoding of minor opcode field (bits 5..0) */
15330 /* These are the bit 7..6 values */
15339 /* These are the bit 8..6 values */
15364 MOVZ_FMT_05
= 0x05,
15398 CABS_COND_FMT
= 0x1c, /* MIPS3D */
15405 /* POOL32Fxf encoding of minor opcode extension field */
15443 /* POOL32I encoding of minor opcode field (bits 25..21) */
15473 /* These overlap and are distinguished by bit16 of the instruction */
15482 /* POOL16A encoding of minor opcode field */
15489 /* POOL16B encoding of minor opcode field */
15496 /* POOL16C encoding of minor opcode field */
15516 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
15540 /* POOL16D encoding of minor opcode field */
15547 /* POOL16E encoding of minor opcode field */
15554 static int mmreg(int r
)
15556 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
15561 /* Used for 16-bit store instructions. */
15562 static int mmreg2(int r
)
15564 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
15569 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15570 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15571 #define uMIPS_RS2(op) uMIPS_RS(op)
15572 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15573 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15574 #define uMIPS_RS5(op) (op & 0x1f)
15576 /* Signed immediate */
15577 #define SIMM(op, start, width) \
15578 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15581 /* Zero-extended immediate */
15582 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15584 static void gen_addiur1sp(DisasContext
*ctx
)
15586 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15588 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15591 static void gen_addiur2(DisasContext
*ctx
)
15593 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15594 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15595 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15597 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15600 static void gen_addiusp(DisasContext
*ctx
)
15602 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15605 if (encoded
<= 1) {
15606 decoded
= 256 + encoded
;
15607 } else if (encoded
<= 255) {
15609 } else if (encoded
<= 509) {
15610 decoded
= encoded
- 512;
15612 decoded
= encoded
- 768;
15615 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15618 static void gen_addius5(DisasContext
*ctx
)
15620 int imm
= SIMM(ctx
->opcode
, 1, 4);
15621 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15623 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15626 static void gen_andi16(DisasContext
*ctx
)
15628 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15629 31, 32, 63, 64, 255, 32768, 65535 };
15630 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15631 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15632 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15634 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15637 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15638 int base
, int16_t offset
)
15643 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15644 gen_reserved_instruction(ctx
);
15648 t0
= tcg_temp_new();
15650 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15652 t1
= tcg_const_tl(reglist
);
15653 t2
= tcg_const_i32(ctx
->mem_idx
);
15655 save_cpu_state(ctx
, 1);
15658 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15661 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15663 #ifdef TARGET_MIPS64
15665 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15668 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15674 tcg_temp_free_i32(t2
);
15678 static void gen_pool16c_insn(DisasContext
*ctx
)
15680 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15681 int rs
= mmreg(ctx
->opcode
& 0x7);
15683 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15688 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15694 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15700 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15706 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15713 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15714 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15716 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15725 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15726 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15728 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15735 int reg
= ctx
->opcode
& 0x1f;
15737 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15743 int reg
= ctx
->opcode
& 0x1f;
15744 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15746 * Let normal delay slot handling in our caller take us
15747 * to the branch target.
15753 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15754 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15758 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15759 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15763 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15767 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15770 generate_exception_end(ctx
, EXCP_BREAK
);
15773 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15774 gen_helper_do_semihosting(cpu_env
);
15777 * XXX: not clear which exception should be raised
15778 * when in debug mode...
15780 check_insn(ctx
, ISA_MIPS_R1
);
15781 generate_exception_end(ctx
, EXCP_DBp
);
15784 case JRADDIUSP
+ 0:
15785 case JRADDIUSP
+ 1:
15787 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15788 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15789 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15791 * Let normal delay slot handling in our caller take us
15792 * to the branch target.
15797 gen_reserved_instruction(ctx
);
15802 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15805 int rd
, rs
, re
, rt
;
15806 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15807 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15808 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15809 rd
= rd_enc
[enc_dest
];
15810 re
= re_enc
[enc_dest
];
15811 rs
= rs_rt_enc
[enc_rs
];
15812 rt
= rs_rt_enc
[enc_rt
];
15814 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15816 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15819 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15821 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15825 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15827 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15828 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15830 switch (ctx
->opcode
& 0xf) {
15832 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15835 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15839 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15840 int offset
= extract32(ctx
->opcode
, 4, 4);
15841 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15844 case R6_JRC16
: /* JRCADDIUSP */
15845 if ((ctx
->opcode
>> 4) & 1) {
15847 int imm
= extract32(ctx
->opcode
, 5, 5);
15848 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15849 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15852 rs
= extract32(ctx
->opcode
, 5, 5);
15853 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15865 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15866 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15867 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15868 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15872 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15875 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15879 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15880 int offset
= extract32(ctx
->opcode
, 4, 4);
15881 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15884 case JALRC16
: /* BREAK16, SDBBP16 */
15885 switch (ctx
->opcode
& 0x3f) {
15887 case JALRC16
+ 0x20:
15889 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15894 generate_exception(ctx
, EXCP_BREAK
);
15898 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15899 gen_helper_do_semihosting(cpu_env
);
15901 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15902 generate_exception(ctx
, EXCP_RI
);
15904 generate_exception(ctx
, EXCP_DBp
);
15911 generate_exception(ctx
, EXCP_RI
);
15916 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15918 TCGv t0
= tcg_temp_new();
15919 TCGv t1
= tcg_temp_new();
15921 gen_load_gpr(t0
, base
);
15924 gen_load_gpr(t1
, index
);
15925 tcg_gen_shli_tl(t1
, t1
, 2);
15926 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15929 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15930 gen_store_gpr(t1
, rd
);
15936 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15937 int base
, int16_t offset
)
15941 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15942 gen_reserved_instruction(ctx
);
15946 t0
= tcg_temp_new();
15947 t1
= tcg_temp_new();
15949 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15954 gen_reserved_instruction(ctx
);
15957 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15958 gen_store_gpr(t1
, rd
);
15959 tcg_gen_movi_tl(t1
, 4);
15960 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15961 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15962 gen_store_gpr(t1
, rd
+ 1);
15965 gen_load_gpr(t1
, rd
);
15966 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15967 tcg_gen_movi_tl(t1
, 4);
15968 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15969 gen_load_gpr(t1
, rd
+ 1);
15970 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15972 #ifdef TARGET_MIPS64
15975 gen_reserved_instruction(ctx
);
15978 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15979 gen_store_gpr(t1
, rd
);
15980 tcg_gen_movi_tl(t1
, 8);
15981 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15982 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15983 gen_store_gpr(t1
, rd
+ 1);
15986 gen_load_gpr(t1
, rd
);
15987 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15988 tcg_gen_movi_tl(t1
, 8);
15989 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15990 gen_load_gpr(t1
, rd
+ 1);
15991 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15999 static void gen_sync(int stype
)
16001 TCGBar tcg_mo
= TCG_BAR_SC
;
16004 case 0x4: /* SYNC_WMB */
16005 tcg_mo
|= TCG_MO_ST_ST
;
16007 case 0x10: /* SYNC_MB */
16008 tcg_mo
|= TCG_MO_ALL
;
16010 case 0x11: /* SYNC_ACQUIRE */
16011 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
16013 case 0x12: /* SYNC_RELEASE */
16014 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
16016 case 0x13: /* SYNC_RMB */
16017 tcg_mo
|= TCG_MO_LD_LD
;
16020 tcg_mo
|= TCG_MO_ALL
;
16024 tcg_gen_mb(tcg_mo
);
16027 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
16029 int extension
= (ctx
->opcode
>> 6) & 0x3f;
16030 int minor
= (ctx
->opcode
>> 12) & 0xf;
16031 uint32_t mips32_op
;
16033 switch (extension
) {
16035 mips32_op
= OPC_TEQ
;
16038 mips32_op
= OPC_TGE
;
16041 mips32_op
= OPC_TGEU
;
16044 mips32_op
= OPC_TLT
;
16047 mips32_op
= OPC_TLTU
;
16050 mips32_op
= OPC_TNE
;
16052 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
16054 #ifndef CONFIG_USER_ONLY
16057 check_cp0_enabled(ctx
);
16059 /* Treat as NOP. */
16062 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
16066 check_cp0_enabled(ctx
);
16068 TCGv t0
= tcg_temp_new();
16070 gen_load_gpr(t0
, rt
);
16071 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
16077 switch (minor
& 3) {
16079 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16082 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16085 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16088 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16091 goto pool32axf_invalid
;
16095 switch (minor
& 3) {
16097 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16100 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
16103 goto pool32axf_invalid
;
16109 check_insn(ctx
, ISA_MIPS_R6
);
16110 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
16113 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
16116 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
16119 mips32_op
= OPC_CLO
;
16122 mips32_op
= OPC_CLZ
;
16124 check_insn(ctx
, ISA_MIPS_R1
);
16125 gen_cl(ctx
, mips32_op
, rt
, rs
);
16128 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16129 gen_rdhwr(ctx
, rt
, rs
, 0);
16132 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
16135 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16136 mips32_op
= OPC_MULT
;
16139 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16140 mips32_op
= OPC_MULTU
;
16143 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16144 mips32_op
= OPC_DIV
;
16147 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16148 mips32_op
= OPC_DIVU
;
16151 check_insn(ctx
, ISA_MIPS_R1
);
16152 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
16155 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16156 mips32_op
= OPC_MADD
;
16159 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16160 mips32_op
= OPC_MADDU
;
16163 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16164 mips32_op
= OPC_MSUB
;
16167 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16168 mips32_op
= OPC_MSUBU
;
16170 check_insn(ctx
, ISA_MIPS_R1
);
16171 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
16174 goto pool32axf_invalid
;
16185 generate_exception_err(ctx
, EXCP_CpU
, 2);
16188 goto pool32axf_invalid
;
16193 case JALR
: /* JALRC */
16194 case JALR_HB
: /* JALRC_HB */
16195 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16196 /* JALRC, JALRC_HB */
16197 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
16199 /* JALR, JALR_HB */
16200 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
16201 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16206 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16207 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
16208 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16211 goto pool32axf_invalid
;
16217 check_cp0_enabled(ctx
);
16218 check_insn(ctx
, ISA_MIPS_R2
);
16219 gen_load_srsgpr(rs
, rt
);
16222 check_cp0_enabled(ctx
);
16223 check_insn(ctx
, ISA_MIPS_R2
);
16224 gen_store_srsgpr(rs
, rt
);
16227 goto pool32axf_invalid
;
16230 #ifndef CONFIG_USER_ONLY
16234 mips32_op
= OPC_TLBP
;
16237 mips32_op
= OPC_TLBR
;
16240 mips32_op
= OPC_TLBWI
;
16243 mips32_op
= OPC_TLBWR
;
16246 mips32_op
= OPC_TLBINV
;
16249 mips32_op
= OPC_TLBINVF
;
16252 mips32_op
= OPC_WAIT
;
16255 mips32_op
= OPC_DERET
;
16258 mips32_op
= OPC_ERET
;
16260 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
16263 goto pool32axf_invalid
;
16269 check_cp0_enabled(ctx
);
16271 TCGv t0
= tcg_temp_new();
16273 save_cpu_state(ctx
, 1);
16274 gen_helper_di(t0
, cpu_env
);
16275 gen_store_gpr(t0
, rs
);
16277 * Stop translation as we may have switched the execution
16280 ctx
->base
.is_jmp
= DISAS_STOP
;
16285 check_cp0_enabled(ctx
);
16287 TCGv t0
= tcg_temp_new();
16289 save_cpu_state(ctx
, 1);
16290 gen_helper_ei(t0
, cpu_env
);
16291 gen_store_gpr(t0
, rs
);
16293 * DISAS_STOP isn't sufficient, we need to ensure we break out
16294 * of translated code to check for pending interrupts.
16296 gen_save_pc(ctx
->base
.pc_next
+ 4);
16297 ctx
->base
.is_jmp
= DISAS_EXIT
;
16302 goto pool32axf_invalid
;
16309 gen_sync(extract32(ctx
->opcode
, 16, 5));
16312 generate_exception_end(ctx
, EXCP_SYSCALL
);
16315 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
16316 gen_helper_do_semihosting(cpu_env
);
16318 check_insn(ctx
, ISA_MIPS_R1
);
16319 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
16320 gen_reserved_instruction(ctx
);
16322 generate_exception_end(ctx
, EXCP_DBp
);
16327 goto pool32axf_invalid
;
16331 switch (minor
& 3) {
16333 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
16336 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
16339 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
16342 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
16345 goto pool32axf_invalid
;
16349 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16352 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
16355 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
16358 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
16361 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
16364 goto pool32axf_invalid
;
16369 MIPS_INVAL("pool32axf");
16370 gen_reserved_instruction(ctx
);
16376 * Values for microMIPS fmt field. Variable-width, depending on which
16377 * formats the instruction supports.
16396 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
16398 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
16399 uint32_t mips32_op
;
16401 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
16402 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
16403 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
16405 switch (extension
) {
16406 case FLOAT_1BIT_FMT(CFC1
, 0):
16407 mips32_op
= OPC_CFC1
;
16409 case FLOAT_1BIT_FMT(CTC1
, 0):
16410 mips32_op
= OPC_CTC1
;
16412 case FLOAT_1BIT_FMT(MFC1
, 0):
16413 mips32_op
= OPC_MFC1
;
16415 case FLOAT_1BIT_FMT(MTC1
, 0):
16416 mips32_op
= OPC_MTC1
;
16418 case FLOAT_1BIT_FMT(MFHC1
, 0):
16419 mips32_op
= OPC_MFHC1
;
16421 case FLOAT_1BIT_FMT(MTHC1
, 0):
16422 mips32_op
= OPC_MTHC1
;
16424 gen_cp1(ctx
, mips32_op
, rt
, rs
);
16427 /* Reciprocal square root */
16428 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
16429 mips32_op
= OPC_RSQRT_S
;
16431 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
16432 mips32_op
= OPC_RSQRT_D
;
16436 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
16437 mips32_op
= OPC_SQRT_S
;
16439 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
16440 mips32_op
= OPC_SQRT_D
;
16444 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
16445 mips32_op
= OPC_RECIP_S
;
16447 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
16448 mips32_op
= OPC_RECIP_D
;
16452 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
16453 mips32_op
= OPC_FLOOR_L_S
;
16455 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
16456 mips32_op
= OPC_FLOOR_L_D
;
16458 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
16459 mips32_op
= OPC_FLOOR_W_S
;
16461 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
16462 mips32_op
= OPC_FLOOR_W_D
;
16466 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
16467 mips32_op
= OPC_CEIL_L_S
;
16469 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
16470 mips32_op
= OPC_CEIL_L_D
;
16472 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
16473 mips32_op
= OPC_CEIL_W_S
;
16475 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
16476 mips32_op
= OPC_CEIL_W_D
;
16480 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
16481 mips32_op
= OPC_TRUNC_L_S
;
16483 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
16484 mips32_op
= OPC_TRUNC_L_D
;
16486 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
16487 mips32_op
= OPC_TRUNC_W_S
;
16489 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
16490 mips32_op
= OPC_TRUNC_W_D
;
16494 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
16495 mips32_op
= OPC_ROUND_L_S
;
16497 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
16498 mips32_op
= OPC_ROUND_L_D
;
16500 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
16501 mips32_op
= OPC_ROUND_W_S
;
16503 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
16504 mips32_op
= OPC_ROUND_W_D
;
16507 /* Integer to floating-point conversion */
16508 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
16509 mips32_op
= OPC_CVT_L_S
;
16511 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
16512 mips32_op
= OPC_CVT_L_D
;
16514 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
16515 mips32_op
= OPC_CVT_W_S
;
16517 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
16518 mips32_op
= OPC_CVT_W_D
;
16521 /* Paired-foo conversions */
16522 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
16523 mips32_op
= OPC_CVT_S_PL
;
16525 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
16526 mips32_op
= OPC_CVT_S_PU
;
16528 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
16529 mips32_op
= OPC_CVT_PW_PS
;
16531 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
16532 mips32_op
= OPC_CVT_PS_PW
;
16535 /* Floating-point moves */
16536 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
16537 mips32_op
= OPC_MOV_S
;
16539 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
16540 mips32_op
= OPC_MOV_D
;
16542 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
16543 mips32_op
= OPC_MOV_PS
;
16546 /* Absolute value */
16547 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
16548 mips32_op
= OPC_ABS_S
;
16550 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
16551 mips32_op
= OPC_ABS_D
;
16553 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
16554 mips32_op
= OPC_ABS_PS
;
16558 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
16559 mips32_op
= OPC_NEG_S
;
16561 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
16562 mips32_op
= OPC_NEG_D
;
16564 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
16565 mips32_op
= OPC_NEG_PS
;
16568 /* Reciprocal square root step */
16569 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16570 mips32_op
= OPC_RSQRT1_S
;
16572 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16573 mips32_op
= OPC_RSQRT1_D
;
16575 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16576 mips32_op
= OPC_RSQRT1_PS
;
16579 /* Reciprocal step */
16580 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16581 mips32_op
= OPC_RECIP1_S
;
16583 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16584 mips32_op
= OPC_RECIP1_S
;
16586 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16587 mips32_op
= OPC_RECIP1_PS
;
16590 /* Conversions from double */
16591 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16592 mips32_op
= OPC_CVT_D_S
;
16594 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16595 mips32_op
= OPC_CVT_D_W
;
16597 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16598 mips32_op
= OPC_CVT_D_L
;
16601 /* Conversions from single */
16602 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16603 mips32_op
= OPC_CVT_S_D
;
16605 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16606 mips32_op
= OPC_CVT_S_W
;
16608 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16609 mips32_op
= OPC_CVT_S_L
;
16611 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16614 /* Conditional moves on floating-point codes */
16615 case COND_FLOAT_MOV(MOVT
, 0):
16616 case COND_FLOAT_MOV(MOVT
, 1):
16617 case COND_FLOAT_MOV(MOVT
, 2):
16618 case COND_FLOAT_MOV(MOVT
, 3):
16619 case COND_FLOAT_MOV(MOVT
, 4):
16620 case COND_FLOAT_MOV(MOVT
, 5):
16621 case COND_FLOAT_MOV(MOVT
, 6):
16622 case COND_FLOAT_MOV(MOVT
, 7):
16623 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16624 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16626 case COND_FLOAT_MOV(MOVF
, 0):
16627 case COND_FLOAT_MOV(MOVF
, 1):
16628 case COND_FLOAT_MOV(MOVF
, 2):
16629 case COND_FLOAT_MOV(MOVF
, 3):
16630 case COND_FLOAT_MOV(MOVF
, 4):
16631 case COND_FLOAT_MOV(MOVF
, 5):
16632 case COND_FLOAT_MOV(MOVF
, 6):
16633 case COND_FLOAT_MOV(MOVF
, 7):
16634 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16635 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16638 MIPS_INVAL("pool32fxf");
16639 gen_reserved_instruction(ctx
);
16644 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16648 int rt
, rs
, rd
, rr
;
16650 uint32_t op
, minor
, minor2
, mips32_op
;
16651 uint32_t cond
, fmt
, cc
;
16653 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
16654 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16656 rt
= (ctx
->opcode
>> 21) & 0x1f;
16657 rs
= (ctx
->opcode
>> 16) & 0x1f;
16658 rd
= (ctx
->opcode
>> 11) & 0x1f;
16659 rr
= (ctx
->opcode
>> 6) & 0x1f;
16660 imm
= (int16_t) ctx
->opcode
;
16662 op
= (ctx
->opcode
>> 26) & 0x3f;
16665 minor
= ctx
->opcode
& 0x3f;
16668 minor
= (ctx
->opcode
>> 6) & 0xf;
16671 mips32_op
= OPC_SLL
;
16674 mips32_op
= OPC_SRA
;
16677 mips32_op
= OPC_SRL
;
16680 mips32_op
= OPC_ROTR
;
16682 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16685 check_insn(ctx
, ISA_MIPS_R6
);
16686 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16689 check_insn(ctx
, ISA_MIPS_R6
);
16690 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16693 check_insn(ctx
, ISA_MIPS_R6
);
16694 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16697 goto pool32a_invalid
;
16701 minor
= (ctx
->opcode
>> 6) & 0xf;
16705 mips32_op
= OPC_ADD
;
16708 mips32_op
= OPC_ADDU
;
16711 mips32_op
= OPC_SUB
;
16714 mips32_op
= OPC_SUBU
;
16717 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16718 mips32_op
= OPC_MUL
;
16720 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16724 mips32_op
= OPC_SLLV
;
16727 mips32_op
= OPC_SRLV
;
16730 mips32_op
= OPC_SRAV
;
16733 mips32_op
= OPC_ROTRV
;
16735 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16737 /* Logical operations */
16739 mips32_op
= OPC_AND
;
16742 mips32_op
= OPC_OR
;
16745 mips32_op
= OPC_NOR
;
16748 mips32_op
= OPC_XOR
;
16750 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16752 /* Set less than */
16754 mips32_op
= OPC_SLT
;
16757 mips32_op
= OPC_SLTU
;
16759 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16762 goto pool32a_invalid
;
16766 minor
= (ctx
->opcode
>> 6) & 0xf;
16768 /* Conditional moves */
16769 case MOVN
: /* MUL */
16770 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16772 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16775 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16778 case MOVZ
: /* MUH */
16779 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16781 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16784 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16788 check_insn(ctx
, ISA_MIPS_R6
);
16789 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16792 check_insn(ctx
, ISA_MIPS_R6
);
16793 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16795 case LWXS
: /* DIV */
16796 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
16798 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16801 gen_ldxs(ctx
, rs
, rt
, rd
);
16805 check_insn(ctx
, ISA_MIPS_R6
);
16806 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16809 check_insn(ctx
, ISA_MIPS_R6
);
16810 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16813 check_insn(ctx
, ISA_MIPS_R6
);
16814 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16817 goto pool32a_invalid
;
16821 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16824 check_insn(ctx
, ISA_MIPS_R6
);
16825 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
16826 extract32(ctx
->opcode
, 9, 2));
16829 check_insn(ctx
, ISA_MIPS_R6
);
16830 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16833 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16836 gen_pool32axf(env
, ctx
, rt
, rs
);
16839 generate_exception_end(ctx
, EXCP_BREAK
);
16842 check_insn(ctx
, ISA_MIPS_R6
);
16843 gen_reserved_instruction(ctx
);
16847 MIPS_INVAL("pool32a");
16848 gen_reserved_instruction(ctx
);
16853 minor
= (ctx
->opcode
>> 12) & 0xf;
16856 check_cp0_enabled(ctx
);
16857 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16858 gen_cache_operation(ctx
, rt
, rs
, imm
);
16863 /* COP2: Not implemented. */
16864 generate_exception_err(ctx
, EXCP_CpU
, 2);
16866 #ifdef TARGET_MIPS64
16869 check_insn(ctx
, ISA_MIPS3
);
16870 check_mips_64(ctx
);
16875 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16877 #ifdef TARGET_MIPS64
16880 check_insn(ctx
, ISA_MIPS3
);
16881 check_mips_64(ctx
);
16886 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16889 MIPS_INVAL("pool32b");
16890 gen_reserved_instruction(ctx
);
16895 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16896 minor
= ctx
->opcode
& 0x3f;
16897 check_cp1_enabled(ctx
);
16900 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16901 mips32_op
= OPC_ALNV_PS
;
16904 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16905 mips32_op
= OPC_MADD_S
;
16908 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16909 mips32_op
= OPC_MADD_D
;
16912 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16913 mips32_op
= OPC_MADD_PS
;
16916 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16917 mips32_op
= OPC_MSUB_S
;
16920 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16921 mips32_op
= OPC_MSUB_D
;
16924 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16925 mips32_op
= OPC_MSUB_PS
;
16928 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16929 mips32_op
= OPC_NMADD_S
;
16932 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16933 mips32_op
= OPC_NMADD_D
;
16936 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16937 mips32_op
= OPC_NMADD_PS
;
16940 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16941 mips32_op
= OPC_NMSUB_S
;
16944 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16945 mips32_op
= OPC_NMSUB_D
;
16948 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16949 mips32_op
= OPC_NMSUB_PS
;
16951 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
16953 case CABS_COND_FMT
:
16954 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16955 cond
= (ctx
->opcode
>> 6) & 0xf;
16956 cc
= (ctx
->opcode
>> 13) & 0x7;
16957 fmt
= (ctx
->opcode
>> 10) & 0x3;
16960 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
16963 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
16966 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
16969 goto pool32f_invalid
;
16973 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
16974 cond
= (ctx
->opcode
>> 6) & 0xf;
16975 cc
= (ctx
->opcode
>> 13) & 0x7;
16976 fmt
= (ctx
->opcode
>> 10) & 0x3;
16979 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
16982 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
16985 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
16988 goto pool32f_invalid
;
16992 check_insn(ctx
, ISA_MIPS_R6
);
16993 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16996 check_insn(ctx
, ISA_MIPS_R6
);
16997 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
17000 gen_pool32fxf(ctx
, rt
, rs
);
17004 switch ((ctx
->opcode
>> 6) & 0x7) {
17006 mips32_op
= OPC_PLL_PS
;
17009 mips32_op
= OPC_PLU_PS
;
17012 mips32_op
= OPC_PUL_PS
;
17015 mips32_op
= OPC_PUU_PS
;
17018 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17019 mips32_op
= OPC_CVT_PS_S
;
17021 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17024 goto pool32f_invalid
;
17028 check_insn(ctx
, ISA_MIPS_R6
);
17029 switch ((ctx
->opcode
>> 9) & 0x3) {
17031 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
17034 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
17037 goto pool32f_invalid
;
17042 switch ((ctx
->opcode
>> 6) & 0x7) {
17044 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17045 mips32_op
= OPC_LWXC1
;
17048 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17049 mips32_op
= OPC_SWXC1
;
17052 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17053 mips32_op
= OPC_LDXC1
;
17056 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17057 mips32_op
= OPC_SDXC1
;
17060 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17061 mips32_op
= OPC_LUXC1
;
17064 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17065 mips32_op
= OPC_SUXC1
;
17067 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
17070 goto pool32f_invalid
;
17074 check_insn(ctx
, ISA_MIPS_R6
);
17075 switch ((ctx
->opcode
>> 9) & 0x3) {
17077 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
17080 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
17083 goto pool32f_invalid
;
17088 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17089 fmt
= (ctx
->opcode
>> 9) & 0x3;
17090 switch ((ctx
->opcode
>> 6) & 0x7) {
17094 mips32_op
= OPC_RSQRT2_S
;
17097 mips32_op
= OPC_RSQRT2_D
;
17100 mips32_op
= OPC_RSQRT2_PS
;
17103 goto pool32f_invalid
;
17109 mips32_op
= OPC_RECIP2_S
;
17112 mips32_op
= OPC_RECIP2_D
;
17115 mips32_op
= OPC_RECIP2_PS
;
17118 goto pool32f_invalid
;
17122 mips32_op
= OPC_ADDR_PS
;
17125 mips32_op
= OPC_MULR_PS
;
17127 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17130 goto pool32f_invalid
;
17134 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
17135 cc
= (ctx
->opcode
>> 13) & 0x7;
17136 fmt
= (ctx
->opcode
>> 9) & 0x3;
17137 switch ((ctx
->opcode
>> 6) & 0x7) {
17138 case MOVF_FMT
: /* RINT_FMT */
17139 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17143 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
17146 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
17149 goto pool32f_invalid
;
17155 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
17158 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
17162 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
17165 goto pool32f_invalid
;
17169 case MOVT_FMT
: /* CLASS_FMT */
17170 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17174 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
17177 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
17180 goto pool32f_invalid
;
17186 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
17189 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
17193 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
17196 goto pool32f_invalid
;
17201 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17204 goto pool32f_invalid
;
17207 #define FINSN_3ARG_SDPS(prfx) \
17208 switch ((ctx->opcode >> 8) & 0x3) { \
17210 mips32_op = OPC_##prfx##_S; \
17213 mips32_op = OPC_##prfx##_D; \
17215 case FMT_SDPS_PS: \
17217 mips32_op = OPC_##prfx##_PS; \
17220 goto pool32f_invalid; \
17223 check_insn(ctx
, ISA_MIPS_R6
);
17224 switch ((ctx
->opcode
>> 9) & 0x3) {
17226 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
17229 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
17232 goto pool32f_invalid
;
17236 check_insn(ctx
, ISA_MIPS_R6
);
17237 switch ((ctx
->opcode
>> 9) & 0x3) {
17239 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
17242 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
17245 goto pool32f_invalid
;
17249 /* regular FP ops */
17250 switch ((ctx
->opcode
>> 6) & 0x3) {
17252 FINSN_3ARG_SDPS(ADD
);
17255 FINSN_3ARG_SDPS(SUB
);
17258 FINSN_3ARG_SDPS(MUL
);
17261 fmt
= (ctx
->opcode
>> 8) & 0x3;
17263 mips32_op
= OPC_DIV_D
;
17264 } else if (fmt
== 0) {
17265 mips32_op
= OPC_DIV_S
;
17267 goto pool32f_invalid
;
17271 goto pool32f_invalid
;
17276 switch ((ctx
->opcode
>> 6) & 0x7) {
17277 case MOVN_FMT
: /* SELEQZ_FMT */
17278 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17280 switch ((ctx
->opcode
>> 9) & 0x3) {
17282 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
17285 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
17288 goto pool32f_invalid
;
17292 FINSN_3ARG_SDPS(MOVN
);
17296 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17297 FINSN_3ARG_SDPS(MOVN
);
17299 case MOVZ_FMT
: /* SELNEZ_FMT */
17300 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17302 switch ((ctx
->opcode
>> 9) & 0x3) {
17304 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
17307 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
17310 goto pool32f_invalid
;
17314 FINSN_3ARG_SDPS(MOVZ
);
17318 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17319 FINSN_3ARG_SDPS(MOVZ
);
17322 check_insn(ctx
, ISA_MIPS_R6
);
17323 switch ((ctx
->opcode
>> 9) & 0x3) {
17325 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
17328 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
17331 goto pool32f_invalid
;
17335 check_insn(ctx
, ISA_MIPS_R6
);
17336 switch ((ctx
->opcode
>> 9) & 0x3) {
17338 mips32_op
= OPC_MADDF_S
;
17341 mips32_op
= OPC_MADDF_D
;
17344 goto pool32f_invalid
;
17348 check_insn(ctx
, ISA_MIPS_R6
);
17349 switch ((ctx
->opcode
>> 9) & 0x3) {
17351 mips32_op
= OPC_MSUBF_S
;
17354 mips32_op
= OPC_MSUBF_D
;
17357 goto pool32f_invalid
;
17361 goto pool32f_invalid
;
17365 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
17369 MIPS_INVAL("pool32f");
17370 gen_reserved_instruction(ctx
);
17374 generate_exception_err(ctx
, EXCP_CpU
, 1);
17378 minor
= (ctx
->opcode
>> 21) & 0x1f;
17381 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17382 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
17385 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17386 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
17387 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17390 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17391 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
17392 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17395 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17396 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
17399 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17400 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
17401 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17404 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17405 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
17406 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17409 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17410 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
17413 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17414 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
17418 case TLTI
: /* BC1EQZC */
17419 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17421 check_cp1_enabled(ctx
);
17422 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
17425 mips32_op
= OPC_TLTI
;
17429 case TGEI
: /* BC1NEZC */
17430 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17432 check_cp1_enabled(ctx
);
17433 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
17436 mips32_op
= OPC_TGEI
;
17441 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17442 mips32_op
= OPC_TLTIU
;
17445 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17446 mips32_op
= OPC_TGEIU
;
17448 case TNEI
: /* SYNCI */
17449 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17452 * Break the TB to be able to sync copied instructions
17455 ctx
->base
.is_jmp
= DISAS_STOP
;
17458 mips32_op
= OPC_TNEI
;
17463 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17464 mips32_op
= OPC_TEQI
;
17466 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
17471 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17472 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
17473 4, rs
, 0, imm
<< 1, 0);
17475 * Compact branches don't have a delay slot, so just let
17476 * the normal delay slot handling take us to the branch
17481 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17482 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
17485 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17487 * Break the TB to be able to sync copied instructions
17490 ctx
->base
.is_jmp
= DISAS_STOP
;
17494 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17495 /* COP2: Not implemented. */
17496 generate_exception_err(ctx
, EXCP_CpU
, 2);
17499 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17500 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
17503 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17504 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
17507 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17508 mips32_op
= OPC_BC1FANY4
;
17511 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17512 mips32_op
= OPC_BC1TANY4
;
17515 check_insn(ctx
, ASE_MIPS3D
);
17518 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17519 check_cp1_enabled(ctx
);
17520 gen_compute_branch1(ctx
, mips32_op
,
17521 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
17523 generate_exception_err(ctx
, EXCP_CpU
, 1);
17528 /* MIPS DSP: not implemented */
17531 MIPS_INVAL("pool32i");
17532 gen_reserved_instruction(ctx
);
17537 minor
= (ctx
->opcode
>> 12) & 0xf;
17538 offset
= sextract32(ctx
->opcode
, 0,
17539 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 9 : 12);
17542 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17543 mips32_op
= OPC_LWL
;
17546 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17547 mips32_op
= OPC_SWL
;
17550 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17551 mips32_op
= OPC_LWR
;
17554 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17555 mips32_op
= OPC_SWR
;
17557 #if defined(TARGET_MIPS64)
17559 check_insn(ctx
, ISA_MIPS3
);
17560 check_mips_64(ctx
);
17561 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17562 mips32_op
= OPC_LDL
;
17565 check_insn(ctx
, ISA_MIPS3
);
17566 check_mips_64(ctx
);
17567 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17568 mips32_op
= OPC_SDL
;
17571 check_insn(ctx
, ISA_MIPS3
);
17572 check_mips_64(ctx
);
17573 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17574 mips32_op
= OPC_LDR
;
17577 check_insn(ctx
, ISA_MIPS3
);
17578 check_mips_64(ctx
);
17579 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17580 mips32_op
= OPC_SDR
;
17583 check_insn(ctx
, ISA_MIPS3
);
17584 check_mips_64(ctx
);
17585 mips32_op
= OPC_LWU
;
17588 check_insn(ctx
, ISA_MIPS3
);
17589 check_mips_64(ctx
);
17590 mips32_op
= OPC_LLD
;
17594 mips32_op
= OPC_LL
;
17597 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17600 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17603 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17605 #if defined(TARGET_MIPS64)
17607 check_insn(ctx
, ISA_MIPS3
);
17608 check_mips_64(ctx
);
17609 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17614 MIPS_INVAL("pool32c ld-eva");
17615 gen_reserved_instruction(ctx
);
17618 check_cp0_enabled(ctx
);
17620 minor2
= (ctx
->opcode
>> 9) & 0x7;
17621 offset
= sextract32(ctx
->opcode
, 0, 9);
17624 mips32_op
= OPC_LBUE
;
17627 mips32_op
= OPC_LHUE
;
17630 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17631 mips32_op
= OPC_LWLE
;
17634 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17635 mips32_op
= OPC_LWRE
;
17638 mips32_op
= OPC_LBE
;
17641 mips32_op
= OPC_LHE
;
17644 mips32_op
= OPC_LLE
;
17647 mips32_op
= OPC_LWE
;
17653 MIPS_INVAL("pool32c st-eva");
17654 gen_reserved_instruction(ctx
);
17657 check_cp0_enabled(ctx
);
17659 minor2
= (ctx
->opcode
>> 9) & 0x7;
17660 offset
= sextract32(ctx
->opcode
, 0, 9);
17663 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17664 mips32_op
= OPC_SWLE
;
17667 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17668 mips32_op
= OPC_SWRE
;
17671 /* Treat as no-op */
17672 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17673 /* hint codes 24-31 are reserved and signal RI */
17674 generate_exception(ctx
, EXCP_RI
);
17678 /* Treat as no-op */
17679 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17680 gen_cache_operation(ctx
, rt
, rs
, offset
);
17684 mips32_op
= OPC_SBE
;
17687 mips32_op
= OPC_SHE
;
17690 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17693 mips32_op
= OPC_SWE
;
17698 /* Treat as no-op */
17699 if ((ctx
->insn_flags
& ISA_MIPS_R6
) && (rt
>= 24)) {
17700 /* hint codes 24-31 are reserved and signal RI */
17701 generate_exception(ctx
, EXCP_RI
);
17705 MIPS_INVAL("pool32c");
17706 gen_reserved_instruction(ctx
);
17710 case ADDI32
: /* AUI, LUI */
17711 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17713 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17716 mips32_op
= OPC_ADDI
;
17721 mips32_op
= OPC_ADDIU
;
17723 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17726 /* Logical operations */
17728 mips32_op
= OPC_ORI
;
17731 mips32_op
= OPC_XORI
;
17734 mips32_op
= OPC_ANDI
;
17736 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17739 /* Set less than immediate */
17741 mips32_op
= OPC_SLTI
;
17744 mips32_op
= OPC_SLTIU
;
17746 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17749 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
17750 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17751 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17752 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17754 case JALS32
: /* BOVC, BEQC, BEQZALC */
17755 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17758 mips32_op
= OPC_BOVC
;
17759 } else if (rs
< rt
&& rs
== 0) {
17761 mips32_op
= OPC_BEQZALC
;
17764 mips32_op
= OPC_BEQC
;
17766 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17769 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17770 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17771 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17774 case BEQ32
: /* BC */
17775 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17777 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17778 sextract32(ctx
->opcode
<< 1, 0, 27));
17781 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17784 case BNE32
: /* BALC */
17785 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17787 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17788 sextract32(ctx
->opcode
<< 1, 0, 27));
17791 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17794 case J32
: /* BGTZC, BLTZC, BLTC */
17795 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17796 if (rs
== 0 && rt
!= 0) {
17798 mips32_op
= OPC_BGTZC
;
17799 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17801 mips32_op
= OPC_BLTZC
;
17804 mips32_op
= OPC_BLTC
;
17806 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17809 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17810 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17813 case JAL32
: /* BLEZC, BGEZC, BGEC */
17814 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17815 if (rs
== 0 && rt
!= 0) {
17817 mips32_op
= OPC_BLEZC
;
17818 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17820 mips32_op
= OPC_BGEZC
;
17823 mips32_op
= OPC_BGEC
;
17825 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17828 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17829 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17830 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17833 /* Floating point (COP1) */
17835 mips32_op
= OPC_LWC1
;
17838 mips32_op
= OPC_LDC1
;
17841 mips32_op
= OPC_SWC1
;
17844 mips32_op
= OPC_SDC1
;
17846 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17848 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17849 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
17850 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17851 switch ((ctx
->opcode
>> 16) & 0x1f) {
17860 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17863 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17866 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17876 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17879 generate_exception(ctx
, EXCP_RI
);
17884 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17885 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17887 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17890 case BNVC
: /* BNEC, BNEZALC */
17891 check_insn(ctx
, ISA_MIPS_R6
);
17894 mips32_op
= OPC_BNVC
;
17895 } else if (rs
< rt
&& rs
== 0) {
17897 mips32_op
= OPC_BNEZALC
;
17900 mips32_op
= OPC_BNEC
;
17902 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17904 case R6_BNEZC
: /* JIALC */
17905 check_insn(ctx
, ISA_MIPS_R6
);
17908 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17909 sextract32(ctx
->opcode
<< 1, 0, 22));
17912 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17915 case R6_BEQZC
: /* JIC */
17916 check_insn(ctx
, ISA_MIPS_R6
);
17919 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17920 sextract32(ctx
->opcode
<< 1, 0, 22));
17923 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17926 case BLEZALC
: /* BGEZALC, BGEUC */
17927 check_insn(ctx
, ISA_MIPS_R6
);
17928 if (rs
== 0 && rt
!= 0) {
17930 mips32_op
= OPC_BLEZALC
;
17931 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17933 mips32_op
= OPC_BGEZALC
;
17936 mips32_op
= OPC_BGEUC
;
17938 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17940 case BGTZALC
: /* BLTZALC, BLTUC */
17941 check_insn(ctx
, ISA_MIPS_R6
);
17942 if (rs
== 0 && rt
!= 0) {
17944 mips32_op
= OPC_BGTZALC
;
17945 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17947 mips32_op
= OPC_BLTZALC
;
17950 mips32_op
= OPC_BLTUC
;
17952 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17954 /* Loads and stores */
17956 mips32_op
= OPC_LB
;
17959 mips32_op
= OPC_LBU
;
17962 mips32_op
= OPC_LH
;
17965 mips32_op
= OPC_LHU
;
17968 mips32_op
= OPC_LW
;
17970 #ifdef TARGET_MIPS64
17972 check_insn(ctx
, ISA_MIPS3
);
17973 check_mips_64(ctx
);
17974 mips32_op
= OPC_LD
;
17977 check_insn(ctx
, ISA_MIPS3
);
17978 check_mips_64(ctx
);
17979 mips32_op
= OPC_SD
;
17983 mips32_op
= OPC_SB
;
17986 mips32_op
= OPC_SH
;
17989 mips32_op
= OPC_SW
;
17992 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
17995 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
17998 gen_reserved_instruction(ctx
);
18003 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
18007 /* make sure instructions are on a halfword boundary */
18008 if (ctx
->base
.pc_next
& 0x1) {
18009 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
18010 generate_exception_end(ctx
, EXCP_AdEL
);
18014 op
= (ctx
->opcode
>> 10) & 0x3f;
18015 /* Enforce properly-sized instructions in a delay slot */
18016 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
18017 switch (op
& 0x7) { /* MSB-3..MSB-5 */
18019 /* POOL32A, POOL32B, POOL32I, POOL32C */
18021 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
18023 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
18025 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
18027 /* LB32, LH32, LWC132, LDC132, LW32 */
18028 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
18029 gen_reserved_instruction(ctx
);
18034 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
18036 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
18038 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
18039 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
18040 gen_reserved_instruction(ctx
);
18050 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18051 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
18052 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
18055 switch (ctx
->opcode
& 0x1) {
18063 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
18065 * In the Release 6, the register number location in
18066 * the instruction encoding has changed.
18068 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
18070 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
18076 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18077 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
18078 int amount
= (ctx
->opcode
>> 1) & 0x7;
18080 amount
= amount
== 0 ? 8 : amount
;
18082 switch (ctx
->opcode
& 0x1) {
18091 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
18095 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
18096 gen_pool16c_r6_insn(ctx
);
18098 gen_pool16c_insn(ctx
);
18103 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18104 int rb
= 28; /* GP */
18105 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
18107 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18111 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
18112 if (ctx
->opcode
& 1) {
18113 gen_reserved_instruction(ctx
);
18116 int enc_dest
= uMIPS_RD(ctx
->opcode
);
18117 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
18118 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
18119 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
18124 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18125 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18126 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
18127 offset
= (offset
== 0xf ? -1 : offset
);
18129 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
18134 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18135 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18136 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
18138 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
18143 int rd
= (ctx
->opcode
>> 5) & 0x1f;
18144 int rb
= 29; /* SP */
18145 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
18147 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18152 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
18153 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18154 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
18156 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
18161 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18162 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18163 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
18165 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
18170 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18171 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18172 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
18174 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
18179 int rd
= (ctx
->opcode
>> 5) & 0x1f;
18180 int rb
= 29; /* SP */
18181 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
18183 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
18188 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
18189 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
18190 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
18192 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
18197 int rd
= uMIPS_RD5(ctx
->opcode
);
18198 int rs
= uMIPS_RS5(ctx
->opcode
);
18200 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
18207 switch (ctx
->opcode
& 0x1) {
18217 switch (ctx
->opcode
& 0x1) {
18222 gen_addiur1sp(ctx
);
18226 case B16
: /* BC16 */
18227 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
18228 sextract32(ctx
->opcode
, 0, 10) << 1,
18229 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
18231 case BNEZ16
: /* BNEZC16 */
18232 case BEQZ16
: /* BEQZC16 */
18233 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
18234 mmreg(uMIPS_RD(ctx
->opcode
)),
18235 0, sextract32(ctx
->opcode
, 0, 7) << 1,
18236 (ctx
->insn_flags
& ISA_MIPS_R6
) ? 0 : 4);
18241 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
18242 int imm
= ZIMM(ctx
->opcode
, 0, 7);
18244 imm
= (imm
== 0x7f ? -1 : imm
);
18245 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
18251 gen_reserved_instruction(ctx
);
18254 decode_micromips32_opc(env
, ctx
);
18267 /* MAJOR, P16, and P32 pools opcodes */
18271 NM_MOVE_BALC
= 0x02,
18279 NM_P16_SHIFT
= 0x0c,
18297 NM_P_LS_U12
= 0x21,
18307 NM_P16_ADDU
= 0x2c,
18321 NM_MOVEPREV
= 0x3f,
18324 /* POOL32A instruction pool */
18326 NM_POOL32A0
= 0x00,
18327 NM_SPECIAL2
= 0x01,
18330 NM_POOL32A5
= 0x05,
18331 NM_POOL32A7
= 0x07,
18334 /* P.GP.W instruction pool */
18336 NM_ADDIUGP_W
= 0x00,
18341 /* P48I instruction pool */
18345 NM_ADDIUGP48
= 0x02,
18346 NM_ADDIUPC48
= 0x03,
18351 /* P.U12 instruction pool */
18360 NM_ADDIUNEG
= 0x08,
18367 /* POOL32F instruction pool */
18369 NM_POOL32F_0
= 0x00,
18370 NM_POOL32F_3
= 0x03,
18371 NM_POOL32F_5
= 0x05,
18374 /* POOL32S instruction pool */
18376 NM_POOL32S_0
= 0x00,
18377 NM_POOL32S_4
= 0x04,
18380 /* P.LUI instruction pool */
18386 /* P.GP.BH instruction pool */
18391 NM_ADDIUGP_B
= 0x03,
18394 NM_P_GP_CP1
= 0x06,
18397 /* P.LS.U12 instruction pool */
18402 NM_P_PREFU12
= 0x03,
18415 /* P.LS.S9 instruction pool */
18421 NM_P_LS_UAWM
= 0x05,
18424 /* P.BAL instruction pool */
18430 /* P.J instruction pool */
18433 NM_JALRC_HB
= 0x01,
18434 NM_P_BALRSC
= 0x08,
18437 /* P.BR1 instruction pool */
18445 /* P.BR2 instruction pool */
18452 /* P.BRI instruction pool */
18464 /* P16.SHIFT instruction pool */
18470 /* POOL16C instruction pool */
18472 NM_POOL16C_0
= 0x00,
18476 /* P16.A1 instruction pool */
18478 NM_ADDIUR1SP
= 0x01,
18481 /* P16.A2 instruction pool */
18484 NM_P_ADDIURS5
= 0x01,
18487 /* P16.ADDU instruction pool */
18493 /* P16.SR instruction pool */
18496 NM_RESTORE_JRC16
= 0x01,
18499 /* P16.4X4 instruction pool */
18505 /* P16.LB instruction pool */
18512 /* P16.LH instruction pool */
18519 /* P.RI instruction pool */
18522 NM_P_SYSCALL
= 0x01,
18527 /* POOL32A0 instruction pool */
18562 NM_D_E_MT_VPE
= 0x56,
18570 /* CRC32 instruction pool */
18580 /* POOL32A5 instruction pool */
18582 NM_CMP_EQ_PH
= 0x00,
18583 NM_CMP_LT_PH
= 0x08,
18584 NM_CMP_LE_PH
= 0x10,
18585 NM_CMPGU_EQ_QB
= 0x18,
18586 NM_CMPGU_LT_QB
= 0x20,
18587 NM_CMPGU_LE_QB
= 0x28,
18588 NM_CMPGDU_EQ_QB
= 0x30,
18589 NM_CMPGDU_LT_QB
= 0x38,
18590 NM_CMPGDU_LE_QB
= 0x40,
18591 NM_CMPU_EQ_QB
= 0x48,
18592 NM_CMPU_LT_QB
= 0x50,
18593 NM_CMPU_LE_QB
= 0x58,
18594 NM_ADDQ_S_W
= 0x60,
18595 NM_SUBQ_S_W
= 0x68,
18599 NM_ADDQ_S_PH
= 0x01,
18600 NM_ADDQH_R_PH
= 0x09,
18601 NM_ADDQH_R_W
= 0x11,
18602 NM_ADDU_S_QB
= 0x19,
18603 NM_ADDU_S_PH
= 0x21,
18604 NM_ADDUH_R_QB
= 0x29,
18605 NM_SHRAV_R_PH
= 0x31,
18606 NM_SHRAV_R_QB
= 0x39,
18607 NM_SUBQ_S_PH
= 0x41,
18608 NM_SUBQH_R_PH
= 0x49,
18609 NM_SUBQH_R_W
= 0x51,
18610 NM_SUBU_S_QB
= 0x59,
18611 NM_SUBU_S_PH
= 0x61,
18612 NM_SUBUH_R_QB
= 0x69,
18613 NM_SHLLV_S_PH
= 0x71,
18614 NM_PRECR_SRA_R_PH_W
= 0x79,
18616 NM_MULEU_S_PH_QBL
= 0x12,
18617 NM_MULEU_S_PH_QBR
= 0x1a,
18618 NM_MULQ_RS_PH
= 0x22,
18619 NM_MULQ_S_PH
= 0x2a,
18620 NM_MULQ_RS_W
= 0x32,
18621 NM_MULQ_S_W
= 0x3a,
18624 NM_SHRAV_R_W
= 0x5a,
18625 NM_SHRLV_PH
= 0x62,
18626 NM_SHRLV_QB
= 0x6a,
18627 NM_SHLLV_QB
= 0x72,
18628 NM_SHLLV_S_W
= 0x7a,
18632 NM_MULEQ_S_W_PHL
= 0x04,
18633 NM_MULEQ_S_W_PHR
= 0x0c,
18635 NM_MUL_S_PH
= 0x05,
18636 NM_PRECR_QB_PH
= 0x0d,
18637 NM_PRECRQ_QB_PH
= 0x15,
18638 NM_PRECRQ_PH_W
= 0x1d,
18639 NM_PRECRQ_RS_PH_W
= 0x25,
18640 NM_PRECRQU_S_QB_PH
= 0x2d,
18641 NM_PACKRL_PH
= 0x35,
18645 NM_SHRA_R_W
= 0x5e,
18646 NM_SHRA_R_PH
= 0x66,
18647 NM_SHLL_S_PH
= 0x76,
18648 NM_SHLL_S_W
= 0x7e,
18653 /* POOL32A7 instruction pool */
18658 NM_POOL32AXF
= 0x07,
18661 /* P.SR instruction pool */
18667 /* P.SHIFT instruction pool */
18675 /* P.ROTX instruction pool */
18680 /* P.INS instruction pool */
18685 /* P.EXT instruction pool */
18690 /* POOL32F_0 (fmt) instruction pool */
18695 NM_SELEQZ_S
= 0x07,
18696 NM_SELEQZ_D
= 0x47,
18700 NM_SELNEZ_S
= 0x0f,
18701 NM_SELNEZ_D
= 0x4f,
18716 /* POOL32F_3 instruction pool */
18720 NM_MINA_FMT
= 0x04,
18721 NM_MAXA_FMT
= 0x05,
18722 NM_POOL32FXF
= 0x07,
18725 /* POOL32F_5 instruction pool */
18727 NM_CMP_CONDN_S
= 0x00,
18728 NM_CMP_CONDN_D
= 0x02,
18731 /* P.GP.LH instruction pool */
18737 /* P.GP.SH instruction pool */
18742 /* P.GP.CP1 instruction pool */
18750 /* P.LS.S0 instruction pool */
18767 NM_P_PREFS9
= 0x03,
18773 /* P.LS.S1 instruction pool */
18775 NM_ASET_ACLR
= 0x02,
18783 /* P.LS.E0 instruction pool */
18799 /* P.PREFE instruction pool */
18805 /* P.LLE instruction pool */
18811 /* P.SCE instruction pool */
18817 /* P.LS.WM instruction pool */
18823 /* P.LS.UAWM instruction pool */
18829 /* P.BR3A instruction pool */
18835 NM_BPOSGE32C
= 0x04,
18838 /* P16.RI instruction pool */
18840 NM_P16_SYSCALL
= 0x01,
18845 /* POOL16C_0 instruction pool */
18847 NM_POOL16C_00
= 0x00,
18850 /* P16.JRC instruction pool */
18856 /* P.SYSCALL instruction pool */
18862 /* P.TRAP instruction pool */
18868 /* P.CMOVE instruction pool */
18874 /* POOL32Axf instruction pool */
18876 NM_POOL32AXF_1
= 0x01,
18877 NM_POOL32AXF_2
= 0x02,
18878 NM_POOL32AXF_4
= 0x04,
18879 NM_POOL32AXF_5
= 0x05,
18880 NM_POOL32AXF_7
= 0x07,
18883 /* POOL32Axf_1 instruction pool */
18885 NM_POOL32AXF_1_0
= 0x00,
18886 NM_POOL32AXF_1_1
= 0x01,
18887 NM_POOL32AXF_1_3
= 0x03,
18888 NM_POOL32AXF_1_4
= 0x04,
18889 NM_POOL32AXF_1_5
= 0x05,
18890 NM_POOL32AXF_1_7
= 0x07,
18893 /* POOL32Axf_2 instruction pool */
18895 NM_POOL32AXF_2_0_7
= 0x00,
18896 NM_POOL32AXF_2_8_15
= 0x01,
18897 NM_POOL32AXF_2_16_23
= 0x02,
18898 NM_POOL32AXF_2_24_31
= 0x03,
18901 /* POOL32Axf_7 instruction pool */
18903 NM_SHRA_R_QB
= 0x0,
18908 /* POOL32Axf_1_0 instruction pool */
18916 /* POOL32Axf_1_1 instruction pool */
18922 /* POOL32Axf_1_3 instruction pool */
18930 /* POOL32Axf_1_4 instruction pool */
18936 /* POOL32Axf_1_5 instruction pool */
18938 NM_MAQ_S_W_PHR
= 0x0,
18939 NM_MAQ_S_W_PHL
= 0x1,
18940 NM_MAQ_SA_W_PHR
= 0x2,
18941 NM_MAQ_SA_W_PHL
= 0x3,
18944 /* POOL32Axf_1_7 instruction pool */
18948 NM_EXTR_RS_W
= 0x2,
18952 /* POOL32Axf_2_0_7 instruction pool */
18955 NM_DPAQ_S_W_PH
= 0x1,
18957 NM_DPSQ_S_W_PH
= 0x3,
18964 /* POOL32Axf_2_8_15 instruction pool */
18966 NM_DPAX_W_PH
= 0x0,
18967 NM_DPAQ_SA_L_W
= 0x1,
18968 NM_DPSX_W_PH
= 0x2,
18969 NM_DPSQ_SA_L_W
= 0x3,
18972 NM_EXTRV_R_W
= 0x7,
18975 /* POOL32Axf_2_16_23 instruction pool */
18977 NM_DPAU_H_QBL
= 0x0,
18978 NM_DPAQX_S_W_PH
= 0x1,
18979 NM_DPSU_H_QBL
= 0x2,
18980 NM_DPSQX_S_W_PH
= 0x3,
18983 NM_MULSA_W_PH
= 0x6,
18984 NM_EXTRV_RS_W
= 0x7,
18987 /* POOL32Axf_2_24_31 instruction pool */
18989 NM_DPAU_H_QBR
= 0x0,
18990 NM_DPAQX_SA_W_PH
= 0x1,
18991 NM_DPSU_H_QBR
= 0x2,
18992 NM_DPSQX_SA_W_PH
= 0x3,
18995 NM_MULSAQ_S_W_PH
= 0x6,
18996 NM_EXTRV_S_H
= 0x7,
18999 /* POOL32Axf_{4, 5} instruction pool */
19018 /* nanoMIPS DSP instructions */
19019 NM_ABSQ_S_QB
= 0x00,
19020 NM_ABSQ_S_PH
= 0x08,
19021 NM_ABSQ_S_W
= 0x10,
19022 NM_PRECEQ_W_PHL
= 0x28,
19023 NM_PRECEQ_W_PHR
= 0x30,
19024 NM_PRECEQU_PH_QBL
= 0x38,
19025 NM_PRECEQU_PH_QBR
= 0x48,
19026 NM_PRECEU_PH_QBL
= 0x58,
19027 NM_PRECEU_PH_QBR
= 0x68,
19028 NM_PRECEQU_PH_QBLA
= 0x39,
19029 NM_PRECEQU_PH_QBRA
= 0x49,
19030 NM_PRECEU_PH_QBLA
= 0x59,
19031 NM_PRECEU_PH_QBRA
= 0x69,
19032 NM_REPLV_PH
= 0x01,
19033 NM_REPLV_QB
= 0x09,
19036 NM_RADDU_W_QB
= 0x78,
19042 /* PP.SR instruction pool */
19046 NM_RESTORE_JRC
= 0x03,
19049 /* P.SR.F instruction pool */
19052 NM_RESTOREF
= 0x01,
19055 /* P16.SYSCALL instruction pool */
19057 NM_SYSCALL16
= 0x00,
19058 NM_HYPCALL16
= 0x01,
19061 /* POOL16C_00 instruction pool */
19069 /* PP.LSX and PP.LSXS instruction pool */
19107 /* ERETx instruction pool */
19113 /* POOL32FxF_{0, 1} insturction pool */
19122 NM_CVT_S_PL
= 0x84,
19123 NM_CVT_S_PU
= 0xa4,
19125 NM_CVT_L_S
= 0x004,
19126 NM_CVT_L_D
= 0x104,
19127 NM_CVT_W_S
= 0x024,
19128 NM_CVT_W_D
= 0x124,
19130 NM_RSQRT_S
= 0x008,
19131 NM_RSQRT_D
= 0x108,
19136 NM_RECIP_S
= 0x048,
19137 NM_RECIP_D
= 0x148,
19139 NM_FLOOR_L_S
= 0x00c,
19140 NM_FLOOR_L_D
= 0x10c,
19142 NM_FLOOR_W_S
= 0x02c,
19143 NM_FLOOR_W_D
= 0x12c,
19145 NM_CEIL_L_S
= 0x04c,
19146 NM_CEIL_L_D
= 0x14c,
19147 NM_CEIL_W_S
= 0x06c,
19148 NM_CEIL_W_D
= 0x16c,
19149 NM_TRUNC_L_S
= 0x08c,
19150 NM_TRUNC_L_D
= 0x18c,
19151 NM_TRUNC_W_S
= 0x0ac,
19152 NM_TRUNC_W_D
= 0x1ac,
19153 NM_ROUND_L_S
= 0x0cc,
19154 NM_ROUND_L_D
= 0x1cc,
19155 NM_ROUND_W_S
= 0x0ec,
19156 NM_ROUND_W_D
= 0x1ec,
19164 NM_CVT_D_S
= 0x04d,
19165 NM_CVT_D_W
= 0x0cd,
19166 NM_CVT_D_L
= 0x14d,
19167 NM_CVT_S_D
= 0x06d,
19168 NM_CVT_S_W
= 0x0ed,
19169 NM_CVT_S_L
= 0x16d,
19172 /* P.LL instruction pool */
19178 /* P.SC instruction pool */
19184 /* P.DVP instruction pool */
19193 * nanoMIPS decoding engine
19198 /* extraction utilities */
19200 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
19201 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
19202 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
19203 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
19204 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
19206 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
19207 static inline int decode_gpr_gpr3(int r
)
19209 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
19211 return map
[r
& 0x7];
19214 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
19215 static inline int decode_gpr_gpr3_src_store(int r
)
19217 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
19219 return map
[r
& 0x7];
19222 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
19223 static inline int decode_gpr_gpr4(int r
)
19225 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
19226 16, 17, 18, 19, 20, 21, 22, 23 };
19228 return map
[r
& 0xf];
19231 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
19232 static inline int decode_gpr_gpr4_zero(int r
)
19234 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
19235 16, 17, 18, 19, 20, 21, 22, 23 };
19237 return map
[r
& 0xf];
19241 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
19243 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
19246 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
19247 uint8_t gp
, uint16_t u
)
19250 TCGv va
= tcg_temp_new();
19251 TCGv t0
= tcg_temp_new();
19253 while (counter
!= count
) {
19254 bool use_gp
= gp
&& (counter
== count
- 1);
19255 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
19256 int this_offset
= -((counter
+ 1) << 2);
19257 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
19258 gen_load_gpr(t0
, this_rt
);
19259 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
19260 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
19264 /* adjust stack pointer */
19265 gen_adjust_sp(ctx
, -u
);
19271 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
19272 uint8_t gp
, uint16_t u
)
19275 TCGv va
= tcg_temp_new();
19276 TCGv t0
= tcg_temp_new();
19278 while (counter
!= count
) {
19279 bool use_gp
= gp
&& (counter
== count
- 1);
19280 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
19281 int this_offset
= u
- ((counter
+ 1) << 2);
19282 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
19283 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
19284 ctx
->default_tcg_memop_mask
);
19285 tcg_gen_ext32s_tl(t0
, t0
);
19286 gen_store_gpr(t0
, this_rt
);
19290 /* adjust stack pointer */
19291 gen_adjust_sp(ctx
, u
);
19297 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
19299 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
19300 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
19302 switch (extract32(ctx
->opcode
, 2, 2)) {
19304 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
19307 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
19310 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
19313 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
19318 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19320 int rt
= extract32(ctx
->opcode
, 21, 5);
19321 int rs
= extract32(ctx
->opcode
, 16, 5);
19322 int rd
= extract32(ctx
->opcode
, 11, 5);
19324 switch (extract32(ctx
->opcode
, 3, 7)) {
19326 switch (extract32(ctx
->opcode
, 10, 1)) {
19329 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
19333 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
19339 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
19343 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
19346 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
19349 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
19352 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
19355 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
19358 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
19361 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
19364 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
19368 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
19371 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
19374 switch (extract32(ctx
->opcode
, 10, 1)) {
19376 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
19379 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
19384 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
19387 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
19390 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
19393 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
19396 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
19401 #ifndef CONFIG_USER_ONLY
19402 TCGv t0
= tcg_temp_new();
19403 switch (extract32(ctx
->opcode
, 10, 1)) {
19406 check_cp0_enabled(ctx
);
19407 gen_helper_dvp(t0
, cpu_env
);
19408 gen_store_gpr(t0
, rt
);
19413 check_cp0_enabled(ctx
);
19414 gen_helper_evp(t0
, cpu_env
);
19415 gen_store_gpr(t0
, rt
);
19422 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
19427 TCGv t0
= tcg_temp_new();
19428 TCGv t1
= tcg_temp_new();
19429 TCGv t2
= tcg_temp_new();
19431 gen_load_gpr(t1
, rs
);
19432 gen_load_gpr(t2
, rt
);
19433 tcg_gen_add_tl(t0
, t1
, t2
);
19434 tcg_gen_ext32s_tl(t0
, t0
);
19435 tcg_gen_xor_tl(t1
, t1
, t2
);
19436 tcg_gen_xor_tl(t2
, t0
, t2
);
19437 tcg_gen_andc_tl(t1
, t2
, t1
);
19439 /* operands of same sign, result different sign */
19440 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
19441 gen_store_gpr(t0
, rd
);
19449 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
19452 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
19455 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
19458 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
19461 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
19464 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
19467 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
19470 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
19472 #ifndef CONFIG_USER_ONLY
19474 check_cp0_enabled(ctx
);
19476 /* Treat as NOP. */
19479 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
19482 check_cp0_enabled(ctx
);
19484 TCGv t0
= tcg_temp_new();
19486 gen_load_gpr(t0
, rt
);
19487 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
19491 case NM_D_E_MT_VPE
:
19493 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
19494 TCGv t0
= tcg_temp_new();
19501 gen_helper_dmt(t0
);
19502 gen_store_gpr(t0
, rt
);
19503 } else if (rs
== 0) {
19506 gen_helper_dvpe(t0
, cpu_env
);
19507 gen_store_gpr(t0
, rt
);
19509 gen_reserved_instruction(ctx
);
19516 gen_helper_emt(t0
);
19517 gen_store_gpr(t0
, rt
);
19518 } else if (rs
== 0) {
19521 gen_helper_evpe(t0
, cpu_env
);
19522 gen_store_gpr(t0
, rt
);
19524 gen_reserved_instruction(ctx
);
19535 TCGv t0
= tcg_temp_new();
19536 TCGv t1
= tcg_temp_new();
19538 gen_load_gpr(t0
, rt
);
19539 gen_load_gpr(t1
, rs
);
19540 gen_helper_fork(t0
, t1
);
19547 check_cp0_enabled(ctx
);
19549 /* Treat as NOP. */
19552 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19553 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19557 check_cp0_enabled(ctx
);
19558 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
19559 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
19564 TCGv t0
= tcg_temp_new();
19566 gen_load_gpr(t0
, rs
);
19567 gen_helper_yield(t0
, cpu_env
, t0
);
19568 gen_store_gpr(t0
, rt
);
19574 gen_reserved_instruction(ctx
);
19580 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19581 int ret
, int v1
, int v2
)
19587 t0
= tcg_temp_new_i32();
19589 v0_t
= tcg_temp_new();
19590 v1_t
= tcg_temp_new();
19592 tcg_gen_movi_i32(t0
, v2
>> 3);
19594 gen_load_gpr(v0_t
, ret
);
19595 gen_load_gpr(v1_t
, v1
);
19598 case NM_MAQ_S_W_PHR
:
19600 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19602 case NM_MAQ_S_W_PHL
:
19604 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19606 case NM_MAQ_SA_W_PHR
:
19608 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19610 case NM_MAQ_SA_W_PHL
:
19612 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19615 gen_reserved_instruction(ctx
);
19619 tcg_temp_free_i32(t0
);
19621 tcg_temp_free(v0_t
);
19622 tcg_temp_free(v1_t
);
19626 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19627 int ret
, int v1
, int v2
)
19630 TCGv t0
= tcg_temp_new();
19631 TCGv t1
= tcg_temp_new();
19632 TCGv v0_t
= tcg_temp_new();
19634 gen_load_gpr(v0_t
, v1
);
19637 case NM_POOL32AXF_1_0
:
19639 switch (extract32(ctx
->opcode
, 12, 2)) {
19641 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19644 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19647 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19650 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19654 case NM_POOL32AXF_1_1
:
19656 switch (extract32(ctx
->opcode
, 12, 2)) {
19658 tcg_gen_movi_tl(t0
, v2
);
19659 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19662 tcg_gen_movi_tl(t0
, v2
>> 3);
19663 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19666 gen_reserved_instruction(ctx
);
19670 case NM_POOL32AXF_1_3
:
19672 imm
= extract32(ctx
->opcode
, 14, 7);
19673 switch (extract32(ctx
->opcode
, 12, 2)) {
19675 tcg_gen_movi_tl(t0
, imm
);
19676 gen_helper_rddsp(t0
, t0
, cpu_env
);
19677 gen_store_gpr(t0
, ret
);
19680 gen_load_gpr(t0
, ret
);
19681 tcg_gen_movi_tl(t1
, imm
);
19682 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19685 tcg_gen_movi_tl(t0
, v2
>> 3);
19686 tcg_gen_movi_tl(t1
, v1
);
19687 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19688 gen_store_gpr(t0
, ret
);
19691 tcg_gen_movi_tl(t0
, v2
>> 3);
19692 tcg_gen_movi_tl(t1
, v1
);
19693 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19694 gen_store_gpr(t0
, ret
);
19698 case NM_POOL32AXF_1_4
:
19700 tcg_gen_movi_tl(t0
, v2
>> 2);
19701 switch (extract32(ctx
->opcode
, 12, 1)) {
19703 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19704 gen_store_gpr(t0
, ret
);
19707 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19708 gen_store_gpr(t0
, ret
);
19712 case NM_POOL32AXF_1_5
:
19713 opc
= extract32(ctx
->opcode
, 12, 2);
19714 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19716 case NM_POOL32AXF_1_7
:
19718 tcg_gen_movi_tl(t0
, v2
>> 3);
19719 tcg_gen_movi_tl(t1
, v1
);
19720 switch (extract32(ctx
->opcode
, 12, 2)) {
19722 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19723 gen_store_gpr(t0
, ret
);
19726 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19727 gen_store_gpr(t0
, ret
);
19730 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19731 gen_store_gpr(t0
, ret
);
19734 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19735 gen_store_gpr(t0
, ret
);
19740 gen_reserved_instruction(ctx
);
19746 tcg_temp_free(v0_t
);
19749 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19750 TCGv v0
, TCGv v1
, int rd
)
19754 t0
= tcg_temp_new_i32();
19756 tcg_gen_movi_i32(t0
, rd
>> 3);
19759 case NM_POOL32AXF_2_0_7
:
19760 switch (extract32(ctx
->opcode
, 9, 3)) {
19763 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19765 case NM_DPAQ_S_W_PH
:
19767 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19771 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19773 case NM_DPSQ_S_W_PH
:
19775 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19778 gen_reserved_instruction(ctx
);
19782 case NM_POOL32AXF_2_8_15
:
19783 switch (extract32(ctx
->opcode
, 9, 3)) {
19786 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19788 case NM_DPAQ_SA_L_W
:
19790 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19794 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19796 case NM_DPSQ_SA_L_W
:
19798 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19801 gen_reserved_instruction(ctx
);
19805 case NM_POOL32AXF_2_16_23
:
19806 switch (extract32(ctx
->opcode
, 9, 3)) {
19807 case NM_DPAU_H_QBL
:
19809 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19811 case NM_DPAQX_S_W_PH
:
19813 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19815 case NM_DPSU_H_QBL
:
19817 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19819 case NM_DPSQX_S_W_PH
:
19821 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19823 case NM_MULSA_W_PH
:
19825 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19828 gen_reserved_instruction(ctx
);
19832 case NM_POOL32AXF_2_24_31
:
19833 switch (extract32(ctx
->opcode
, 9, 3)) {
19834 case NM_DPAU_H_QBR
:
19836 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19838 case NM_DPAQX_SA_W_PH
:
19840 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19842 case NM_DPSU_H_QBR
:
19844 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19846 case NM_DPSQX_SA_W_PH
:
19848 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19850 case NM_MULSAQ_S_W_PH
:
19852 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19855 gen_reserved_instruction(ctx
);
19860 gen_reserved_instruction(ctx
);
19864 tcg_temp_free_i32(t0
);
19867 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19868 int rt
, int rs
, int rd
)
19871 TCGv t0
= tcg_temp_new();
19872 TCGv t1
= tcg_temp_new();
19873 TCGv v0_t
= tcg_temp_new();
19874 TCGv v1_t
= tcg_temp_new();
19876 gen_load_gpr(v0_t
, rt
);
19877 gen_load_gpr(v1_t
, rs
);
19880 case NM_POOL32AXF_2_0_7
:
19881 switch (extract32(ctx
->opcode
, 9, 3)) {
19883 case NM_DPAQ_S_W_PH
:
19885 case NM_DPSQ_S_W_PH
:
19886 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19891 gen_load_gpr(t0
, rs
);
19893 if (rd
!= 0 && rd
!= 2) {
19894 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19895 tcg_gen_ext32u_tl(t0
, t0
);
19896 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19897 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19899 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19905 int acc
= extract32(ctx
->opcode
, 14, 2);
19906 TCGv_i64 t2
= tcg_temp_new_i64();
19907 TCGv_i64 t3
= tcg_temp_new_i64();
19909 gen_load_gpr(t0
, rt
);
19910 gen_load_gpr(t1
, rs
);
19911 tcg_gen_ext_tl_i64(t2
, t0
);
19912 tcg_gen_ext_tl_i64(t3
, t1
);
19913 tcg_gen_mul_i64(t2
, t2
, t3
);
19914 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19915 tcg_gen_add_i64(t2
, t2
, t3
);
19916 tcg_temp_free_i64(t3
);
19917 gen_move_low32(cpu_LO
[acc
], t2
);
19918 gen_move_high32(cpu_HI
[acc
], t2
);
19919 tcg_temp_free_i64(t2
);
19925 int acc
= extract32(ctx
->opcode
, 14, 2);
19926 TCGv_i32 t2
= tcg_temp_new_i32();
19927 TCGv_i32 t3
= tcg_temp_new_i32();
19929 gen_load_gpr(t0
, rs
);
19930 gen_load_gpr(t1
, rt
);
19931 tcg_gen_trunc_tl_i32(t2
, t0
);
19932 tcg_gen_trunc_tl_i32(t3
, t1
);
19933 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19934 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19935 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19936 tcg_temp_free_i32(t2
);
19937 tcg_temp_free_i32(t3
);
19942 gen_load_gpr(v1_t
, rs
);
19943 tcg_gen_movi_tl(t0
, rd
>> 3);
19944 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19945 gen_store_gpr(t0
, ret
);
19949 case NM_POOL32AXF_2_8_15
:
19950 switch (extract32(ctx
->opcode
, 9, 3)) {
19952 case NM_DPAQ_SA_L_W
:
19954 case NM_DPSQ_SA_L_W
:
19955 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19960 int acc
= extract32(ctx
->opcode
, 14, 2);
19961 TCGv_i64 t2
= tcg_temp_new_i64();
19962 TCGv_i64 t3
= tcg_temp_new_i64();
19964 gen_load_gpr(t0
, rs
);
19965 gen_load_gpr(t1
, rt
);
19966 tcg_gen_ext32u_tl(t0
, t0
);
19967 tcg_gen_ext32u_tl(t1
, t1
);
19968 tcg_gen_extu_tl_i64(t2
, t0
);
19969 tcg_gen_extu_tl_i64(t3
, t1
);
19970 tcg_gen_mul_i64(t2
, t2
, t3
);
19971 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19972 tcg_gen_add_i64(t2
, t2
, t3
);
19973 tcg_temp_free_i64(t3
);
19974 gen_move_low32(cpu_LO
[acc
], t2
);
19975 gen_move_high32(cpu_HI
[acc
], t2
);
19976 tcg_temp_free_i64(t2
);
19982 int acc
= extract32(ctx
->opcode
, 14, 2);
19983 TCGv_i32 t2
= tcg_temp_new_i32();
19984 TCGv_i32 t3
= tcg_temp_new_i32();
19986 gen_load_gpr(t0
, rs
);
19987 gen_load_gpr(t1
, rt
);
19988 tcg_gen_trunc_tl_i32(t2
, t0
);
19989 tcg_gen_trunc_tl_i32(t3
, t1
);
19990 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
19991 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19992 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19993 tcg_temp_free_i32(t2
);
19994 tcg_temp_free_i32(t3
);
19999 tcg_gen_movi_tl(t0
, rd
>> 3);
20000 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
20001 gen_store_gpr(t0
, ret
);
20004 gen_reserved_instruction(ctx
);
20008 case NM_POOL32AXF_2_16_23
:
20009 switch (extract32(ctx
->opcode
, 9, 3)) {
20010 case NM_DPAU_H_QBL
:
20011 case NM_DPAQX_S_W_PH
:
20012 case NM_DPSU_H_QBL
:
20013 case NM_DPSQX_S_W_PH
:
20014 case NM_MULSA_W_PH
:
20015 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
20019 tcg_gen_movi_tl(t0
, rd
>> 3);
20020 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
20021 gen_store_gpr(t0
, ret
);
20026 int acc
= extract32(ctx
->opcode
, 14, 2);
20027 TCGv_i64 t2
= tcg_temp_new_i64();
20028 TCGv_i64 t3
= tcg_temp_new_i64();
20030 gen_load_gpr(t0
, rs
);
20031 gen_load_gpr(t1
, rt
);
20032 tcg_gen_ext_tl_i64(t2
, t0
);
20033 tcg_gen_ext_tl_i64(t3
, t1
);
20034 tcg_gen_mul_i64(t2
, t2
, t3
);
20035 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
20036 tcg_gen_sub_i64(t2
, t3
, t2
);
20037 tcg_temp_free_i64(t3
);
20038 gen_move_low32(cpu_LO
[acc
], t2
);
20039 gen_move_high32(cpu_HI
[acc
], t2
);
20040 tcg_temp_free_i64(t2
);
20043 case NM_EXTRV_RS_W
:
20045 tcg_gen_movi_tl(t0
, rd
>> 3);
20046 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
20047 gen_store_gpr(t0
, ret
);
20051 case NM_POOL32AXF_2_24_31
:
20052 switch (extract32(ctx
->opcode
, 9, 3)) {
20053 case NM_DPAU_H_QBR
:
20054 case NM_DPAQX_SA_W_PH
:
20055 case NM_DPSU_H_QBR
:
20056 case NM_DPSQX_SA_W_PH
:
20057 case NM_MULSAQ_S_W_PH
:
20058 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
20062 tcg_gen_movi_tl(t0
, rd
>> 3);
20063 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
20064 gen_store_gpr(t0
, ret
);
20069 int acc
= extract32(ctx
->opcode
, 14, 2);
20070 TCGv_i64 t2
= tcg_temp_new_i64();
20071 TCGv_i64 t3
= tcg_temp_new_i64();
20073 gen_load_gpr(t0
, rs
);
20074 gen_load_gpr(t1
, rt
);
20075 tcg_gen_ext32u_tl(t0
, t0
);
20076 tcg_gen_ext32u_tl(t1
, t1
);
20077 tcg_gen_extu_tl_i64(t2
, t0
);
20078 tcg_gen_extu_tl_i64(t3
, t1
);
20079 tcg_gen_mul_i64(t2
, t2
, t3
);
20080 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
20081 tcg_gen_sub_i64(t2
, t3
, t2
);
20082 tcg_temp_free_i64(t3
);
20083 gen_move_low32(cpu_LO
[acc
], t2
);
20084 gen_move_high32(cpu_HI
[acc
], t2
);
20085 tcg_temp_free_i64(t2
);
20090 tcg_gen_movi_tl(t0
, rd
>> 3);
20091 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
20092 gen_store_gpr(t0
, ret
);
20097 gen_reserved_instruction(ctx
);
20104 tcg_temp_free(v0_t
);
20105 tcg_temp_free(v1_t
);
20108 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
20112 TCGv t0
= tcg_temp_new();
20113 TCGv v0_t
= tcg_temp_new();
20115 gen_load_gpr(v0_t
, rs
);
20120 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
20121 gen_store_gpr(v0_t
, ret
);
20125 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
20126 gen_store_gpr(v0_t
, ret
);
20130 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
20131 gen_store_gpr(v0_t
, ret
);
20133 case NM_PRECEQ_W_PHL
:
20135 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
20136 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20137 gen_store_gpr(v0_t
, ret
);
20139 case NM_PRECEQ_W_PHR
:
20141 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
20142 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
20143 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20144 gen_store_gpr(v0_t
, ret
);
20146 case NM_PRECEQU_PH_QBL
:
20148 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
20149 gen_store_gpr(v0_t
, ret
);
20151 case NM_PRECEQU_PH_QBR
:
20153 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
20154 gen_store_gpr(v0_t
, ret
);
20156 case NM_PRECEQU_PH_QBLA
:
20158 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
20159 gen_store_gpr(v0_t
, ret
);
20161 case NM_PRECEQU_PH_QBRA
:
20163 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
20164 gen_store_gpr(v0_t
, ret
);
20166 case NM_PRECEU_PH_QBL
:
20168 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
20169 gen_store_gpr(v0_t
, ret
);
20171 case NM_PRECEU_PH_QBR
:
20173 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
20174 gen_store_gpr(v0_t
, ret
);
20176 case NM_PRECEU_PH_QBLA
:
20178 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
20179 gen_store_gpr(v0_t
, ret
);
20181 case NM_PRECEU_PH_QBRA
:
20183 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
20184 gen_store_gpr(v0_t
, ret
);
20188 tcg_gen_ext16u_tl(v0_t
, v0_t
);
20189 tcg_gen_shli_tl(t0
, v0_t
, 16);
20190 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20191 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20192 gen_store_gpr(v0_t
, ret
);
20196 tcg_gen_ext8u_tl(v0_t
, v0_t
);
20197 tcg_gen_shli_tl(t0
, v0_t
, 8);
20198 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20199 tcg_gen_shli_tl(t0
, v0_t
, 16);
20200 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
20201 tcg_gen_ext32s_tl(v0_t
, v0_t
);
20202 gen_store_gpr(v0_t
, ret
);
20206 gen_helper_bitrev(v0_t
, v0_t
);
20207 gen_store_gpr(v0_t
, ret
);
20212 TCGv tv0
= tcg_temp_new();
20214 gen_load_gpr(tv0
, rt
);
20215 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
20216 gen_store_gpr(v0_t
, ret
);
20217 tcg_temp_free(tv0
);
20220 case NM_RADDU_W_QB
:
20222 gen_helper_raddu_w_qb(v0_t
, v0_t
);
20223 gen_store_gpr(v0_t
, ret
);
20226 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
20230 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
20234 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
20237 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
20240 gen_reserved_instruction(ctx
);
20244 tcg_temp_free(v0_t
);
20248 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
20249 int rt
, int rs
, int rd
)
20251 TCGv t0
= tcg_temp_new();
20252 TCGv rs_t
= tcg_temp_new();
20254 gen_load_gpr(rs_t
, rs
);
20259 tcg_gen_movi_tl(t0
, rd
>> 2);
20260 switch (extract32(ctx
->opcode
, 12, 1)) {
20263 gen_helper_shra_qb(t0
, t0
, rs_t
);
20264 gen_store_gpr(t0
, rt
);
20268 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
20269 gen_store_gpr(t0
, rt
);
20275 tcg_gen_movi_tl(t0
, rd
>> 1);
20276 gen_helper_shrl_ph(t0
, t0
, rs_t
);
20277 gen_store_gpr(t0
, rt
);
20283 target_long result
;
20284 imm
= extract32(ctx
->opcode
, 13, 8);
20285 result
= (uint32_t)imm
<< 24 |
20286 (uint32_t)imm
<< 16 |
20287 (uint32_t)imm
<< 8 |
20289 result
= (int32_t)result
;
20290 tcg_gen_movi_tl(t0
, result
);
20291 gen_store_gpr(t0
, rt
);
20295 gen_reserved_instruction(ctx
);
20299 tcg_temp_free(rs_t
);
20303 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
20305 int rt
= extract32(ctx
->opcode
, 21, 5);
20306 int rs
= extract32(ctx
->opcode
, 16, 5);
20307 int rd
= extract32(ctx
->opcode
, 11, 5);
20309 switch (extract32(ctx
->opcode
, 6, 3)) {
20310 case NM_POOL32AXF_1
:
20312 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20313 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20316 case NM_POOL32AXF_2
:
20318 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
20319 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20322 case NM_POOL32AXF_4
:
20324 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
20325 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
20328 case NM_POOL32AXF_5
:
20329 switch (extract32(ctx
->opcode
, 9, 7)) {
20330 #ifndef CONFIG_USER_ONLY
20332 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
20335 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
20338 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
20341 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
20344 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
20347 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
20350 check_cp0_enabled(ctx
);
20352 TCGv t0
= tcg_temp_new();
20354 save_cpu_state(ctx
, 1);
20355 gen_helper_di(t0
, cpu_env
);
20356 gen_store_gpr(t0
, rt
);
20357 /* Stop translation as we may have switched the execution mode */
20358 ctx
->base
.is_jmp
= DISAS_STOP
;
20363 check_cp0_enabled(ctx
);
20365 TCGv t0
= tcg_temp_new();
20367 save_cpu_state(ctx
, 1);
20368 gen_helper_ei(t0
, cpu_env
);
20369 gen_store_gpr(t0
, rt
);
20370 /* Stop translation as we may have switched the execution mode */
20371 ctx
->base
.is_jmp
= DISAS_STOP
;
20376 gen_load_srsgpr(rs
, rt
);
20379 gen_store_srsgpr(rs
, rt
);
20382 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
20385 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
20388 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
20392 gen_reserved_instruction(ctx
);
20396 case NM_POOL32AXF_7
:
20398 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
20399 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
20403 gen_reserved_instruction(ctx
);
20408 /* Immediate Value Compact Branches */
20409 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
20410 int rt
, int32_t imm
, int32_t offset
)
20412 TCGCond cond
= TCG_COND_ALWAYS
;
20413 TCGv t0
= tcg_temp_new();
20414 TCGv t1
= tcg_temp_new();
20416 gen_load_gpr(t0
, rt
);
20417 tcg_gen_movi_tl(t1
, imm
);
20418 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20420 /* Load needed operands and calculate btarget */
20423 if (rt
== 0 && imm
== 0) {
20424 /* Unconditional branch */
20425 } else if (rt
== 0 && imm
!= 0) {
20429 cond
= TCG_COND_EQ
;
20435 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
20436 gen_reserved_instruction(ctx
);
20438 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
20439 /* Unconditional branch */
20440 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
20444 tcg_gen_shri_tl(t0
, t0
, imm
);
20445 tcg_gen_andi_tl(t0
, t0
, 1);
20446 tcg_gen_movi_tl(t1
, 0);
20447 if (opc
== NM_BBEQZC
) {
20448 cond
= TCG_COND_EQ
;
20450 cond
= TCG_COND_NE
;
20455 if (rt
== 0 && imm
== 0) {
20458 } else if (rt
== 0 && imm
!= 0) {
20459 /* Unconditional branch */
20461 cond
= TCG_COND_NE
;
20465 if (rt
== 0 && imm
== 0) {
20466 /* Unconditional branch */
20468 cond
= TCG_COND_GE
;
20472 cond
= TCG_COND_LT
;
20475 if (rt
== 0 && imm
== 0) {
20476 /* Unconditional branch */
20478 cond
= TCG_COND_GEU
;
20482 cond
= TCG_COND_LTU
;
20485 MIPS_INVAL("Immediate Value Compact branch");
20486 gen_reserved_instruction(ctx
);
20490 /* branch completion */
20491 clear_branch_hflags(ctx
);
20492 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20494 if (cond
== TCG_COND_ALWAYS
) {
20495 /* Uncoditional compact branch */
20496 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20498 /* Conditional compact branch */
20499 TCGLabel
*fs
= gen_new_label();
20501 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
20503 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20506 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20514 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
20515 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
20518 TCGv t0
= tcg_temp_new();
20519 TCGv t1
= tcg_temp_new();
20522 gen_load_gpr(t0
, rs
);
20526 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
20529 /* calculate btarget */
20530 tcg_gen_shli_tl(t0
, t0
, 1);
20531 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
20532 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
20534 /* branch completion */
20535 clear_branch_hflags(ctx
);
20536 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20538 /* unconditional branch to register */
20539 tcg_gen_mov_tl(cpu_PC
, btarget
);
20540 tcg_gen_lookup_and_goto_ptr();
20546 /* nanoMIPS Branches */
20547 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
20548 int rs
, int rt
, int32_t offset
)
20550 int bcond_compute
= 0;
20551 TCGv t0
= tcg_temp_new();
20552 TCGv t1
= tcg_temp_new();
20554 /* Load needed operands and calculate btarget */
20556 /* compact branch */
20559 gen_load_gpr(t0
, rs
);
20560 gen_load_gpr(t1
, rt
);
20562 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20566 if (rs
== 0 || rs
== rt
) {
20567 /* OPC_BLEZALC, OPC_BGEZALC */
20568 /* OPC_BGTZALC, OPC_BLTZALC */
20569 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20571 gen_load_gpr(t0
, rs
);
20572 gen_load_gpr(t1
, rt
);
20574 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20577 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20581 /* OPC_BEQZC, OPC_BNEZC */
20582 gen_load_gpr(t0
, rs
);
20584 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20586 /* OPC_JIC, OPC_JIALC */
20587 TCGv tbase
= tcg_temp_new();
20588 TCGv toffset
= tcg_temp_new();
20590 gen_load_gpr(tbase
, rt
);
20591 tcg_gen_movi_tl(toffset
, offset
);
20592 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20593 tcg_temp_free(tbase
);
20594 tcg_temp_free(toffset
);
20598 MIPS_INVAL("Compact branch/jump");
20599 gen_reserved_instruction(ctx
);
20603 if (bcond_compute
== 0) {
20604 /* Uncoditional compact branch */
20607 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20610 MIPS_INVAL("Compact branch/jump");
20611 gen_reserved_instruction(ctx
);
20615 /* Conditional compact branch */
20616 TCGLabel
*fs
= gen_new_label();
20620 if (rs
== 0 && rt
!= 0) {
20622 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20623 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20625 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20628 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20632 if (rs
== 0 && rt
!= 0) {
20634 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20635 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20637 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20640 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20644 if (rs
== 0 && rt
!= 0) {
20646 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20647 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20649 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20652 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20656 if (rs
== 0 && rt
!= 0) {
20658 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20659 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20661 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20664 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20668 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20671 MIPS_INVAL("Compact conditional branch/jump");
20672 gen_reserved_instruction(ctx
);
20676 /* branch completion */
20677 clear_branch_hflags(ctx
);
20678 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20680 /* Generating branch here as compact branches don't have delay slot */
20681 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20684 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20693 /* nanoMIPS CP1 Branches */
20694 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20695 int32_t ft
, int32_t offset
)
20697 target_ulong btarget
;
20698 TCGv_i64 t0
= tcg_temp_new_i64();
20700 gen_load_fpr64(ctx
, t0
, ft
);
20701 tcg_gen_andi_i64(t0
, t0
, 1);
20703 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20707 tcg_gen_xori_i64(t0
, t0
, 1);
20708 ctx
->hflags
|= MIPS_HFLAG_BC
;
20711 /* t0 already set */
20712 ctx
->hflags
|= MIPS_HFLAG_BC
;
20715 MIPS_INVAL("cp1 cond branch");
20716 gen_reserved_instruction(ctx
);
20720 tcg_gen_trunc_i64_tl(bcond
, t0
);
20722 ctx
->btarget
= btarget
;
20725 tcg_temp_free_i64(t0
);
20729 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20732 t0
= tcg_temp_new();
20733 t1
= tcg_temp_new();
20735 gen_load_gpr(t0
, rs
);
20736 gen_load_gpr(t1
, rt
);
20738 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20739 /* PP.LSXS instructions require shifting */
20740 switch (extract32(ctx
->opcode
, 7, 4)) {
20746 tcg_gen_shli_tl(t0
, t0
, 1);
20754 tcg_gen_shli_tl(t0
, t0
, 2);
20758 tcg_gen_shli_tl(t0
, t0
, 3);
20762 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20764 switch (extract32(ctx
->opcode
, 7, 4)) {
20766 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20768 gen_store_gpr(t0
, rd
);
20772 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20774 gen_store_gpr(t0
, rd
);
20778 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20780 gen_store_gpr(t0
, rd
);
20783 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20785 gen_store_gpr(t0
, rd
);
20789 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20791 gen_store_gpr(t0
, rd
);
20795 gen_load_gpr(t1
, rd
);
20796 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20802 gen_load_gpr(t1
, rd
);
20803 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20809 gen_load_gpr(t1
, rd
);
20810 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20814 /*case NM_LWC1XS:*/
20816 /*case NM_LDC1XS:*/
20818 /*case NM_SWC1XS:*/
20820 /*case NM_SDC1XS:*/
20821 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20822 check_cp1_enabled(ctx
);
20823 switch (extract32(ctx
->opcode
, 7, 4)) {
20825 /*case NM_LWC1XS:*/
20826 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20829 /*case NM_LDC1XS:*/
20830 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20833 /*case NM_SWC1XS:*/
20834 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20837 /*case NM_SDC1XS:*/
20838 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20842 generate_exception_err(ctx
, EXCP_CpU
, 1);
20846 gen_reserved_instruction(ctx
);
20854 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20858 rt
= extract32(ctx
->opcode
, 21, 5);
20859 rs
= extract32(ctx
->opcode
, 16, 5);
20860 rd
= extract32(ctx
->opcode
, 11, 5);
20862 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20863 gen_reserved_instruction(ctx
);
20866 check_cp1_enabled(ctx
);
20867 switch (extract32(ctx
->opcode
, 0, 3)) {
20869 switch (extract32(ctx
->opcode
, 3, 7)) {
20871 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20874 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20877 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20880 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20883 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20886 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20889 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20892 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20895 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20898 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20901 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20904 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20907 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20910 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20913 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20916 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20919 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20922 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20925 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20928 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20931 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20934 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20937 gen_reserved_instruction(ctx
);
20942 switch (extract32(ctx
->opcode
, 3, 3)) {
20944 switch (extract32(ctx
->opcode
, 9, 1)) {
20946 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
20949 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
20954 switch (extract32(ctx
->opcode
, 9, 1)) {
20956 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
20959 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
20964 switch (extract32(ctx
->opcode
, 9, 1)) {
20966 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
20969 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
20974 switch (extract32(ctx
->opcode
, 9, 1)) {
20976 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
20979 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
20984 switch (extract32(ctx
->opcode
, 6, 8)) {
20986 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
20989 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
20992 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
20995 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
20998 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
21001 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
21004 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
21007 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
21010 switch (extract32(ctx
->opcode
, 6, 9)) {
21012 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
21015 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
21018 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
21021 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
21024 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
21027 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
21030 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
21033 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
21036 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
21039 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
21042 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
21045 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
21048 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
21051 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
21054 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
21057 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
21060 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
21063 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
21066 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
21069 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
21072 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
21075 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
21078 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
21081 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
21084 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
21087 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
21090 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
21093 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
21096 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
21099 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
21102 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
21105 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
21108 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
21111 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
21114 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
21117 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
21120 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
21123 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
21126 gen_reserved_instruction(ctx
);
21135 switch (extract32(ctx
->opcode
, 3, 3)) {
21136 case NM_CMP_CONDN_S
:
21137 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
21139 case NM_CMP_CONDN_D
:
21140 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
21143 gen_reserved_instruction(ctx
);
21148 gen_reserved_instruction(ctx
);
21153 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
21154 int rd
, int rs
, int rt
)
21157 TCGv t0
= tcg_temp_new();
21158 TCGv v1_t
= tcg_temp_new();
21159 TCGv v2_t
= tcg_temp_new();
21161 gen_load_gpr(v1_t
, rs
);
21162 gen_load_gpr(v2_t
, rt
);
21167 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
21171 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
21175 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
21177 case NM_CMPU_EQ_QB
:
21179 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
21181 case NM_CMPU_LT_QB
:
21183 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
21185 case NM_CMPU_LE_QB
:
21187 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
21189 case NM_CMPGU_EQ_QB
:
21191 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
21192 gen_store_gpr(v1_t
, ret
);
21194 case NM_CMPGU_LT_QB
:
21196 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
21197 gen_store_gpr(v1_t
, ret
);
21199 case NM_CMPGU_LE_QB
:
21201 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
21202 gen_store_gpr(v1_t
, ret
);
21204 case NM_CMPGDU_EQ_QB
:
21206 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
21207 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21208 gen_store_gpr(v1_t
, ret
);
21210 case NM_CMPGDU_LT_QB
:
21212 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
21213 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21214 gen_store_gpr(v1_t
, ret
);
21216 case NM_CMPGDU_LE_QB
:
21218 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
21219 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
21220 gen_store_gpr(v1_t
, ret
);
21224 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
21225 gen_store_gpr(v1_t
, ret
);
21229 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21230 gen_store_gpr(v1_t
, ret
);
21234 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21235 gen_store_gpr(v1_t
, ret
);
21239 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21240 gen_store_gpr(v1_t
, ret
);
21244 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21245 gen_store_gpr(v1_t
, ret
);
21249 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
21250 gen_store_gpr(v1_t
, ret
);
21254 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
21255 gen_store_gpr(v1_t
, ret
);
21259 switch (extract32(ctx
->opcode
, 10, 1)) {
21262 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21263 gen_store_gpr(v1_t
, ret
);
21267 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21268 gen_store_gpr(v1_t
, ret
);
21272 case NM_ADDQH_R_PH
:
21274 switch (extract32(ctx
->opcode
, 10, 1)) {
21277 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
21278 gen_store_gpr(v1_t
, ret
);
21282 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
21283 gen_store_gpr(v1_t
, ret
);
21289 switch (extract32(ctx
->opcode
, 10, 1)) {
21292 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
21293 gen_store_gpr(v1_t
, ret
);
21297 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
21298 gen_store_gpr(v1_t
, ret
);
21304 switch (extract32(ctx
->opcode
, 10, 1)) {
21307 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21308 gen_store_gpr(v1_t
, ret
);
21312 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21313 gen_store_gpr(v1_t
, ret
);
21319 switch (extract32(ctx
->opcode
, 10, 1)) {
21322 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21323 gen_store_gpr(v1_t
, ret
);
21327 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21328 gen_store_gpr(v1_t
, ret
);
21332 case NM_ADDUH_R_QB
:
21334 switch (extract32(ctx
->opcode
, 10, 1)) {
21337 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
21338 gen_store_gpr(v1_t
, ret
);
21342 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
21343 gen_store_gpr(v1_t
, ret
);
21347 case NM_SHRAV_R_PH
:
21349 switch (extract32(ctx
->opcode
, 10, 1)) {
21352 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
21353 gen_store_gpr(v1_t
, ret
);
21357 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
21358 gen_store_gpr(v1_t
, ret
);
21362 case NM_SHRAV_R_QB
:
21364 switch (extract32(ctx
->opcode
, 10, 1)) {
21367 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
21368 gen_store_gpr(v1_t
, ret
);
21372 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
21373 gen_store_gpr(v1_t
, ret
);
21379 switch (extract32(ctx
->opcode
, 10, 1)) {
21382 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21383 gen_store_gpr(v1_t
, ret
);
21387 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21388 gen_store_gpr(v1_t
, ret
);
21392 case NM_SUBQH_R_PH
:
21394 switch (extract32(ctx
->opcode
, 10, 1)) {
21397 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
21398 gen_store_gpr(v1_t
, ret
);
21402 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
21403 gen_store_gpr(v1_t
, ret
);
21409 switch (extract32(ctx
->opcode
, 10, 1)) {
21412 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
21413 gen_store_gpr(v1_t
, ret
);
21417 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
21418 gen_store_gpr(v1_t
, ret
);
21424 switch (extract32(ctx
->opcode
, 10, 1)) {
21427 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21428 gen_store_gpr(v1_t
, ret
);
21432 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21433 gen_store_gpr(v1_t
, ret
);
21439 switch (extract32(ctx
->opcode
, 10, 1)) {
21442 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21443 gen_store_gpr(v1_t
, ret
);
21447 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21448 gen_store_gpr(v1_t
, ret
);
21452 case NM_SUBUH_R_QB
:
21454 switch (extract32(ctx
->opcode
, 10, 1)) {
21457 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
21458 gen_store_gpr(v1_t
, ret
);
21462 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
21463 gen_store_gpr(v1_t
, ret
);
21467 case NM_SHLLV_S_PH
:
21469 switch (extract32(ctx
->opcode
, 10, 1)) {
21472 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21473 gen_store_gpr(v1_t
, ret
);
21477 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21478 gen_store_gpr(v1_t
, ret
);
21482 case NM_PRECR_SRA_R_PH_W
:
21484 switch (extract32(ctx
->opcode
, 10, 1)) {
21486 /* PRECR_SRA_PH_W */
21488 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21489 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
21491 gen_store_gpr(v1_t
, rt
);
21492 tcg_temp_free_i32(sa_t
);
21496 /* PRECR_SRA_R_PH_W */
21498 TCGv_i32 sa_t
= tcg_const_i32(rd
);
21499 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
21501 gen_store_gpr(v1_t
, rt
);
21502 tcg_temp_free_i32(sa_t
);
21507 case NM_MULEU_S_PH_QBL
:
21509 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
21510 gen_store_gpr(v1_t
, ret
);
21512 case NM_MULEU_S_PH_QBR
:
21514 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
21515 gen_store_gpr(v1_t
, ret
);
21517 case NM_MULQ_RS_PH
:
21519 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21520 gen_store_gpr(v1_t
, ret
);
21524 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21525 gen_store_gpr(v1_t
, ret
);
21529 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21530 gen_store_gpr(v1_t
, ret
);
21534 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21535 gen_store_gpr(v1_t
, ret
);
21539 gen_load_gpr(t0
, rs
);
21541 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
21543 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21547 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
21548 gen_store_gpr(v1_t
, ret
);
21552 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
21553 gen_store_gpr(v1_t
, ret
);
21557 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
21558 gen_store_gpr(v1_t
, ret
);
21562 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21563 gen_store_gpr(v1_t
, ret
);
21567 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21568 gen_store_gpr(v1_t
, ret
);
21572 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21573 gen_store_gpr(v1_t
, ret
);
21578 TCGv tv0
= tcg_temp_new();
21579 TCGv tv1
= tcg_temp_new();
21580 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21582 tcg_gen_movi_tl(tv0
, rd
>> 3);
21583 tcg_gen_movi_tl(tv1
, imm
);
21584 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21587 case NM_MULEQ_S_W_PHL
:
21589 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21590 gen_store_gpr(v1_t
, ret
);
21592 case NM_MULEQ_S_W_PHR
:
21594 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21595 gen_store_gpr(v1_t
, ret
);
21599 switch (extract32(ctx
->opcode
, 10, 1)) {
21602 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21603 gen_store_gpr(v1_t
, ret
);
21607 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21608 gen_store_gpr(v1_t
, ret
);
21612 case NM_PRECR_QB_PH
:
21614 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21615 gen_store_gpr(v1_t
, ret
);
21617 case NM_PRECRQ_QB_PH
:
21619 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21620 gen_store_gpr(v1_t
, ret
);
21622 case NM_PRECRQ_PH_W
:
21624 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21625 gen_store_gpr(v1_t
, ret
);
21627 case NM_PRECRQ_RS_PH_W
:
21629 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21630 gen_store_gpr(v1_t
, ret
);
21632 case NM_PRECRQU_S_QB_PH
:
21634 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21635 gen_store_gpr(v1_t
, ret
);
21639 tcg_gen_movi_tl(t0
, rd
);
21640 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21641 gen_store_gpr(v1_t
, rt
);
21645 tcg_gen_movi_tl(t0
, rd
>> 1);
21646 switch (extract32(ctx
->opcode
, 10, 1)) {
21649 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21650 gen_store_gpr(v1_t
, rt
);
21654 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21655 gen_store_gpr(v1_t
, rt
);
21661 tcg_gen_movi_tl(t0
, rd
>> 1);
21662 switch (extract32(ctx
->opcode
, 10, 2)) {
21665 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21666 gen_store_gpr(v1_t
, rt
);
21670 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21671 gen_store_gpr(v1_t
, rt
);
21674 gen_reserved_instruction(ctx
);
21680 tcg_gen_movi_tl(t0
, rd
);
21681 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21682 gen_store_gpr(v1_t
, rt
);
21688 imm
= sextract32(ctx
->opcode
, 11, 11);
21689 imm
= (int16_t)(imm
<< 6) >> 6;
21691 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21696 gen_reserved_instruction(ctx
);
21701 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21709 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
21710 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21712 rt
= extract32(ctx
->opcode
, 21, 5);
21713 rs
= extract32(ctx
->opcode
, 16, 5);
21714 rd
= extract32(ctx
->opcode
, 11, 5);
21716 op
= extract32(ctx
->opcode
, 26, 6);
21721 switch (extract32(ctx
->opcode
, 19, 2)) {
21724 gen_reserved_instruction(ctx
);
21727 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21728 generate_exception_end(ctx
, EXCP_SYSCALL
);
21730 gen_reserved_instruction(ctx
);
21734 generate_exception_end(ctx
, EXCP_BREAK
);
21737 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21738 gen_helper_do_semihosting(cpu_env
);
21740 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21741 gen_reserved_instruction(ctx
);
21743 generate_exception_end(ctx
, EXCP_DBp
);
21750 imm
= extract32(ctx
->opcode
, 0, 16);
21752 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21754 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21756 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21761 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21762 extract32(ctx
->opcode
, 1, 20) << 1;
21763 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21764 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21768 switch (ctx
->opcode
& 0x07) {
21770 gen_pool32a0_nanomips_insn(env
, ctx
);
21774 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21775 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21779 switch (extract32(ctx
->opcode
, 3, 3)) {
21781 gen_p_lsx(ctx
, rd
, rs
, rt
);
21785 * In nanoMIPS, the shift field directly encodes the shift
21786 * amount, meaning that the supported shift values are in
21787 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21789 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
21790 extract32(ctx
->opcode
, 9, 2) - 1);
21793 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21796 gen_pool32axf_nanomips_insn(env
, ctx
);
21799 gen_reserved_instruction(ctx
);
21804 gen_reserved_instruction(ctx
);
21809 switch (ctx
->opcode
& 0x03) {
21812 offset
= extract32(ctx
->opcode
, 0, 21);
21813 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21817 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21820 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21823 gen_reserved_instruction(ctx
);
21829 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 4);
21830 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21831 switch (extract32(ctx
->opcode
, 16, 5)) {
21835 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21841 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21842 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21848 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21854 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21857 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21864 t0
= tcg_temp_new();
21866 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21869 tcg_gen_movi_tl(t0
, addr
);
21870 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21878 t0
= tcg_temp_new();
21879 t1
= tcg_temp_new();
21881 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21884 tcg_gen_movi_tl(t0
, addr
);
21885 gen_load_gpr(t1
, rt
);
21887 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21894 gen_reserved_instruction(ctx
);
21900 switch (extract32(ctx
->opcode
, 12, 4)) {
21902 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21905 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21908 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21911 switch (extract32(ctx
->opcode
, 20, 1)) {
21913 switch (ctx
->opcode
& 3) {
21915 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21916 extract32(ctx
->opcode
, 2, 1),
21917 extract32(ctx
->opcode
, 3, 9) << 3);
21920 case NM_RESTORE_JRC
:
21921 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21922 extract32(ctx
->opcode
, 2, 1),
21923 extract32(ctx
->opcode
, 3, 9) << 3);
21924 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21925 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21929 gen_reserved_instruction(ctx
);
21934 gen_reserved_instruction(ctx
);
21939 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21942 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21946 TCGv t0
= tcg_temp_new();
21948 imm
= extract32(ctx
->opcode
, 0, 12);
21949 gen_load_gpr(t0
, rs
);
21950 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
21951 gen_store_gpr(t0
, rt
);
21957 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
21958 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
21962 int shift
= extract32(ctx
->opcode
, 0, 5);
21963 switch (extract32(ctx
->opcode
, 5, 4)) {
21965 if (rt
== 0 && shift
== 0) {
21967 } else if (rt
== 0 && shift
== 3) {
21968 /* EHB - treat as NOP */
21969 } else if (rt
== 0 && shift
== 5) {
21970 /* PAUSE - treat as NOP */
21971 } else if (rt
== 0 && shift
== 6) {
21973 gen_sync(extract32(ctx
->opcode
, 16, 5));
21976 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
21977 extract32(ctx
->opcode
, 0, 5));
21981 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
21982 extract32(ctx
->opcode
, 0, 5));
21985 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
21986 extract32(ctx
->opcode
, 0, 5));
21989 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
21990 extract32(ctx
->opcode
, 0, 5));
21998 TCGv t0
= tcg_temp_new();
21999 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
22000 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
22002 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
22004 gen_load_gpr(t0
, rs
);
22005 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
22008 tcg_temp_free_i32(shift
);
22009 tcg_temp_free_i32(shiftx
);
22010 tcg_temp_free_i32(stripe
);
22014 switch (((ctx
->opcode
>> 10) & 2) |
22015 (extract32(ctx
->opcode
, 5, 1))) {
22018 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
22019 extract32(ctx
->opcode
, 6, 5));
22022 gen_reserved_instruction(ctx
);
22027 switch (((ctx
->opcode
>> 10) & 2) |
22028 (extract32(ctx
->opcode
, 5, 1))) {
22031 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
22032 extract32(ctx
->opcode
, 6, 5));
22035 gen_reserved_instruction(ctx
);
22040 gen_reserved_instruction(ctx
);
22045 gen_pool32f_nanomips_insn(ctx
);
22050 switch (extract32(ctx
->opcode
, 1, 1)) {
22053 tcg_gen_movi_tl(cpu_gpr
[rt
],
22054 sextract32(ctx
->opcode
, 0, 1) << 31 |
22055 extract32(ctx
->opcode
, 2, 10) << 21 |
22056 extract32(ctx
->opcode
, 12, 9) << 12);
22061 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
22062 extract32(ctx
->opcode
, 2, 10) << 21 |
22063 extract32(ctx
->opcode
, 12, 9) << 12;
22065 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
22066 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
22073 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
22075 switch (extract32(ctx
->opcode
, 18, 3)) {
22077 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
22080 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
22083 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
22087 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
22092 switch (ctx
->opcode
& 1) {
22094 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
22097 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
22103 switch (ctx
->opcode
& 1) {
22105 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
22108 gen_reserved_instruction(ctx
);
22114 switch (ctx
->opcode
& 0x3) {
22116 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
22119 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
22122 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
22125 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
22130 gen_reserved_instruction(ctx
);
22137 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
22139 switch (extract32(ctx
->opcode
, 12, 4)) {
22144 * Break the TB to be able to sync copied instructions
22147 ctx
->base
.is_jmp
= DISAS_STOP
;
22150 /* Treat as NOP. */
22154 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
22157 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
22160 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
22163 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
22166 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
22169 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
22172 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
22175 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
22178 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
22181 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
22184 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
22187 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
22190 gen_reserved_instruction(ctx
);
22197 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
22198 extract32(ctx
->opcode
, 0, 8);
22200 switch (extract32(ctx
->opcode
, 8, 3)) {
22202 switch (extract32(ctx
->opcode
, 11, 4)) {
22204 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
22207 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
22210 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
22213 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
22216 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
22219 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
22222 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
22225 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
22228 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
22231 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
22234 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
22237 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
22243 * Break the TB to be able to sync copied instructions
22246 ctx
->base
.is_jmp
= DISAS_STOP
;
22249 /* Treat as NOP. */
22253 gen_reserved_instruction(ctx
);
22258 switch (extract32(ctx
->opcode
, 11, 4)) {
22263 TCGv t0
= tcg_temp_new();
22264 TCGv t1
= tcg_temp_new();
22266 gen_base_offset_addr(ctx
, t0
, rs
, s
);
22268 switch (extract32(ctx
->opcode
, 11, 4)) {
22270 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
22272 gen_store_gpr(t0
, rt
);
22275 gen_load_gpr(t1
, rt
);
22276 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
22285 switch (ctx
->opcode
& 0x03) {
22287 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
22291 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22296 switch (ctx
->opcode
& 0x03) {
22298 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
22302 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22308 check_cp0_enabled(ctx
);
22309 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
22310 gen_cache_operation(ctx
, rt
, rs
, s
);
22316 switch (extract32(ctx
->opcode
, 11, 4)) {
22319 check_cp0_enabled(ctx
);
22320 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
22324 check_cp0_enabled(ctx
);
22325 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
22329 check_cp0_enabled(ctx
);
22330 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
22334 /* case NM_SYNCIE */
22336 check_cp0_enabled(ctx
);
22338 * Break the TB to be able to sync copied instructions
22341 ctx
->base
.is_jmp
= DISAS_STOP
;
22343 /* case NM_PREFE */
22345 check_cp0_enabled(ctx
);
22346 /* Treat as NOP. */
22351 check_cp0_enabled(ctx
);
22352 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
22356 check_cp0_enabled(ctx
);
22357 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
22361 check_cp0_enabled(ctx
);
22362 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
22365 check_nms_dl_il_sl_tl_l2c(ctx
);
22366 gen_cache_operation(ctx
, rt
, rs
, s
);
22370 check_cp0_enabled(ctx
);
22371 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
22375 check_cp0_enabled(ctx
);
22376 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
22379 switch (extract32(ctx
->opcode
, 2, 2)) {
22383 check_cp0_enabled(ctx
);
22384 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
22389 check_cp0_enabled(ctx
);
22390 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
22393 gen_reserved_instruction(ctx
);
22398 switch (extract32(ctx
->opcode
, 2, 2)) {
22402 check_cp0_enabled(ctx
);
22403 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
22408 check_cp0_enabled(ctx
);
22409 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
22413 gen_reserved_instruction(ctx
);
22423 int count
= extract32(ctx
->opcode
, 12, 3);
22426 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
22427 extract32(ctx
->opcode
, 0, 8);
22428 TCGv va
= tcg_temp_new();
22429 TCGv t1
= tcg_temp_new();
22430 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
22431 NM_P_LS_UAWM
? MO_UNALN
: 0;
22433 count
= (count
== 0) ? 8 : count
;
22434 while (counter
!= count
) {
22435 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
22436 int this_offset
= offset
+ (counter
<< 2);
22438 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
22440 switch (extract32(ctx
->opcode
, 11, 1)) {
22442 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
22444 gen_store_gpr(t1
, this_rt
);
22445 if ((this_rt
== rs
) &&
22446 (counter
!= (count
- 1))) {
22447 /* UNPREDICTABLE */
22451 this_rt
= (rt
== 0) ? 0 : this_rt
;
22452 gen_load_gpr(t1
, this_rt
);
22453 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
22464 gen_reserved_instruction(ctx
);
22472 TCGv t0
= tcg_temp_new();
22473 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
22474 extract32(ctx
->opcode
, 1, 20) << 1;
22475 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
22476 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
22477 extract32(ctx
->opcode
, 21, 3));
22478 gen_load_gpr(t0
, rt
);
22479 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22480 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22486 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
22487 extract32(ctx
->opcode
, 1, 24) << 1;
22489 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
22491 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
22494 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
22499 switch (extract32(ctx
->opcode
, 12, 4)) {
22502 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
22505 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
22508 gen_reserved_instruction(ctx
);
22514 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22515 extract32(ctx
->opcode
, 1, 13) << 1;
22516 switch (extract32(ctx
->opcode
, 14, 2)) {
22519 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
22522 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22523 extract32(ctx
->opcode
, 1, 13) << 1;
22524 check_cp1_enabled(ctx
);
22525 switch (extract32(ctx
->opcode
, 16, 5)) {
22527 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
22530 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
22535 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
22536 extract32(ctx
->opcode
, 0, 1) << 13;
22538 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
22543 gen_reserved_instruction(ctx
);
22549 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
22551 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
22555 if (rs
== rt
|| rt
== 0) {
22556 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
22557 } else if (rs
== 0) {
22558 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
22560 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22568 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22569 extract32(ctx
->opcode
, 1, 13) << 1;
22570 switch (extract32(ctx
->opcode
, 14, 2)) {
22573 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22576 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22578 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22580 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22584 if (rs
== 0 || rs
== rt
) {
22586 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22588 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22592 gen_reserved_instruction(ctx
);
22599 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22600 extract32(ctx
->opcode
, 1, 10) << 1;
22601 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22603 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22608 gen_reserved_instruction(ctx
);
22614 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22617 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22618 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22619 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22623 /* make sure instructions are on a halfword boundary */
22624 if (ctx
->base
.pc_next
& 0x1) {
22625 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22626 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22627 tcg_temp_free(tmp
);
22628 generate_exception_end(ctx
, EXCP_AdEL
);
22632 op
= extract32(ctx
->opcode
, 10, 6);
22635 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22638 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22639 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22642 switch (extract32(ctx
->opcode
, 3, 2)) {
22643 case NM_P16_SYSCALL
:
22644 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22645 generate_exception_end(ctx
, EXCP_SYSCALL
);
22647 gen_reserved_instruction(ctx
);
22651 generate_exception_end(ctx
, EXCP_BREAK
);
22654 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22655 gen_helper_do_semihosting(cpu_env
);
22657 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22658 gen_reserved_instruction(ctx
);
22660 generate_exception_end(ctx
, EXCP_DBp
);
22665 gen_reserved_instruction(ctx
);
22672 int shift
= extract32(ctx
->opcode
, 0, 3);
22674 shift
= (shift
== 0) ? 8 : shift
;
22676 switch (extract32(ctx
->opcode
, 3, 1)) {
22684 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22688 switch (ctx
->opcode
& 1) {
22690 gen_pool16c_nanomips_insn(ctx
);
22693 gen_ldxs(ctx
, rt
, rs
, rd
);
22698 switch (extract32(ctx
->opcode
, 6, 1)) {
22700 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22701 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22704 gen_reserved_instruction(ctx
);
22709 switch (extract32(ctx
->opcode
, 3, 1)) {
22711 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22712 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22714 case NM_P_ADDIURS5
:
22715 rt
= extract32(ctx
->opcode
, 5, 5);
22717 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22718 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22719 (extract32(ctx
->opcode
, 0, 3));
22720 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22726 switch (ctx
->opcode
& 0x1) {
22728 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22731 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22736 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22737 extract32(ctx
->opcode
, 5, 3);
22738 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22739 extract32(ctx
->opcode
, 0, 3);
22740 rt
= decode_gpr_gpr4(rt
);
22741 rs
= decode_gpr_gpr4(rs
);
22742 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22743 (extract32(ctx
->opcode
, 3, 1))) {
22746 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22750 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22753 gen_reserved_instruction(ctx
);
22759 int imm
= extract32(ctx
->opcode
, 0, 7);
22760 imm
= (imm
== 0x7f ? -1 : imm
);
22762 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22768 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22769 u
= (u
== 12) ? 0xff :
22770 (u
== 13) ? 0xffff : u
;
22771 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22775 offset
= extract32(ctx
->opcode
, 0, 2);
22776 switch (extract32(ctx
->opcode
, 2, 2)) {
22778 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22781 rt
= decode_gpr_gpr3_src_store(
22782 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22783 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22786 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22789 gen_reserved_instruction(ctx
);
22794 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22795 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22797 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22800 rt
= decode_gpr_gpr3_src_store(
22801 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22802 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22805 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22808 gen_reserved_instruction(ctx
);
22813 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22814 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22817 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22818 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22819 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22823 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22824 extract32(ctx
->opcode
, 5, 3);
22825 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22826 extract32(ctx
->opcode
, 0, 3);
22827 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22828 (extract32(ctx
->opcode
, 8, 1) << 2);
22829 rt
= decode_gpr_gpr4(rt
);
22830 rs
= decode_gpr_gpr4(rs
);
22831 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22835 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22836 extract32(ctx
->opcode
, 5, 3);
22837 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22838 extract32(ctx
->opcode
, 0, 3);
22839 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22840 (extract32(ctx
->opcode
, 8, 1) << 2);
22841 rt
= decode_gpr_gpr4_zero(rt
);
22842 rs
= decode_gpr_gpr4(rs
);
22843 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22846 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22847 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22850 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22851 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22852 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22855 rt
= decode_gpr_gpr3_src_store(
22856 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22857 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22858 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22859 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22862 rt
= decode_gpr_gpr3_src_store(
22863 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22864 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22865 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22868 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22869 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22870 (extract32(ctx
->opcode
, 1, 9) << 1));
22873 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22874 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22875 (extract32(ctx
->opcode
, 1, 9) << 1));
22878 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22879 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22880 (extract32(ctx
->opcode
, 1, 6) << 1));
22883 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22884 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22885 (extract32(ctx
->opcode
, 1, 6) << 1));
22888 switch (ctx
->opcode
& 0xf) {
22891 switch (extract32(ctx
->opcode
, 4, 1)) {
22893 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22894 extract32(ctx
->opcode
, 5, 5), 0, 0);
22897 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22898 extract32(ctx
->opcode
, 5, 5), 31, 0);
22905 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22906 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22907 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22908 extract32(ctx
->opcode
, 0, 4) << 1);
22915 int count
= extract32(ctx
->opcode
, 0, 4);
22916 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22918 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22919 switch (extract32(ctx
->opcode
, 8, 1)) {
22921 gen_save(ctx
, rt
, count
, 0, u
);
22923 case NM_RESTORE_JRC16
:
22924 gen_restore(ctx
, rt
, count
, 0, u
);
22925 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22934 static const int gpr2reg1
[] = {4, 5, 6, 7};
22935 static const int gpr2reg2
[] = {5, 6, 7, 8};
22937 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22938 extract32(ctx
->opcode
, 8, 1);
22939 int r1
= gpr2reg1
[rd2
];
22940 int r2
= gpr2reg2
[rd2
];
22941 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22942 extract32(ctx
->opcode
, 0, 3);
22943 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22944 extract32(ctx
->opcode
, 5, 3);
22945 TCGv t0
= tcg_temp_new();
22946 TCGv t1
= tcg_temp_new();
22947 if (op
== NM_MOVEP
) {
22950 rs
= decode_gpr_gpr4_zero(r3
);
22951 rt
= decode_gpr_gpr4_zero(r4
);
22953 rd
= decode_gpr_gpr4(r3
);
22954 re
= decode_gpr_gpr4(r4
);
22958 gen_load_gpr(t0
, rs
);
22959 gen_load_gpr(t1
, rt
);
22960 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22961 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
22967 return decode_nanomips_32_48_opc(env
, ctx
);
22974 /* SmartMIPS extension to MIPS32 */
22976 #if defined(TARGET_MIPS64)
22978 /* MDMX extension to MIPS64 */
22982 /* MIPSDSP functions. */
22983 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
22984 int rd
, int base
, int offset
)
22989 t0
= tcg_temp_new();
22992 gen_load_gpr(t0
, offset
);
22993 } else if (offset
== 0) {
22994 gen_load_gpr(t0
, base
);
22996 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
23001 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
23002 gen_store_gpr(t0
, rd
);
23005 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
23006 gen_store_gpr(t0
, rd
);
23009 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
23010 gen_store_gpr(t0
, rd
);
23012 #if defined(TARGET_MIPS64)
23014 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
23015 gen_store_gpr(t0
, rd
);
23022 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23023 int ret
, int v1
, int v2
)
23029 /* Treat as NOP. */
23033 v1_t
= tcg_temp_new();
23034 v2_t
= tcg_temp_new();
23036 gen_load_gpr(v1_t
, v1
);
23037 gen_load_gpr(v2_t
, v2
);
23040 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
23041 case OPC_MULT_G_2E
:
23045 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23047 case OPC_ADDUH_R_QB
:
23048 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23051 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23053 case OPC_ADDQH_R_PH
:
23054 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23057 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23059 case OPC_ADDQH_R_W
:
23060 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23063 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23065 case OPC_SUBUH_R_QB
:
23066 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23069 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23071 case OPC_SUBQH_R_PH
:
23072 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23075 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23077 case OPC_SUBQH_R_W
:
23078 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23082 case OPC_ABSQ_S_PH_DSP
:
23084 case OPC_ABSQ_S_QB
:
23086 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
23088 case OPC_ABSQ_S_PH
:
23090 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
23094 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
23096 case OPC_PRECEQ_W_PHL
:
23098 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
23099 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23101 case OPC_PRECEQ_W_PHR
:
23103 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
23104 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
23105 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23107 case OPC_PRECEQU_PH_QBL
:
23109 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
23111 case OPC_PRECEQU_PH_QBR
:
23113 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
23115 case OPC_PRECEQU_PH_QBLA
:
23117 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
23119 case OPC_PRECEQU_PH_QBRA
:
23121 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
23123 case OPC_PRECEU_PH_QBL
:
23125 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
23127 case OPC_PRECEU_PH_QBR
:
23129 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
23131 case OPC_PRECEU_PH_QBLA
:
23133 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
23135 case OPC_PRECEU_PH_QBRA
:
23137 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
23141 case OPC_ADDU_QB_DSP
:
23145 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23147 case OPC_ADDQ_S_PH
:
23149 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23153 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23157 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23159 case OPC_ADDU_S_QB
:
23161 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23165 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23167 case OPC_ADDU_S_PH
:
23169 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23173 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23175 case OPC_SUBQ_S_PH
:
23177 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23181 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23185 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23187 case OPC_SUBU_S_QB
:
23189 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23193 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23195 case OPC_SUBU_S_PH
:
23197 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23201 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23205 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23209 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
23211 case OPC_RADDU_W_QB
:
23213 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
23217 case OPC_CMPU_EQ_QB_DSP
:
23219 case OPC_PRECR_QB_PH
:
23221 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23223 case OPC_PRECRQ_QB_PH
:
23225 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23227 case OPC_PRECR_SRA_PH_W
:
23230 TCGv_i32 sa_t
= tcg_const_i32(v2
);
23231 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
23233 tcg_temp_free_i32(sa_t
);
23236 case OPC_PRECR_SRA_R_PH_W
:
23239 TCGv_i32 sa_t
= tcg_const_i32(v2
);
23240 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
23242 tcg_temp_free_i32(sa_t
);
23245 case OPC_PRECRQ_PH_W
:
23247 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23249 case OPC_PRECRQ_RS_PH_W
:
23251 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23253 case OPC_PRECRQU_S_QB_PH
:
23255 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23259 #ifdef TARGET_MIPS64
23260 case OPC_ABSQ_S_QH_DSP
:
23262 case OPC_PRECEQ_L_PWL
:
23264 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
23266 case OPC_PRECEQ_L_PWR
:
23268 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
23270 case OPC_PRECEQ_PW_QHL
:
23272 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
23274 case OPC_PRECEQ_PW_QHR
:
23276 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
23278 case OPC_PRECEQ_PW_QHLA
:
23280 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
23282 case OPC_PRECEQ_PW_QHRA
:
23284 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
23286 case OPC_PRECEQU_QH_OBL
:
23288 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
23290 case OPC_PRECEQU_QH_OBR
:
23292 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
23294 case OPC_PRECEQU_QH_OBLA
:
23296 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
23298 case OPC_PRECEQU_QH_OBRA
:
23300 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
23302 case OPC_PRECEU_QH_OBL
:
23304 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
23306 case OPC_PRECEU_QH_OBR
:
23308 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
23310 case OPC_PRECEU_QH_OBLA
:
23312 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
23314 case OPC_PRECEU_QH_OBRA
:
23316 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
23318 case OPC_ABSQ_S_OB
:
23320 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
23322 case OPC_ABSQ_S_PW
:
23324 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
23326 case OPC_ABSQ_S_QH
:
23328 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
23332 case OPC_ADDU_OB_DSP
:
23334 case OPC_RADDU_L_OB
:
23336 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
23340 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23342 case OPC_SUBQ_S_PW
:
23344 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23348 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23350 case OPC_SUBQ_S_QH
:
23352 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23356 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23358 case OPC_SUBU_S_OB
:
23360 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23364 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23366 case OPC_SUBU_S_QH
:
23368 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23372 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23374 case OPC_SUBUH_R_OB
:
23376 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23380 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23382 case OPC_ADDQ_S_PW
:
23384 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23388 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23390 case OPC_ADDQ_S_QH
:
23392 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23396 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23398 case OPC_ADDU_S_OB
:
23400 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23404 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23406 case OPC_ADDU_S_QH
:
23408 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23412 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23414 case OPC_ADDUH_R_OB
:
23416 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23420 case OPC_CMPU_EQ_OB_DSP
:
23422 case OPC_PRECR_OB_QH
:
23424 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23426 case OPC_PRECR_SRA_QH_PW
:
23429 TCGv_i32 ret_t
= tcg_const_i32(ret
);
23430 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
23431 tcg_temp_free_i32(ret_t
);
23434 case OPC_PRECR_SRA_R_QH_PW
:
23437 TCGv_i32 sa_v
= tcg_const_i32(ret
);
23438 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
23439 tcg_temp_free_i32(sa_v
);
23442 case OPC_PRECRQ_OB_QH
:
23444 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
23446 case OPC_PRECRQ_PW_L
:
23448 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
23450 case OPC_PRECRQ_QH_PW
:
23452 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23454 case OPC_PRECRQ_RS_QH_PW
:
23456 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23458 case OPC_PRECRQU_S_OB_QH
:
23460 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23467 tcg_temp_free(v1_t
);
23468 tcg_temp_free(v2_t
);
23471 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
23472 int ret
, int v1
, int v2
)
23480 /* Treat as NOP. */
23484 t0
= tcg_temp_new();
23485 v1_t
= tcg_temp_new();
23486 v2_t
= tcg_temp_new();
23488 tcg_gen_movi_tl(t0
, v1
);
23489 gen_load_gpr(v1_t
, v1
);
23490 gen_load_gpr(v2_t
, v2
);
23493 case OPC_SHLL_QB_DSP
:
23495 op2
= MASK_SHLL_QB(ctx
->opcode
);
23499 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23503 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23507 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23511 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23513 case OPC_SHLL_S_PH
:
23515 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23517 case OPC_SHLLV_S_PH
:
23519 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23523 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
23525 case OPC_SHLLV_S_W
:
23527 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23531 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
23535 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23539 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
23543 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23547 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
23549 case OPC_SHRA_R_QB
:
23551 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
23555 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23557 case OPC_SHRAV_R_QB
:
23559 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23563 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23565 case OPC_SHRA_R_PH
:
23567 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23571 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23573 case OPC_SHRAV_R_PH
:
23575 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23579 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23581 case OPC_SHRAV_R_W
:
23583 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23585 default: /* Invalid */
23586 MIPS_INVAL("MASK SHLL.QB");
23587 gen_reserved_instruction(ctx
);
23592 #ifdef TARGET_MIPS64
23593 case OPC_SHLL_OB_DSP
:
23594 op2
= MASK_SHLL_OB(ctx
->opcode
);
23598 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23602 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23604 case OPC_SHLL_S_PW
:
23606 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23608 case OPC_SHLLV_S_PW
:
23610 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23614 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23618 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23622 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23626 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23628 case OPC_SHLL_S_QH
:
23630 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23632 case OPC_SHLLV_S_QH
:
23634 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23638 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23642 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23644 case OPC_SHRA_R_OB
:
23646 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23648 case OPC_SHRAV_R_OB
:
23650 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23654 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23658 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23660 case OPC_SHRA_R_PW
:
23662 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23664 case OPC_SHRAV_R_PW
:
23666 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23670 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23674 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23676 case OPC_SHRA_R_QH
:
23678 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23680 case OPC_SHRAV_R_QH
:
23682 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23686 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23690 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23694 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23698 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23700 default: /* Invalid */
23701 MIPS_INVAL("MASK SHLL.OB");
23702 gen_reserved_instruction(ctx
);
23710 tcg_temp_free(v1_t
);
23711 tcg_temp_free(v2_t
);
23714 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23715 int ret
, int v1
, int v2
, int check_ret
)
23721 if ((ret
== 0) && (check_ret
== 1)) {
23722 /* Treat as NOP. */
23726 t0
= tcg_temp_new_i32();
23727 v1_t
= tcg_temp_new();
23728 v2_t
= tcg_temp_new();
23730 tcg_gen_movi_i32(t0
, ret
);
23731 gen_load_gpr(v1_t
, v1
);
23732 gen_load_gpr(v2_t
, v2
);
23736 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23737 * the same mask and op1.
23739 case OPC_MULT_G_2E
:
23743 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23746 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23749 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23751 case OPC_MULQ_RS_W
:
23752 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23756 case OPC_DPA_W_PH_DSP
:
23758 case OPC_DPAU_H_QBL
:
23760 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23762 case OPC_DPAU_H_QBR
:
23764 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23766 case OPC_DPSU_H_QBL
:
23768 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23770 case OPC_DPSU_H_QBR
:
23772 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23776 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23778 case OPC_DPAX_W_PH
:
23780 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23782 case OPC_DPAQ_S_W_PH
:
23784 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23786 case OPC_DPAQX_S_W_PH
:
23788 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23790 case OPC_DPAQX_SA_W_PH
:
23792 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23796 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23798 case OPC_DPSX_W_PH
:
23800 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23802 case OPC_DPSQ_S_W_PH
:
23804 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23806 case OPC_DPSQX_S_W_PH
:
23808 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23810 case OPC_DPSQX_SA_W_PH
:
23812 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23814 case OPC_MULSAQ_S_W_PH
:
23816 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23818 case OPC_DPAQ_SA_L_W
:
23820 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23822 case OPC_DPSQ_SA_L_W
:
23824 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23826 case OPC_MAQ_S_W_PHL
:
23828 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23830 case OPC_MAQ_S_W_PHR
:
23832 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23834 case OPC_MAQ_SA_W_PHL
:
23836 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23838 case OPC_MAQ_SA_W_PHR
:
23840 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23842 case OPC_MULSA_W_PH
:
23844 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23848 #ifdef TARGET_MIPS64
23849 case OPC_DPAQ_W_QH_DSP
:
23851 int ac
= ret
& 0x03;
23852 tcg_gen_movi_i32(t0
, ac
);
23857 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23861 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23865 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23869 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23873 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23875 case OPC_DPAQ_S_W_QH
:
23877 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23879 case OPC_DPAQ_SA_L_PW
:
23881 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23883 case OPC_DPAU_H_OBL
:
23885 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23887 case OPC_DPAU_H_OBR
:
23889 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23893 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23895 case OPC_DPSQ_S_W_QH
:
23897 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23899 case OPC_DPSQ_SA_L_PW
:
23901 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23903 case OPC_DPSU_H_OBL
:
23905 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23907 case OPC_DPSU_H_OBR
:
23909 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23911 case OPC_MAQ_S_L_PWL
:
23913 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23915 case OPC_MAQ_S_L_PWR
:
23917 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23919 case OPC_MAQ_S_W_QHLL
:
23921 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23923 case OPC_MAQ_SA_W_QHLL
:
23925 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23927 case OPC_MAQ_S_W_QHLR
:
23929 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23931 case OPC_MAQ_SA_W_QHLR
:
23933 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23935 case OPC_MAQ_S_W_QHRL
:
23937 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23939 case OPC_MAQ_SA_W_QHRL
:
23941 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23943 case OPC_MAQ_S_W_QHRR
:
23945 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23947 case OPC_MAQ_SA_W_QHRR
:
23949 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23951 case OPC_MULSAQ_S_L_PW
:
23953 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23955 case OPC_MULSAQ_S_W_QH
:
23957 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23963 case OPC_ADDU_QB_DSP
:
23965 case OPC_MULEU_S_PH_QBL
:
23967 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23969 case OPC_MULEU_S_PH_QBR
:
23971 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23973 case OPC_MULQ_RS_PH
:
23975 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23977 case OPC_MULEQ_S_W_PHL
:
23979 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23981 case OPC_MULEQ_S_W_PHR
:
23983 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23985 case OPC_MULQ_S_PH
:
23987 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23991 #ifdef TARGET_MIPS64
23992 case OPC_ADDU_OB_DSP
:
23994 case OPC_MULEQ_S_PW_QHL
:
23996 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23998 case OPC_MULEQ_S_PW_QHR
:
24000 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24002 case OPC_MULEU_S_QH_OBL
:
24004 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24006 case OPC_MULEU_S_QH_OBR
:
24008 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24010 case OPC_MULQ_RS_QH
:
24012 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24019 tcg_temp_free_i32(t0
);
24020 tcg_temp_free(v1_t
);
24021 tcg_temp_free(v2_t
);
24024 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24032 /* Treat as NOP. */
24036 t0
= tcg_temp_new();
24037 val_t
= tcg_temp_new();
24038 gen_load_gpr(val_t
, val
);
24041 case OPC_ABSQ_S_PH_DSP
:
24045 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
24050 target_long result
;
24051 imm
= (ctx
->opcode
>> 16) & 0xFF;
24052 result
= (uint32_t)imm
<< 24 |
24053 (uint32_t)imm
<< 16 |
24054 (uint32_t)imm
<< 8 |
24056 result
= (int32_t)result
;
24057 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
24062 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
24063 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
24064 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24065 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24066 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24067 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
24072 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24073 imm
= (int16_t)(imm
<< 6) >> 6;
24074 tcg_gen_movi_tl(cpu_gpr
[ret
], \
24075 (target_long
)((int32_t)imm
<< 16 | \
24081 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
24082 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24083 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24084 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
24088 #ifdef TARGET_MIPS64
24089 case OPC_ABSQ_S_QH_DSP
:
24096 imm
= (ctx
->opcode
>> 16) & 0xFF;
24097 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
24098 temp
= (temp
<< 16) | temp
;
24099 temp
= (temp
<< 32) | temp
;
24100 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24108 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24109 imm
= (int16_t)(imm
<< 6) >> 6;
24110 temp
= ((target_long
)imm
<< 32) \
24111 | ((target_long
)imm
& 0xFFFFFFFF);
24112 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24120 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24121 imm
= (int16_t)(imm
<< 6) >> 6;
24123 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
24124 ((uint64_t)(uint16_t)imm
<< 32) |
24125 ((uint64_t)(uint16_t)imm
<< 16) |
24126 (uint64_t)(uint16_t)imm
;
24127 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
24132 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
24133 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
24134 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24135 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24136 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24137 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24138 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24142 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
24143 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24144 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24148 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
24149 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
24150 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24151 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
24152 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
24159 tcg_temp_free(val_t
);
24162 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
24163 uint32_t op1
, uint32_t op2
,
24164 int ret
, int v1
, int v2
, int check_ret
)
24170 if ((ret
== 0) && (check_ret
== 1)) {
24171 /* Treat as NOP. */
24175 t1
= tcg_temp_new();
24176 v1_t
= tcg_temp_new();
24177 v2_t
= tcg_temp_new();
24179 gen_load_gpr(v1_t
, v1
);
24180 gen_load_gpr(v2_t
, v2
);
24183 case OPC_CMPU_EQ_QB_DSP
:
24185 case OPC_CMPU_EQ_QB
:
24187 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
24189 case OPC_CMPU_LT_QB
:
24191 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
24193 case OPC_CMPU_LE_QB
:
24195 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
24197 case OPC_CMPGU_EQ_QB
:
24199 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24201 case OPC_CMPGU_LT_QB
:
24203 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24205 case OPC_CMPGU_LE_QB
:
24207 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
24209 case OPC_CMPGDU_EQ_QB
:
24211 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
24212 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24213 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24214 tcg_gen_shli_tl(t1
, t1
, 24);
24215 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24217 case OPC_CMPGDU_LT_QB
:
24219 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
24220 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24221 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24222 tcg_gen_shli_tl(t1
, t1
, 24);
24223 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24225 case OPC_CMPGDU_LE_QB
:
24227 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
24228 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
24229 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
24230 tcg_gen_shli_tl(t1
, t1
, 24);
24231 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
24233 case OPC_CMP_EQ_PH
:
24235 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
24237 case OPC_CMP_LT_PH
:
24239 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
24241 case OPC_CMP_LE_PH
:
24243 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
24247 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24251 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24253 case OPC_PACKRL_PH
:
24255 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
24259 #ifdef TARGET_MIPS64
24260 case OPC_CMPU_EQ_OB_DSP
:
24262 case OPC_CMP_EQ_PW
:
24264 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
24266 case OPC_CMP_LT_PW
:
24268 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
24270 case OPC_CMP_LE_PW
:
24272 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
24274 case OPC_CMP_EQ_QH
:
24276 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
24278 case OPC_CMP_LT_QH
:
24280 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
24282 case OPC_CMP_LE_QH
:
24284 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
24286 case OPC_CMPGDU_EQ_OB
:
24288 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24290 case OPC_CMPGDU_LT_OB
:
24292 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24294 case OPC_CMPGDU_LE_OB
:
24296 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24298 case OPC_CMPGU_EQ_OB
:
24300 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24302 case OPC_CMPGU_LT_OB
:
24304 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24306 case OPC_CMPGU_LE_OB
:
24308 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
24310 case OPC_CMPU_EQ_OB
:
24312 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
24314 case OPC_CMPU_LT_OB
:
24316 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
24318 case OPC_CMPU_LE_OB
:
24320 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
24322 case OPC_PACKRL_PW
:
24324 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
24328 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24332 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24336 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
24344 tcg_temp_free(v1_t
);
24345 tcg_temp_free(v2_t
);
24348 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
24349 uint32_t op1
, int rt
, int rs
, int sa
)
24356 /* Treat as NOP. */
24360 t0
= tcg_temp_new();
24361 gen_load_gpr(t0
, rs
);
24364 case OPC_APPEND_DSP
:
24365 switch (MASK_APPEND(ctx
->opcode
)) {
24368 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
24370 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24374 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24375 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24376 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
24377 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24379 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24383 if (sa
!= 0 && sa
!= 2) {
24384 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24385 tcg_gen_ext32u_tl(t0
, t0
);
24386 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
24387 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24389 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
24391 default: /* Invalid */
24392 MIPS_INVAL("MASK APPEND");
24393 gen_reserved_instruction(ctx
);
24397 #ifdef TARGET_MIPS64
24398 case OPC_DAPPEND_DSP
:
24399 switch (MASK_DAPPEND(ctx
->opcode
)) {
24402 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
24406 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
24407 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
24408 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
24412 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
24413 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
24414 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24419 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
24420 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
24421 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
24422 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
24425 default: /* Invalid */
24426 MIPS_INVAL("MASK DAPPEND");
24427 gen_reserved_instruction(ctx
);
24436 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
24437 int ret
, int v1
, int v2
, int check_ret
)
24446 if ((ret
== 0) && (check_ret
== 1)) {
24447 /* Treat as NOP. */
24451 t0
= tcg_temp_new();
24452 t1
= tcg_temp_new();
24453 v1_t
= tcg_temp_new();
24454 v2_t
= tcg_temp_new();
24456 gen_load_gpr(v1_t
, v1
);
24457 gen_load_gpr(v2_t
, v2
);
24460 case OPC_EXTR_W_DSP
:
24464 tcg_gen_movi_tl(t0
, v2
);
24465 tcg_gen_movi_tl(t1
, v1
);
24466 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24469 tcg_gen_movi_tl(t0
, v2
);
24470 tcg_gen_movi_tl(t1
, v1
);
24471 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24473 case OPC_EXTR_RS_W
:
24474 tcg_gen_movi_tl(t0
, v2
);
24475 tcg_gen_movi_tl(t1
, v1
);
24476 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24479 tcg_gen_movi_tl(t0
, v2
);
24480 tcg_gen_movi_tl(t1
, v1
);
24481 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24483 case OPC_EXTRV_S_H
:
24484 tcg_gen_movi_tl(t0
, v2
);
24485 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24488 tcg_gen_movi_tl(t0
, v2
);
24489 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24491 case OPC_EXTRV_R_W
:
24492 tcg_gen_movi_tl(t0
, v2
);
24493 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24495 case OPC_EXTRV_RS_W
:
24496 tcg_gen_movi_tl(t0
, v2
);
24497 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24500 tcg_gen_movi_tl(t0
, v2
);
24501 tcg_gen_movi_tl(t1
, v1
);
24502 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24505 tcg_gen_movi_tl(t0
, v2
);
24506 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24509 tcg_gen_movi_tl(t0
, v2
);
24510 tcg_gen_movi_tl(t1
, v1
);
24511 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24514 tcg_gen_movi_tl(t0
, v2
);
24515 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24518 imm
= (ctx
->opcode
>> 20) & 0x3F;
24519 tcg_gen_movi_tl(t0
, ret
);
24520 tcg_gen_movi_tl(t1
, imm
);
24521 gen_helper_shilo(t0
, t1
, cpu_env
);
24524 tcg_gen_movi_tl(t0
, ret
);
24525 gen_helper_shilo(t0
, v1_t
, cpu_env
);
24528 tcg_gen_movi_tl(t0
, ret
);
24529 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
24532 imm
= (ctx
->opcode
>> 11) & 0x3FF;
24533 tcg_gen_movi_tl(t0
, imm
);
24534 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
24537 imm
= (ctx
->opcode
>> 16) & 0x03FF;
24538 tcg_gen_movi_tl(t0
, imm
);
24539 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
24543 #ifdef TARGET_MIPS64
24544 case OPC_DEXTR_W_DSP
:
24548 tcg_gen_movi_tl(t0
, ret
);
24549 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
24553 int shift
= (ctx
->opcode
>> 19) & 0x7F;
24554 int ac
= (ctx
->opcode
>> 11) & 0x03;
24555 tcg_gen_movi_tl(t0
, shift
);
24556 tcg_gen_movi_tl(t1
, ac
);
24557 gen_helper_dshilo(t0
, t1
, cpu_env
);
24562 int ac
= (ctx
->opcode
>> 11) & 0x03;
24563 tcg_gen_movi_tl(t0
, ac
);
24564 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24568 tcg_gen_movi_tl(t0
, v2
);
24569 tcg_gen_movi_tl(t1
, v1
);
24571 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24574 tcg_gen_movi_tl(t0
, v2
);
24575 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24578 tcg_gen_movi_tl(t0
, v2
);
24579 tcg_gen_movi_tl(t1
, v1
);
24580 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24583 tcg_gen_movi_tl(t0
, v2
);
24584 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24587 tcg_gen_movi_tl(t0
, v2
);
24588 tcg_gen_movi_tl(t1
, v1
);
24589 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24591 case OPC_DEXTR_R_L
:
24592 tcg_gen_movi_tl(t0
, v2
);
24593 tcg_gen_movi_tl(t1
, v1
);
24594 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24596 case OPC_DEXTR_RS_L
:
24597 tcg_gen_movi_tl(t0
, v2
);
24598 tcg_gen_movi_tl(t1
, v1
);
24599 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24602 tcg_gen_movi_tl(t0
, v2
);
24603 tcg_gen_movi_tl(t1
, v1
);
24604 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24606 case OPC_DEXTR_R_W
:
24607 tcg_gen_movi_tl(t0
, v2
);
24608 tcg_gen_movi_tl(t1
, v1
);
24609 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24611 case OPC_DEXTR_RS_W
:
24612 tcg_gen_movi_tl(t0
, v2
);
24613 tcg_gen_movi_tl(t1
, v1
);
24614 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24616 case OPC_DEXTR_S_H
:
24617 tcg_gen_movi_tl(t0
, v2
);
24618 tcg_gen_movi_tl(t1
, v1
);
24619 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24621 case OPC_DEXTRV_S_H
:
24622 tcg_gen_movi_tl(t0
, v2
);
24623 tcg_gen_movi_tl(t1
, v1
);
24624 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24627 tcg_gen_movi_tl(t0
, v2
);
24628 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24630 case OPC_DEXTRV_R_L
:
24631 tcg_gen_movi_tl(t0
, v2
);
24632 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24634 case OPC_DEXTRV_RS_L
:
24635 tcg_gen_movi_tl(t0
, v2
);
24636 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24639 tcg_gen_movi_tl(t0
, v2
);
24640 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24642 case OPC_DEXTRV_R_W
:
24643 tcg_gen_movi_tl(t0
, v2
);
24644 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24646 case OPC_DEXTRV_RS_W
:
24647 tcg_gen_movi_tl(t0
, v2
);
24648 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24657 tcg_temp_free(v1_t
);
24658 tcg_temp_free(v2_t
);
24661 /* End MIPSDSP functions. */
24663 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24665 int rs
, rt
, rd
, sa
;
24668 rs
= (ctx
->opcode
>> 21) & 0x1f;
24669 rt
= (ctx
->opcode
>> 16) & 0x1f;
24670 rd
= (ctx
->opcode
>> 11) & 0x1f;
24671 sa
= (ctx
->opcode
>> 6) & 0x1f;
24673 op1
= MASK_SPECIAL(ctx
->opcode
);
24676 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24682 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24692 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24695 MIPS_INVAL("special_r6 muldiv");
24696 gen_reserved_instruction(ctx
);
24702 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24706 if (rt
== 0 && sa
== 1) {
24708 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24709 * We need additionally to check other fields.
24711 gen_cl(ctx
, op1
, rd
, rs
);
24713 gen_reserved_instruction(ctx
);
24717 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24718 gen_helper_do_semihosting(cpu_env
);
24720 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24721 gen_reserved_instruction(ctx
);
24723 generate_exception_end(ctx
, EXCP_DBp
);
24727 #if defined(TARGET_MIPS64)
24729 check_mips_64(ctx
);
24730 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24734 if (rt
== 0 && sa
== 1) {
24736 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24737 * We need additionally to check other fields.
24739 check_mips_64(ctx
);
24740 gen_cl(ctx
, op1
, rd
, rs
);
24742 gen_reserved_instruction(ctx
);
24750 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24760 check_mips_64(ctx
);
24761 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24764 MIPS_INVAL("special_r6 muldiv");
24765 gen_reserved_instruction(ctx
);
24770 default: /* Invalid */
24771 MIPS_INVAL("special_r6");
24772 gen_reserved_instruction(ctx
);
24777 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24779 int rs
= extract32(ctx
->opcode
, 21, 5);
24780 int rt
= extract32(ctx
->opcode
, 16, 5);
24781 int rd
= extract32(ctx
->opcode
, 11, 5);
24782 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24785 case OPC_MOVN
: /* Conditional move */
24787 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24789 case OPC_MFHI
: /* Move from HI/LO */
24791 gen_HILO(ctx
, op1
, 0, rd
);
24794 case OPC_MTLO
: /* Move to HI/LO */
24795 gen_HILO(ctx
, op1
, 0, rs
);
24799 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24803 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24805 #if defined(TARGET_MIPS64)
24810 check_insn_opc_user_only(ctx
, INSN_R5900
);
24811 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24815 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24817 default: /* Invalid */
24818 MIPS_INVAL("special_tx79");
24819 gen_reserved_instruction(ctx
);
24824 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24826 int rs
, rt
, rd
, sa
;
24829 rs
= (ctx
->opcode
>> 21) & 0x1f;
24830 rt
= (ctx
->opcode
>> 16) & 0x1f;
24831 rd
= (ctx
->opcode
>> 11) & 0x1f;
24832 sa
= (ctx
->opcode
>> 6) & 0x1f;
24834 op1
= MASK_SPECIAL(ctx
->opcode
);
24836 case OPC_MOVN
: /* Conditional move */
24838 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
|
24839 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24840 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24842 case OPC_MFHI
: /* Move from HI/LO */
24844 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24847 case OPC_MTLO
: /* Move to HI/LO */
24848 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24851 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
24852 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24853 check_cp1_enabled(ctx
);
24854 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24855 (ctx
->opcode
>> 16) & 1);
24857 generate_exception_err(ctx
, EXCP_CpU
, 1);
24863 check_insn(ctx
, INSN_VR54XX
);
24864 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24865 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24867 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24872 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24874 #if defined(TARGET_MIPS64)
24879 check_insn(ctx
, ISA_MIPS3
);
24880 check_mips_64(ctx
);
24881 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24885 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24888 #ifdef MIPS_STRICT_STANDARD
24889 MIPS_INVAL("SPIM");
24890 gen_reserved_instruction(ctx
);
24892 /* Implemented as RI exception for now. */
24893 MIPS_INVAL("spim (unofficial)");
24894 gen_reserved_instruction(ctx
);
24897 default: /* Invalid */
24898 MIPS_INVAL("special_legacy");
24899 gen_reserved_instruction(ctx
);
24904 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24906 int rs
, rt
, rd
, sa
;
24909 rs
= (ctx
->opcode
>> 21) & 0x1f;
24910 rt
= (ctx
->opcode
>> 16) & 0x1f;
24911 rd
= (ctx
->opcode
>> 11) & 0x1f;
24912 sa
= (ctx
->opcode
>> 6) & 0x1f;
24914 op1
= MASK_SPECIAL(ctx
->opcode
);
24916 case OPC_SLL
: /* Shift with immediate */
24917 if (sa
== 5 && rd
== 0 &&
24918 rs
== 0 && rt
== 0) { /* PAUSE */
24919 if ((ctx
->insn_flags
& ISA_MIPS_R6
) &&
24920 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24921 gen_reserved_instruction(ctx
);
24927 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24930 switch ((ctx
->opcode
>> 21) & 0x1f) {
24932 /* rotr is decoded as srl on non-R2 CPUs */
24933 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24938 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24941 gen_reserved_instruction(ctx
);
24949 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24951 case OPC_SLLV
: /* Shifts */
24953 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24956 switch ((ctx
->opcode
>> 6) & 0x1f) {
24958 /* rotrv is decoded as srlv on non-R2 CPUs */
24959 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
24964 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24967 gen_reserved_instruction(ctx
);
24971 case OPC_SLT
: /* Set on less than */
24973 gen_slt(ctx
, op1
, rd
, rs
, rt
);
24975 case OPC_AND
: /* Logic*/
24979 gen_logic(ctx
, op1
, rd
, rs
, rt
);
24982 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24984 case OPC_TGE
: /* Traps */
24990 check_insn(ctx
, ISA_MIPS2
);
24991 gen_trap(ctx
, op1
, rs
, rt
, -1);
24993 case OPC_LSA
: /* OPC_PMON */
24994 if ((ctx
->insn_flags
& ISA_MIPS_R6
) ||
24995 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
24996 decode_opc_special_r6(env
, ctx
);
24998 /* Pmon entry point, also R4010 selsl */
24999 #ifdef MIPS_STRICT_STANDARD
25000 MIPS_INVAL("PMON / selsl");
25001 gen_reserved_instruction(ctx
);
25003 gen_helper_0e0i(pmon
, sa
);
25008 generate_exception_end(ctx
, EXCP_SYSCALL
);
25011 generate_exception_end(ctx
, EXCP_BREAK
);
25014 check_insn(ctx
, ISA_MIPS2
);
25015 gen_sync(extract32(ctx
->opcode
, 6, 5));
25018 #if defined(TARGET_MIPS64)
25019 /* MIPS64 specific opcodes */
25024 check_insn(ctx
, ISA_MIPS3
);
25025 check_mips_64(ctx
);
25026 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
25029 switch ((ctx
->opcode
>> 21) & 0x1f) {
25031 /* drotr is decoded as dsrl on non-R2 CPUs */
25032 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
25037 check_insn(ctx
, ISA_MIPS3
);
25038 check_mips_64(ctx
);
25039 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
25042 gen_reserved_instruction(ctx
);
25047 switch ((ctx
->opcode
>> 21) & 0x1f) {
25049 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
25050 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
25055 check_insn(ctx
, ISA_MIPS3
);
25056 check_mips_64(ctx
);
25057 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
25060 gen_reserved_instruction(ctx
);
25068 check_insn(ctx
, ISA_MIPS3
);
25069 check_mips_64(ctx
);
25070 gen_arith(ctx
, op1
, rd
, rs
, rt
);
25074 check_insn(ctx
, ISA_MIPS3
);
25075 check_mips_64(ctx
);
25076 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25079 switch ((ctx
->opcode
>> 6) & 0x1f) {
25081 /* drotrv is decoded as dsrlv on non-R2 CPUs */
25082 if (ctx
->insn_flags
& ISA_MIPS_R2
) {
25087 check_insn(ctx
, ISA_MIPS3
);
25088 check_mips_64(ctx
);
25089 gen_shift(ctx
, op1
, rd
, rs
, rt
);
25092 gen_reserved_instruction(ctx
);
25097 if ((ctx
->insn_flags
& ISA_MIPS_R6
) ||
25098 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
25099 decode_opc_special_r6(env
, ctx
);
25104 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
25105 decode_opc_special_r6(env
, ctx
);
25106 } else if (ctx
->insn_flags
& INSN_R5900
) {
25107 decode_opc_special_tx79(env
, ctx
);
25109 decode_opc_special_legacy(env
, ctx
);
25115 #if defined(TARGET_MIPS64)
25119 * MMI (MultiMedia Interface) ASE instructions
25120 * ===========================================
25124 * MMI instructions category: data communication
25125 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25127 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
25128 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
25129 * PCPYUD PEXEH PEXTLW PPACW
25138 * Parallel Copy Halfword
25140 * 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
25141 * +-----------+---------+---------+---------+---------+-----------+
25142 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
25143 * +-----------+---------+---------+---------+---------+-----------+
25145 static void gen_mmi_pcpyh(DisasContext
*ctx
)
25147 uint32_t pd
, rt
, rd
;
25150 opcode
= ctx
->opcode
;
25152 pd
= extract32(opcode
, 21, 5);
25153 rt
= extract32(opcode
, 16, 5);
25154 rd
= extract32(opcode
, 11, 5);
25156 if (unlikely(pd
!= 0)) {
25157 gen_reserved_instruction(ctx
);
25158 } else if (rd
== 0) {
25160 } else if (rt
== 0) {
25161 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25162 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25164 TCGv_i64 t0
= tcg_temp_new();
25165 TCGv_i64 t1
= tcg_temp_new();
25166 uint64_t mask
= (1ULL << 16) - 1;
25168 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
25169 tcg_gen_movi_i64(t1
, 0);
25170 tcg_gen_or_i64(t1
, t0
, t1
);
25171 tcg_gen_shli_i64(t0
, t0
, 16);
25172 tcg_gen_or_i64(t1
, t0
, t1
);
25173 tcg_gen_shli_i64(t0
, t0
, 16);
25174 tcg_gen_or_i64(t1
, t0
, t1
);
25175 tcg_gen_shli_i64(t0
, t0
, 16);
25176 tcg_gen_or_i64(t1
, t0
, t1
);
25178 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
25180 tcg_gen_andi_i64(t0
, cpu_mmr
[rt
], mask
);
25181 tcg_gen_movi_i64(t1
, 0);
25182 tcg_gen_or_i64(t1
, t0
, t1
);
25183 tcg_gen_shli_i64(t0
, t0
, 16);
25184 tcg_gen_or_i64(t1
, t0
, t1
);
25185 tcg_gen_shli_i64(t0
, t0
, 16);
25186 tcg_gen_or_i64(t1
, t0
, t1
);
25187 tcg_gen_shli_i64(t0
, t0
, 16);
25188 tcg_gen_or_i64(t1
, t0
, t1
);
25190 tcg_gen_mov_i64(cpu_mmr
[rd
], t1
);
25198 * PCPYLD rd, rs, rt
25200 * Parallel Copy Lower Doubleword
25202 * 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
25203 * +-----------+---------+---------+---------+---------+-----------+
25204 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
25205 * +-----------+---------+---------+---------+---------+-----------+
25207 static void gen_mmi_pcpyld(DisasContext
*ctx
)
25209 uint32_t rs
, rt
, rd
;
25212 opcode
= ctx
->opcode
;
25214 rs
= extract32(opcode
, 21, 5);
25215 rt
= extract32(opcode
, 16, 5);
25216 rd
= extract32(opcode
, 11, 5);
25222 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25224 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_gpr
[rs
]);
25227 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25230 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
25237 * PCPYUD rd, rs, rt
25239 * Parallel Copy Upper Doubleword
25241 * 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
25242 * +-----------+---------+---------+---------+---------+-----------+
25243 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
25244 * +-----------+---------+---------+---------+---------+-----------+
25246 static void gen_mmi_pcpyud(DisasContext
*ctx
)
25248 uint32_t rs
, rt
, rd
;
25251 opcode
= ctx
->opcode
;
25253 rs
= extract32(opcode
, 21, 5);
25254 rt
= extract32(opcode
, 16, 5);
25255 rd
= extract32(opcode
, 11, 5);
25261 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
25263 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_mmr
[rs
]);
25266 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
25269 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_mmr
[rt
]);
25278 #if !defined(TARGET_MIPS64)
25280 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
25281 #define MXU_APTN1_A 0
25282 #define MXU_APTN1_S 1
25284 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
25285 #define MXU_APTN2_AA 0
25286 #define MXU_APTN2_AS 1
25287 #define MXU_APTN2_SA 2
25288 #define MXU_APTN2_SS 3
25290 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
25291 #define MXU_EPTN2_AA 0
25292 #define MXU_EPTN2_AS 1
25293 #define MXU_EPTN2_SA 2
25294 #define MXU_EPTN2_SS 3
25296 /* MXU operand getting pattern 'optn2' */
25297 #define MXU_OPTN2_PTN0 0
25298 #define MXU_OPTN2_PTN1 1
25299 #define MXU_OPTN2_PTN2 2
25300 #define MXU_OPTN2_PTN3 3
25301 /* alternative naming scheme for 'optn2' */
25302 #define MXU_OPTN2_WW 0
25303 #define MXU_OPTN2_LW 1
25304 #define MXU_OPTN2_HW 2
25305 #define MXU_OPTN2_XW 3
25307 /* MXU operand getting pattern 'optn3' */
25308 #define MXU_OPTN3_PTN0 0
25309 #define MXU_OPTN3_PTN1 1
25310 #define MXU_OPTN3_PTN2 2
25311 #define MXU_OPTN3_PTN3 3
25312 #define MXU_OPTN3_PTN4 4
25313 #define MXU_OPTN3_PTN5 5
25314 #define MXU_OPTN3_PTN6 6
25315 #define MXU_OPTN3_PTN7 7
25319 * S32I2M XRa, rb - Register move from GRF to XRF
25321 static void gen_mxu_s32i2m(DisasContext
*ctx
)
25326 t0
= tcg_temp_new();
25328 XRa
= extract32(ctx
->opcode
, 6, 5);
25329 Rb
= extract32(ctx
->opcode
, 16, 5);
25331 gen_load_gpr(t0
, Rb
);
25333 gen_store_mxu_gpr(t0
, XRa
);
25334 } else if (XRa
== 16) {
25335 gen_store_mxu_cr(t0
);
25342 * S32M2I XRa, rb - Register move from XRF to GRF
25344 static void gen_mxu_s32m2i(DisasContext
*ctx
)
25349 t0
= tcg_temp_new();
25351 XRa
= extract32(ctx
->opcode
, 6, 5);
25352 Rb
= extract32(ctx
->opcode
, 16, 5);
25355 gen_load_mxu_gpr(t0
, XRa
);
25356 } else if (XRa
== 16) {
25357 gen_load_mxu_cr(t0
);
25360 gen_store_gpr(t0
, Rb
);
25366 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
25368 static void gen_mxu_s8ldd(DisasContext
*ctx
)
25371 uint32_t XRa
, Rb
, s8
, optn3
;
25373 t0
= tcg_temp_new();
25374 t1
= tcg_temp_new();
25376 XRa
= extract32(ctx
->opcode
, 6, 4);
25377 s8
= extract32(ctx
->opcode
, 10, 8);
25378 optn3
= extract32(ctx
->opcode
, 18, 3);
25379 Rb
= extract32(ctx
->opcode
, 21, 5);
25381 gen_load_gpr(t0
, Rb
);
25382 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
25385 /* XRa[7:0] = tmp8 */
25386 case MXU_OPTN3_PTN0
:
25387 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25388 gen_load_mxu_gpr(t0
, XRa
);
25389 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
25391 /* XRa[15:8] = tmp8 */
25392 case MXU_OPTN3_PTN1
:
25393 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25394 gen_load_mxu_gpr(t0
, XRa
);
25395 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
25397 /* XRa[23:16] = tmp8 */
25398 case MXU_OPTN3_PTN2
:
25399 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25400 gen_load_mxu_gpr(t0
, XRa
);
25401 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
25403 /* XRa[31:24] = tmp8 */
25404 case MXU_OPTN3_PTN3
:
25405 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25406 gen_load_mxu_gpr(t0
, XRa
);
25407 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
25409 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
25410 case MXU_OPTN3_PTN4
:
25411 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25412 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25414 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
25415 case MXU_OPTN3_PTN5
:
25416 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25417 tcg_gen_shli_tl(t1
, t1
, 8);
25418 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25420 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
25421 case MXU_OPTN3_PTN6
:
25422 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
25423 tcg_gen_mov_tl(t0
, t1
);
25424 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
25425 tcg_gen_shli_tl(t1
, t1
, 16);
25426 tcg_gen_or_tl(t0
, t0
, t1
);
25428 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
25429 case MXU_OPTN3_PTN7
:
25430 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
25431 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
25432 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
25436 gen_store_mxu_gpr(t0
, XRa
);
25443 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
25445 static void gen_mxu_d16mul(DisasContext
*ctx
)
25447 TCGv t0
, t1
, t2
, t3
;
25448 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
25450 t0
= tcg_temp_new();
25451 t1
= tcg_temp_new();
25452 t2
= tcg_temp_new();
25453 t3
= tcg_temp_new();
25455 XRa
= extract32(ctx
->opcode
, 6, 4);
25456 XRb
= extract32(ctx
->opcode
, 10, 4);
25457 XRc
= extract32(ctx
->opcode
, 14, 4);
25458 XRd
= extract32(ctx
->opcode
, 18, 4);
25459 optn2
= extract32(ctx
->opcode
, 22, 2);
25461 gen_load_mxu_gpr(t1
, XRb
);
25462 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25463 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25464 gen_load_mxu_gpr(t3
, XRc
);
25465 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25466 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25469 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25470 tcg_gen_mul_tl(t3
, t1
, t3
);
25471 tcg_gen_mul_tl(t2
, t0
, t2
);
25473 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25474 tcg_gen_mul_tl(t3
, t0
, t3
);
25475 tcg_gen_mul_tl(t2
, t0
, t2
);
25477 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25478 tcg_gen_mul_tl(t3
, t1
, t3
);
25479 tcg_gen_mul_tl(t2
, t1
, t2
);
25481 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25482 tcg_gen_mul_tl(t3
, t0
, t3
);
25483 tcg_gen_mul_tl(t2
, t1
, t2
);
25486 gen_store_mxu_gpr(t3
, XRa
);
25487 gen_store_mxu_gpr(t2
, XRd
);
25496 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
25499 static void gen_mxu_d16mac(DisasContext
*ctx
)
25501 TCGv t0
, t1
, t2
, t3
;
25502 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
25504 t0
= tcg_temp_new();
25505 t1
= tcg_temp_new();
25506 t2
= tcg_temp_new();
25507 t3
= tcg_temp_new();
25509 XRa
= extract32(ctx
->opcode
, 6, 4);
25510 XRb
= extract32(ctx
->opcode
, 10, 4);
25511 XRc
= extract32(ctx
->opcode
, 14, 4);
25512 XRd
= extract32(ctx
->opcode
, 18, 4);
25513 optn2
= extract32(ctx
->opcode
, 22, 2);
25514 aptn2
= extract32(ctx
->opcode
, 24, 2);
25516 gen_load_mxu_gpr(t1
, XRb
);
25517 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
25518 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
25520 gen_load_mxu_gpr(t3
, XRc
);
25521 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
25522 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
25525 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
25526 tcg_gen_mul_tl(t3
, t1
, t3
);
25527 tcg_gen_mul_tl(t2
, t0
, t2
);
25529 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
25530 tcg_gen_mul_tl(t3
, t0
, t3
);
25531 tcg_gen_mul_tl(t2
, t0
, t2
);
25533 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
25534 tcg_gen_mul_tl(t3
, t1
, t3
);
25535 tcg_gen_mul_tl(t2
, t1
, t2
);
25537 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
25538 tcg_gen_mul_tl(t3
, t0
, t3
);
25539 tcg_gen_mul_tl(t2
, t1
, t2
);
25542 gen_load_mxu_gpr(t0
, XRa
);
25543 gen_load_mxu_gpr(t1
, XRd
);
25547 tcg_gen_add_tl(t3
, t0
, t3
);
25548 tcg_gen_add_tl(t2
, t1
, t2
);
25551 tcg_gen_add_tl(t3
, t0
, t3
);
25552 tcg_gen_sub_tl(t2
, t1
, t2
);
25555 tcg_gen_sub_tl(t3
, t0
, t3
);
25556 tcg_gen_add_tl(t2
, t1
, t2
);
25559 tcg_gen_sub_tl(t3
, t0
, t3
);
25560 tcg_gen_sub_tl(t2
, t1
, t2
);
25563 gen_store_mxu_gpr(t3
, XRa
);
25564 gen_store_mxu_gpr(t2
, XRd
);
25573 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25574 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25576 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25578 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25579 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25581 t0
= tcg_temp_new();
25582 t1
= tcg_temp_new();
25583 t2
= tcg_temp_new();
25584 t3
= tcg_temp_new();
25585 t4
= tcg_temp_new();
25586 t5
= tcg_temp_new();
25587 t6
= tcg_temp_new();
25588 t7
= tcg_temp_new();
25590 XRa
= extract32(ctx
->opcode
, 6, 4);
25591 XRb
= extract32(ctx
->opcode
, 10, 4);
25592 XRc
= extract32(ctx
->opcode
, 14, 4);
25593 XRd
= extract32(ctx
->opcode
, 18, 4);
25594 sel
= extract32(ctx
->opcode
, 22, 2);
25596 gen_load_mxu_gpr(t3
, XRb
);
25597 gen_load_mxu_gpr(t7
, XRc
);
25601 tcg_gen_ext8s_tl(t0
, t3
);
25602 tcg_gen_shri_tl(t3
, t3
, 8);
25603 tcg_gen_ext8s_tl(t1
, t3
);
25604 tcg_gen_shri_tl(t3
, t3
, 8);
25605 tcg_gen_ext8s_tl(t2
, t3
);
25606 tcg_gen_shri_tl(t3
, t3
, 8);
25607 tcg_gen_ext8s_tl(t3
, t3
);
25610 tcg_gen_ext8u_tl(t0
, t3
);
25611 tcg_gen_shri_tl(t3
, t3
, 8);
25612 tcg_gen_ext8u_tl(t1
, t3
);
25613 tcg_gen_shri_tl(t3
, t3
, 8);
25614 tcg_gen_ext8u_tl(t2
, t3
);
25615 tcg_gen_shri_tl(t3
, t3
, 8);
25616 tcg_gen_ext8u_tl(t3
, t3
);
25619 tcg_gen_ext8u_tl(t4
, t7
);
25620 tcg_gen_shri_tl(t7
, t7
, 8);
25621 tcg_gen_ext8u_tl(t5
, t7
);
25622 tcg_gen_shri_tl(t7
, t7
, 8);
25623 tcg_gen_ext8u_tl(t6
, t7
);
25624 tcg_gen_shri_tl(t7
, t7
, 8);
25625 tcg_gen_ext8u_tl(t7
, t7
);
25627 tcg_gen_mul_tl(t0
, t0
, t4
);
25628 tcg_gen_mul_tl(t1
, t1
, t5
);
25629 tcg_gen_mul_tl(t2
, t2
, t6
);
25630 tcg_gen_mul_tl(t3
, t3
, t7
);
25632 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25633 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25634 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25635 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25637 tcg_gen_shli_tl(t1
, t1
, 16);
25638 tcg_gen_shli_tl(t3
, t3
, 16);
25640 tcg_gen_or_tl(t0
, t0
, t1
);
25641 tcg_gen_or_tl(t1
, t2
, t3
);
25643 gen_store_mxu_gpr(t0
, XRd
);
25644 gen_store_mxu_gpr(t1
, XRa
);
25657 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25658 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25660 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25663 uint32_t XRa
, Rb
, s12
, sel
;
25665 t0
= tcg_temp_new();
25666 t1
= tcg_temp_new();
25668 XRa
= extract32(ctx
->opcode
, 6, 4);
25669 s12
= extract32(ctx
->opcode
, 10, 10);
25670 sel
= extract32(ctx
->opcode
, 20, 1);
25671 Rb
= extract32(ctx
->opcode
, 21, 5);
25673 gen_load_gpr(t0
, Rb
);
25675 tcg_gen_movi_tl(t1
, s12
);
25676 tcg_gen_shli_tl(t1
, t1
, 2);
25678 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25680 tcg_gen_add_tl(t1
, t0
, t1
);
25681 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25685 tcg_gen_bswap32_tl(t1
, t1
);
25687 gen_store_mxu_gpr(t1
, XRa
);
25695 * MXU instruction category: logic
25696 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25698 * S32NOR S32AND S32OR S32XOR
25702 * S32NOR XRa, XRb, XRc
25703 * Update XRa with the result of logical bitwise 'nor' operation
25704 * applied to the content of XRb and XRc.
25706 * 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
25707 * +-----------+---------+-----+-------+-------+-------+-----------+
25708 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25709 * +-----------+---------+-----+-------+-------+-------+-----------+
25711 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25713 uint32_t pad
, XRc
, XRb
, XRa
;
25715 pad
= extract32(ctx
->opcode
, 21, 5);
25716 XRc
= extract32(ctx
->opcode
, 14, 4);
25717 XRb
= extract32(ctx
->opcode
, 10, 4);
25718 XRa
= extract32(ctx
->opcode
, 6, 4);
25720 if (unlikely(pad
!= 0)) {
25721 /* opcode padding incorrect -> do nothing */
25722 } else if (unlikely(XRa
== 0)) {
25723 /* destination is zero register -> do nothing */
25724 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25725 /* both operands zero registers -> just set destination to all 1s */
25726 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25727 } else if (unlikely(XRb
== 0)) {
25728 /* XRb zero register -> just set destination to the negation of XRc */
25729 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25730 } else if (unlikely(XRc
== 0)) {
25731 /* XRa zero register -> just set destination to the negation of XRb */
25732 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25733 } else if (unlikely(XRb
== XRc
)) {
25734 /* both operands same -> just set destination to the negation of XRb */
25735 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25737 /* the most general case */
25738 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25743 * S32AND XRa, XRb, XRc
25744 * Update XRa with the result of logical bitwise 'and' operation
25745 * applied to the content of XRb and XRc.
25747 * 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
25748 * +-----------+---------+-----+-------+-------+-------+-----------+
25749 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25750 * +-----------+---------+-----+-------+-------+-------+-----------+
25752 static void gen_mxu_S32AND(DisasContext
*ctx
)
25754 uint32_t pad
, XRc
, XRb
, XRa
;
25756 pad
= extract32(ctx
->opcode
, 21, 5);
25757 XRc
= extract32(ctx
->opcode
, 14, 4);
25758 XRb
= extract32(ctx
->opcode
, 10, 4);
25759 XRa
= extract32(ctx
->opcode
, 6, 4);
25761 if (unlikely(pad
!= 0)) {
25762 /* opcode padding incorrect -> do nothing */
25763 } else if (unlikely(XRa
== 0)) {
25764 /* destination is zero register -> do nothing */
25765 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25766 /* one of operands zero register -> just set destination to all 0s */
25767 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25768 } else if (unlikely(XRb
== XRc
)) {
25769 /* both operands same -> just set destination to one of them */
25770 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25772 /* the most general case */
25773 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25778 * S32OR XRa, XRb, XRc
25779 * Update XRa with the result of logical bitwise 'or' operation
25780 * applied to the content of XRb and XRc.
25782 * 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
25783 * +-----------+---------+-----+-------+-------+-------+-----------+
25784 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25785 * +-----------+---------+-----+-------+-------+-------+-----------+
25787 static void gen_mxu_S32OR(DisasContext
*ctx
)
25789 uint32_t pad
, XRc
, XRb
, XRa
;
25791 pad
= extract32(ctx
->opcode
, 21, 5);
25792 XRc
= extract32(ctx
->opcode
, 14, 4);
25793 XRb
= extract32(ctx
->opcode
, 10, 4);
25794 XRa
= extract32(ctx
->opcode
, 6, 4);
25796 if (unlikely(pad
!= 0)) {
25797 /* opcode padding incorrect -> do nothing */
25798 } else if (unlikely(XRa
== 0)) {
25799 /* destination is zero register -> do nothing */
25800 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25801 /* both operands zero registers -> just set destination to all 0s */
25802 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25803 } else if (unlikely(XRb
== 0)) {
25804 /* XRb zero register -> just set destination to the content of XRc */
25805 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25806 } else if (unlikely(XRc
== 0)) {
25807 /* XRc zero register -> just set destination to the content of XRb */
25808 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25809 } else if (unlikely(XRb
== XRc
)) {
25810 /* both operands same -> just set destination to one of them */
25811 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25813 /* the most general case */
25814 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25819 * S32XOR XRa, XRb, XRc
25820 * Update XRa with the result of logical bitwise 'xor' operation
25821 * applied to the content of XRb and XRc.
25823 * 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
25824 * +-----------+---------+-----+-------+-------+-------+-----------+
25825 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25826 * +-----------+---------+-----+-------+-------+-------+-----------+
25828 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25830 uint32_t pad
, XRc
, XRb
, XRa
;
25832 pad
= extract32(ctx
->opcode
, 21, 5);
25833 XRc
= extract32(ctx
->opcode
, 14, 4);
25834 XRb
= extract32(ctx
->opcode
, 10, 4);
25835 XRa
= extract32(ctx
->opcode
, 6, 4);
25837 if (unlikely(pad
!= 0)) {
25838 /* opcode padding incorrect -> do nothing */
25839 } else if (unlikely(XRa
== 0)) {
25840 /* destination is zero register -> do nothing */
25841 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25842 /* both operands zero registers -> just set destination to all 0s */
25843 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25844 } else if (unlikely(XRb
== 0)) {
25845 /* XRb zero register -> just set destination to the content of XRc */
25846 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25847 } else if (unlikely(XRc
== 0)) {
25848 /* XRc zero register -> just set destination to the content of XRb */
25849 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25850 } else if (unlikely(XRb
== XRc
)) {
25851 /* both operands same -> just set destination to all 0s */
25852 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25854 /* the most general case */
25855 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25861 * MXU instruction category max/min
25862 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25864 * S32MAX D16MAX Q8MAX
25865 * S32MIN D16MIN Q8MIN
25869 * S32MAX XRa, XRb, XRc
25870 * Update XRa with the maximum of signed 32-bit integers contained
25873 * S32MIN XRa, XRb, XRc
25874 * Update XRa with the minimum of signed 32-bit integers contained
25877 * 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
25878 * +-----------+---------+-----+-------+-------+-------+-----------+
25879 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25880 * +-----------+---------+-----+-------+-------+-------+-----------+
25882 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25884 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25886 pad
= extract32(ctx
->opcode
, 21, 5);
25887 opc
= extract32(ctx
->opcode
, 18, 3);
25888 XRc
= extract32(ctx
->opcode
, 14, 4);
25889 XRb
= extract32(ctx
->opcode
, 10, 4);
25890 XRa
= extract32(ctx
->opcode
, 6, 4);
25892 if (unlikely(pad
!= 0)) {
25893 /* opcode padding incorrect -> do nothing */
25894 } else if (unlikely(XRa
== 0)) {
25895 /* destination is zero register -> do nothing */
25896 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25897 /* both operands zero registers -> just set destination to zero */
25898 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25899 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25900 /* exactly one operand is zero register - find which one is not...*/
25901 uint32_t XRx
= XRb
? XRb
: XRc
;
25902 /* ...and do max/min operation with one operand 0 */
25903 if (opc
== OPC_MXU_S32MAX
) {
25904 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25906 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25908 } else if (unlikely(XRb
== XRc
)) {
25909 /* both operands same -> just set destination to one of them */
25910 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25912 /* the most general case */
25913 if (opc
== OPC_MXU_S32MAX
) {
25914 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25917 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25925 * Update XRa with the 16-bit-wise maximums of signed integers
25926 * contained in XRb and XRc.
25929 * Update XRa with the 16-bit-wise minimums of signed integers
25930 * contained in XRb and XRc.
25932 * 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
25933 * +-----------+---------+-----+-------+-------+-------+-----------+
25934 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25935 * +-----------+---------+-----+-------+-------+-------+-----------+
25937 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25939 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25941 pad
= extract32(ctx
->opcode
, 21, 5);
25942 opc
= extract32(ctx
->opcode
, 18, 3);
25943 XRc
= extract32(ctx
->opcode
, 14, 4);
25944 XRb
= extract32(ctx
->opcode
, 10, 4);
25945 XRa
= extract32(ctx
->opcode
, 6, 4);
25947 if (unlikely(pad
!= 0)) {
25948 /* opcode padding incorrect -> do nothing */
25949 } else if (unlikely(XRc
== 0)) {
25950 /* destination is zero register -> do nothing */
25951 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
25952 /* both operands zero registers -> just set destination to zero */
25953 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
25954 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
25955 /* exactly one operand is zero register - find which one is not...*/
25956 uint32_t XRx
= XRb
? XRb
: XRc
;
25957 /* ...and do half-word-wise max/min with one operand 0 */
25958 TCGv_i32 t0
= tcg_temp_new();
25959 TCGv_i32 t1
= tcg_const_i32(0);
25961 /* the left half-word first */
25962 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
25963 if (opc
== OPC_MXU_D16MAX
) {
25964 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25966 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25969 /* the right half-word */
25970 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
25971 /* move half-words to the leftmost position */
25972 tcg_gen_shli_i32(t0
, t0
, 16);
25973 /* t0 will be max/min of t0 and t1 */
25974 if (opc
== OPC_MXU_D16MAX
) {
25975 tcg_gen_smax_i32(t0
, t0
, t1
);
25977 tcg_gen_smin_i32(t0
, t0
, t1
);
25979 /* return resulting half-words to its original position */
25980 tcg_gen_shri_i32(t0
, t0
, 16);
25981 /* finally update the destination */
25982 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25986 } else if (unlikely(XRb
== XRc
)) {
25987 /* both operands same -> just set destination to one of them */
25988 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25990 /* the most general case */
25991 TCGv_i32 t0
= tcg_temp_new();
25992 TCGv_i32 t1
= tcg_temp_new();
25994 /* the left half-word first */
25995 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
25996 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25997 if (opc
== OPC_MXU_D16MAX
) {
25998 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26000 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26003 /* the right half-word */
26004 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
26005 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
26006 /* move half-words to the leftmost position */
26007 tcg_gen_shli_i32(t0
, t0
, 16);
26008 tcg_gen_shli_i32(t1
, t1
, 16);
26009 /* t0 will be max/min of t0 and t1 */
26010 if (opc
== OPC_MXU_D16MAX
) {
26011 tcg_gen_smax_i32(t0
, t0
, t1
);
26013 tcg_gen_smin_i32(t0
, t0
, t1
);
26015 /* return resulting half-words to its original position */
26016 tcg_gen_shri_i32(t0
, t0
, 16);
26017 /* finally update the destination */
26018 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26027 * Update XRa with the 8-bit-wise maximums of signed integers
26028 * contained in XRb and XRc.
26031 * Update XRa with the 8-bit-wise minimums of signed integers
26032 * contained in XRb and XRc.
26034 * 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
26035 * +-----------+---------+-----+-------+-------+-------+-----------+
26036 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
26037 * +-----------+---------+-----+-------+-------+-------+-----------+
26039 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
26041 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
26043 pad
= extract32(ctx
->opcode
, 21, 5);
26044 opc
= extract32(ctx
->opcode
, 18, 3);
26045 XRc
= extract32(ctx
->opcode
, 14, 4);
26046 XRb
= extract32(ctx
->opcode
, 10, 4);
26047 XRa
= extract32(ctx
->opcode
, 6, 4);
26049 if (unlikely(pad
!= 0)) {
26050 /* opcode padding incorrect -> do nothing */
26051 } else if (unlikely(XRa
== 0)) {
26052 /* destination is zero register -> do nothing */
26053 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
26054 /* both operands zero registers -> just set destination to zero */
26055 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26056 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
26057 /* exactly one operand is zero register - make it be the first...*/
26058 uint32_t XRx
= XRb
? XRb
: XRc
;
26059 /* ...and do byte-wise max/min with one operand 0 */
26060 TCGv_i32 t0
= tcg_temp_new();
26061 TCGv_i32 t1
= tcg_const_i32(0);
26064 /* the leftmost byte (byte 3) first */
26065 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
26066 if (opc
== OPC_MXU_Q8MAX
) {
26067 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26069 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26072 /* bytes 2, 1, 0 */
26073 for (i
= 2; i
>= 0; i
--) {
26074 /* extract the byte */
26075 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
26076 /* move the byte to the leftmost position */
26077 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
26078 /* t0 will be max/min of t0 and t1 */
26079 if (opc
== OPC_MXU_Q8MAX
) {
26080 tcg_gen_smax_i32(t0
, t0
, t1
);
26082 tcg_gen_smin_i32(t0
, t0
, t1
);
26084 /* return resulting byte to its original position */
26085 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
26086 /* finally update the destination */
26087 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26092 } else if (unlikely(XRb
== XRc
)) {
26093 /* both operands same -> just set destination to one of them */
26094 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26096 /* the most general case */
26097 TCGv_i32 t0
= tcg_temp_new();
26098 TCGv_i32 t1
= tcg_temp_new();
26101 /* the leftmost bytes (bytes 3) first */
26102 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
26103 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
26104 if (opc
== OPC_MXU_Q8MAX
) {
26105 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26107 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26110 /* bytes 2, 1, 0 */
26111 for (i
= 2; i
>= 0; i
--) {
26112 /* extract corresponding bytes */
26113 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
26114 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
26115 /* move the bytes to the leftmost position */
26116 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
26117 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
26118 /* t0 will be max/min of t0 and t1 */
26119 if (opc
== OPC_MXU_Q8MAX
) {
26120 tcg_gen_smax_i32(t0
, t0
, t1
);
26122 tcg_gen_smin_i32(t0
, t0
, t1
);
26124 /* return resulting byte to its original position */
26125 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
26126 /* finally update the destination */
26127 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
26137 * MXU instruction category: align
26138 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26144 * S32ALNI XRc, XRb, XRa, optn3
26145 * Arrange bytes from XRb and XRc according to one of five sets of
26146 * rules determined by optn3, and place the result in XRa.
26148 * 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
26149 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26150 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26151 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26154 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
26156 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
26158 optn3
= extract32(ctx
->opcode
, 23, 3);
26159 pad
= extract32(ctx
->opcode
, 21, 2);
26160 XRc
= extract32(ctx
->opcode
, 14, 4);
26161 XRb
= extract32(ctx
->opcode
, 10, 4);
26162 XRa
= extract32(ctx
->opcode
, 6, 4);
26164 if (unlikely(pad
!= 0)) {
26165 /* opcode padding incorrect -> do nothing */
26166 } else if (unlikely(XRa
== 0)) {
26167 /* destination is zero register -> do nothing */
26168 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
26169 /* both operands zero registers -> just set destination to all 0s */
26170 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26171 } else if (unlikely(XRb
== 0)) {
26172 /* XRb zero register -> just appropriatelly shift XRc into XRa */
26174 case MXU_OPTN3_PTN0
:
26175 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26177 case MXU_OPTN3_PTN1
:
26178 case MXU_OPTN3_PTN2
:
26179 case MXU_OPTN3_PTN3
:
26180 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
26183 case MXU_OPTN3_PTN4
:
26184 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
26187 } else if (unlikely(XRc
== 0)) {
26188 /* XRc zero register -> just appropriatelly shift XRb into XRa */
26190 case MXU_OPTN3_PTN0
:
26191 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26193 case MXU_OPTN3_PTN1
:
26194 case MXU_OPTN3_PTN2
:
26195 case MXU_OPTN3_PTN3
:
26196 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
26198 case MXU_OPTN3_PTN4
:
26199 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
26202 } else if (unlikely(XRb
== XRc
)) {
26203 /* both operands same -> just rotation or moving from any of them */
26205 case MXU_OPTN3_PTN0
:
26206 case MXU_OPTN3_PTN4
:
26207 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26209 case MXU_OPTN3_PTN1
:
26210 case MXU_OPTN3_PTN2
:
26211 case MXU_OPTN3_PTN3
:
26212 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
26216 /* the most general case */
26218 case MXU_OPTN3_PTN0
:
26222 /* +---------------+ */
26223 /* | A B C D | E F G H */
26224 /* +-------+-------+ */
26229 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
26232 case MXU_OPTN3_PTN1
:
26236 /* +-------------------+ */
26237 /* A | B C D E | F G H */
26238 /* +---------+---------+ */
26243 TCGv_i32 t0
= tcg_temp_new();
26244 TCGv_i32 t1
= tcg_temp_new();
26246 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
26247 tcg_gen_shli_i32(t0
, t0
, 8);
26249 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
26250 tcg_gen_shri_i32(t1
, t1
, 24);
26252 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26258 case MXU_OPTN3_PTN2
:
26262 /* +-------------------+ */
26263 /* A B | C D E F | G H */
26264 /* +---------+---------+ */
26269 TCGv_i32 t0
= tcg_temp_new();
26270 TCGv_i32 t1
= tcg_temp_new();
26272 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
26273 tcg_gen_shli_i32(t0
, t0
, 16);
26275 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
26276 tcg_gen_shri_i32(t1
, t1
, 16);
26278 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26284 case MXU_OPTN3_PTN3
:
26288 /* +-------------------+ */
26289 /* A B C | D E F G | H */
26290 /* +---------+---------+ */
26295 TCGv_i32 t0
= tcg_temp_new();
26296 TCGv_i32 t1
= tcg_temp_new();
26298 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
26299 tcg_gen_shli_i32(t0
, t0
, 24);
26301 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
26302 tcg_gen_shri_i32(t1
, t1
, 8);
26304 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
26310 case MXU_OPTN3_PTN4
:
26314 /* +---------------+ */
26315 /* A B C D | E F G H | */
26316 /* +-------+-------+ */
26321 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
26330 * Decoding engine for MXU
26331 * =======================
26336 * Decode MXU pool00
26338 * 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
26339 * +-----------+---------+-----+-------+-------+-------+-----------+
26340 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
26341 * +-----------+---------+-----+-------+-------+-------+-----------+
26344 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
26346 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26349 case OPC_MXU_S32MAX
:
26350 case OPC_MXU_S32MIN
:
26351 gen_mxu_S32MAX_S32MIN(ctx
);
26353 case OPC_MXU_D16MAX
:
26354 case OPC_MXU_D16MIN
:
26355 gen_mxu_D16MAX_D16MIN(ctx
);
26357 case OPC_MXU_Q8MAX
:
26358 case OPC_MXU_Q8MIN
:
26359 gen_mxu_Q8MAX_Q8MIN(ctx
);
26361 case OPC_MXU_Q8SLT
:
26362 /* TODO: Implement emulation of Q8SLT instruction. */
26363 MIPS_INVAL("OPC_MXU_Q8SLT");
26364 gen_reserved_instruction(ctx
);
26366 case OPC_MXU_Q8SLTU
:
26367 /* TODO: Implement emulation of Q8SLTU instruction. */
26368 MIPS_INVAL("OPC_MXU_Q8SLTU");
26369 gen_reserved_instruction(ctx
);
26372 MIPS_INVAL("decode_opc_mxu");
26373 gen_reserved_instruction(ctx
);
26380 * Decode MXU pool01
26382 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
26383 * 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
26384 * +-----------+---------+-----+-------+-------+-------+-----------+
26385 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26386 * +-----------+---------+-----+-------+-------+-------+-----------+
26389 * 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
26390 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26391 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
26392 * +-----------+---+-----+-----+-------+-------+-------+-----------+
26395 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
26397 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26400 case OPC_MXU_S32SLT
:
26401 /* TODO: Implement emulation of S32SLT instruction. */
26402 MIPS_INVAL("OPC_MXU_S32SLT");
26403 gen_reserved_instruction(ctx
);
26405 case OPC_MXU_D16SLT
:
26406 /* TODO: Implement emulation of D16SLT instruction. */
26407 MIPS_INVAL("OPC_MXU_D16SLT");
26408 gen_reserved_instruction(ctx
);
26410 case OPC_MXU_D16AVG
:
26411 /* TODO: Implement emulation of D16AVG instruction. */
26412 MIPS_INVAL("OPC_MXU_D16AVG");
26413 gen_reserved_instruction(ctx
);
26415 case OPC_MXU_D16AVGR
:
26416 /* TODO: Implement emulation of D16AVGR instruction. */
26417 MIPS_INVAL("OPC_MXU_D16AVGR");
26418 gen_reserved_instruction(ctx
);
26420 case OPC_MXU_Q8AVG
:
26421 /* TODO: Implement emulation of Q8AVG instruction. */
26422 MIPS_INVAL("OPC_MXU_Q8AVG");
26423 gen_reserved_instruction(ctx
);
26425 case OPC_MXU_Q8AVGR
:
26426 /* TODO: Implement emulation of Q8AVGR instruction. */
26427 MIPS_INVAL("OPC_MXU_Q8AVGR");
26428 gen_reserved_instruction(ctx
);
26430 case OPC_MXU_Q8ADD
:
26431 /* TODO: Implement emulation of Q8ADD instruction. */
26432 MIPS_INVAL("OPC_MXU_Q8ADD");
26433 gen_reserved_instruction(ctx
);
26436 MIPS_INVAL("decode_opc_mxu");
26437 gen_reserved_instruction(ctx
);
26444 * Decode MXU pool02
26446 * 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
26447 * +-----------+---------+-----+-------+-------+-------+-----------+
26448 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
26449 * +-----------+---------+-----+-------+-------+-------+-----------+
26452 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
26454 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26457 case OPC_MXU_S32CPS
:
26458 /* TODO: Implement emulation of S32CPS instruction. */
26459 MIPS_INVAL("OPC_MXU_S32CPS");
26460 gen_reserved_instruction(ctx
);
26462 case OPC_MXU_D16CPS
:
26463 /* TODO: Implement emulation of D16CPS instruction. */
26464 MIPS_INVAL("OPC_MXU_D16CPS");
26465 gen_reserved_instruction(ctx
);
26467 case OPC_MXU_Q8ABD
:
26468 /* TODO: Implement emulation of Q8ABD instruction. */
26469 MIPS_INVAL("OPC_MXU_Q8ABD");
26470 gen_reserved_instruction(ctx
);
26472 case OPC_MXU_Q16SAT
:
26473 /* TODO: Implement emulation of Q16SAT instruction. */
26474 MIPS_INVAL("OPC_MXU_Q16SAT");
26475 gen_reserved_instruction(ctx
);
26478 MIPS_INVAL("decode_opc_mxu");
26479 gen_reserved_instruction(ctx
);
26486 * Decode MXU pool03
26489 * 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
26490 * +-----------+---+---+-------+-------+-------+-------+-----------+
26491 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
26492 * +-----------+---+---+-------+-------+-------+-------+-----------+
26495 * 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
26496 * +-----------+---+---+-------+-------+-------+-------+-----------+
26497 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
26498 * +-----------+---+---+-------+-------+-------+-------+-----------+
26501 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
26503 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
26506 case OPC_MXU_D16MULF
:
26507 /* TODO: Implement emulation of D16MULF instruction. */
26508 MIPS_INVAL("OPC_MXU_D16MULF");
26509 gen_reserved_instruction(ctx
);
26511 case OPC_MXU_D16MULE
:
26512 /* TODO: Implement emulation of D16MULE instruction. */
26513 MIPS_INVAL("OPC_MXU_D16MULE");
26514 gen_reserved_instruction(ctx
);
26517 MIPS_INVAL("decode_opc_mxu");
26518 gen_reserved_instruction(ctx
);
26525 * Decode MXU pool04
26527 * 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
26528 * +-----------+---------+-+-------------------+-------+-----------+
26529 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
26530 * +-----------+---------+-+-------------------+-------+-----------+
26533 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
26535 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26538 case OPC_MXU_S32LDD
:
26539 case OPC_MXU_S32LDDR
:
26540 gen_mxu_s32ldd_s32lddr(ctx
);
26543 MIPS_INVAL("decode_opc_mxu");
26544 gen_reserved_instruction(ctx
);
26551 * Decode MXU pool05
26553 * 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
26554 * +-----------+---------+-+-------------------+-------+-----------+
26555 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
26556 * +-----------+---------+-+-------------------+-------+-----------+
26559 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
26561 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26564 case OPC_MXU_S32STD
:
26565 /* TODO: Implement emulation of S32STD instruction. */
26566 MIPS_INVAL("OPC_MXU_S32STD");
26567 gen_reserved_instruction(ctx
);
26569 case OPC_MXU_S32STDR
:
26570 /* TODO: Implement emulation of S32STDR instruction. */
26571 MIPS_INVAL("OPC_MXU_S32STDR");
26572 gen_reserved_instruction(ctx
);
26575 MIPS_INVAL("decode_opc_mxu");
26576 gen_reserved_instruction(ctx
);
26583 * Decode MXU pool06
26585 * 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
26586 * +-----------+---------+---------+---+-------+-------+-----------+
26587 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26588 * +-----------+---------+---------+---+-------+-------+-----------+
26591 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26593 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26596 case OPC_MXU_S32LDDV
:
26597 /* TODO: Implement emulation of S32LDDV instruction. */
26598 MIPS_INVAL("OPC_MXU_S32LDDV");
26599 gen_reserved_instruction(ctx
);
26601 case OPC_MXU_S32LDDVR
:
26602 /* TODO: Implement emulation of S32LDDVR instruction. */
26603 MIPS_INVAL("OPC_MXU_S32LDDVR");
26604 gen_reserved_instruction(ctx
);
26607 MIPS_INVAL("decode_opc_mxu");
26608 gen_reserved_instruction(ctx
);
26615 * Decode MXU pool07
26617 * 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
26618 * +-----------+---------+---------+---+-------+-------+-----------+
26619 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26620 * +-----------+---------+---------+---+-------+-------+-----------+
26623 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26625 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26628 case OPC_MXU_S32STDV
:
26629 /* TODO: Implement emulation of S32TDV instruction. */
26630 MIPS_INVAL("OPC_MXU_S32TDV");
26631 gen_reserved_instruction(ctx
);
26633 case OPC_MXU_S32STDVR
:
26634 /* TODO: Implement emulation of S32TDVR instruction. */
26635 MIPS_INVAL("OPC_MXU_S32TDVR");
26636 gen_reserved_instruction(ctx
);
26639 MIPS_INVAL("decode_opc_mxu");
26640 gen_reserved_instruction(ctx
);
26647 * Decode MXU pool08
26649 * 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
26650 * +-----------+---------+-+-------------------+-------+-----------+
26651 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26652 * +-----------+---------+-+-------------------+-------+-----------+
26655 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26657 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26660 case OPC_MXU_S32LDI
:
26661 /* TODO: Implement emulation of S32LDI instruction. */
26662 MIPS_INVAL("OPC_MXU_S32LDI");
26663 gen_reserved_instruction(ctx
);
26665 case OPC_MXU_S32LDIR
:
26666 /* TODO: Implement emulation of S32LDIR instruction. */
26667 MIPS_INVAL("OPC_MXU_S32LDIR");
26668 gen_reserved_instruction(ctx
);
26671 MIPS_INVAL("decode_opc_mxu");
26672 gen_reserved_instruction(ctx
);
26679 * Decode MXU pool09
26681 * 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
26682 * +-----------+---------+-+-------------------+-------+-----------+
26683 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26684 * +-----------+---------+-+-------------------+-------+-----------+
26687 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26689 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26692 case OPC_MXU_S32SDI
:
26693 /* TODO: Implement emulation of S32SDI instruction. */
26694 MIPS_INVAL("OPC_MXU_S32SDI");
26695 gen_reserved_instruction(ctx
);
26697 case OPC_MXU_S32SDIR
:
26698 /* TODO: Implement emulation of S32SDIR instruction. */
26699 MIPS_INVAL("OPC_MXU_S32SDIR");
26700 gen_reserved_instruction(ctx
);
26703 MIPS_INVAL("decode_opc_mxu");
26704 gen_reserved_instruction(ctx
);
26711 * Decode MXU pool10
26713 * 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
26714 * +-----------+---------+---------+---+-------+-------+-----------+
26715 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26716 * +-----------+---------+---------+---+-------+-------+-----------+
26719 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26721 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26724 case OPC_MXU_S32LDIV
:
26725 /* TODO: Implement emulation of S32LDIV instruction. */
26726 MIPS_INVAL("OPC_MXU_S32LDIV");
26727 gen_reserved_instruction(ctx
);
26729 case OPC_MXU_S32LDIVR
:
26730 /* TODO: Implement emulation of S32LDIVR instruction. */
26731 MIPS_INVAL("OPC_MXU_S32LDIVR");
26732 gen_reserved_instruction(ctx
);
26735 MIPS_INVAL("decode_opc_mxu");
26736 gen_reserved_instruction(ctx
);
26743 * Decode MXU pool11
26745 * 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
26746 * +-----------+---------+---------+---+-------+-------+-----------+
26747 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26748 * +-----------+---------+---------+---+-------+-------+-----------+
26751 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26753 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26756 case OPC_MXU_S32SDIV
:
26757 /* TODO: Implement emulation of S32SDIV instruction. */
26758 MIPS_INVAL("OPC_MXU_S32SDIV");
26759 gen_reserved_instruction(ctx
);
26761 case OPC_MXU_S32SDIVR
:
26762 /* TODO: Implement emulation of S32SDIVR instruction. */
26763 MIPS_INVAL("OPC_MXU_S32SDIVR");
26764 gen_reserved_instruction(ctx
);
26767 MIPS_INVAL("decode_opc_mxu");
26768 gen_reserved_instruction(ctx
);
26775 * Decode MXU pool12
26777 * 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
26778 * +-----------+---+---+-------+-------+-------+-------+-----------+
26779 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26780 * +-----------+---+---+-------+-------+-------+-------+-----------+
26783 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26785 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26788 case OPC_MXU_D32ACC
:
26789 /* TODO: Implement emulation of D32ACC instruction. */
26790 MIPS_INVAL("OPC_MXU_D32ACC");
26791 gen_reserved_instruction(ctx
);
26793 case OPC_MXU_D32ACCM
:
26794 /* TODO: Implement emulation of D32ACCM instruction. */
26795 MIPS_INVAL("OPC_MXU_D32ACCM");
26796 gen_reserved_instruction(ctx
);
26798 case OPC_MXU_D32ASUM
:
26799 /* TODO: Implement emulation of D32ASUM instruction. */
26800 MIPS_INVAL("OPC_MXU_D32ASUM");
26801 gen_reserved_instruction(ctx
);
26804 MIPS_INVAL("decode_opc_mxu");
26805 gen_reserved_instruction(ctx
);
26812 * Decode MXU pool13
26814 * 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
26815 * +-----------+---+---+-------+-------+-------+-------+-----------+
26816 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26817 * +-----------+---+---+-------+-------+-------+-------+-----------+
26820 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26822 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26825 case OPC_MXU_Q16ACC
:
26826 /* TODO: Implement emulation of Q16ACC instruction. */
26827 MIPS_INVAL("OPC_MXU_Q16ACC");
26828 gen_reserved_instruction(ctx
);
26830 case OPC_MXU_Q16ACCM
:
26831 /* TODO: Implement emulation of Q16ACCM instruction. */
26832 MIPS_INVAL("OPC_MXU_Q16ACCM");
26833 gen_reserved_instruction(ctx
);
26835 case OPC_MXU_Q16ASUM
:
26836 /* TODO: Implement emulation of Q16ASUM instruction. */
26837 MIPS_INVAL("OPC_MXU_Q16ASUM");
26838 gen_reserved_instruction(ctx
);
26841 MIPS_INVAL("decode_opc_mxu");
26842 gen_reserved_instruction(ctx
);
26849 * Decode MXU pool14
26852 * 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
26853 * +-----------+---+---+-------+-------+-------+-------+-----------+
26854 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26855 * +-----------+---+---+-------+-------+-------+-------+-----------+
26858 * 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
26859 * +-----------+---+---+-------+-------+-------+-------+-----------+
26860 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26861 * +-----------+---+---+-------+-------+-------+-------+-----------+
26864 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26866 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26869 case OPC_MXU_Q8ADDE
:
26870 /* TODO: Implement emulation of Q8ADDE instruction. */
26871 MIPS_INVAL("OPC_MXU_Q8ADDE");
26872 gen_reserved_instruction(ctx
);
26874 case OPC_MXU_D8SUM
:
26875 /* TODO: Implement emulation of D8SUM instruction. */
26876 MIPS_INVAL("OPC_MXU_D8SUM");
26877 gen_reserved_instruction(ctx
);
26879 case OPC_MXU_D8SUMC
:
26880 /* TODO: Implement emulation of D8SUMC instruction. */
26881 MIPS_INVAL("OPC_MXU_D8SUMC");
26882 gen_reserved_instruction(ctx
);
26885 MIPS_INVAL("decode_opc_mxu");
26886 gen_reserved_instruction(ctx
);
26893 * Decode MXU pool15
26895 * S32MUL, S32MULU, S32EXTRV:
26896 * 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
26897 * +-----------+---------+---------+---+-------+-------+-----------+
26898 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26899 * +-----------+---------+---------+---+-------+-------+-----------+
26902 * 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
26903 * +-----------+---------+---------+---+-------+-------+-----------+
26904 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26905 * +-----------+---------+---------+---+-------+-------+-----------+
26908 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26910 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26913 case OPC_MXU_S32MUL
:
26914 /* TODO: Implement emulation of S32MUL instruction. */
26915 MIPS_INVAL("OPC_MXU_S32MUL");
26916 gen_reserved_instruction(ctx
);
26918 case OPC_MXU_S32MULU
:
26919 /* TODO: Implement emulation of S32MULU instruction. */
26920 MIPS_INVAL("OPC_MXU_S32MULU");
26921 gen_reserved_instruction(ctx
);
26923 case OPC_MXU_S32EXTR
:
26924 /* TODO: Implement emulation of S32EXTR instruction. */
26925 MIPS_INVAL("OPC_MXU_S32EXTR");
26926 gen_reserved_instruction(ctx
);
26928 case OPC_MXU_S32EXTRV
:
26929 /* TODO: Implement emulation of S32EXTRV instruction. */
26930 MIPS_INVAL("OPC_MXU_S32EXTRV");
26931 gen_reserved_instruction(ctx
);
26934 MIPS_INVAL("decode_opc_mxu");
26935 gen_reserved_instruction(ctx
);
26942 * Decode MXU pool16
26945 * 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
26946 * +-----------+---------+-----+-------+-------+-------+-----------+
26947 * | SPECIAL2 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
26948 * +-----------+---------+-----+-------+-------+-------+-----------+
26951 * 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
26952 * +-----------+---------+-----+-------+-------+-------+-----------+
26953 * | SPECIAL2 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26954 * +-----------+---------+-----+-------+-------+-------+-----------+
26957 * 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
26958 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26959 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26960 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26963 * 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
26964 * +-----------+-----+---+-----+-------+---------------+-----------+
26965 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26966 * +-----------+-----+---+-----+-------+---------------+-----------+
26968 * S32NOR, S32AND, S32OR, S32XOR:
26969 * 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
26970 * +-----------+---------+-----+-------+-------+-------+-----------+
26971 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26972 * +-----------+---------+-----+-------+-------+-------+-----------+
26975 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
26977 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26980 case OPC_MXU_D32SARW
:
26981 /* TODO: Implement emulation of D32SARW instruction. */
26982 MIPS_INVAL("OPC_MXU_D32SARW");
26983 gen_reserved_instruction(ctx
);
26985 case OPC_MXU_S32ALN
:
26986 /* TODO: Implement emulation of S32ALN instruction. */
26987 MIPS_INVAL("OPC_MXU_S32ALN");
26988 gen_reserved_instruction(ctx
);
26990 case OPC_MXU_S32ALNI
:
26991 gen_mxu_S32ALNI(ctx
);
26993 case OPC_MXU_S32LUI
:
26994 /* TODO: Implement emulation of S32LUI instruction. */
26995 MIPS_INVAL("OPC_MXU_S32LUI");
26996 gen_reserved_instruction(ctx
);
26998 case OPC_MXU_S32NOR
:
26999 gen_mxu_S32NOR(ctx
);
27001 case OPC_MXU_S32AND
:
27002 gen_mxu_S32AND(ctx
);
27004 case OPC_MXU_S32OR
:
27005 gen_mxu_S32OR(ctx
);
27007 case OPC_MXU_S32XOR
:
27008 gen_mxu_S32XOR(ctx
);
27011 MIPS_INVAL("decode_opc_mxu");
27012 gen_reserved_instruction(ctx
);
27019 * Decode MXU pool17
27021 * 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
27022 * +-----------+---------+---------+---+---------+-----+-----------+
27023 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
27024 * +-----------+---------+---------+---+---------+-----+-----------+
27027 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
27029 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
27033 /* TODO: Implement emulation of LXW instruction. */
27034 MIPS_INVAL("OPC_MXU_LXW");
27035 gen_reserved_instruction(ctx
);
27038 /* TODO: Implement emulation of LXH instruction. */
27039 MIPS_INVAL("OPC_MXU_LXH");
27040 gen_reserved_instruction(ctx
);
27043 /* TODO: Implement emulation of LXHU instruction. */
27044 MIPS_INVAL("OPC_MXU_LXHU");
27045 gen_reserved_instruction(ctx
);
27048 /* TODO: Implement emulation of LXB instruction. */
27049 MIPS_INVAL("OPC_MXU_LXB");
27050 gen_reserved_instruction(ctx
);
27053 /* TODO: Implement emulation of LXBU instruction. */
27054 MIPS_INVAL("OPC_MXU_LXBU");
27055 gen_reserved_instruction(ctx
);
27058 MIPS_INVAL("decode_opc_mxu");
27059 gen_reserved_instruction(ctx
);
27065 * Decode MXU pool18
27067 * 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
27068 * +-----------+---------+-----+-------+-------+-------+-----------+
27069 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
27070 * +-----------+---------+-----+-------+-------+-------+-----------+
27073 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
27075 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27078 case OPC_MXU_D32SLLV
:
27079 /* TODO: Implement emulation of D32SLLV instruction. */
27080 MIPS_INVAL("OPC_MXU_D32SLLV");
27081 gen_reserved_instruction(ctx
);
27083 case OPC_MXU_D32SLRV
:
27084 /* TODO: Implement emulation of D32SLRV instruction. */
27085 MIPS_INVAL("OPC_MXU_D32SLRV");
27086 gen_reserved_instruction(ctx
);
27088 case OPC_MXU_D32SARV
:
27089 /* TODO: Implement emulation of D32SARV instruction. */
27090 MIPS_INVAL("OPC_MXU_D32SARV");
27091 gen_reserved_instruction(ctx
);
27093 case OPC_MXU_Q16SLLV
:
27094 /* TODO: Implement emulation of Q16SLLV instruction. */
27095 MIPS_INVAL("OPC_MXU_Q16SLLV");
27096 gen_reserved_instruction(ctx
);
27098 case OPC_MXU_Q16SLRV
:
27099 /* TODO: Implement emulation of Q16SLRV instruction. */
27100 MIPS_INVAL("OPC_MXU_Q16SLRV");
27101 gen_reserved_instruction(ctx
);
27103 case OPC_MXU_Q16SARV
:
27104 /* TODO: Implement emulation of Q16SARV instruction. */
27105 MIPS_INVAL("OPC_MXU_Q16SARV");
27106 gen_reserved_instruction(ctx
);
27109 MIPS_INVAL("decode_opc_mxu");
27110 gen_reserved_instruction(ctx
);
27117 * Decode MXU pool19
27119 * 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
27120 * +-----------+---+---+-------+-------+-------+-------+-----------+
27121 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
27122 * +-----------+---+---+-------+-------+-------+-------+-----------+
27125 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
27127 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
27130 case OPC_MXU_Q8MUL
:
27131 case OPC_MXU_Q8MULSU
:
27132 gen_mxu_q8mul_q8mulsu(ctx
);
27135 MIPS_INVAL("decode_opc_mxu");
27136 gen_reserved_instruction(ctx
);
27143 * Decode MXU pool20
27145 * 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
27146 * +-----------+---------+-----+-------+-------+-------+-----------+
27147 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
27148 * +-----------+---------+-----+-------+-------+-------+-----------+
27151 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
27153 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
27156 case OPC_MXU_Q8MOVZ
:
27157 /* TODO: Implement emulation of Q8MOVZ instruction. */
27158 MIPS_INVAL("OPC_MXU_Q8MOVZ");
27159 gen_reserved_instruction(ctx
);
27161 case OPC_MXU_Q8MOVN
:
27162 /* TODO: Implement emulation of Q8MOVN instruction. */
27163 MIPS_INVAL("OPC_MXU_Q8MOVN");
27164 gen_reserved_instruction(ctx
);
27166 case OPC_MXU_D16MOVZ
:
27167 /* TODO: Implement emulation of D16MOVZ instruction. */
27168 MIPS_INVAL("OPC_MXU_D16MOVZ");
27169 gen_reserved_instruction(ctx
);
27171 case OPC_MXU_D16MOVN
:
27172 /* TODO: Implement emulation of D16MOVN instruction. */
27173 MIPS_INVAL("OPC_MXU_D16MOVN");
27174 gen_reserved_instruction(ctx
);
27176 case OPC_MXU_S32MOVZ
:
27177 /* TODO: Implement emulation of S32MOVZ instruction. */
27178 MIPS_INVAL("OPC_MXU_S32MOVZ");
27179 gen_reserved_instruction(ctx
);
27181 case OPC_MXU_S32MOVN
:
27182 /* TODO: Implement emulation of S32MOVN instruction. */
27183 MIPS_INVAL("OPC_MXU_S32MOVN");
27184 gen_reserved_instruction(ctx
);
27187 MIPS_INVAL("decode_opc_mxu");
27188 gen_reserved_instruction(ctx
);
27195 * Decode MXU pool21
27197 * 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
27198 * +-----------+---+---+-------+-------+-------+-------+-----------+
27199 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
27200 * +-----------+---+---+-------+-------+-------+-------+-----------+
27203 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
27205 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
27208 case OPC_MXU_Q8MAC
:
27209 /* TODO: Implement emulation of Q8MAC instruction. */
27210 MIPS_INVAL("OPC_MXU_Q8MAC");
27211 gen_reserved_instruction(ctx
);
27213 case OPC_MXU_Q8MACSU
:
27214 /* TODO: Implement emulation of Q8MACSU instruction. */
27215 MIPS_INVAL("OPC_MXU_Q8MACSU");
27216 gen_reserved_instruction(ctx
);
27219 MIPS_INVAL("decode_opc_mxu");
27220 gen_reserved_instruction(ctx
);
27227 * Main MXU decoding function
27229 * 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
27230 * +-----------+---------------------------------------+-----------+
27231 * | SPECIAL2 | |x x x x x x|
27232 * +-----------+---------------------------------------+-----------+
27235 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
27238 * TODO: Investigate necessity of including handling of
27239 * CLZ, CLO, SDBB in this function, as they belong to
27240 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
27242 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
27244 if (opcode
== OPC__MXU_MUL
) {
27245 uint32_t rs
, rt
, rd
, op1
;
27247 rs
= extract32(ctx
->opcode
, 21, 5);
27248 rt
= extract32(ctx
->opcode
, 16, 5);
27249 rd
= extract32(ctx
->opcode
, 11, 5);
27250 op1
= MASK_SPECIAL2(ctx
->opcode
);
27252 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27257 if (opcode
== OPC_MXU_S32M2I
) {
27258 gen_mxu_s32m2i(ctx
);
27262 if (opcode
== OPC_MXU_S32I2M
) {
27263 gen_mxu_s32i2m(ctx
);
27268 TCGv t_mxu_cr
= tcg_temp_new();
27269 TCGLabel
*l_exit
= gen_new_label();
27271 gen_load_mxu_cr(t_mxu_cr
);
27272 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
27273 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
27276 case OPC_MXU_S32MADD
:
27277 /* TODO: Implement emulation of S32MADD instruction. */
27278 MIPS_INVAL("OPC_MXU_S32MADD");
27279 gen_reserved_instruction(ctx
);
27281 case OPC_MXU_S32MADDU
:
27282 /* TODO: Implement emulation of S32MADDU instruction. */
27283 MIPS_INVAL("OPC_MXU_S32MADDU");
27284 gen_reserved_instruction(ctx
);
27286 case OPC_MXU__POOL00
:
27287 decode_opc_mxu__pool00(env
, ctx
);
27289 case OPC_MXU_S32MSUB
:
27290 /* TODO: Implement emulation of S32MSUB instruction. */
27291 MIPS_INVAL("OPC_MXU_S32MSUB");
27292 gen_reserved_instruction(ctx
);
27294 case OPC_MXU_S32MSUBU
:
27295 /* TODO: Implement emulation of S32MSUBU instruction. */
27296 MIPS_INVAL("OPC_MXU_S32MSUBU");
27297 gen_reserved_instruction(ctx
);
27299 case OPC_MXU__POOL01
:
27300 decode_opc_mxu__pool01(env
, ctx
);
27302 case OPC_MXU__POOL02
:
27303 decode_opc_mxu__pool02(env
, ctx
);
27305 case OPC_MXU_D16MUL
:
27306 gen_mxu_d16mul(ctx
);
27308 case OPC_MXU__POOL03
:
27309 decode_opc_mxu__pool03(env
, ctx
);
27311 case OPC_MXU_D16MAC
:
27312 gen_mxu_d16mac(ctx
);
27314 case OPC_MXU_D16MACF
:
27315 /* TODO: Implement emulation of D16MACF instruction. */
27316 MIPS_INVAL("OPC_MXU_D16MACF");
27317 gen_reserved_instruction(ctx
);
27319 case OPC_MXU_D16MADL
:
27320 /* TODO: Implement emulation of D16MADL instruction. */
27321 MIPS_INVAL("OPC_MXU_D16MADL");
27322 gen_reserved_instruction(ctx
);
27324 case OPC_MXU_S16MAD
:
27325 /* TODO: Implement emulation of S16MAD instruction. */
27326 MIPS_INVAL("OPC_MXU_S16MAD");
27327 gen_reserved_instruction(ctx
);
27329 case OPC_MXU_Q16ADD
:
27330 /* TODO: Implement emulation of Q16ADD instruction. */
27331 MIPS_INVAL("OPC_MXU_Q16ADD");
27332 gen_reserved_instruction(ctx
);
27334 case OPC_MXU_D16MACE
:
27335 /* TODO: Implement emulation of D16MACE instruction. */
27336 MIPS_INVAL("OPC_MXU_D16MACE");
27337 gen_reserved_instruction(ctx
);
27339 case OPC_MXU__POOL04
:
27340 decode_opc_mxu__pool04(env
, ctx
);
27342 case OPC_MXU__POOL05
:
27343 decode_opc_mxu__pool05(env
, ctx
);
27345 case OPC_MXU__POOL06
:
27346 decode_opc_mxu__pool06(env
, ctx
);
27348 case OPC_MXU__POOL07
:
27349 decode_opc_mxu__pool07(env
, ctx
);
27351 case OPC_MXU__POOL08
:
27352 decode_opc_mxu__pool08(env
, ctx
);
27354 case OPC_MXU__POOL09
:
27355 decode_opc_mxu__pool09(env
, ctx
);
27357 case OPC_MXU__POOL10
:
27358 decode_opc_mxu__pool10(env
, ctx
);
27360 case OPC_MXU__POOL11
:
27361 decode_opc_mxu__pool11(env
, ctx
);
27363 case OPC_MXU_D32ADD
:
27364 /* TODO: Implement emulation of D32ADD instruction. */
27365 MIPS_INVAL("OPC_MXU_D32ADD");
27366 gen_reserved_instruction(ctx
);
27368 case OPC_MXU__POOL12
:
27369 decode_opc_mxu__pool12(env
, ctx
);
27371 case OPC_MXU__POOL13
:
27372 decode_opc_mxu__pool13(env
, ctx
);
27374 case OPC_MXU__POOL14
:
27375 decode_opc_mxu__pool14(env
, ctx
);
27377 case OPC_MXU_Q8ACCE
:
27378 /* TODO: Implement emulation of Q8ACCE instruction. */
27379 MIPS_INVAL("OPC_MXU_Q8ACCE");
27380 gen_reserved_instruction(ctx
);
27382 case OPC_MXU_S8LDD
:
27383 gen_mxu_s8ldd(ctx
);
27385 case OPC_MXU_S8STD
:
27386 /* TODO: Implement emulation of S8STD instruction. */
27387 MIPS_INVAL("OPC_MXU_S8STD");
27388 gen_reserved_instruction(ctx
);
27390 case OPC_MXU_S8LDI
:
27391 /* TODO: Implement emulation of S8LDI instruction. */
27392 MIPS_INVAL("OPC_MXU_S8LDI");
27393 gen_reserved_instruction(ctx
);
27395 case OPC_MXU_S8SDI
:
27396 /* TODO: Implement emulation of S8SDI instruction. */
27397 MIPS_INVAL("OPC_MXU_S8SDI");
27398 gen_reserved_instruction(ctx
);
27400 case OPC_MXU__POOL15
:
27401 decode_opc_mxu__pool15(env
, ctx
);
27403 case OPC_MXU__POOL16
:
27404 decode_opc_mxu__pool16(env
, ctx
);
27406 case OPC_MXU__POOL17
:
27407 decode_opc_mxu__pool17(env
, ctx
);
27409 case OPC_MXU_S16LDD
:
27410 /* TODO: Implement emulation of S16LDD instruction. */
27411 MIPS_INVAL("OPC_MXU_S16LDD");
27412 gen_reserved_instruction(ctx
);
27414 case OPC_MXU_S16STD
:
27415 /* TODO: Implement emulation of S16STD instruction. */
27416 MIPS_INVAL("OPC_MXU_S16STD");
27417 gen_reserved_instruction(ctx
);
27419 case OPC_MXU_S16LDI
:
27420 /* TODO: Implement emulation of S16LDI instruction. */
27421 MIPS_INVAL("OPC_MXU_S16LDI");
27422 gen_reserved_instruction(ctx
);
27424 case OPC_MXU_S16SDI
:
27425 /* TODO: Implement emulation of S16SDI instruction. */
27426 MIPS_INVAL("OPC_MXU_S16SDI");
27427 gen_reserved_instruction(ctx
);
27429 case OPC_MXU_D32SLL
:
27430 /* TODO: Implement emulation of D32SLL instruction. */
27431 MIPS_INVAL("OPC_MXU_D32SLL");
27432 gen_reserved_instruction(ctx
);
27434 case OPC_MXU_D32SLR
:
27435 /* TODO: Implement emulation of D32SLR instruction. */
27436 MIPS_INVAL("OPC_MXU_D32SLR");
27437 gen_reserved_instruction(ctx
);
27439 case OPC_MXU_D32SARL
:
27440 /* TODO: Implement emulation of D32SARL instruction. */
27441 MIPS_INVAL("OPC_MXU_D32SARL");
27442 gen_reserved_instruction(ctx
);
27444 case OPC_MXU_D32SAR
:
27445 /* TODO: Implement emulation of D32SAR instruction. */
27446 MIPS_INVAL("OPC_MXU_D32SAR");
27447 gen_reserved_instruction(ctx
);
27449 case OPC_MXU_Q16SLL
:
27450 /* TODO: Implement emulation of Q16SLL instruction. */
27451 MIPS_INVAL("OPC_MXU_Q16SLL");
27452 gen_reserved_instruction(ctx
);
27454 case OPC_MXU_Q16SLR
:
27455 /* TODO: Implement emulation of Q16SLR instruction. */
27456 MIPS_INVAL("OPC_MXU_Q16SLR");
27457 gen_reserved_instruction(ctx
);
27459 case OPC_MXU__POOL18
:
27460 decode_opc_mxu__pool18(env
, ctx
);
27462 case OPC_MXU_Q16SAR
:
27463 /* TODO: Implement emulation of Q16SAR instruction. */
27464 MIPS_INVAL("OPC_MXU_Q16SAR");
27465 gen_reserved_instruction(ctx
);
27467 case OPC_MXU__POOL19
:
27468 decode_opc_mxu__pool19(env
, ctx
);
27470 case OPC_MXU__POOL20
:
27471 decode_opc_mxu__pool20(env
, ctx
);
27473 case OPC_MXU__POOL21
:
27474 decode_opc_mxu__pool21(env
, ctx
);
27476 case OPC_MXU_Q16SCOP
:
27477 /* TODO: Implement emulation of Q16SCOP instruction. */
27478 MIPS_INVAL("OPC_MXU_Q16SCOP");
27479 gen_reserved_instruction(ctx
);
27481 case OPC_MXU_Q8MADL
:
27482 /* TODO: Implement emulation of Q8MADL instruction. */
27483 MIPS_INVAL("OPC_MXU_Q8MADL");
27484 gen_reserved_instruction(ctx
);
27486 case OPC_MXU_S32SFL
:
27487 /* TODO: Implement emulation of S32SFL instruction. */
27488 MIPS_INVAL("OPC_MXU_S32SFL");
27489 gen_reserved_instruction(ctx
);
27491 case OPC_MXU_Q8SAD
:
27492 /* TODO: Implement emulation of Q8SAD instruction. */
27493 MIPS_INVAL("OPC_MXU_Q8SAD");
27494 gen_reserved_instruction(ctx
);
27497 MIPS_INVAL("decode_opc_mxu");
27498 gen_reserved_instruction(ctx
);
27501 gen_set_label(l_exit
);
27502 tcg_temp_free(t_mxu_cr
);
27506 #endif /* !defined(TARGET_MIPS64) */
27509 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27514 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
27516 rs
= (ctx
->opcode
>> 21) & 0x1f;
27517 rt
= (ctx
->opcode
>> 16) & 0x1f;
27518 rd
= (ctx
->opcode
>> 11) & 0x1f;
27520 op1
= MASK_SPECIAL2(ctx
->opcode
);
27522 case OPC_MADD
: /* Multiply and add/sub */
27526 check_insn(ctx
, ISA_MIPS_R1
);
27527 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
27530 gen_arith(ctx
, op1
, rd
, rs
, rt
);
27533 case OPC_DIVU_G_2F
:
27534 case OPC_MULT_G_2F
:
27535 case OPC_MULTU_G_2F
:
27537 case OPC_MODU_G_2F
:
27538 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27539 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27543 check_insn(ctx
, ISA_MIPS_R1
);
27544 gen_cl(ctx
, op1
, rd
, rs
);
27547 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
27548 gen_helper_do_semihosting(cpu_env
);
27551 * XXX: not clear which exception should be raised
27552 * when in debug mode...
27554 check_insn(ctx
, ISA_MIPS_R1
);
27555 generate_exception_end(ctx
, EXCP_DBp
);
27558 #if defined(TARGET_MIPS64)
27561 check_insn(ctx
, ISA_MIPS_R1
);
27562 check_mips_64(ctx
);
27563 gen_cl(ctx
, op1
, rd
, rs
);
27565 case OPC_DMULT_G_2F
:
27566 case OPC_DMULTU_G_2F
:
27567 case OPC_DDIV_G_2F
:
27568 case OPC_DDIVU_G_2F
:
27569 case OPC_DMOD_G_2F
:
27570 case OPC_DMODU_G_2F
:
27571 check_insn(ctx
, INSN_LOONGSON2F
| ASE_LEXT
);
27572 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27575 default: /* Invalid */
27576 MIPS_INVAL("special2_legacy");
27577 gen_reserved_instruction(ctx
);
27582 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27584 int rs
, rt
, rd
, sa
;
27588 rs
= (ctx
->opcode
>> 21) & 0x1f;
27589 rt
= (ctx
->opcode
>> 16) & 0x1f;
27590 rd
= (ctx
->opcode
>> 11) & 0x1f;
27591 sa
= (ctx
->opcode
>> 6) & 0x1f;
27592 imm
= (int16_t)ctx
->opcode
>> 7;
27594 op1
= MASK_SPECIAL3(ctx
->opcode
);
27598 /* hint codes 24-31 are reserved and signal RI */
27599 gen_reserved_instruction(ctx
);
27601 /* Treat as NOP. */
27604 check_cp0_enabled(ctx
);
27605 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27606 gen_cache_operation(ctx
, rt
, rs
, imm
);
27610 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27613 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27618 /* Treat as NOP. */
27621 op2
= MASK_BSHFL(ctx
->opcode
);
27627 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27630 gen_bitswap(ctx
, op2
, rd
, rt
);
27635 #ifndef CONFIG_USER_ONLY
27637 if (unlikely(ctx
->gi
<= 1)) {
27638 gen_reserved_instruction(ctx
);
27640 check_cp0_enabled(ctx
);
27641 switch ((ctx
->opcode
>> 6) & 3) {
27642 case 0: /* GINVI */
27643 /* Treat as NOP. */
27645 case 2: /* GINVT */
27646 gen_helper_0e1i(ginvt
, cpu_gpr
[rs
], extract32(ctx
->opcode
, 8, 2));
27649 gen_reserved_instruction(ctx
);
27654 #if defined(TARGET_MIPS64)
27656 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27659 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27662 check_mips_64(ctx
);
27665 /* Treat as NOP. */
27668 op2
= MASK_DBSHFL(ctx
->opcode
);
27678 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27681 gen_bitswap(ctx
, op2
, rd
, rt
);
27688 default: /* Invalid */
27689 MIPS_INVAL("special3_r6");
27690 gen_reserved_instruction(ctx
);
27695 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27700 rs
= (ctx
->opcode
>> 21) & 0x1f;
27701 rt
= (ctx
->opcode
>> 16) & 0x1f;
27702 rd
= (ctx
->opcode
>> 11) & 0x1f;
27704 op1
= MASK_SPECIAL3(ctx
->opcode
);
27707 case OPC_DIVU_G_2E
:
27709 case OPC_MODU_G_2E
:
27710 case OPC_MULT_G_2E
:
27711 case OPC_MULTU_G_2E
:
27713 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27714 * the same mask and op1.
27716 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27717 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27720 case OPC_ADDUH_R_QB
:
27722 case OPC_ADDQH_R_PH
:
27724 case OPC_ADDQH_R_W
:
27726 case OPC_SUBUH_R_QB
:
27728 case OPC_SUBQH_R_PH
:
27730 case OPC_SUBQH_R_W
:
27731 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27736 case OPC_MULQ_RS_W
:
27737 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27740 MIPS_INVAL("MASK ADDUH.QB");
27741 gen_reserved_instruction(ctx
);
27744 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27745 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27747 gen_reserved_instruction(ctx
);
27751 op2
= MASK_LX(ctx
->opcode
);
27753 #if defined(TARGET_MIPS64)
27759 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27761 default: /* Invalid */
27762 MIPS_INVAL("MASK LX");
27763 gen_reserved_instruction(ctx
);
27767 case OPC_ABSQ_S_PH_DSP
:
27768 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27770 case OPC_ABSQ_S_QB
:
27771 case OPC_ABSQ_S_PH
:
27773 case OPC_PRECEQ_W_PHL
:
27774 case OPC_PRECEQ_W_PHR
:
27775 case OPC_PRECEQU_PH_QBL
:
27776 case OPC_PRECEQU_PH_QBR
:
27777 case OPC_PRECEQU_PH_QBLA
:
27778 case OPC_PRECEQU_PH_QBRA
:
27779 case OPC_PRECEU_PH_QBL
:
27780 case OPC_PRECEU_PH_QBR
:
27781 case OPC_PRECEU_PH_QBLA
:
27782 case OPC_PRECEU_PH_QBRA
:
27783 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27790 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27793 MIPS_INVAL("MASK ABSQ_S.PH");
27794 gen_reserved_instruction(ctx
);
27798 case OPC_ADDU_QB_DSP
:
27799 op2
= MASK_ADDU_QB(ctx
->opcode
);
27802 case OPC_ADDQ_S_PH
:
27805 case OPC_ADDU_S_QB
:
27807 case OPC_ADDU_S_PH
:
27809 case OPC_SUBQ_S_PH
:
27812 case OPC_SUBU_S_QB
:
27814 case OPC_SUBU_S_PH
:
27818 case OPC_RADDU_W_QB
:
27819 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27821 case OPC_MULEU_S_PH_QBL
:
27822 case OPC_MULEU_S_PH_QBR
:
27823 case OPC_MULQ_RS_PH
:
27824 case OPC_MULEQ_S_W_PHL
:
27825 case OPC_MULEQ_S_W_PHR
:
27826 case OPC_MULQ_S_PH
:
27827 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27829 default: /* Invalid */
27830 MIPS_INVAL("MASK ADDU.QB");
27831 gen_reserved_instruction(ctx
);
27836 case OPC_CMPU_EQ_QB_DSP
:
27837 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27839 case OPC_PRECR_SRA_PH_W
:
27840 case OPC_PRECR_SRA_R_PH_W
:
27841 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27843 case OPC_PRECR_QB_PH
:
27844 case OPC_PRECRQ_QB_PH
:
27845 case OPC_PRECRQ_PH_W
:
27846 case OPC_PRECRQ_RS_PH_W
:
27847 case OPC_PRECRQU_S_QB_PH
:
27848 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27850 case OPC_CMPU_EQ_QB
:
27851 case OPC_CMPU_LT_QB
:
27852 case OPC_CMPU_LE_QB
:
27853 case OPC_CMP_EQ_PH
:
27854 case OPC_CMP_LT_PH
:
27855 case OPC_CMP_LE_PH
:
27856 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27858 case OPC_CMPGU_EQ_QB
:
27859 case OPC_CMPGU_LT_QB
:
27860 case OPC_CMPGU_LE_QB
:
27861 case OPC_CMPGDU_EQ_QB
:
27862 case OPC_CMPGDU_LT_QB
:
27863 case OPC_CMPGDU_LE_QB
:
27866 case OPC_PACKRL_PH
:
27867 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27869 default: /* Invalid */
27870 MIPS_INVAL("MASK CMPU.EQ.QB");
27871 gen_reserved_instruction(ctx
);
27875 case OPC_SHLL_QB_DSP
:
27876 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27878 case OPC_DPA_W_PH_DSP
:
27879 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27881 case OPC_DPAU_H_QBL
:
27882 case OPC_DPAU_H_QBR
:
27883 case OPC_DPSU_H_QBL
:
27884 case OPC_DPSU_H_QBR
:
27886 case OPC_DPAX_W_PH
:
27887 case OPC_DPAQ_S_W_PH
:
27888 case OPC_DPAQX_S_W_PH
:
27889 case OPC_DPAQX_SA_W_PH
:
27891 case OPC_DPSX_W_PH
:
27892 case OPC_DPSQ_S_W_PH
:
27893 case OPC_DPSQX_S_W_PH
:
27894 case OPC_DPSQX_SA_W_PH
:
27895 case OPC_MULSAQ_S_W_PH
:
27896 case OPC_DPAQ_SA_L_W
:
27897 case OPC_DPSQ_SA_L_W
:
27898 case OPC_MAQ_S_W_PHL
:
27899 case OPC_MAQ_S_W_PHR
:
27900 case OPC_MAQ_SA_W_PHL
:
27901 case OPC_MAQ_SA_W_PHR
:
27902 case OPC_MULSA_W_PH
:
27903 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27905 default: /* Invalid */
27906 MIPS_INVAL("MASK DPAW.PH");
27907 gen_reserved_instruction(ctx
);
27912 op2
= MASK_INSV(ctx
->opcode
);
27923 t0
= tcg_temp_new();
27924 t1
= tcg_temp_new();
27926 gen_load_gpr(t0
, rt
);
27927 gen_load_gpr(t1
, rs
);
27929 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27935 default: /* Invalid */
27936 MIPS_INVAL("MASK INSV");
27937 gen_reserved_instruction(ctx
);
27941 case OPC_APPEND_DSP
:
27942 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27944 case OPC_EXTR_W_DSP
:
27945 op2
= MASK_EXTR_W(ctx
->opcode
);
27949 case OPC_EXTR_RS_W
:
27951 case OPC_EXTRV_S_H
:
27953 case OPC_EXTRV_R_W
:
27954 case OPC_EXTRV_RS_W
:
27959 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27962 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27968 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27970 default: /* Invalid */
27971 MIPS_INVAL("MASK EXTR.W");
27972 gen_reserved_instruction(ctx
);
27976 #if defined(TARGET_MIPS64)
27977 case OPC_DDIV_G_2E
:
27978 case OPC_DDIVU_G_2E
:
27979 case OPC_DMULT_G_2E
:
27980 case OPC_DMULTU_G_2E
:
27981 case OPC_DMOD_G_2E
:
27982 case OPC_DMODU_G_2E
:
27983 check_insn(ctx
, INSN_LOONGSON2E
);
27984 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27986 case OPC_ABSQ_S_QH_DSP
:
27987 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
27989 case OPC_PRECEQ_L_PWL
:
27990 case OPC_PRECEQ_L_PWR
:
27991 case OPC_PRECEQ_PW_QHL
:
27992 case OPC_PRECEQ_PW_QHR
:
27993 case OPC_PRECEQ_PW_QHLA
:
27994 case OPC_PRECEQ_PW_QHRA
:
27995 case OPC_PRECEQU_QH_OBL
:
27996 case OPC_PRECEQU_QH_OBR
:
27997 case OPC_PRECEQU_QH_OBLA
:
27998 case OPC_PRECEQU_QH_OBRA
:
27999 case OPC_PRECEU_QH_OBL
:
28000 case OPC_PRECEU_QH_OBR
:
28001 case OPC_PRECEU_QH_OBLA
:
28002 case OPC_PRECEU_QH_OBRA
:
28003 case OPC_ABSQ_S_OB
:
28004 case OPC_ABSQ_S_PW
:
28005 case OPC_ABSQ_S_QH
:
28006 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28014 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
28016 default: /* Invalid */
28017 MIPS_INVAL("MASK ABSQ_S.QH");
28018 gen_reserved_instruction(ctx
);
28022 case OPC_ADDU_OB_DSP
:
28023 op2
= MASK_ADDU_OB(ctx
->opcode
);
28025 case OPC_RADDU_L_OB
:
28027 case OPC_SUBQ_S_PW
:
28029 case OPC_SUBQ_S_QH
:
28031 case OPC_SUBU_S_OB
:
28033 case OPC_SUBU_S_QH
:
28035 case OPC_SUBUH_R_OB
:
28037 case OPC_ADDQ_S_PW
:
28039 case OPC_ADDQ_S_QH
:
28041 case OPC_ADDU_S_OB
:
28043 case OPC_ADDU_S_QH
:
28045 case OPC_ADDUH_R_OB
:
28046 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28048 case OPC_MULEQ_S_PW_QHL
:
28049 case OPC_MULEQ_S_PW_QHR
:
28050 case OPC_MULEU_S_QH_OBL
:
28051 case OPC_MULEU_S_QH_OBR
:
28052 case OPC_MULQ_RS_QH
:
28053 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
28055 default: /* Invalid */
28056 MIPS_INVAL("MASK ADDU.OB");
28057 gen_reserved_instruction(ctx
);
28061 case OPC_CMPU_EQ_OB_DSP
:
28062 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
28064 case OPC_PRECR_SRA_QH_PW
:
28065 case OPC_PRECR_SRA_R_QH_PW
:
28066 /* Return value is rt. */
28067 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
28069 case OPC_PRECR_OB_QH
:
28070 case OPC_PRECRQ_OB_QH
:
28071 case OPC_PRECRQ_PW_L
:
28072 case OPC_PRECRQ_QH_PW
:
28073 case OPC_PRECRQ_RS_QH_PW
:
28074 case OPC_PRECRQU_S_OB_QH
:
28075 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
28077 case OPC_CMPU_EQ_OB
:
28078 case OPC_CMPU_LT_OB
:
28079 case OPC_CMPU_LE_OB
:
28080 case OPC_CMP_EQ_QH
:
28081 case OPC_CMP_LT_QH
:
28082 case OPC_CMP_LE_QH
:
28083 case OPC_CMP_EQ_PW
:
28084 case OPC_CMP_LT_PW
:
28085 case OPC_CMP_LE_PW
:
28086 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28088 case OPC_CMPGDU_EQ_OB
:
28089 case OPC_CMPGDU_LT_OB
:
28090 case OPC_CMPGDU_LE_OB
:
28091 case OPC_CMPGU_EQ_OB
:
28092 case OPC_CMPGU_LT_OB
:
28093 case OPC_CMPGU_LE_OB
:
28094 case OPC_PACKRL_PW
:
28098 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
28100 default: /* Invalid */
28101 MIPS_INVAL("MASK CMPU_EQ.OB");
28102 gen_reserved_instruction(ctx
);
28106 case OPC_DAPPEND_DSP
:
28107 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
28109 case OPC_DEXTR_W_DSP
:
28110 op2
= MASK_DEXTR_W(ctx
->opcode
);
28117 case OPC_DEXTR_R_L
:
28118 case OPC_DEXTR_RS_L
:
28120 case OPC_DEXTR_R_W
:
28121 case OPC_DEXTR_RS_W
:
28122 case OPC_DEXTR_S_H
:
28124 case OPC_DEXTRV_R_L
:
28125 case OPC_DEXTRV_RS_L
:
28126 case OPC_DEXTRV_S_H
:
28128 case OPC_DEXTRV_R_W
:
28129 case OPC_DEXTRV_RS_W
:
28130 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
28135 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28137 default: /* Invalid */
28138 MIPS_INVAL("MASK EXTR.W");
28139 gen_reserved_instruction(ctx
);
28143 case OPC_DPAQ_W_QH_DSP
:
28144 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
28146 case OPC_DPAU_H_OBL
:
28147 case OPC_DPAU_H_OBR
:
28148 case OPC_DPSU_H_OBL
:
28149 case OPC_DPSU_H_OBR
:
28151 case OPC_DPAQ_S_W_QH
:
28153 case OPC_DPSQ_S_W_QH
:
28154 case OPC_MULSAQ_S_W_QH
:
28155 case OPC_DPAQ_SA_L_PW
:
28156 case OPC_DPSQ_SA_L_PW
:
28157 case OPC_MULSAQ_S_L_PW
:
28158 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28160 case OPC_MAQ_S_W_QHLL
:
28161 case OPC_MAQ_S_W_QHLR
:
28162 case OPC_MAQ_S_W_QHRL
:
28163 case OPC_MAQ_S_W_QHRR
:
28164 case OPC_MAQ_SA_W_QHLL
:
28165 case OPC_MAQ_SA_W_QHLR
:
28166 case OPC_MAQ_SA_W_QHRL
:
28167 case OPC_MAQ_SA_W_QHRR
:
28168 case OPC_MAQ_S_L_PWL
:
28169 case OPC_MAQ_S_L_PWR
:
28174 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
28176 default: /* Invalid */
28177 MIPS_INVAL("MASK DPAQ.W.QH");
28178 gen_reserved_instruction(ctx
);
28182 case OPC_DINSV_DSP
:
28183 op2
= MASK_INSV(ctx
->opcode
);
28194 t0
= tcg_temp_new();
28195 t1
= tcg_temp_new();
28197 gen_load_gpr(t0
, rt
);
28198 gen_load_gpr(t1
, rs
);
28200 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
28206 default: /* Invalid */
28207 MIPS_INVAL("MASK DINSV");
28208 gen_reserved_instruction(ctx
);
28212 case OPC_SHLL_OB_DSP
:
28213 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
28216 default: /* Invalid */
28217 MIPS_INVAL("special3_legacy");
28218 gen_reserved_instruction(ctx
);
28224 #if defined(TARGET_MIPS64)
28226 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
28228 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
28231 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
28232 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
28233 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
28234 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
28235 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
28236 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
28237 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
28238 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
28239 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
28240 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
28241 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
28242 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
28243 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
28244 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
28245 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
28246 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
28247 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
28248 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
28249 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
28250 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
28251 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
28252 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
28253 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
28254 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
28255 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
28256 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI0 */
28259 MIPS_INVAL("TX79 MMI class MMI0");
28260 gen_reserved_instruction(ctx
);
28265 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
28267 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
28270 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
28271 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
28272 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
28273 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
28274 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
28275 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
28276 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
28277 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
28278 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
28279 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
28280 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
28281 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
28282 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
28283 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
28284 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
28285 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
28286 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
28287 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
28288 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI1 */
28291 MIPS_INVAL("TX79 MMI class MMI1");
28292 gen_reserved_instruction(ctx
);
28297 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
28299 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
28302 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
28303 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
28304 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
28305 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
28306 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
28307 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
28308 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
28309 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
28310 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
28311 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
28312 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
28313 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
28314 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
28315 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
28316 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
28317 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
28318 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
28319 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
28320 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
28321 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
28322 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
28323 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI2 */
28325 case MMI_OPC_2_PCPYLD
:
28326 gen_mmi_pcpyld(ctx
);
28329 MIPS_INVAL("TX79 MMI class MMI2");
28330 gen_reserved_instruction(ctx
);
28335 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
28337 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
28340 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
28341 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
28342 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
28343 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
28344 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
28345 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
28346 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
28347 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
28348 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
28349 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
28350 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
28351 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI3 */
28353 case MMI_OPC_3_PCPYH
:
28354 gen_mmi_pcpyh(ctx
);
28356 case MMI_OPC_3_PCPYUD
:
28357 gen_mmi_pcpyud(ctx
);
28360 MIPS_INVAL("TX79 MMI class MMI3");
28361 gen_reserved_instruction(ctx
);
28366 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
28368 uint32_t opc
= MASK_MMI(ctx
->opcode
);
28369 int rs
= extract32(ctx
->opcode
, 21, 5);
28370 int rt
= extract32(ctx
->opcode
, 16, 5);
28371 int rd
= extract32(ctx
->opcode
, 11, 5);
28374 case MMI_OPC_CLASS_MMI0
:
28375 decode_mmi0(env
, ctx
);
28377 case MMI_OPC_CLASS_MMI1
:
28378 decode_mmi1(env
, ctx
);
28380 case MMI_OPC_CLASS_MMI2
:
28381 decode_mmi2(env
, ctx
);
28383 case MMI_OPC_CLASS_MMI3
:
28384 decode_mmi3(env
, ctx
);
28386 case MMI_OPC_MULT1
:
28387 case MMI_OPC_MULTU1
:
28389 case MMI_OPC_MADDU
:
28390 case MMI_OPC_MADD1
:
28391 case MMI_OPC_MADDU1
:
28392 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
28395 case MMI_OPC_DIVU1
:
28396 gen_div1_tx79(ctx
, opc
, rs
, rt
);
28398 case MMI_OPC_MTLO1
:
28399 case MMI_OPC_MTHI1
:
28400 gen_HILO1_tx79(ctx
, opc
, rs
);
28402 case MMI_OPC_MFLO1
:
28403 case MMI_OPC_MFHI1
:
28404 gen_HILO1_tx79(ctx
, opc
, rd
);
28406 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
28407 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
28408 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
28409 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
28410 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
28411 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
28412 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
28413 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
28414 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
28415 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_CLASS_MMI */
28418 MIPS_INVAL("TX79 MMI class");
28419 gen_reserved_instruction(ctx
);
28424 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
28426 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_LQ */
28429 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
28431 gen_reserved_instruction(ctx
); /* TODO: MMI_OPC_SQ */
28435 * The TX79-specific instruction Store Quadword
28437 * +--------+-------+-------+------------------------+
28438 * | 011111 | base | rt | offset | SQ
28439 * +--------+-------+-------+------------------------+
28442 * has the same opcode as the Read Hardware Register instruction
28444 * +--------+-------+-------+-------+-------+--------+
28445 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
28446 * +--------+-------+-------+-------+-------+--------+
28449 * that is required, trapped and emulated by the Linux kernel. However, all
28450 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
28451 * offset is odd. Therefore all valid SQ instructions can execute normally.
28452 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
28453 * between SQ and RDHWR, as the Linux kernel does.
28455 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
28457 int base
= extract32(ctx
->opcode
, 21, 5);
28458 int rt
= extract32(ctx
->opcode
, 16, 5);
28459 int offset
= extract32(ctx
->opcode
, 0, 16);
28461 #ifdef CONFIG_USER_ONLY
28462 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
28463 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
28465 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
28466 int rd
= extract32(ctx
->opcode
, 11, 5);
28468 gen_rdhwr(ctx
, rt
, rd
, 0);
28473 gen_mmi_sq(ctx
, base
, rt
, offset
);
28478 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
28480 int rs
, rt
, rd
, sa
;
28484 rs
= (ctx
->opcode
>> 21) & 0x1f;
28485 rt
= (ctx
->opcode
>> 16) & 0x1f;
28486 rd
= (ctx
->opcode
>> 11) & 0x1f;
28487 sa
= (ctx
->opcode
>> 6) & 0x1f;
28488 imm
= sextract32(ctx
->opcode
, 7, 9);
28490 op1
= MASK_SPECIAL3(ctx
->opcode
);
28493 * EVA loads and stores overlap Loongson 2E instructions decoded by
28494 * decode_opc_special3_legacy(), so be careful to allow their decoding when
28501 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28509 check_cp0_enabled(ctx
);
28510 gen_ld(ctx
, op1
, rt
, rs
, imm
);
28514 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
28519 check_cp0_enabled(ctx
);
28520 gen_st(ctx
, op1
, rt
, rs
, imm
);
28523 check_cp0_enabled(ctx
);
28524 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
28527 check_cp0_enabled(ctx
);
28528 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
28529 gen_cache_operation(ctx
, rt
, rs
, imm
);
28531 /* Treat as NOP. */
28534 check_cp0_enabled(ctx
);
28535 /* Treat as NOP. */
28543 check_insn(ctx
, ISA_MIPS_R2
);
28544 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28547 op2
= MASK_BSHFL(ctx
->opcode
);
28554 check_insn(ctx
, ISA_MIPS_R6
);
28555 decode_opc_special3_r6(env
, ctx
);
28558 check_insn(ctx
, ISA_MIPS_R2
);
28559 gen_bshfl(ctx
, op2
, rt
, rd
);
28563 #if defined(TARGET_MIPS64)
28570 check_insn(ctx
, ISA_MIPS_R2
);
28571 check_mips_64(ctx
);
28572 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
28575 op2
= MASK_DBSHFL(ctx
->opcode
);
28586 check_insn(ctx
, ISA_MIPS_R6
);
28587 decode_opc_special3_r6(env
, ctx
);
28590 check_insn(ctx
, ISA_MIPS_R2
);
28591 check_mips_64(ctx
);
28592 op2
= MASK_DBSHFL(ctx
->opcode
);
28593 gen_bshfl(ctx
, op2
, rt
, rd
);
28599 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28604 TCGv t0
= tcg_temp_new();
28605 TCGv t1
= tcg_temp_new();
28607 gen_load_gpr(t0
, rt
);
28608 gen_load_gpr(t1
, rs
);
28609 gen_helper_fork(t0
, t1
);
28617 TCGv t0
= tcg_temp_new();
28619 gen_load_gpr(t0
, rs
);
28620 gen_helper_yield(t0
, cpu_env
, t0
);
28621 gen_store_gpr(t0
, rd
);
28626 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
28627 decode_opc_special3_r6(env
, ctx
);
28629 decode_opc_special3_legacy(env
, ctx
);
28634 /* MIPS SIMD Architecture (MSA) */
28635 static inline int check_msa_access(DisasContext
*ctx
)
28637 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
28638 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
28639 gen_reserved_instruction(ctx
);
28643 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
28644 if (ctx
->insn_flags
& ASE_MSA
) {
28645 generate_exception_end(ctx
, EXCP_MSADIS
);
28648 gen_reserved_instruction(ctx
);
28655 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
28657 /* generates tcg ops to check if any element is 0 */
28658 /* Note this function only works with MSA_WRLEN = 128 */
28659 uint64_t eval_zero_or_big
= 0;
28660 uint64_t eval_big
= 0;
28661 TCGv_i64 t0
= tcg_temp_new_i64();
28662 TCGv_i64 t1
= tcg_temp_new_i64();
28665 eval_zero_or_big
= 0x0101010101010101ULL
;
28666 eval_big
= 0x8080808080808080ULL
;
28669 eval_zero_or_big
= 0x0001000100010001ULL
;
28670 eval_big
= 0x8000800080008000ULL
;
28673 eval_zero_or_big
= 0x0000000100000001ULL
;
28674 eval_big
= 0x8000000080000000ULL
;
28677 eval_zero_or_big
= 0x0000000000000001ULL
;
28678 eval_big
= 0x8000000000000000ULL
;
28681 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<< 1], eval_zero_or_big
);
28682 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<< 1]);
28683 tcg_gen_andi_i64(t0
, t0
, eval_big
);
28684 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<< 1) + 1], eval_zero_or_big
);
28685 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<< 1) + 1]);
28686 tcg_gen_andi_i64(t1
, t1
, eval_big
);
28687 tcg_gen_or_i64(t0
, t0
, t1
);
28688 /* if all bits are zero then all elements are not zero */
28689 /* if some bit is non-zero then some element is zero */
28690 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
28691 tcg_gen_trunc_i64_tl(tresult
, t0
);
28692 tcg_temp_free_i64(t0
);
28693 tcg_temp_free_i64(t1
);
28696 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
28698 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28699 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28700 int64_t s16
= (int16_t)ctx
->opcode
;
28702 check_msa_access(ctx
);
28704 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
28705 gen_reserved_instruction(ctx
);
28712 TCGv_i64 t0
= tcg_temp_new_i64();
28713 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<< 1], msa_wr_d
[(wt
<< 1) + 1]);
28714 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
28715 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
28716 tcg_gen_trunc_i64_tl(bcond
, t0
);
28717 tcg_temp_free_i64(t0
);
28724 gen_check_zero_element(bcond
, df
, wt
);
28730 gen_check_zero_element(bcond
, df
, wt
);
28731 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
28735 ctx
->btarget
= ctx
->base
.pc_next
+ (s16
<< 2) + 4;
28737 ctx
->hflags
|= MIPS_HFLAG_BC
;
28738 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
28741 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
28743 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28744 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
28745 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28746 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28748 TCGv_i32 twd
= tcg_const_i32(wd
);
28749 TCGv_i32 tws
= tcg_const_i32(ws
);
28750 TCGv_i32 ti8
= tcg_const_i32(i8
);
28752 switch (MASK_MSA_I8(ctx
->opcode
)) {
28754 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
28757 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
28760 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
28763 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
28766 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
28769 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
28772 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
28778 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
28779 if (df
== DF_DOUBLE
) {
28780 gen_reserved_instruction(ctx
);
28782 TCGv_i32 tdf
= tcg_const_i32(df
);
28783 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
28784 tcg_temp_free_i32(tdf
);
28789 MIPS_INVAL("MSA instruction");
28790 gen_reserved_instruction(ctx
);
28794 tcg_temp_free_i32(twd
);
28795 tcg_temp_free_i32(tws
);
28796 tcg_temp_free_i32(ti8
);
28799 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
28801 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28802 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28803 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
28804 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
28805 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28806 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28808 TCGv_i32 tdf
= tcg_const_i32(df
);
28809 TCGv_i32 twd
= tcg_const_i32(wd
);
28810 TCGv_i32 tws
= tcg_const_i32(ws
);
28811 TCGv_i32 timm
= tcg_temp_new_i32();
28812 tcg_gen_movi_i32(timm
, u5
);
28814 switch (MASK_MSA_I5(ctx
->opcode
)) {
28816 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28819 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28821 case OPC_MAXI_S_df
:
28822 tcg_gen_movi_i32(timm
, s5
);
28823 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28825 case OPC_MAXI_U_df
:
28826 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28828 case OPC_MINI_S_df
:
28829 tcg_gen_movi_i32(timm
, s5
);
28830 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28832 case OPC_MINI_U_df
:
28833 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28836 tcg_gen_movi_i32(timm
, s5
);
28837 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28839 case OPC_CLTI_S_df
:
28840 tcg_gen_movi_i32(timm
, s5
);
28841 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28843 case OPC_CLTI_U_df
:
28844 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28846 case OPC_CLEI_S_df
:
28847 tcg_gen_movi_i32(timm
, s5
);
28848 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28850 case OPC_CLEI_U_df
:
28851 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28855 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
28856 tcg_gen_movi_i32(timm
, s10
);
28857 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
28861 MIPS_INVAL("MSA instruction");
28862 gen_reserved_instruction(ctx
);
28866 tcg_temp_free_i32(tdf
);
28867 tcg_temp_free_i32(twd
);
28868 tcg_temp_free_i32(tws
);
28869 tcg_temp_free_i32(timm
);
28872 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
28874 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28875 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
28876 uint32_t df
= 0, m
= 0;
28877 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28878 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28885 if ((dfm
& 0x40) == 0x00) {
28888 } else if ((dfm
& 0x60) == 0x40) {
28891 } else if ((dfm
& 0x70) == 0x60) {
28894 } else if ((dfm
& 0x78) == 0x70) {
28898 gen_reserved_instruction(ctx
);
28902 tdf
= tcg_const_i32(df
);
28903 tm
= tcg_const_i32(m
);
28904 twd
= tcg_const_i32(wd
);
28905 tws
= tcg_const_i32(ws
);
28907 switch (MASK_MSA_BIT(ctx
->opcode
)) {
28909 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28912 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
28915 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28918 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28921 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
28924 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
28926 case OPC_BINSLI_df
:
28927 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28929 case OPC_BINSRI_df
:
28930 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28933 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
28936 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
28939 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
28942 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28945 MIPS_INVAL("MSA instruction");
28946 gen_reserved_instruction(ctx
);
28950 tcg_temp_free_i32(tdf
);
28951 tcg_temp_free_i32(tm
);
28952 tcg_temp_free_i32(twd
);
28953 tcg_temp_free_i32(tws
);
28956 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
28958 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28959 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28960 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28961 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28962 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28964 TCGv_i32 tdf
= tcg_const_i32(df
);
28965 TCGv_i32 twd
= tcg_const_i32(wd
);
28966 TCGv_i32 tws
= tcg_const_i32(ws
);
28967 TCGv_i32 twt
= tcg_const_i32(wt
);
28969 switch (MASK_MSA_3R(ctx
->opcode
)) {
28973 gen_helper_msa_binsl_b(cpu_env
, twd
, tws
, twt
);
28976 gen_helper_msa_binsl_h(cpu_env
, twd
, tws
, twt
);
28979 gen_helper_msa_binsl_w(cpu_env
, twd
, tws
, twt
);
28982 gen_helper_msa_binsl_d(cpu_env
, twd
, tws
, twt
);
28989 gen_helper_msa_binsr_b(cpu_env
, twd
, tws
, twt
);
28992 gen_helper_msa_binsr_h(cpu_env
, twd
, tws
, twt
);
28995 gen_helper_msa_binsr_w(cpu_env
, twd
, tws
, twt
);
28998 gen_helper_msa_binsr_d(cpu_env
, twd
, tws
, twt
);
29005 gen_helper_msa_bclr_b(cpu_env
, twd
, tws
, twt
);
29008 gen_helper_msa_bclr_h(cpu_env
, twd
, tws
, twt
);
29011 gen_helper_msa_bclr_w(cpu_env
, twd
, tws
, twt
);
29014 gen_helper_msa_bclr_d(cpu_env
, twd
, tws
, twt
);
29021 gen_helper_msa_bneg_b(cpu_env
, twd
, tws
, twt
);
29024 gen_helper_msa_bneg_h(cpu_env
, twd
, tws
, twt
);
29027 gen_helper_msa_bneg_w(cpu_env
, twd
, tws
, twt
);
29030 gen_helper_msa_bneg_d(cpu_env
, twd
, tws
, twt
);
29037 gen_helper_msa_bset_b(cpu_env
, twd
, tws
, twt
);
29040 gen_helper_msa_bset_h(cpu_env
, twd
, tws
, twt
);
29043 gen_helper_msa_bset_w(cpu_env
, twd
, tws
, twt
);
29046 gen_helper_msa_bset_d(cpu_env
, twd
, tws
, twt
);
29053 gen_helper_msa_add_a_b(cpu_env
, twd
, tws
, twt
);
29056 gen_helper_msa_add_a_h(cpu_env
, twd
, tws
, twt
);
29059 gen_helper_msa_add_a_w(cpu_env
, twd
, tws
, twt
);
29062 gen_helper_msa_add_a_d(cpu_env
, twd
, tws
, twt
);
29066 case OPC_ADDS_A_df
:
29069 gen_helper_msa_adds_a_b(cpu_env
, twd
, tws
, twt
);
29072 gen_helper_msa_adds_a_h(cpu_env
, twd
, tws
, twt
);
29075 gen_helper_msa_adds_a_w(cpu_env
, twd
, tws
, twt
);
29078 gen_helper_msa_adds_a_d(cpu_env
, twd
, tws
, twt
);
29082 case OPC_ADDS_S_df
:
29085 gen_helper_msa_adds_s_b(cpu_env
, twd
, tws
, twt
);
29088 gen_helper_msa_adds_s_h(cpu_env
, twd
, tws
, twt
);
29091 gen_helper_msa_adds_s_w(cpu_env
, twd
, tws
, twt
);
29094 gen_helper_msa_adds_s_d(cpu_env
, twd
, tws
, twt
);
29098 case OPC_ADDS_U_df
:
29101 gen_helper_msa_adds_u_b(cpu_env
, twd
, tws
, twt
);
29104 gen_helper_msa_adds_u_h(cpu_env
, twd
, tws
, twt
);
29107 gen_helper_msa_adds_u_w(cpu_env
, twd
, tws
, twt
);
29110 gen_helper_msa_adds_u_d(cpu_env
, twd
, tws
, twt
);
29117 gen_helper_msa_addv_b(cpu_env
, twd
, tws
, twt
);
29120 gen_helper_msa_addv_h(cpu_env
, twd
, tws
, twt
);
29123 gen_helper_msa_addv_w(cpu_env
, twd
, tws
, twt
);
29126 gen_helper_msa_addv_d(cpu_env
, twd
, tws
, twt
);
29133 gen_helper_msa_ave_s_b(cpu_env
, twd
, tws
, twt
);
29136 gen_helper_msa_ave_s_h(cpu_env
, twd
, tws
, twt
);
29139 gen_helper_msa_ave_s_w(cpu_env
, twd
, tws
, twt
);
29142 gen_helper_msa_ave_s_d(cpu_env
, twd
, tws
, twt
);
29149 gen_helper_msa_ave_u_b(cpu_env
, twd
, tws
, twt
);
29152 gen_helper_msa_ave_u_h(cpu_env
, twd
, tws
, twt
);
29155 gen_helper_msa_ave_u_w(cpu_env
, twd
, tws
, twt
);
29158 gen_helper_msa_ave_u_d(cpu_env
, twd
, tws
, twt
);
29162 case OPC_AVER_S_df
:
29165 gen_helper_msa_aver_s_b(cpu_env
, twd
, tws
, twt
);
29168 gen_helper_msa_aver_s_h(cpu_env
, twd
, tws
, twt
);
29171 gen_helper_msa_aver_s_w(cpu_env
, twd
, tws
, twt
);
29174 gen_helper_msa_aver_s_d(cpu_env
, twd
, tws
, twt
);
29178 case OPC_AVER_U_df
:
29181 gen_helper_msa_aver_u_b(cpu_env
, twd
, tws
, twt
);
29184 gen_helper_msa_aver_u_h(cpu_env
, twd
, tws
, twt
);
29187 gen_helper_msa_aver_u_w(cpu_env
, twd
, tws
, twt
);
29190 gen_helper_msa_aver_u_d(cpu_env
, twd
, tws
, twt
);
29197 gen_helper_msa_ceq_b(cpu_env
, twd
, tws
, twt
);
29200 gen_helper_msa_ceq_h(cpu_env
, twd
, tws
, twt
);
29203 gen_helper_msa_ceq_w(cpu_env
, twd
, tws
, twt
);
29206 gen_helper_msa_ceq_d(cpu_env
, twd
, tws
, twt
);
29213 gen_helper_msa_cle_s_b(cpu_env
, twd
, tws
, twt
);
29216 gen_helper_msa_cle_s_h(cpu_env
, twd
, tws
, twt
);
29219 gen_helper_msa_cle_s_w(cpu_env
, twd
, tws
, twt
);
29222 gen_helper_msa_cle_s_d(cpu_env
, twd
, tws
, twt
);
29229 gen_helper_msa_cle_u_b(cpu_env
, twd
, tws
, twt
);
29232 gen_helper_msa_cle_u_h(cpu_env
, twd
, tws
, twt
);
29235 gen_helper_msa_cle_u_w(cpu_env
, twd
, tws
, twt
);
29238 gen_helper_msa_cle_u_d(cpu_env
, twd
, tws
, twt
);
29245 gen_helper_msa_clt_s_b(cpu_env
, twd
, tws
, twt
);
29248 gen_helper_msa_clt_s_h(cpu_env
, twd
, tws
, twt
);
29251 gen_helper_msa_clt_s_w(cpu_env
, twd
, tws
, twt
);
29254 gen_helper_msa_clt_s_d(cpu_env
, twd
, tws
, twt
);
29261 gen_helper_msa_clt_u_b(cpu_env
, twd
, tws
, twt
);
29264 gen_helper_msa_clt_u_h(cpu_env
, twd
, tws
, twt
);
29267 gen_helper_msa_clt_u_w(cpu_env
, twd
, tws
, twt
);
29270 gen_helper_msa_clt_u_d(cpu_env
, twd
, tws
, twt
);
29277 gen_helper_msa_div_s_b(cpu_env
, twd
, tws
, twt
);
29280 gen_helper_msa_div_s_h(cpu_env
, twd
, tws
, twt
);
29283 gen_helper_msa_div_s_w(cpu_env
, twd
, tws
, twt
);
29286 gen_helper_msa_div_s_d(cpu_env
, twd
, tws
, twt
);
29293 gen_helper_msa_div_u_b(cpu_env
, twd
, tws
, twt
);
29296 gen_helper_msa_div_u_h(cpu_env
, twd
, tws
, twt
);
29299 gen_helper_msa_div_u_w(cpu_env
, twd
, tws
, twt
);
29302 gen_helper_msa_div_u_d(cpu_env
, twd
, tws
, twt
);
29309 gen_helper_msa_max_a_b(cpu_env
, twd
, tws
, twt
);
29312 gen_helper_msa_max_a_h(cpu_env
, twd
, tws
, twt
);
29315 gen_helper_msa_max_a_w(cpu_env
, twd
, tws
, twt
);
29318 gen_helper_msa_max_a_d(cpu_env
, twd
, tws
, twt
);
29325 gen_helper_msa_max_s_b(cpu_env
, twd
, tws
, twt
);
29328 gen_helper_msa_max_s_h(cpu_env
, twd
, tws
, twt
);
29331 gen_helper_msa_max_s_w(cpu_env
, twd
, tws
, twt
);
29334 gen_helper_msa_max_s_d(cpu_env
, twd
, tws
, twt
);
29341 gen_helper_msa_max_u_b(cpu_env
, twd
, tws
, twt
);
29344 gen_helper_msa_max_u_h(cpu_env
, twd
, tws
, twt
);
29347 gen_helper_msa_max_u_w(cpu_env
, twd
, tws
, twt
);
29350 gen_helper_msa_max_u_d(cpu_env
, twd
, tws
, twt
);
29357 gen_helper_msa_min_a_b(cpu_env
, twd
, tws
, twt
);
29360 gen_helper_msa_min_a_h(cpu_env
, twd
, tws
, twt
);
29363 gen_helper_msa_min_a_w(cpu_env
, twd
, tws
, twt
);
29366 gen_helper_msa_min_a_d(cpu_env
, twd
, tws
, twt
);
29373 gen_helper_msa_min_s_b(cpu_env
, twd
, tws
, twt
);
29376 gen_helper_msa_min_s_h(cpu_env
, twd
, tws
, twt
);
29379 gen_helper_msa_min_s_w(cpu_env
, twd
, tws
, twt
);
29382 gen_helper_msa_min_s_d(cpu_env
, twd
, tws
, twt
);
29389 gen_helper_msa_min_u_b(cpu_env
, twd
, tws
, twt
);
29392 gen_helper_msa_min_u_h(cpu_env
, twd
, tws
, twt
);
29395 gen_helper_msa_min_u_w(cpu_env
, twd
, tws
, twt
);
29398 gen_helper_msa_min_u_d(cpu_env
, twd
, tws
, twt
);
29405 gen_helper_msa_mod_s_b(cpu_env
, twd
, tws
, twt
);
29408 gen_helper_msa_mod_s_h(cpu_env
, twd
, tws
, twt
);
29411 gen_helper_msa_mod_s_w(cpu_env
, twd
, tws
, twt
);
29414 gen_helper_msa_mod_s_d(cpu_env
, twd
, tws
, twt
);
29421 gen_helper_msa_mod_u_b(cpu_env
, twd
, tws
, twt
);
29424 gen_helper_msa_mod_u_h(cpu_env
, twd
, tws
, twt
);
29427 gen_helper_msa_mod_u_w(cpu_env
, twd
, tws
, twt
);
29430 gen_helper_msa_mod_u_d(cpu_env
, twd
, tws
, twt
);
29437 gen_helper_msa_maddv_b(cpu_env
, twd
, tws
, twt
);
29440 gen_helper_msa_maddv_h(cpu_env
, twd
, tws
, twt
);
29443 gen_helper_msa_maddv_w(cpu_env
, twd
, tws
, twt
);
29446 gen_helper_msa_maddv_d(cpu_env
, twd
, tws
, twt
);
29453 gen_helper_msa_msubv_b(cpu_env
, twd
, tws
, twt
);
29456 gen_helper_msa_msubv_h(cpu_env
, twd
, tws
, twt
);
29459 gen_helper_msa_msubv_w(cpu_env
, twd
, tws
, twt
);
29462 gen_helper_msa_msubv_d(cpu_env
, twd
, tws
, twt
);
29466 case OPC_ASUB_S_df
:
29469 gen_helper_msa_asub_s_b(cpu_env
, twd
, tws
, twt
);
29472 gen_helper_msa_asub_s_h(cpu_env
, twd
, tws
, twt
);
29475 gen_helper_msa_asub_s_w(cpu_env
, twd
, tws
, twt
);
29478 gen_helper_msa_asub_s_d(cpu_env
, twd
, tws
, twt
);
29482 case OPC_ASUB_U_df
:
29485 gen_helper_msa_asub_u_b(cpu_env
, twd
, tws
, twt
);
29488 gen_helper_msa_asub_u_h(cpu_env
, twd
, tws
, twt
);
29491 gen_helper_msa_asub_u_w(cpu_env
, twd
, tws
, twt
);
29494 gen_helper_msa_asub_u_d(cpu_env
, twd
, tws
, twt
);
29501 gen_helper_msa_ilvev_b(cpu_env
, twd
, tws
, twt
);
29504 gen_helper_msa_ilvev_h(cpu_env
, twd
, tws
, twt
);
29507 gen_helper_msa_ilvev_w(cpu_env
, twd
, tws
, twt
);
29510 gen_helper_msa_ilvev_d(cpu_env
, twd
, tws
, twt
);
29517 gen_helper_msa_ilvod_b(cpu_env
, twd
, tws
, twt
);
29520 gen_helper_msa_ilvod_h(cpu_env
, twd
, tws
, twt
);
29523 gen_helper_msa_ilvod_w(cpu_env
, twd
, tws
, twt
);
29526 gen_helper_msa_ilvod_d(cpu_env
, twd
, tws
, twt
);
29533 gen_helper_msa_ilvl_b(cpu_env
, twd
, tws
, twt
);
29536 gen_helper_msa_ilvl_h(cpu_env
, twd
, tws
, twt
);
29539 gen_helper_msa_ilvl_w(cpu_env
, twd
, tws
, twt
);
29542 gen_helper_msa_ilvl_d(cpu_env
, twd
, tws
, twt
);
29549 gen_helper_msa_ilvr_b(cpu_env
, twd
, tws
, twt
);
29552 gen_helper_msa_ilvr_h(cpu_env
, twd
, tws
, twt
);
29555 gen_helper_msa_ilvr_w(cpu_env
, twd
, tws
, twt
);
29558 gen_helper_msa_ilvr_d(cpu_env
, twd
, tws
, twt
);
29565 gen_helper_msa_pckev_b(cpu_env
, twd
, tws
, twt
);
29568 gen_helper_msa_pckev_h(cpu_env
, twd
, tws
, twt
);
29571 gen_helper_msa_pckev_w(cpu_env
, twd
, tws
, twt
);
29574 gen_helper_msa_pckev_d(cpu_env
, twd
, tws
, twt
);
29581 gen_helper_msa_pckod_b(cpu_env
, twd
, tws
, twt
);
29584 gen_helper_msa_pckod_h(cpu_env
, twd
, tws
, twt
);
29587 gen_helper_msa_pckod_w(cpu_env
, twd
, tws
, twt
);
29590 gen_helper_msa_pckod_d(cpu_env
, twd
, tws
, twt
);
29597 gen_helper_msa_sll_b(cpu_env
, twd
, tws
, twt
);
29600 gen_helper_msa_sll_h(cpu_env
, twd
, tws
, twt
);
29603 gen_helper_msa_sll_w(cpu_env
, twd
, tws
, twt
);
29606 gen_helper_msa_sll_d(cpu_env
, twd
, tws
, twt
);
29613 gen_helper_msa_sra_b(cpu_env
, twd
, tws
, twt
);
29616 gen_helper_msa_sra_h(cpu_env
, twd
, tws
, twt
);
29619 gen_helper_msa_sra_w(cpu_env
, twd
, tws
, twt
);
29622 gen_helper_msa_sra_d(cpu_env
, twd
, tws
, twt
);
29629 gen_helper_msa_srar_b(cpu_env
, twd
, tws
, twt
);
29632 gen_helper_msa_srar_h(cpu_env
, twd
, tws
, twt
);
29635 gen_helper_msa_srar_w(cpu_env
, twd
, tws
, twt
);
29638 gen_helper_msa_srar_d(cpu_env
, twd
, tws
, twt
);
29645 gen_helper_msa_srl_b(cpu_env
, twd
, tws
, twt
);
29648 gen_helper_msa_srl_h(cpu_env
, twd
, tws
, twt
);
29651 gen_helper_msa_srl_w(cpu_env
, twd
, tws
, twt
);
29654 gen_helper_msa_srl_d(cpu_env
, twd
, tws
, twt
);
29661 gen_helper_msa_srlr_b(cpu_env
, twd
, tws
, twt
);
29664 gen_helper_msa_srlr_h(cpu_env
, twd
, tws
, twt
);
29667 gen_helper_msa_srlr_w(cpu_env
, twd
, tws
, twt
);
29670 gen_helper_msa_srlr_d(cpu_env
, twd
, tws
, twt
);
29674 case OPC_SUBS_S_df
:
29677 gen_helper_msa_subs_s_b(cpu_env
, twd
, tws
, twt
);
29680 gen_helper_msa_subs_s_h(cpu_env
, twd
, tws
, twt
);
29683 gen_helper_msa_subs_s_w(cpu_env
, twd
, tws
, twt
);
29686 gen_helper_msa_subs_s_d(cpu_env
, twd
, tws
, twt
);
29693 gen_helper_msa_mulv_b(cpu_env
, twd
, tws
, twt
);
29696 gen_helper_msa_mulv_h(cpu_env
, twd
, tws
, twt
);
29699 gen_helper_msa_mulv_w(cpu_env
, twd
, tws
, twt
);
29702 gen_helper_msa_mulv_d(cpu_env
, twd
, tws
, twt
);
29707 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
29710 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29715 gen_helper_msa_subv_b(cpu_env
, twd
, tws
, twt
);
29718 gen_helper_msa_subv_h(cpu_env
, twd
, tws
, twt
);
29721 gen_helper_msa_subv_w(cpu_env
, twd
, tws
, twt
);
29724 gen_helper_msa_subv_d(cpu_env
, twd
, tws
, twt
);
29728 case OPC_SUBS_U_df
:
29731 gen_helper_msa_subs_u_b(cpu_env
, twd
, tws
, twt
);
29734 gen_helper_msa_subs_u_h(cpu_env
, twd
, tws
, twt
);
29737 gen_helper_msa_subs_u_w(cpu_env
, twd
, tws
, twt
);
29740 gen_helper_msa_subs_u_d(cpu_env
, twd
, tws
, twt
);
29745 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
29747 case OPC_SUBSUS_U_df
:
29750 gen_helper_msa_subsus_u_b(cpu_env
, twd
, tws
, twt
);
29753 gen_helper_msa_subsus_u_h(cpu_env
, twd
, tws
, twt
);
29756 gen_helper_msa_subsus_u_w(cpu_env
, twd
, tws
, twt
);
29759 gen_helper_msa_subsus_u_d(cpu_env
, twd
, tws
, twt
);
29763 case OPC_SUBSUU_S_df
:
29766 gen_helper_msa_subsuu_s_b(cpu_env
, twd
, tws
, twt
);
29769 gen_helper_msa_subsuu_s_h(cpu_env
, twd
, tws
, twt
);
29772 gen_helper_msa_subsuu_s_w(cpu_env
, twd
, tws
, twt
);
29775 gen_helper_msa_subsuu_s_d(cpu_env
, twd
, tws
, twt
);
29780 case OPC_DOTP_S_df
:
29781 case OPC_DOTP_U_df
:
29782 case OPC_DPADD_S_df
:
29783 case OPC_DPADD_U_df
:
29784 case OPC_DPSUB_S_df
:
29785 case OPC_HADD_S_df
:
29786 case OPC_DPSUB_U_df
:
29787 case OPC_HADD_U_df
:
29788 case OPC_HSUB_S_df
:
29789 case OPC_HSUB_U_df
:
29790 if (df
== DF_BYTE
) {
29791 gen_reserved_instruction(ctx
);
29794 switch (MASK_MSA_3R(ctx
->opcode
)) {
29795 case OPC_HADD_S_df
:
29798 gen_helper_msa_hadd_s_h(cpu_env
, twd
, tws
, twt
);
29801 gen_helper_msa_hadd_s_w(cpu_env
, twd
, tws
, twt
);
29804 gen_helper_msa_hadd_s_d(cpu_env
, twd
, tws
, twt
);
29808 case OPC_HADD_U_df
:
29811 gen_helper_msa_hadd_u_h(cpu_env
, twd
, tws
, twt
);
29814 gen_helper_msa_hadd_u_w(cpu_env
, twd
, tws
, twt
);
29817 gen_helper_msa_hadd_u_d(cpu_env
, twd
, tws
, twt
);
29821 case OPC_HSUB_S_df
:
29824 gen_helper_msa_hsub_s_h(cpu_env
, twd
, tws
, twt
);
29827 gen_helper_msa_hsub_s_w(cpu_env
, twd
, tws
, twt
);
29830 gen_helper_msa_hsub_s_d(cpu_env
, twd
, tws
, twt
);
29834 case OPC_HSUB_U_df
:
29837 gen_helper_msa_hsub_u_h(cpu_env
, twd
, tws
, twt
);
29840 gen_helper_msa_hsub_u_w(cpu_env
, twd
, tws
, twt
);
29843 gen_helper_msa_hsub_u_d(cpu_env
, twd
, tws
, twt
);
29847 case OPC_DOTP_S_df
:
29850 gen_helper_msa_dotp_s_h(cpu_env
, twd
, tws
, twt
);
29853 gen_helper_msa_dotp_s_w(cpu_env
, twd
, tws
, twt
);
29856 gen_helper_msa_dotp_s_d(cpu_env
, twd
, tws
, twt
);
29860 case OPC_DOTP_U_df
:
29863 gen_helper_msa_dotp_u_h(cpu_env
, twd
, tws
, twt
);
29866 gen_helper_msa_dotp_u_w(cpu_env
, twd
, tws
, twt
);
29869 gen_helper_msa_dotp_u_d(cpu_env
, twd
, tws
, twt
);
29873 case OPC_DPADD_S_df
:
29876 gen_helper_msa_dpadd_s_h(cpu_env
, twd
, tws
, twt
);
29879 gen_helper_msa_dpadd_s_w(cpu_env
, twd
, tws
, twt
);
29882 gen_helper_msa_dpadd_s_d(cpu_env
, twd
, tws
, twt
);
29886 case OPC_DPADD_U_df
:
29889 gen_helper_msa_dpadd_u_h(cpu_env
, twd
, tws
, twt
);
29892 gen_helper_msa_dpadd_u_w(cpu_env
, twd
, tws
, twt
);
29895 gen_helper_msa_dpadd_u_d(cpu_env
, twd
, tws
, twt
);
29899 case OPC_DPSUB_S_df
:
29902 gen_helper_msa_dpsub_s_h(cpu_env
, twd
, tws
, twt
);
29905 gen_helper_msa_dpsub_s_w(cpu_env
, twd
, tws
, twt
);
29908 gen_helper_msa_dpsub_s_d(cpu_env
, twd
, tws
, twt
);
29912 case OPC_DPSUB_U_df
:
29915 gen_helper_msa_dpsub_u_h(cpu_env
, twd
, tws
, twt
);
29918 gen_helper_msa_dpsub_u_w(cpu_env
, twd
, tws
, twt
);
29921 gen_helper_msa_dpsub_u_d(cpu_env
, twd
, tws
, twt
);
29928 MIPS_INVAL("MSA instruction");
29929 gen_reserved_instruction(ctx
);
29932 tcg_temp_free_i32(twd
);
29933 tcg_temp_free_i32(tws
);
29934 tcg_temp_free_i32(twt
);
29935 tcg_temp_free_i32(tdf
);
29938 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
29940 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
29941 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
29942 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
29943 TCGv telm
= tcg_temp_new();
29944 TCGv_i32 tsr
= tcg_const_i32(source
);
29945 TCGv_i32 tdt
= tcg_const_i32(dest
);
29947 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
29949 gen_load_gpr(telm
, source
);
29950 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
29953 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
29954 gen_store_gpr(telm
, dest
);
29957 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
29960 MIPS_INVAL("MSA instruction");
29961 gen_reserved_instruction(ctx
);
29965 tcg_temp_free(telm
);
29966 tcg_temp_free_i32(tdt
);
29967 tcg_temp_free_i32(tsr
);
29970 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
29973 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29974 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29975 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29977 TCGv_i32 tws
= tcg_const_i32(ws
);
29978 TCGv_i32 twd
= tcg_const_i32(wd
);
29979 TCGv_i32 tn
= tcg_const_i32(n
);
29980 TCGv_i32 tdf
= tcg_const_i32(df
);
29982 switch (MASK_MSA_ELM(ctx
->opcode
)) {
29984 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
29986 case OPC_SPLATI_df
:
29987 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
29990 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
29992 case OPC_COPY_S_df
:
29993 case OPC_COPY_U_df
:
29994 case OPC_INSERT_df
:
29995 #if !defined(TARGET_MIPS64)
29996 /* Double format valid only for MIPS64 */
29997 if (df
== DF_DOUBLE
) {
29998 gen_reserved_instruction(ctx
);
30001 if ((MASK_MSA_ELM(ctx
->opcode
) == OPC_COPY_U_df
) &&
30003 gen_reserved_instruction(ctx
);
30007 switch (MASK_MSA_ELM(ctx
->opcode
)) {
30008 case OPC_COPY_S_df
:
30009 if (likely(wd
!= 0)) {
30012 gen_helper_msa_copy_s_b(cpu_env
, twd
, tws
, tn
);
30015 gen_helper_msa_copy_s_h(cpu_env
, twd
, tws
, tn
);
30018 gen_helper_msa_copy_s_w(cpu_env
, twd
, tws
, tn
);
30020 #if defined(TARGET_MIPS64)
30022 gen_helper_msa_copy_s_d(cpu_env
, twd
, tws
, tn
);
30030 case OPC_COPY_U_df
:
30031 if (likely(wd
!= 0)) {
30034 gen_helper_msa_copy_u_b(cpu_env
, twd
, tws
, tn
);
30037 gen_helper_msa_copy_u_h(cpu_env
, twd
, tws
, tn
);
30039 #if defined(TARGET_MIPS64)
30041 gen_helper_msa_copy_u_w(cpu_env
, twd
, tws
, tn
);
30049 case OPC_INSERT_df
:
30052 gen_helper_msa_insert_b(cpu_env
, twd
, tws
, tn
);
30055 gen_helper_msa_insert_h(cpu_env
, twd
, tws
, tn
);
30058 gen_helper_msa_insert_w(cpu_env
, twd
, tws
, tn
);
30060 #if defined(TARGET_MIPS64)
30062 gen_helper_msa_insert_d(cpu_env
, twd
, tws
, tn
);
30072 MIPS_INVAL("MSA instruction");
30073 gen_reserved_instruction(ctx
);
30075 tcg_temp_free_i32(twd
);
30076 tcg_temp_free_i32(tws
);
30077 tcg_temp_free_i32(tn
);
30078 tcg_temp_free_i32(tdf
);
30081 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
30083 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
30084 uint32_t df
= 0, n
= 0;
30086 if ((dfn
& 0x30) == 0x00) {
30089 } else if ((dfn
& 0x38) == 0x20) {
30092 } else if ((dfn
& 0x3c) == 0x30) {
30095 } else if ((dfn
& 0x3e) == 0x38) {
30098 } else if (dfn
== 0x3E) {
30099 /* CTCMSA, CFCMSA, MOVE.V */
30100 gen_msa_elm_3e(env
, ctx
);
30103 gen_reserved_instruction(ctx
);
30107 gen_msa_elm_df(env
, ctx
, df
, n
);
30110 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
30112 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
30113 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
30114 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30115 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30116 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30118 TCGv_i32 twd
= tcg_const_i32(wd
);
30119 TCGv_i32 tws
= tcg_const_i32(ws
);
30120 TCGv_i32 twt
= tcg_const_i32(wt
);
30121 TCGv_i32 tdf
= tcg_temp_new_i32();
30123 /* adjust df value for floating-point instruction */
30124 tcg_gen_movi_i32(tdf
, df
+ 2);
30126 switch (MASK_MSA_3RF(ctx
->opcode
)) {
30128 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
30131 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
30134 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
30137 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
30140 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
30143 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30146 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
30149 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
30152 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30155 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
30158 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
30161 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
30164 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
30167 tcg_gen_movi_i32(tdf
, df
+ 1);
30168 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30171 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
30174 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
30176 case OPC_MADD_Q_df
:
30177 tcg_gen_movi_i32(tdf
, df
+ 1);
30178 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30181 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
30183 case OPC_MSUB_Q_df
:
30184 tcg_gen_movi_i32(tdf
, df
+ 1);
30185 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30188 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
30191 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
30194 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
30197 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
30200 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
30203 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
30206 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30209 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30212 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
30215 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
30218 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
30221 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
30224 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
30226 case OPC_MULR_Q_df
:
30227 tcg_gen_movi_i32(tdf
, df
+ 1);
30228 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30231 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
30233 case OPC_FMIN_A_df
:
30234 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
30236 case OPC_MADDR_Q_df
:
30237 tcg_gen_movi_i32(tdf
, df
+ 1);
30238 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30241 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
30244 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
30246 case OPC_MSUBR_Q_df
:
30247 tcg_gen_movi_i32(tdf
, df
+ 1);
30248 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
30251 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
30253 case OPC_FMAX_A_df
:
30254 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
30257 MIPS_INVAL("MSA instruction");
30258 gen_reserved_instruction(ctx
);
30262 tcg_temp_free_i32(twd
);
30263 tcg_temp_free_i32(tws
);
30264 tcg_temp_free_i32(twt
);
30265 tcg_temp_free_i32(tdf
);
30268 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
30270 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30271 (op & (0x7 << 18)))
30272 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30273 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30274 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30275 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
30276 TCGv_i32 twd
= tcg_const_i32(wd
);
30277 TCGv_i32 tws
= tcg_const_i32(ws
);
30278 TCGv_i32 twt
= tcg_const_i32(wt
);
30279 TCGv_i32 tdf
= tcg_const_i32(df
);
30281 switch (MASK_MSA_2R(ctx
->opcode
)) {
30283 #if !defined(TARGET_MIPS64)
30284 /* Double format valid only for MIPS64 */
30285 if (df
== DF_DOUBLE
) {
30286 gen_reserved_instruction(ctx
);
30290 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
30295 gen_helper_msa_nloc_b(cpu_env
, twd
, tws
);
30298 gen_helper_msa_nloc_h(cpu_env
, twd
, tws
);
30301 gen_helper_msa_nloc_w(cpu_env
, twd
, tws
);
30304 gen_helper_msa_nloc_d(cpu_env
, twd
, tws
);
30311 gen_helper_msa_nlzc_b(cpu_env
, twd
, tws
);
30314 gen_helper_msa_nlzc_h(cpu_env
, twd
, tws
);
30317 gen_helper_msa_nlzc_w(cpu_env
, twd
, tws
);
30320 gen_helper_msa_nlzc_d(cpu_env
, twd
, tws
);
30327 gen_helper_msa_pcnt_b(cpu_env
, twd
, tws
);
30330 gen_helper_msa_pcnt_h(cpu_env
, twd
, tws
);
30333 gen_helper_msa_pcnt_w(cpu_env
, twd
, tws
);
30336 gen_helper_msa_pcnt_d(cpu_env
, twd
, tws
);
30341 MIPS_INVAL("MSA instruction");
30342 gen_reserved_instruction(ctx
);
30346 tcg_temp_free_i32(twd
);
30347 tcg_temp_free_i32(tws
);
30348 tcg_temp_free_i32(twt
);
30349 tcg_temp_free_i32(tdf
);
30352 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
30354 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
30355 (op & (0xf << 17)))
30356 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30357 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30358 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30359 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
30360 TCGv_i32 twd
= tcg_const_i32(wd
);
30361 TCGv_i32 tws
= tcg_const_i32(ws
);
30362 TCGv_i32 twt
= tcg_const_i32(wt
);
30363 /* adjust df value for floating-point instruction */
30364 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
30366 switch (MASK_MSA_2RF(ctx
->opcode
)) {
30367 case OPC_FCLASS_df
:
30368 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
30370 case OPC_FTRUNC_S_df
:
30371 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
30373 case OPC_FTRUNC_U_df
:
30374 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
30377 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
30379 case OPC_FRSQRT_df
:
30380 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
30383 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
30386 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
30389 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
30391 case OPC_FEXUPL_df
:
30392 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
30394 case OPC_FEXUPR_df
:
30395 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
30398 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
30401 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
30403 case OPC_FTINT_S_df
:
30404 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
30406 case OPC_FTINT_U_df
:
30407 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
30409 case OPC_FFINT_S_df
:
30410 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
30412 case OPC_FFINT_U_df
:
30413 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
30417 tcg_temp_free_i32(twd
);
30418 tcg_temp_free_i32(tws
);
30419 tcg_temp_free_i32(twt
);
30420 tcg_temp_free_i32(tdf
);
30423 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
30425 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
30426 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
30427 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
30428 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30429 TCGv_i32 twd
= tcg_const_i32(wd
);
30430 TCGv_i32 tws
= tcg_const_i32(ws
);
30431 TCGv_i32 twt
= tcg_const_i32(wt
);
30433 switch (MASK_MSA_VEC(ctx
->opcode
)) {
30435 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
30438 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
30441 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
30444 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
30447 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
30450 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
30453 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
30456 MIPS_INVAL("MSA instruction");
30457 gen_reserved_instruction(ctx
);
30461 tcg_temp_free_i32(twd
);
30462 tcg_temp_free_i32(tws
);
30463 tcg_temp_free_i32(twt
);
30466 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
30468 switch (MASK_MSA_VEC(ctx
->opcode
)) {
30476 gen_msa_vec_v(env
, ctx
);
30479 gen_msa_2r(env
, ctx
);
30482 gen_msa_2rf(env
, ctx
);
30485 MIPS_INVAL("MSA instruction");
30486 gen_reserved_instruction(ctx
);
30491 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
30493 uint32_t opcode
= ctx
->opcode
;
30494 check_insn(ctx
, ASE_MSA
);
30495 check_msa_access(ctx
);
30497 switch (MASK_MSA_MINOR(opcode
)) {
30498 case OPC_MSA_I8_00
:
30499 case OPC_MSA_I8_01
:
30500 case OPC_MSA_I8_02
:
30501 gen_msa_i8(env
, ctx
);
30503 case OPC_MSA_I5_06
:
30504 case OPC_MSA_I5_07
:
30505 gen_msa_i5(env
, ctx
);
30507 case OPC_MSA_BIT_09
:
30508 case OPC_MSA_BIT_0A
:
30509 gen_msa_bit(env
, ctx
);
30511 case OPC_MSA_3R_0D
:
30512 case OPC_MSA_3R_0E
:
30513 case OPC_MSA_3R_0F
:
30514 case OPC_MSA_3R_10
:
30515 case OPC_MSA_3R_11
:
30516 case OPC_MSA_3R_12
:
30517 case OPC_MSA_3R_13
:
30518 case OPC_MSA_3R_14
:
30519 case OPC_MSA_3R_15
:
30520 gen_msa_3r(env
, ctx
);
30523 gen_msa_elm(env
, ctx
);
30525 case OPC_MSA_3RF_1A
:
30526 case OPC_MSA_3RF_1B
:
30527 case OPC_MSA_3RF_1C
:
30528 gen_msa_3rf(env
, ctx
);
30531 gen_msa_vec(env
, ctx
);
30542 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
30543 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
30544 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
30545 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
30547 TCGv_i32 twd
= tcg_const_i32(wd
);
30548 TCGv taddr
= tcg_temp_new();
30549 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
30551 switch (MASK_MSA_MINOR(opcode
)) {
30553 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
30556 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
30559 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
30562 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
30565 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
30568 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
30571 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
30574 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
30578 tcg_temp_free_i32(twd
);
30579 tcg_temp_free(taddr
);
30583 MIPS_INVAL("MSA instruction");
30584 gen_reserved_instruction(ctx
);
30590 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
30593 int rs
, rt
, rd
, sa
;
30597 /* make sure instructions are on a word boundary */
30598 if (ctx
->base
.pc_next
& 0x3) {
30599 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
30600 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
30604 /* Handle blikely not taken case */
30605 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
30606 TCGLabel
*l1
= gen_new_label();
30608 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
30609 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
30610 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
30614 op
= MASK_OP_MAJOR(ctx
->opcode
);
30615 rs
= (ctx
->opcode
>> 21) & 0x1f;
30616 rt
= (ctx
->opcode
>> 16) & 0x1f;
30617 rd
= (ctx
->opcode
>> 11) & 0x1f;
30618 sa
= (ctx
->opcode
>> 6) & 0x1f;
30619 imm
= (int16_t)ctx
->opcode
;
30622 decode_opc_special(env
, ctx
);
30625 #if defined(TARGET_MIPS64)
30626 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
30627 decode_mmi(env
, ctx
);
30629 if (ctx
->insn_flags
& ASE_MXU
) {
30630 decode_opc_mxu(env
, ctx
);
30633 decode_opc_special2_legacy(env
, ctx
);
30637 #if defined(TARGET_MIPS64)
30638 if (ctx
->insn_flags
& INSN_R5900
) {
30639 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
30641 decode_opc_special3(env
, ctx
);
30644 decode_opc_special3(env
, ctx
);
30648 op1
= MASK_REGIMM(ctx
->opcode
);
30650 case OPC_BLTZL
: /* REGIMM branches */
30654 check_insn(ctx
, ISA_MIPS2
);
30655 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30659 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30663 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30665 /* OPC_NAL, OPC_BAL */
30666 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
30668 gen_reserved_instruction(ctx
);
30671 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
30674 case OPC_TGEI
: /* REGIMM traps */
30681 check_insn(ctx
, ISA_MIPS2
);
30682 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30683 gen_trap(ctx
, op1
, rs
, -1, imm
);
30686 check_insn(ctx
, ISA_MIPS_R6
);
30687 gen_reserved_instruction(ctx
);
30690 check_insn(ctx
, ISA_MIPS_R2
);
30692 * Break the TB to be able to sync copied instructions
30695 ctx
->base
.is_jmp
= DISAS_STOP
;
30697 case OPC_BPOSGE32
: /* MIPS DSP branch */
30698 #if defined(TARGET_MIPS64)
30702 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
30704 #if defined(TARGET_MIPS64)
30706 check_insn(ctx
, ISA_MIPS_R6
);
30707 check_mips_64(ctx
);
30709 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
30713 check_insn(ctx
, ISA_MIPS_R6
);
30714 check_mips_64(ctx
);
30716 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
30720 default: /* Invalid */
30721 MIPS_INVAL("regimm");
30722 gen_reserved_instruction(ctx
);
30727 check_cp0_enabled(ctx
);
30728 op1
= MASK_CP0(ctx
->opcode
);
30736 #if defined(TARGET_MIPS64)
30740 #ifndef CONFIG_USER_ONLY
30741 gen_cp0(env
, ctx
, op1
, rt
, rd
);
30742 #endif /* !CONFIG_USER_ONLY */
30760 #ifndef CONFIG_USER_ONLY
30761 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
30762 #endif /* !CONFIG_USER_ONLY */
30765 #ifndef CONFIG_USER_ONLY
30768 TCGv t0
= tcg_temp_new();
30770 op2
= MASK_MFMC0(ctx
->opcode
);
30774 gen_helper_dmt(t0
);
30775 gen_store_gpr(t0
, rt
);
30779 gen_helper_emt(t0
);
30780 gen_store_gpr(t0
, rt
);
30784 gen_helper_dvpe(t0
, cpu_env
);
30785 gen_store_gpr(t0
, rt
);
30789 gen_helper_evpe(t0
, cpu_env
);
30790 gen_store_gpr(t0
, rt
);
30793 check_insn(ctx
, ISA_MIPS_R6
);
30795 gen_helper_dvp(t0
, cpu_env
);
30796 gen_store_gpr(t0
, rt
);
30800 check_insn(ctx
, ISA_MIPS_R6
);
30802 gen_helper_evp(t0
, cpu_env
);
30803 gen_store_gpr(t0
, rt
);
30807 check_insn(ctx
, ISA_MIPS_R2
);
30808 save_cpu_state(ctx
, 1);
30809 gen_helper_di(t0
, cpu_env
);
30810 gen_store_gpr(t0
, rt
);
30812 * Stop translation as we may have switched
30813 * the execution mode.
30815 ctx
->base
.is_jmp
= DISAS_STOP
;
30818 check_insn(ctx
, ISA_MIPS_R2
);
30819 save_cpu_state(ctx
, 1);
30820 gen_helper_ei(t0
, cpu_env
);
30821 gen_store_gpr(t0
, rt
);
30823 * DISAS_STOP isn't sufficient, we need to ensure we break
30824 * out of translated code to check for pending interrupts.
30826 gen_save_pc(ctx
->base
.pc_next
+ 4);
30827 ctx
->base
.is_jmp
= DISAS_EXIT
;
30829 default: /* Invalid */
30830 MIPS_INVAL("mfmc0");
30831 gen_reserved_instruction(ctx
);
30836 #endif /* !CONFIG_USER_ONLY */
30839 check_insn(ctx
, ISA_MIPS_R2
);
30840 gen_load_srsgpr(rt
, rd
);
30843 check_insn(ctx
, ISA_MIPS_R2
);
30844 gen_store_srsgpr(rt
, rd
);
30848 gen_reserved_instruction(ctx
);
30852 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
30853 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30854 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
30855 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30858 /* Arithmetic with immediate opcode */
30859 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30863 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30865 case OPC_SLTI
: /* Set on less than with immediate opcode */
30867 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
30869 case OPC_ANDI
: /* Arithmetic with immediate opcode */
30870 case OPC_LUI
: /* OPC_AUI */
30873 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
30875 case OPC_J
: /* Jump */
30877 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30878 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30881 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
30882 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30884 gen_reserved_instruction(ctx
);
30887 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
30888 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30891 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30894 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
30895 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
30897 gen_reserved_instruction(ctx
);
30900 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
30901 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30904 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30907 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
30910 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30912 check_insn(ctx
, ISA_MIPS_R6
);
30913 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
30914 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30917 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
30920 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30922 check_insn(ctx
, ISA_MIPS_R6
);
30923 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
30924 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30929 check_insn(ctx
, ISA_MIPS2
);
30930 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30934 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
30936 case OPC_LL
: /* Load and stores */
30937 check_insn(ctx
, ISA_MIPS2
);
30938 if (ctx
->insn_flags
& INSN_R5900
) {
30939 check_insn_opc_user_only(ctx
, INSN_R5900
);
30944 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30952 gen_ld(ctx
, op
, rt
, rs
, imm
);
30956 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30961 gen_st(ctx
, op
, rt
, rs
, imm
);
30964 check_insn(ctx
, ISA_MIPS2
);
30965 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30966 if (ctx
->insn_flags
& INSN_R5900
) {
30967 check_insn_opc_user_only(ctx
, INSN_R5900
);
30969 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
30972 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30973 check_cp0_enabled(ctx
);
30974 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS_R1
);
30975 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
30976 gen_cache_operation(ctx
, rt
, rs
, imm
);
30978 /* Treat as NOP. */
30981 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
30982 if (ctx
->insn_flags
& INSN_R5900
) {
30983 /* Treat as NOP. */
30985 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R1
);
30986 /* Treat as NOP. */
30990 /* Floating point (COP1). */
30995 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
30999 op1
= MASK_CP1(ctx
->opcode
);
31004 check_cp1_enabled(ctx
);
31005 check_insn(ctx
, ISA_MIPS_R2
);
31011 check_cp1_enabled(ctx
);
31012 gen_cp1(ctx
, op1
, rt
, rd
);
31014 #if defined(TARGET_MIPS64)
31017 check_cp1_enabled(ctx
);
31018 check_insn(ctx
, ISA_MIPS3
);
31019 check_mips_64(ctx
);
31020 gen_cp1(ctx
, op1
, rt
, rd
);
31023 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
31024 check_cp1_enabled(ctx
);
31025 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31027 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
31032 check_insn(ctx
, ASE_MIPS3D
);
31033 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
31034 (rt
>> 2) & 0x7, imm
<< 2);
31038 check_cp1_enabled(ctx
);
31039 check_insn(ctx
, ISA_MIPS_R6
);
31040 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
31044 check_cp1_enabled(ctx
);
31045 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31047 check_insn(ctx
, ASE_MIPS3D
);
31050 check_cp1_enabled(ctx
);
31051 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31052 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
31053 (rt
>> 2) & 0x7, imm
<< 2);
31060 check_cp1_enabled(ctx
);
31061 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
31067 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
31068 check_cp1_enabled(ctx
);
31069 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31071 case R6_OPC_CMP_AF_S
:
31072 case R6_OPC_CMP_UN_S
:
31073 case R6_OPC_CMP_EQ_S
:
31074 case R6_OPC_CMP_UEQ_S
:
31075 case R6_OPC_CMP_LT_S
:
31076 case R6_OPC_CMP_ULT_S
:
31077 case R6_OPC_CMP_LE_S
:
31078 case R6_OPC_CMP_ULE_S
:
31079 case R6_OPC_CMP_SAF_S
:
31080 case R6_OPC_CMP_SUN_S
:
31081 case R6_OPC_CMP_SEQ_S
:
31082 case R6_OPC_CMP_SEUQ_S
:
31083 case R6_OPC_CMP_SLT_S
:
31084 case R6_OPC_CMP_SULT_S
:
31085 case R6_OPC_CMP_SLE_S
:
31086 case R6_OPC_CMP_SULE_S
:
31087 case R6_OPC_CMP_OR_S
:
31088 case R6_OPC_CMP_UNE_S
:
31089 case R6_OPC_CMP_NE_S
:
31090 case R6_OPC_CMP_SOR_S
:
31091 case R6_OPC_CMP_SUNE_S
:
31092 case R6_OPC_CMP_SNE_S
:
31093 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
31095 case R6_OPC_CMP_AF_D
:
31096 case R6_OPC_CMP_UN_D
:
31097 case R6_OPC_CMP_EQ_D
:
31098 case R6_OPC_CMP_UEQ_D
:
31099 case R6_OPC_CMP_LT_D
:
31100 case R6_OPC_CMP_ULT_D
:
31101 case R6_OPC_CMP_LE_D
:
31102 case R6_OPC_CMP_ULE_D
:
31103 case R6_OPC_CMP_SAF_D
:
31104 case R6_OPC_CMP_SUN_D
:
31105 case R6_OPC_CMP_SEQ_D
:
31106 case R6_OPC_CMP_SEUQ_D
:
31107 case R6_OPC_CMP_SLT_D
:
31108 case R6_OPC_CMP_SULT_D
:
31109 case R6_OPC_CMP_SLE_D
:
31110 case R6_OPC_CMP_SULE_D
:
31111 case R6_OPC_CMP_OR_D
:
31112 case R6_OPC_CMP_UNE_D
:
31113 case R6_OPC_CMP_NE_D
:
31114 case R6_OPC_CMP_SOR_D
:
31115 case R6_OPC_CMP_SUNE_D
:
31116 case R6_OPC_CMP_SNE_D
:
31117 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
31120 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
31121 rt
, rd
, sa
, (imm
>> 8) & 0x7);
31126 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
31141 check_insn(ctx
, ASE_MSA
);
31142 gen_msa_branch(env
, ctx
, op1
);
31146 gen_reserved_instruction(ctx
);
31151 /* Compact branches [R6] and COP2 [non-R6] */
31152 case OPC_BC
: /* OPC_LWC2 */
31153 case OPC_BALC
: /* OPC_SWC2 */
31154 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31155 /* OPC_BC, OPC_BALC */
31156 gen_compute_compact_branch(ctx
, op
, 0, 0,
31157 sextract32(ctx
->opcode
<< 2, 0, 28));
31158 } else if (ctx
->insn_flags
& ASE_LEXT
) {
31159 gen_loongson_lswc2(ctx
, rt
, rs
, rd
);
31161 /* OPC_LWC2, OPC_SWC2 */
31162 /* COP2: Not implemented. */
31163 generate_exception_err(ctx
, EXCP_CpU
, 2);
31166 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
31167 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
31168 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31170 /* OPC_BEQZC, OPC_BNEZC */
31171 gen_compute_compact_branch(ctx
, op
, rs
, 0,
31172 sextract32(ctx
->opcode
<< 2, 0, 23));
31174 /* OPC_JIC, OPC_JIALC */
31175 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
31177 } else if (ctx
->insn_flags
& ASE_LEXT
) {
31178 gen_loongson_lsdc2(ctx
, rt
, rs
, rd
);
31180 /* OPC_LWC2, OPC_SWC2 */
31181 /* COP2: Not implemented. */
31182 generate_exception_err(ctx
, EXCP_CpU
, 2);
31186 check_insn(ctx
, ASE_LMMI
);
31187 /* Note that these instructions use different fields. */
31188 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
31192 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31193 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
31194 check_cp1_enabled(ctx
);
31195 op1
= MASK_CP3(ctx
->opcode
);
31199 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
31205 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
31206 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
31209 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
31210 /* Treat as NOP. */
31213 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS_R2
);
31227 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS_R2
);
31228 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
31232 gen_reserved_instruction(ctx
);
31236 generate_exception_err(ctx
, EXCP_CpU
, 1);
31240 #if defined(TARGET_MIPS64)
31241 /* MIPS64 opcodes */
31243 if (ctx
->insn_flags
& INSN_R5900
) {
31244 check_insn_opc_user_only(ctx
, INSN_R5900
);
31249 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31253 check_insn(ctx
, ISA_MIPS3
);
31254 check_mips_64(ctx
);
31255 gen_ld(ctx
, op
, rt
, rs
, imm
);
31259 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31262 check_insn(ctx
, ISA_MIPS3
);
31263 check_mips_64(ctx
);
31264 gen_st(ctx
, op
, rt
, rs
, imm
);
31267 check_insn_opc_removed(ctx
, ISA_MIPS_R6
);
31268 check_insn(ctx
, ISA_MIPS3
);
31269 if (ctx
->insn_flags
& INSN_R5900
) {
31270 check_insn_opc_user_only(ctx
, INSN_R5900
);
31272 check_mips_64(ctx
);
31273 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
31275 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
31276 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31277 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
31278 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
31281 check_insn(ctx
, ISA_MIPS3
);
31282 check_mips_64(ctx
);
31283 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
31287 check_insn(ctx
, ISA_MIPS3
);
31288 check_mips_64(ctx
);
31289 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
31292 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
31293 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31294 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
31296 MIPS_INVAL("major opcode");
31297 gen_reserved_instruction(ctx
);
31301 case OPC_DAUI
: /* OPC_JALX */
31302 if (ctx
->insn_flags
& ISA_MIPS_R6
) {
31303 #if defined(TARGET_MIPS64)
31305 check_mips_64(ctx
);
31307 generate_exception(ctx
, EXCP_RI
);
31308 } else if (rt
!= 0) {
31309 TCGv t0
= tcg_temp_new();
31310 gen_load_gpr(t0
, rs
);
31311 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
31315 gen_reserved_instruction(ctx
);
31316 MIPS_INVAL("major opcode");
31320 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
31321 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
31322 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
31325 case OPC_MSA
: /* OPC_MDMX */
31326 if (ctx
->insn_flags
& INSN_R5900
) {
31327 #if defined(TARGET_MIPS64)
31328 gen_mmi_lq(env
, ctx
); /* MMI_OPC_LQ */
31331 /* MDMX: Not implemented. */
31336 check_insn(ctx
, ISA_MIPS_R6
);
31337 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
31339 default: /* Invalid */
31340 MIPS_INVAL("major opcode");
31341 gen_reserved_instruction(ctx
);
31346 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
31348 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31349 CPUMIPSState
*env
= cs
->env_ptr
;
31351 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
31352 ctx
->saved_pc
= -1;
31353 ctx
->insn_flags
= env
->insn_flags
;
31354 ctx
->CP0_Config1
= env
->CP0_Config1
;
31355 ctx
->CP0_Config2
= env
->CP0_Config2
;
31356 ctx
->CP0_Config3
= env
->CP0_Config3
;
31357 ctx
->CP0_Config5
= env
->CP0_Config5
;
31359 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
31360 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
31361 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
31362 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
31363 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
31364 ctx
->PAMask
= env
->PAMask
;
31365 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
31366 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
31367 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
31368 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
31369 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
31370 /* Restore delay slot state from the tb context. */
31371 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
31372 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
31373 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
31374 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
31375 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
31376 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
31377 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
31378 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
31379 ctx
->mi
= (env
->CP0_Config5
>> CP0C5_MI
) & 1;
31380 ctx
->gi
= (env
->CP0_Config5
>> CP0C5_GI
) & 3;
31381 restore_cpu_state(env
, ctx
);
31382 #ifdef CONFIG_USER_ONLY
31383 ctx
->mem_idx
= MIPS_HFLAG_UM
;
31385 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
31387 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& (ISA_MIPS_R6
|
31388 INSN_LOONGSON3A
)) ? MO_UNALN
: MO_ALIGN
;
31390 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
31394 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
31398 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
31400 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31402 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
31406 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
31407 const CPUBreakpoint
*bp
)
31409 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31411 save_cpu_state(ctx
, 1);
31412 ctx
->base
.is_jmp
= DISAS_NORETURN
;
31413 gen_helper_raise_exception_debug(cpu_env
);
31415 * The address covered by the breakpoint must be included in
31416 * [tb->pc, tb->pc + tb->size) in order to for it to be
31417 * properly cleared -- thus we increment the PC here so that
31418 * the logic setting tb->size below does the right thing.
31420 ctx
->base
.pc_next
+= 4;
31424 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
31426 CPUMIPSState
*env
= cs
->env_ptr
;
31427 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31431 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
31432 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
31433 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31434 insn_bytes
= decode_nanomips_opc(env
, ctx
);
31435 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
31436 ctx
->opcode
= cpu_ldl_code(env
, ctx
->base
.pc_next
);
31438 decode_opc(env
, ctx
);
31439 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
31440 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31441 insn_bytes
= decode_micromips_opc(env
, ctx
);
31442 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
31443 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
31444 insn_bytes
= decode_mips16_opc(env
, ctx
);
31446 gen_reserved_instruction(ctx
);
31447 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
31451 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
31452 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
31453 MIPS_HFLAG_FBNSLOT
))) {
31455 * Force to generate branch as there is neither delay nor
31460 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
31461 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
31463 * Force to generate branch as microMIPS R6 doesn't restrict
31464 * branches in the forbidden slot.
31470 gen_branch(ctx
, insn_bytes
);
31472 ctx
->base
.pc_next
+= insn_bytes
;
31474 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
31478 * Execute a branch and its delay slot as a single instruction.
31479 * This is what GDB expects and is consistent with what the
31480 * hardware does (e.g. if a delay slot instruction faults, the
31481 * reported PC is the PC of the branch).
31483 if (ctx
->base
.singlestep_enabled
&&
31484 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
31485 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
31487 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
31488 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
31492 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
31494 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
31496 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
31497 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
31498 gen_helper_raise_exception_debug(cpu_env
);
31500 switch (ctx
->base
.is_jmp
) {
31502 gen_save_pc(ctx
->base
.pc_next
);
31503 tcg_gen_lookup_and_goto_ptr();
31506 case DISAS_TOO_MANY
:
31507 save_cpu_state(ctx
, 0);
31508 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
31511 tcg_gen_exit_tb(NULL
, 0);
31513 case DISAS_NORETURN
:
31516 g_assert_not_reached();
31521 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
31523 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
31524 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
31527 static const TranslatorOps mips_tr_ops
= {
31528 .init_disas_context
= mips_tr_init_disas_context
,
31529 .tb_start
= mips_tr_tb_start
,
31530 .insn_start
= mips_tr_insn_start
,
31531 .breakpoint_check
= mips_tr_breakpoint_check
,
31532 .translate_insn
= mips_tr_translate_insn
,
31533 .tb_stop
= mips_tr_tb_stop
,
31534 .disas_log
= mips_tr_disas_log
,
31537 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
31541 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
31544 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
31547 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
31549 #define printfpr(fp) \
31552 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31553 " fd:%13g fs:%13g psu: %13g\n", \
31554 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
31555 (double)(fp)->fd, \
31556 (double)(fp)->fs[FP_ENDIAN_IDX], \
31557 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
31560 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
31561 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
31562 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
31563 " fd:%13g fs:%13g psu:%13g\n", \
31564 tmp.w[FP_ENDIAN_IDX], tmp.d, \
31566 (double)tmp.fs[FP_ENDIAN_IDX], \
31567 (double)tmp.fs[!FP_ENDIAN_IDX]); \
31573 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
31574 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
31575 get_float_exception_flags(&env
->active_fpu
.fp_status
));
31576 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
31577 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
31578 printfpr(&env
->active_fpu
.fpr
[i
]);
31584 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
31586 MIPSCPU
*cpu
= MIPS_CPU(cs
);
31587 CPUMIPSState
*env
= &cpu
->env
;
31590 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
31591 " LO=0x" TARGET_FMT_lx
" ds %04x "
31592 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
31593 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
31594 env
->hflags
, env
->btarget
, env
->bcond
);
31595 for (i
= 0; i
< 32; i
++) {
31596 if ((i
& 3) == 0) {
31597 qemu_fprintf(f
, "GPR%02d:", i
);
31599 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
31600 regnames
[i
], env
->active_tc
.gpr
[i
]);
31601 if ((i
& 3) == 3) {
31602 qemu_fprintf(f
, "\n");
31606 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
31607 TARGET_FMT_lx
"\n",
31608 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
31609 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
31611 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
31612 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
31613 env
->CP0_Config2
, env
->CP0_Config3
);
31614 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
31615 env
->CP0_Config4
, env
->CP0_Config5
);
31616 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
31617 fpu_dump_state(env
, f
, flags
);
31621 void mips_tcg_init(void)
31626 for (i
= 1; i
< 32; i
++)
31627 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31628 offsetof(CPUMIPSState
,
31632 for (i
= 0; i
< 32; i
++) {
31633 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
31635 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
31637 * The scalar floating-point unit (FPU) registers are mapped on
31638 * the MSA vector registers.
31640 fpu_f64
[i
] = msa_wr_d
[i
* 2];
31641 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
31642 msa_wr_d
[i
* 2 + 1] =
31643 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
31646 cpu_PC
= tcg_global_mem_new(cpu_env
,
31647 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
31648 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
31649 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
31650 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
31652 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
31653 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
31656 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
31657 offsetof(CPUMIPSState
,
31658 active_tc
.DSPControl
),
31660 bcond
= tcg_global_mem_new(cpu_env
,
31661 offsetof(CPUMIPSState
, bcond
), "bcond");
31662 btarget
= tcg_global_mem_new(cpu_env
,
31663 offsetof(CPUMIPSState
, btarget
), "btarget");
31664 hflags
= tcg_global_mem_new_i32(cpu_env
,
31665 offsetof(CPUMIPSState
, hflags
), "hflags");
31667 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
31668 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
31670 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
31671 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
31673 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
31675 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
31678 #if defined(TARGET_MIPS64)
31680 for (i
= 1; i
< 32; i
++) {
31681 cpu_mmr
[i
] = tcg_global_mem_new_i64(cpu_env
,
31682 offsetof(CPUMIPSState
,
31688 #if !defined(TARGET_MIPS64)
31689 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
31690 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
31691 offsetof(CPUMIPSState
,
31692 active_tc
.mxu_gpr
[i
]),
31696 mxu_CR
= tcg_global_mem_new(cpu_env
,
31697 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
31698 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
31702 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
31703 target_ulong
*data
)
31705 env
->active_tc
.PC
= data
[0];
31706 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
31707 env
->hflags
|= data
[1];
31708 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
31709 case MIPS_HFLAG_BR
:
31711 case MIPS_HFLAG_BC
:
31712 case MIPS_HFLAG_BL
:
31714 env
->btarget
= data
[2];