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 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 "disas/disas.h"
28 #include "exec/exec-all.h"
30 #include "exec/cpu_ldst.h"
31 #include "hw/mips/cpudevs.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
35 #include "hw/semihosting/semihost.h"
37 #include "target/mips/trace.h"
38 #include "trace-tcg.h"
39 #include "exec/translator.h"
41 #include "qemu/qemu-print.h"
43 #define MIPS_DEBUG_DISAS 0
45 /* MIPS major opcodes */
46 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
49 /* indirect opcode tables */
50 OPC_SPECIAL
= (0x00 << 26),
51 OPC_REGIMM
= (0x01 << 26),
52 OPC_CP0
= (0x10 << 26),
53 OPC_CP1
= (0x11 << 26),
54 OPC_CP2
= (0x12 << 26),
55 OPC_CP3
= (0x13 << 26),
56 OPC_SPECIAL2
= (0x1C << 26),
57 OPC_SPECIAL3
= (0x1F << 26),
58 /* arithmetic with immediate */
59 OPC_ADDI
= (0x08 << 26),
60 OPC_ADDIU
= (0x09 << 26),
61 OPC_SLTI
= (0x0A << 26),
62 OPC_SLTIU
= (0x0B << 26),
63 /* logic with immediate */
64 OPC_ANDI
= (0x0C << 26),
65 OPC_ORI
= (0x0D << 26),
66 OPC_XORI
= (0x0E << 26),
67 OPC_LUI
= (0x0F << 26),
68 /* arithmetic with immediate */
69 OPC_DADDI
= (0x18 << 26),
70 OPC_DADDIU
= (0x19 << 26),
71 /* Jump and branches */
73 OPC_JAL
= (0x03 << 26),
74 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
75 OPC_BEQL
= (0x14 << 26),
76 OPC_BNE
= (0x05 << 26),
77 OPC_BNEL
= (0x15 << 26),
78 OPC_BLEZ
= (0x06 << 26),
79 OPC_BLEZL
= (0x16 << 26),
80 OPC_BGTZ
= (0x07 << 26),
81 OPC_BGTZL
= (0x17 << 26),
82 OPC_JALX
= (0x1D << 26),
83 OPC_DAUI
= (0x1D << 26),
85 OPC_LDL
= (0x1A << 26),
86 OPC_LDR
= (0x1B << 26),
87 OPC_LB
= (0x20 << 26),
88 OPC_LH
= (0x21 << 26),
89 OPC_LWL
= (0x22 << 26),
90 OPC_LW
= (0x23 << 26),
91 OPC_LWPC
= OPC_LW
| 0x5,
92 OPC_LBU
= (0x24 << 26),
93 OPC_LHU
= (0x25 << 26),
94 OPC_LWR
= (0x26 << 26),
95 OPC_LWU
= (0x27 << 26),
96 OPC_SB
= (0x28 << 26),
97 OPC_SH
= (0x29 << 26),
98 OPC_SWL
= (0x2A << 26),
99 OPC_SW
= (0x2B << 26),
100 OPC_SDL
= (0x2C << 26),
101 OPC_SDR
= (0x2D << 26),
102 OPC_SWR
= (0x2E << 26),
103 OPC_LL
= (0x30 << 26),
104 OPC_LLD
= (0x34 << 26),
105 OPC_LD
= (0x37 << 26),
106 OPC_LDPC
= OPC_LD
| 0x5,
107 OPC_SC
= (0x38 << 26),
108 OPC_SCD
= (0x3C << 26),
109 OPC_SD
= (0x3F << 26),
110 /* Floating point load/store */
111 OPC_LWC1
= (0x31 << 26),
112 OPC_LWC2
= (0x32 << 26),
113 OPC_LDC1
= (0x35 << 26),
114 OPC_LDC2
= (0x36 << 26),
115 OPC_SWC1
= (0x39 << 26),
116 OPC_SWC2
= (0x3A << 26),
117 OPC_SDC1
= (0x3D << 26),
118 OPC_SDC2
= (0x3E << 26),
119 /* Compact Branches */
120 OPC_BLEZALC
= (0x06 << 26),
121 OPC_BGEZALC
= (0x06 << 26),
122 OPC_BGEUC
= (0x06 << 26),
123 OPC_BGTZALC
= (0x07 << 26),
124 OPC_BLTZALC
= (0x07 << 26),
125 OPC_BLTUC
= (0x07 << 26),
126 OPC_BOVC
= (0x08 << 26),
127 OPC_BEQZALC
= (0x08 << 26),
128 OPC_BEQC
= (0x08 << 26),
129 OPC_BLEZC
= (0x16 << 26),
130 OPC_BGEZC
= (0x16 << 26),
131 OPC_BGEC
= (0x16 << 26),
132 OPC_BGTZC
= (0x17 << 26),
133 OPC_BLTZC
= (0x17 << 26),
134 OPC_BLTC
= (0x17 << 26),
135 OPC_BNVC
= (0x18 << 26),
136 OPC_BNEZALC
= (0x18 << 26),
137 OPC_BNEC
= (0x18 << 26),
138 OPC_BC
= (0x32 << 26),
139 OPC_BEQZC
= (0x36 << 26),
140 OPC_JIC
= (0x36 << 26),
141 OPC_BALC
= (0x3A << 26),
142 OPC_BNEZC
= (0x3E << 26),
143 OPC_JIALC
= (0x3E << 26),
144 /* MDMX ASE specific */
145 OPC_MDMX
= (0x1E << 26),
146 /* MSA ASE, same as MDMX */
148 /* Cache and prefetch */
149 OPC_CACHE
= (0x2F << 26),
150 OPC_PREF
= (0x33 << 26),
151 /* PC-relative address computation / loads */
152 OPC_PCREL
= (0x3B << 26),
155 /* PC-relative address computation / loads */
156 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
157 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
159 /* Instructions determined by bits 19 and 20 */
160 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
161 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
162 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
164 /* Instructions determined by bits 16 ... 20 */
165 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
166 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
169 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
172 /* MIPS special opcodes */
173 #define MASK_SPECIAL(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
177 OPC_SLL
= 0x00 | OPC_SPECIAL
,
178 /* NOP is SLL r0, r0, 0 */
179 /* SSNOP is SLL r0, r0, 1 */
180 /* EHB is SLL r0, r0, 3 */
181 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
182 OPC_ROTR
= OPC_SRL
| (1 << 21),
183 OPC_SRA
= 0x03 | OPC_SPECIAL
,
184 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
185 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
186 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
187 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
188 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
189 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
190 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
191 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
192 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
193 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
194 OPC_DROTR
= OPC_DSRL
| (1 << 21),
195 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
196 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
197 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
198 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
199 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
200 /* Multiplication / division */
201 OPC_MULT
= 0x18 | OPC_SPECIAL
,
202 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
203 OPC_DIV
= 0x1A | OPC_SPECIAL
,
204 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
205 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
206 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
207 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
208 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
210 /* 2 registers arithmetic / logic */
211 OPC_ADD
= 0x20 | OPC_SPECIAL
,
212 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
213 OPC_SUB
= 0x22 | OPC_SPECIAL
,
214 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
215 OPC_AND
= 0x24 | OPC_SPECIAL
,
216 OPC_OR
= 0x25 | OPC_SPECIAL
,
217 OPC_XOR
= 0x26 | OPC_SPECIAL
,
218 OPC_NOR
= 0x27 | OPC_SPECIAL
,
219 OPC_SLT
= 0x2A | OPC_SPECIAL
,
220 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
221 OPC_DADD
= 0x2C | OPC_SPECIAL
,
222 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
223 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
224 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
226 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
227 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
229 OPC_TGE
= 0x30 | OPC_SPECIAL
,
230 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
231 OPC_TLT
= 0x32 | OPC_SPECIAL
,
232 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
233 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
234 OPC_TNE
= 0x36 | OPC_SPECIAL
,
235 /* HI / LO registers load & stores */
236 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
237 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
238 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
239 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
240 /* Conditional moves */
241 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
242 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
244 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
245 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
247 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
250 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
251 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
252 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
253 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
254 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
256 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
257 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
258 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
259 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
263 * R6 Multiply and Divide instructions have the same opcode
264 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
266 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
269 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
270 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
271 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
272 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
273 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
274 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
275 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
276 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
278 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
279 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
280 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
281 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
282 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
283 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
284 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
285 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
287 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
288 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
289 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
290 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
291 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
293 OPC_LSA
= 0x05 | OPC_SPECIAL
,
294 OPC_DLSA
= 0x15 | OPC_SPECIAL
,
297 /* Multiplication variants of the vr54xx. */
298 #define MASK_MUL_VR54XX(op) (MASK_SPECIAL(op) | (op & (0x1F << 6)))
301 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
302 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
303 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
304 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
305 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
306 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
307 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
308 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
309 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
310 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
311 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
312 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
313 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
314 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
317 /* REGIMM (rt field) opcodes */
318 #define MASK_REGIMM(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
321 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
322 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
323 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
324 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
325 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
326 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
327 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
328 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
329 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
330 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
331 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
332 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
333 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
334 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
335 OPC_SIGRIE
= (0x17 << 16) | OPC_REGIMM
,
336 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
338 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
339 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
342 /* Special2 opcodes */
343 #define MASK_SPECIAL2(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
346 /* Multiply & xxx operations */
347 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
348 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
349 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
350 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
351 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
353 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
354 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
355 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
356 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
357 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
358 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
359 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
360 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
361 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
362 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
363 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
364 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
366 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
367 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
368 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
369 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
371 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
374 /* Special3 opcodes */
375 #define MASK_SPECIAL3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
378 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
379 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
380 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
381 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
382 OPC_INS
= 0x04 | OPC_SPECIAL3
,
383 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
384 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
385 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
386 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
387 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
388 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
389 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
390 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
393 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
394 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
395 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
396 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
397 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
398 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
399 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
400 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
401 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
402 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
403 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
404 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
407 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
408 /* MIPS DSP Arithmetic */
409 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
410 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
411 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
412 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
413 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
414 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
415 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
416 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
417 /* MIPS DSP GPR-Based Shift Sub-class */
418 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
419 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
420 /* MIPS DSP Multiply Sub-class insns */
421 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
422 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
423 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
424 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
425 /* DSP Bit/Manipulation Sub-class */
426 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
427 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
428 /* MIPS DSP Append Sub-class */
429 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
430 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
431 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
432 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
433 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
436 OPC_LWLE
= 0x19 | OPC_SPECIAL3
,
437 OPC_LWRE
= 0x1A | OPC_SPECIAL3
,
438 OPC_CACHEE
= 0x1B | OPC_SPECIAL3
,
439 OPC_SBE
= 0x1C | OPC_SPECIAL3
,
440 OPC_SHE
= 0x1D | OPC_SPECIAL3
,
441 OPC_SCE
= 0x1E | OPC_SPECIAL3
,
442 OPC_SWE
= 0x1F | OPC_SPECIAL3
,
443 OPC_SWLE
= 0x21 | OPC_SPECIAL3
,
444 OPC_SWRE
= 0x22 | OPC_SPECIAL3
,
445 OPC_PREFE
= 0x23 | OPC_SPECIAL3
,
446 OPC_LBUE
= 0x28 | OPC_SPECIAL3
,
447 OPC_LHUE
= 0x29 | OPC_SPECIAL3
,
448 OPC_LBE
= 0x2C | OPC_SPECIAL3
,
449 OPC_LHE
= 0x2D | OPC_SPECIAL3
,
450 OPC_LLE
= 0x2E | OPC_SPECIAL3
,
451 OPC_LWE
= 0x2F | OPC_SPECIAL3
,
454 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
455 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
456 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
457 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
458 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
459 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
463 #define MASK_BSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
466 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
467 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
468 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
469 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp (010.00 to 010.11) */
470 OPC_ALIGN_1
= (0x09 << 6) | OPC_BSHFL
,
471 OPC_ALIGN_2
= (0x0A << 6) | OPC_BSHFL
,
472 OPC_ALIGN_3
= (0x0B << 6) | OPC_BSHFL
,
473 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
477 #define MASK_DBSHFL(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
480 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
481 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
482 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp (01.000 to 01.111) */
483 OPC_DALIGN_1
= (0x09 << 6) | OPC_DBSHFL
,
484 OPC_DALIGN_2
= (0x0A << 6) | OPC_DBSHFL
,
485 OPC_DALIGN_3
= (0x0B << 6) | OPC_DBSHFL
,
486 OPC_DALIGN_4
= (0x0C << 6) | OPC_DBSHFL
,
487 OPC_DALIGN_5
= (0x0D << 6) | OPC_DBSHFL
,
488 OPC_DALIGN_6
= (0x0E << 6) | OPC_DBSHFL
,
489 OPC_DALIGN_7
= (0x0F << 6) | OPC_DBSHFL
,
490 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
493 /* MIPS DSP REGIMM opcodes */
495 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
496 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
499 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
502 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
503 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
504 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
505 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
508 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
510 /* MIPS DSP Arithmetic Sub-class */
511 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
512 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
513 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
514 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
515 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
516 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
517 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
518 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
519 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
520 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
521 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
522 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
523 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
524 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
525 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
526 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
527 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
528 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
529 /* MIPS DSP Multiply Sub-class insns */
530 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
531 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
532 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
533 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
534 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
535 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
538 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
539 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
541 /* MIPS DSP Arithmetic Sub-class */
542 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
543 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
544 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
545 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
546 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
547 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
548 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
549 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
550 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
551 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
552 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
553 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
554 /* MIPS DSP Multiply Sub-class insns */
555 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
556 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
557 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
558 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
561 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
563 /* MIPS DSP Arithmetic Sub-class */
564 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
565 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
566 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
567 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
568 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
569 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
570 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
571 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
572 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
573 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
574 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
575 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
576 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
577 /* DSP Bit/Manipulation Sub-class */
578 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
579 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
580 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
581 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
582 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
585 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
587 /* MIPS DSP Arithmetic Sub-class */
588 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
589 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
590 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
591 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
592 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
593 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
594 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
595 /* DSP Compare-Pick Sub-class */
596 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
597 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
598 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
599 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
600 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
601 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
602 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
603 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
604 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
605 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
606 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
607 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
608 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
609 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
610 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
613 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
615 /* MIPS DSP GPR-Based Shift Sub-class */
616 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
617 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
618 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
619 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
620 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
621 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
622 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
623 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
624 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
625 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
626 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
627 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
628 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
629 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
630 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
631 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
632 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
633 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
634 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
635 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
636 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
637 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
640 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
642 /* MIPS DSP Multiply Sub-class insns */
643 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
644 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
645 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
646 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
647 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
648 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
649 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
650 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
651 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
652 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
653 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
654 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
655 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
656 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
657 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
658 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
659 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
660 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
661 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
662 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
663 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
664 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
667 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669 /* DSP Bit/Manipulation Sub-class */
670 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
673 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
675 /* MIPS DSP Append Sub-class */
676 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
677 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
678 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
681 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
683 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
684 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
685 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
686 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
687 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
688 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
689 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
690 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
691 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
692 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
693 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
694 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
695 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
696 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
697 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
698 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
699 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
700 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
703 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* MIPS DSP Arithmetic Sub-class */
706 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
707 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
708 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
709 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
710 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
711 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
712 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
713 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
714 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
715 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
716 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
717 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
718 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
719 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
720 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
721 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
722 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
723 /* DSP Bit/Manipulation Sub-class */
724 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
725 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
726 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
727 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
728 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
729 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
732 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
734 /* MIPS DSP Multiply Sub-class insns */
735 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
736 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
737 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
738 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
739 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
740 /* MIPS DSP Arithmetic Sub-class */
741 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
742 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
743 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
744 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
745 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
746 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
747 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
748 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
749 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
750 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
751 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
752 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
753 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
754 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
755 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
756 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
757 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
758 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
759 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
760 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
761 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
764 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
766 /* DSP Compare-Pick Sub-class */
767 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
768 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
769 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
770 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
771 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
772 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
773 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
774 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
775 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
776 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
777 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
778 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
779 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
780 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
781 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
782 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
783 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
784 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
785 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
786 /* MIPS DSP Arithmetic Sub-class */
787 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
788 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
789 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
790 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
791 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
792 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
793 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
794 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
797 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
799 /* DSP Append Sub-class */
800 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
801 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
802 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
803 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
806 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
808 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
809 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
810 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
811 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
812 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
813 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
814 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
815 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
816 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
817 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
818 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
819 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
820 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
821 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
822 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
823 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
824 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
825 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
826 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
827 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
828 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
829 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
832 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
834 /* DSP Bit/Manipulation Sub-class */
835 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
838 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
840 /* MIPS DSP Multiply Sub-class insns */
841 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
842 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
843 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
844 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
845 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
846 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
847 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
848 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
849 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
850 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
851 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
852 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
853 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
854 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
855 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
856 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
857 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
858 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
859 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
860 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
861 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
862 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
863 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
864 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
865 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
866 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
869 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
871 /* MIPS DSP GPR-Based Shift Sub-class */
872 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
873 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
874 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
875 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
876 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
877 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
878 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
879 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
880 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
881 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
882 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
883 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
884 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
885 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
886 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
887 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
888 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
889 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
890 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
891 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
892 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
893 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
894 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
895 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
896 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
897 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
900 /* Coprocessor 0 (rs field) */
901 #define MASK_CP0(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
904 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
905 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
906 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
907 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
908 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
909 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
910 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
911 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
912 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
913 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
914 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
915 OPC_C0
= (0x10 << 21) | OPC_CP0
,
916 OPC_C0_1
= (0x11 << 21) | OPC_CP0
,
917 OPC_C0_2
= (0x12 << 21) | OPC_CP0
,
918 OPC_C0_3
= (0x13 << 21) | OPC_CP0
,
919 OPC_C0_4
= (0x14 << 21) | OPC_CP0
,
920 OPC_C0_5
= (0x15 << 21) | OPC_CP0
,
921 OPC_C0_6
= (0x16 << 21) | OPC_CP0
,
922 OPC_C0_7
= (0x17 << 21) | OPC_CP0
,
923 OPC_C0_8
= (0x18 << 21) | OPC_CP0
,
924 OPC_C0_9
= (0x19 << 21) | OPC_CP0
,
925 OPC_C0_A
= (0x1A << 21) | OPC_CP0
,
926 OPC_C0_B
= (0x1B << 21) | OPC_CP0
,
927 OPC_C0_C
= (0x1C << 21) | OPC_CP0
,
928 OPC_C0_D
= (0x1D << 21) | OPC_CP0
,
929 OPC_C0_E
= (0x1E << 21) | OPC_CP0
,
930 OPC_C0_F
= (0x1F << 21) | OPC_CP0
,
934 #define MASK_MFMC0(op) (MASK_CP0(op) | (op & 0xFFFF))
937 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
938 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
939 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
940 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
941 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
942 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
943 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
944 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
947 /* Coprocessor 0 (with rs == C0) */
948 #define MASK_C0(op) (MASK_CP0(op) | (op & 0x3F))
951 OPC_TLBR
= 0x01 | OPC_C0
,
952 OPC_TLBWI
= 0x02 | OPC_C0
,
953 OPC_TLBINV
= 0x03 | OPC_C0
,
954 OPC_TLBINVF
= 0x04 | OPC_C0
,
955 OPC_TLBWR
= 0x06 | OPC_C0
,
956 OPC_TLBP
= 0x08 | OPC_C0
,
957 OPC_RFE
= 0x10 | OPC_C0
,
958 OPC_ERET
= 0x18 | OPC_C0
,
959 OPC_DERET
= 0x1F | OPC_C0
,
960 OPC_WAIT
= 0x20 | OPC_C0
,
963 /* Coprocessor 1 (rs field) */
964 #define MASK_CP1(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
966 /* Values for the fmt field in FP instructions */
968 /* 0 - 15 are reserved */
969 FMT_S
= 16, /* single fp */
970 FMT_D
= 17, /* double fp */
971 FMT_E
= 18, /* extended fp */
972 FMT_Q
= 19, /* quad fp */
973 FMT_W
= 20, /* 32-bit fixed */
974 FMT_L
= 21, /* 64-bit fixed */
975 FMT_PS
= 22, /* paired single fp */
976 /* 23 - 31 are reserved */
980 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
981 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
982 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
983 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
984 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
985 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
986 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
987 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
988 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
989 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
990 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
991 OPC_BZ_V
= (0x0B << 21) | OPC_CP1
,
992 OPC_BNZ_V
= (0x0F << 21) | OPC_CP1
,
993 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
994 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
995 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
996 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
997 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
998 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
999 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
1000 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
1001 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
1002 OPC_BZ_B
= (0x18 << 21) | OPC_CP1
,
1003 OPC_BZ_H
= (0x19 << 21) | OPC_CP1
,
1004 OPC_BZ_W
= (0x1A << 21) | OPC_CP1
,
1005 OPC_BZ_D
= (0x1B << 21) | OPC_CP1
,
1006 OPC_BNZ_B
= (0x1C << 21) | OPC_CP1
,
1007 OPC_BNZ_H
= (0x1D << 21) | OPC_CP1
,
1008 OPC_BNZ_W
= (0x1E << 21) | OPC_CP1
,
1009 OPC_BNZ_D
= (0x1F << 21) | OPC_CP1
,
1012 #define MASK_CP1_FUNC(op) (MASK_CP1(op) | (op & 0x3F))
1013 #define MASK_BC1(op) (MASK_CP1(op) | (op & (0x3 << 16)))
1016 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
1017 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
1018 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
1019 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
1023 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
1024 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
1028 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
1029 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
1032 #define MASK_CP2(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
1035 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
1036 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
1037 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
1038 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
1039 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
1040 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
1041 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
1042 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
1043 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
1044 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1045 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1048 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1051 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1052 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1053 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1054 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1055 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1056 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1057 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1058 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1060 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1061 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1062 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1063 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1064 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1065 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1066 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1067 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1069 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1070 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1071 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1072 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1073 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1074 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1075 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1076 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1078 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1079 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1080 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1081 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1082 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1083 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1084 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1085 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1087 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1088 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1089 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1090 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1091 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1092 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1094 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1095 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1096 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1097 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1098 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1099 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1101 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1102 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1103 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1104 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1105 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1106 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1108 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1109 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1110 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1111 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1112 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1113 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1115 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1116 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1117 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1118 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1119 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1120 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1122 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1123 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1124 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1125 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1126 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1127 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1129 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1130 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1131 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1132 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1133 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1134 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1136 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1137 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1138 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1139 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1140 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1141 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1145 #define MASK_CP3(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1148 OPC_LWXC1
= 0x00 | OPC_CP3
,
1149 OPC_LDXC1
= 0x01 | OPC_CP3
,
1150 OPC_LUXC1
= 0x05 | OPC_CP3
,
1151 OPC_SWXC1
= 0x08 | OPC_CP3
,
1152 OPC_SDXC1
= 0x09 | OPC_CP3
,
1153 OPC_SUXC1
= 0x0D | OPC_CP3
,
1154 OPC_PREFX
= 0x0F | OPC_CP3
,
1155 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1156 OPC_MADD_S
= 0x20 | OPC_CP3
,
1157 OPC_MADD_D
= 0x21 | OPC_CP3
,
1158 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1159 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1160 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1161 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1162 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1163 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1164 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1165 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1166 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1167 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1171 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1173 OPC_MSA_I8_00
= 0x00 | OPC_MSA
,
1174 OPC_MSA_I8_01
= 0x01 | OPC_MSA
,
1175 OPC_MSA_I8_02
= 0x02 | OPC_MSA
,
1176 OPC_MSA_I5_06
= 0x06 | OPC_MSA
,
1177 OPC_MSA_I5_07
= 0x07 | OPC_MSA
,
1178 OPC_MSA_BIT_09
= 0x09 | OPC_MSA
,
1179 OPC_MSA_BIT_0A
= 0x0A | OPC_MSA
,
1180 OPC_MSA_3R_0D
= 0x0D | OPC_MSA
,
1181 OPC_MSA_3R_0E
= 0x0E | OPC_MSA
,
1182 OPC_MSA_3R_0F
= 0x0F | OPC_MSA
,
1183 OPC_MSA_3R_10
= 0x10 | OPC_MSA
,
1184 OPC_MSA_3R_11
= 0x11 | OPC_MSA
,
1185 OPC_MSA_3R_12
= 0x12 | OPC_MSA
,
1186 OPC_MSA_3R_13
= 0x13 | OPC_MSA
,
1187 OPC_MSA_3R_14
= 0x14 | OPC_MSA
,
1188 OPC_MSA_3R_15
= 0x15 | OPC_MSA
,
1189 OPC_MSA_ELM
= 0x19 | OPC_MSA
,
1190 OPC_MSA_3RF_1A
= 0x1A | OPC_MSA
,
1191 OPC_MSA_3RF_1B
= 0x1B | OPC_MSA
,
1192 OPC_MSA_3RF_1C
= 0x1C | OPC_MSA
,
1193 OPC_MSA_VEC
= 0x1E | OPC_MSA
,
1195 /* MI10 instruction */
1196 OPC_LD_B
= (0x20) | OPC_MSA
,
1197 OPC_LD_H
= (0x21) | OPC_MSA
,
1198 OPC_LD_W
= (0x22) | OPC_MSA
,
1199 OPC_LD_D
= (0x23) | OPC_MSA
,
1200 OPC_ST_B
= (0x24) | OPC_MSA
,
1201 OPC_ST_H
= (0x25) | OPC_MSA
,
1202 OPC_ST_W
= (0x26) | OPC_MSA
,
1203 OPC_ST_D
= (0x27) | OPC_MSA
,
1207 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1208 OPC_ADDVI_df
= (0x0 << 23) | OPC_MSA_I5_06
,
1209 OPC_CEQI_df
= (0x0 << 23) | OPC_MSA_I5_07
,
1210 OPC_SUBVI_df
= (0x1 << 23) | OPC_MSA_I5_06
,
1211 OPC_MAXI_S_df
= (0x2 << 23) | OPC_MSA_I5_06
,
1212 OPC_CLTI_S_df
= (0x2 << 23) | OPC_MSA_I5_07
,
1213 OPC_MAXI_U_df
= (0x3 << 23) | OPC_MSA_I5_06
,
1214 OPC_CLTI_U_df
= (0x3 << 23) | OPC_MSA_I5_07
,
1215 OPC_MINI_S_df
= (0x4 << 23) | OPC_MSA_I5_06
,
1216 OPC_CLEI_S_df
= (0x4 << 23) | OPC_MSA_I5_07
,
1217 OPC_MINI_U_df
= (0x5 << 23) | OPC_MSA_I5_06
,
1218 OPC_CLEI_U_df
= (0x5 << 23) | OPC_MSA_I5_07
,
1219 OPC_LDI_df
= (0x6 << 23) | OPC_MSA_I5_07
,
1221 /* I8 instruction */
1222 OPC_ANDI_B
= (0x0 << 24) | OPC_MSA_I8_00
,
1223 OPC_BMNZI_B
= (0x0 << 24) | OPC_MSA_I8_01
,
1224 OPC_SHF_B
= (0x0 << 24) | OPC_MSA_I8_02
,
1225 OPC_ORI_B
= (0x1 << 24) | OPC_MSA_I8_00
,
1226 OPC_BMZI_B
= (0x1 << 24) | OPC_MSA_I8_01
,
1227 OPC_SHF_H
= (0x1 << 24) | OPC_MSA_I8_02
,
1228 OPC_NORI_B
= (0x2 << 24) | OPC_MSA_I8_00
,
1229 OPC_BSELI_B
= (0x2 << 24) | OPC_MSA_I8_01
,
1230 OPC_SHF_W
= (0x2 << 24) | OPC_MSA_I8_02
,
1231 OPC_XORI_B
= (0x3 << 24) | OPC_MSA_I8_00
,
1233 /* VEC/2R/2RF instruction */
1234 OPC_AND_V
= (0x00 << 21) | OPC_MSA_VEC
,
1235 OPC_OR_V
= (0x01 << 21) | OPC_MSA_VEC
,
1236 OPC_NOR_V
= (0x02 << 21) | OPC_MSA_VEC
,
1237 OPC_XOR_V
= (0x03 << 21) | OPC_MSA_VEC
,
1238 OPC_BMNZ_V
= (0x04 << 21) | OPC_MSA_VEC
,
1239 OPC_BMZ_V
= (0x05 << 21) | OPC_MSA_VEC
,
1240 OPC_BSEL_V
= (0x06 << 21) | OPC_MSA_VEC
,
1242 OPC_MSA_2R
= (0x18 << 21) | OPC_MSA_VEC
,
1243 OPC_MSA_2RF
= (0x19 << 21) | OPC_MSA_VEC
,
1245 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1246 OPC_FILL_df
= (0x00 << 18) | OPC_MSA_2R
,
1247 OPC_PCNT_df
= (0x01 << 18) | OPC_MSA_2R
,
1248 OPC_NLOC_df
= (0x02 << 18) | OPC_MSA_2R
,
1249 OPC_NLZC_df
= (0x03 << 18) | OPC_MSA_2R
,
1251 /* 2RF instruction df(bit 16) = _w, _d */
1252 OPC_FCLASS_df
= (0x00 << 17) | OPC_MSA_2RF
,
1253 OPC_FTRUNC_S_df
= (0x01 << 17) | OPC_MSA_2RF
,
1254 OPC_FTRUNC_U_df
= (0x02 << 17) | OPC_MSA_2RF
,
1255 OPC_FSQRT_df
= (0x03 << 17) | OPC_MSA_2RF
,
1256 OPC_FRSQRT_df
= (0x04 << 17) | OPC_MSA_2RF
,
1257 OPC_FRCP_df
= (0x05 << 17) | OPC_MSA_2RF
,
1258 OPC_FRINT_df
= (0x06 << 17) | OPC_MSA_2RF
,
1259 OPC_FLOG2_df
= (0x07 << 17) | OPC_MSA_2RF
,
1260 OPC_FEXUPL_df
= (0x08 << 17) | OPC_MSA_2RF
,
1261 OPC_FEXUPR_df
= (0x09 << 17) | OPC_MSA_2RF
,
1262 OPC_FFQL_df
= (0x0A << 17) | OPC_MSA_2RF
,
1263 OPC_FFQR_df
= (0x0B << 17) | OPC_MSA_2RF
,
1264 OPC_FTINT_S_df
= (0x0C << 17) | OPC_MSA_2RF
,
1265 OPC_FTINT_U_df
= (0x0D << 17) | OPC_MSA_2RF
,
1266 OPC_FFINT_S_df
= (0x0E << 17) | OPC_MSA_2RF
,
1267 OPC_FFINT_U_df
= (0x0F << 17) | OPC_MSA_2RF
,
1269 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1270 OPC_SLL_df
= (0x0 << 23) | OPC_MSA_3R_0D
,
1271 OPC_ADDV_df
= (0x0 << 23) | OPC_MSA_3R_0E
,
1272 OPC_CEQ_df
= (0x0 << 23) | OPC_MSA_3R_0F
,
1273 OPC_ADD_A_df
= (0x0 << 23) | OPC_MSA_3R_10
,
1274 OPC_SUBS_S_df
= (0x0 << 23) | OPC_MSA_3R_11
,
1275 OPC_MULV_df
= (0x0 << 23) | OPC_MSA_3R_12
,
1276 OPC_DOTP_S_df
= (0x0 << 23) | OPC_MSA_3R_13
,
1277 OPC_SLD_df
= (0x0 << 23) | OPC_MSA_3R_14
,
1278 OPC_VSHF_df
= (0x0 << 23) | OPC_MSA_3R_15
,
1279 OPC_SRA_df
= (0x1 << 23) | OPC_MSA_3R_0D
,
1280 OPC_SUBV_df
= (0x1 << 23) | OPC_MSA_3R_0E
,
1281 OPC_ADDS_A_df
= (0x1 << 23) | OPC_MSA_3R_10
,
1282 OPC_SUBS_U_df
= (0x1 << 23) | OPC_MSA_3R_11
,
1283 OPC_MADDV_df
= (0x1 << 23) | OPC_MSA_3R_12
,
1284 OPC_DOTP_U_df
= (0x1 << 23) | OPC_MSA_3R_13
,
1285 OPC_SPLAT_df
= (0x1 << 23) | OPC_MSA_3R_14
,
1286 OPC_SRAR_df
= (0x1 << 23) | OPC_MSA_3R_15
,
1287 OPC_SRL_df
= (0x2 << 23) | OPC_MSA_3R_0D
,
1288 OPC_MAX_S_df
= (0x2 << 23) | OPC_MSA_3R_0E
,
1289 OPC_CLT_S_df
= (0x2 << 23) | OPC_MSA_3R_0F
,
1290 OPC_ADDS_S_df
= (0x2 << 23) | OPC_MSA_3R_10
,
1291 OPC_SUBSUS_U_df
= (0x2 << 23) | OPC_MSA_3R_11
,
1292 OPC_MSUBV_df
= (0x2 << 23) | OPC_MSA_3R_12
,
1293 OPC_DPADD_S_df
= (0x2 << 23) | OPC_MSA_3R_13
,
1294 OPC_PCKEV_df
= (0x2 << 23) | OPC_MSA_3R_14
,
1295 OPC_SRLR_df
= (0x2 << 23) | OPC_MSA_3R_15
,
1296 OPC_BCLR_df
= (0x3 << 23) | OPC_MSA_3R_0D
,
1297 OPC_MAX_U_df
= (0x3 << 23) | OPC_MSA_3R_0E
,
1298 OPC_CLT_U_df
= (0x3 << 23) | OPC_MSA_3R_0F
,
1299 OPC_ADDS_U_df
= (0x3 << 23) | OPC_MSA_3R_10
,
1300 OPC_SUBSUU_S_df
= (0x3 << 23) | OPC_MSA_3R_11
,
1301 OPC_DPADD_U_df
= (0x3 << 23) | OPC_MSA_3R_13
,
1302 OPC_PCKOD_df
= (0x3 << 23) | OPC_MSA_3R_14
,
1303 OPC_BSET_df
= (0x4 << 23) | OPC_MSA_3R_0D
,
1304 OPC_MIN_S_df
= (0x4 << 23) | OPC_MSA_3R_0E
,
1305 OPC_CLE_S_df
= (0x4 << 23) | OPC_MSA_3R_0F
,
1306 OPC_AVE_S_df
= (0x4 << 23) | OPC_MSA_3R_10
,
1307 OPC_ASUB_S_df
= (0x4 << 23) | OPC_MSA_3R_11
,
1308 OPC_DIV_S_df
= (0x4 << 23) | OPC_MSA_3R_12
,
1309 OPC_DPSUB_S_df
= (0x4 << 23) | OPC_MSA_3R_13
,
1310 OPC_ILVL_df
= (0x4 << 23) | OPC_MSA_3R_14
,
1311 OPC_HADD_S_df
= (0x4 << 23) | OPC_MSA_3R_15
,
1312 OPC_BNEG_df
= (0x5 << 23) | OPC_MSA_3R_0D
,
1313 OPC_MIN_U_df
= (0x5 << 23) | OPC_MSA_3R_0E
,
1314 OPC_CLE_U_df
= (0x5 << 23) | OPC_MSA_3R_0F
,
1315 OPC_AVE_U_df
= (0x5 << 23) | OPC_MSA_3R_10
,
1316 OPC_ASUB_U_df
= (0x5 << 23) | OPC_MSA_3R_11
,
1317 OPC_DIV_U_df
= (0x5 << 23) | OPC_MSA_3R_12
,
1318 OPC_DPSUB_U_df
= (0x5 << 23) | OPC_MSA_3R_13
,
1319 OPC_ILVR_df
= (0x5 << 23) | OPC_MSA_3R_14
,
1320 OPC_HADD_U_df
= (0x5 << 23) | OPC_MSA_3R_15
,
1321 OPC_BINSL_df
= (0x6 << 23) | OPC_MSA_3R_0D
,
1322 OPC_MAX_A_df
= (0x6 << 23) | OPC_MSA_3R_0E
,
1323 OPC_AVER_S_df
= (0x6 << 23) | OPC_MSA_3R_10
,
1324 OPC_MOD_S_df
= (0x6 << 23) | OPC_MSA_3R_12
,
1325 OPC_ILVEV_df
= (0x6 << 23) | OPC_MSA_3R_14
,
1326 OPC_HSUB_S_df
= (0x6 << 23) | OPC_MSA_3R_15
,
1327 OPC_BINSR_df
= (0x7 << 23) | OPC_MSA_3R_0D
,
1328 OPC_MIN_A_df
= (0x7 << 23) | OPC_MSA_3R_0E
,
1329 OPC_AVER_U_df
= (0x7 << 23) | OPC_MSA_3R_10
,
1330 OPC_MOD_U_df
= (0x7 << 23) | OPC_MSA_3R_12
,
1331 OPC_ILVOD_df
= (0x7 << 23) | OPC_MSA_3R_14
,
1332 OPC_HSUB_U_df
= (0x7 << 23) | OPC_MSA_3R_15
,
1334 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1335 OPC_SLDI_df
= (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1336 OPC_CTCMSA
= (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1337 OPC_SPLATI_df
= (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1338 OPC_CFCMSA
= (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1339 OPC_COPY_S_df
= (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1340 OPC_MOVE_V
= (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1341 OPC_COPY_U_df
= (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1342 OPC_INSERT_df
= (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1343 OPC_INSVE_df
= (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1345 /* 3RF instruction _df(bit 21) = _w, _d */
1346 OPC_FCAF_df
= (0x0 << 22) | OPC_MSA_3RF_1A
,
1347 OPC_FADD_df
= (0x0 << 22) | OPC_MSA_3RF_1B
,
1348 OPC_FCUN_df
= (0x1 << 22) | OPC_MSA_3RF_1A
,
1349 OPC_FSUB_df
= (0x1 << 22) | OPC_MSA_3RF_1B
,
1350 OPC_FCOR_df
= (0x1 << 22) | OPC_MSA_3RF_1C
,
1351 OPC_FCEQ_df
= (0x2 << 22) | OPC_MSA_3RF_1A
,
1352 OPC_FMUL_df
= (0x2 << 22) | OPC_MSA_3RF_1B
,
1353 OPC_FCUNE_df
= (0x2 << 22) | OPC_MSA_3RF_1C
,
1354 OPC_FCUEQ_df
= (0x3 << 22) | OPC_MSA_3RF_1A
,
1355 OPC_FDIV_df
= (0x3 << 22) | OPC_MSA_3RF_1B
,
1356 OPC_FCNE_df
= (0x3 << 22) | OPC_MSA_3RF_1C
,
1357 OPC_FCLT_df
= (0x4 << 22) | OPC_MSA_3RF_1A
,
1358 OPC_FMADD_df
= (0x4 << 22) | OPC_MSA_3RF_1B
,
1359 OPC_MUL_Q_df
= (0x4 << 22) | OPC_MSA_3RF_1C
,
1360 OPC_FCULT_df
= (0x5 << 22) | OPC_MSA_3RF_1A
,
1361 OPC_FMSUB_df
= (0x5 << 22) | OPC_MSA_3RF_1B
,
1362 OPC_MADD_Q_df
= (0x5 << 22) | OPC_MSA_3RF_1C
,
1363 OPC_FCLE_df
= (0x6 << 22) | OPC_MSA_3RF_1A
,
1364 OPC_MSUB_Q_df
= (0x6 << 22) | OPC_MSA_3RF_1C
,
1365 OPC_FCULE_df
= (0x7 << 22) | OPC_MSA_3RF_1A
,
1366 OPC_FEXP2_df
= (0x7 << 22) | OPC_MSA_3RF_1B
,
1367 OPC_FSAF_df
= (0x8 << 22) | OPC_MSA_3RF_1A
,
1368 OPC_FEXDO_df
= (0x8 << 22) | OPC_MSA_3RF_1B
,
1369 OPC_FSUN_df
= (0x9 << 22) | OPC_MSA_3RF_1A
,
1370 OPC_FSOR_df
= (0x9 << 22) | OPC_MSA_3RF_1C
,
1371 OPC_FSEQ_df
= (0xA << 22) | OPC_MSA_3RF_1A
,
1372 OPC_FTQ_df
= (0xA << 22) | OPC_MSA_3RF_1B
,
1373 OPC_FSUNE_df
= (0xA << 22) | OPC_MSA_3RF_1C
,
1374 OPC_FSUEQ_df
= (0xB << 22) | OPC_MSA_3RF_1A
,
1375 OPC_FSNE_df
= (0xB << 22) | OPC_MSA_3RF_1C
,
1376 OPC_FSLT_df
= (0xC << 22) | OPC_MSA_3RF_1A
,
1377 OPC_FMIN_df
= (0xC << 22) | OPC_MSA_3RF_1B
,
1378 OPC_MULR_Q_df
= (0xC << 22) | OPC_MSA_3RF_1C
,
1379 OPC_FSULT_df
= (0xD << 22) | OPC_MSA_3RF_1A
,
1380 OPC_FMIN_A_df
= (0xD << 22) | OPC_MSA_3RF_1B
,
1381 OPC_MADDR_Q_df
= (0xD << 22) | OPC_MSA_3RF_1C
,
1382 OPC_FSLE_df
= (0xE << 22) | OPC_MSA_3RF_1A
,
1383 OPC_FMAX_df
= (0xE << 22) | OPC_MSA_3RF_1B
,
1384 OPC_MSUBR_Q_df
= (0xE << 22) | OPC_MSA_3RF_1C
,
1385 OPC_FSULE_df
= (0xF << 22) | OPC_MSA_3RF_1A
,
1386 OPC_FMAX_A_df
= (0xF << 22) | OPC_MSA_3RF_1B
,
1388 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1389 OPC_SLLI_df
= (0x0 << 23) | OPC_MSA_BIT_09
,
1390 OPC_SAT_S_df
= (0x0 << 23) | OPC_MSA_BIT_0A
,
1391 OPC_SRAI_df
= (0x1 << 23) | OPC_MSA_BIT_09
,
1392 OPC_SAT_U_df
= (0x1 << 23) | OPC_MSA_BIT_0A
,
1393 OPC_SRLI_df
= (0x2 << 23) | OPC_MSA_BIT_09
,
1394 OPC_SRARI_df
= (0x2 << 23) | OPC_MSA_BIT_0A
,
1395 OPC_BCLRI_df
= (0x3 << 23) | OPC_MSA_BIT_09
,
1396 OPC_SRLRI_df
= (0x3 << 23) | OPC_MSA_BIT_0A
,
1397 OPC_BSETI_df
= (0x4 << 23) | OPC_MSA_BIT_09
,
1398 OPC_BNEGI_df
= (0x5 << 23) | OPC_MSA_BIT_09
,
1399 OPC_BINSLI_df
= (0x6 << 23) | OPC_MSA_BIT_09
,
1400 OPC_BINSRI_df
= (0x7 << 23) | OPC_MSA_BIT_09
,
1406 * AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1407 * ============================================
1410 * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1411 * instructions set. It is designed to fit the needs of signal, graphical and
1412 * video processing applications. MXU instruction set is used in Xburst family
1413 * of microprocessors by Ingenic.
1415 * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1416 * the control register.
1419 * The notation used in MXU assembler mnemonics
1420 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1422 * Register operands:
1424 * XRa, XRb, XRc, XRd - MXU registers
1425 * Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1427 * Non-register operands:
1429 * aptn1 - 1-bit accumulate add/subtract pattern
1430 * aptn2 - 2-bit accumulate add/subtract pattern
1431 * eptn2 - 2-bit execute add/subtract pattern
1432 * optn2 - 2-bit operand pattern
1433 * optn3 - 3-bit operand pattern
1434 * sft4 - 4-bit shift amount
1435 * strd2 - 2-bit stride amount
1439 * Level of parallelism: Operand size:
1440 * S - single operation at a time 32 - word
1441 * D - two operations in parallel 16 - half word
1442 * Q - four operations in parallel 8 - byte
1446 * ADD - Add or subtract
1447 * ADDC - Add with carry-in
1449 * ASUM - Sum together then accumulate (add or subtract)
1450 * ASUMC - Sum together then accumulate (add or subtract) with carry-in
1451 * AVG - Average between 2 operands
1452 * ABD - Absolute difference
1454 * AND - Logical bitwise 'and' operation
1456 * EXTR - Extract bits
1457 * I2M - Move from GPR register to MXU register
1458 * LDD - Load data from memory to XRF
1459 * LDI - Load data from memory to XRF (and increase the address base)
1460 * LUI - Load unsigned immediate
1462 * MULU - Unsigned multiply
1463 * MADD - 64-bit operand add 32x32 product
1464 * MSUB - 64-bit operand subtract 32x32 product
1465 * MAC - Multiply and accumulate (add or subtract)
1466 * MAD - Multiply and add or subtract
1467 * MAX - Maximum between 2 operands
1468 * MIN - Minimum between 2 operands
1469 * M2I - Move from MXU register to GPR register
1470 * MOVZ - Move if zero
1471 * MOVN - Move if non-zero
1472 * NOR - Logical bitwise 'nor' operation
1473 * OR - Logical bitwise 'or' operation
1474 * STD - Store data from XRF to memory
1475 * SDI - Store data from XRF to memory (and increase the address base)
1476 * SLT - Set of less than comparison
1477 * SAD - Sum of absolute differences
1478 * SLL - Logical shift left
1479 * SLR - Logical shift right
1480 * SAR - Arithmetic shift right
1483 * SCOP - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1484 * XOR - Logical bitwise 'exclusive or' operation
1488 * E - Expand results
1489 * F - Fixed point multiplication
1490 * L - Low part result
1491 * R - Doing rounding
1492 * V - Variable instead of immediate
1493 * W - Combine above L and V
1496 * The list of MXU instructions grouped by functionality
1497 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1499 * Load/Store instructions Multiplication instructions
1500 * ----------------------- ---------------------------
1502 * S32LDD XRa, Rb, s12 S32MADD XRa, XRd, Rs, Rt
1503 * S32STD XRa, Rb, s12 S32MADDU XRa, XRd, Rs, Rt
1504 * S32LDDV XRa, Rb, rc, strd2 S32MSUB XRa, XRd, Rs, Rt
1505 * S32STDV XRa, Rb, rc, strd2 S32MSUBU XRa, XRd, Rs, Rt
1506 * S32LDI XRa, Rb, s12 S32MUL XRa, XRd, Rs, Rt
1507 * S32SDI XRa, Rb, s12 S32MULU XRa, XRd, Rs, Rt
1508 * S32LDIV XRa, Rb, rc, strd2 D16MUL XRa, XRb, XRc, XRd, optn2
1509 * S32SDIV XRa, Rb, rc, strd2 D16MULE XRa, XRb, XRc, optn2
1510 * S32LDDR XRa, Rb, s12 D16MULF XRa, XRb, XRc, optn2
1511 * S32STDR XRa, Rb, s12 D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1512 * S32LDDVR XRa, Rb, rc, strd2 D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1513 * S32STDVR XRa, Rb, rc, strd2 D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1514 * S32LDIR XRa, Rb, s12 D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1515 * S32SDIR XRa, Rb, s12 S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1516 * S32LDIVR XRa, Rb, rc, strd2 Q8MUL XRa, XRb, XRc, XRd
1517 * S32SDIVR XRa, Rb, rc, strd2 Q8MULSU XRa, XRb, XRc, XRd
1518 * S16LDD XRa, Rb, s10, eptn2 Q8MAC XRa, XRb, XRc, XRd, aptn2
1519 * S16STD XRa, Rb, s10, eptn2 Q8MACSU XRa, XRb, XRc, XRd, aptn2
1520 * S16LDI XRa, Rb, s10, eptn2 Q8MADL XRa, XRb, XRc, XRd, aptn2
1521 * S16SDI XRa, Rb, s10, eptn2
1522 * S8LDD XRa, Rb, s8, eptn3
1523 * S8STD XRa, Rb, s8, eptn3 Addition and subtraction instructions
1524 * S8LDI XRa, Rb, s8, eptn3 -------------------------------------
1525 * S8SDI XRa, Rb, s8, eptn3
1526 * LXW Rd, Rs, Rt, strd2 D32ADD XRa, XRb, XRc, XRd, eptn2
1527 * LXH Rd, Rs, Rt, strd2 D32ADDC XRa, XRb, XRc, XRd
1528 * LXHU Rd, Rs, Rt, strd2 D32ACC XRa, XRb, XRc, XRd, eptn2
1529 * LXB Rd, Rs, Rt, strd2 D32ACCM XRa, XRb, XRc, XRd, eptn2
1530 * LXBU Rd, Rs, Rt, strd2 D32ASUM XRa, XRb, XRc, XRd, eptn2
1531 * S32CPS XRa, XRb, XRc
1532 * Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1533 * Comparison instructions Q16ACC XRa, XRb, XRc, XRd, eptn2
1534 * ----------------------- Q16ACCM XRa, XRb, XRc, XRd, eptn2
1535 * D16ASUM XRa, XRb, XRc, XRd, eptn2
1536 * S32MAX XRa, XRb, XRc D16CPS XRa, XRb,
1537 * S32MIN XRa, XRb, XRc D16AVG XRa, XRb, XRc
1538 * S32SLT XRa, XRb, XRc D16AVGR XRa, XRb, XRc
1539 * S32MOVZ XRa, XRb, XRc Q8ADD XRa, XRb, XRc, eptn2
1540 * S32MOVN XRa, XRb, XRc Q8ADDE XRa, XRb, XRc, XRd, eptn2
1541 * D16MAX XRa, XRb, XRc Q8ACCE XRa, XRb, XRc, XRd, eptn2
1542 * D16MIN XRa, XRb, XRc Q8ABD XRa, XRb, XRc
1543 * D16SLT XRa, XRb, XRc Q8SAD XRa, XRb, XRc, XRd
1544 * D16MOVZ XRa, XRb, XRc Q8AVG XRa, XRb, XRc
1545 * D16MOVN XRa, XRb, XRc Q8AVGR XRa, XRb, XRc
1546 * Q8MAX XRa, XRb, XRc D8SUM XRa, XRb, XRc, XRd
1547 * Q8MIN XRa, XRb, XRc D8SUMC XRa, XRb, XRc, XRd
1548 * Q8SLT XRa, XRb, XRc
1549 * Q8SLTU XRa, XRb, XRc
1550 * Q8MOVZ XRa, XRb, XRc Shift instructions
1551 * Q8MOVN XRa, XRb, XRc ------------------
1553 * D32SLL XRa, XRb, XRc, XRd, sft4
1554 * Bitwise instructions D32SLR XRa, XRb, XRc, XRd, sft4
1555 * -------------------- D32SAR XRa, XRb, XRc, XRd, sft4
1556 * D32SARL XRa, XRb, XRc, sft4
1557 * S32NOR XRa, XRb, XRc D32SLLV XRa, XRb, Rb
1558 * S32AND XRa, XRb, XRc D32SLRV XRa, XRb, Rb
1559 * S32XOR XRa, XRb, XRc D32SARV XRa, XRb, Rb
1560 * S32OR XRa, XRb, XRc D32SARW XRa, XRb, XRc, Rb
1561 * Q16SLL XRa, XRb, XRc, XRd, sft4
1562 * Q16SLR XRa, XRb, XRc, XRd, sft4
1563 * Miscellaneous instructions Q16SAR XRa, XRb, XRc, XRd, sft4
1564 * ------------------------- Q16SLLV XRa, XRb, Rb
1565 * Q16SLRV XRa, XRb, Rb
1566 * S32SFL XRa, XRb, XRc, XRd, optn2 Q16SARV XRa, XRb, Rb
1567 * S32ALN XRa, XRb, XRc, Rb
1568 * S32ALNI XRa, XRb, XRc, s3
1569 * S32LUI XRa, s8, optn3 Move instructions
1570 * S32EXTR XRa, XRb, Rb, bits5 -----------------
1571 * S32EXTRV XRa, XRb, Rs, Rt
1572 * Q16SCOP XRa, XRb, XRc, XRd S32M2I XRa, Rb
1573 * Q16SAT XRa, XRb, XRc S32I2M XRa, Rb
1576 * The opcode organization of MXU instructions
1577 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1579 * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1580 * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1581 * other bits up to the instruction level is as follows:
1586 * ┌─ 000000 ─ OPC_MXU_S32MADD
1587 * ├─ 000001 ─ OPC_MXU_S32MADDU
1588 * ├─ 000010 ─ <not assigned> (non-MXU OPC_MUL)
1591 * ├─ 000011 ─ OPC_MXU__POOL00 ─┬─ 000 ─ OPC_MXU_S32MAX
1592 * │ ├─ 001 ─ OPC_MXU_S32MIN
1593 * │ ├─ 010 ─ OPC_MXU_D16MAX
1594 * │ ├─ 011 ─ OPC_MXU_D16MIN
1595 * │ ├─ 100 ─ OPC_MXU_Q8MAX
1596 * │ ├─ 101 ─ OPC_MXU_Q8MIN
1597 * │ ├─ 110 ─ OPC_MXU_Q8SLT
1598 * │ └─ 111 ─ OPC_MXU_Q8SLTU
1599 * ├─ 000100 ─ OPC_MXU_S32MSUB
1600 * ├─ 000101 ─ OPC_MXU_S32MSUBU 20..18
1601 * ├─ 000110 ─ OPC_MXU__POOL01 ─┬─ 000 ─ OPC_MXU_S32SLT
1602 * │ ├─ 001 ─ OPC_MXU_D16SLT
1603 * │ ├─ 010 ─ OPC_MXU_D16AVG
1604 * │ ├─ 011 ─ OPC_MXU_D16AVGR
1605 * │ ├─ 100 ─ OPC_MXU_Q8AVG
1606 * │ ├─ 101 ─ OPC_MXU_Q8AVGR
1607 * │ └─ 111 ─ OPC_MXU_Q8ADD
1610 * ├─ 000111 ─ OPC_MXU__POOL02 ─┬─ 000 ─ OPC_MXU_S32CPS
1611 * │ ├─ 010 ─ OPC_MXU_D16CPS
1612 * │ ├─ 100 ─ OPC_MXU_Q8ABD
1613 * │ └─ 110 ─ OPC_MXU_Q16SAT
1614 * ├─ 001000 ─ OPC_MXU_D16MUL
1616 * ├─ 001001 ─ OPC_MXU__POOL03 ─┬─ 00 ─ OPC_MXU_D16MULF
1617 * │ └─ 01 ─ OPC_MXU_D16MULE
1618 * ├─ 001010 ─ OPC_MXU_D16MAC
1619 * ├─ 001011 ─ OPC_MXU_D16MACF
1620 * ├─ 001100 ─ OPC_MXU_D16MADL
1621 * ├─ 001101 ─ OPC_MXU_S16MAD
1622 * ├─ 001110 ─ OPC_MXU_Q16ADD
1623 * ├─ 001111 ─ OPC_MXU_D16MACE 23
1624 * │ ┌─ 0 ─ OPC_MXU_S32LDD
1625 * ├─ 010000 ─ OPC_MXU__POOL04 ─┴─ 1 ─ OPC_MXU_S32LDDR
1628 * ├─ 010001 ─ OPC_MXU__POOL05 ─┬─ 0 ─ OPC_MXU_S32STD
1629 * │ └─ 1 ─ OPC_MXU_S32STDR
1632 * ├─ 010010 ─ OPC_MXU__POOL06 ─┬─ 0000 ─ OPC_MXU_S32LDDV
1633 * │ └─ 0001 ─ OPC_MXU_S32LDDVR
1636 * ├─ 010011 ─ OPC_MXU__POOL07 ─┬─ 0000 ─ OPC_MXU_S32STDV
1637 * │ └─ 0001 ─ OPC_MXU_S32STDVR
1640 * ├─ 010100 ─ OPC_MXU__POOL08 ─┬─ 0 ─ OPC_MXU_S32LDI
1641 * │ └─ 1 ─ OPC_MXU_S32LDIR
1644 * ├─ 010101 ─ OPC_MXU__POOL09 ─┬─ 0 ─ OPC_MXU_S32SDI
1645 * │ └─ 1 ─ OPC_MXU_S32SDIR
1648 * ├─ 010110 ─ OPC_MXU__POOL10 ─┬─ 0000 ─ OPC_MXU_S32LDIV
1649 * │ └─ 0001 ─ OPC_MXU_S32LDIVR
1652 * ├─ 010111 ─ OPC_MXU__POOL11 ─┬─ 0000 ─ OPC_MXU_S32SDIV
1653 * │ └─ 0001 ─ OPC_MXU_S32SDIVR
1654 * ├─ 011000 ─ OPC_MXU_D32ADD
1656 * MXU ├─ 011001 ─ OPC_MXU__POOL12 ─┬─ 00 ─ OPC_MXU_D32ACC
1657 * opcodes ─┤ ├─ 01 ─ OPC_MXU_D32ACCM
1658 * │ └─ 10 ─ OPC_MXU_D32ASUM
1659 * ├─ 011010 ─ <not assigned>
1661 * ├─ 011011 ─ OPC_MXU__POOL13 ─┬─ 00 ─ OPC_MXU_Q16ACC
1662 * │ ├─ 01 ─ OPC_MXU_Q16ACCM
1663 * │ └─ 10 ─ OPC_MXU_Q16ASUM
1666 * ├─ 011100 ─ OPC_MXU__POOL14 ─┬─ 00 ─ OPC_MXU_Q8ADDE
1667 * │ ├─ 01 ─ OPC_MXU_D8SUM
1668 * ├─ 011101 ─ OPC_MXU_Q8ACCE └─ 10 ─ OPC_MXU_D8SUMC
1669 * ├─ 011110 ─ <not assigned>
1670 * ├─ 011111 ─ <not assigned>
1671 * ├─ 100000 ─ <not assigned> (overlaps with CLZ)
1672 * ├─ 100001 ─ <not assigned> (overlaps with CLO)
1673 * ├─ 100010 ─ OPC_MXU_S8LDD
1674 * ├─ 100011 ─ OPC_MXU_S8STD 15..14
1675 * ├─ 100100 ─ OPC_MXU_S8LDI ┌─ 00 ─ OPC_MXU_S32MUL
1676 * ├─ 100101 ─ OPC_MXU_S8SDI ├─ 00 ─ OPC_MXU_S32MULU
1677 * │ ├─ 00 ─ OPC_MXU_S32EXTR
1678 * ├─ 100110 ─ OPC_MXU__POOL15 ─┴─ 00 ─ OPC_MXU_S32EXTRV
1681 * ├─ 100111 ─ OPC_MXU__POOL16 ─┬─ 000 ─ OPC_MXU_D32SARW
1682 * │ ├─ 001 ─ OPC_MXU_S32ALN
1683 * │ ├─ 010 ─ OPC_MXU_S32ALNI
1684 * │ ├─ 011 ─ OPC_MXU_S32LUI
1685 * │ ├─ 100 ─ OPC_MXU_S32NOR
1686 * │ ├─ 101 ─ OPC_MXU_S32AND
1687 * │ ├─ 110 ─ OPC_MXU_S32OR
1688 * │ └─ 111 ─ OPC_MXU_S32XOR
1691 * ├─ 101000 ─ OPC_MXU__POOL17 ─┬─ 000 ─ OPC_MXU_LXB
1692 * │ ├─ 001 ─ OPC_MXU_LXH
1693 * ├─ 101001 ─ <not assigned> ├─ 011 ─ OPC_MXU_LXW
1694 * ├─ 101010 ─ OPC_MXU_S16LDD ├─ 100 ─ OPC_MXU_LXBU
1695 * ├─ 101011 ─ OPC_MXU_S16STD └─ 101 ─ OPC_MXU_LXHU
1696 * ├─ 101100 ─ OPC_MXU_S16LDI
1697 * ├─ 101101 ─ OPC_MXU_S16SDI
1698 * ├─ 101110 ─ OPC_MXU_S32M2I
1699 * ├─ 101111 ─ OPC_MXU_S32I2M
1700 * ├─ 110000 ─ OPC_MXU_D32SLL
1701 * ├─ 110001 ─ OPC_MXU_D32SLR 20..18
1702 * ├─ 110010 ─ OPC_MXU_D32SARL ┌─ 000 ─ OPC_MXU_D32SLLV
1703 * ├─ 110011 ─ OPC_MXU_D32SAR ├─ 001 ─ OPC_MXU_D32SLRV
1704 * ├─ 110100 ─ OPC_MXU_Q16SLL ├─ 010 ─ OPC_MXU_D32SARV
1705 * ├─ 110101 ─ OPC_MXU_Q16SLR ├─ 011 ─ OPC_MXU_Q16SLLV
1706 * │ ├─ 100 ─ OPC_MXU_Q16SLRV
1707 * ├─ 110110 ─ OPC_MXU__POOL18 ─┴─ 101 ─ OPC_MXU_Q16SARV
1709 * ├─ 110111 ─ OPC_MXU_Q16SAR
1711 * ├─ 111000 ─ OPC_MXU__POOL19 ─┬─ 00 ─ OPC_MXU_Q8MUL
1712 * │ └─ 01 ─ OPC_MXU_Q8MULSU
1715 * ├─ 111001 ─ OPC_MXU__POOL20 ─┬─ 000 ─ OPC_MXU_Q8MOVZ
1716 * │ ├─ 001 ─ OPC_MXU_Q8MOVN
1717 * │ ├─ 010 ─ OPC_MXU_D16MOVZ
1718 * │ ├─ 011 ─ OPC_MXU_D16MOVN
1719 * │ ├─ 100 ─ OPC_MXU_S32MOVZ
1720 * │ └─ 101 ─ OPC_MXU_S32MOVN
1723 * ├─ 111010 ─ OPC_MXU__POOL21 ─┬─ 00 ─ OPC_MXU_Q8MAC
1724 * │ └─ 10 ─ OPC_MXU_Q8MACSU
1725 * ├─ 111011 ─ OPC_MXU_Q16SCOP
1726 * ├─ 111100 ─ OPC_MXU_Q8MADL
1727 * ├─ 111101 ─ OPC_MXU_S32SFL
1728 * ├─ 111110 ─ OPC_MXU_Q8SAD
1729 * └─ 111111 ─ <not assigned> (overlaps with SDBBP)
1734 * "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1735 * Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1739 OPC_MXU_S32MADD
= 0x00,
1740 OPC_MXU_S32MADDU
= 0x01,
1741 OPC__MXU_MUL
= 0x02,
1742 OPC_MXU__POOL00
= 0x03,
1743 OPC_MXU_S32MSUB
= 0x04,
1744 OPC_MXU_S32MSUBU
= 0x05,
1745 OPC_MXU__POOL01
= 0x06,
1746 OPC_MXU__POOL02
= 0x07,
1747 OPC_MXU_D16MUL
= 0x08,
1748 OPC_MXU__POOL03
= 0x09,
1749 OPC_MXU_D16MAC
= 0x0A,
1750 OPC_MXU_D16MACF
= 0x0B,
1751 OPC_MXU_D16MADL
= 0x0C,
1752 OPC_MXU_S16MAD
= 0x0D,
1753 OPC_MXU_Q16ADD
= 0x0E,
1754 OPC_MXU_D16MACE
= 0x0F,
1755 OPC_MXU__POOL04
= 0x10,
1756 OPC_MXU__POOL05
= 0x11,
1757 OPC_MXU__POOL06
= 0x12,
1758 OPC_MXU__POOL07
= 0x13,
1759 OPC_MXU__POOL08
= 0x14,
1760 OPC_MXU__POOL09
= 0x15,
1761 OPC_MXU__POOL10
= 0x16,
1762 OPC_MXU__POOL11
= 0x17,
1763 OPC_MXU_D32ADD
= 0x18,
1764 OPC_MXU__POOL12
= 0x19,
1765 /* not assigned 0x1A */
1766 OPC_MXU__POOL13
= 0x1B,
1767 OPC_MXU__POOL14
= 0x1C,
1768 OPC_MXU_Q8ACCE
= 0x1D,
1769 /* not assigned 0x1E */
1770 /* not assigned 0x1F */
1771 /* not assigned 0x20 */
1772 /* not assigned 0x21 */
1773 OPC_MXU_S8LDD
= 0x22,
1774 OPC_MXU_S8STD
= 0x23,
1775 OPC_MXU_S8LDI
= 0x24,
1776 OPC_MXU_S8SDI
= 0x25,
1777 OPC_MXU__POOL15
= 0x26,
1778 OPC_MXU__POOL16
= 0x27,
1779 OPC_MXU__POOL17
= 0x28,
1780 /* not assigned 0x29 */
1781 OPC_MXU_S16LDD
= 0x2A,
1782 OPC_MXU_S16STD
= 0x2B,
1783 OPC_MXU_S16LDI
= 0x2C,
1784 OPC_MXU_S16SDI
= 0x2D,
1785 OPC_MXU_S32M2I
= 0x2E,
1786 OPC_MXU_S32I2M
= 0x2F,
1787 OPC_MXU_D32SLL
= 0x30,
1788 OPC_MXU_D32SLR
= 0x31,
1789 OPC_MXU_D32SARL
= 0x32,
1790 OPC_MXU_D32SAR
= 0x33,
1791 OPC_MXU_Q16SLL
= 0x34,
1792 OPC_MXU_Q16SLR
= 0x35,
1793 OPC_MXU__POOL18
= 0x36,
1794 OPC_MXU_Q16SAR
= 0x37,
1795 OPC_MXU__POOL19
= 0x38,
1796 OPC_MXU__POOL20
= 0x39,
1797 OPC_MXU__POOL21
= 0x3A,
1798 OPC_MXU_Q16SCOP
= 0x3B,
1799 OPC_MXU_Q8MADL
= 0x3C,
1800 OPC_MXU_S32SFL
= 0x3D,
1801 OPC_MXU_Q8SAD
= 0x3E,
1802 /* not assigned 0x3F */
1810 OPC_MXU_S32MAX
= 0x00,
1811 OPC_MXU_S32MIN
= 0x01,
1812 OPC_MXU_D16MAX
= 0x02,
1813 OPC_MXU_D16MIN
= 0x03,
1814 OPC_MXU_Q8MAX
= 0x04,
1815 OPC_MXU_Q8MIN
= 0x05,
1816 OPC_MXU_Q8SLT
= 0x06,
1817 OPC_MXU_Q8SLTU
= 0x07,
1824 OPC_MXU_S32SLT
= 0x00,
1825 OPC_MXU_D16SLT
= 0x01,
1826 OPC_MXU_D16AVG
= 0x02,
1827 OPC_MXU_D16AVGR
= 0x03,
1828 OPC_MXU_Q8AVG
= 0x04,
1829 OPC_MXU_Q8AVGR
= 0x05,
1830 OPC_MXU_Q8ADD
= 0x07,
1837 OPC_MXU_S32CPS
= 0x00,
1838 OPC_MXU_D16CPS
= 0x02,
1839 OPC_MXU_Q8ABD
= 0x04,
1840 OPC_MXU_Q16SAT
= 0x06,
1847 OPC_MXU_D16MULF
= 0x00,
1848 OPC_MXU_D16MULE
= 0x01,
1855 OPC_MXU_S32LDD
= 0x00,
1856 OPC_MXU_S32LDDR
= 0x01,
1863 OPC_MXU_S32STD
= 0x00,
1864 OPC_MXU_S32STDR
= 0x01,
1871 OPC_MXU_S32LDDV
= 0x00,
1872 OPC_MXU_S32LDDVR
= 0x01,
1879 OPC_MXU_S32STDV
= 0x00,
1880 OPC_MXU_S32STDVR
= 0x01,
1887 OPC_MXU_S32LDI
= 0x00,
1888 OPC_MXU_S32LDIR
= 0x01,
1895 OPC_MXU_S32SDI
= 0x00,
1896 OPC_MXU_S32SDIR
= 0x01,
1903 OPC_MXU_S32LDIV
= 0x00,
1904 OPC_MXU_S32LDIVR
= 0x01,
1911 OPC_MXU_S32SDIV
= 0x00,
1912 OPC_MXU_S32SDIVR
= 0x01,
1919 OPC_MXU_D32ACC
= 0x00,
1920 OPC_MXU_D32ACCM
= 0x01,
1921 OPC_MXU_D32ASUM
= 0x02,
1928 OPC_MXU_Q16ACC
= 0x00,
1929 OPC_MXU_Q16ACCM
= 0x01,
1930 OPC_MXU_Q16ASUM
= 0x02,
1937 OPC_MXU_Q8ADDE
= 0x00,
1938 OPC_MXU_D8SUM
= 0x01,
1939 OPC_MXU_D8SUMC
= 0x02,
1946 OPC_MXU_S32MUL
= 0x00,
1947 OPC_MXU_S32MULU
= 0x01,
1948 OPC_MXU_S32EXTR
= 0x02,
1949 OPC_MXU_S32EXTRV
= 0x03,
1956 OPC_MXU_D32SARW
= 0x00,
1957 OPC_MXU_S32ALN
= 0x01,
1958 OPC_MXU_S32ALNI
= 0x02,
1959 OPC_MXU_S32LUI
= 0x03,
1960 OPC_MXU_S32NOR
= 0x04,
1961 OPC_MXU_S32AND
= 0x05,
1962 OPC_MXU_S32OR
= 0x06,
1963 OPC_MXU_S32XOR
= 0x07,
1973 OPC_MXU_LXBU
= 0x04,
1974 OPC_MXU_LXHU
= 0x05,
1981 OPC_MXU_D32SLLV
= 0x00,
1982 OPC_MXU_D32SLRV
= 0x01,
1983 OPC_MXU_D32SARV
= 0x03,
1984 OPC_MXU_Q16SLLV
= 0x04,
1985 OPC_MXU_Q16SLRV
= 0x05,
1986 OPC_MXU_Q16SARV
= 0x07,
1993 OPC_MXU_Q8MUL
= 0x00,
1994 OPC_MXU_Q8MULSU
= 0x01,
2001 OPC_MXU_Q8MOVZ
= 0x00,
2002 OPC_MXU_Q8MOVN
= 0x01,
2003 OPC_MXU_D16MOVZ
= 0x02,
2004 OPC_MXU_D16MOVN
= 0x03,
2005 OPC_MXU_S32MOVZ
= 0x04,
2006 OPC_MXU_S32MOVN
= 0x05,
2013 OPC_MXU_Q8MAC
= 0x00,
2014 OPC_MXU_Q8MACSU
= 0x01,
2018 * Overview of the TX79-specific instruction set
2019 * =============================================
2021 * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2022 * are only used by the specific quadword (128-bit) LQ/SQ load/store
2023 * instructions and certain multimedia instructions (MMIs). These MMIs
2024 * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2025 * or sixteen 8-bit paths.
2029 * The Toshiba TX System RISC TX79 Core Architecture manual,
2030 * https://wiki.qemu.org/File:C790.pdf
2032 * Three-Operand Multiply and Multiply-Add (4 instructions)
2033 * --------------------------------------------------------
2034 * MADD [rd,] rs, rt Multiply/Add
2035 * MADDU [rd,] rs, rt Multiply/Add Unsigned
2036 * MULT [rd,] rs, rt Multiply (3-operand)
2037 * MULTU [rd,] rs, rt Multiply Unsigned (3-operand)
2039 * Multiply Instructions for Pipeline 1 (10 instructions)
2040 * ------------------------------------------------------
2041 * MULT1 [rd,] rs, rt Multiply Pipeline 1
2042 * MULTU1 [rd,] rs, rt Multiply Unsigned Pipeline 1
2043 * DIV1 rs, rt Divide Pipeline 1
2044 * DIVU1 rs, rt Divide Unsigned Pipeline 1
2045 * MADD1 [rd,] rs, rt Multiply-Add Pipeline 1
2046 * MADDU1 [rd,] rs, rt Multiply-Add Unsigned Pipeline 1
2047 * MFHI1 rd Move From HI1 Register
2048 * MFLO1 rd Move From LO1 Register
2049 * MTHI1 rs Move To HI1 Register
2050 * MTLO1 rs Move To LO1 Register
2052 * Arithmetic (19 instructions)
2053 * ----------------------------
2054 * PADDB rd, rs, rt Parallel Add Byte
2055 * PSUBB rd, rs, rt Parallel Subtract Byte
2056 * PADDH rd, rs, rt Parallel Add Halfword
2057 * PSUBH rd, rs, rt Parallel Subtract Halfword
2058 * PADDW rd, rs, rt Parallel Add Word
2059 * PSUBW rd, rs, rt Parallel Subtract Word
2060 * PADSBH rd, rs, rt Parallel Add/Subtract Halfword
2061 * PADDSB rd, rs, rt Parallel Add with Signed Saturation Byte
2062 * PSUBSB rd, rs, rt Parallel Subtract with Signed Saturation Byte
2063 * PADDSH rd, rs, rt Parallel Add with Signed Saturation Halfword
2064 * PSUBSH rd, rs, rt Parallel Subtract with Signed Saturation Halfword
2065 * PADDSW rd, rs, rt Parallel Add with Signed Saturation Word
2066 * PSUBSW rd, rs, rt Parallel Subtract with Signed Saturation Word
2067 * PADDUB rd, rs, rt Parallel Add with Unsigned saturation Byte
2068 * PSUBUB rd, rs, rt Parallel Subtract with Unsigned saturation Byte
2069 * PADDUH rd, rs, rt Parallel Add with Unsigned saturation Halfword
2070 * PSUBUH rd, rs, rt Parallel Subtract with Unsigned saturation Halfword
2071 * PADDUW rd, rs, rt Parallel Add with Unsigned saturation Word
2072 * PSUBUW rd, rs, rt Parallel Subtract with Unsigned saturation Word
2074 * Min/Max (4 instructions)
2075 * ------------------------
2076 * PMAXH rd, rs, rt Parallel Maximum Halfword
2077 * PMINH rd, rs, rt Parallel Minimum Halfword
2078 * PMAXW rd, rs, rt Parallel Maximum Word
2079 * PMINW rd, rs, rt Parallel Minimum Word
2081 * Absolute (2 instructions)
2082 * -------------------------
2083 * PABSH rd, rt Parallel Absolute Halfword
2084 * PABSW rd, rt Parallel Absolute Word
2086 * Logical (4 instructions)
2087 * ------------------------
2088 * PAND rd, rs, rt Parallel AND
2089 * POR rd, rs, rt Parallel OR
2090 * PXOR rd, rs, rt Parallel XOR
2091 * PNOR rd, rs, rt Parallel NOR
2093 * Shift (9 instructions)
2094 * ----------------------
2095 * PSLLH rd, rt, sa Parallel Shift Left Logical Halfword
2096 * PSRLH rd, rt, sa Parallel Shift Right Logical Halfword
2097 * PSRAH rd, rt, sa Parallel Shift Right Arithmetic Halfword
2098 * PSLLW rd, rt, sa Parallel Shift Left Logical Word
2099 * PSRLW rd, rt, sa Parallel Shift Right Logical Word
2100 * PSRAW rd, rt, sa Parallel Shift Right Arithmetic Word
2101 * PSLLVW rd, rt, rs Parallel Shift Left Logical Variable Word
2102 * PSRLVW rd, rt, rs Parallel Shift Right Logical Variable Word
2103 * PSRAVW rd, rt, rs Parallel Shift Right Arithmetic Variable Word
2105 * Compare (6 instructions)
2106 * ------------------------
2107 * PCGTB rd, rs, rt Parallel Compare for Greater Than Byte
2108 * PCEQB rd, rs, rt Parallel Compare for Equal Byte
2109 * PCGTH rd, rs, rt Parallel Compare for Greater Than Halfword
2110 * PCEQH rd, rs, rt Parallel Compare for Equal Halfword
2111 * PCGTW rd, rs, rt Parallel Compare for Greater Than Word
2112 * PCEQW rd, rs, rt Parallel Compare for Equal Word
2114 * LZC (1 instruction)
2115 * -------------------
2116 * PLZCW rd, rs Parallel Leading Zero or One Count Word
2118 * Quadword Load and Store (2 instructions)
2119 * ----------------------------------------
2120 * LQ rt, offset(base) Load Quadword
2121 * SQ rt, offset(base) Store Quadword
2123 * Multiply and Divide (19 instructions)
2124 * -------------------------------------
2125 * PMULTW rd, rs, rt Parallel Multiply Word
2126 * PMULTUW rd, rs, rt Parallel Multiply Unsigned Word
2127 * PDIVW rs, rt Parallel Divide Word
2128 * PDIVUW rs, rt Parallel Divide Unsigned Word
2129 * PMADDW rd, rs, rt Parallel Multiply-Add Word
2130 * PMADDUW rd, rs, rt Parallel Multiply-Add Unsigned Word
2131 * PMSUBW rd, rs, rt Parallel Multiply-Subtract Word
2132 * PMULTH rd, rs, rt Parallel Multiply Halfword
2133 * PMADDH rd, rs, rt Parallel Multiply-Add Halfword
2134 * PMSUBH rd, rs, rt Parallel Multiply-Subtract Halfword
2135 * PHMADH rd, rs, rt Parallel Horizontal Multiply-Add Halfword
2136 * PHMSBH rd, rs, rt Parallel Horizontal Multiply-Subtract Halfword
2137 * PDIVBW rs, rt Parallel Divide Broadcast Word
2138 * PMFHI rd Parallel Move From HI Register
2139 * PMFLO rd Parallel Move From LO Register
2140 * PMTHI rs Parallel Move To HI Register
2141 * PMTLO rs Parallel Move To LO Register
2142 * PMFHL rd Parallel Move From HI/LO Register
2143 * PMTHL rs Parallel Move To HI/LO Register
2145 * Pack/Extend (11 instructions)
2146 * -----------------------------
2147 * PPAC5 rd, rt Parallel Pack to 5 bits
2148 * PPACB rd, rs, rt Parallel Pack to Byte
2149 * PPACH rd, rs, rt Parallel Pack to Halfword
2150 * PPACW rd, rs, rt Parallel Pack to Word
2151 * PEXT5 rd, rt Parallel Extend Upper from 5 bits
2152 * PEXTUB rd, rs, rt Parallel Extend Upper from Byte
2153 * PEXTLB rd, rs, rt Parallel Extend Lower from Byte
2154 * PEXTUH rd, rs, rt Parallel Extend Upper from Halfword
2155 * PEXTLH rd, rs, rt Parallel Extend Lower from Halfword
2156 * PEXTUW rd, rs, rt Parallel Extend Upper from Word
2157 * PEXTLW rd, rs, rt Parallel Extend Lower from Word
2159 * Others (16 instructions)
2160 * ------------------------
2161 * PCPYH rd, rt Parallel Copy Halfword
2162 * PCPYLD rd, rs, rt Parallel Copy Lower Doubleword
2163 * PCPYUD rd, rs, rt Parallel Copy Upper Doubleword
2164 * PREVH rd, rt Parallel Reverse Halfword
2165 * PINTH rd, rs, rt Parallel Interleave Halfword
2166 * PINTEH rd, rs, rt Parallel Interleave Even Halfword
2167 * PEXEH rd, rt Parallel Exchange Even Halfword
2168 * PEXCH rd, rt Parallel Exchange Center Halfword
2169 * PEXEW rd, rt Parallel Exchange Even Word
2170 * PEXCW rd, rt Parallel Exchange Center Word
2171 * QFSRV rd, rs, rt Quadword Funnel Shift Right Variable
2172 * MFSA rd Move from Shift Amount Register
2173 * MTSA rs Move to Shift Amount Register
2174 * MTSAB rs, immediate Move Byte Count to Shift Amount Register
2175 * MTSAH rs, immediate Move Halfword Count to Shift Amount Register
2176 * PROT3W rd, rt Parallel Rotate 3 Words
2178 * MMI (MultiMedia Instruction) encodings
2179 * ======================================
2181 * MMI instructions encoding table keys:
2183 * * This code is reserved for future use. An attempt to execute it
2184 * causes a Reserved Instruction exception.
2185 * % This code indicates an instruction class. The instruction word
2186 * must be further decoded by examining additional tables that show
2187 * the values for other instruction fields.
2188 * # This code is reserved for the unsupported instructions DMULT,
2189 * DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2190 * to execute it causes a Reserved Instruction exception.
2192 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2195 * +--------+----------------------------------------+
2197 * +--------+----------------------------------------+
2199 * opcode bits 28..26
2200 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2201 * 31..29 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2202 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2203 * 0 000 |SPECIAL| REGIMM| J | JAL | BEQ | BNE | BLEZ | BGTZ
2204 * 1 001 | ADDI | ADDIU | SLTI | SLTIU | ANDI | ORI | XORI | LUI
2205 * 2 010 | COP0 | COP1 | * | * | BEQL | BNEL | BLEZL | BGTZL
2206 * 3 011 | DADDI | DADDIU| LDL | LDR | MMI% | * | LQ | SQ
2207 * 4 100 | LB | LH | LWL | LW | LBU | LHU | LWR | LWU
2208 * 5 101 | SB | SH | SWL | SW | SDL | SDR | SWR | CACHE
2209 * 6 110 | # | LWC1 | # | PREF | # | LDC1 | # | LD
2210 * 7 111 | # | SWC1 | # | * | # | SDC1 | # | SD
2214 MMI_OPC_CLASS_MMI
= 0x1C << 26, /* Same as OPC_SPECIAL2 */
2215 MMI_OPC_LQ
= 0x1E << 26, /* Same as OPC_MSA */
2216 MMI_OPC_SQ
= 0x1F << 26, /* Same as OPC_SPECIAL3 */
2220 * MMI instructions with opcode field = MMI:
2223 * +--------+-------------------------------+--------+
2224 * | MMI | |function|
2225 * +--------+-------------------------------+--------+
2227 * function bits 2..0
2228 * bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
2229 * 5..3 | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
2230 * -------+-------+-------+-------+-------+-------+-------+-------+-------
2231 * 0 000 | MADD | MADDU | * | * | PLZCW | * | * | *
2232 * 1 001 | MMI0% | MMI2% | * | * | * | * | * | *
2233 * 2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 | * | * | * | *
2234 * 3 011 | MULT1 | MULTU1| DIV1 | DIVU1 | * | * | * | *
2235 * 4 100 | MADD1 | MADDU1| * | * | * | * | * | *
2236 * 5 101 | MMI1% | MMI3% | * | * | * | * | * | *
2237 * 6 110 | PMFHL | PMTHL | * | * | PSLLH | * | PSRLH | PSRAH
2238 * 7 111 | * | * | * | * | PSLLW | * | PSRLW | PSRAW
2241 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2243 MMI_OPC_MADD
= 0x00 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADD */
2244 MMI_OPC_MADDU
= 0x01 | MMI_OPC_CLASS_MMI
, /* Same as OPC_MADDU */
2245 MMI_OPC_PLZCW
= 0x04 | MMI_OPC_CLASS_MMI
,
2246 MMI_OPC_CLASS_MMI0
= 0x08 | MMI_OPC_CLASS_MMI
,
2247 MMI_OPC_CLASS_MMI2
= 0x09 | MMI_OPC_CLASS_MMI
,
2248 MMI_OPC_MFHI1
= 0x10 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFHI */
2249 MMI_OPC_MTHI1
= 0x11 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTHI */
2250 MMI_OPC_MFLO1
= 0x12 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MFLO */
2251 MMI_OPC_MTLO1
= 0x13 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MTLO */
2252 MMI_OPC_MULT1
= 0x18 | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_MULT */
2253 MMI_OPC_MULTU1
= 0x19 | MMI_OPC_CLASS_MMI
, /* Same min. as OPC_MULTU */
2254 MMI_OPC_DIV1
= 0x1A | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIV */
2255 MMI_OPC_DIVU1
= 0x1B | MMI_OPC_CLASS_MMI
, /* Same minor as OPC_DIVU */
2256 MMI_OPC_MADD1
= 0x20 | MMI_OPC_CLASS_MMI
,
2257 MMI_OPC_MADDU1
= 0x21 | MMI_OPC_CLASS_MMI
,
2258 MMI_OPC_CLASS_MMI1
= 0x28 | MMI_OPC_CLASS_MMI
,
2259 MMI_OPC_CLASS_MMI3
= 0x29 | MMI_OPC_CLASS_MMI
,
2260 MMI_OPC_PMFHL
= 0x30 | MMI_OPC_CLASS_MMI
,
2261 MMI_OPC_PMTHL
= 0x31 | MMI_OPC_CLASS_MMI
,
2262 MMI_OPC_PSLLH
= 0x34 | MMI_OPC_CLASS_MMI
,
2263 MMI_OPC_PSRLH
= 0x36 | MMI_OPC_CLASS_MMI
,
2264 MMI_OPC_PSRAH
= 0x37 | MMI_OPC_CLASS_MMI
,
2265 MMI_OPC_PSLLW
= 0x3C | MMI_OPC_CLASS_MMI
,
2266 MMI_OPC_PSRLW
= 0x3E | MMI_OPC_CLASS_MMI
,
2267 MMI_OPC_PSRAW
= 0x3F | MMI_OPC_CLASS_MMI
,
2271 * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2274 * +--------+----------------------+--------+--------+
2275 * | MMI | |function| MMI0 |
2276 * +--------+----------------------+--------+--------+
2278 * function bits 7..6
2279 * bits | 0 | 1 | 2 | 3
2280 * 10..8 | 00 | 01 | 10 | 11
2281 * -------+-------+-------+-------+-------
2282 * 0 000 | PADDW | PSUBW | PCGTW | PMAXW
2283 * 1 001 | PADDH | PSUBH | PCGTH | PMAXH
2284 * 2 010 | PADDB | PSUBB | PCGTB | *
2285 * 3 011 | * | * | * | *
2286 * 4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2287 * 5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2288 * 6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2289 * 7 111 | * | * | PEXT5 | PPAC5
2292 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2294 MMI_OPC_0_PADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI0
,
2295 MMI_OPC_0_PSUBW
= (0x01 << 6) | MMI_OPC_CLASS_MMI0
,
2296 MMI_OPC_0_PCGTW
= (0x02 << 6) | MMI_OPC_CLASS_MMI0
,
2297 MMI_OPC_0_PMAXW
= (0x03 << 6) | MMI_OPC_CLASS_MMI0
,
2298 MMI_OPC_0_PADDH
= (0x04 << 6) | MMI_OPC_CLASS_MMI0
,
2299 MMI_OPC_0_PSUBH
= (0x05 << 6) | MMI_OPC_CLASS_MMI0
,
2300 MMI_OPC_0_PCGTH
= (0x06 << 6) | MMI_OPC_CLASS_MMI0
,
2301 MMI_OPC_0_PMAXH
= (0x07 << 6) | MMI_OPC_CLASS_MMI0
,
2302 MMI_OPC_0_PADDB
= (0x08 << 6) | MMI_OPC_CLASS_MMI0
,
2303 MMI_OPC_0_PSUBB
= (0x09 << 6) | MMI_OPC_CLASS_MMI0
,
2304 MMI_OPC_0_PCGTB
= (0x0A << 6) | MMI_OPC_CLASS_MMI0
,
2305 MMI_OPC_0_PADDSW
= (0x10 << 6) | MMI_OPC_CLASS_MMI0
,
2306 MMI_OPC_0_PSUBSW
= (0x11 << 6) | MMI_OPC_CLASS_MMI0
,
2307 MMI_OPC_0_PEXTLW
= (0x12 << 6) | MMI_OPC_CLASS_MMI0
,
2308 MMI_OPC_0_PPACW
= (0x13 << 6) | MMI_OPC_CLASS_MMI0
,
2309 MMI_OPC_0_PADDSH
= (0x14 << 6) | MMI_OPC_CLASS_MMI0
,
2310 MMI_OPC_0_PSUBSH
= (0x15 << 6) | MMI_OPC_CLASS_MMI0
,
2311 MMI_OPC_0_PEXTLH
= (0x16 << 6) | MMI_OPC_CLASS_MMI0
,
2312 MMI_OPC_0_PPACH
= (0x17 << 6) | MMI_OPC_CLASS_MMI0
,
2313 MMI_OPC_0_PADDSB
= (0x18 << 6) | MMI_OPC_CLASS_MMI0
,
2314 MMI_OPC_0_PSUBSB
= (0x19 << 6) | MMI_OPC_CLASS_MMI0
,
2315 MMI_OPC_0_PEXTLB
= (0x1A << 6) | MMI_OPC_CLASS_MMI0
,
2316 MMI_OPC_0_PPACB
= (0x1B << 6) | MMI_OPC_CLASS_MMI0
,
2317 MMI_OPC_0_PEXT5
= (0x1E << 6) | MMI_OPC_CLASS_MMI0
,
2318 MMI_OPC_0_PPAC5
= (0x1F << 6) | MMI_OPC_CLASS_MMI0
,
2322 * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2325 * +--------+----------------------+--------+--------+
2326 * | MMI | |function| MMI1 |
2327 * +--------+----------------------+--------+--------+
2329 * function bits 7..6
2330 * bits | 0 | 1 | 2 | 3
2331 * 10..8 | 00 | 01 | 10 | 11
2332 * -------+-------+-------+-------+-------
2333 * 0 000 | * | PABSW | PCEQW | PMINW
2334 * 1 001 | PADSBH| PABSH | PCEQH | PMINH
2335 * 2 010 | * | * | PCEQB | *
2336 * 3 011 | * | * | * | *
2337 * 4 100 | PADDUW| PSUBUW| PEXTUW| *
2338 * 5 101 | PADDUH| PSUBUH| PEXTUH| *
2339 * 6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2340 * 7 111 | * | * | * | *
2343 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2345 MMI_OPC_1_PABSW
= (0x01 << 6) | MMI_OPC_CLASS_MMI1
,
2346 MMI_OPC_1_PCEQW
= (0x02 << 6) | MMI_OPC_CLASS_MMI1
,
2347 MMI_OPC_1_PMINW
= (0x03 << 6) | MMI_OPC_CLASS_MMI1
,
2348 MMI_OPC_1_PADSBH
= (0x04 << 6) | MMI_OPC_CLASS_MMI1
,
2349 MMI_OPC_1_PABSH
= (0x05 << 6) | MMI_OPC_CLASS_MMI1
,
2350 MMI_OPC_1_PCEQH
= (0x06 << 6) | MMI_OPC_CLASS_MMI1
,
2351 MMI_OPC_1_PMINH
= (0x07 << 6) | MMI_OPC_CLASS_MMI1
,
2352 MMI_OPC_1_PCEQB
= (0x0A << 6) | MMI_OPC_CLASS_MMI1
,
2353 MMI_OPC_1_PADDUW
= (0x10 << 6) | MMI_OPC_CLASS_MMI1
,
2354 MMI_OPC_1_PSUBUW
= (0x11 << 6) | MMI_OPC_CLASS_MMI1
,
2355 MMI_OPC_1_PEXTUW
= (0x12 << 6) | MMI_OPC_CLASS_MMI1
,
2356 MMI_OPC_1_PADDUH
= (0x14 << 6) | MMI_OPC_CLASS_MMI1
,
2357 MMI_OPC_1_PSUBUH
= (0x15 << 6) | MMI_OPC_CLASS_MMI1
,
2358 MMI_OPC_1_PEXTUH
= (0x16 << 6) | MMI_OPC_CLASS_MMI1
,
2359 MMI_OPC_1_PADDUB
= (0x18 << 6) | MMI_OPC_CLASS_MMI1
,
2360 MMI_OPC_1_PSUBUB
= (0x19 << 6) | MMI_OPC_CLASS_MMI1
,
2361 MMI_OPC_1_PEXTUB
= (0x1A << 6) | MMI_OPC_CLASS_MMI1
,
2362 MMI_OPC_1_QFSRV
= (0x1B << 6) | MMI_OPC_CLASS_MMI1
,
2366 * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2369 * +--------+----------------------+--------+--------+
2370 * | MMI | |function| MMI2 |
2371 * +--------+----------------------+--------+--------+
2373 * function bits 7..6
2374 * bits | 0 | 1 | 2 | 3
2375 * 10..8 | 00 | 01 | 10 | 11
2376 * -------+-------+-------+-------+-------
2377 * 0 000 | PMADDW| * | PSLLVW| PSRLVW
2378 * 1 001 | PMSUBW| * | * | *
2379 * 2 010 | PMFHI | PMFLO | PINTH | *
2380 * 3 011 | PMULTW| PDIVW | PCPYLD| *
2381 * 4 100 | PMADDH| PHMADH| PAND | PXOR
2382 * 5 101 | PMSUBH| PHMSBH| * | *
2383 * 6 110 | * | * | PEXEH | PREVH
2384 * 7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2387 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2389 MMI_OPC_2_PMADDW
= (0x00 << 6) | MMI_OPC_CLASS_MMI2
,
2390 MMI_OPC_2_PSLLVW
= (0x02 << 6) | MMI_OPC_CLASS_MMI2
,
2391 MMI_OPC_2_PSRLVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI2
,
2392 MMI_OPC_2_PMSUBW
= (0x04 << 6) | MMI_OPC_CLASS_MMI2
,
2393 MMI_OPC_2_PMFHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI2
,
2394 MMI_OPC_2_PMFLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI2
,
2395 MMI_OPC_2_PINTH
= (0x0A << 6) | MMI_OPC_CLASS_MMI2
,
2396 MMI_OPC_2_PMULTW
= (0x0C << 6) | MMI_OPC_CLASS_MMI2
,
2397 MMI_OPC_2_PDIVW
= (0x0D << 6) | MMI_OPC_CLASS_MMI2
,
2398 MMI_OPC_2_PCPYLD
= (0x0E << 6) | MMI_OPC_CLASS_MMI2
,
2399 MMI_OPC_2_PMADDH
= (0x10 << 6) | MMI_OPC_CLASS_MMI2
,
2400 MMI_OPC_2_PHMADH
= (0x11 << 6) | MMI_OPC_CLASS_MMI2
,
2401 MMI_OPC_2_PAND
= (0x12 << 6) | MMI_OPC_CLASS_MMI2
,
2402 MMI_OPC_2_PXOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI2
,
2403 MMI_OPC_2_PMSUBH
= (0x14 << 6) | MMI_OPC_CLASS_MMI2
,
2404 MMI_OPC_2_PHMSBH
= (0x15 << 6) | MMI_OPC_CLASS_MMI2
,
2405 MMI_OPC_2_PEXEH
= (0x1A << 6) | MMI_OPC_CLASS_MMI2
,
2406 MMI_OPC_2_PREVH
= (0x1B << 6) | MMI_OPC_CLASS_MMI2
,
2407 MMI_OPC_2_PMULTH
= (0x1C << 6) | MMI_OPC_CLASS_MMI2
,
2408 MMI_OPC_2_PDIVBW
= (0x1D << 6) | MMI_OPC_CLASS_MMI2
,
2409 MMI_OPC_2_PEXEW
= (0x1E << 6) | MMI_OPC_CLASS_MMI2
,
2410 MMI_OPC_2_PROT3W
= (0x1F << 6) | MMI_OPC_CLASS_MMI2
,
2414 * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2417 * +--------+----------------------+--------+--------+
2418 * | MMI | |function| MMI3 |
2419 * +--------+----------------------+--------+--------+
2421 * function bits 7..6
2422 * bits | 0 | 1 | 2 | 3
2423 * 10..8 | 00 | 01 | 10 | 11
2424 * -------+-------+-------+-------+-------
2425 * 0 000 |PMADDUW| * | * | PSRAVW
2426 * 1 001 | * | * | * | *
2427 * 2 010 | PMTHI | PMTLO | PINTEH| *
2428 * 3 011 |PMULTUW| PDIVUW| PCPYUD| *
2429 * 4 100 | * | * | POR | PNOR
2430 * 5 101 | * | * | * | *
2431 * 6 110 | * | * | PEXCH | PCPYH
2432 * 7 111 | * | * | PEXCW | *
2435 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2437 MMI_OPC_3_PMADDUW
= (0x00 << 6) | MMI_OPC_CLASS_MMI3
,
2438 MMI_OPC_3_PSRAVW
= (0x03 << 6) | MMI_OPC_CLASS_MMI3
,
2439 MMI_OPC_3_PMTHI
= (0x08 << 6) | MMI_OPC_CLASS_MMI3
,
2440 MMI_OPC_3_PMTLO
= (0x09 << 6) | MMI_OPC_CLASS_MMI3
,
2441 MMI_OPC_3_PINTEH
= (0x0A << 6) | MMI_OPC_CLASS_MMI3
,
2442 MMI_OPC_3_PMULTUW
= (0x0C << 6) | MMI_OPC_CLASS_MMI3
,
2443 MMI_OPC_3_PDIVUW
= (0x0D << 6) | MMI_OPC_CLASS_MMI3
,
2444 MMI_OPC_3_PCPYUD
= (0x0E << 6) | MMI_OPC_CLASS_MMI3
,
2445 MMI_OPC_3_POR
= (0x12 << 6) | MMI_OPC_CLASS_MMI3
,
2446 MMI_OPC_3_PNOR
= (0x13 << 6) | MMI_OPC_CLASS_MMI3
,
2447 MMI_OPC_3_PEXCH
= (0x1A << 6) | MMI_OPC_CLASS_MMI3
,
2448 MMI_OPC_3_PCPYH
= (0x1B << 6) | MMI_OPC_CLASS_MMI3
,
2449 MMI_OPC_3_PEXCW
= (0x1E << 6) | MMI_OPC_CLASS_MMI3
,
2452 /* global register indices */
2453 static TCGv cpu_gpr
[32], cpu_PC
;
2454 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
2455 static TCGv cpu_dspctrl
, btarget
, bcond
;
2456 static TCGv cpu_lladdr
, cpu_llval
;
2457 static TCGv_i32 hflags
;
2458 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
2459 static TCGv_i64 fpu_f64
[32];
2460 static TCGv_i64 msa_wr_d
[64];
2462 #if defined(TARGET_MIPS64)
2463 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2464 static TCGv_i64 cpu_mmr
[32];
2467 #if !defined(TARGET_MIPS64)
2469 static TCGv mxu_gpr
[NUMBER_OF_MXU_REGISTERS
- 1];
2473 #include "exec/gen-icount.h"
2475 #define gen_helper_0e0i(name, arg) do { \
2476 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
2477 gen_helper_##name(cpu_env, helper_tmp); \
2478 tcg_temp_free_i32(helper_tmp); \
2481 #define gen_helper_0e1i(name, arg1, arg2) do { \
2482 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2483 gen_helper_##name(cpu_env, arg1, helper_tmp); \
2484 tcg_temp_free_i32(helper_tmp); \
2487 #define gen_helper_1e0i(name, ret, arg1) do { \
2488 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
2489 gen_helper_##name(ret, cpu_env, helper_tmp); \
2490 tcg_temp_free_i32(helper_tmp); \
2493 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
2494 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
2495 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
2496 tcg_temp_free_i32(helper_tmp); \
2499 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
2500 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2501 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
2502 tcg_temp_free_i32(helper_tmp); \
2505 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
2506 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
2507 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
2508 tcg_temp_free_i32(helper_tmp); \
2511 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
2512 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
2513 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
2514 tcg_temp_free_i32(helper_tmp); \
2517 typedef struct DisasContext
{
2518 DisasContextBase base
;
2519 target_ulong saved_pc
;
2520 target_ulong page_start
;
2522 uint64_t insn_flags
;
2523 int32_t CP0_Config1
;
2524 int32_t CP0_Config2
;
2525 int32_t CP0_Config3
;
2526 int32_t CP0_Config5
;
2527 /* Routine used to access memory */
2529 MemOp default_tcg_memop_mask
;
2530 uint32_t hflags
, saved_hflags
;
2531 target_ulong btarget
;
2542 int CP0_LLAddr_shift
;
2552 #define DISAS_STOP DISAS_TARGET_0
2553 #define DISAS_EXIT DISAS_TARGET_1
2555 static const char * const regnames
[] = {
2556 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2557 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2558 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2559 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2562 static const char * const regnames_HI
[] = {
2563 "HI0", "HI1", "HI2", "HI3",
2566 static const char * const regnames_LO
[] = {
2567 "LO0", "LO1", "LO2", "LO3",
2570 static const char * const fregnames
[] = {
2571 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
2572 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
2573 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2574 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2577 static const char * const msaregnames
[] = {
2578 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
2579 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
2580 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
2581 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
2582 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
2583 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2584 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2585 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2586 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2587 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2588 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2589 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2590 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2591 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2592 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2593 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2596 #if !defined(TARGET_MIPS64)
2597 static const char * const mxuregnames
[] = {
2598 "XR1", "XR2", "XR3", "XR4", "XR5", "XR6", "XR7", "XR8",
2599 "XR9", "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2603 #define LOG_DISAS(...) \
2605 if (MIPS_DEBUG_DISAS) { \
2606 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
2610 #define MIPS_INVAL(op) \
2612 if (MIPS_DEBUG_DISAS) { \
2613 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
2614 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2615 ctx->base.pc_next, ctx->opcode, op, \
2616 ctx->opcode >> 26, ctx->opcode & 0x3F, \
2617 ((ctx->opcode >> 16) & 0x1F)); \
2621 /* General purpose registers moves. */
2622 static inline void gen_load_gpr(TCGv t
, int reg
)
2625 tcg_gen_movi_tl(t
, 0);
2627 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
2631 static inline void gen_store_gpr(TCGv t
, int reg
)
2634 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
2638 /* Moves to/from shadow registers. */
2639 static inline void gen_load_srsgpr(int from
, int to
)
2641 TCGv t0
= tcg_temp_new();
2644 tcg_gen_movi_tl(t0
, 0);
2646 TCGv_i32 t2
= tcg_temp_new_i32();
2647 TCGv_ptr addr
= tcg_temp_new_ptr();
2649 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2650 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2651 tcg_gen_andi_i32(t2
, t2
, 0xf);
2652 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2653 tcg_gen_ext_i32_ptr(addr
, t2
);
2654 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2656 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
2657 tcg_temp_free_ptr(addr
);
2658 tcg_temp_free_i32(t2
);
2660 gen_store_gpr(t0
, to
);
2664 static inline void gen_store_srsgpr(int from
, int to
)
2667 TCGv t0
= tcg_temp_new();
2668 TCGv_i32 t2
= tcg_temp_new_i32();
2669 TCGv_ptr addr
= tcg_temp_new_ptr();
2671 gen_load_gpr(t0
, from
);
2672 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
2673 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
2674 tcg_gen_andi_i32(t2
, t2
, 0xf);
2675 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
2676 tcg_gen_ext_i32_ptr(addr
, t2
);
2677 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
2679 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
2680 tcg_temp_free_ptr(addr
);
2681 tcg_temp_free_i32(t2
);
2686 #if !defined(TARGET_MIPS64)
2687 /* MXU General purpose registers moves. */
2688 static inline void gen_load_mxu_gpr(TCGv t
, unsigned int reg
)
2691 tcg_gen_movi_tl(t
, 0);
2692 } else if (reg
<= 15) {
2693 tcg_gen_mov_tl(t
, mxu_gpr
[reg
- 1]);
2697 static inline void gen_store_mxu_gpr(TCGv t
, unsigned int reg
)
2699 if (reg
> 0 && reg
<= 15) {
2700 tcg_gen_mov_tl(mxu_gpr
[reg
- 1], t
);
2704 /* MXU control register moves. */
2705 static inline void gen_load_mxu_cr(TCGv t
)
2707 tcg_gen_mov_tl(t
, mxu_CR
);
2710 static inline void gen_store_mxu_cr(TCGv t
)
2712 /* TODO: Add handling of RW rules for MXU_CR. */
2713 tcg_gen_mov_tl(mxu_CR
, t
);
2719 static inline void gen_save_pc(target_ulong pc
)
2721 tcg_gen_movi_tl(cpu_PC
, pc
);
2724 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
2726 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
2727 if (do_save_pc
&& ctx
->base
.pc_next
!= ctx
->saved_pc
) {
2728 gen_save_pc(ctx
->base
.pc_next
);
2729 ctx
->saved_pc
= ctx
->base
.pc_next
;
2731 if (ctx
->hflags
!= ctx
->saved_hflags
) {
2732 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
2733 ctx
->saved_hflags
= ctx
->hflags
;
2734 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2740 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
2746 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
2748 ctx
->saved_hflags
= ctx
->hflags
;
2749 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
2755 ctx
->btarget
= env
->btarget
;
2760 static inline void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
2762 TCGv_i32 texcp
= tcg_const_i32(excp
);
2763 TCGv_i32 terr
= tcg_const_i32(err
);
2764 save_cpu_state(ctx
, 1);
2765 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
2766 tcg_temp_free_i32(terr
);
2767 tcg_temp_free_i32(texcp
);
2768 ctx
->base
.is_jmp
= DISAS_NORETURN
;
2771 static inline void generate_exception(DisasContext
*ctx
, int excp
)
2773 gen_helper_0e0i(raise_exception
, excp
);
2776 static inline void generate_exception_end(DisasContext
*ctx
, int excp
)
2778 generate_exception_err(ctx
, excp
, 0);
2781 /* Floating point register moves. */
2782 static void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2784 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2785 generate_exception(ctx
, EXCP_RI
);
2787 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
2790 static void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2793 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
2794 generate_exception(ctx
, EXCP_RI
);
2796 t64
= tcg_temp_new_i64();
2797 tcg_gen_extu_i32_i64(t64
, t
);
2798 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
2799 tcg_temp_free_i64(t64
);
2802 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2804 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2805 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
2807 gen_load_fpr32(ctx
, t
, reg
| 1);
2811 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
2813 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2814 TCGv_i64 t64
= tcg_temp_new_i64();
2815 tcg_gen_extu_i32_i64(t64
, t
);
2816 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
2817 tcg_temp_free_i64(t64
);
2819 gen_store_fpr32(ctx
, t
, reg
| 1);
2823 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2825 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2826 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
2828 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
2832 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
2834 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
2835 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
2838 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
2839 t0
= tcg_temp_new_i64();
2840 tcg_gen_shri_i64(t0
, t
, 32);
2841 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
2842 tcg_temp_free_i64(t0
);
2846 static inline int get_fp_bit(int cc
)
2855 /* Addresses computation */
2856 static inline void gen_op_addr_add(DisasContext
*ctx
, TCGv ret
, TCGv arg0
,
2859 tcg_gen_add_tl(ret
, arg0
, arg1
);
2861 #if defined(TARGET_MIPS64)
2862 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2863 tcg_gen_ext32s_i64(ret
, ret
);
2868 static inline void gen_op_addr_addi(DisasContext
*ctx
, TCGv ret
, TCGv base
,
2871 tcg_gen_addi_tl(ret
, base
, ofs
);
2873 #if defined(TARGET_MIPS64)
2874 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2875 tcg_gen_ext32s_i64(ret
, ret
);
2880 /* Addresses computation (translation time) */
2881 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
2884 target_long sum
= base
+ offset
;
2886 #if defined(TARGET_MIPS64)
2887 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
2894 /* Sign-extract the low 32-bits to a target_long. */
2895 static inline void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
2897 #if defined(TARGET_MIPS64)
2898 tcg_gen_ext32s_i64(ret
, arg
);
2900 tcg_gen_extrl_i64_i32(ret
, arg
);
2904 /* Sign-extract the high 32-bits to a target_long. */
2905 static inline void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
2907 #if defined(TARGET_MIPS64)
2908 tcg_gen_sari_i64(ret
, arg
, 32);
2910 tcg_gen_extrh_i64_i32(ret
, arg
);
2914 static inline void check_cp0_enabled(DisasContext
*ctx
)
2916 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
2917 generate_exception_err(ctx
, EXCP_CpU
, 0);
2921 static inline void check_cp1_enabled(DisasContext
*ctx
)
2923 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
))) {
2924 generate_exception_err(ctx
, EXCP_CpU
, 1);
2929 * Verify that the processor is running with COP1X instructions enabled.
2930 * This is associated with the nabla symbol in the MIPS32 and MIPS64
2933 static inline void check_cop1x(DisasContext
*ctx
)
2935 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
))) {
2936 generate_exception_end(ctx
, EXCP_RI
);
2941 * Verify that the processor is running with 64-bit floating-point
2942 * operations enabled.
2944 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
2946 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
))) {
2947 generate_exception_end(ctx
, EXCP_RI
);
2952 * Verify if floating point register is valid; an operation is not defined
2953 * if bit 0 of any register specification is set and the FR bit in the
2954 * Status register equals zero, since the register numbers specify an
2955 * even-odd pair of adjacent coprocessor general registers. When the FR bit
2956 * in the Status register equals one, both even and odd register numbers
2957 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2959 * Multiple 64 bit wide registers can be checked by calling
2960 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2962 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
2964 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1))) {
2965 generate_exception_end(ctx
, EXCP_RI
);
2970 * Verify that the processor is running with DSP instructions enabled.
2971 * This is enabled by CP0 Status register MX(24) bit.
2973 static inline void check_dsp(DisasContext
*ctx
)
2975 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
2976 if (ctx
->insn_flags
& ASE_DSP
) {
2977 generate_exception_end(ctx
, EXCP_DSPDIS
);
2979 generate_exception_end(ctx
, EXCP_RI
);
2984 static inline void check_dsp_r2(DisasContext
*ctx
)
2986 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R2
))) {
2987 if (ctx
->insn_flags
& ASE_DSP
) {
2988 generate_exception_end(ctx
, EXCP_DSPDIS
);
2990 generate_exception_end(ctx
, EXCP_RI
);
2995 static inline void check_dsp_r3(DisasContext
*ctx
)
2997 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP_R3
))) {
2998 if (ctx
->insn_flags
& ASE_DSP
) {
2999 generate_exception_end(ctx
, EXCP_DSPDIS
);
3001 generate_exception_end(ctx
, EXCP_RI
);
3007 * This code generates a "reserved instruction" exception if the
3008 * CPU does not support the instruction set corresponding to flags.
3010 static inline void check_insn(DisasContext
*ctx
, uint64_t flags
)
3012 if (unlikely(!(ctx
->insn_flags
& flags
))) {
3013 generate_exception_end(ctx
, EXCP_RI
);
3018 * This code generates a "reserved instruction" exception if the
3019 * CPU has corresponding flag set which indicates that the instruction
3022 static inline void check_insn_opc_removed(DisasContext
*ctx
, uint64_t flags
)
3024 if (unlikely(ctx
->insn_flags
& flags
)) {
3025 generate_exception_end(ctx
, EXCP_RI
);
3030 * The Linux kernel traps certain reserved instruction exceptions to
3031 * emulate the corresponding instructions. QEMU is the kernel in user
3032 * mode, so those traps are emulated by accepting the instructions.
3034 * A reserved instruction exception is generated for flagged CPUs if
3035 * QEMU runs in system mode.
3037 static inline void check_insn_opc_user_only(DisasContext
*ctx
, uint64_t flags
)
3039 #ifndef CONFIG_USER_ONLY
3040 check_insn_opc_removed(ctx
, flags
);
3045 * This code generates a "reserved instruction" exception if the
3046 * CPU does not support 64-bit paired-single (PS) floating point data type.
3048 static inline void check_ps(DisasContext
*ctx
)
3050 if (unlikely(!ctx
->ps
)) {
3051 generate_exception(ctx
, EXCP_RI
);
3053 check_cp1_64bitmode(ctx
);
3056 #ifdef TARGET_MIPS64
3058 * This code generates a "reserved instruction" exception if 64-bit
3059 * instructions are not enabled.
3061 static inline void check_mips_64(DisasContext
*ctx
)
3063 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
))) {
3064 generate_exception_end(ctx
, EXCP_RI
);
3069 #ifndef CONFIG_USER_ONLY
3070 static inline void check_mvh(DisasContext
*ctx
)
3072 if (unlikely(!ctx
->mvh
)) {
3073 generate_exception(ctx
, EXCP_RI
);
3079 * This code generates a "reserved instruction" exception if the
3080 * Config5 XNP bit is set.
3082 static inline void check_xnp(DisasContext
*ctx
)
3084 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_XNP
))) {
3085 generate_exception_end(ctx
, EXCP_RI
);
3089 #ifndef CONFIG_USER_ONLY
3091 * This code generates a "reserved instruction" exception if the
3092 * Config3 PW bit is NOT set.
3094 static inline void check_pw(DisasContext
*ctx
)
3096 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_PW
)))) {
3097 generate_exception_end(ctx
, EXCP_RI
);
3103 * This code generates a "reserved instruction" exception if the
3104 * Config3 MT bit is NOT set.
3106 static inline void check_mt(DisasContext
*ctx
)
3108 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3109 generate_exception_end(ctx
, EXCP_RI
);
3113 #ifndef CONFIG_USER_ONLY
3115 * This code generates a "coprocessor unusable" exception if CP0 is not
3116 * available, and, if that is not the case, generates a "reserved instruction"
3117 * exception if the Config5 MT bit is NOT set. This is needed for availability
3118 * control of some of MT ASE instructions.
3120 static inline void check_cp0_mt(DisasContext
*ctx
)
3122 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
))) {
3123 generate_exception_err(ctx
, EXCP_CpU
, 0);
3125 if (unlikely(!(ctx
->CP0_Config3
& (1 << CP0C3_MT
)))) {
3126 generate_exception_err(ctx
, EXCP_RI
, 0);
3133 * This code generates a "reserved instruction" exception if the
3134 * Config5 NMS bit is set.
3136 static inline void check_nms(DisasContext
*ctx
)
3138 if (unlikely(ctx
->CP0_Config5
& (1 << CP0C5_NMS
))) {
3139 generate_exception_end(ctx
, EXCP_RI
);
3144 * This code generates a "reserved instruction" exception if the
3145 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3146 * Config2 TL, and Config5 L2C are unset.
3148 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext
*ctx
)
3150 if (unlikely((ctx
->CP0_Config5
& (1 << CP0C5_NMS
)) &&
3151 !(ctx
->CP0_Config1
& (1 << CP0C1_DL
)) &&
3152 !(ctx
->CP0_Config1
& (1 << CP0C1_IL
)) &&
3153 !(ctx
->CP0_Config2
& (1 << CP0C2_SL
)) &&
3154 !(ctx
->CP0_Config2
& (1 << CP0C2_TL
)) &&
3155 !(ctx
->CP0_Config5
& (1 << CP0C5_L2C
)))) {
3156 generate_exception_end(ctx
, EXCP_RI
);
3161 * This code generates a "reserved instruction" exception if the
3162 * Config5 EVA bit is NOT set.
3164 static inline void check_eva(DisasContext
*ctx
)
3166 if (unlikely(!(ctx
->CP0_Config5
& (1 << CP0C5_EVA
)))) {
3167 generate_exception_end(ctx
, EXCP_RI
);
3173 * Define small wrappers for gen_load_fpr* so that we have a uniform
3174 * calling interface for 32 and 64-bit FPRs. No sense in changing
3175 * all callers for gen_load_fpr32 when we need the CTX parameter for
3178 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3179 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3180 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
3181 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
3182 int ft, int fs, int cc) \
3184 TCGv_i##bits fp0 = tcg_temp_new_i##bits(); \
3185 TCGv_i##bits fp1 = tcg_temp_new_i##bits(); \
3194 check_cp1_registers(ctx, fs | ft); \
3202 gen_ldcmp_fpr##bits(ctx, fp0, fs); \
3203 gen_ldcmp_fpr##bits(ctx, fp1, ft); \
3206 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); \
3209 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); \
3212 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); \
3215 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); \
3218 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); \
3221 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); \
3224 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); \
3227 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); \
3230 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); \
3233 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); \
3236 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); \
3239 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); \
3242 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); \
3245 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); \
3248 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); \
3251 gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); \
3256 tcg_temp_free_i##bits(fp0); \
3257 tcg_temp_free_i##bits(fp1); \
3260 FOP_CONDS(, 0, d
, FMT_D
, 64)
3261 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
3262 FOP_CONDS(, 0, s
, FMT_S
, 32)
3263 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
3264 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
3265 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
3268 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
3269 static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n, \
3270 int ft, int fs, int fd) \
3272 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
3273 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
3274 if (ifmt == FMT_D) { \
3275 check_cp1_registers(ctx, fs | ft | fd); \
3277 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
3278 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
3281 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
3284 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
3287 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
3290 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
3293 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
3296 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
3299 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
3302 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
3305 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
3308 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
3311 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
3314 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
3317 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
3320 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
3323 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
3326 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
3329 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
3332 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
3335 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
3338 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
3341 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
3344 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
3350 tcg_temp_free_i ## bits(fp0); \
3351 tcg_temp_free_i ## bits(fp1); \
3354 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
3355 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
3357 #undef gen_ldcmp_fpr32
3358 #undef gen_ldcmp_fpr64
3360 /* load/store instructions. */
3361 #ifdef CONFIG_USER_ONLY
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 TCGv t0 = tcg_temp_new(); \
3367 tcg_gen_mov_tl(t0, arg1); \
3368 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
3369 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
3370 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
3371 tcg_temp_free(t0); \
3374 #define OP_LD_ATOMIC(insn, fname) \
3375 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
3376 DisasContext *ctx) \
3378 gen_helper_1e1i(insn, ret, arg1, mem_idx); \
3381 OP_LD_ATOMIC(ll
, ld32s
);
3382 #if defined(TARGET_MIPS64)
3383 OP_LD_ATOMIC(lld
, ld64
);
3387 static void gen_base_offset_addr(DisasContext
*ctx
, TCGv addr
,
3388 int base
, int offset
)
3391 tcg_gen_movi_tl(addr
, offset
);
3392 } else if (offset
== 0) {
3393 gen_load_gpr(addr
, base
);
3395 tcg_gen_movi_tl(addr
, offset
);
3396 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
3400 static target_ulong
pc_relative_pc(DisasContext
*ctx
)
3402 target_ulong pc
= ctx
->base
.pc_next
;
3404 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3405 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
3410 pc
&= ~(target_ulong
)3;
3415 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
3416 int rt
, int base
, int offset
)
3419 int mem_idx
= ctx
->mem_idx
;
3421 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
3423 * Loongson CPU uses a load to zero register for prefetch.
3424 * We emulate it as a NOP. On other CPU we must perform the
3425 * actual memory access.
3430 t0
= tcg_temp_new();
3431 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3434 #if defined(TARGET_MIPS64)
3436 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
|
3437 ctx
->default_tcg_memop_mask
);
3438 gen_store_gpr(t0
, rt
);
3441 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
|
3442 ctx
->default_tcg_memop_mask
);
3443 gen_store_gpr(t0
, rt
);
3447 op_ld_lld(t0
, t0
, mem_idx
, ctx
);
3448 gen_store_gpr(t0
, rt
);
3451 t1
= tcg_temp_new();
3453 * Do a byte access to possibly trigger a page
3454 * fault with the unaligned address.
3456 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3457 tcg_gen_andi_tl(t1
, t0
, 7);
3458 #ifndef TARGET_WORDS_BIGENDIAN
3459 tcg_gen_xori_tl(t1
, t1
, 7);
3461 tcg_gen_shli_tl(t1
, t1
, 3);
3462 tcg_gen_andi_tl(t0
, t0
, ~7);
3463 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3464 tcg_gen_shl_tl(t0
, t0
, t1
);
3465 t2
= tcg_const_tl(-1);
3466 tcg_gen_shl_tl(t2
, t2
, t1
);
3467 gen_load_gpr(t1
, rt
);
3468 tcg_gen_andc_tl(t1
, t1
, t2
);
3470 tcg_gen_or_tl(t0
, t0
, t1
);
3472 gen_store_gpr(t0
, rt
);
3475 t1
= tcg_temp_new();
3477 * Do a byte access to possibly trigger a page
3478 * fault with the unaligned address.
3480 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3481 tcg_gen_andi_tl(t1
, t0
, 7);
3482 #ifdef TARGET_WORDS_BIGENDIAN
3483 tcg_gen_xori_tl(t1
, t1
, 7);
3485 tcg_gen_shli_tl(t1
, t1
, 3);
3486 tcg_gen_andi_tl(t0
, t0
, ~7);
3487 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3488 tcg_gen_shr_tl(t0
, t0
, t1
);
3489 tcg_gen_xori_tl(t1
, t1
, 63);
3490 t2
= tcg_const_tl(0xfffffffffffffffeull
);
3491 tcg_gen_shl_tl(t2
, t2
, t1
);
3492 gen_load_gpr(t1
, rt
);
3493 tcg_gen_and_tl(t1
, t1
, t2
);
3495 tcg_gen_or_tl(t0
, t0
, t1
);
3497 gen_store_gpr(t0
, rt
);
3500 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3501 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3503 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEQ
);
3504 gen_store_gpr(t0
, rt
);
3508 t1
= tcg_const_tl(pc_relative_pc(ctx
));
3509 gen_op_addr_add(ctx
, t0
, t0
, t1
);
3511 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
);
3512 gen_store_gpr(t0
, rt
);
3515 mem_idx
= MIPS_HFLAG_UM
;
3518 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESL
|
3519 ctx
->default_tcg_memop_mask
);
3520 gen_store_gpr(t0
, rt
);
3523 mem_idx
= MIPS_HFLAG_UM
;
3526 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TESW
|
3527 ctx
->default_tcg_memop_mask
);
3528 gen_store_gpr(t0
, rt
);
3531 mem_idx
= MIPS_HFLAG_UM
;
3534 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUW
|
3535 ctx
->default_tcg_memop_mask
);
3536 gen_store_gpr(t0
, rt
);
3539 mem_idx
= MIPS_HFLAG_UM
;
3542 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_SB
);
3543 gen_store_gpr(t0
, rt
);
3546 mem_idx
= MIPS_HFLAG_UM
;
3549 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_UB
);
3550 gen_store_gpr(t0
, rt
);
3553 mem_idx
= MIPS_HFLAG_UM
;
3556 t1
= tcg_temp_new();
3558 * Do a byte access to possibly trigger a page
3559 * fault with the unaligned address.
3561 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3562 tcg_gen_andi_tl(t1
, t0
, 3);
3563 #ifndef TARGET_WORDS_BIGENDIAN
3564 tcg_gen_xori_tl(t1
, t1
, 3);
3566 tcg_gen_shli_tl(t1
, t1
, 3);
3567 tcg_gen_andi_tl(t0
, t0
, ~3);
3568 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3569 tcg_gen_shl_tl(t0
, t0
, t1
);
3570 t2
= tcg_const_tl(-1);
3571 tcg_gen_shl_tl(t2
, t2
, t1
);
3572 gen_load_gpr(t1
, rt
);
3573 tcg_gen_andc_tl(t1
, t1
, t2
);
3575 tcg_gen_or_tl(t0
, t0
, t1
);
3577 tcg_gen_ext32s_tl(t0
, t0
);
3578 gen_store_gpr(t0
, rt
);
3581 mem_idx
= MIPS_HFLAG_UM
;
3584 t1
= tcg_temp_new();
3586 * Do a byte access to possibly trigger a page
3587 * fault with the unaligned address.
3589 tcg_gen_qemu_ld_tl(t1
, t0
, mem_idx
, MO_UB
);
3590 tcg_gen_andi_tl(t1
, t0
, 3);
3591 #ifdef TARGET_WORDS_BIGENDIAN
3592 tcg_gen_xori_tl(t1
, t1
, 3);
3594 tcg_gen_shli_tl(t1
, t1
, 3);
3595 tcg_gen_andi_tl(t0
, t0
, ~3);
3596 tcg_gen_qemu_ld_tl(t0
, t0
, mem_idx
, MO_TEUL
);
3597 tcg_gen_shr_tl(t0
, t0
, t1
);
3598 tcg_gen_xori_tl(t1
, t1
, 31);
3599 t2
= tcg_const_tl(0xfffffffeull
);
3600 tcg_gen_shl_tl(t2
, t2
, t1
);
3601 gen_load_gpr(t1
, rt
);
3602 tcg_gen_and_tl(t1
, t1
, t2
);
3604 tcg_gen_or_tl(t0
, t0
, t1
);
3606 tcg_gen_ext32s_tl(t0
, t0
);
3607 gen_store_gpr(t0
, rt
);
3610 mem_idx
= MIPS_HFLAG_UM
;
3614 op_ld_ll(t0
, t0
, mem_idx
, ctx
);
3615 gen_store_gpr(t0
, rt
);
3621 static void gen_llwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3622 uint32_t reg1
, uint32_t reg2
)
3624 TCGv taddr
= tcg_temp_new();
3625 TCGv_i64 tval
= tcg_temp_new_i64();
3626 TCGv tmp1
= tcg_temp_new();
3627 TCGv tmp2
= tcg_temp_new();
3629 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3630 tcg_gen_qemu_ld64(tval
, taddr
, ctx
->mem_idx
);
3631 #ifdef TARGET_WORDS_BIGENDIAN
3632 tcg_gen_extr_i64_tl(tmp2
, tmp1
, tval
);
3634 tcg_gen_extr_i64_tl(tmp1
, tmp2
, tval
);
3636 gen_store_gpr(tmp1
, reg1
);
3637 tcg_temp_free(tmp1
);
3638 gen_store_gpr(tmp2
, reg2
);
3639 tcg_temp_free(tmp2
);
3640 tcg_gen_st_i64(tval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3641 tcg_temp_free_i64(tval
);
3642 tcg_gen_st_tl(taddr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3643 tcg_temp_free(taddr
);
3647 static void gen_st(DisasContext
*ctx
, uint32_t opc
, int rt
,
3648 int base
, int offset
)
3650 TCGv t0
= tcg_temp_new();
3651 TCGv t1
= tcg_temp_new();
3652 int mem_idx
= ctx
->mem_idx
;
3654 gen_base_offset_addr(ctx
, t0
, base
, offset
);
3655 gen_load_gpr(t1
, rt
);
3657 #if defined(TARGET_MIPS64)
3659 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEQ
|
3660 ctx
->default_tcg_memop_mask
);
3663 gen_helper_0e2i(sdl
, t1
, t0
, mem_idx
);
3666 gen_helper_0e2i(sdr
, t1
, t0
, mem_idx
);
3670 mem_idx
= MIPS_HFLAG_UM
;
3673 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUL
|
3674 ctx
->default_tcg_memop_mask
);
3677 mem_idx
= MIPS_HFLAG_UM
;
3680 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_TEUW
|
3681 ctx
->default_tcg_memop_mask
);
3684 mem_idx
= MIPS_HFLAG_UM
;
3687 tcg_gen_qemu_st_tl(t1
, t0
, mem_idx
, MO_8
);
3690 mem_idx
= MIPS_HFLAG_UM
;
3693 gen_helper_0e2i(swl
, t1
, t0
, mem_idx
);
3696 mem_idx
= MIPS_HFLAG_UM
;
3699 gen_helper_0e2i(swr
, t1
, t0
, mem_idx
);
3707 /* Store conditional */
3708 static void gen_st_cond(DisasContext
*ctx
, int rt
, int base
, int offset
,
3709 MemOp tcg_mo
, bool eva
)
3712 TCGLabel
*l1
= gen_new_label();
3713 TCGLabel
*done
= gen_new_label();
3715 t0
= tcg_temp_new();
3716 addr
= tcg_temp_new();
3717 /* compare the address against that of the preceeding LL */
3718 gen_base_offset_addr(ctx
, addr
, base
, offset
);
3719 tcg_gen_brcond_tl(TCG_COND_EQ
, addr
, cpu_lladdr
, l1
);
3720 tcg_temp_free(addr
);
3721 tcg_gen_movi_tl(t0
, 0);
3722 gen_store_gpr(t0
, rt
);
3726 /* generate cmpxchg */
3727 val
= tcg_temp_new();
3728 gen_load_gpr(val
, rt
);
3729 tcg_gen_atomic_cmpxchg_tl(t0
, cpu_lladdr
, cpu_llval
, val
,
3730 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, tcg_mo
);
3731 tcg_gen_setcond_tl(TCG_COND_EQ
, t0
, t0
, cpu_llval
);
3732 gen_store_gpr(t0
, rt
);
3735 gen_set_label(done
);
3740 static void gen_scwp(DisasContext
*ctx
, uint32_t base
, int16_t offset
,
3741 uint32_t reg1
, uint32_t reg2
, bool eva
)
3743 TCGv taddr
= tcg_temp_local_new();
3744 TCGv lladdr
= tcg_temp_local_new();
3745 TCGv_i64 tval
= tcg_temp_new_i64();
3746 TCGv_i64 llval
= tcg_temp_new_i64();
3747 TCGv_i64 val
= tcg_temp_new_i64();
3748 TCGv tmp1
= tcg_temp_new();
3749 TCGv tmp2
= tcg_temp_new();
3750 TCGLabel
*lab_fail
= gen_new_label();
3751 TCGLabel
*lab_done
= gen_new_label();
3753 gen_base_offset_addr(ctx
, taddr
, base
, offset
);
3755 tcg_gen_ld_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3756 tcg_gen_brcond_tl(TCG_COND_NE
, taddr
, lladdr
, lab_fail
);
3758 gen_load_gpr(tmp1
, reg1
);
3759 gen_load_gpr(tmp2
, reg2
);
3761 #ifdef TARGET_WORDS_BIGENDIAN
3762 tcg_gen_concat_tl_i64(tval
, tmp2
, tmp1
);
3764 tcg_gen_concat_tl_i64(tval
, tmp1
, tmp2
);
3767 tcg_gen_ld_i64(llval
, cpu_env
, offsetof(CPUMIPSState
, llval_wp
));
3768 tcg_gen_atomic_cmpxchg_i64(val
, taddr
, llval
, tval
,
3769 eva
? MIPS_HFLAG_UM
: ctx
->mem_idx
, MO_64
);
3771 tcg_gen_movi_tl(cpu_gpr
[reg1
], 1);
3773 tcg_gen_brcond_i64(TCG_COND_EQ
, val
, llval
, lab_done
);
3775 gen_set_label(lab_fail
);
3778 tcg_gen_movi_tl(cpu_gpr
[reg1
], 0);
3780 gen_set_label(lab_done
);
3781 tcg_gen_movi_tl(lladdr
, -1);
3782 tcg_gen_st_tl(lladdr
, cpu_env
, offsetof(CPUMIPSState
, lladdr
));
3785 /* Load and store */
3786 static void gen_flt_ldst(DisasContext
*ctx
, uint32_t opc
, int ft
,
3790 * Don't do NOP if destination is zero: we must perform the actual
3796 TCGv_i32 fp0
= tcg_temp_new_i32();
3797 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
3798 ctx
->default_tcg_memop_mask
);
3799 gen_store_fpr32(ctx
, fp0
, ft
);
3800 tcg_temp_free_i32(fp0
);
3805 TCGv_i32 fp0
= tcg_temp_new_i32();
3806 gen_load_fpr32(ctx
, fp0
, ft
);
3807 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
3808 ctx
->default_tcg_memop_mask
);
3809 tcg_temp_free_i32(fp0
);
3814 TCGv_i64 fp0
= tcg_temp_new_i64();
3815 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3816 ctx
->default_tcg_memop_mask
);
3817 gen_store_fpr64(ctx
, fp0
, ft
);
3818 tcg_temp_free_i64(fp0
);
3823 TCGv_i64 fp0
= tcg_temp_new_i64();
3824 gen_load_fpr64(ctx
, fp0
, ft
);
3825 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
3826 ctx
->default_tcg_memop_mask
);
3827 tcg_temp_free_i64(fp0
);
3831 MIPS_INVAL("flt_ldst");
3832 generate_exception_end(ctx
, EXCP_RI
);
3837 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
3838 int rs
, int16_t imm
)
3840 TCGv t0
= tcg_temp_new();
3842 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
3843 check_cp1_enabled(ctx
);
3847 check_insn(ctx
, ISA_MIPS2
);
3850 gen_base_offset_addr(ctx
, t0
, rs
, imm
);
3851 gen_flt_ldst(ctx
, op
, rt
, t0
);
3854 generate_exception_err(ctx
, EXCP_CpU
, 1);
3859 /* Arithmetic with immediate operand */
3860 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
3861 int rt
, int rs
, int imm
)
3863 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3865 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
3867 * If no destination, treat it as a NOP.
3868 * For addi, we must generate the overflow exception when needed.
3875 TCGv t0
= tcg_temp_local_new();
3876 TCGv t1
= tcg_temp_new();
3877 TCGv t2
= tcg_temp_new();
3878 TCGLabel
*l1
= gen_new_label();
3880 gen_load_gpr(t1
, rs
);
3881 tcg_gen_addi_tl(t0
, t1
, uimm
);
3882 tcg_gen_ext32s_tl(t0
, t0
);
3884 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3885 tcg_gen_xori_tl(t2
, t0
, uimm
);
3886 tcg_gen_and_tl(t1
, t1
, t2
);
3888 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3890 /* operands of same sign, result different sign */
3891 generate_exception(ctx
, EXCP_OVERFLOW
);
3893 tcg_gen_ext32s_tl(t0
, t0
);
3894 gen_store_gpr(t0
, rt
);
3900 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3901 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3903 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3906 #if defined(TARGET_MIPS64)
3909 TCGv t0
= tcg_temp_local_new();
3910 TCGv t1
= tcg_temp_new();
3911 TCGv t2
= tcg_temp_new();
3912 TCGLabel
*l1
= gen_new_label();
3914 gen_load_gpr(t1
, rs
);
3915 tcg_gen_addi_tl(t0
, t1
, uimm
);
3917 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
3918 tcg_gen_xori_tl(t2
, t0
, uimm
);
3919 tcg_gen_and_tl(t1
, t1
, t2
);
3921 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
3923 /* operands of same sign, result different sign */
3924 generate_exception(ctx
, EXCP_OVERFLOW
);
3926 gen_store_gpr(t0
, rt
);
3932 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3934 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3941 /* Logic with immediate operand */
3942 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
3943 int rt
, int rs
, int16_t imm
)
3948 /* If no destination, treat it as a NOP. */
3951 uimm
= (uint16_t)imm
;
3954 if (likely(rs
!= 0)) {
3955 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3957 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
3962 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3964 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3968 if (likely(rs
!= 0)) {
3969 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
3971 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
3975 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
3977 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
3978 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
3980 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
3989 /* Set on less than with immediate operand */
3990 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
3991 int rt
, int rs
, int16_t imm
)
3993 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
3997 /* If no destination, treat it as a NOP. */
4000 t0
= tcg_temp_new();
4001 gen_load_gpr(t0
, rs
);
4004 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
4007 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
4013 /* Shifts with immediate operand */
4014 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
4015 int rt
, int rs
, int16_t imm
)
4017 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
4021 /* If no destination, treat it as a NOP. */
4025 t0
= tcg_temp_new();
4026 gen_load_gpr(t0
, rs
);
4029 tcg_gen_shli_tl(t0
, t0
, uimm
);
4030 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4033 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4037 tcg_gen_ext32u_tl(t0
, t0
);
4038 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4040 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4045 TCGv_i32 t1
= tcg_temp_new_i32();
4047 tcg_gen_trunc_tl_i32(t1
, t0
);
4048 tcg_gen_rotri_i32(t1
, t1
, uimm
);
4049 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
4050 tcg_temp_free_i32(t1
);
4052 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
4055 #if defined(TARGET_MIPS64)
4057 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
4060 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
4063 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
4067 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
4069 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
4073 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4076 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4079 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4082 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
4090 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
4091 int rd
, int rs
, int rt
)
4093 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
4094 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
4096 * If no destination, treat it as a NOP.
4097 * For add & sub, we must generate the overflow exception when needed.
4105 TCGv t0
= tcg_temp_local_new();
4106 TCGv t1
= tcg_temp_new();
4107 TCGv t2
= tcg_temp_new();
4108 TCGLabel
*l1
= gen_new_label();
4110 gen_load_gpr(t1
, rs
);
4111 gen_load_gpr(t2
, rt
);
4112 tcg_gen_add_tl(t0
, t1
, t2
);
4113 tcg_gen_ext32s_tl(t0
, t0
);
4114 tcg_gen_xor_tl(t1
, t1
, t2
);
4115 tcg_gen_xor_tl(t2
, t0
, t2
);
4116 tcg_gen_andc_tl(t1
, t2
, t1
);
4118 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4120 /* operands of same sign, result different sign */
4121 generate_exception(ctx
, EXCP_OVERFLOW
);
4123 gen_store_gpr(t0
, rd
);
4128 if (rs
!= 0 && rt
!= 0) {
4129 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4130 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4131 } else if (rs
== 0 && rt
!= 0) {
4132 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4133 } else if (rs
!= 0 && rt
== 0) {
4134 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4136 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4141 TCGv t0
= tcg_temp_local_new();
4142 TCGv t1
= tcg_temp_new();
4143 TCGv t2
= tcg_temp_new();
4144 TCGLabel
*l1
= gen_new_label();
4146 gen_load_gpr(t1
, rs
);
4147 gen_load_gpr(t2
, rt
);
4148 tcg_gen_sub_tl(t0
, t1
, t2
);
4149 tcg_gen_ext32s_tl(t0
, t0
);
4150 tcg_gen_xor_tl(t2
, t1
, t2
);
4151 tcg_gen_xor_tl(t1
, t0
, t1
);
4152 tcg_gen_and_tl(t1
, t1
, t2
);
4154 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4157 * operands of different sign, first operand and the result
4160 generate_exception(ctx
, EXCP_OVERFLOW
);
4162 gen_store_gpr(t0
, rd
);
4167 if (rs
!= 0 && rt
!= 0) {
4168 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4169 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4170 } else if (rs
== 0 && rt
!= 0) {
4171 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4172 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4173 } else if (rs
!= 0 && rt
== 0) {
4174 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4176 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4179 #if defined(TARGET_MIPS64)
4182 TCGv t0
= tcg_temp_local_new();
4183 TCGv t1
= tcg_temp_new();
4184 TCGv t2
= tcg_temp_new();
4185 TCGLabel
*l1
= gen_new_label();
4187 gen_load_gpr(t1
, rs
);
4188 gen_load_gpr(t2
, rt
);
4189 tcg_gen_add_tl(t0
, t1
, t2
);
4190 tcg_gen_xor_tl(t1
, t1
, t2
);
4191 tcg_gen_xor_tl(t2
, t0
, t2
);
4192 tcg_gen_andc_tl(t1
, t2
, t1
);
4194 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4196 /* operands of same sign, result different sign */
4197 generate_exception(ctx
, EXCP_OVERFLOW
);
4199 gen_store_gpr(t0
, rd
);
4204 if (rs
!= 0 && rt
!= 0) {
4205 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4206 } else if (rs
== 0 && rt
!= 0) {
4207 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4208 } else if (rs
!= 0 && rt
== 0) {
4209 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4211 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4216 TCGv t0
= tcg_temp_local_new();
4217 TCGv t1
= tcg_temp_new();
4218 TCGv t2
= tcg_temp_new();
4219 TCGLabel
*l1
= gen_new_label();
4221 gen_load_gpr(t1
, rs
);
4222 gen_load_gpr(t2
, rt
);
4223 tcg_gen_sub_tl(t0
, t1
, t2
);
4224 tcg_gen_xor_tl(t2
, t1
, t2
);
4225 tcg_gen_xor_tl(t1
, t0
, t1
);
4226 tcg_gen_and_tl(t1
, t1
, t2
);
4228 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
4231 * Operands of different sign, first operand and result different
4234 generate_exception(ctx
, EXCP_OVERFLOW
);
4236 gen_store_gpr(t0
, rd
);
4241 if (rs
!= 0 && rt
!= 0) {
4242 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4243 } else if (rs
== 0 && rt
!= 0) {
4244 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4245 } else if (rs
!= 0 && rt
== 0) {
4246 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4248 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4253 if (likely(rs
!= 0 && rt
!= 0)) {
4254 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4255 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4257 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4263 /* Conditional move */
4264 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
4265 int rd
, int rs
, int rt
)
4270 /* If no destination, treat it as a NOP. */
4274 t0
= tcg_temp_new();
4275 gen_load_gpr(t0
, rt
);
4276 t1
= tcg_const_tl(0);
4277 t2
= tcg_temp_new();
4278 gen_load_gpr(t2
, rs
);
4281 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4284 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
4287 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4290 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
4299 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
4300 int rd
, int rs
, int rt
)
4303 /* If no destination, treat it as a NOP. */
4309 if (likely(rs
!= 0 && rt
!= 0)) {
4310 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4312 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4316 if (rs
!= 0 && rt
!= 0) {
4317 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4318 } else if (rs
== 0 && rt
!= 0) {
4319 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4320 } else if (rs
!= 0 && rt
== 0) {
4321 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4323 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
4327 if (likely(rs
!= 0 && rt
!= 0)) {
4328 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4329 } else if (rs
== 0 && rt
!= 0) {
4330 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4331 } else if (rs
!= 0 && rt
== 0) {
4332 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4334 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4338 if (likely(rs
!= 0 && rt
!= 0)) {
4339 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
4340 } else if (rs
== 0 && rt
!= 0) {
4341 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
4342 } else if (rs
!= 0 && rt
== 0) {
4343 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
4345 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4351 /* Set on lower than */
4352 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
4353 int rd
, int rs
, int rt
)
4358 /* If no destination, treat it as a NOP. */
4362 t0
= tcg_temp_new();
4363 t1
= tcg_temp_new();
4364 gen_load_gpr(t0
, rs
);
4365 gen_load_gpr(t1
, rt
);
4368 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
4371 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
4379 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
4380 int rd
, int rs
, int rt
)
4386 * If no destination, treat it as a NOP.
4387 * For add & sub, we must generate the overflow exception when needed.
4392 t0
= tcg_temp_new();
4393 t1
= tcg_temp_new();
4394 gen_load_gpr(t0
, rs
);
4395 gen_load_gpr(t1
, rt
);
4398 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4399 tcg_gen_shl_tl(t0
, t1
, t0
);
4400 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4403 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4404 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4407 tcg_gen_ext32u_tl(t1
, t1
);
4408 tcg_gen_andi_tl(t0
, t0
, 0x1f);
4409 tcg_gen_shr_tl(t0
, t1
, t0
);
4410 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4414 TCGv_i32 t2
= tcg_temp_new_i32();
4415 TCGv_i32 t3
= tcg_temp_new_i32();
4417 tcg_gen_trunc_tl_i32(t2
, t0
);
4418 tcg_gen_trunc_tl_i32(t3
, t1
);
4419 tcg_gen_andi_i32(t2
, t2
, 0x1f);
4420 tcg_gen_rotr_i32(t2
, t3
, t2
);
4421 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4422 tcg_temp_free_i32(t2
);
4423 tcg_temp_free_i32(t3
);
4426 #if defined(TARGET_MIPS64)
4428 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4429 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
4432 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4433 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
4436 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4437 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
4440 tcg_gen_andi_tl(t0
, t0
, 0x3f);
4441 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
4449 #if defined(TARGET_MIPS64)
4450 /* Copy GPR to and from TX79 HI1/LO1 register. */
4451 static void gen_HILO1_tx79(DisasContext
*ctx
, uint32_t opc
, int reg
)
4453 if (reg
== 0 && (opc
== MMI_OPC_MFHI1
|| opc
== MMI_OPC_MFLO1
)) {
4460 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[1]);
4463 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[1]);
4467 tcg_gen_mov_tl(cpu_HI
[1], cpu_gpr
[reg
]);
4469 tcg_gen_movi_tl(cpu_HI
[1], 0);
4474 tcg_gen_mov_tl(cpu_LO
[1], cpu_gpr
[reg
]);
4476 tcg_gen_movi_tl(cpu_LO
[1], 0);
4480 MIPS_INVAL("mfthilo1 TX79");
4481 generate_exception_end(ctx
, EXCP_RI
);
4487 /* Arithmetic on HI/LO registers */
4488 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
4490 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
4501 #if defined(TARGET_MIPS64)
4503 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4507 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
4511 #if defined(TARGET_MIPS64)
4513 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4517 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
4522 #if defined(TARGET_MIPS64)
4524 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4528 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
4531 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
4536 #if defined(TARGET_MIPS64)
4538 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4542 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
4545 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
4551 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
4554 TCGv t0
= tcg_const_tl(addr
);
4555 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
4556 gen_store_gpr(t0
, reg
);
4560 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
4566 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
4569 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4570 addr
= addr_add(ctx
, pc
, offset
);
4571 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4575 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4576 addr
= addr_add(ctx
, pc
, offset
);
4577 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
4579 #if defined(TARGET_MIPS64)
4582 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
4583 addr
= addr_add(ctx
, pc
, offset
);
4584 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
4588 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
4591 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4592 addr
= addr_add(ctx
, pc
, offset
);
4593 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4598 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
4599 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
4600 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
4603 #if defined(TARGET_MIPS64)
4604 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
4605 case R6_OPC_LDPC
+ (1 << 16):
4606 case R6_OPC_LDPC
+ (2 << 16):
4607 case R6_OPC_LDPC
+ (3 << 16):
4609 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
4610 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
4611 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
4615 MIPS_INVAL("OPC_PCREL");
4616 generate_exception_end(ctx
, EXCP_RI
);
4623 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
4632 t0
= tcg_temp_new();
4633 t1
= tcg_temp_new();
4635 gen_load_gpr(t0
, rs
);
4636 gen_load_gpr(t1
, rt
);
4641 TCGv t2
= tcg_temp_new();
4642 TCGv t3
= tcg_temp_new();
4643 tcg_gen_ext32s_tl(t0
, t0
);
4644 tcg_gen_ext32s_tl(t1
, t1
);
4645 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4646 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4647 tcg_gen_and_tl(t2
, t2
, t3
);
4648 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4649 tcg_gen_or_tl(t2
, t2
, t3
);
4650 tcg_gen_movi_tl(t3
, 0);
4651 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4652 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4653 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4660 TCGv t2
= tcg_temp_new();
4661 TCGv t3
= tcg_temp_new();
4662 tcg_gen_ext32s_tl(t0
, t0
);
4663 tcg_gen_ext32s_tl(t1
, t1
);
4664 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4665 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4666 tcg_gen_and_tl(t2
, t2
, t3
);
4667 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4668 tcg_gen_or_tl(t2
, t2
, t3
);
4669 tcg_gen_movi_tl(t3
, 0);
4670 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4671 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4672 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4679 TCGv t2
= tcg_const_tl(0);
4680 TCGv t3
= tcg_const_tl(1);
4681 tcg_gen_ext32u_tl(t0
, t0
);
4682 tcg_gen_ext32u_tl(t1
, t1
);
4683 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4684 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4685 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4692 TCGv t2
= tcg_const_tl(0);
4693 TCGv t3
= tcg_const_tl(1);
4694 tcg_gen_ext32u_tl(t0
, t0
);
4695 tcg_gen_ext32u_tl(t1
, t1
);
4696 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4697 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4698 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
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_mul_i32(t2
, t2
, t3
);
4710 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
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_muls2_i32(t2
, t3
, t2
, t3
);
4722 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
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_mul_i32(t2
, t2
, t3
);
4734 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
4735 tcg_temp_free_i32(t2
);
4736 tcg_temp_free_i32(t3
);
4741 TCGv_i32 t2
= tcg_temp_new_i32();
4742 TCGv_i32 t3
= tcg_temp_new_i32();
4743 tcg_gen_trunc_tl_i32(t2
, t0
);
4744 tcg_gen_trunc_tl_i32(t3
, t1
);
4745 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4746 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
4747 tcg_temp_free_i32(t2
);
4748 tcg_temp_free_i32(t3
);
4751 #if defined(TARGET_MIPS64)
4754 TCGv t2
= tcg_temp_new();
4755 TCGv t3
= tcg_temp_new();
4756 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4757 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4758 tcg_gen_and_tl(t2
, t2
, t3
);
4759 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4760 tcg_gen_or_tl(t2
, t2
, t3
);
4761 tcg_gen_movi_tl(t3
, 0);
4762 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4763 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4770 TCGv t2
= tcg_temp_new();
4771 TCGv t3
= tcg_temp_new();
4772 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4773 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4774 tcg_gen_and_tl(t2
, t2
, t3
);
4775 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4776 tcg_gen_or_tl(t2
, t2
, t3
);
4777 tcg_gen_movi_tl(t3
, 0);
4778 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4779 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4786 TCGv t2
= tcg_const_tl(0);
4787 TCGv t3
= tcg_const_tl(1);
4788 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4789 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
4796 TCGv t2
= tcg_const_tl(0);
4797 TCGv t3
= tcg_const_tl(1);
4798 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4799 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
4805 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4809 TCGv t2
= tcg_temp_new();
4810 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4815 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
4819 TCGv t2
= tcg_temp_new();
4820 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
4826 MIPS_INVAL("r6 mul/div");
4827 generate_exception_end(ctx
, EXCP_RI
);
4835 #if defined(TARGET_MIPS64)
4836 static void gen_div1_tx79(DisasContext
*ctx
, uint32_t opc
, int rs
, int rt
)
4840 t0
= tcg_temp_new();
4841 t1
= tcg_temp_new();
4843 gen_load_gpr(t0
, rs
);
4844 gen_load_gpr(t1
, rt
);
4849 TCGv t2
= tcg_temp_new();
4850 TCGv t3
= tcg_temp_new();
4851 tcg_gen_ext32s_tl(t0
, t0
);
4852 tcg_gen_ext32s_tl(t1
, t1
);
4853 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4854 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4855 tcg_gen_and_tl(t2
, t2
, t3
);
4856 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4857 tcg_gen_or_tl(t2
, t2
, t3
);
4858 tcg_gen_movi_tl(t3
, 0);
4859 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4860 tcg_gen_div_tl(cpu_LO
[1], t0
, t1
);
4861 tcg_gen_rem_tl(cpu_HI
[1], t0
, t1
);
4862 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4863 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4870 TCGv t2
= tcg_const_tl(0);
4871 TCGv t3
= tcg_const_tl(1);
4872 tcg_gen_ext32u_tl(t0
, t0
);
4873 tcg_gen_ext32u_tl(t1
, t1
);
4874 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4875 tcg_gen_divu_tl(cpu_LO
[1], t0
, t1
);
4876 tcg_gen_remu_tl(cpu_HI
[1], t0
, t1
);
4877 tcg_gen_ext32s_tl(cpu_LO
[1], cpu_LO
[1]);
4878 tcg_gen_ext32s_tl(cpu_HI
[1], cpu_HI
[1]);
4884 MIPS_INVAL("div1 TX79");
4885 generate_exception_end(ctx
, EXCP_RI
);
4894 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
4895 int acc
, int rs
, int rt
)
4899 t0
= tcg_temp_new();
4900 t1
= tcg_temp_new();
4902 gen_load_gpr(t0
, rs
);
4903 gen_load_gpr(t1
, rt
);
4912 TCGv t2
= tcg_temp_new();
4913 TCGv t3
= tcg_temp_new();
4914 tcg_gen_ext32s_tl(t0
, t0
);
4915 tcg_gen_ext32s_tl(t1
, t1
);
4916 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
4917 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
4918 tcg_gen_and_tl(t2
, t2
, t3
);
4919 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4920 tcg_gen_or_tl(t2
, t2
, t3
);
4921 tcg_gen_movi_tl(t3
, 0);
4922 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4923 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4924 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4925 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4926 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4933 TCGv t2
= tcg_const_tl(0);
4934 TCGv t3
= tcg_const_tl(1);
4935 tcg_gen_ext32u_tl(t0
, t0
);
4936 tcg_gen_ext32u_tl(t1
, t1
);
4937 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4938 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
4939 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
4940 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
4941 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
4948 TCGv_i32 t2
= tcg_temp_new_i32();
4949 TCGv_i32 t3
= tcg_temp_new_i32();
4950 tcg_gen_trunc_tl_i32(t2
, t0
);
4951 tcg_gen_trunc_tl_i32(t3
, t1
);
4952 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
4953 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4954 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4955 tcg_temp_free_i32(t2
);
4956 tcg_temp_free_i32(t3
);
4961 TCGv_i32 t2
= tcg_temp_new_i32();
4962 TCGv_i32 t3
= tcg_temp_new_i32();
4963 tcg_gen_trunc_tl_i32(t2
, t0
);
4964 tcg_gen_trunc_tl_i32(t3
, t1
);
4965 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
4966 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
4967 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
4968 tcg_temp_free_i32(t2
);
4969 tcg_temp_free_i32(t3
);
4972 #if defined(TARGET_MIPS64)
4975 TCGv t2
= tcg_temp_new();
4976 TCGv t3
= tcg_temp_new();
4977 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
4978 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
4979 tcg_gen_and_tl(t2
, t2
, t3
);
4980 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
4981 tcg_gen_or_tl(t2
, t2
, t3
);
4982 tcg_gen_movi_tl(t3
, 0);
4983 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
4984 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
4985 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
4992 TCGv t2
= tcg_const_tl(0);
4993 TCGv t3
= tcg_const_tl(1);
4994 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
4995 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
4996 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
5002 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
5005 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
5010 TCGv_i64 t2
= tcg_temp_new_i64();
5011 TCGv_i64 t3
= tcg_temp_new_i64();
5013 tcg_gen_ext_tl_i64(t2
, t0
);
5014 tcg_gen_ext_tl_i64(t3
, t1
);
5015 tcg_gen_mul_i64(t2
, t2
, t3
);
5016 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5017 tcg_gen_add_i64(t2
, t2
, t3
);
5018 tcg_temp_free_i64(t3
);
5019 gen_move_low32(cpu_LO
[acc
], t2
);
5020 gen_move_high32(cpu_HI
[acc
], t2
);
5021 tcg_temp_free_i64(t2
);
5026 TCGv_i64 t2
= tcg_temp_new_i64();
5027 TCGv_i64 t3
= tcg_temp_new_i64();
5029 tcg_gen_ext32u_tl(t0
, t0
);
5030 tcg_gen_ext32u_tl(t1
, t1
);
5031 tcg_gen_extu_tl_i64(t2
, t0
);
5032 tcg_gen_extu_tl_i64(t3
, t1
);
5033 tcg_gen_mul_i64(t2
, t2
, t3
);
5034 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5035 tcg_gen_add_i64(t2
, t2
, t3
);
5036 tcg_temp_free_i64(t3
);
5037 gen_move_low32(cpu_LO
[acc
], t2
);
5038 gen_move_high32(cpu_HI
[acc
], t2
);
5039 tcg_temp_free_i64(t2
);
5044 TCGv_i64 t2
= tcg_temp_new_i64();
5045 TCGv_i64 t3
= tcg_temp_new_i64();
5047 tcg_gen_ext_tl_i64(t2
, t0
);
5048 tcg_gen_ext_tl_i64(t3
, t1
);
5049 tcg_gen_mul_i64(t2
, t2
, t3
);
5050 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5051 tcg_gen_sub_i64(t2
, t3
, t2
);
5052 tcg_temp_free_i64(t3
);
5053 gen_move_low32(cpu_LO
[acc
], t2
);
5054 gen_move_high32(cpu_HI
[acc
], t2
);
5055 tcg_temp_free_i64(t2
);
5060 TCGv_i64 t2
= tcg_temp_new_i64();
5061 TCGv_i64 t3
= tcg_temp_new_i64();
5063 tcg_gen_ext32u_tl(t0
, t0
);
5064 tcg_gen_ext32u_tl(t1
, t1
);
5065 tcg_gen_extu_tl_i64(t2
, t0
);
5066 tcg_gen_extu_tl_i64(t3
, t1
);
5067 tcg_gen_mul_i64(t2
, t2
, t3
);
5068 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5069 tcg_gen_sub_i64(t2
, t3
, t2
);
5070 tcg_temp_free_i64(t3
);
5071 gen_move_low32(cpu_LO
[acc
], t2
);
5072 gen_move_high32(cpu_HI
[acc
], t2
);
5073 tcg_temp_free_i64(t2
);
5077 MIPS_INVAL("mul/div");
5078 generate_exception_end(ctx
, EXCP_RI
);
5087 * These MULT[U] and MADD[U] instructions implemented in for example
5088 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5089 * architectures are special three-operand variants with the syntax
5091 * MULT[U][1] rd, rs, rt
5095 * (rd, LO, HI) <- rs * rt
5099 * MADD[U][1] rd, rs, rt
5103 * (rd, LO, HI) <- (LO, HI) + rs * rt
5105 * where the low-order 32-bits of the result is placed into both the
5106 * GPR rd and the special register LO. The high-order 32-bits of the
5107 * result is placed into the special register HI.
5109 * If the GPR rd is omitted in assembly language, it is taken to be 0,
5110 * which is the zero register that always reads as 0.
5112 static void gen_mul_txx9(DisasContext
*ctx
, uint32_t opc
,
5113 int rd
, int rs
, int rt
)
5115 TCGv t0
= tcg_temp_new();
5116 TCGv t1
= tcg_temp_new();
5119 gen_load_gpr(t0
, rs
);
5120 gen_load_gpr(t1
, rt
);
5128 TCGv_i32 t2
= tcg_temp_new_i32();
5129 TCGv_i32 t3
= tcg_temp_new_i32();
5130 tcg_gen_trunc_tl_i32(t2
, t0
);
5131 tcg_gen_trunc_tl_i32(t3
, t1
);
5132 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
5134 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5136 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5137 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5138 tcg_temp_free_i32(t2
);
5139 tcg_temp_free_i32(t3
);
5142 case MMI_OPC_MULTU1
:
5147 TCGv_i32 t2
= tcg_temp_new_i32();
5148 TCGv_i32 t3
= tcg_temp_new_i32();
5149 tcg_gen_trunc_tl_i32(t2
, t0
);
5150 tcg_gen_trunc_tl_i32(t3
, t1
);
5151 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
5153 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
5155 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
5156 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
5157 tcg_temp_free_i32(t2
);
5158 tcg_temp_free_i32(t3
);
5166 TCGv_i64 t2
= tcg_temp_new_i64();
5167 TCGv_i64 t3
= tcg_temp_new_i64();
5169 tcg_gen_ext_tl_i64(t2
, t0
);
5170 tcg_gen_ext_tl_i64(t3
, t1
);
5171 tcg_gen_mul_i64(t2
, t2
, t3
);
5172 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5173 tcg_gen_add_i64(t2
, t2
, t3
);
5174 tcg_temp_free_i64(t3
);
5175 gen_move_low32(cpu_LO
[acc
], t2
);
5176 gen_move_high32(cpu_HI
[acc
], t2
);
5178 gen_move_low32(cpu_gpr
[rd
], t2
);
5180 tcg_temp_free_i64(t2
);
5183 case MMI_OPC_MADDU1
:
5188 TCGv_i64 t2
= tcg_temp_new_i64();
5189 TCGv_i64 t3
= tcg_temp_new_i64();
5191 tcg_gen_ext32u_tl(t0
, t0
);
5192 tcg_gen_ext32u_tl(t1
, t1
);
5193 tcg_gen_extu_tl_i64(t2
, t0
);
5194 tcg_gen_extu_tl_i64(t3
, t1
);
5195 tcg_gen_mul_i64(t2
, t2
, t3
);
5196 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
5197 tcg_gen_add_i64(t2
, t2
, t3
);
5198 tcg_temp_free_i64(t3
);
5199 gen_move_low32(cpu_LO
[acc
], t2
);
5200 gen_move_high32(cpu_HI
[acc
], t2
);
5202 gen_move_low32(cpu_gpr
[rd
], t2
);
5204 tcg_temp_free_i64(t2
);
5208 MIPS_INVAL("mul/madd TXx9");
5209 generate_exception_end(ctx
, EXCP_RI
);
5218 static void gen_mul_vr54xx(DisasContext
*ctx
, uint32_t opc
,
5219 int rd
, int rs
, int rt
)
5221 TCGv t0
= tcg_temp_new();
5222 TCGv t1
= tcg_temp_new();
5224 gen_load_gpr(t0
, rs
);
5225 gen_load_gpr(t1
, rt
);
5228 case OPC_VR54XX_MULS
:
5229 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
5231 case OPC_VR54XX_MULSU
:
5232 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
5234 case OPC_VR54XX_MACC
:
5235 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
5237 case OPC_VR54XX_MACCU
:
5238 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
5240 case OPC_VR54XX_MSAC
:
5241 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
5243 case OPC_VR54XX_MSACU
:
5244 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
5246 case OPC_VR54XX_MULHI
:
5247 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
5249 case OPC_VR54XX_MULHIU
:
5250 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
5252 case OPC_VR54XX_MULSHI
:
5253 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
5255 case OPC_VR54XX_MULSHIU
:
5256 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
5258 case OPC_VR54XX_MACCHI
:
5259 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
5261 case OPC_VR54XX_MACCHIU
:
5262 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
5264 case OPC_VR54XX_MSACHI
:
5265 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
5267 case OPC_VR54XX_MSACHIU
:
5268 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
5271 MIPS_INVAL("mul vr54xx");
5272 generate_exception_end(ctx
, EXCP_RI
);
5275 gen_store_gpr(t0
, rd
);
5282 static void gen_cl(DisasContext
*ctx
, uint32_t opc
,
5292 gen_load_gpr(t0
, rs
);
5297 #if defined(TARGET_MIPS64)
5301 tcg_gen_not_tl(t0
, t0
);
5310 tcg_gen_ext32u_tl(t0
, t0
);
5311 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
5312 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
5314 #if defined(TARGET_MIPS64)
5319 tcg_gen_clzi_i64(t0
, t0
, 64);
5325 /* Godson integer instructions */
5326 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
5327 int rd
, int rs
, int rt
)
5339 case OPC_MULTU_G_2E
:
5340 case OPC_MULTU_G_2F
:
5341 #if defined(TARGET_MIPS64)
5342 case OPC_DMULT_G_2E
:
5343 case OPC_DMULT_G_2F
:
5344 case OPC_DMULTU_G_2E
:
5345 case OPC_DMULTU_G_2F
:
5347 t0
= tcg_temp_new();
5348 t1
= tcg_temp_new();
5351 t0
= tcg_temp_local_new();
5352 t1
= tcg_temp_local_new();
5356 gen_load_gpr(t0
, rs
);
5357 gen_load_gpr(t1
, rt
);
5362 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5363 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5365 case OPC_MULTU_G_2E
:
5366 case OPC_MULTU_G_2F
:
5367 tcg_gen_ext32u_tl(t0
, t0
);
5368 tcg_gen_ext32u_tl(t1
, t1
);
5369 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5370 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5375 TCGLabel
*l1
= gen_new_label();
5376 TCGLabel
*l2
= gen_new_label();
5377 TCGLabel
*l3
= gen_new_label();
5378 tcg_gen_ext32s_tl(t0
, t0
);
5379 tcg_gen_ext32s_tl(t1
, t1
);
5380 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5381 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5384 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5385 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5386 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5389 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5390 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5397 TCGLabel
*l1
= gen_new_label();
5398 TCGLabel
*l2
= gen_new_label();
5399 tcg_gen_ext32u_tl(t0
, t0
);
5400 tcg_gen_ext32u_tl(t1
, t1
);
5401 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5402 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5405 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5406 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5413 TCGLabel
*l1
= gen_new_label();
5414 TCGLabel
*l2
= gen_new_label();
5415 TCGLabel
*l3
= gen_new_label();
5416 tcg_gen_ext32u_tl(t0
, t0
);
5417 tcg_gen_ext32u_tl(t1
, t1
);
5418 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5419 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
5420 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
5422 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5425 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5426 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5433 TCGLabel
*l1
= gen_new_label();
5434 TCGLabel
*l2
= gen_new_label();
5435 tcg_gen_ext32u_tl(t0
, t0
);
5436 tcg_gen_ext32u_tl(t1
, t1
);
5437 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5438 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5441 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5442 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
5446 #if defined(TARGET_MIPS64)
5447 case OPC_DMULT_G_2E
:
5448 case OPC_DMULT_G_2F
:
5449 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5451 case OPC_DMULTU_G_2E
:
5452 case OPC_DMULTU_G_2F
:
5453 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
5458 TCGLabel
*l1
= gen_new_label();
5459 TCGLabel
*l2
= gen_new_label();
5460 TCGLabel
*l3
= gen_new_label();
5461 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5462 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5465 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5466 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5467 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
5470 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
5474 case OPC_DDIVU_G_2E
:
5475 case OPC_DDIVU_G_2F
:
5477 TCGLabel
*l1
= gen_new_label();
5478 TCGLabel
*l2
= gen_new_label();
5479 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5480 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5483 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
5490 TCGLabel
*l1
= gen_new_label();
5491 TCGLabel
*l2
= gen_new_label();
5492 TCGLabel
*l3
= gen_new_label();
5493 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
5494 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
5495 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
5497 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5500 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
5504 case OPC_DMODU_G_2E
:
5505 case OPC_DMODU_G_2F
:
5507 TCGLabel
*l1
= gen_new_label();
5508 TCGLabel
*l2
= gen_new_label();
5509 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
5510 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
5513 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
5524 /* Loongson multimedia instructions */
5525 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
5527 uint32_t opc
, shift_max
;
5530 opc
= MASK_LMI(ctx
->opcode
);
5536 t0
= tcg_temp_local_new_i64();
5537 t1
= tcg_temp_local_new_i64();
5540 t0
= tcg_temp_new_i64();
5541 t1
= tcg_temp_new_i64();
5545 check_cp1_enabled(ctx
);
5546 gen_load_fpr64(ctx
, t0
, rs
);
5547 gen_load_fpr64(ctx
, t1
, rt
);
5549 #define LMI_HELPER(UP, LO) \
5550 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5551 #define LMI_HELPER_1(UP, LO) \
5552 case OPC_##UP: gen_helper_##LO(t0, t0); break
5553 #define LMI_DIRECT(UP, LO, OP) \
5554 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5557 LMI_HELPER(PADDSH
, paddsh
);
5558 LMI_HELPER(PADDUSH
, paddush
);
5559 LMI_HELPER(PADDH
, paddh
);
5560 LMI_HELPER(PADDW
, paddw
);
5561 LMI_HELPER(PADDSB
, paddsb
);
5562 LMI_HELPER(PADDUSB
, paddusb
);
5563 LMI_HELPER(PADDB
, paddb
);
5565 LMI_HELPER(PSUBSH
, psubsh
);
5566 LMI_HELPER(PSUBUSH
, psubush
);
5567 LMI_HELPER(PSUBH
, psubh
);
5568 LMI_HELPER(PSUBW
, psubw
);
5569 LMI_HELPER(PSUBSB
, psubsb
);
5570 LMI_HELPER(PSUBUSB
, psubusb
);
5571 LMI_HELPER(PSUBB
, psubb
);
5573 LMI_HELPER(PSHUFH
, pshufh
);
5574 LMI_HELPER(PACKSSWH
, packsswh
);
5575 LMI_HELPER(PACKSSHB
, packsshb
);
5576 LMI_HELPER(PACKUSHB
, packushb
);
5578 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
5579 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
5580 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
5581 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
5582 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
5583 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
5585 LMI_HELPER(PAVGH
, pavgh
);
5586 LMI_HELPER(PAVGB
, pavgb
);
5587 LMI_HELPER(PMAXSH
, pmaxsh
);
5588 LMI_HELPER(PMINSH
, pminsh
);
5589 LMI_HELPER(PMAXUB
, pmaxub
);
5590 LMI_HELPER(PMINUB
, pminub
);
5592 LMI_HELPER(PCMPEQW
, pcmpeqw
);
5593 LMI_HELPER(PCMPGTW
, pcmpgtw
);
5594 LMI_HELPER(PCMPEQH
, pcmpeqh
);
5595 LMI_HELPER(PCMPGTH
, pcmpgth
);
5596 LMI_HELPER(PCMPEQB
, pcmpeqb
);
5597 LMI_HELPER(PCMPGTB
, pcmpgtb
);
5599 LMI_HELPER(PSLLW
, psllw
);
5600 LMI_HELPER(PSLLH
, psllh
);
5601 LMI_HELPER(PSRLW
, psrlw
);
5602 LMI_HELPER(PSRLH
, psrlh
);
5603 LMI_HELPER(PSRAW
, psraw
);
5604 LMI_HELPER(PSRAH
, psrah
);
5606 LMI_HELPER(PMULLH
, pmullh
);
5607 LMI_HELPER(PMULHH
, pmulhh
);
5608 LMI_HELPER(PMULHUH
, pmulhuh
);
5609 LMI_HELPER(PMADDHW
, pmaddhw
);
5611 LMI_HELPER(PASUBUB
, pasubub
);
5612 LMI_HELPER_1(BIADD
, biadd
);
5613 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
5615 LMI_DIRECT(PADDD
, paddd
, add
);
5616 LMI_DIRECT(PSUBD
, psubd
, sub
);
5617 LMI_DIRECT(XOR_CP2
, xor, xor);
5618 LMI_DIRECT(NOR_CP2
, nor
, nor
);
5619 LMI_DIRECT(AND_CP2
, and, and);
5620 LMI_DIRECT(OR_CP2
, or, or);
5623 tcg_gen_andc_i64(t0
, t1
, t0
);
5627 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
5630 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
5633 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
5636 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
5640 tcg_gen_andi_i64(t1
, t1
, 3);
5641 tcg_gen_shli_i64(t1
, t1
, 4);
5642 tcg_gen_shr_i64(t0
, t0
, t1
);
5643 tcg_gen_ext16u_i64(t0
, t0
);
5647 tcg_gen_add_i64(t0
, t0
, t1
);
5648 tcg_gen_ext32s_i64(t0
, t0
);
5651 tcg_gen_sub_i64(t0
, t0
, t1
);
5652 tcg_gen_ext32s_i64(t0
, t0
);
5674 /* Make sure shift count isn't TCG undefined behaviour. */
5675 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
5680 tcg_gen_shl_i64(t0
, t0
, t1
);
5685 * Since SRA is UndefinedResult without sign-extended inputs,
5686 * we can treat SRA and DSRA the same.
5688 tcg_gen_sar_i64(t0
, t0
, t1
);
5691 /* We want to shift in zeros for SRL; zero-extend first. */
5692 tcg_gen_ext32u_i64(t0
, t0
);
5695 tcg_gen_shr_i64(t0
, t0
, t1
);
5699 if (shift_max
== 32) {
5700 tcg_gen_ext32s_i64(t0
, t0
);
5703 /* Shifts larger than MAX produce zero. */
5704 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
5705 tcg_gen_neg_i64(t1
, t1
);
5706 tcg_gen_and_i64(t0
, t0
, t1
);
5712 TCGv_i64 t2
= tcg_temp_new_i64();
5713 TCGLabel
*lab
= gen_new_label();
5715 tcg_gen_mov_i64(t2
, t0
);
5716 tcg_gen_add_i64(t0
, t1
, t2
);
5717 if (opc
== OPC_ADD_CP2
) {
5718 tcg_gen_ext32s_i64(t0
, t0
);
5720 tcg_gen_xor_i64(t1
, t1
, t2
);
5721 tcg_gen_xor_i64(t2
, t2
, t0
);
5722 tcg_gen_andc_i64(t1
, t2
, t1
);
5723 tcg_temp_free_i64(t2
);
5724 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5725 generate_exception(ctx
, EXCP_OVERFLOW
);
5733 TCGv_i64 t2
= tcg_temp_new_i64();
5734 TCGLabel
*lab
= gen_new_label();
5736 tcg_gen_mov_i64(t2
, t0
);
5737 tcg_gen_sub_i64(t0
, t1
, t2
);
5738 if (opc
== OPC_SUB_CP2
) {
5739 tcg_gen_ext32s_i64(t0
, t0
);
5741 tcg_gen_xor_i64(t1
, t1
, t2
);
5742 tcg_gen_xor_i64(t2
, t2
, t0
);
5743 tcg_gen_and_i64(t1
, t1
, t2
);
5744 tcg_temp_free_i64(t2
);
5745 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
5746 generate_exception(ctx
, EXCP_OVERFLOW
);
5752 tcg_gen_ext32u_i64(t0
, t0
);
5753 tcg_gen_ext32u_i64(t1
, t1
);
5754 tcg_gen_mul_i64(t0
, t0
, t1
);
5764 * ??? Document is unclear: Set FCC[CC]. Does that mean the
5765 * FD field is the CC field?
5768 MIPS_INVAL("loongson_cp2");
5769 generate_exception_end(ctx
, EXCP_RI
);
5776 gen_store_fpr64(ctx
, t0
, rd
);
5778 tcg_temp_free_i64(t0
);
5779 tcg_temp_free_i64(t1
);
5783 static void gen_trap(DisasContext
*ctx
, uint32_t opc
,
5784 int rs
, int rt
, int16_t imm
)
5787 TCGv t0
= tcg_temp_new();
5788 TCGv t1
= tcg_temp_new();
5791 /* Load needed operands */
5799 /* Compare two registers */
5801 gen_load_gpr(t0
, rs
);
5802 gen_load_gpr(t1
, rt
);
5812 /* Compare register to immediate */
5813 if (rs
!= 0 || imm
!= 0) {
5814 gen_load_gpr(t0
, rs
);
5815 tcg_gen_movi_tl(t1
, (int32_t)imm
);
5822 case OPC_TEQ
: /* rs == rs */
5823 case OPC_TEQI
: /* r0 == 0 */
5824 case OPC_TGE
: /* rs >= rs */
5825 case OPC_TGEI
: /* r0 >= 0 */
5826 case OPC_TGEU
: /* rs >= rs unsigned */
5827 case OPC_TGEIU
: /* r0 >= 0 unsigned */
5829 generate_exception_end(ctx
, EXCP_TRAP
);
5831 case OPC_TLT
: /* rs < rs */
5832 case OPC_TLTI
: /* r0 < 0 */
5833 case OPC_TLTU
: /* rs < rs unsigned */
5834 case OPC_TLTIU
: /* r0 < 0 unsigned */
5835 case OPC_TNE
: /* rs != rs */
5836 case OPC_TNEI
: /* r0 != 0 */
5837 /* Never trap: treat as NOP. */
5841 TCGLabel
*l1
= gen_new_label();
5846 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
5850 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
5854 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
5858 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
5862 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
5866 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
5869 generate_exception(ctx
, EXCP_TRAP
);
5876 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
5878 if (unlikely(ctx
->base
.singlestep_enabled
)) {
5882 #ifndef CONFIG_USER_ONLY
5883 return (ctx
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
5889 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
5891 if (use_goto_tb(ctx
, dest
)) {
5894 tcg_gen_exit_tb(ctx
->base
.tb
, n
);
5897 if (ctx
->base
.singlestep_enabled
) {
5898 save_cpu_state(ctx
, 0);
5899 gen_helper_raise_exception_debug(cpu_env
);
5901 tcg_gen_lookup_and_goto_ptr();
5905 /* Branches (before delay slot) */
5906 static void gen_compute_branch(DisasContext
*ctx
, uint32_t opc
,
5908 int rs
, int rt
, int32_t offset
,
5911 target_ulong btgt
= -1;
5913 int bcond_compute
= 0;
5914 TCGv t0
= tcg_temp_new();
5915 TCGv t1
= tcg_temp_new();
5917 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
5918 #ifdef MIPS_DEBUG_DISAS
5919 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5920 TARGET_FMT_lx
"\n", ctx
->base
.pc_next
);
5922 generate_exception_end(ctx
, EXCP_RI
);
5926 /* Load needed operands */
5932 /* Compare two registers */
5934 gen_load_gpr(t0
, rs
);
5935 gen_load_gpr(t1
, rt
);
5938 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5952 /* Compare to zero */
5954 gen_load_gpr(t0
, rs
);
5957 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5960 #if defined(TARGET_MIPS64)
5962 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
5964 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
5967 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
5972 /* Jump to immediate */
5973 btgt
= ((ctx
->base
.pc_next
+ insn_bytes
) & (int32_t)0xF0000000) |
5978 /* Jump to register */
5979 if (offset
!= 0 && offset
!= 16) {
5981 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5982 * others are reserved.
5984 MIPS_INVAL("jump hint");
5985 generate_exception_end(ctx
, EXCP_RI
);
5988 gen_load_gpr(btarget
, rs
);
5991 MIPS_INVAL("branch/jump");
5992 generate_exception_end(ctx
, EXCP_RI
);
5995 if (bcond_compute
== 0) {
5996 /* No condition to be computed */
5998 case OPC_BEQ
: /* rx == rx */
5999 case OPC_BEQL
: /* rx == rx likely */
6000 case OPC_BGEZ
: /* 0 >= 0 */
6001 case OPC_BGEZL
: /* 0 >= 0 likely */
6002 case OPC_BLEZ
: /* 0 <= 0 */
6003 case OPC_BLEZL
: /* 0 <= 0 likely */
6005 ctx
->hflags
|= MIPS_HFLAG_B
;
6007 case OPC_BGEZAL
: /* 0 >= 0 */
6008 case OPC_BGEZALL
: /* 0 >= 0 likely */
6009 /* Always take and link */
6011 ctx
->hflags
|= MIPS_HFLAG_B
;
6013 case OPC_BNE
: /* rx != rx */
6014 case OPC_BGTZ
: /* 0 > 0 */
6015 case OPC_BLTZ
: /* 0 < 0 */
6018 case OPC_BLTZAL
: /* 0 < 0 */
6020 * Handle as an unconditional branch to get correct delay
6024 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ delayslot_size
;
6025 ctx
->hflags
|= MIPS_HFLAG_B
;
6027 case OPC_BLTZALL
: /* 0 < 0 likely */
6028 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6029 /* Skip the instruction in the delay slot */
6030 ctx
->base
.pc_next
+= 4;
6032 case OPC_BNEL
: /* rx != rx likely */
6033 case OPC_BGTZL
: /* 0 > 0 likely */
6034 case OPC_BLTZL
: /* 0 < 0 likely */
6035 /* Skip the instruction in the delay slot */
6036 ctx
->base
.pc_next
+= 4;
6039 ctx
->hflags
|= MIPS_HFLAG_B
;
6042 ctx
->hflags
|= MIPS_HFLAG_BX
;
6046 ctx
->hflags
|= MIPS_HFLAG_B
;
6049 ctx
->hflags
|= MIPS_HFLAG_BR
;
6053 ctx
->hflags
|= MIPS_HFLAG_BR
;
6056 MIPS_INVAL("branch/jump");
6057 generate_exception_end(ctx
, EXCP_RI
);
6063 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6066 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6069 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6072 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6075 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6078 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6081 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6085 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6089 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6092 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
6095 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6098 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
6101 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6104 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6107 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6109 #if defined(TARGET_MIPS64)
6111 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
6115 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6118 ctx
->hflags
|= MIPS_HFLAG_BC
;
6121 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
6124 ctx
->hflags
|= MIPS_HFLAG_BL
;
6127 MIPS_INVAL("conditional branch/jump");
6128 generate_exception_end(ctx
, EXCP_RI
);
6133 ctx
->btarget
= btgt
;
6135 switch (delayslot_size
) {
6137 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
6140 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
6145 int post_delay
= insn_bytes
+ delayslot_size
;
6146 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
6148 tcg_gen_movi_tl(cpu_gpr
[blink
],
6149 ctx
->base
.pc_next
+ post_delay
+ lowbit
);
6153 if (insn_bytes
== 2) {
6154 ctx
->hflags
|= MIPS_HFLAG_B16
;
6161 /* nanoMIPS Branches */
6162 static void gen_compute_branch_nm(DisasContext
*ctx
, uint32_t opc
,
6164 int rs
, int rt
, int32_t offset
)
6166 target_ulong btgt
= -1;
6167 int bcond_compute
= 0;
6168 TCGv t0
= tcg_temp_new();
6169 TCGv t1
= tcg_temp_new();
6171 /* Load needed operands */
6175 /* Compare two registers */
6177 gen_load_gpr(t0
, rs
);
6178 gen_load_gpr(t1
, rt
);
6181 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6184 /* Compare to zero */
6186 gen_load_gpr(t0
, rs
);
6189 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6192 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
6194 btgt
= ctx
->base
.pc_next
+ insn_bytes
+ offset
;
6198 /* Jump to register */
6199 if (offset
!= 0 && offset
!= 16) {
6201 * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6202 * others are reserved.
6204 MIPS_INVAL("jump hint");
6205 generate_exception_end(ctx
, EXCP_RI
);
6208 gen_load_gpr(btarget
, rs
);
6211 MIPS_INVAL("branch/jump");
6212 generate_exception_end(ctx
, EXCP_RI
);
6215 if (bcond_compute
== 0) {
6216 /* No condition to be computed */
6218 case OPC_BEQ
: /* rx == rx */
6220 ctx
->hflags
|= MIPS_HFLAG_B
;
6222 case OPC_BGEZAL
: /* 0 >= 0 */
6223 /* Always take and link */
6224 tcg_gen_movi_tl(cpu_gpr
[31],
6225 ctx
->base
.pc_next
+ insn_bytes
);
6226 ctx
->hflags
|= MIPS_HFLAG_B
;
6228 case OPC_BNE
: /* rx != rx */
6229 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 8);
6230 /* Skip the instruction in the delay slot */
6231 ctx
->base
.pc_next
+= 4;
6234 ctx
->hflags
|= MIPS_HFLAG_BR
;
6238 tcg_gen_movi_tl(cpu_gpr
[rt
],
6239 ctx
->base
.pc_next
+ insn_bytes
);
6241 ctx
->hflags
|= MIPS_HFLAG_BR
;
6244 MIPS_INVAL("branch/jump");
6245 generate_exception_end(ctx
, EXCP_RI
);
6251 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
6254 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
6257 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
6258 tcg_gen_movi_tl(cpu_gpr
[31],
6259 ctx
->base
.pc_next
+ insn_bytes
);
6262 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
6264 ctx
->hflags
|= MIPS_HFLAG_BC
;
6267 MIPS_INVAL("conditional branch/jump");
6268 generate_exception_end(ctx
, EXCP_RI
);
6273 ctx
->btarget
= btgt
;
6276 if (insn_bytes
== 2) {
6277 ctx
->hflags
|= MIPS_HFLAG_B16
;
6284 /* special3 bitfield operations */
6285 static void gen_bitops(DisasContext
*ctx
, uint32_t opc
, int rt
,
6286 int rs
, int lsb
, int msb
)
6288 TCGv t0
= tcg_temp_new();
6289 TCGv t1
= tcg_temp_new();
6291 gen_load_gpr(t1
, rs
);
6294 if (lsb
+ msb
> 31) {
6298 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6301 * The two checks together imply that lsb == 0,
6302 * so this is a simple sign-extension.
6304 tcg_gen_ext32s_tl(t0
, t1
);
6307 #if defined(TARGET_MIPS64)
6316 if (lsb
+ msb
> 63) {
6319 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
6326 gen_load_gpr(t0
, rt
);
6327 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6328 tcg_gen_ext32s_tl(t0
, t0
);
6330 #if defined(TARGET_MIPS64)
6341 gen_load_gpr(t0
, rt
);
6342 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
6347 MIPS_INVAL("bitops");
6348 generate_exception_end(ctx
, EXCP_RI
);
6353 gen_store_gpr(t0
, rt
);
6358 static void gen_bshfl(DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
6363 /* If no destination, treat it as a NOP. */
6367 t0
= tcg_temp_new();
6368 gen_load_gpr(t0
, rt
);
6372 TCGv t1
= tcg_temp_new();
6373 TCGv t2
= tcg_const_tl(0x00FF00FF);
6375 tcg_gen_shri_tl(t1
, t0
, 8);
6376 tcg_gen_and_tl(t1
, t1
, t2
);
6377 tcg_gen_and_tl(t0
, t0
, t2
);
6378 tcg_gen_shli_tl(t0
, t0
, 8);
6379 tcg_gen_or_tl(t0
, t0
, t1
);
6382 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6386 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
6389 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
6391 #if defined(TARGET_MIPS64)
6394 TCGv t1
= tcg_temp_new();
6395 TCGv t2
= tcg_const_tl(0x00FF00FF00FF00FFULL
);
6397 tcg_gen_shri_tl(t1
, t0
, 8);
6398 tcg_gen_and_tl(t1
, t1
, t2
);
6399 tcg_gen_and_tl(t0
, t0
, t2
);
6400 tcg_gen_shli_tl(t0
, t0
, 8);
6401 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6408 TCGv t1
= tcg_temp_new();
6409 TCGv t2
= tcg_const_tl(0x0000FFFF0000FFFFULL
);
6411 tcg_gen_shri_tl(t1
, t0
, 16);
6412 tcg_gen_and_tl(t1
, t1
, t2
);
6413 tcg_gen_and_tl(t0
, t0
, t2
);
6414 tcg_gen_shli_tl(t0
, t0
, 16);
6415 tcg_gen_or_tl(t0
, t0
, t1
);
6416 tcg_gen_shri_tl(t1
, t0
, 32);
6417 tcg_gen_shli_tl(t0
, t0
, 32);
6418 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
6425 MIPS_INVAL("bsfhl");
6426 generate_exception_end(ctx
, EXCP_RI
);
6433 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
6442 t0
= tcg_temp_new();
6443 t1
= tcg_temp_new();
6444 gen_load_gpr(t0
, rs
);
6445 gen_load_gpr(t1
, rt
);
6446 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
6447 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
6448 if (opc
== OPC_LSA
) {
6449 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
6458 static void gen_align_bits(DisasContext
*ctx
, int wordsz
, int rd
, int rs
,
6466 t0
= tcg_temp_new();
6467 if (bits
== 0 || bits
== wordsz
) {
6469 gen_load_gpr(t0
, rt
);
6471 gen_load_gpr(t0
, rs
);
6475 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
6477 #if defined(TARGET_MIPS64)
6479 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
6484 TCGv t1
= tcg_temp_new();
6485 gen_load_gpr(t0
, rt
);
6486 gen_load_gpr(t1
, rs
);
6490 TCGv_i64 t2
= tcg_temp_new_i64();
6491 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
6492 tcg_gen_shri_i64(t2
, t2
, 32 - bits
);
6493 gen_move_low32(cpu_gpr
[rd
], t2
);
6494 tcg_temp_free_i64(t2
);
6497 #if defined(TARGET_MIPS64)
6499 tcg_gen_shli_tl(t0
, t0
, bits
);
6500 tcg_gen_shri_tl(t1
, t1
, 64 - bits
);
6501 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
6511 static void gen_align(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6514 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, bp
* 8);
6517 static void gen_ext(DisasContext
*ctx
, int wordsz
, int rd
, int rs
, int rt
,
6520 gen_align_bits(ctx
, wordsz
, rd
, rs
, rt
, wordsz
- shift
);
6523 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
6530 t0
= tcg_temp_new();
6531 gen_load_gpr(t0
, rt
);
6534 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
6536 #if defined(TARGET_MIPS64)
6538 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
6545 #ifndef CONFIG_USER_ONLY
6546 /* CP0 (MMU and control) */
6547 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
6549 TCGv_i64 t0
= tcg_temp_new_i64();
6550 TCGv_i64 t1
= tcg_temp_new_i64();
6552 tcg_gen_ext_tl_i64(t0
, arg
);
6553 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6554 #if defined(TARGET_MIPS64)
6555 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
6557 tcg_gen_concat32_i64(t1
, t1
, t0
);
6559 tcg_gen_st_i64(t1
, cpu_env
, off
);
6560 tcg_temp_free_i64(t1
);
6561 tcg_temp_free_i64(t0
);
6564 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
6566 TCGv_i64 t0
= tcg_temp_new_i64();
6567 TCGv_i64 t1
= tcg_temp_new_i64();
6569 tcg_gen_ext_tl_i64(t0
, arg
);
6570 tcg_gen_ld_i64(t1
, cpu_env
, off
);
6571 tcg_gen_concat32_i64(t1
, t1
, t0
);
6572 tcg_gen_st_i64(t1
, cpu_env
, off
);
6573 tcg_temp_free_i64(t1
);
6574 tcg_temp_free_i64(t0
);
6577 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
6579 TCGv_i64 t0
= tcg_temp_new_i64();
6581 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6582 #if defined(TARGET_MIPS64)
6583 tcg_gen_shri_i64(t0
, t0
, 30);
6585 tcg_gen_shri_i64(t0
, t0
, 32);
6587 gen_move_low32(arg
, t0
);
6588 tcg_temp_free_i64(t0
);
6591 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
6593 TCGv_i64 t0
= tcg_temp_new_i64();
6595 tcg_gen_ld_i64(t0
, cpu_env
, off
);
6596 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
6597 gen_move_low32(arg
, t0
);
6598 tcg_temp_free_i64(t0
);
6601 static inline void gen_mfc0_load32(TCGv arg
, target_ulong off
)
6603 TCGv_i32 t0
= tcg_temp_new_i32();
6605 tcg_gen_ld_i32(t0
, cpu_env
, off
);
6606 tcg_gen_ext_i32_tl(arg
, t0
);
6607 tcg_temp_free_i32(t0
);
6610 static inline void gen_mfc0_load64(TCGv arg
, target_ulong off
)
6612 tcg_gen_ld_tl(arg
, cpu_env
, off
);
6613 tcg_gen_ext32s_tl(arg
, arg
);
6616 static inline void gen_mtc0_store32(TCGv arg
, target_ulong off
)
6618 TCGv_i32 t0
= tcg_temp_new_i32();
6620 tcg_gen_trunc_tl_i32(t0
, arg
);
6621 tcg_gen_st_i32(t0
, cpu_env
, off
);
6622 tcg_temp_free_i32(t0
);
6625 #define CP0_CHECK(c) \
6628 goto cp0_unimplemented; \
6632 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6634 const char *register_name
= "invalid";
6637 case CP0_REGISTER_02
:
6640 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6641 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6642 register_name
= "EntryLo0";
6645 goto cp0_unimplemented
;
6648 case CP0_REGISTER_03
:
6650 case CP0_REG03__ENTRYLO1
:
6651 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6652 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6653 register_name
= "EntryLo1";
6656 goto cp0_unimplemented
;
6659 case CP0_REGISTER_09
:
6661 case CP0_REG09__SAAR
:
6662 CP0_CHECK(ctx
->saar
);
6663 gen_helper_mfhc0_saar(arg
, cpu_env
);
6664 register_name
= "SAAR";
6667 goto cp0_unimplemented
;
6670 case CP0_REGISTER_17
:
6672 case CP0_REG17__LLADDR
:
6673 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_LLAddr
),
6674 ctx
->CP0_LLAddr_shift
);
6675 register_name
= "LLAddr";
6677 case CP0_REG17__MAAR
:
6678 CP0_CHECK(ctx
->mrp
);
6679 gen_helper_mfhc0_maar(arg
, cpu_env
);
6680 register_name
= "MAAR";
6683 goto cp0_unimplemented
;
6686 case CP0_REGISTER_28
:
6692 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
6693 register_name
= "TagLo";
6696 goto cp0_unimplemented
;
6700 goto cp0_unimplemented
;
6702 trace_mips_translate_c0("mfhc0", register_name
, reg
, sel
);
6706 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n",
6707 register_name
, reg
, sel
);
6708 tcg_gen_movi_tl(arg
, 0);
6711 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6713 const char *register_name
= "invalid";
6714 uint64_t mask
= ctx
->PAMask
>> 36;
6717 case CP0_REGISTER_02
:
6720 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6721 tcg_gen_andi_tl(arg
, arg
, mask
);
6722 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6723 register_name
= "EntryLo0";
6726 goto cp0_unimplemented
;
6729 case CP0_REGISTER_03
:
6731 case CP0_REG03__ENTRYLO1
:
6732 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
6733 tcg_gen_andi_tl(arg
, arg
, mask
);
6734 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6735 register_name
= "EntryLo1";
6738 goto cp0_unimplemented
;
6741 case CP0_REGISTER_09
:
6743 case CP0_REG09__SAAR
:
6744 CP0_CHECK(ctx
->saar
);
6745 gen_helper_mthc0_saar(cpu_env
, arg
);
6746 register_name
= "SAAR";
6749 goto cp0_unimplemented
;
6752 case CP0_REGISTER_17
:
6754 case CP0_REG17__LLADDR
:
6756 * LLAddr is read-only (the only exception is bit 0 if LLB is
6757 * supported); the CP0_LLAddr_rw_bitmask does not seem to be
6758 * relevant for modern MIPS cores supporting MTHC0, therefore
6759 * treating MTHC0 to LLAddr as NOP.
6761 register_name
= "LLAddr";
6763 case CP0_REG17__MAAR
:
6764 CP0_CHECK(ctx
->mrp
);
6765 gen_helper_mthc0_maar(cpu_env
, arg
);
6766 register_name
= "MAAR";
6769 goto cp0_unimplemented
;
6772 case CP0_REGISTER_28
:
6778 tcg_gen_andi_tl(arg
, arg
, mask
);
6779 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6780 register_name
= "TagLo";
6783 goto cp0_unimplemented
;
6787 goto cp0_unimplemented
;
6789 trace_mips_translate_c0("mthc0", register_name
, reg
, sel
);
6792 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n",
6793 register_name
, reg
, sel
);
6796 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
6798 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
6799 tcg_gen_movi_tl(arg
, 0);
6801 tcg_gen_movi_tl(arg
, ~0);
6805 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6807 const char *register_name
= "invalid";
6810 check_insn(ctx
, ISA_MIPS32
);
6814 case CP0_REGISTER_00
:
6816 case CP0_REG00__INDEX
:
6817 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6818 register_name
= "Index";
6820 case CP0_REG00__MVPCONTROL
:
6821 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6822 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6823 register_name
= "MVPControl";
6825 case CP0_REG00__MVPCONF0
:
6826 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6827 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6828 register_name
= "MVPConf0";
6830 case CP0_REG00__MVPCONF1
:
6831 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6832 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6833 register_name
= "MVPConf1";
6835 case CP0_REG00__VPCONTROL
:
6837 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
6838 register_name
= "VPControl";
6841 goto cp0_unimplemented
;
6844 case CP0_REGISTER_01
:
6846 case CP0_REG01__RANDOM
:
6847 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6848 gen_helper_mfc0_random(arg
, cpu_env
);
6849 register_name
= "Random";
6851 case CP0_REG01__VPECONTROL
:
6852 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6853 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6854 register_name
= "VPEControl";
6856 case CP0_REG01__VPECONF0
:
6857 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6858 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6859 register_name
= "VPEConf0";
6861 case CP0_REG01__VPECONF1
:
6862 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6863 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6864 register_name
= "VPEConf1";
6866 case CP0_REG01__YQMASK
:
6867 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6868 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
6869 register_name
= "YQMask";
6871 case CP0_REG01__VPESCHEDULE
:
6872 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6873 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6874 register_name
= "VPESchedule";
6876 case CP0_REG01__VPESCHEFBACK
:
6877 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6878 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6879 register_name
= "VPEScheFBack";
6881 case CP0_REG01__VPEOPT
:
6882 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6883 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6884 register_name
= "VPEOpt";
6887 goto cp0_unimplemented
;
6890 case CP0_REGISTER_02
:
6892 case CP0_REG02__ENTRYLO0
:
6894 TCGv_i64 tmp
= tcg_temp_new_i64();
6895 tcg_gen_ld_i64(tmp
, cpu_env
,
6896 offsetof(CPUMIPSState
, CP0_EntryLo0
));
6897 #if defined(TARGET_MIPS64)
6899 /* Move RI/XI fields to bits 31:30 */
6900 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6901 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6904 gen_move_low32(arg
, tmp
);
6905 tcg_temp_free_i64(tmp
);
6907 register_name
= "EntryLo0";
6909 case CP0_REG02__TCSTATUS
:
6910 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6911 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6912 register_name
= "TCStatus";
6914 case CP0_REG02__TCBIND
:
6915 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6916 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6917 register_name
= "TCBind";
6919 case CP0_REG02__TCRESTART
:
6920 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6921 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
6922 register_name
= "TCRestart";
6924 case CP0_REG02__TCHALT
:
6925 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6926 gen_helper_mfc0_tchalt(arg
, cpu_env
);
6927 register_name
= "TCHalt";
6929 case CP0_REG02__TCCONTEXT
:
6930 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6931 gen_helper_mfc0_tccontext(arg
, cpu_env
);
6932 register_name
= "TCContext";
6934 case CP0_REG02__TCSCHEDULE
:
6935 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6936 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
6937 register_name
= "TCSchedule";
6939 case CP0_REG02__TCSCHEFBACK
:
6940 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6941 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
6942 register_name
= "TCScheFBack";
6945 goto cp0_unimplemented
;
6948 case CP0_REGISTER_03
:
6950 case CP0_REG03__ENTRYLO1
:
6952 TCGv_i64 tmp
= tcg_temp_new_i64();
6953 tcg_gen_ld_i64(tmp
, cpu_env
,
6954 offsetof(CPUMIPSState
, CP0_EntryLo1
));
6955 #if defined(TARGET_MIPS64)
6957 /* Move RI/XI fields to bits 31:30 */
6958 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
6959 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
6962 gen_move_low32(arg
, tmp
);
6963 tcg_temp_free_i64(tmp
);
6965 register_name
= "EntryLo1";
6967 case CP0_REG03__GLOBALNUM
:
6969 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6970 register_name
= "GlobalNumber";
6973 goto cp0_unimplemented
;
6976 case CP0_REGISTER_04
:
6978 case CP0_REG04__CONTEXT
:
6979 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6980 tcg_gen_ext32s_tl(arg
, arg
);
6981 register_name
= "Context";
6983 case CP0_REG04__CONTEXTCONFIG
:
6985 /* gen_helper_mfc0_contextconfig(arg); */
6986 register_name
= "ContextConfig";
6987 goto cp0_unimplemented
;
6988 case CP0_REG04__USERLOCAL
:
6989 CP0_CHECK(ctx
->ulri
);
6990 tcg_gen_ld_tl(arg
, cpu_env
,
6991 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6992 tcg_gen_ext32s_tl(arg
, arg
);
6993 register_name
= "UserLocal";
6996 goto cp0_unimplemented
;
6999 case CP0_REGISTER_05
:
7001 case CP0_REG05__PAGEMASK
:
7002 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
7003 register_name
= "PageMask";
7005 case CP0_REG05__PAGEGRAIN
:
7006 check_insn(ctx
, ISA_MIPS32R2
);
7007 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
7008 register_name
= "PageGrain";
7010 case CP0_REG05__SEGCTL0
:
7012 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
7013 tcg_gen_ext32s_tl(arg
, arg
);
7014 register_name
= "SegCtl0";
7016 case CP0_REG05__SEGCTL1
:
7018 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
7019 tcg_gen_ext32s_tl(arg
, arg
);
7020 register_name
= "SegCtl1";
7022 case CP0_REG05__SEGCTL2
:
7024 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
7025 tcg_gen_ext32s_tl(arg
, arg
);
7026 register_name
= "SegCtl2";
7028 case CP0_REG05__PWBASE
:
7030 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7031 register_name
= "PWBase";
7033 case CP0_REG05__PWFIELD
:
7035 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWField
));
7036 register_name
= "PWField";
7038 case CP0_REG05__PWSIZE
:
7040 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWSize
));
7041 register_name
= "PWSize";
7044 goto cp0_unimplemented
;
7047 case CP0_REGISTER_06
:
7049 case CP0_REG06__WIRED
:
7050 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
7051 register_name
= "Wired";
7053 case CP0_REG06__SRSCONF0
:
7054 check_insn(ctx
, ISA_MIPS32R2
);
7055 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
7056 register_name
= "SRSConf0";
7058 case CP0_REG06__SRSCONF1
:
7059 check_insn(ctx
, ISA_MIPS32R2
);
7060 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
7061 register_name
= "SRSConf1";
7063 case CP0_REG06__SRSCONF2
:
7064 check_insn(ctx
, ISA_MIPS32R2
);
7065 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
7066 register_name
= "SRSConf2";
7068 case CP0_REG06__SRSCONF3
:
7069 check_insn(ctx
, ISA_MIPS32R2
);
7070 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
7071 register_name
= "SRSConf3";
7073 case CP0_REG06__SRSCONF4
:
7074 check_insn(ctx
, ISA_MIPS32R2
);
7075 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
7076 register_name
= "SRSConf4";
7078 case CP0_REG06__PWCTL
:
7080 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
7081 register_name
= "PWCtl";
7084 goto cp0_unimplemented
;
7087 case CP0_REGISTER_07
:
7089 case CP0_REG07__HWRENA
:
7090 check_insn(ctx
, ISA_MIPS32R2
);
7091 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
7092 register_name
= "HWREna";
7095 goto cp0_unimplemented
;
7098 case CP0_REGISTER_08
:
7100 case CP0_REG08__BADVADDR
:
7101 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
7102 tcg_gen_ext32s_tl(arg
, arg
);
7103 register_name
= "BadVAddr";
7105 case CP0_REG08__BADINSTR
:
7107 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
7108 register_name
= "BadInstr";
7110 case CP0_REG08__BADINSTRP
:
7112 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
7113 register_name
= "BadInstrP";
7115 case CP0_REG08__BADINSTRX
:
7117 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
7118 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
7119 register_name
= "BadInstrX";
7122 goto cp0_unimplemented
;
7125 case CP0_REGISTER_09
:
7127 case CP0_REG09__COUNT
:
7128 /* Mark as an IO operation because we read the time. */
7129 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7132 gen_helper_mfc0_count(arg
, cpu_env
);
7134 * Break the TB to be able to take timer interrupts immediately
7135 * after reading count. DISAS_STOP isn't sufficient, we need to
7136 * ensure we break completely out of translated code.
7138 gen_save_pc(ctx
->base
.pc_next
+ 4);
7139 ctx
->base
.is_jmp
= DISAS_EXIT
;
7140 register_name
= "Count";
7142 case CP0_REG09__SAARI
:
7143 CP0_CHECK(ctx
->saar
);
7144 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
7145 register_name
= "SAARI";
7147 case CP0_REG09__SAAR
:
7148 CP0_CHECK(ctx
->saar
);
7149 gen_helper_mfc0_saar(arg
, cpu_env
);
7150 register_name
= "SAAR";
7153 goto cp0_unimplemented
;
7156 case CP0_REGISTER_10
:
7158 case CP0_REG10__ENTRYHI
:
7159 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
7160 tcg_gen_ext32s_tl(arg
, arg
);
7161 register_name
= "EntryHi";
7164 goto cp0_unimplemented
;
7167 case CP0_REGISTER_11
:
7169 case CP0_REG11__COMPARE
:
7170 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
7171 register_name
= "Compare";
7173 /* 6,7 are implementation dependent */
7175 goto cp0_unimplemented
;
7178 case CP0_REGISTER_12
:
7180 case CP0_REG12__STATUS
:
7181 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
7182 register_name
= "Status";
7184 case CP0_REG12__INTCTL
:
7185 check_insn(ctx
, ISA_MIPS32R2
);
7186 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
7187 register_name
= "IntCtl";
7189 case CP0_REG12__SRSCTL
:
7190 check_insn(ctx
, ISA_MIPS32R2
);
7191 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
7192 register_name
= "SRSCtl";
7194 case CP0_REG12__SRSMAP
:
7195 check_insn(ctx
, ISA_MIPS32R2
);
7196 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7197 register_name
= "SRSMap";
7200 goto cp0_unimplemented
;
7203 case CP0_REGISTER_13
:
7205 case CP0_REG13__CAUSE
:
7206 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
7207 register_name
= "Cause";
7210 goto cp0_unimplemented
;
7213 case CP0_REGISTER_14
:
7215 case CP0_REG14__EPC
:
7216 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7217 tcg_gen_ext32s_tl(arg
, arg
);
7218 register_name
= "EPC";
7221 goto cp0_unimplemented
;
7224 case CP0_REGISTER_15
:
7226 case CP0_REG15__PRID
:
7227 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
7228 register_name
= "PRid";
7230 case CP0_REG15__EBASE
:
7231 check_insn(ctx
, ISA_MIPS32R2
);
7232 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
7233 tcg_gen_ext32s_tl(arg
, arg
);
7234 register_name
= "EBase";
7236 case CP0_REG15__CMGCRBASE
:
7237 check_insn(ctx
, ISA_MIPS32R2
);
7238 CP0_CHECK(ctx
->cmgcr
);
7239 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
7240 tcg_gen_ext32s_tl(arg
, arg
);
7241 register_name
= "CMGCRBase";
7244 goto cp0_unimplemented
;
7247 case CP0_REGISTER_16
:
7249 case CP0_REG16__CONFIG
:
7250 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
7251 register_name
= "Config";
7253 case CP0_REG16__CONFIG1
:
7254 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
7255 register_name
= "Config1";
7257 case CP0_REG16__CONFIG2
:
7258 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
7259 register_name
= "Config2";
7261 case CP0_REG16__CONFIG3
:
7262 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
7263 register_name
= "Config3";
7265 case CP0_REG16__CONFIG4
:
7266 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
7267 register_name
= "Config4";
7269 case CP0_REG16__CONFIG5
:
7270 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
7271 register_name
= "Config5";
7273 /* 6,7 are implementation dependent */
7274 case CP0_REG16__CONFIG6
:
7275 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
7276 register_name
= "Config6";
7278 case CP0_REG16__CONFIG7
:
7279 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
7280 register_name
= "Config7";
7283 goto cp0_unimplemented
;
7286 case CP0_REGISTER_17
:
7288 case CP0_REG17__LLADDR
:
7289 gen_helper_mfc0_lladdr(arg
, cpu_env
);
7290 register_name
= "LLAddr";
7292 case CP0_REG17__MAAR
:
7293 CP0_CHECK(ctx
->mrp
);
7294 gen_helper_mfc0_maar(arg
, cpu_env
);
7295 register_name
= "MAAR";
7297 case CP0_REG17__MAARI
:
7298 CP0_CHECK(ctx
->mrp
);
7299 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
7300 register_name
= "MAARI";
7303 goto cp0_unimplemented
;
7306 case CP0_REGISTER_18
:
7308 case CP0_REG18__WATCHLO0
:
7309 case CP0_REG18__WATCHLO1
:
7310 case CP0_REG18__WATCHLO2
:
7311 case CP0_REG18__WATCHLO3
:
7312 case CP0_REG18__WATCHLO4
:
7313 case CP0_REG18__WATCHLO5
:
7314 case CP0_REG18__WATCHLO6
:
7315 case CP0_REG18__WATCHLO7
:
7316 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7317 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
7318 register_name
= "WatchLo";
7321 goto cp0_unimplemented
;
7324 case CP0_REGISTER_19
:
7326 case CP0_REG19__WATCHHI0
:
7327 case CP0_REG19__WATCHHI1
:
7328 case CP0_REG19__WATCHHI2
:
7329 case CP0_REG19__WATCHHI3
:
7330 case CP0_REG19__WATCHHI4
:
7331 case CP0_REG19__WATCHHI5
:
7332 case CP0_REG19__WATCHHI6
:
7333 case CP0_REG19__WATCHHI7
:
7334 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
7335 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
7336 register_name
= "WatchHi";
7339 goto cp0_unimplemented
;
7342 case CP0_REGISTER_20
:
7344 case CP0_REG20__XCONTEXT
:
7345 #if defined(TARGET_MIPS64)
7346 check_insn(ctx
, ISA_MIPS3
);
7347 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
7348 tcg_gen_ext32s_tl(arg
, arg
);
7349 register_name
= "XContext";
7353 goto cp0_unimplemented
;
7356 case CP0_REGISTER_21
:
7357 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7358 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7361 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
7362 register_name
= "Framemask";
7365 goto cp0_unimplemented
;
7368 case CP0_REGISTER_22
:
7369 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7370 register_name
= "'Diagnostic"; /* implementation dependent */
7372 case CP0_REGISTER_23
:
7374 case CP0_REG23__DEBUG
:
7375 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
7376 register_name
= "Debug";
7378 case CP0_REG23__TRACECONTROL
:
7379 /* PDtrace support */
7380 /* gen_helper_mfc0_tracecontrol(arg); */
7381 register_name
= "TraceControl";
7382 goto cp0_unimplemented
;
7383 case CP0_REG23__TRACECONTROL2
:
7384 /* PDtrace support */
7385 /* gen_helper_mfc0_tracecontrol2(arg); */
7386 register_name
= "TraceControl2";
7387 goto cp0_unimplemented
;
7388 case CP0_REG23__USERTRACEDATA1
:
7389 /* PDtrace support */
7390 /* gen_helper_mfc0_usertracedata1(arg);*/
7391 register_name
= "UserTraceData1";
7392 goto cp0_unimplemented
;
7393 case CP0_REG23__TRACEIBPC
:
7394 /* PDtrace support */
7395 /* gen_helper_mfc0_traceibpc(arg); */
7396 register_name
= "TraceIBPC";
7397 goto cp0_unimplemented
;
7398 case CP0_REG23__TRACEDBPC
:
7399 /* PDtrace support */
7400 /* gen_helper_mfc0_tracedbpc(arg); */
7401 register_name
= "TraceDBPC";
7402 goto cp0_unimplemented
;
7404 goto cp0_unimplemented
;
7407 case CP0_REGISTER_24
:
7409 case CP0_REG24__DEPC
:
7411 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7412 tcg_gen_ext32s_tl(arg
, arg
);
7413 register_name
= "DEPC";
7416 goto cp0_unimplemented
;
7419 case CP0_REGISTER_25
:
7421 case CP0_REG25__PERFCTL0
:
7422 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
7423 register_name
= "Performance0";
7425 case CP0_REG25__PERFCNT0
:
7426 /* gen_helper_mfc0_performance1(arg); */
7427 register_name
= "Performance1";
7428 goto cp0_unimplemented
;
7429 case CP0_REG25__PERFCTL1
:
7430 /* gen_helper_mfc0_performance2(arg); */
7431 register_name
= "Performance2";
7432 goto cp0_unimplemented
;
7433 case CP0_REG25__PERFCNT1
:
7434 /* gen_helper_mfc0_performance3(arg); */
7435 register_name
= "Performance3";
7436 goto cp0_unimplemented
;
7437 case CP0_REG25__PERFCTL2
:
7438 /* gen_helper_mfc0_performance4(arg); */
7439 register_name
= "Performance4";
7440 goto cp0_unimplemented
;
7441 case CP0_REG25__PERFCNT2
:
7442 /* gen_helper_mfc0_performance5(arg); */
7443 register_name
= "Performance5";
7444 goto cp0_unimplemented
;
7445 case CP0_REG25__PERFCTL3
:
7446 /* gen_helper_mfc0_performance6(arg); */
7447 register_name
= "Performance6";
7448 goto cp0_unimplemented
;
7449 case CP0_REG25__PERFCNT3
:
7450 /* gen_helper_mfc0_performance7(arg); */
7451 register_name
= "Performance7";
7452 goto cp0_unimplemented
;
7454 goto cp0_unimplemented
;
7457 case CP0_REGISTER_26
:
7459 case CP0_REG26__ERRCTL
:
7460 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
7461 register_name
= "ErrCtl";
7464 goto cp0_unimplemented
;
7467 case CP0_REGISTER_27
:
7469 case CP0_REG27__CACHERR
:
7470 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7471 register_name
= "CacheErr";
7474 goto cp0_unimplemented
;
7477 case CP0_REGISTER_28
:
7479 case CP0_REG28__TAGLO
:
7480 case CP0_REG28__TAGLO1
:
7481 case CP0_REG28__TAGLO2
:
7482 case CP0_REG28__TAGLO3
:
7484 TCGv_i64 tmp
= tcg_temp_new_i64();
7485 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
7486 gen_move_low32(arg
, tmp
);
7487 tcg_temp_free_i64(tmp
);
7489 register_name
= "TagLo";
7491 case CP0_REG28__DATALO
:
7492 case CP0_REG28__DATALO1
:
7493 case CP0_REG28__DATALO2
:
7494 case CP0_REG28__DATALO3
:
7495 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7496 register_name
= "DataLo";
7499 goto cp0_unimplemented
;
7502 case CP0_REGISTER_29
:
7504 case CP0_REG29__TAGHI
:
7505 case CP0_REG29__TAGHI1
:
7506 case CP0_REG29__TAGHI2
:
7507 case CP0_REG29__TAGHI3
:
7508 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7509 register_name
= "TagHi";
7511 case CP0_REG29__DATAHI
:
7512 case CP0_REG29__DATAHI1
:
7513 case CP0_REG29__DATAHI2
:
7514 case CP0_REG29__DATAHI3
:
7515 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7516 register_name
= "DataHi";
7519 goto cp0_unimplemented
;
7522 case CP0_REGISTER_30
:
7524 case CP0_REG30__ERROREPC
:
7525 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7526 tcg_gen_ext32s_tl(arg
, arg
);
7527 register_name
= "ErrorEPC";
7530 goto cp0_unimplemented
;
7533 case CP0_REGISTER_31
:
7535 case CP0_REG31__DESAVE
:
7537 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7538 register_name
= "DESAVE";
7540 case CP0_REG31__KSCRATCH1
:
7541 case CP0_REG31__KSCRATCH2
:
7542 case CP0_REG31__KSCRATCH3
:
7543 case CP0_REG31__KSCRATCH4
:
7544 case CP0_REG31__KSCRATCH5
:
7545 case CP0_REG31__KSCRATCH6
:
7546 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7547 tcg_gen_ld_tl(arg
, cpu_env
,
7548 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
7549 tcg_gen_ext32s_tl(arg
, arg
);
7550 register_name
= "KScratch";
7553 goto cp0_unimplemented
;
7557 goto cp0_unimplemented
;
7559 trace_mips_translate_c0("mfc0", register_name
, reg
, sel
);
7563 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n",
7564 register_name
, reg
, sel
);
7565 gen_mfc0_unimplemented(ctx
, arg
);
7568 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7570 const char *register_name
= "invalid";
7573 check_insn(ctx
, ISA_MIPS32
);
7576 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
7581 case CP0_REGISTER_00
:
7583 case CP0_REG00__INDEX
:
7584 gen_helper_mtc0_index(cpu_env
, arg
);
7585 register_name
= "Index";
7587 case CP0_REG00__MVPCONTROL
:
7588 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7589 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7590 register_name
= "MVPControl";
7592 case CP0_REG00__MVPCONF0
:
7593 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7595 register_name
= "MVPConf0";
7597 case CP0_REG00__MVPCONF1
:
7598 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7600 register_name
= "MVPConf1";
7602 case CP0_REG00__VPCONTROL
:
7605 register_name
= "VPControl";
7608 goto cp0_unimplemented
;
7611 case CP0_REGISTER_01
:
7613 case CP0_REG01__RANDOM
:
7615 register_name
= "Random";
7617 case CP0_REG01__VPECONTROL
:
7618 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7619 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7620 register_name
= "VPEControl";
7622 case CP0_REG01__VPECONF0
:
7623 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7624 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7625 register_name
= "VPEConf0";
7627 case CP0_REG01__VPECONF1
:
7628 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7629 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7630 register_name
= "VPEConf1";
7632 case CP0_REG01__YQMASK
:
7633 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7634 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7635 register_name
= "YQMask";
7637 case CP0_REG01__VPESCHEDULE
:
7638 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7639 tcg_gen_st_tl(arg
, cpu_env
,
7640 offsetof(CPUMIPSState
, CP0_VPESchedule
));
7641 register_name
= "VPESchedule";
7643 case CP0_REG01__VPESCHEFBACK
:
7644 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7645 tcg_gen_st_tl(arg
, cpu_env
,
7646 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7647 register_name
= "VPEScheFBack";
7649 case CP0_REG01__VPEOPT
:
7650 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7651 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7652 register_name
= "VPEOpt";
7655 goto cp0_unimplemented
;
7658 case CP0_REGISTER_02
:
7660 case CP0_REG02__ENTRYLO0
:
7661 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
7662 register_name
= "EntryLo0";
7664 case CP0_REG02__TCSTATUS
:
7665 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7666 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7667 register_name
= "TCStatus";
7669 case CP0_REG02__TCBIND
:
7670 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7671 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7672 register_name
= "TCBind";
7674 case CP0_REG02__TCRESTART
:
7675 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7676 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7677 register_name
= "TCRestart";
7679 case CP0_REG02__TCHALT
:
7680 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7681 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7682 register_name
= "TCHalt";
7684 case CP0_REG02__TCCONTEXT
:
7685 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7686 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7687 register_name
= "TCContext";
7689 case CP0_REG02__TCSCHEDULE
:
7690 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7691 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7692 register_name
= "TCSchedule";
7694 case CP0_REG02__TCSCHEFBACK
:
7695 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7696 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7697 register_name
= "TCScheFBack";
7700 goto cp0_unimplemented
;
7703 case CP0_REGISTER_03
:
7705 case CP0_REG03__ENTRYLO1
:
7706 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
7707 register_name
= "EntryLo1";
7709 case CP0_REG03__GLOBALNUM
:
7712 register_name
= "GlobalNumber";
7715 goto cp0_unimplemented
;
7718 case CP0_REGISTER_04
:
7720 case CP0_REG04__CONTEXT
:
7721 gen_helper_mtc0_context(cpu_env
, arg
);
7722 register_name
= "Context";
7724 case CP0_REG04__CONTEXTCONFIG
:
7726 /* gen_helper_mtc0_contextconfig(arg); */
7727 register_name
= "ContextConfig";
7728 goto cp0_unimplemented
;
7729 case CP0_REG04__USERLOCAL
:
7730 CP0_CHECK(ctx
->ulri
);
7731 tcg_gen_st_tl(arg
, cpu_env
,
7732 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7733 register_name
= "UserLocal";
7736 goto cp0_unimplemented
;
7739 case CP0_REGISTER_05
:
7741 case CP0_REG05__PAGEMASK
:
7742 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7743 register_name
= "PageMask";
7745 case CP0_REG05__PAGEGRAIN
:
7746 check_insn(ctx
, ISA_MIPS32R2
);
7747 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7748 register_name
= "PageGrain";
7749 ctx
->base
.is_jmp
= DISAS_STOP
;
7751 case CP0_REG05__SEGCTL0
:
7753 gen_helper_mtc0_segctl0(cpu_env
, arg
);
7754 register_name
= "SegCtl0";
7756 case CP0_REG05__SEGCTL1
:
7758 gen_helper_mtc0_segctl1(cpu_env
, arg
);
7759 register_name
= "SegCtl1";
7761 case CP0_REG05__SEGCTL2
:
7763 gen_helper_mtc0_segctl2(cpu_env
, arg
);
7764 register_name
= "SegCtl2";
7766 case CP0_REG05__PWBASE
:
7768 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_PWBase
));
7769 register_name
= "PWBase";
7771 case CP0_REG05__PWFIELD
:
7773 gen_helper_mtc0_pwfield(cpu_env
, arg
);
7774 register_name
= "PWField";
7776 case CP0_REG05__PWSIZE
:
7778 gen_helper_mtc0_pwsize(cpu_env
, arg
);
7779 register_name
= "PWSize";
7782 goto cp0_unimplemented
;
7785 case CP0_REGISTER_06
:
7787 case CP0_REG06__WIRED
:
7788 gen_helper_mtc0_wired(cpu_env
, arg
);
7789 register_name
= "Wired";
7791 case CP0_REG06__SRSCONF0
:
7792 check_insn(ctx
, ISA_MIPS32R2
);
7793 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7794 register_name
= "SRSConf0";
7796 case CP0_REG06__SRSCONF1
:
7797 check_insn(ctx
, ISA_MIPS32R2
);
7798 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7799 register_name
= "SRSConf1";
7801 case CP0_REG06__SRSCONF2
:
7802 check_insn(ctx
, ISA_MIPS32R2
);
7803 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7804 register_name
= "SRSConf2";
7806 case CP0_REG06__SRSCONF3
:
7807 check_insn(ctx
, ISA_MIPS32R2
);
7808 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7809 register_name
= "SRSConf3";
7811 case CP0_REG06__SRSCONF4
:
7812 check_insn(ctx
, ISA_MIPS32R2
);
7813 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7814 register_name
= "SRSConf4";
7816 case CP0_REG06__PWCTL
:
7818 gen_helper_mtc0_pwctl(cpu_env
, arg
);
7819 register_name
= "PWCtl";
7822 goto cp0_unimplemented
;
7825 case CP0_REGISTER_07
:
7827 case CP0_REG07__HWRENA
:
7828 check_insn(ctx
, ISA_MIPS32R2
);
7829 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7830 ctx
->base
.is_jmp
= DISAS_STOP
;
7831 register_name
= "HWREna";
7834 goto cp0_unimplemented
;
7837 case CP0_REGISTER_08
:
7839 case CP0_REG08__BADVADDR
:
7841 register_name
= "BadVAddr";
7843 case CP0_REG08__BADINSTR
:
7845 register_name
= "BadInstr";
7847 case CP0_REG08__BADINSTRP
:
7849 register_name
= "BadInstrP";
7851 case CP0_REG08__BADINSTRX
:
7853 register_name
= "BadInstrX";
7856 goto cp0_unimplemented
;
7859 case CP0_REGISTER_09
:
7861 case CP0_REG09__COUNT
:
7862 gen_helper_mtc0_count(cpu_env
, arg
);
7863 register_name
= "Count";
7865 case CP0_REG09__SAARI
:
7866 CP0_CHECK(ctx
->saar
);
7867 gen_helper_mtc0_saari(cpu_env
, arg
);
7868 register_name
= "SAARI";
7870 case CP0_REG09__SAAR
:
7871 CP0_CHECK(ctx
->saar
);
7872 gen_helper_mtc0_saar(cpu_env
, arg
);
7873 register_name
= "SAAR";
7876 goto cp0_unimplemented
;
7879 case CP0_REGISTER_10
:
7881 case CP0_REG10__ENTRYHI
:
7882 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7883 register_name
= "EntryHi";
7886 goto cp0_unimplemented
;
7889 case CP0_REGISTER_11
:
7891 case CP0_REG11__COMPARE
:
7892 gen_helper_mtc0_compare(cpu_env
, arg
);
7893 register_name
= "Compare";
7895 /* 6,7 are implementation dependent */
7897 goto cp0_unimplemented
;
7900 case CP0_REGISTER_12
:
7902 case CP0_REG12__STATUS
:
7903 save_cpu_state(ctx
, 1);
7904 gen_helper_mtc0_status(cpu_env
, arg
);
7905 /* DISAS_STOP isn't good enough here, hflags may have changed. */
7906 gen_save_pc(ctx
->base
.pc_next
+ 4);
7907 ctx
->base
.is_jmp
= DISAS_EXIT
;
7908 register_name
= "Status";
7910 case CP0_REG12__INTCTL
:
7911 check_insn(ctx
, ISA_MIPS32R2
);
7912 gen_helper_mtc0_intctl(cpu_env
, arg
);
7913 /* Stop translation as we may have switched the execution mode */
7914 ctx
->base
.is_jmp
= DISAS_STOP
;
7915 register_name
= "IntCtl";
7917 case CP0_REG12__SRSCTL
:
7918 check_insn(ctx
, ISA_MIPS32R2
);
7919 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7920 /* Stop translation as we may have switched the execution mode */
7921 ctx
->base
.is_jmp
= DISAS_STOP
;
7922 register_name
= "SRSCtl";
7924 case CP0_REG12__SRSMAP
:
7925 check_insn(ctx
, ISA_MIPS32R2
);
7926 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7927 /* Stop translation as we may have switched the execution mode */
7928 ctx
->base
.is_jmp
= DISAS_STOP
;
7929 register_name
= "SRSMap";
7932 goto cp0_unimplemented
;
7935 case CP0_REGISTER_13
:
7937 case CP0_REG13__CAUSE
:
7938 save_cpu_state(ctx
, 1);
7939 gen_helper_mtc0_cause(cpu_env
, arg
);
7941 * Stop translation as we may have triggered an interrupt.
7942 * DISAS_STOP isn't sufficient, we need to ensure we break out of
7943 * translated code to check for pending interrupts.
7945 gen_save_pc(ctx
->base
.pc_next
+ 4);
7946 ctx
->base
.is_jmp
= DISAS_EXIT
;
7947 register_name
= "Cause";
7950 goto cp0_unimplemented
;
7953 case CP0_REGISTER_14
:
7955 case CP0_REG14__EPC
:
7956 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7957 register_name
= "EPC";
7960 goto cp0_unimplemented
;
7963 case CP0_REGISTER_15
:
7965 case CP0_REG15__PRID
:
7967 register_name
= "PRid";
7969 case CP0_REG15__EBASE
:
7970 check_insn(ctx
, ISA_MIPS32R2
);
7971 gen_helper_mtc0_ebase(cpu_env
, arg
);
7972 register_name
= "EBase";
7975 goto cp0_unimplemented
;
7978 case CP0_REGISTER_16
:
7980 case CP0_REG16__CONFIG
:
7981 gen_helper_mtc0_config0(cpu_env
, arg
);
7982 register_name
= "Config";
7983 /* Stop translation as we may have switched the execution mode */
7984 ctx
->base
.is_jmp
= DISAS_STOP
;
7986 case CP0_REG16__CONFIG1
:
7987 /* ignored, read only */
7988 register_name
= "Config1";
7990 case CP0_REG16__CONFIG2
:
7991 gen_helper_mtc0_config2(cpu_env
, arg
);
7992 register_name
= "Config2";
7993 /* Stop translation as we may have switched the execution mode */
7994 ctx
->base
.is_jmp
= DISAS_STOP
;
7996 case CP0_REG16__CONFIG3
:
7997 gen_helper_mtc0_config3(cpu_env
, arg
);
7998 register_name
= "Config3";
7999 /* Stop translation as we may have switched the execution mode */
8000 ctx
->base
.is_jmp
= DISAS_STOP
;
8002 case CP0_REG16__CONFIG4
:
8003 gen_helper_mtc0_config4(cpu_env
, arg
);
8004 register_name
= "Config4";
8005 ctx
->base
.is_jmp
= DISAS_STOP
;
8007 case CP0_REG16__CONFIG5
:
8008 gen_helper_mtc0_config5(cpu_env
, arg
);
8009 register_name
= "Config5";
8010 /* Stop translation as we may have switched the execution mode */
8011 ctx
->base
.is_jmp
= DISAS_STOP
;
8013 /* 6,7 are implementation dependent */
8014 case CP0_REG16__CONFIG6
:
8016 register_name
= "Config6";
8018 case CP0_REG16__CONFIG7
:
8020 register_name
= "Config7";
8023 register_name
= "Invalid config selector";
8024 goto cp0_unimplemented
;
8027 case CP0_REGISTER_17
:
8029 case CP0_REG17__LLADDR
:
8030 gen_helper_mtc0_lladdr(cpu_env
, arg
);
8031 register_name
= "LLAddr";
8033 case CP0_REG17__MAAR
:
8034 CP0_CHECK(ctx
->mrp
);
8035 gen_helper_mtc0_maar(cpu_env
, arg
);
8036 register_name
= "MAAR";
8038 case CP0_REG17__MAARI
:
8039 CP0_CHECK(ctx
->mrp
);
8040 gen_helper_mtc0_maari(cpu_env
, arg
);
8041 register_name
= "MAARI";
8044 goto cp0_unimplemented
;
8047 case CP0_REGISTER_18
:
8049 case CP0_REG18__WATCHLO0
:
8050 case CP0_REG18__WATCHLO1
:
8051 case CP0_REG18__WATCHLO2
:
8052 case CP0_REG18__WATCHLO3
:
8053 case CP0_REG18__WATCHLO4
:
8054 case CP0_REG18__WATCHLO5
:
8055 case CP0_REG18__WATCHLO6
:
8056 case CP0_REG18__WATCHLO7
:
8057 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8058 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
8059 register_name
= "WatchLo";
8062 goto cp0_unimplemented
;
8065 case CP0_REGISTER_19
:
8067 case CP0_REG19__WATCHHI0
:
8068 case CP0_REG19__WATCHHI1
:
8069 case CP0_REG19__WATCHHI2
:
8070 case CP0_REG19__WATCHHI3
:
8071 case CP0_REG19__WATCHHI4
:
8072 case CP0_REG19__WATCHHI5
:
8073 case CP0_REG19__WATCHHI6
:
8074 case CP0_REG19__WATCHHI7
:
8075 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8076 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
8077 register_name
= "WatchHi";
8080 goto cp0_unimplemented
;
8083 case CP0_REGISTER_20
:
8085 case CP0_REG20__XCONTEXT
:
8086 #if defined(TARGET_MIPS64)
8087 check_insn(ctx
, ISA_MIPS3
);
8088 gen_helper_mtc0_xcontext(cpu_env
, arg
);
8089 register_name
= "XContext";
8093 goto cp0_unimplemented
;
8096 case CP0_REGISTER_21
:
8097 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8098 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8101 gen_helper_mtc0_framemask(cpu_env
, arg
);
8102 register_name
= "Framemask";
8105 goto cp0_unimplemented
;
8108 case CP0_REGISTER_22
:
8110 register_name
= "Diagnostic"; /* implementation dependent */
8112 case CP0_REGISTER_23
:
8114 case CP0_REG23__DEBUG
:
8115 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
8116 /* DISAS_STOP isn't good enough here, hflags may have changed. */
8117 gen_save_pc(ctx
->base
.pc_next
+ 4);
8118 ctx
->base
.is_jmp
= DISAS_EXIT
;
8119 register_name
= "Debug";
8121 case CP0_REG23__TRACECONTROL
:
8122 /* PDtrace support */
8123 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
8124 register_name
= "TraceControl";
8125 /* Stop translation as we may have switched the execution mode */
8126 ctx
->base
.is_jmp
= DISAS_STOP
;
8127 goto cp0_unimplemented
;
8128 case CP0_REG23__TRACECONTROL2
:
8129 /* PDtrace support */
8130 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8131 register_name
= "TraceControl2";
8132 /* Stop translation as we may have switched the execution mode */
8133 ctx
->base
.is_jmp
= DISAS_STOP
;
8134 goto cp0_unimplemented
;
8135 case CP0_REG23__USERTRACEDATA1
:
8136 /* Stop translation as we may have switched the execution mode */
8137 ctx
->base
.is_jmp
= DISAS_STOP
;
8138 /* PDtrace support */
8139 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8140 register_name
= "UserTraceData";
8141 /* Stop translation as we may have switched the execution mode */
8142 ctx
->base
.is_jmp
= DISAS_STOP
;
8143 goto cp0_unimplemented
;
8144 case CP0_REG23__TRACEIBPC
:
8145 /* PDtrace support */
8146 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
8147 /* Stop translation as we may have switched the execution mode */
8148 ctx
->base
.is_jmp
= DISAS_STOP
;
8149 register_name
= "TraceIBPC";
8150 goto cp0_unimplemented
;
8151 case CP0_REG23__TRACEDBPC
:
8152 /* PDtrace support */
8153 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
8154 /* Stop translation as we may have switched the execution mode */
8155 ctx
->base
.is_jmp
= DISAS_STOP
;
8156 register_name
= "TraceDBPC";
8157 goto cp0_unimplemented
;
8159 goto cp0_unimplemented
;
8162 case CP0_REGISTER_24
:
8164 case CP0_REG24__DEPC
:
8166 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8167 register_name
= "DEPC";
8170 goto cp0_unimplemented
;
8173 case CP0_REGISTER_25
:
8175 case CP0_REG25__PERFCTL0
:
8176 gen_helper_mtc0_performance0(cpu_env
, arg
);
8177 register_name
= "Performance0";
8179 case CP0_REG25__PERFCNT0
:
8180 /* gen_helper_mtc0_performance1(arg); */
8181 register_name
= "Performance1";
8182 goto cp0_unimplemented
;
8183 case CP0_REG25__PERFCTL1
:
8184 /* gen_helper_mtc0_performance2(arg); */
8185 register_name
= "Performance2";
8186 goto cp0_unimplemented
;
8187 case CP0_REG25__PERFCNT1
:
8188 /* gen_helper_mtc0_performance3(arg); */
8189 register_name
= "Performance3";
8190 goto cp0_unimplemented
;
8191 case CP0_REG25__PERFCTL2
:
8192 /* gen_helper_mtc0_performance4(arg); */
8193 register_name
= "Performance4";
8194 goto cp0_unimplemented
;
8195 case CP0_REG25__PERFCNT2
:
8196 /* gen_helper_mtc0_performance5(arg); */
8197 register_name
= "Performance5";
8198 goto cp0_unimplemented
;
8199 case CP0_REG25__PERFCTL3
:
8200 /* gen_helper_mtc0_performance6(arg); */
8201 register_name
= "Performance6";
8202 goto cp0_unimplemented
;
8203 case CP0_REG25__PERFCNT3
:
8204 /* gen_helper_mtc0_performance7(arg); */
8205 register_name
= "Performance7";
8206 goto cp0_unimplemented
;
8208 goto cp0_unimplemented
;
8211 case CP0_REGISTER_26
:
8213 case CP0_REG26__ERRCTL
:
8214 gen_helper_mtc0_errctl(cpu_env
, arg
);
8215 ctx
->base
.is_jmp
= DISAS_STOP
;
8216 register_name
= "ErrCtl";
8219 goto cp0_unimplemented
;
8222 case CP0_REGISTER_27
:
8224 case CP0_REG27__CACHERR
:
8226 register_name
= "CacheErr";
8229 goto cp0_unimplemented
;
8232 case CP0_REGISTER_28
:
8234 case CP0_REG28__TAGLO
:
8235 case CP0_REG28__TAGLO1
:
8236 case CP0_REG28__TAGLO2
:
8237 case CP0_REG28__TAGLO3
:
8238 gen_helper_mtc0_taglo(cpu_env
, arg
);
8239 register_name
= "TagLo";
8241 case CP0_REG28__DATALO
:
8242 case CP0_REG28__DATALO1
:
8243 case CP0_REG28__DATALO2
:
8244 case CP0_REG28__DATALO3
:
8245 gen_helper_mtc0_datalo(cpu_env
, arg
);
8246 register_name
= "DataLo";
8249 goto cp0_unimplemented
;
8252 case CP0_REGISTER_29
:
8254 case CP0_REG29__TAGHI
:
8255 case CP0_REG29__TAGHI1
:
8256 case CP0_REG29__TAGHI2
:
8257 case CP0_REG29__TAGHI3
:
8258 gen_helper_mtc0_taghi(cpu_env
, arg
);
8259 register_name
= "TagHi";
8261 case CP0_REG29__DATAHI
:
8262 case CP0_REG29__DATAHI1
:
8263 case CP0_REG29__DATAHI2
:
8264 case CP0_REG29__DATAHI3
:
8265 gen_helper_mtc0_datahi(cpu_env
, arg
);
8266 register_name
= "DataHi";
8269 register_name
= "invalid sel";
8270 goto cp0_unimplemented
;
8273 case CP0_REGISTER_30
:
8275 case CP0_REG30__ERROREPC
:
8276 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
8277 register_name
= "ErrorEPC";
8280 goto cp0_unimplemented
;
8283 case CP0_REGISTER_31
:
8285 case CP0_REG31__DESAVE
:
8287 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
8288 register_name
= "DESAVE";
8290 case CP0_REG31__KSCRATCH1
:
8291 case CP0_REG31__KSCRATCH2
:
8292 case CP0_REG31__KSCRATCH3
:
8293 case CP0_REG31__KSCRATCH4
:
8294 case CP0_REG31__KSCRATCH5
:
8295 case CP0_REG31__KSCRATCH6
:
8296 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
8297 tcg_gen_st_tl(arg
, cpu_env
,
8298 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
8299 register_name
= "KScratch";
8302 goto cp0_unimplemented
;
8306 goto cp0_unimplemented
;
8308 trace_mips_translate_c0("mtc0", register_name
, reg
, sel
);
8310 /* For simplicity assume that all writes can cause interrupts. */
8311 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8313 * DISAS_STOP isn't sufficient, we need to ensure we break out of
8314 * translated code to check for pending interrupts.
8316 gen_save_pc(ctx
->base
.pc_next
+ 4);
8317 ctx
->base
.is_jmp
= DISAS_EXIT
;
8322 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n",
8323 register_name
, reg
, sel
);
8326 #if defined(TARGET_MIPS64)
8327 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
8329 const char *register_name
= "invalid";
8332 check_insn(ctx
, ISA_MIPS64
);
8336 case CP0_REGISTER_00
:
8338 case CP0_REG00__INDEX
:
8339 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
8340 register_name
= "Index";
8342 case CP0_REG00__MVPCONTROL
:
8343 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8344 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
8345 register_name
= "MVPControl";
8347 case CP0_REG00__MVPCONF0
:
8348 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8349 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
8350 register_name
= "MVPConf0";
8352 case CP0_REG00__MVPCONF1
:
8353 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8354 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
8355 register_name
= "MVPConf1";
8357 case CP0_REG00__VPCONTROL
:
8359 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
8360 register_name
= "VPControl";
8363 goto cp0_unimplemented
;
8366 case CP0_REGISTER_01
:
8368 case CP0_REG01__RANDOM
:
8369 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8370 gen_helper_mfc0_random(arg
, cpu_env
);
8371 register_name
= "Random";
8373 case CP0_REG01__VPECONTROL
:
8374 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8375 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
8376 register_name
= "VPEControl";
8378 case CP0_REG01__VPECONF0
:
8379 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8380 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
8381 register_name
= "VPEConf0";
8383 case CP0_REG01__VPECONF1
:
8384 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8385 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
8386 register_name
= "VPEConf1";
8388 case CP0_REG01__YQMASK
:
8389 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8390 tcg_gen_ld_tl(arg
, cpu_env
,
8391 offsetof(CPUMIPSState
, CP0_YQMask
));
8392 register_name
= "YQMask";
8394 case CP0_REG01__VPESCHEDULE
:
8395 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8396 tcg_gen_ld_tl(arg
, cpu_env
,
8397 offsetof(CPUMIPSState
, CP0_VPESchedule
));
8398 register_name
= "VPESchedule";
8400 case CP0_REG01__VPESCHEFBACK
:
8401 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8402 tcg_gen_ld_tl(arg
, cpu_env
,
8403 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
8404 register_name
= "VPEScheFBack";
8406 case CP0_REG01__VPEOPT
:
8407 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8408 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
8409 register_name
= "VPEOpt";
8412 goto cp0_unimplemented
;
8415 case CP0_REGISTER_02
:
8417 case CP0_REG02__ENTRYLO0
:
8418 tcg_gen_ld_tl(arg
, cpu_env
,
8419 offsetof(CPUMIPSState
, CP0_EntryLo0
));
8420 register_name
= "EntryLo0";
8422 case CP0_REG02__TCSTATUS
:
8423 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8424 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
8425 register_name
= "TCStatus";
8427 case CP0_REG02__TCBIND
:
8428 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8429 gen_helper_mfc0_tcbind(arg
, cpu_env
);
8430 register_name
= "TCBind";
8432 case CP0_REG02__TCRESTART
:
8433 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8434 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
8435 register_name
= "TCRestart";
8437 case CP0_REG02__TCHALT
:
8438 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8439 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
8440 register_name
= "TCHalt";
8442 case CP0_REG02__TCCONTEXT
:
8443 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8444 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
8445 register_name
= "TCContext";
8447 case CP0_REG02__TCSCHEDULE
:
8448 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8449 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
8450 register_name
= "TCSchedule";
8452 case CP0_REG02__TCSCHEFBACK
:
8453 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
8454 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
8455 register_name
= "TCScheFBack";
8458 goto cp0_unimplemented
;
8461 case CP0_REGISTER_03
:
8463 case CP0_REG03__ENTRYLO1
:
8464 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
8465 register_name
= "EntryLo1";
8467 case CP0_REG03__GLOBALNUM
:
8469 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
8470 register_name
= "GlobalNumber";
8473 goto cp0_unimplemented
;
8476 case CP0_REGISTER_04
:
8478 case CP0_REG04__CONTEXT
:
8479 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
8480 register_name
= "Context";
8482 case CP0_REG04__CONTEXTCONFIG
:
8484 /* gen_helper_dmfc0_contextconfig(arg); */
8485 register_name
= "ContextConfig";
8486 goto cp0_unimplemented
;
8487 case CP0_REG04__USERLOCAL
:
8488 CP0_CHECK(ctx
->ulri
);
8489 tcg_gen_ld_tl(arg
, cpu_env
,
8490 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
8491 register_name
= "UserLocal";
8494 goto cp0_unimplemented
;
8497 case CP0_REGISTER_05
:
8499 case CP0_REG05__PAGEMASK
:
8500 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
8501 register_name
= "PageMask";
8503 case CP0_REG05__PAGEGRAIN
:
8504 check_insn(ctx
, ISA_MIPS32R2
);
8505 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
8506 register_name
= "PageGrain";
8508 case CP0_REG05__SEGCTL0
:
8510 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl0
));
8511 register_name
= "SegCtl0";
8513 case CP0_REG05__SEGCTL1
:
8515 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl1
));
8516 register_name
= "SegCtl1";
8518 case CP0_REG05__SEGCTL2
:
8520 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_SegCtl2
));
8521 register_name
= "SegCtl2";
8523 case CP0_REG05__PWBASE
:
8525 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
8526 register_name
= "PWBase";
8528 case CP0_REG05__PWFIELD
:
8530 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWField
));
8531 register_name
= "PWField";
8533 case CP0_REG05__PWSIZE
:
8535 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWSize
));
8536 register_name
= "PWSize";
8539 goto cp0_unimplemented
;
8542 case CP0_REGISTER_06
:
8544 case CP0_REG06__WIRED
:
8545 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
8546 register_name
= "Wired";
8548 case CP0_REG06__SRSCONF0
:
8549 check_insn(ctx
, ISA_MIPS32R2
);
8550 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
8551 register_name
= "SRSConf0";
8553 case CP0_REG06__SRSCONF1
:
8554 check_insn(ctx
, ISA_MIPS32R2
);
8555 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
8556 register_name
= "SRSConf1";
8558 case CP0_REG06__SRSCONF2
:
8559 check_insn(ctx
, ISA_MIPS32R2
);
8560 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
8561 register_name
= "SRSConf2";
8563 case CP0_REG06__SRSCONF3
:
8564 check_insn(ctx
, ISA_MIPS32R2
);
8565 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
8566 register_name
= "SRSConf3";
8568 case CP0_REG06__SRSCONF4
:
8569 check_insn(ctx
, ISA_MIPS32R2
);
8570 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
8571 register_name
= "SRSConf4";
8573 case CP0_REG06__PWCTL
:
8575 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PWCtl
));
8576 register_name
= "PWCtl";
8579 goto cp0_unimplemented
;
8582 case CP0_REGISTER_07
:
8584 case CP0_REG07__HWRENA
:
8585 check_insn(ctx
, ISA_MIPS32R2
);
8586 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
8587 register_name
= "HWREna";
8590 goto cp0_unimplemented
;
8593 case CP0_REGISTER_08
:
8595 case CP0_REG08__BADVADDR
:
8596 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
8597 register_name
= "BadVAddr";
8599 case CP0_REG08__BADINSTR
:
8601 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
8602 register_name
= "BadInstr";
8604 case CP0_REG08__BADINSTRP
:
8606 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
8607 register_name
= "BadInstrP";
8609 case CP0_REG08__BADINSTRX
:
8611 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrX
));
8612 tcg_gen_andi_tl(arg
, arg
, ~0xffff);
8613 register_name
= "BadInstrX";
8616 goto cp0_unimplemented
;
8619 case CP0_REGISTER_09
:
8621 case CP0_REG09__COUNT
:
8622 /* Mark as an IO operation because we read the time. */
8623 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
8626 gen_helper_mfc0_count(arg
, cpu_env
);
8628 * Break the TB to be able to take timer interrupts immediately
8629 * after reading count. DISAS_STOP isn't sufficient, we need to
8630 * ensure we break completely out of translated code.
8632 gen_save_pc(ctx
->base
.pc_next
+ 4);
8633 ctx
->base
.is_jmp
= DISAS_EXIT
;
8634 register_name
= "Count";
8636 case CP0_REG09__SAARI
:
8637 CP0_CHECK(ctx
->saar
);
8638 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SAARI
));
8639 register_name
= "SAARI";
8641 case CP0_REG09__SAAR
:
8642 CP0_CHECK(ctx
->saar
);
8643 gen_helper_dmfc0_saar(arg
, cpu_env
);
8644 register_name
= "SAAR";
8647 goto cp0_unimplemented
;
8650 case CP0_REGISTER_10
:
8652 case CP0_REG10__ENTRYHI
:
8653 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
8654 register_name
= "EntryHi";
8657 goto cp0_unimplemented
;
8660 case CP0_REGISTER_11
:
8662 case CP0_REG11__COMPARE
:
8663 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
8664 register_name
= "Compare";
8666 /* 6,7 are implementation dependent */
8668 goto cp0_unimplemented
;
8671 case CP0_REGISTER_12
:
8673 case CP0_REG12__STATUS
:
8674 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
8675 register_name
= "Status";
8677 case CP0_REG12__INTCTL
:
8678 check_insn(ctx
, ISA_MIPS32R2
);
8679 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
8680 register_name
= "IntCtl";
8682 case CP0_REG12__SRSCTL
:
8683 check_insn(ctx
, ISA_MIPS32R2
);
8684 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
8685 register_name
= "SRSCtl";
8687 case CP0_REG12__SRSMAP
:
8688 check_insn(ctx
, ISA_MIPS32R2
);
8689 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
8690 register_name
= "SRSMap";
8693 goto cp0_unimplemented
;
8696 case CP0_REGISTER_13
:
8698 case CP0_REG13__CAUSE
:
8699 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
8700 register_name
= "Cause";
8703 goto cp0_unimplemented
;
8706 case CP0_REGISTER_14
:
8708 case CP0_REG14__EPC
:
8709 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
8710 register_name
= "EPC";
8713 goto cp0_unimplemented
;
8716 case CP0_REGISTER_15
:
8718 case CP0_REG15__PRID
:
8719 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
8720 register_name
= "PRid";
8722 case CP0_REG15__EBASE
:
8723 check_insn(ctx
, ISA_MIPS32R2
);
8724 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EBase
));
8725 register_name
= "EBase";
8727 case CP0_REG15__CMGCRBASE
:
8728 check_insn(ctx
, ISA_MIPS32R2
);
8729 CP0_CHECK(ctx
->cmgcr
);
8730 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
8731 register_name
= "CMGCRBase";
8734 goto cp0_unimplemented
;
8737 case CP0_REGISTER_16
:
8739 case CP0_REG16__CONFIG
:
8740 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
8741 register_name
= "Config";
8743 case CP0_REG16__CONFIG1
:
8744 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
8745 register_name
= "Config1";
8747 case CP0_REG16__CONFIG2
:
8748 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
8749 register_name
= "Config2";
8751 case CP0_REG16__CONFIG3
:
8752 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
8753 register_name
= "Config3";
8755 case CP0_REG16__CONFIG4
:
8756 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
8757 register_name
= "Config4";
8759 case CP0_REG16__CONFIG5
:
8760 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
8761 register_name
= "Config5";
8763 /* 6,7 are implementation dependent */
8764 case CP0_REG16__CONFIG6
:
8765 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
8766 register_name
= "Config6";
8768 case CP0_REG16__CONFIG7
:
8769 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
8770 register_name
= "Config7";
8773 goto cp0_unimplemented
;
8776 case CP0_REGISTER_17
:
8778 case CP0_REG17__LLADDR
:
8779 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
8780 register_name
= "LLAddr";
8782 case CP0_REG17__MAAR
:
8783 CP0_CHECK(ctx
->mrp
);
8784 gen_helper_dmfc0_maar(arg
, cpu_env
);
8785 register_name
= "MAAR";
8787 case CP0_REG17__MAARI
:
8788 CP0_CHECK(ctx
->mrp
);
8789 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
8790 register_name
= "MAARI";
8793 goto cp0_unimplemented
;
8796 case CP0_REGISTER_18
:
8798 case CP0_REG18__WATCHLO0
:
8799 case CP0_REG18__WATCHLO1
:
8800 case CP0_REG18__WATCHLO2
:
8801 case CP0_REG18__WATCHLO3
:
8802 case CP0_REG18__WATCHLO4
:
8803 case CP0_REG18__WATCHLO5
:
8804 case CP0_REG18__WATCHLO6
:
8805 case CP0_REG18__WATCHLO7
:
8806 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8807 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
8808 register_name
= "WatchLo";
8811 goto cp0_unimplemented
;
8814 case CP0_REGISTER_19
:
8816 case CP0_REG19__WATCHHI0
:
8817 case CP0_REG19__WATCHHI1
:
8818 case CP0_REG19__WATCHHI2
:
8819 case CP0_REG19__WATCHHI3
:
8820 case CP0_REG19__WATCHHI4
:
8821 case CP0_REG19__WATCHHI5
:
8822 case CP0_REG19__WATCHHI6
:
8823 case CP0_REG19__WATCHHI7
:
8824 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
8825 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
8826 register_name
= "WatchHi";
8829 goto cp0_unimplemented
;
8832 case CP0_REGISTER_20
:
8834 case CP0_REG20__XCONTEXT
:
8835 check_insn(ctx
, ISA_MIPS3
);
8836 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
8837 register_name
= "XContext";
8840 goto cp0_unimplemented
;
8843 case CP0_REGISTER_21
:
8844 /* Officially reserved, but sel 0 is used for R1x000 framemask */
8845 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
8848 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
8849 register_name
= "Framemask";
8852 goto cp0_unimplemented
;
8855 case CP0_REGISTER_22
:
8856 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8857 register_name
= "'Diagnostic"; /* implementation dependent */
8859 case CP0_REGISTER_23
:
8861 case CP0_REG23__DEBUG
:
8862 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
8863 register_name
= "Debug";
8865 case CP0_REG23__TRACECONTROL
:
8866 /* PDtrace support */
8867 /* gen_helper_dmfc0_tracecontrol(arg, cpu_env); */
8868 register_name
= "TraceControl";
8869 goto cp0_unimplemented
;
8870 case CP0_REG23__TRACECONTROL2
:
8871 /* PDtrace support */
8872 /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8873 register_name
= "TraceControl2";
8874 goto cp0_unimplemented
;
8875 case CP0_REG23__USERTRACEDATA1
:
8876 /* PDtrace support */
8877 /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8878 register_name
= "UserTraceData1";
8879 goto cp0_unimplemented
;
8880 case CP0_REG23__TRACEIBPC
:
8881 /* PDtrace support */
8882 /* gen_helper_dmfc0_traceibpc(arg, cpu_env); */
8883 register_name
= "TraceIBPC";
8884 goto cp0_unimplemented
;
8885 case CP0_REG23__TRACEDBPC
:
8886 /* PDtrace support */
8887 /* gen_helper_dmfc0_tracedbpc(arg, cpu_env); */
8888 register_name
= "TraceDBPC";
8889 goto cp0_unimplemented
;
8891 goto cp0_unimplemented
;
8894 case CP0_REGISTER_24
:
8896 case CP0_REG24__DEPC
:
8898 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
8899 register_name
= "DEPC";
8902 goto cp0_unimplemented
;
8905 case CP0_REGISTER_25
:
8907 case CP0_REG25__PERFCTL0
:
8908 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
8909 register_name
= "Performance0";
8911 case CP0_REG25__PERFCNT0
:
8912 /* gen_helper_dmfc0_performance1(arg); */
8913 register_name
= "Performance1";
8914 goto cp0_unimplemented
;
8915 case CP0_REG25__PERFCTL1
:
8916 /* gen_helper_dmfc0_performance2(arg); */
8917 register_name
= "Performance2";
8918 goto cp0_unimplemented
;
8919 case CP0_REG25__PERFCNT1
:
8920 /* gen_helper_dmfc0_performance3(arg); */
8921 register_name
= "Performance3";
8922 goto cp0_unimplemented
;
8923 case CP0_REG25__PERFCTL2
:
8924 /* gen_helper_dmfc0_performance4(arg); */
8925 register_name
= "Performance4";
8926 goto cp0_unimplemented
;
8927 case CP0_REG25__PERFCNT2
:
8928 /* gen_helper_dmfc0_performance5(arg); */
8929 register_name
= "Performance5";
8930 goto cp0_unimplemented
;
8931 case CP0_REG25__PERFCTL3
:
8932 /* gen_helper_dmfc0_performance6(arg); */
8933 register_name
= "Performance6";
8934 goto cp0_unimplemented
;
8935 case CP0_REG25__PERFCNT3
:
8936 /* gen_helper_dmfc0_performance7(arg); */
8937 register_name
= "Performance7";
8938 goto cp0_unimplemented
;
8940 goto cp0_unimplemented
;
8943 case CP0_REGISTER_26
:
8945 case CP0_REG26__ERRCTL
:
8946 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
8947 register_name
= "ErrCtl";
8950 goto cp0_unimplemented
;
8953 case CP0_REGISTER_27
:
8956 case CP0_REG27__CACHERR
:
8957 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
8958 register_name
= "CacheErr";
8961 goto cp0_unimplemented
;
8964 case CP0_REGISTER_28
:
8966 case CP0_REG28__TAGLO
:
8967 case CP0_REG28__TAGLO1
:
8968 case CP0_REG28__TAGLO2
:
8969 case CP0_REG28__TAGLO3
:
8970 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
8971 register_name
= "TagLo";
8973 case CP0_REG28__DATALO
:
8974 case CP0_REG28__DATALO1
:
8975 case CP0_REG28__DATALO2
:
8976 case CP0_REG28__DATALO3
:
8977 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
8978 register_name
= "DataLo";
8981 goto cp0_unimplemented
;
8984 case CP0_REGISTER_29
:
8986 case CP0_REG29__TAGHI
:
8987 case CP0_REG29__TAGHI1
:
8988 case CP0_REG29__TAGHI2
:
8989 case CP0_REG29__TAGHI3
:
8990 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
8991 register_name
= "TagHi";
8993 case CP0_REG29__DATAHI
:
8994 case CP0_REG29__DATAHI1
:
8995 case CP0_REG29__DATAHI2
:
8996 case CP0_REG29__DATAHI3
:
8997 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
8998 register_name
= "DataHi";
9001 goto cp0_unimplemented
;
9004 case CP0_REGISTER_30
:
9006 case CP0_REG30__ERROREPC
:
9007 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9008 register_name
= "ErrorEPC";
9011 goto cp0_unimplemented
;
9014 case CP0_REGISTER_31
:
9016 case CP0_REG31__DESAVE
:
9018 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9019 register_name
= "DESAVE";
9021 case CP0_REG31__KSCRATCH1
:
9022 case CP0_REG31__KSCRATCH2
:
9023 case CP0_REG31__KSCRATCH3
:
9024 case CP0_REG31__KSCRATCH4
:
9025 case CP0_REG31__KSCRATCH5
:
9026 case CP0_REG31__KSCRATCH6
:
9027 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9028 tcg_gen_ld_tl(arg
, cpu_env
,
9029 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9030 register_name
= "KScratch";
9033 goto cp0_unimplemented
;
9037 goto cp0_unimplemented
;
9039 trace_mips_translate_c0("dmfc0", register_name
, reg
, sel
);
9043 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n",
9044 register_name
, reg
, sel
);
9045 gen_mfc0_unimplemented(ctx
, arg
);
9048 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
9050 const char *register_name
= "invalid";
9053 check_insn(ctx
, ISA_MIPS64
);
9056 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9061 case CP0_REGISTER_00
:
9063 case CP0_REG00__INDEX
:
9064 gen_helper_mtc0_index(cpu_env
, arg
);
9065 register_name
= "Index";
9067 case CP0_REG00__MVPCONTROL
:
9068 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9069 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
9070 register_name
= "MVPControl";
9072 case CP0_REG00__MVPCONF0
:
9073 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9075 register_name
= "MVPConf0";
9077 case CP0_REG00__MVPCONF1
:
9078 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9080 register_name
= "MVPConf1";
9082 case CP0_REG00__VPCONTROL
:
9085 register_name
= "VPControl";
9088 goto cp0_unimplemented
;
9091 case CP0_REGISTER_01
:
9093 case CP0_REG01__RANDOM
:
9095 register_name
= "Random";
9097 case CP0_REG01__VPECONTROL
:
9098 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9099 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
9100 register_name
= "VPEControl";
9102 case CP0_REG01__VPECONF0
:
9103 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9104 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
9105 register_name
= "VPEConf0";
9107 case CP0_REG01__VPECONF1
:
9108 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9109 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
9110 register_name
= "VPEConf1";
9112 case CP0_REG01__YQMASK
:
9113 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9114 gen_helper_mtc0_yqmask(cpu_env
, arg
);
9115 register_name
= "YQMask";
9117 case CP0_REG01__VPESCHEDULE
:
9118 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9119 tcg_gen_st_tl(arg
, cpu_env
,
9120 offsetof(CPUMIPSState
, CP0_VPESchedule
));
9121 register_name
= "VPESchedule";
9123 case CP0_REG01__VPESCHEFBACK
:
9124 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9125 tcg_gen_st_tl(arg
, cpu_env
,
9126 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
9127 register_name
= "VPEScheFBack";
9129 case CP0_REG01__VPEOPT
:
9130 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9131 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
9132 register_name
= "VPEOpt";
9135 goto cp0_unimplemented
;
9138 case CP0_REGISTER_02
:
9140 case CP0_REG02__ENTRYLO0
:
9141 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
9142 register_name
= "EntryLo0";
9144 case CP0_REG02__TCSTATUS
:
9145 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9146 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
9147 register_name
= "TCStatus";
9149 case CP0_REG02__TCBIND
:
9150 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9151 gen_helper_mtc0_tcbind(cpu_env
, arg
);
9152 register_name
= "TCBind";
9154 case CP0_REG02__TCRESTART
:
9155 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9156 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
9157 register_name
= "TCRestart";
9159 case CP0_REG02__TCHALT
:
9160 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9161 gen_helper_mtc0_tchalt(cpu_env
, arg
);
9162 register_name
= "TCHalt";
9164 case CP0_REG02__TCCONTEXT
:
9165 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9166 gen_helper_mtc0_tccontext(cpu_env
, arg
);
9167 register_name
= "TCContext";
9169 case CP0_REG02__TCSCHEDULE
:
9170 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9171 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
9172 register_name
= "TCSchedule";
9174 case CP0_REG02__TCSCHEFBACK
:
9175 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
9176 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
9177 register_name
= "TCScheFBack";
9180 goto cp0_unimplemented
;
9183 case CP0_REGISTER_03
:
9185 case CP0_REG03__ENTRYLO1
:
9186 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
9187 register_name
= "EntryLo1";
9189 case CP0_REG03__GLOBALNUM
:
9192 register_name
= "GlobalNumber";
9195 goto cp0_unimplemented
;
9198 case CP0_REGISTER_04
:
9200 case CP0_REG04__CONTEXT
:
9201 gen_helper_mtc0_context(cpu_env
, arg
);
9202 register_name
= "Context";
9204 case CP0_REG04__CONTEXTCONFIG
:
9206 /* gen_helper_dmtc0_contextconfig(arg); */
9207 register_name
= "ContextConfig";
9208 goto cp0_unimplemented
;
9209 case CP0_REG04__USERLOCAL
:
9210 CP0_CHECK(ctx
->ulri
);
9211 tcg_gen_st_tl(arg
, cpu_env
,
9212 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9213 register_name
= "UserLocal";
9216 goto cp0_unimplemented
;
9219 case CP0_REGISTER_05
:
9221 case CP0_REG05__PAGEMASK
:
9222 gen_helper_mtc0_pagemask(cpu_env
, arg
);
9223 register_name
= "PageMask";
9225 case CP0_REG05__PAGEGRAIN
:
9226 check_insn(ctx
, ISA_MIPS32R2
);
9227 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
9228 register_name
= "PageGrain";
9230 case CP0_REG05__SEGCTL0
:
9232 gen_helper_mtc0_segctl0(cpu_env
, arg
);
9233 register_name
= "SegCtl0";
9235 case CP0_REG05__SEGCTL1
:
9237 gen_helper_mtc0_segctl1(cpu_env
, arg
);
9238 register_name
= "SegCtl1";
9240 case CP0_REG05__SEGCTL2
:
9242 gen_helper_mtc0_segctl2(cpu_env
, arg
);
9243 register_name
= "SegCtl2";
9245 case CP0_REG05__PWBASE
:
9247 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_PWBase
));
9248 register_name
= "PWBase";
9250 case CP0_REG05__PWFIELD
:
9252 gen_helper_mtc0_pwfield(cpu_env
, arg
);
9253 register_name
= "PWField";
9255 case CP0_REG05__PWSIZE
:
9257 gen_helper_mtc0_pwsize(cpu_env
, arg
);
9258 register_name
= "PWSize";
9261 goto cp0_unimplemented
;
9264 case CP0_REGISTER_06
:
9266 case CP0_REG06__WIRED
:
9267 gen_helper_mtc0_wired(cpu_env
, arg
);
9268 register_name
= "Wired";
9270 case CP0_REG06__SRSCONF0
:
9271 check_insn(ctx
, ISA_MIPS32R2
);
9272 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
9273 register_name
= "SRSConf0";
9275 case CP0_REG06__SRSCONF1
:
9276 check_insn(ctx
, ISA_MIPS32R2
);
9277 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
9278 register_name
= "SRSConf1";
9280 case CP0_REG06__SRSCONF2
:
9281 check_insn(ctx
, ISA_MIPS32R2
);
9282 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
9283 register_name
= "SRSConf2";
9285 case CP0_REG06__SRSCONF3
:
9286 check_insn(ctx
, ISA_MIPS32R2
);
9287 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
9288 register_name
= "SRSConf3";
9290 case CP0_REG06__SRSCONF4
:
9291 check_insn(ctx
, ISA_MIPS32R2
);
9292 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
9293 register_name
= "SRSConf4";
9295 case CP0_REG06__PWCTL
:
9297 gen_helper_mtc0_pwctl(cpu_env
, arg
);
9298 register_name
= "PWCtl";
9301 goto cp0_unimplemented
;
9304 case CP0_REGISTER_07
:
9306 case CP0_REG07__HWRENA
:
9307 check_insn(ctx
, ISA_MIPS32R2
);
9308 gen_helper_mtc0_hwrena(cpu_env
, arg
);
9309 ctx
->base
.is_jmp
= DISAS_STOP
;
9310 register_name
= "HWREna";
9313 goto cp0_unimplemented
;
9316 case CP0_REGISTER_08
:
9318 case CP0_REG08__BADVADDR
:
9320 register_name
= "BadVAddr";
9322 case CP0_REG08__BADINSTR
:
9324 register_name
= "BadInstr";
9326 case CP0_REG08__BADINSTRP
:
9328 register_name
= "BadInstrP";
9330 case CP0_REG08__BADINSTRX
:
9332 register_name
= "BadInstrX";
9335 goto cp0_unimplemented
;
9338 case CP0_REGISTER_09
:
9340 case CP0_REG09__COUNT
:
9341 gen_helper_mtc0_count(cpu_env
, arg
);
9342 register_name
= "Count";
9344 case CP0_REG09__SAARI
:
9345 CP0_CHECK(ctx
->saar
);
9346 gen_helper_mtc0_saari(cpu_env
, arg
);
9347 register_name
= "SAARI";
9349 case CP0_REG09__SAAR
:
9350 CP0_CHECK(ctx
->saar
);
9351 gen_helper_mtc0_saar(cpu_env
, arg
);
9352 register_name
= "SAAR";
9355 goto cp0_unimplemented
;
9357 /* Stop translation as we may have switched the execution mode */
9358 ctx
->base
.is_jmp
= DISAS_STOP
;
9360 case CP0_REGISTER_10
:
9362 case CP0_REG10__ENTRYHI
:
9363 gen_helper_mtc0_entryhi(cpu_env
, arg
);
9364 register_name
= "EntryHi";
9367 goto cp0_unimplemented
;
9370 case CP0_REGISTER_11
:
9372 case CP0_REG11__COMPARE
:
9373 gen_helper_mtc0_compare(cpu_env
, arg
);
9374 register_name
= "Compare";
9376 /* 6,7 are implementation dependent */
9378 goto cp0_unimplemented
;
9380 /* Stop translation as we may have switched the execution mode */
9381 ctx
->base
.is_jmp
= DISAS_STOP
;
9383 case CP0_REGISTER_12
:
9385 case CP0_REG12__STATUS
:
9386 save_cpu_state(ctx
, 1);
9387 gen_helper_mtc0_status(cpu_env
, arg
);
9388 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9389 gen_save_pc(ctx
->base
.pc_next
+ 4);
9390 ctx
->base
.is_jmp
= DISAS_EXIT
;
9391 register_name
= "Status";
9393 case CP0_REG12__INTCTL
:
9394 check_insn(ctx
, ISA_MIPS32R2
);
9395 gen_helper_mtc0_intctl(cpu_env
, arg
);
9396 /* Stop translation as we may have switched the execution mode */
9397 ctx
->base
.is_jmp
= DISAS_STOP
;
9398 register_name
= "IntCtl";
9400 case CP0_REG12__SRSCTL
:
9401 check_insn(ctx
, ISA_MIPS32R2
);
9402 gen_helper_mtc0_srsctl(cpu_env
, arg
);
9403 /* Stop translation as we may have switched the execution mode */
9404 ctx
->base
.is_jmp
= DISAS_STOP
;
9405 register_name
= "SRSCtl";
9407 case CP0_REG12__SRSMAP
:
9408 check_insn(ctx
, ISA_MIPS32R2
);
9409 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
9410 /* Stop translation as we may have switched the execution mode */
9411 ctx
->base
.is_jmp
= DISAS_STOP
;
9412 register_name
= "SRSMap";
9415 goto cp0_unimplemented
;
9418 case CP0_REGISTER_13
:
9420 case CP0_REG13__CAUSE
:
9421 save_cpu_state(ctx
, 1);
9422 gen_helper_mtc0_cause(cpu_env
, arg
);
9424 * Stop translation as we may have triggered an interrupt.
9425 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9426 * translated code to check for pending interrupts.
9428 gen_save_pc(ctx
->base
.pc_next
+ 4);
9429 ctx
->base
.is_jmp
= DISAS_EXIT
;
9430 register_name
= "Cause";
9433 goto cp0_unimplemented
;
9436 case CP0_REGISTER_14
:
9438 case CP0_REG14__EPC
:
9439 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
9440 register_name
= "EPC";
9443 goto cp0_unimplemented
;
9446 case CP0_REGISTER_15
:
9448 case CP0_REG15__PRID
:
9450 register_name
= "PRid";
9452 case CP0_REG15__EBASE
:
9453 check_insn(ctx
, ISA_MIPS32R2
);
9454 gen_helper_mtc0_ebase(cpu_env
, arg
);
9455 register_name
= "EBase";
9458 goto cp0_unimplemented
;
9461 case CP0_REGISTER_16
:
9463 case CP0_REG16__CONFIG
:
9464 gen_helper_mtc0_config0(cpu_env
, arg
);
9465 register_name
= "Config";
9466 /* Stop translation as we may have switched the execution mode */
9467 ctx
->base
.is_jmp
= DISAS_STOP
;
9469 case CP0_REG16__CONFIG1
:
9470 /* ignored, read only */
9471 register_name
= "Config1";
9473 case CP0_REG16__CONFIG2
:
9474 gen_helper_mtc0_config2(cpu_env
, arg
);
9475 register_name
= "Config2";
9476 /* Stop translation as we may have switched the execution mode */
9477 ctx
->base
.is_jmp
= DISAS_STOP
;
9479 case CP0_REG16__CONFIG3
:
9480 gen_helper_mtc0_config3(cpu_env
, arg
);
9481 register_name
= "Config3";
9482 /* Stop translation as we may have switched the execution mode */
9483 ctx
->base
.is_jmp
= DISAS_STOP
;
9485 case CP0_REG16__CONFIG4
:
9486 /* currently ignored */
9487 register_name
= "Config4";
9489 case CP0_REG16__CONFIG5
:
9490 gen_helper_mtc0_config5(cpu_env
, arg
);
9491 register_name
= "Config5";
9492 /* Stop translation as we may have switched the execution mode */
9493 ctx
->base
.is_jmp
= DISAS_STOP
;
9495 /* 6,7 are implementation dependent */
9497 register_name
= "Invalid config selector";
9498 goto cp0_unimplemented
;
9501 case CP0_REGISTER_17
:
9503 case CP0_REG17__LLADDR
:
9504 gen_helper_mtc0_lladdr(cpu_env
, arg
);
9505 register_name
= "LLAddr";
9507 case CP0_REG17__MAAR
:
9508 CP0_CHECK(ctx
->mrp
);
9509 gen_helper_mtc0_maar(cpu_env
, arg
);
9510 register_name
= "MAAR";
9512 case CP0_REG17__MAARI
:
9513 CP0_CHECK(ctx
->mrp
);
9514 gen_helper_mtc0_maari(cpu_env
, arg
);
9515 register_name
= "MAARI";
9518 goto cp0_unimplemented
;
9521 case CP0_REGISTER_18
:
9523 case CP0_REG18__WATCHLO0
:
9524 case CP0_REG18__WATCHLO1
:
9525 case CP0_REG18__WATCHLO2
:
9526 case CP0_REG18__WATCHLO3
:
9527 case CP0_REG18__WATCHLO4
:
9528 case CP0_REG18__WATCHLO5
:
9529 case CP0_REG18__WATCHLO6
:
9530 case CP0_REG18__WATCHLO7
:
9531 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9532 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
9533 register_name
= "WatchLo";
9536 goto cp0_unimplemented
;
9539 case CP0_REGISTER_19
:
9541 case CP0_REG19__WATCHHI0
:
9542 case CP0_REG19__WATCHHI1
:
9543 case CP0_REG19__WATCHHI2
:
9544 case CP0_REG19__WATCHHI3
:
9545 case CP0_REG19__WATCHHI4
:
9546 case CP0_REG19__WATCHHI5
:
9547 case CP0_REG19__WATCHHI6
:
9548 case CP0_REG19__WATCHHI7
:
9549 CP0_CHECK(ctx
->CP0_Config1
& (1 << CP0C1_WR
));
9550 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
9551 register_name
= "WatchHi";
9554 goto cp0_unimplemented
;
9557 case CP0_REGISTER_20
:
9559 case CP0_REG20__XCONTEXT
:
9560 check_insn(ctx
, ISA_MIPS3
);
9561 gen_helper_mtc0_xcontext(cpu_env
, arg
);
9562 register_name
= "XContext";
9565 goto cp0_unimplemented
;
9568 case CP0_REGISTER_21
:
9569 /* Officially reserved, but sel 0 is used for R1x000 framemask */
9570 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
9573 gen_helper_mtc0_framemask(cpu_env
, arg
);
9574 register_name
= "Framemask";
9577 goto cp0_unimplemented
;
9580 case CP0_REGISTER_22
:
9582 register_name
= "Diagnostic"; /* implementation dependent */
9584 case CP0_REGISTER_23
:
9586 case CP0_REG23__DEBUG
:
9587 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
9588 /* DISAS_STOP isn't good enough here, hflags may have changed. */
9589 gen_save_pc(ctx
->base
.pc_next
+ 4);
9590 ctx
->base
.is_jmp
= DISAS_EXIT
;
9591 register_name
= "Debug";
9593 case CP0_REG23__TRACECONTROL
:
9594 /* PDtrace support */
9595 /* gen_helper_mtc0_tracecontrol(cpu_env, arg); */
9596 /* Stop translation as we may have switched the execution mode */
9597 ctx
->base
.is_jmp
= DISAS_STOP
;
9598 register_name
= "TraceControl";
9599 goto cp0_unimplemented
;
9600 case CP0_REG23__TRACECONTROL2
:
9601 /* PDtrace support */
9602 /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
9603 /* Stop translation as we may have switched the execution mode */
9604 ctx
->base
.is_jmp
= DISAS_STOP
;
9605 register_name
= "TraceControl2";
9606 goto cp0_unimplemented
;
9607 case CP0_REG23__USERTRACEDATA1
:
9608 /* PDtrace support */
9609 /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
9610 /* Stop translation as we may have switched the execution mode */
9611 ctx
->base
.is_jmp
= DISAS_STOP
;
9612 register_name
= "UserTraceData1";
9613 goto cp0_unimplemented
;
9614 case CP0_REG23__TRACEIBPC
:
9615 /* PDtrace support */
9616 /* gen_helper_mtc0_traceibpc(cpu_env, arg); */
9617 /* Stop translation as we may have switched the execution mode */
9618 ctx
->base
.is_jmp
= DISAS_STOP
;
9619 register_name
= "TraceIBPC";
9620 goto cp0_unimplemented
;
9621 case CP0_REG23__TRACEDBPC
:
9622 /* PDtrace support */
9623 /* gen_helper_mtc0_tracedbpc(cpu_env, arg); */
9624 /* Stop translation as we may have switched the execution mode */
9625 ctx
->base
.is_jmp
= DISAS_STOP
;
9626 register_name
= "TraceDBPC";
9627 goto cp0_unimplemented
;
9629 goto cp0_unimplemented
;
9632 case CP0_REGISTER_24
:
9634 case CP0_REG24__DEPC
:
9636 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
9637 register_name
= "DEPC";
9640 goto cp0_unimplemented
;
9643 case CP0_REGISTER_25
:
9645 case CP0_REG25__PERFCTL0
:
9646 gen_helper_mtc0_performance0(cpu_env
, arg
);
9647 register_name
= "Performance0";
9649 case CP0_REG25__PERFCNT0
:
9650 /* gen_helper_mtc0_performance1(cpu_env, arg); */
9651 register_name
= "Performance1";
9652 goto cp0_unimplemented
;
9653 case CP0_REG25__PERFCTL1
:
9654 /* gen_helper_mtc0_performance2(cpu_env, arg); */
9655 register_name
= "Performance2";
9656 goto cp0_unimplemented
;
9657 case CP0_REG25__PERFCNT1
:
9658 /* gen_helper_mtc0_performance3(cpu_env, arg); */
9659 register_name
= "Performance3";
9660 goto cp0_unimplemented
;
9661 case CP0_REG25__PERFCTL2
:
9662 /* gen_helper_mtc0_performance4(cpu_env, arg); */
9663 register_name
= "Performance4";
9664 goto cp0_unimplemented
;
9665 case CP0_REG25__PERFCNT2
:
9666 /* gen_helper_mtc0_performance5(cpu_env, arg); */
9667 register_name
= "Performance5";
9668 goto cp0_unimplemented
;
9669 case CP0_REG25__PERFCTL3
:
9670 /* gen_helper_mtc0_performance6(cpu_env, arg); */
9671 register_name
= "Performance6";
9672 goto cp0_unimplemented
;
9673 case CP0_REG25__PERFCNT3
:
9674 /* gen_helper_mtc0_performance7(cpu_env, arg); */
9675 register_name
= "Performance7";
9676 goto cp0_unimplemented
;
9678 goto cp0_unimplemented
;
9681 case CP0_REGISTER_26
:
9683 case CP0_REG26__ERRCTL
:
9684 gen_helper_mtc0_errctl(cpu_env
, arg
);
9685 ctx
->base
.is_jmp
= DISAS_STOP
;
9686 register_name
= "ErrCtl";
9689 goto cp0_unimplemented
;
9692 case CP0_REGISTER_27
:
9694 case CP0_REG27__CACHERR
:
9696 register_name
= "CacheErr";
9699 goto cp0_unimplemented
;
9702 case CP0_REGISTER_28
:
9704 case CP0_REG28__TAGLO
:
9705 case CP0_REG28__TAGLO1
:
9706 case CP0_REG28__TAGLO2
:
9707 case CP0_REG28__TAGLO3
:
9708 gen_helper_mtc0_taglo(cpu_env
, arg
);
9709 register_name
= "TagLo";
9711 case CP0_REG28__DATALO
:
9712 case CP0_REG28__DATALO1
:
9713 case CP0_REG28__DATALO2
:
9714 case CP0_REG28__DATALO3
:
9715 gen_helper_mtc0_datalo(cpu_env
, arg
);
9716 register_name
= "DataLo";
9719 goto cp0_unimplemented
;
9722 case CP0_REGISTER_29
:
9724 case CP0_REG29__TAGHI
:
9725 case CP0_REG29__TAGHI1
:
9726 case CP0_REG29__TAGHI2
:
9727 case CP0_REG29__TAGHI3
:
9728 gen_helper_mtc0_taghi(cpu_env
, arg
);
9729 register_name
= "TagHi";
9731 case CP0_REG29__DATAHI
:
9732 case CP0_REG29__DATAHI1
:
9733 case CP0_REG29__DATAHI2
:
9734 case CP0_REG29__DATAHI3
:
9735 gen_helper_mtc0_datahi(cpu_env
, arg
);
9736 register_name
= "DataHi";
9739 register_name
= "invalid sel";
9740 goto cp0_unimplemented
;
9743 case CP0_REGISTER_30
:
9745 case CP0_REG30__ERROREPC
:
9746 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
9747 register_name
= "ErrorEPC";
9750 goto cp0_unimplemented
;
9753 case CP0_REGISTER_31
:
9755 case CP0_REG31__DESAVE
:
9757 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
9758 register_name
= "DESAVE";
9760 case CP0_REG31__KSCRATCH1
:
9761 case CP0_REG31__KSCRATCH2
:
9762 case CP0_REG31__KSCRATCH3
:
9763 case CP0_REG31__KSCRATCH4
:
9764 case CP0_REG31__KSCRATCH5
:
9765 case CP0_REG31__KSCRATCH6
:
9766 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
9767 tcg_gen_st_tl(arg
, cpu_env
,
9768 offsetof(CPUMIPSState
, CP0_KScratch
[sel
- 2]));
9769 register_name
= "KScratch";
9772 goto cp0_unimplemented
;
9776 goto cp0_unimplemented
;
9778 trace_mips_translate_c0("dmtc0", register_name
, reg
, sel
);
9780 /* For simplicity assume that all writes can cause interrupts. */
9781 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
9783 * DISAS_STOP isn't sufficient, we need to ensure we break out of
9784 * translated code to check for pending interrupts.
9786 gen_save_pc(ctx
->base
.pc_next
+ 4);
9787 ctx
->base
.is_jmp
= DISAS_EXIT
;
9792 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n",
9793 register_name
, reg
, sel
);
9795 #endif /* TARGET_MIPS64 */
9797 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
9798 int u
, int sel
, int h
)
9800 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
9801 TCGv t0
= tcg_temp_local_new();
9803 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
9804 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
9805 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
9806 tcg_gen_movi_tl(t0
, -1);
9807 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
9808 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
9809 tcg_gen_movi_tl(t0
, -1);
9810 } else if (u
== 0) {
9815 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
9818 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
9828 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
9831 gen_helper_mftc0_tcbind(t0
, cpu_env
);
9834 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
9837 gen_helper_mftc0_tchalt(t0
, cpu_env
);
9840 gen_helper_mftc0_tccontext(t0
, cpu_env
);
9843 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
9846 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
9849 gen_mfc0(ctx
, t0
, rt
, sel
);
9856 gen_helper_mftc0_entryhi(t0
, cpu_env
);
9859 gen_mfc0(ctx
, t0
, rt
, sel
);
9866 gen_helper_mftc0_status(t0
, cpu_env
);
9869 gen_mfc0(ctx
, t0
, rt
, sel
);
9876 gen_helper_mftc0_cause(t0
, cpu_env
);
9886 gen_helper_mftc0_epc(t0
, cpu_env
);
9896 gen_helper_mftc0_ebase(t0
, cpu_env
);
9913 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
9923 gen_helper_mftc0_debug(t0
, cpu_env
);
9926 gen_mfc0(ctx
, t0
, rt
, sel
);
9931 gen_mfc0(ctx
, t0
, rt
, sel
);
9935 /* GPR registers. */
9937 gen_helper_1e0i(mftgpr
, t0
, rt
);
9939 /* Auxiliary CPU registers */
9943 gen_helper_1e0i(mftlo
, t0
, 0);
9946 gen_helper_1e0i(mfthi
, t0
, 0);
9949 gen_helper_1e0i(mftacx
, t0
, 0);
9952 gen_helper_1e0i(mftlo
, t0
, 1);
9955 gen_helper_1e0i(mfthi
, t0
, 1);
9958 gen_helper_1e0i(mftacx
, t0
, 1);
9961 gen_helper_1e0i(mftlo
, t0
, 2);
9964 gen_helper_1e0i(mfthi
, t0
, 2);
9967 gen_helper_1e0i(mftacx
, t0
, 2);
9970 gen_helper_1e0i(mftlo
, t0
, 3);
9973 gen_helper_1e0i(mfthi
, t0
, 3);
9976 gen_helper_1e0i(mftacx
, t0
, 3);
9979 gen_helper_mftdsp(t0
, cpu_env
);
9985 /* Floating point (COP1). */
9987 /* XXX: For now we support only a single FPU context. */
9989 TCGv_i32 fp0
= tcg_temp_new_i32();
9991 gen_load_fpr32(ctx
, fp0
, rt
);
9992 tcg_gen_ext_i32_tl(t0
, fp0
);
9993 tcg_temp_free_i32(fp0
);
9995 TCGv_i32 fp0
= tcg_temp_new_i32();
9997 gen_load_fpr32h(ctx
, fp0
, rt
);
9998 tcg_gen_ext_i32_tl(t0
, fp0
);
9999 tcg_temp_free_i32(fp0
);
10003 /* XXX: For now we support only a single FPU context. */
10004 gen_helper_1e0i(cfc1
, t0
, rt
);
10006 /* COP2: Not implemented. */
10014 trace_mips_translate_tr("mftr", rt
, u
, sel
, h
);
10015 gen_store_gpr(t0
, rd
);
10021 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
10022 generate_exception_end(ctx
, EXCP_RI
);
10025 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
10026 int u
, int sel
, int h
)
10028 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
10029 TCGv t0
= tcg_temp_local_new();
10031 gen_load_gpr(t0
, rt
);
10032 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
10033 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
10034 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)))) {
10037 } else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
10038 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
))) {
10041 } else if (u
== 0) {
10046 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
10049 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
10059 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
10062 gen_helper_mttc0_tcbind(cpu_env
, t0
);
10065 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
10068 gen_helper_mttc0_tchalt(cpu_env
, t0
);
10071 gen_helper_mttc0_tccontext(cpu_env
, t0
);
10074 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
10077 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
10080 gen_mtc0(ctx
, t0
, rd
, sel
);
10087 gen_helper_mttc0_entryhi(cpu_env
, t0
);
10090 gen_mtc0(ctx
, t0
, rd
, sel
);
10097 gen_helper_mttc0_status(cpu_env
, t0
);
10100 gen_mtc0(ctx
, t0
, rd
, sel
);
10107 gen_helper_mttc0_cause(cpu_env
, t0
);
10117 gen_helper_mttc0_ebase(cpu_env
, t0
);
10127 gen_helper_mttc0_debug(cpu_env
, t0
);
10130 gen_mtc0(ctx
, t0
, rd
, sel
);
10135 gen_mtc0(ctx
, t0
, rd
, sel
);
10139 /* GPR registers. */
10141 gen_helper_0e1i(mttgpr
, t0
, rd
);
10143 /* Auxiliary CPU registers */
10147 gen_helper_0e1i(mttlo
, t0
, 0);
10150 gen_helper_0e1i(mtthi
, t0
, 0);
10153 gen_helper_0e1i(mttacx
, t0
, 0);
10156 gen_helper_0e1i(mttlo
, t0
, 1);
10159 gen_helper_0e1i(mtthi
, t0
, 1);
10162 gen_helper_0e1i(mttacx
, t0
, 1);
10165 gen_helper_0e1i(mttlo
, t0
, 2);
10168 gen_helper_0e1i(mtthi
, t0
, 2);
10171 gen_helper_0e1i(mttacx
, t0
, 2);
10174 gen_helper_0e1i(mttlo
, t0
, 3);
10177 gen_helper_0e1i(mtthi
, t0
, 3);
10180 gen_helper_0e1i(mttacx
, t0
, 3);
10183 gen_helper_mttdsp(cpu_env
, t0
);
10189 /* Floating point (COP1). */
10191 /* XXX: For now we support only a single FPU context. */
10193 TCGv_i32 fp0
= tcg_temp_new_i32();
10195 tcg_gen_trunc_tl_i32(fp0
, t0
);
10196 gen_store_fpr32(ctx
, fp0
, rd
);
10197 tcg_temp_free_i32(fp0
);
10199 TCGv_i32 fp0
= tcg_temp_new_i32();
10201 tcg_gen_trunc_tl_i32(fp0
, t0
);
10202 gen_store_fpr32h(ctx
, fp0
, rd
);
10203 tcg_temp_free_i32(fp0
);
10207 /* XXX: For now we support only a single FPU context. */
10209 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
10211 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10212 tcg_temp_free_i32(fs_tmp
);
10214 /* Stop translation as we may have changed hflags */
10215 ctx
->base
.is_jmp
= DISAS_STOP
;
10217 /* COP2: Not implemented. */
10225 trace_mips_translate_tr("mttr", rd
, u
, sel
, h
);
10231 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
10232 generate_exception_end(ctx
, EXCP_RI
);
10235 static void gen_cp0(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
,
10238 const char *opn
= "ldst";
10240 check_cp0_enabled(ctx
);
10244 /* Treat as NOP. */
10247 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10252 TCGv t0
= tcg_temp_new();
10254 gen_load_gpr(t0
, rt
);
10255 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10260 #if defined(TARGET_MIPS64)
10262 check_insn(ctx
, ISA_MIPS3
);
10264 /* Treat as NOP. */
10267 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10271 check_insn(ctx
, ISA_MIPS3
);
10273 TCGv t0
= tcg_temp_new();
10275 gen_load_gpr(t0
, rt
);
10276 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10285 /* Treat as NOP. */
10288 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
10294 TCGv t0
= tcg_temp_new();
10295 gen_load_gpr(t0
, rt
);
10296 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
10302 check_cp0_enabled(ctx
);
10304 /* Treat as NOP. */
10307 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
10308 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10312 check_cp0_enabled(ctx
);
10313 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
10314 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
10319 if (!env
->tlb
->helper_tlbwi
) {
10322 gen_helper_tlbwi(cpu_env
);
10326 if (ctx
->ie
>= 2) {
10327 if (!env
->tlb
->helper_tlbinv
) {
10330 gen_helper_tlbinv(cpu_env
);
10331 } /* treat as nop if TLBINV not supported */
10335 if (ctx
->ie
>= 2) {
10336 if (!env
->tlb
->helper_tlbinvf
) {
10339 gen_helper_tlbinvf(cpu_env
);
10340 } /* treat as nop if TLBINV not supported */
10344 if (!env
->tlb
->helper_tlbwr
) {
10347 gen_helper_tlbwr(cpu_env
);
10351 if (!env
->tlb
->helper_tlbp
) {
10354 gen_helper_tlbp(cpu_env
);
10358 if (!env
->tlb
->helper_tlbr
) {
10361 gen_helper_tlbr(cpu_env
);
10363 case OPC_ERET
: /* OPC_ERETNC */
10364 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10365 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10368 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
10369 if (ctx
->opcode
& (1 << bit_shift
)) {
10372 check_insn(ctx
, ISA_MIPS32R5
);
10373 gen_helper_eretnc(cpu_env
);
10377 check_insn(ctx
, ISA_MIPS2
);
10378 gen_helper_eret(cpu_env
);
10380 ctx
->base
.is_jmp
= DISAS_EXIT
;
10385 check_insn(ctx
, ISA_MIPS32
);
10386 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10387 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10390 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10392 generate_exception_end(ctx
, EXCP_RI
);
10394 gen_helper_deret(cpu_env
);
10395 ctx
->base
.is_jmp
= DISAS_EXIT
;
10400 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
10401 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
10402 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10405 /* If we get an exception, we want to restart at next instruction */
10406 ctx
->base
.pc_next
+= 4;
10407 save_cpu_state(ctx
, 1);
10408 ctx
->base
.pc_next
-= 4;
10409 gen_helper_wait(cpu_env
);
10410 ctx
->base
.is_jmp
= DISAS_NORETURN
;
10415 generate_exception_end(ctx
, EXCP_RI
);
10418 (void)opn
; /* avoid a compiler warning */
10420 #endif /* !CONFIG_USER_ONLY */
10422 /* CP1 Branches (before delay slot) */
10423 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
10424 int32_t cc
, int32_t offset
)
10426 target_ulong btarget
;
10427 TCGv_i32 t0
= tcg_temp_new_i32();
10429 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10430 generate_exception_end(ctx
, EXCP_RI
);
10435 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
10438 btarget
= ctx
->base
.pc_next
+ 4 + offset
;
10442 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10443 tcg_gen_not_i32(t0
, t0
);
10444 tcg_gen_andi_i32(t0
, t0
, 1);
10445 tcg_gen_extu_i32_tl(bcond
, t0
);
10448 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10449 tcg_gen_not_i32(t0
, t0
);
10450 tcg_gen_andi_i32(t0
, t0
, 1);
10451 tcg_gen_extu_i32_tl(bcond
, t0
);
10454 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10455 tcg_gen_andi_i32(t0
, t0
, 1);
10456 tcg_gen_extu_i32_tl(bcond
, t0
);
10459 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10460 tcg_gen_andi_i32(t0
, t0
, 1);
10461 tcg_gen_extu_i32_tl(bcond
, t0
);
10463 ctx
->hflags
|= MIPS_HFLAG_BL
;
10467 TCGv_i32 t1
= tcg_temp_new_i32();
10468 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10469 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10470 tcg_gen_nand_i32(t0
, t0
, t1
);
10471 tcg_temp_free_i32(t1
);
10472 tcg_gen_andi_i32(t0
, t0
, 1);
10473 tcg_gen_extu_i32_tl(bcond
, t0
);
10478 TCGv_i32 t1
= tcg_temp_new_i32();
10479 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10480 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10481 tcg_gen_or_i32(t0
, t0
, t1
);
10482 tcg_temp_free_i32(t1
);
10483 tcg_gen_andi_i32(t0
, t0
, 1);
10484 tcg_gen_extu_i32_tl(bcond
, t0
);
10489 TCGv_i32 t1
= tcg_temp_new_i32();
10490 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10491 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10492 tcg_gen_and_i32(t0
, t0
, t1
);
10493 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10494 tcg_gen_and_i32(t0
, t0
, t1
);
10495 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10496 tcg_gen_nand_i32(t0
, t0
, t1
);
10497 tcg_temp_free_i32(t1
);
10498 tcg_gen_andi_i32(t0
, t0
, 1);
10499 tcg_gen_extu_i32_tl(bcond
, t0
);
10504 TCGv_i32 t1
= tcg_temp_new_i32();
10505 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
10506 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 1));
10507 tcg_gen_or_i32(t0
, t0
, t1
);
10508 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 2));
10509 tcg_gen_or_i32(t0
, t0
, t1
);
10510 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+ 3));
10511 tcg_gen_or_i32(t0
, t0
, t1
);
10512 tcg_temp_free_i32(t1
);
10513 tcg_gen_andi_i32(t0
, t0
, 1);
10514 tcg_gen_extu_i32_tl(bcond
, t0
);
10517 ctx
->hflags
|= MIPS_HFLAG_BC
;
10520 MIPS_INVAL("cp1 cond branch");
10521 generate_exception_end(ctx
, EXCP_RI
);
10524 ctx
->btarget
= btarget
;
10525 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10527 tcg_temp_free_i32(t0
);
10530 /* R6 CP1 Branches */
10531 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
10532 int32_t ft
, int32_t offset
,
10533 int delayslot_size
)
10535 target_ulong btarget
;
10536 TCGv_i64 t0
= tcg_temp_new_i64();
10538 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10539 #ifdef MIPS_DEBUG_DISAS
10540 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10541 "\n", ctx
->base
.pc_next
);
10543 generate_exception_end(ctx
, EXCP_RI
);
10547 gen_load_fpr64(ctx
, t0
, ft
);
10548 tcg_gen_andi_i64(t0
, t0
, 1);
10550 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
10554 tcg_gen_xori_i64(t0
, t0
, 1);
10555 ctx
->hflags
|= MIPS_HFLAG_BC
;
10558 /* t0 already set */
10559 ctx
->hflags
|= MIPS_HFLAG_BC
;
10562 MIPS_INVAL("cp1 cond branch");
10563 generate_exception_end(ctx
, EXCP_RI
);
10567 tcg_gen_trunc_i64_tl(bcond
, t0
);
10569 ctx
->btarget
= btarget
;
10571 switch (delayslot_size
) {
10573 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
10576 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
10581 tcg_temp_free_i64(t0
);
10584 /* Coprocessor 1 (FPU) */
10586 #define FOP(func, fmt) (((fmt) << 21) | (func))
10589 OPC_ADD_S
= FOP(0, FMT_S
),
10590 OPC_SUB_S
= FOP(1, FMT_S
),
10591 OPC_MUL_S
= FOP(2, FMT_S
),
10592 OPC_DIV_S
= FOP(3, FMT_S
),
10593 OPC_SQRT_S
= FOP(4, FMT_S
),
10594 OPC_ABS_S
= FOP(5, FMT_S
),
10595 OPC_MOV_S
= FOP(6, FMT_S
),
10596 OPC_NEG_S
= FOP(7, FMT_S
),
10597 OPC_ROUND_L_S
= FOP(8, FMT_S
),
10598 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
10599 OPC_CEIL_L_S
= FOP(10, FMT_S
),
10600 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
10601 OPC_ROUND_W_S
= FOP(12, FMT_S
),
10602 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
10603 OPC_CEIL_W_S
= FOP(14, FMT_S
),
10604 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
10605 OPC_SEL_S
= FOP(16, FMT_S
),
10606 OPC_MOVCF_S
= FOP(17, FMT_S
),
10607 OPC_MOVZ_S
= FOP(18, FMT_S
),
10608 OPC_MOVN_S
= FOP(19, FMT_S
),
10609 OPC_SELEQZ_S
= FOP(20, FMT_S
),
10610 OPC_RECIP_S
= FOP(21, FMT_S
),
10611 OPC_RSQRT_S
= FOP(22, FMT_S
),
10612 OPC_SELNEZ_S
= FOP(23, FMT_S
),
10613 OPC_MADDF_S
= FOP(24, FMT_S
),
10614 OPC_MSUBF_S
= FOP(25, FMT_S
),
10615 OPC_RINT_S
= FOP(26, FMT_S
),
10616 OPC_CLASS_S
= FOP(27, FMT_S
),
10617 OPC_MIN_S
= FOP(28, FMT_S
),
10618 OPC_RECIP2_S
= FOP(28, FMT_S
),
10619 OPC_MINA_S
= FOP(29, FMT_S
),
10620 OPC_RECIP1_S
= FOP(29, FMT_S
),
10621 OPC_MAX_S
= FOP(30, FMT_S
),
10622 OPC_RSQRT1_S
= FOP(30, FMT_S
),
10623 OPC_MAXA_S
= FOP(31, FMT_S
),
10624 OPC_RSQRT2_S
= FOP(31, FMT_S
),
10625 OPC_CVT_D_S
= FOP(33, FMT_S
),
10626 OPC_CVT_W_S
= FOP(36, FMT_S
),
10627 OPC_CVT_L_S
= FOP(37, FMT_S
),
10628 OPC_CVT_PS_S
= FOP(38, FMT_S
),
10629 OPC_CMP_F_S
= FOP(48, FMT_S
),
10630 OPC_CMP_UN_S
= FOP(49, FMT_S
),
10631 OPC_CMP_EQ_S
= FOP(50, FMT_S
),
10632 OPC_CMP_UEQ_S
= FOP(51, FMT_S
),
10633 OPC_CMP_OLT_S
= FOP(52, FMT_S
),
10634 OPC_CMP_ULT_S
= FOP(53, FMT_S
),
10635 OPC_CMP_OLE_S
= FOP(54, FMT_S
),
10636 OPC_CMP_ULE_S
= FOP(55, FMT_S
),
10637 OPC_CMP_SF_S
= FOP(56, FMT_S
),
10638 OPC_CMP_NGLE_S
= FOP(57, FMT_S
),
10639 OPC_CMP_SEQ_S
= FOP(58, FMT_S
),
10640 OPC_CMP_NGL_S
= FOP(59, FMT_S
),
10641 OPC_CMP_LT_S
= FOP(60, FMT_S
),
10642 OPC_CMP_NGE_S
= FOP(61, FMT_S
),
10643 OPC_CMP_LE_S
= FOP(62, FMT_S
),
10644 OPC_CMP_NGT_S
= FOP(63, FMT_S
),
10646 OPC_ADD_D
= FOP(0, FMT_D
),
10647 OPC_SUB_D
= FOP(1, FMT_D
),
10648 OPC_MUL_D
= FOP(2, FMT_D
),
10649 OPC_DIV_D
= FOP(3, FMT_D
),
10650 OPC_SQRT_D
= FOP(4, FMT_D
),
10651 OPC_ABS_D
= FOP(5, FMT_D
),
10652 OPC_MOV_D
= FOP(6, FMT_D
),
10653 OPC_NEG_D
= FOP(7, FMT_D
),
10654 OPC_ROUND_L_D
= FOP(8, FMT_D
),
10655 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
10656 OPC_CEIL_L_D
= FOP(10, FMT_D
),
10657 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
10658 OPC_ROUND_W_D
= FOP(12, FMT_D
),
10659 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
10660 OPC_CEIL_W_D
= FOP(14, FMT_D
),
10661 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
10662 OPC_SEL_D
= FOP(16, FMT_D
),
10663 OPC_MOVCF_D
= FOP(17, FMT_D
),
10664 OPC_MOVZ_D
= FOP(18, FMT_D
),
10665 OPC_MOVN_D
= FOP(19, FMT_D
),
10666 OPC_SELEQZ_D
= FOP(20, FMT_D
),
10667 OPC_RECIP_D
= FOP(21, FMT_D
),
10668 OPC_RSQRT_D
= FOP(22, FMT_D
),
10669 OPC_SELNEZ_D
= FOP(23, FMT_D
),
10670 OPC_MADDF_D
= FOP(24, FMT_D
),
10671 OPC_MSUBF_D
= FOP(25, FMT_D
),
10672 OPC_RINT_D
= FOP(26, FMT_D
),
10673 OPC_CLASS_D
= FOP(27, FMT_D
),
10674 OPC_MIN_D
= FOP(28, FMT_D
),
10675 OPC_RECIP2_D
= FOP(28, FMT_D
),
10676 OPC_MINA_D
= FOP(29, FMT_D
),
10677 OPC_RECIP1_D
= FOP(29, FMT_D
),
10678 OPC_MAX_D
= FOP(30, FMT_D
),
10679 OPC_RSQRT1_D
= FOP(30, FMT_D
),
10680 OPC_MAXA_D
= FOP(31, FMT_D
),
10681 OPC_RSQRT2_D
= FOP(31, FMT_D
),
10682 OPC_CVT_S_D
= FOP(32, FMT_D
),
10683 OPC_CVT_W_D
= FOP(36, FMT_D
),
10684 OPC_CVT_L_D
= FOP(37, FMT_D
),
10685 OPC_CMP_F_D
= FOP(48, FMT_D
),
10686 OPC_CMP_UN_D
= FOP(49, FMT_D
),
10687 OPC_CMP_EQ_D
= FOP(50, FMT_D
),
10688 OPC_CMP_UEQ_D
= FOP(51, FMT_D
),
10689 OPC_CMP_OLT_D
= FOP(52, FMT_D
),
10690 OPC_CMP_ULT_D
= FOP(53, FMT_D
),
10691 OPC_CMP_OLE_D
= FOP(54, FMT_D
),
10692 OPC_CMP_ULE_D
= FOP(55, FMT_D
),
10693 OPC_CMP_SF_D
= FOP(56, FMT_D
),
10694 OPC_CMP_NGLE_D
= FOP(57, FMT_D
),
10695 OPC_CMP_SEQ_D
= FOP(58, FMT_D
),
10696 OPC_CMP_NGL_D
= FOP(59, FMT_D
),
10697 OPC_CMP_LT_D
= FOP(60, FMT_D
),
10698 OPC_CMP_NGE_D
= FOP(61, FMT_D
),
10699 OPC_CMP_LE_D
= FOP(62, FMT_D
),
10700 OPC_CMP_NGT_D
= FOP(63, FMT_D
),
10702 OPC_CVT_S_W
= FOP(32, FMT_W
),
10703 OPC_CVT_D_W
= FOP(33, FMT_W
),
10704 OPC_CVT_S_L
= FOP(32, FMT_L
),
10705 OPC_CVT_D_L
= FOP(33, FMT_L
),
10706 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
10708 OPC_ADD_PS
= FOP(0, FMT_PS
),
10709 OPC_SUB_PS
= FOP(1, FMT_PS
),
10710 OPC_MUL_PS
= FOP(2, FMT_PS
),
10711 OPC_DIV_PS
= FOP(3, FMT_PS
),
10712 OPC_ABS_PS
= FOP(5, FMT_PS
),
10713 OPC_MOV_PS
= FOP(6, FMT_PS
),
10714 OPC_NEG_PS
= FOP(7, FMT_PS
),
10715 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
10716 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
10717 OPC_MOVN_PS
= FOP(19, FMT_PS
),
10718 OPC_ADDR_PS
= FOP(24, FMT_PS
),
10719 OPC_MULR_PS
= FOP(26, FMT_PS
),
10720 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
10721 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
10722 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
10723 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
10725 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
10726 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
10727 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
10728 OPC_PLL_PS
= FOP(44, FMT_PS
),
10729 OPC_PLU_PS
= FOP(45, FMT_PS
),
10730 OPC_PUL_PS
= FOP(46, FMT_PS
),
10731 OPC_PUU_PS
= FOP(47, FMT_PS
),
10732 OPC_CMP_F_PS
= FOP(48, FMT_PS
),
10733 OPC_CMP_UN_PS
= FOP(49, FMT_PS
),
10734 OPC_CMP_EQ_PS
= FOP(50, FMT_PS
),
10735 OPC_CMP_UEQ_PS
= FOP(51, FMT_PS
),
10736 OPC_CMP_OLT_PS
= FOP(52, FMT_PS
),
10737 OPC_CMP_ULT_PS
= FOP(53, FMT_PS
),
10738 OPC_CMP_OLE_PS
= FOP(54, FMT_PS
),
10739 OPC_CMP_ULE_PS
= FOP(55, FMT_PS
),
10740 OPC_CMP_SF_PS
= FOP(56, FMT_PS
),
10741 OPC_CMP_NGLE_PS
= FOP(57, FMT_PS
),
10742 OPC_CMP_SEQ_PS
= FOP(58, FMT_PS
),
10743 OPC_CMP_NGL_PS
= FOP(59, FMT_PS
),
10744 OPC_CMP_LT_PS
= FOP(60, FMT_PS
),
10745 OPC_CMP_NGE_PS
= FOP(61, FMT_PS
),
10746 OPC_CMP_LE_PS
= FOP(62, FMT_PS
),
10747 OPC_CMP_NGT_PS
= FOP(63, FMT_PS
),
10751 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
10752 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
10753 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
10754 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
10755 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
10756 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
10757 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
10758 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
10759 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
10760 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
10761 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
10762 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
10763 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
10764 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
10765 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
10766 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
10767 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
10768 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
10769 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
10770 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
10771 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
10772 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
10774 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
10775 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
10776 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
10777 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
10778 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
10779 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
10780 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
10781 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
10782 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
10783 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
10784 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
10785 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
10786 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
10787 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
10788 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
10789 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
10790 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
10791 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
10792 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
10793 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
10794 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
10795 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
10798 static void gen_cp1(DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
10800 TCGv t0
= tcg_temp_new();
10805 TCGv_i32 fp0
= tcg_temp_new_i32();
10807 gen_load_fpr32(ctx
, fp0
, fs
);
10808 tcg_gen_ext_i32_tl(t0
, fp0
);
10809 tcg_temp_free_i32(fp0
);
10811 gen_store_gpr(t0
, rt
);
10814 gen_load_gpr(t0
, rt
);
10816 TCGv_i32 fp0
= tcg_temp_new_i32();
10818 tcg_gen_trunc_tl_i32(fp0
, t0
);
10819 gen_store_fpr32(ctx
, fp0
, fs
);
10820 tcg_temp_free_i32(fp0
);
10824 gen_helper_1e0i(cfc1
, t0
, fs
);
10825 gen_store_gpr(t0
, rt
);
10828 gen_load_gpr(t0
, rt
);
10829 save_cpu_state(ctx
, 0);
10831 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
10833 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
10834 tcg_temp_free_i32(fs_tmp
);
10836 /* Stop translation as we may have changed hflags */
10837 ctx
->base
.is_jmp
= DISAS_STOP
;
10839 #if defined(TARGET_MIPS64)
10841 gen_load_fpr64(ctx
, t0
, fs
);
10842 gen_store_gpr(t0
, rt
);
10845 gen_load_gpr(t0
, rt
);
10846 gen_store_fpr64(ctx
, t0
, fs
);
10851 TCGv_i32 fp0
= tcg_temp_new_i32();
10853 gen_load_fpr32h(ctx
, fp0
, fs
);
10854 tcg_gen_ext_i32_tl(t0
, fp0
);
10855 tcg_temp_free_i32(fp0
);
10857 gen_store_gpr(t0
, rt
);
10860 gen_load_gpr(t0
, rt
);
10862 TCGv_i32 fp0
= tcg_temp_new_i32();
10864 tcg_gen_trunc_tl_i32(fp0
, t0
);
10865 gen_store_fpr32h(ctx
, fp0
, fs
);
10866 tcg_temp_free_i32(fp0
);
10870 MIPS_INVAL("cp1 move");
10871 generate_exception_end(ctx
, EXCP_RI
);
10879 static void gen_movci(DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
10886 /* Treat as NOP. */
10891 cond
= TCG_COND_EQ
;
10893 cond
= TCG_COND_NE
;
10896 l1
= gen_new_label();
10897 t0
= tcg_temp_new_i32();
10898 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10899 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10900 tcg_temp_free_i32(t0
);
10902 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
10904 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
10909 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10913 TCGv_i32 t0
= tcg_temp_new_i32();
10914 TCGLabel
*l1
= gen_new_label();
10917 cond
= TCG_COND_EQ
;
10919 cond
= TCG_COND_NE
;
10922 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10923 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10924 gen_load_fpr32(ctx
, t0
, fs
);
10925 gen_store_fpr32(ctx
, t0
, fd
);
10927 tcg_temp_free_i32(t0
);
10930 static inline void gen_movcf_d(DisasContext
*ctx
, int fs
, int fd
, int cc
,
10934 TCGv_i32 t0
= tcg_temp_new_i32();
10936 TCGLabel
*l1
= gen_new_label();
10939 cond
= TCG_COND_EQ
;
10941 cond
= TCG_COND_NE
;
10944 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10945 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10946 tcg_temp_free_i32(t0
);
10947 fp0
= tcg_temp_new_i64();
10948 gen_load_fpr64(ctx
, fp0
, fs
);
10949 gen_store_fpr64(ctx
, fp0
, fd
);
10950 tcg_temp_free_i64(fp0
);
10954 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
10958 TCGv_i32 t0
= tcg_temp_new_i32();
10959 TCGLabel
*l1
= gen_new_label();
10960 TCGLabel
*l2
= gen_new_label();
10963 cond
= TCG_COND_EQ
;
10965 cond
= TCG_COND_NE
;
10968 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
10969 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
10970 gen_load_fpr32(ctx
, t0
, fs
);
10971 gen_store_fpr32(ctx
, t0
, fd
);
10974 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+ 1));
10975 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
10976 gen_load_fpr32h(ctx
, t0
, fs
);
10977 gen_store_fpr32h(ctx
, t0
, fd
);
10978 tcg_temp_free_i32(t0
);
10982 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
10985 TCGv_i32 t1
= tcg_const_i32(0);
10986 TCGv_i32 fp0
= tcg_temp_new_i32();
10987 TCGv_i32 fp1
= tcg_temp_new_i32();
10988 TCGv_i32 fp2
= tcg_temp_new_i32();
10989 gen_load_fpr32(ctx
, fp0
, fd
);
10990 gen_load_fpr32(ctx
, fp1
, ft
);
10991 gen_load_fpr32(ctx
, fp2
, fs
);
10995 tcg_gen_andi_i32(fp0
, fp0
, 1);
10996 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
10999 tcg_gen_andi_i32(fp1
, fp1
, 1);
11000 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11003 tcg_gen_andi_i32(fp1
, fp1
, 1);
11004 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11007 MIPS_INVAL("gen_sel_s");
11008 generate_exception_end(ctx
, EXCP_RI
);
11012 gen_store_fpr32(ctx
, fp0
, fd
);
11013 tcg_temp_free_i32(fp2
);
11014 tcg_temp_free_i32(fp1
);
11015 tcg_temp_free_i32(fp0
);
11016 tcg_temp_free_i32(t1
);
11019 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
11022 TCGv_i64 t1
= tcg_const_i64(0);
11023 TCGv_i64 fp0
= tcg_temp_new_i64();
11024 TCGv_i64 fp1
= tcg_temp_new_i64();
11025 TCGv_i64 fp2
= tcg_temp_new_i64();
11026 gen_load_fpr64(ctx
, fp0
, fd
);
11027 gen_load_fpr64(ctx
, fp1
, ft
);
11028 gen_load_fpr64(ctx
, fp2
, fs
);
11032 tcg_gen_andi_i64(fp0
, fp0
, 1);
11033 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
11036 tcg_gen_andi_i64(fp1
, fp1
, 1);
11037 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
11040 tcg_gen_andi_i64(fp1
, fp1
, 1);
11041 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
11044 MIPS_INVAL("gen_sel_d");
11045 generate_exception_end(ctx
, EXCP_RI
);
11049 gen_store_fpr64(ctx
, fp0
, fd
);
11050 tcg_temp_free_i64(fp2
);
11051 tcg_temp_free_i64(fp1
);
11052 tcg_temp_free_i64(fp0
);
11053 tcg_temp_free_i64(t1
);
11056 static void gen_farith(DisasContext
*ctx
, enum fopcode op1
,
11057 int ft
, int fs
, int fd
, int cc
)
11059 uint32_t func
= ctx
->opcode
& 0x3f;
11063 TCGv_i32 fp0
= tcg_temp_new_i32();
11064 TCGv_i32 fp1
= tcg_temp_new_i32();
11066 gen_load_fpr32(ctx
, fp0
, fs
);
11067 gen_load_fpr32(ctx
, fp1
, ft
);
11068 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
11069 tcg_temp_free_i32(fp1
);
11070 gen_store_fpr32(ctx
, fp0
, fd
);
11071 tcg_temp_free_i32(fp0
);
11076 TCGv_i32 fp0
= tcg_temp_new_i32();
11077 TCGv_i32 fp1
= tcg_temp_new_i32();
11079 gen_load_fpr32(ctx
, fp0
, fs
);
11080 gen_load_fpr32(ctx
, fp1
, ft
);
11081 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
11082 tcg_temp_free_i32(fp1
);
11083 gen_store_fpr32(ctx
, fp0
, fd
);
11084 tcg_temp_free_i32(fp0
);
11089 TCGv_i32 fp0
= tcg_temp_new_i32();
11090 TCGv_i32 fp1
= tcg_temp_new_i32();
11092 gen_load_fpr32(ctx
, fp0
, fs
);
11093 gen_load_fpr32(ctx
, fp1
, ft
);
11094 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
11095 tcg_temp_free_i32(fp1
);
11096 gen_store_fpr32(ctx
, fp0
, fd
);
11097 tcg_temp_free_i32(fp0
);
11102 TCGv_i32 fp0
= tcg_temp_new_i32();
11103 TCGv_i32 fp1
= tcg_temp_new_i32();
11105 gen_load_fpr32(ctx
, fp0
, fs
);
11106 gen_load_fpr32(ctx
, fp1
, ft
);
11107 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
11108 tcg_temp_free_i32(fp1
);
11109 gen_store_fpr32(ctx
, fp0
, fd
);
11110 tcg_temp_free_i32(fp0
);
11115 TCGv_i32 fp0
= tcg_temp_new_i32();
11117 gen_load_fpr32(ctx
, fp0
, fs
);
11118 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
11119 gen_store_fpr32(ctx
, fp0
, fd
);
11120 tcg_temp_free_i32(fp0
);
11125 TCGv_i32 fp0
= tcg_temp_new_i32();
11127 gen_load_fpr32(ctx
, fp0
, fs
);
11128 if (ctx
->abs2008
) {
11129 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
11131 gen_helper_float_abs_s(fp0
, fp0
);
11133 gen_store_fpr32(ctx
, fp0
, fd
);
11134 tcg_temp_free_i32(fp0
);
11139 TCGv_i32 fp0
= tcg_temp_new_i32();
11141 gen_load_fpr32(ctx
, fp0
, fs
);
11142 gen_store_fpr32(ctx
, fp0
, fd
);
11143 tcg_temp_free_i32(fp0
);
11148 TCGv_i32 fp0
= tcg_temp_new_i32();
11150 gen_load_fpr32(ctx
, fp0
, fs
);
11151 if (ctx
->abs2008
) {
11152 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
11154 gen_helper_float_chs_s(fp0
, fp0
);
11156 gen_store_fpr32(ctx
, fp0
, fd
);
11157 tcg_temp_free_i32(fp0
);
11160 case OPC_ROUND_L_S
:
11161 check_cp1_64bitmode(ctx
);
11163 TCGv_i32 fp32
= tcg_temp_new_i32();
11164 TCGv_i64 fp64
= tcg_temp_new_i64();
11166 gen_load_fpr32(ctx
, fp32
, fs
);
11167 if (ctx
->nan2008
) {
11168 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
11170 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
11172 tcg_temp_free_i32(fp32
);
11173 gen_store_fpr64(ctx
, fp64
, fd
);
11174 tcg_temp_free_i64(fp64
);
11177 case OPC_TRUNC_L_S
:
11178 check_cp1_64bitmode(ctx
);
11180 TCGv_i32 fp32
= tcg_temp_new_i32();
11181 TCGv_i64 fp64
= tcg_temp_new_i64();
11183 gen_load_fpr32(ctx
, fp32
, fs
);
11184 if (ctx
->nan2008
) {
11185 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
11187 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
11189 tcg_temp_free_i32(fp32
);
11190 gen_store_fpr64(ctx
, fp64
, fd
);
11191 tcg_temp_free_i64(fp64
);
11195 check_cp1_64bitmode(ctx
);
11197 TCGv_i32 fp32
= tcg_temp_new_i32();
11198 TCGv_i64 fp64
= tcg_temp_new_i64();
11200 gen_load_fpr32(ctx
, fp32
, fs
);
11201 if (ctx
->nan2008
) {
11202 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
11204 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
11206 tcg_temp_free_i32(fp32
);
11207 gen_store_fpr64(ctx
, fp64
, fd
);
11208 tcg_temp_free_i64(fp64
);
11211 case OPC_FLOOR_L_S
:
11212 check_cp1_64bitmode(ctx
);
11214 TCGv_i32 fp32
= tcg_temp_new_i32();
11215 TCGv_i64 fp64
= tcg_temp_new_i64();
11217 gen_load_fpr32(ctx
, fp32
, fs
);
11218 if (ctx
->nan2008
) {
11219 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
11221 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
11223 tcg_temp_free_i32(fp32
);
11224 gen_store_fpr64(ctx
, fp64
, fd
);
11225 tcg_temp_free_i64(fp64
);
11228 case OPC_ROUND_W_S
:
11230 TCGv_i32 fp0
= tcg_temp_new_i32();
11232 gen_load_fpr32(ctx
, fp0
, fs
);
11233 if (ctx
->nan2008
) {
11234 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
11236 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
11238 gen_store_fpr32(ctx
, fp0
, fd
);
11239 tcg_temp_free_i32(fp0
);
11242 case OPC_TRUNC_W_S
:
11244 TCGv_i32 fp0
= tcg_temp_new_i32();
11246 gen_load_fpr32(ctx
, fp0
, fs
);
11247 if (ctx
->nan2008
) {
11248 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
11250 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
11252 gen_store_fpr32(ctx
, fp0
, fd
);
11253 tcg_temp_free_i32(fp0
);
11258 TCGv_i32 fp0
= tcg_temp_new_i32();
11260 gen_load_fpr32(ctx
, fp0
, fs
);
11261 if (ctx
->nan2008
) {
11262 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
11264 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
11266 gen_store_fpr32(ctx
, fp0
, fd
);
11267 tcg_temp_free_i32(fp0
);
11270 case OPC_FLOOR_W_S
:
11272 TCGv_i32 fp0
= tcg_temp_new_i32();
11274 gen_load_fpr32(ctx
, fp0
, fs
);
11275 if (ctx
->nan2008
) {
11276 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
11278 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
11280 gen_store_fpr32(ctx
, fp0
, fd
);
11281 tcg_temp_free_i32(fp0
);
11285 check_insn(ctx
, ISA_MIPS32R6
);
11286 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11289 check_insn(ctx
, ISA_MIPS32R6
);
11290 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11293 check_insn(ctx
, ISA_MIPS32R6
);
11294 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
11297 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11298 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11301 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11303 TCGLabel
*l1
= gen_new_label();
11307 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11309 fp0
= tcg_temp_new_i32();
11310 gen_load_fpr32(ctx
, fp0
, fs
);
11311 gen_store_fpr32(ctx
, fp0
, fd
);
11312 tcg_temp_free_i32(fp0
);
11317 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11319 TCGLabel
*l1
= gen_new_label();
11323 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11324 fp0
= tcg_temp_new_i32();
11325 gen_load_fpr32(ctx
, fp0
, fs
);
11326 gen_store_fpr32(ctx
, fp0
, fd
);
11327 tcg_temp_free_i32(fp0
);
11334 TCGv_i32 fp0
= tcg_temp_new_i32();
11336 gen_load_fpr32(ctx
, fp0
, fs
);
11337 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
11338 gen_store_fpr32(ctx
, fp0
, fd
);
11339 tcg_temp_free_i32(fp0
);
11344 TCGv_i32 fp0
= tcg_temp_new_i32();
11346 gen_load_fpr32(ctx
, fp0
, fs
);
11347 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
11348 gen_store_fpr32(ctx
, fp0
, fd
);
11349 tcg_temp_free_i32(fp0
);
11353 check_insn(ctx
, ISA_MIPS32R6
);
11355 TCGv_i32 fp0
= tcg_temp_new_i32();
11356 TCGv_i32 fp1
= tcg_temp_new_i32();
11357 TCGv_i32 fp2
= tcg_temp_new_i32();
11358 gen_load_fpr32(ctx
, fp0
, fs
);
11359 gen_load_fpr32(ctx
, fp1
, ft
);
11360 gen_load_fpr32(ctx
, fp2
, fd
);
11361 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11362 gen_store_fpr32(ctx
, fp2
, fd
);
11363 tcg_temp_free_i32(fp2
);
11364 tcg_temp_free_i32(fp1
);
11365 tcg_temp_free_i32(fp0
);
11369 check_insn(ctx
, ISA_MIPS32R6
);
11371 TCGv_i32 fp0
= tcg_temp_new_i32();
11372 TCGv_i32 fp1
= tcg_temp_new_i32();
11373 TCGv_i32 fp2
= tcg_temp_new_i32();
11374 gen_load_fpr32(ctx
, fp0
, fs
);
11375 gen_load_fpr32(ctx
, fp1
, ft
);
11376 gen_load_fpr32(ctx
, fp2
, fd
);
11377 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11378 gen_store_fpr32(ctx
, fp2
, fd
);
11379 tcg_temp_free_i32(fp2
);
11380 tcg_temp_free_i32(fp1
);
11381 tcg_temp_free_i32(fp0
);
11385 check_insn(ctx
, ISA_MIPS32R6
);
11387 TCGv_i32 fp0
= tcg_temp_new_i32();
11388 gen_load_fpr32(ctx
, fp0
, fs
);
11389 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
11390 gen_store_fpr32(ctx
, fp0
, fd
);
11391 tcg_temp_free_i32(fp0
);
11395 check_insn(ctx
, ISA_MIPS32R6
);
11397 TCGv_i32 fp0
= tcg_temp_new_i32();
11398 gen_load_fpr32(ctx
, fp0
, fs
);
11399 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
11400 gen_store_fpr32(ctx
, fp0
, fd
);
11401 tcg_temp_free_i32(fp0
);
11404 case OPC_MIN_S
: /* OPC_RECIP2_S */
11405 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11407 TCGv_i32 fp0
= tcg_temp_new_i32();
11408 TCGv_i32 fp1
= tcg_temp_new_i32();
11409 TCGv_i32 fp2
= tcg_temp_new_i32();
11410 gen_load_fpr32(ctx
, fp0
, fs
);
11411 gen_load_fpr32(ctx
, fp1
, ft
);
11412 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
11413 gen_store_fpr32(ctx
, fp2
, fd
);
11414 tcg_temp_free_i32(fp2
);
11415 tcg_temp_free_i32(fp1
);
11416 tcg_temp_free_i32(fp0
);
11419 check_cp1_64bitmode(ctx
);
11421 TCGv_i32 fp0
= tcg_temp_new_i32();
11422 TCGv_i32 fp1
= tcg_temp_new_i32();
11424 gen_load_fpr32(ctx
, fp0
, fs
);
11425 gen_load_fpr32(ctx
, fp1
, ft
);
11426 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
11427 tcg_temp_free_i32(fp1
);
11428 gen_store_fpr32(ctx
, fp0
, fd
);
11429 tcg_temp_free_i32(fp0
);
11433 case OPC_MINA_S
: /* OPC_RECIP1_S */
11434 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11436 TCGv_i32 fp0
= tcg_temp_new_i32();
11437 TCGv_i32 fp1
= tcg_temp_new_i32();
11438 TCGv_i32 fp2
= tcg_temp_new_i32();
11439 gen_load_fpr32(ctx
, fp0
, fs
);
11440 gen_load_fpr32(ctx
, fp1
, ft
);
11441 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
11442 gen_store_fpr32(ctx
, fp2
, fd
);
11443 tcg_temp_free_i32(fp2
);
11444 tcg_temp_free_i32(fp1
);
11445 tcg_temp_free_i32(fp0
);
11448 check_cp1_64bitmode(ctx
);
11450 TCGv_i32 fp0
= tcg_temp_new_i32();
11452 gen_load_fpr32(ctx
, fp0
, fs
);
11453 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
11454 gen_store_fpr32(ctx
, fp0
, fd
);
11455 tcg_temp_free_i32(fp0
);
11459 case OPC_MAX_S
: /* OPC_RSQRT1_S */
11460 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11462 TCGv_i32 fp0
= tcg_temp_new_i32();
11463 TCGv_i32 fp1
= tcg_temp_new_i32();
11464 gen_load_fpr32(ctx
, fp0
, fs
);
11465 gen_load_fpr32(ctx
, fp1
, ft
);
11466 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
11467 gen_store_fpr32(ctx
, fp1
, fd
);
11468 tcg_temp_free_i32(fp1
);
11469 tcg_temp_free_i32(fp0
);
11472 check_cp1_64bitmode(ctx
);
11474 TCGv_i32 fp0
= tcg_temp_new_i32();
11476 gen_load_fpr32(ctx
, fp0
, fs
);
11477 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
11478 gen_store_fpr32(ctx
, fp0
, fd
);
11479 tcg_temp_free_i32(fp0
);
11483 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
11484 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11486 TCGv_i32 fp0
= tcg_temp_new_i32();
11487 TCGv_i32 fp1
= tcg_temp_new_i32();
11488 gen_load_fpr32(ctx
, fp0
, fs
);
11489 gen_load_fpr32(ctx
, fp1
, ft
);
11490 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
11491 gen_store_fpr32(ctx
, fp1
, fd
);
11492 tcg_temp_free_i32(fp1
);
11493 tcg_temp_free_i32(fp0
);
11496 check_cp1_64bitmode(ctx
);
11498 TCGv_i32 fp0
= tcg_temp_new_i32();
11499 TCGv_i32 fp1
= tcg_temp_new_i32();
11501 gen_load_fpr32(ctx
, fp0
, fs
);
11502 gen_load_fpr32(ctx
, fp1
, ft
);
11503 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
11504 tcg_temp_free_i32(fp1
);
11505 gen_store_fpr32(ctx
, fp0
, fd
);
11506 tcg_temp_free_i32(fp0
);
11511 check_cp1_registers(ctx
, fd
);
11513 TCGv_i32 fp32
= tcg_temp_new_i32();
11514 TCGv_i64 fp64
= tcg_temp_new_i64();
11516 gen_load_fpr32(ctx
, fp32
, fs
);
11517 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
11518 tcg_temp_free_i32(fp32
);
11519 gen_store_fpr64(ctx
, fp64
, fd
);
11520 tcg_temp_free_i64(fp64
);
11525 TCGv_i32 fp0
= tcg_temp_new_i32();
11527 gen_load_fpr32(ctx
, fp0
, fs
);
11528 if (ctx
->nan2008
) {
11529 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
11531 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
11533 gen_store_fpr32(ctx
, fp0
, fd
);
11534 tcg_temp_free_i32(fp0
);
11538 check_cp1_64bitmode(ctx
);
11540 TCGv_i32 fp32
= tcg_temp_new_i32();
11541 TCGv_i64 fp64
= tcg_temp_new_i64();
11543 gen_load_fpr32(ctx
, fp32
, fs
);
11544 if (ctx
->nan2008
) {
11545 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
11547 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
11549 tcg_temp_free_i32(fp32
);
11550 gen_store_fpr64(ctx
, fp64
, fd
);
11551 tcg_temp_free_i64(fp64
);
11557 TCGv_i64 fp64
= tcg_temp_new_i64();
11558 TCGv_i32 fp32_0
= tcg_temp_new_i32();
11559 TCGv_i32 fp32_1
= tcg_temp_new_i32();
11561 gen_load_fpr32(ctx
, fp32_0
, fs
);
11562 gen_load_fpr32(ctx
, fp32_1
, ft
);
11563 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
11564 tcg_temp_free_i32(fp32_1
);
11565 tcg_temp_free_i32(fp32_0
);
11566 gen_store_fpr64(ctx
, fp64
, fd
);
11567 tcg_temp_free_i64(fp64
);
11573 case OPC_CMP_UEQ_S
:
11574 case OPC_CMP_OLT_S
:
11575 case OPC_CMP_ULT_S
:
11576 case OPC_CMP_OLE_S
:
11577 case OPC_CMP_ULE_S
:
11579 case OPC_CMP_NGLE_S
:
11580 case OPC_CMP_SEQ_S
:
11581 case OPC_CMP_NGL_S
:
11583 case OPC_CMP_NGE_S
:
11585 case OPC_CMP_NGT_S
:
11586 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11587 if (ctx
->opcode
& (1 << 6)) {
11588 gen_cmpabs_s(ctx
, func
- 48, ft
, fs
, cc
);
11590 gen_cmp_s(ctx
, func
- 48, ft
, fs
, cc
);
11594 check_cp1_registers(ctx
, fs
| ft
| fd
);
11596 TCGv_i64 fp0
= tcg_temp_new_i64();
11597 TCGv_i64 fp1
= tcg_temp_new_i64();
11599 gen_load_fpr64(ctx
, fp0
, fs
);
11600 gen_load_fpr64(ctx
, fp1
, ft
);
11601 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
11602 tcg_temp_free_i64(fp1
);
11603 gen_store_fpr64(ctx
, fp0
, fd
);
11604 tcg_temp_free_i64(fp0
);
11608 check_cp1_registers(ctx
, fs
| ft
| fd
);
11610 TCGv_i64 fp0
= tcg_temp_new_i64();
11611 TCGv_i64 fp1
= tcg_temp_new_i64();
11613 gen_load_fpr64(ctx
, fp0
, fs
);
11614 gen_load_fpr64(ctx
, fp1
, ft
);
11615 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
11616 tcg_temp_free_i64(fp1
);
11617 gen_store_fpr64(ctx
, fp0
, fd
);
11618 tcg_temp_free_i64(fp0
);
11622 check_cp1_registers(ctx
, fs
| ft
| fd
);
11624 TCGv_i64 fp0
= tcg_temp_new_i64();
11625 TCGv_i64 fp1
= tcg_temp_new_i64();
11627 gen_load_fpr64(ctx
, fp0
, fs
);
11628 gen_load_fpr64(ctx
, fp1
, ft
);
11629 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
11630 tcg_temp_free_i64(fp1
);
11631 gen_store_fpr64(ctx
, fp0
, fd
);
11632 tcg_temp_free_i64(fp0
);
11636 check_cp1_registers(ctx
, fs
| ft
| fd
);
11638 TCGv_i64 fp0
= tcg_temp_new_i64();
11639 TCGv_i64 fp1
= tcg_temp_new_i64();
11641 gen_load_fpr64(ctx
, fp0
, fs
);
11642 gen_load_fpr64(ctx
, fp1
, ft
);
11643 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
11644 tcg_temp_free_i64(fp1
);
11645 gen_store_fpr64(ctx
, fp0
, fd
);
11646 tcg_temp_free_i64(fp0
);
11650 check_cp1_registers(ctx
, fs
| fd
);
11652 TCGv_i64 fp0
= tcg_temp_new_i64();
11654 gen_load_fpr64(ctx
, fp0
, fs
);
11655 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
11656 gen_store_fpr64(ctx
, fp0
, fd
);
11657 tcg_temp_free_i64(fp0
);
11661 check_cp1_registers(ctx
, fs
| fd
);
11663 TCGv_i64 fp0
= tcg_temp_new_i64();
11665 gen_load_fpr64(ctx
, fp0
, fs
);
11666 if (ctx
->abs2008
) {
11667 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
11669 gen_helper_float_abs_d(fp0
, fp0
);
11671 gen_store_fpr64(ctx
, fp0
, fd
);
11672 tcg_temp_free_i64(fp0
);
11676 check_cp1_registers(ctx
, fs
| fd
);
11678 TCGv_i64 fp0
= tcg_temp_new_i64();
11680 gen_load_fpr64(ctx
, fp0
, fs
);
11681 gen_store_fpr64(ctx
, fp0
, fd
);
11682 tcg_temp_free_i64(fp0
);
11686 check_cp1_registers(ctx
, fs
| fd
);
11688 TCGv_i64 fp0
= tcg_temp_new_i64();
11690 gen_load_fpr64(ctx
, fp0
, fs
);
11691 if (ctx
->abs2008
) {
11692 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
11694 gen_helper_float_chs_d(fp0
, fp0
);
11696 gen_store_fpr64(ctx
, fp0
, fd
);
11697 tcg_temp_free_i64(fp0
);
11700 case OPC_ROUND_L_D
:
11701 check_cp1_64bitmode(ctx
);
11703 TCGv_i64 fp0
= tcg_temp_new_i64();
11705 gen_load_fpr64(ctx
, fp0
, fs
);
11706 if (ctx
->nan2008
) {
11707 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
11709 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
11711 gen_store_fpr64(ctx
, fp0
, fd
);
11712 tcg_temp_free_i64(fp0
);
11715 case OPC_TRUNC_L_D
:
11716 check_cp1_64bitmode(ctx
);
11718 TCGv_i64 fp0
= tcg_temp_new_i64();
11720 gen_load_fpr64(ctx
, fp0
, fs
);
11721 if (ctx
->nan2008
) {
11722 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
11724 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
11726 gen_store_fpr64(ctx
, fp0
, fd
);
11727 tcg_temp_free_i64(fp0
);
11731 check_cp1_64bitmode(ctx
);
11733 TCGv_i64 fp0
= tcg_temp_new_i64();
11735 gen_load_fpr64(ctx
, fp0
, fs
);
11736 if (ctx
->nan2008
) {
11737 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
11739 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
11741 gen_store_fpr64(ctx
, fp0
, fd
);
11742 tcg_temp_free_i64(fp0
);
11745 case OPC_FLOOR_L_D
:
11746 check_cp1_64bitmode(ctx
);
11748 TCGv_i64 fp0
= tcg_temp_new_i64();
11750 gen_load_fpr64(ctx
, fp0
, fs
);
11751 if (ctx
->nan2008
) {
11752 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
11754 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
11756 gen_store_fpr64(ctx
, fp0
, fd
);
11757 tcg_temp_free_i64(fp0
);
11760 case OPC_ROUND_W_D
:
11761 check_cp1_registers(ctx
, fs
);
11763 TCGv_i32 fp32
= tcg_temp_new_i32();
11764 TCGv_i64 fp64
= tcg_temp_new_i64();
11766 gen_load_fpr64(ctx
, fp64
, fs
);
11767 if (ctx
->nan2008
) {
11768 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
11770 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
11772 tcg_temp_free_i64(fp64
);
11773 gen_store_fpr32(ctx
, fp32
, fd
);
11774 tcg_temp_free_i32(fp32
);
11777 case OPC_TRUNC_W_D
:
11778 check_cp1_registers(ctx
, fs
);
11780 TCGv_i32 fp32
= tcg_temp_new_i32();
11781 TCGv_i64 fp64
= tcg_temp_new_i64();
11783 gen_load_fpr64(ctx
, fp64
, fs
);
11784 if (ctx
->nan2008
) {
11785 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
11787 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
11789 tcg_temp_free_i64(fp64
);
11790 gen_store_fpr32(ctx
, fp32
, fd
);
11791 tcg_temp_free_i32(fp32
);
11795 check_cp1_registers(ctx
, fs
);
11797 TCGv_i32 fp32
= tcg_temp_new_i32();
11798 TCGv_i64 fp64
= tcg_temp_new_i64();
11800 gen_load_fpr64(ctx
, fp64
, fs
);
11801 if (ctx
->nan2008
) {
11802 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
11804 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
11806 tcg_temp_free_i64(fp64
);
11807 gen_store_fpr32(ctx
, fp32
, fd
);
11808 tcg_temp_free_i32(fp32
);
11811 case OPC_FLOOR_W_D
:
11812 check_cp1_registers(ctx
, fs
);
11814 TCGv_i32 fp32
= tcg_temp_new_i32();
11815 TCGv_i64 fp64
= tcg_temp_new_i64();
11817 gen_load_fpr64(ctx
, fp64
, fs
);
11818 if (ctx
->nan2008
) {
11819 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
11821 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
11823 tcg_temp_free_i64(fp64
);
11824 gen_store_fpr32(ctx
, fp32
, fd
);
11825 tcg_temp_free_i32(fp32
);
11829 check_insn(ctx
, ISA_MIPS32R6
);
11830 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11833 check_insn(ctx
, ISA_MIPS32R6
);
11834 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11837 check_insn(ctx
, ISA_MIPS32R6
);
11838 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
11841 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11842 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
11845 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11847 TCGLabel
*l1
= gen_new_label();
11851 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
11853 fp0
= tcg_temp_new_i64();
11854 gen_load_fpr64(ctx
, fp0
, fs
);
11855 gen_store_fpr64(ctx
, fp0
, fd
);
11856 tcg_temp_free_i64(fp0
);
11861 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
11863 TCGLabel
*l1
= gen_new_label();
11867 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
11868 fp0
= tcg_temp_new_i64();
11869 gen_load_fpr64(ctx
, fp0
, fs
);
11870 gen_store_fpr64(ctx
, fp0
, fd
);
11871 tcg_temp_free_i64(fp0
);
11877 check_cp1_registers(ctx
, fs
| fd
);
11879 TCGv_i64 fp0
= tcg_temp_new_i64();
11881 gen_load_fpr64(ctx
, fp0
, fs
);
11882 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
11883 gen_store_fpr64(ctx
, fp0
, fd
);
11884 tcg_temp_free_i64(fp0
);
11888 check_cp1_registers(ctx
, fs
| fd
);
11890 TCGv_i64 fp0
= tcg_temp_new_i64();
11892 gen_load_fpr64(ctx
, fp0
, fs
);
11893 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
11894 gen_store_fpr64(ctx
, fp0
, fd
);
11895 tcg_temp_free_i64(fp0
);
11899 check_insn(ctx
, ISA_MIPS32R6
);
11901 TCGv_i64 fp0
= tcg_temp_new_i64();
11902 TCGv_i64 fp1
= tcg_temp_new_i64();
11903 TCGv_i64 fp2
= tcg_temp_new_i64();
11904 gen_load_fpr64(ctx
, fp0
, fs
);
11905 gen_load_fpr64(ctx
, fp1
, ft
);
11906 gen_load_fpr64(ctx
, fp2
, fd
);
11907 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11908 gen_store_fpr64(ctx
, fp2
, fd
);
11909 tcg_temp_free_i64(fp2
);
11910 tcg_temp_free_i64(fp1
);
11911 tcg_temp_free_i64(fp0
);
11915 check_insn(ctx
, ISA_MIPS32R6
);
11917 TCGv_i64 fp0
= tcg_temp_new_i64();
11918 TCGv_i64 fp1
= tcg_temp_new_i64();
11919 TCGv_i64 fp2
= tcg_temp_new_i64();
11920 gen_load_fpr64(ctx
, fp0
, fs
);
11921 gen_load_fpr64(ctx
, fp1
, ft
);
11922 gen_load_fpr64(ctx
, fp2
, fd
);
11923 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
11924 gen_store_fpr64(ctx
, fp2
, fd
);
11925 tcg_temp_free_i64(fp2
);
11926 tcg_temp_free_i64(fp1
);
11927 tcg_temp_free_i64(fp0
);
11931 check_insn(ctx
, ISA_MIPS32R6
);
11933 TCGv_i64 fp0
= tcg_temp_new_i64();
11934 gen_load_fpr64(ctx
, fp0
, fs
);
11935 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
11936 gen_store_fpr64(ctx
, fp0
, fd
);
11937 tcg_temp_free_i64(fp0
);
11941 check_insn(ctx
, ISA_MIPS32R6
);
11943 TCGv_i64 fp0
= tcg_temp_new_i64();
11944 gen_load_fpr64(ctx
, fp0
, fs
);
11945 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
11946 gen_store_fpr64(ctx
, fp0
, fd
);
11947 tcg_temp_free_i64(fp0
);
11950 case OPC_MIN_D
: /* OPC_RECIP2_D */
11951 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11953 TCGv_i64 fp0
= tcg_temp_new_i64();
11954 TCGv_i64 fp1
= tcg_temp_new_i64();
11955 gen_load_fpr64(ctx
, fp0
, fs
);
11956 gen_load_fpr64(ctx
, fp1
, ft
);
11957 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
11958 gen_store_fpr64(ctx
, fp1
, fd
);
11959 tcg_temp_free_i64(fp1
);
11960 tcg_temp_free_i64(fp0
);
11963 check_cp1_64bitmode(ctx
);
11965 TCGv_i64 fp0
= tcg_temp_new_i64();
11966 TCGv_i64 fp1
= tcg_temp_new_i64();
11968 gen_load_fpr64(ctx
, fp0
, fs
);
11969 gen_load_fpr64(ctx
, fp1
, ft
);
11970 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
11971 tcg_temp_free_i64(fp1
);
11972 gen_store_fpr64(ctx
, fp0
, fd
);
11973 tcg_temp_free_i64(fp0
);
11977 case OPC_MINA_D
: /* OPC_RECIP1_D */
11978 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
11980 TCGv_i64 fp0
= tcg_temp_new_i64();
11981 TCGv_i64 fp1
= tcg_temp_new_i64();
11982 gen_load_fpr64(ctx
, fp0
, fs
);
11983 gen_load_fpr64(ctx
, fp1
, ft
);
11984 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
11985 gen_store_fpr64(ctx
, fp1
, fd
);
11986 tcg_temp_free_i64(fp1
);
11987 tcg_temp_free_i64(fp0
);
11990 check_cp1_64bitmode(ctx
);
11992 TCGv_i64 fp0
= tcg_temp_new_i64();
11994 gen_load_fpr64(ctx
, fp0
, fs
);
11995 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
11996 gen_store_fpr64(ctx
, fp0
, fd
);
11997 tcg_temp_free_i64(fp0
);
12001 case OPC_MAX_D
: /* OPC_RSQRT1_D */
12002 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12004 TCGv_i64 fp0
= tcg_temp_new_i64();
12005 TCGv_i64 fp1
= tcg_temp_new_i64();
12006 gen_load_fpr64(ctx
, fp0
, fs
);
12007 gen_load_fpr64(ctx
, fp1
, ft
);
12008 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
12009 gen_store_fpr64(ctx
, fp1
, fd
);
12010 tcg_temp_free_i64(fp1
);
12011 tcg_temp_free_i64(fp0
);
12014 check_cp1_64bitmode(ctx
);
12016 TCGv_i64 fp0
= tcg_temp_new_i64();
12018 gen_load_fpr64(ctx
, fp0
, fs
);
12019 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
12020 gen_store_fpr64(ctx
, fp0
, fd
);
12021 tcg_temp_free_i64(fp0
);
12025 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
12026 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
12028 TCGv_i64 fp0
= tcg_temp_new_i64();
12029 TCGv_i64 fp1
= tcg_temp_new_i64();
12030 gen_load_fpr64(ctx
, fp0
, fs
);
12031 gen_load_fpr64(ctx
, fp1
, ft
);
12032 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
12033 gen_store_fpr64(ctx
, fp1
, fd
);
12034 tcg_temp_free_i64(fp1
);
12035 tcg_temp_free_i64(fp0
);
12038 check_cp1_64bitmode(ctx
);
12040 TCGv_i64 fp0
= tcg_temp_new_i64();
12041 TCGv_i64 fp1
= tcg_temp_new_i64();
12043 gen_load_fpr64(ctx
, fp0
, fs
);
12044 gen_load_fpr64(ctx
, fp1
, ft
);
12045 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
12046 tcg_temp_free_i64(fp1
);
12047 gen_store_fpr64(ctx
, fp0
, fd
);
12048 tcg_temp_free_i64(fp0
);
12055 case OPC_CMP_UEQ_D
:
12056 case OPC_CMP_OLT_D
:
12057 case OPC_CMP_ULT_D
:
12058 case OPC_CMP_OLE_D
:
12059 case OPC_CMP_ULE_D
:
12061 case OPC_CMP_NGLE_D
:
12062 case OPC_CMP_SEQ_D
:
12063 case OPC_CMP_NGL_D
:
12065 case OPC_CMP_NGE_D
:
12067 case OPC_CMP_NGT_D
:
12068 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
12069 if (ctx
->opcode
& (1 << 6)) {
12070 gen_cmpabs_d(ctx
, func
- 48, ft
, fs
, cc
);
12072 gen_cmp_d(ctx
, func
- 48, ft
, fs
, cc
);
12076 check_cp1_registers(ctx
, fs
);
12078 TCGv_i32 fp32
= tcg_temp_new_i32();
12079 TCGv_i64 fp64
= tcg_temp_new_i64();
12081 gen_load_fpr64(ctx
, fp64
, fs
);
12082 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
12083 tcg_temp_free_i64(fp64
);
12084 gen_store_fpr32(ctx
, fp32
, fd
);
12085 tcg_temp_free_i32(fp32
);
12089 check_cp1_registers(ctx
, fs
);
12091 TCGv_i32 fp32
= tcg_temp_new_i32();
12092 TCGv_i64 fp64
= tcg_temp_new_i64();
12094 gen_load_fpr64(ctx
, fp64
, fs
);
12095 if (ctx
->nan2008
) {
12096 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
12098 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
12100 tcg_temp_free_i64(fp64
);
12101 gen_store_fpr32(ctx
, fp32
, fd
);
12102 tcg_temp_free_i32(fp32
);
12106 check_cp1_64bitmode(ctx
);
12108 TCGv_i64 fp0
= tcg_temp_new_i64();
12110 gen_load_fpr64(ctx
, fp0
, fs
);
12111 if (ctx
->nan2008
) {
12112 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
12114 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
12116 gen_store_fpr64(ctx
, fp0
, fd
);
12117 tcg_temp_free_i64(fp0
);
12122 TCGv_i32 fp0
= tcg_temp_new_i32();
12124 gen_load_fpr32(ctx
, fp0
, fs
);
12125 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
12126 gen_store_fpr32(ctx
, fp0
, fd
);
12127 tcg_temp_free_i32(fp0
);
12131 check_cp1_registers(ctx
, fd
);
12133 TCGv_i32 fp32
= tcg_temp_new_i32();
12134 TCGv_i64 fp64
= tcg_temp_new_i64();
12136 gen_load_fpr32(ctx
, fp32
, fs
);
12137 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
12138 tcg_temp_free_i32(fp32
);
12139 gen_store_fpr64(ctx
, fp64
, fd
);
12140 tcg_temp_free_i64(fp64
);
12144 check_cp1_64bitmode(ctx
);
12146 TCGv_i32 fp32
= tcg_temp_new_i32();
12147 TCGv_i64 fp64
= tcg_temp_new_i64();
12149 gen_load_fpr64(ctx
, fp64
, fs
);
12150 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
12151 tcg_temp_free_i64(fp64
);
12152 gen_store_fpr32(ctx
, fp32
, fd
);
12153 tcg_temp_free_i32(fp32
);
12157 check_cp1_64bitmode(ctx
);
12159 TCGv_i64 fp0
= tcg_temp_new_i64();
12161 gen_load_fpr64(ctx
, fp0
, fs
);
12162 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
12163 gen_store_fpr64(ctx
, fp0
, fd
);
12164 tcg_temp_free_i64(fp0
);
12167 case OPC_CVT_PS_PW
:
12170 TCGv_i64 fp0
= tcg_temp_new_i64();
12172 gen_load_fpr64(ctx
, fp0
, fs
);
12173 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
12174 gen_store_fpr64(ctx
, fp0
, fd
);
12175 tcg_temp_free_i64(fp0
);
12181 TCGv_i64 fp0
= tcg_temp_new_i64();
12182 TCGv_i64 fp1
= tcg_temp_new_i64();
12184 gen_load_fpr64(ctx
, fp0
, fs
);
12185 gen_load_fpr64(ctx
, fp1
, ft
);
12186 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
12187 tcg_temp_free_i64(fp1
);
12188 gen_store_fpr64(ctx
, fp0
, fd
);
12189 tcg_temp_free_i64(fp0
);
12195 TCGv_i64 fp0
= tcg_temp_new_i64();
12196 TCGv_i64 fp1
= tcg_temp_new_i64();
12198 gen_load_fpr64(ctx
, fp0
, fs
);
12199 gen_load_fpr64(ctx
, fp1
, ft
);
12200 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
12201 tcg_temp_free_i64(fp1
);
12202 gen_store_fpr64(ctx
, fp0
, fd
);
12203 tcg_temp_free_i64(fp0
);
12209 TCGv_i64 fp0
= tcg_temp_new_i64();
12210 TCGv_i64 fp1
= tcg_temp_new_i64();
12212 gen_load_fpr64(ctx
, fp0
, fs
);
12213 gen_load_fpr64(ctx
, fp1
, ft
);
12214 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
12215 tcg_temp_free_i64(fp1
);
12216 gen_store_fpr64(ctx
, fp0
, fd
);
12217 tcg_temp_free_i64(fp0
);
12223 TCGv_i64 fp0
= tcg_temp_new_i64();
12225 gen_load_fpr64(ctx
, fp0
, fs
);
12226 gen_helper_float_abs_ps(fp0
, fp0
);
12227 gen_store_fpr64(ctx
, fp0
, fd
);
12228 tcg_temp_free_i64(fp0
);
12234 TCGv_i64 fp0
= tcg_temp_new_i64();
12236 gen_load_fpr64(ctx
, fp0
, fs
);
12237 gen_store_fpr64(ctx
, fp0
, fd
);
12238 tcg_temp_free_i64(fp0
);
12244 TCGv_i64 fp0
= tcg_temp_new_i64();
12246 gen_load_fpr64(ctx
, fp0
, fs
);
12247 gen_helper_float_chs_ps(fp0
, fp0
);
12248 gen_store_fpr64(ctx
, fp0
, fd
);
12249 tcg_temp_free_i64(fp0
);
12254 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
12259 TCGLabel
*l1
= gen_new_label();
12263 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
12265 fp0
= tcg_temp_new_i64();
12266 gen_load_fpr64(ctx
, fp0
, fs
);
12267 gen_store_fpr64(ctx
, fp0
, fd
);
12268 tcg_temp_free_i64(fp0
);
12275 TCGLabel
*l1
= gen_new_label();
12279 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
12280 fp0
= tcg_temp_new_i64();
12281 gen_load_fpr64(ctx
, fp0
, fs
);
12282 gen_store_fpr64(ctx
, fp0
, fd
);
12283 tcg_temp_free_i64(fp0
);
12291 TCGv_i64 fp0
= tcg_temp_new_i64();
12292 TCGv_i64 fp1
= tcg_temp_new_i64();
12294 gen_load_fpr64(ctx
, fp0
, ft
);
12295 gen_load_fpr64(ctx
, fp1
, fs
);
12296 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
12297 tcg_temp_free_i64(fp1
);
12298 gen_store_fpr64(ctx
, fp0
, fd
);
12299 tcg_temp_free_i64(fp0
);
12305 TCGv_i64 fp0
= tcg_temp_new_i64();
12306 TCGv_i64 fp1
= tcg_temp_new_i64();
12308 gen_load_fpr64(ctx
, fp0
, ft
);
12309 gen_load_fpr64(ctx
, fp1
, fs
);
12310 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
12311 tcg_temp_free_i64(fp1
);
12312 gen_store_fpr64(ctx
, fp0
, fd
);
12313 tcg_temp_free_i64(fp0
);
12316 case OPC_RECIP2_PS
:
12319 TCGv_i64 fp0
= tcg_temp_new_i64();
12320 TCGv_i64 fp1
= tcg_temp_new_i64();
12322 gen_load_fpr64(ctx
, fp0
, fs
);
12323 gen_load_fpr64(ctx
, fp1
, ft
);
12324 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
12325 tcg_temp_free_i64(fp1
);
12326 gen_store_fpr64(ctx
, fp0
, fd
);
12327 tcg_temp_free_i64(fp0
);
12330 case OPC_RECIP1_PS
:
12333 TCGv_i64 fp0
= tcg_temp_new_i64();
12335 gen_load_fpr64(ctx
, fp0
, fs
);
12336 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
12337 gen_store_fpr64(ctx
, fp0
, fd
);
12338 tcg_temp_free_i64(fp0
);
12341 case OPC_RSQRT1_PS
:
12344 TCGv_i64 fp0
= tcg_temp_new_i64();
12346 gen_load_fpr64(ctx
, fp0
, fs
);
12347 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
12348 gen_store_fpr64(ctx
, fp0
, fd
);
12349 tcg_temp_free_i64(fp0
);
12352 case OPC_RSQRT2_PS
:
12355 TCGv_i64 fp0
= tcg_temp_new_i64();
12356 TCGv_i64 fp1
= tcg_temp_new_i64();
12358 gen_load_fpr64(ctx
, fp0
, fs
);
12359 gen_load_fpr64(ctx
, fp1
, ft
);
12360 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
12361 tcg_temp_free_i64(fp1
);
12362 gen_store_fpr64(ctx
, fp0
, fd
);
12363 tcg_temp_free_i64(fp0
);
12367 check_cp1_64bitmode(ctx
);
12369 TCGv_i32 fp0
= tcg_temp_new_i32();
12371 gen_load_fpr32h(ctx
, fp0
, fs
);
12372 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
12373 gen_store_fpr32(ctx
, fp0
, fd
);
12374 tcg_temp_free_i32(fp0
);
12377 case OPC_CVT_PW_PS
:
12380 TCGv_i64 fp0
= tcg_temp_new_i64();
12382 gen_load_fpr64(ctx
, fp0
, fs
);
12383 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
12384 gen_store_fpr64(ctx
, fp0
, fd
);
12385 tcg_temp_free_i64(fp0
);
12389 check_cp1_64bitmode(ctx
);
12391 TCGv_i32 fp0
= tcg_temp_new_i32();
12393 gen_load_fpr32(ctx
, fp0
, fs
);
12394 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
12395 gen_store_fpr32(ctx
, fp0
, fd
);
12396 tcg_temp_free_i32(fp0
);
12402 TCGv_i32 fp0
= tcg_temp_new_i32();
12403 TCGv_i32 fp1
= tcg_temp_new_i32();
12405 gen_load_fpr32(ctx
, fp0
, fs
);
12406 gen_load_fpr32(ctx
, fp1
, ft
);
12407 gen_store_fpr32h(ctx
, fp0
, fd
);
12408 gen_store_fpr32(ctx
, fp1
, fd
);
12409 tcg_temp_free_i32(fp0
);
12410 tcg_temp_free_i32(fp1
);
12416 TCGv_i32 fp0
= tcg_temp_new_i32();
12417 TCGv_i32 fp1
= tcg_temp_new_i32();
12419 gen_load_fpr32(ctx
, fp0
, fs
);
12420 gen_load_fpr32h(ctx
, fp1
, ft
);
12421 gen_store_fpr32(ctx
, fp1
, fd
);
12422 gen_store_fpr32h(ctx
, fp0
, fd
);
12423 tcg_temp_free_i32(fp0
);
12424 tcg_temp_free_i32(fp1
);
12430 TCGv_i32 fp0
= tcg_temp_new_i32();
12431 TCGv_i32 fp1
= tcg_temp_new_i32();
12433 gen_load_fpr32h(ctx
, fp0
, fs
);
12434 gen_load_fpr32(ctx
, fp1
, ft
);
12435 gen_store_fpr32(ctx
, fp1
, fd
);
12436 gen_store_fpr32h(ctx
, fp0
, fd
);
12437 tcg_temp_free_i32(fp0
);
12438 tcg_temp_free_i32(fp1
);
12444 TCGv_i32 fp0
= tcg_temp_new_i32();
12445 TCGv_i32 fp1
= tcg_temp_new_i32();
12447 gen_load_fpr32h(ctx
, fp0
, fs
);
12448 gen_load_fpr32h(ctx
, fp1
, ft
);
12449 gen_store_fpr32(ctx
, fp1
, fd
);
12450 gen_store_fpr32h(ctx
, fp0
, fd
);
12451 tcg_temp_free_i32(fp0
);
12452 tcg_temp_free_i32(fp1
);
12456 case OPC_CMP_UN_PS
:
12457 case OPC_CMP_EQ_PS
:
12458 case OPC_CMP_UEQ_PS
:
12459 case OPC_CMP_OLT_PS
:
12460 case OPC_CMP_ULT_PS
:
12461 case OPC_CMP_OLE_PS
:
12462 case OPC_CMP_ULE_PS
:
12463 case OPC_CMP_SF_PS
:
12464 case OPC_CMP_NGLE_PS
:
12465 case OPC_CMP_SEQ_PS
:
12466 case OPC_CMP_NGL_PS
:
12467 case OPC_CMP_LT_PS
:
12468 case OPC_CMP_NGE_PS
:
12469 case OPC_CMP_LE_PS
:
12470 case OPC_CMP_NGT_PS
:
12471 if (ctx
->opcode
& (1 << 6)) {
12472 gen_cmpabs_ps(ctx
, func
- 48, ft
, fs
, cc
);
12474 gen_cmp_ps(ctx
, func
- 48, ft
, fs
, cc
);
12478 MIPS_INVAL("farith");
12479 generate_exception_end(ctx
, EXCP_RI
);
12484 /* Coprocessor 3 (FPU) */
12485 static void gen_flt3_ldst(DisasContext
*ctx
, uint32_t opc
,
12486 int fd
, int fs
, int base
, int index
)
12488 TCGv t0
= tcg_temp_new();
12491 gen_load_gpr(t0
, index
);
12492 } else if (index
== 0) {
12493 gen_load_gpr(t0
, base
);
12495 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
12498 * Don't do NOP if destination is zero: we must perform the actual
12505 TCGv_i32 fp0
= tcg_temp_new_i32();
12507 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12508 tcg_gen_trunc_tl_i32(fp0
, t0
);
12509 gen_store_fpr32(ctx
, fp0
, fd
);
12510 tcg_temp_free_i32(fp0
);
12515 check_cp1_registers(ctx
, fd
);
12517 TCGv_i64 fp0
= tcg_temp_new_i64();
12518 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12519 gen_store_fpr64(ctx
, fp0
, fd
);
12520 tcg_temp_free_i64(fp0
);
12524 check_cp1_64bitmode(ctx
);
12525 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12527 TCGv_i64 fp0
= tcg_temp_new_i64();
12529 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12530 gen_store_fpr64(ctx
, fp0
, fd
);
12531 tcg_temp_free_i64(fp0
);
12537 TCGv_i32 fp0
= tcg_temp_new_i32();
12538 gen_load_fpr32(ctx
, fp0
, fs
);
12539 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
12540 tcg_temp_free_i32(fp0
);
12545 check_cp1_registers(ctx
, fs
);
12547 TCGv_i64 fp0
= tcg_temp_new_i64();
12548 gen_load_fpr64(ctx
, fp0
, fs
);
12549 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12550 tcg_temp_free_i64(fp0
);
12554 check_cp1_64bitmode(ctx
);
12555 tcg_gen_andi_tl(t0
, t0
, ~0x7);
12557 TCGv_i64 fp0
= tcg_temp_new_i64();
12558 gen_load_fpr64(ctx
, fp0
, fs
);
12559 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12560 tcg_temp_free_i64(fp0
);
12567 static void gen_flt3_arith(DisasContext
*ctx
, uint32_t opc
,
12568 int fd
, int fr
, int fs
, int ft
)
12574 TCGv t0
= tcg_temp_local_new();
12575 TCGv_i32 fp
= tcg_temp_new_i32();
12576 TCGv_i32 fph
= tcg_temp_new_i32();
12577 TCGLabel
*l1
= gen_new_label();
12578 TCGLabel
*l2
= gen_new_label();
12580 gen_load_gpr(t0
, fr
);
12581 tcg_gen_andi_tl(t0
, t0
, 0x7);
12583 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
12584 gen_load_fpr32(ctx
, fp
, fs
);
12585 gen_load_fpr32h(ctx
, fph
, fs
);
12586 gen_store_fpr32(ctx
, fp
, fd
);
12587 gen_store_fpr32h(ctx
, fph
, fd
);
12590 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
12592 #ifdef TARGET_WORDS_BIGENDIAN
12593 gen_load_fpr32(ctx
, fp
, fs
);
12594 gen_load_fpr32h(ctx
, fph
, ft
);
12595 gen_store_fpr32h(ctx
, fp
, fd
);
12596 gen_store_fpr32(ctx
, fph
, fd
);
12598 gen_load_fpr32h(ctx
, fph
, fs
);
12599 gen_load_fpr32(ctx
, fp
, ft
);
12600 gen_store_fpr32(ctx
, fph
, fd
);
12601 gen_store_fpr32h(ctx
, fp
, fd
);
12604 tcg_temp_free_i32(fp
);
12605 tcg_temp_free_i32(fph
);
12611 TCGv_i32 fp0
= tcg_temp_new_i32();
12612 TCGv_i32 fp1
= tcg_temp_new_i32();
12613 TCGv_i32 fp2
= tcg_temp_new_i32();
12615 gen_load_fpr32(ctx
, fp0
, fs
);
12616 gen_load_fpr32(ctx
, fp1
, ft
);
12617 gen_load_fpr32(ctx
, fp2
, fr
);
12618 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12619 tcg_temp_free_i32(fp0
);
12620 tcg_temp_free_i32(fp1
);
12621 gen_store_fpr32(ctx
, fp2
, fd
);
12622 tcg_temp_free_i32(fp2
);
12627 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12629 TCGv_i64 fp0
= tcg_temp_new_i64();
12630 TCGv_i64 fp1
= tcg_temp_new_i64();
12631 TCGv_i64 fp2
= tcg_temp_new_i64();
12633 gen_load_fpr64(ctx
, fp0
, fs
);
12634 gen_load_fpr64(ctx
, fp1
, ft
);
12635 gen_load_fpr64(ctx
, fp2
, fr
);
12636 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12637 tcg_temp_free_i64(fp0
);
12638 tcg_temp_free_i64(fp1
);
12639 gen_store_fpr64(ctx
, fp2
, fd
);
12640 tcg_temp_free_i64(fp2
);
12646 TCGv_i64 fp0
= tcg_temp_new_i64();
12647 TCGv_i64 fp1
= tcg_temp_new_i64();
12648 TCGv_i64 fp2
= tcg_temp_new_i64();
12650 gen_load_fpr64(ctx
, fp0
, fs
);
12651 gen_load_fpr64(ctx
, fp1
, ft
);
12652 gen_load_fpr64(ctx
, fp2
, fr
);
12653 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12654 tcg_temp_free_i64(fp0
);
12655 tcg_temp_free_i64(fp1
);
12656 gen_store_fpr64(ctx
, fp2
, fd
);
12657 tcg_temp_free_i64(fp2
);
12663 TCGv_i32 fp0
= tcg_temp_new_i32();
12664 TCGv_i32 fp1
= tcg_temp_new_i32();
12665 TCGv_i32 fp2
= tcg_temp_new_i32();
12667 gen_load_fpr32(ctx
, fp0
, fs
);
12668 gen_load_fpr32(ctx
, fp1
, ft
);
12669 gen_load_fpr32(ctx
, fp2
, fr
);
12670 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12671 tcg_temp_free_i32(fp0
);
12672 tcg_temp_free_i32(fp1
);
12673 gen_store_fpr32(ctx
, fp2
, fd
);
12674 tcg_temp_free_i32(fp2
);
12679 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12681 TCGv_i64 fp0
= tcg_temp_new_i64();
12682 TCGv_i64 fp1
= tcg_temp_new_i64();
12683 TCGv_i64 fp2
= tcg_temp_new_i64();
12685 gen_load_fpr64(ctx
, fp0
, fs
);
12686 gen_load_fpr64(ctx
, fp1
, ft
);
12687 gen_load_fpr64(ctx
, fp2
, fr
);
12688 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12689 tcg_temp_free_i64(fp0
);
12690 tcg_temp_free_i64(fp1
);
12691 gen_store_fpr64(ctx
, fp2
, fd
);
12692 tcg_temp_free_i64(fp2
);
12698 TCGv_i64 fp0
= tcg_temp_new_i64();
12699 TCGv_i64 fp1
= tcg_temp_new_i64();
12700 TCGv_i64 fp2
= tcg_temp_new_i64();
12702 gen_load_fpr64(ctx
, fp0
, fs
);
12703 gen_load_fpr64(ctx
, fp1
, ft
);
12704 gen_load_fpr64(ctx
, fp2
, fr
);
12705 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12706 tcg_temp_free_i64(fp0
);
12707 tcg_temp_free_i64(fp1
);
12708 gen_store_fpr64(ctx
, fp2
, fd
);
12709 tcg_temp_free_i64(fp2
);
12715 TCGv_i32 fp0
= tcg_temp_new_i32();
12716 TCGv_i32 fp1
= tcg_temp_new_i32();
12717 TCGv_i32 fp2
= tcg_temp_new_i32();
12719 gen_load_fpr32(ctx
, fp0
, fs
);
12720 gen_load_fpr32(ctx
, fp1
, ft
);
12721 gen_load_fpr32(ctx
, fp2
, fr
);
12722 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12723 tcg_temp_free_i32(fp0
);
12724 tcg_temp_free_i32(fp1
);
12725 gen_store_fpr32(ctx
, fp2
, fd
);
12726 tcg_temp_free_i32(fp2
);
12731 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12733 TCGv_i64 fp0
= tcg_temp_new_i64();
12734 TCGv_i64 fp1
= tcg_temp_new_i64();
12735 TCGv_i64 fp2
= tcg_temp_new_i64();
12737 gen_load_fpr64(ctx
, fp0
, fs
);
12738 gen_load_fpr64(ctx
, fp1
, ft
);
12739 gen_load_fpr64(ctx
, fp2
, fr
);
12740 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12741 tcg_temp_free_i64(fp0
);
12742 tcg_temp_free_i64(fp1
);
12743 gen_store_fpr64(ctx
, fp2
, fd
);
12744 tcg_temp_free_i64(fp2
);
12750 TCGv_i64 fp0
= tcg_temp_new_i64();
12751 TCGv_i64 fp1
= tcg_temp_new_i64();
12752 TCGv_i64 fp2
= tcg_temp_new_i64();
12754 gen_load_fpr64(ctx
, fp0
, fs
);
12755 gen_load_fpr64(ctx
, fp1
, ft
);
12756 gen_load_fpr64(ctx
, fp2
, fr
);
12757 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12758 tcg_temp_free_i64(fp0
);
12759 tcg_temp_free_i64(fp1
);
12760 gen_store_fpr64(ctx
, fp2
, fd
);
12761 tcg_temp_free_i64(fp2
);
12767 TCGv_i32 fp0
= tcg_temp_new_i32();
12768 TCGv_i32 fp1
= tcg_temp_new_i32();
12769 TCGv_i32 fp2
= tcg_temp_new_i32();
12771 gen_load_fpr32(ctx
, fp0
, fs
);
12772 gen_load_fpr32(ctx
, fp1
, ft
);
12773 gen_load_fpr32(ctx
, fp2
, fr
);
12774 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12775 tcg_temp_free_i32(fp0
);
12776 tcg_temp_free_i32(fp1
);
12777 gen_store_fpr32(ctx
, fp2
, fd
);
12778 tcg_temp_free_i32(fp2
);
12783 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
12785 TCGv_i64 fp0
= tcg_temp_new_i64();
12786 TCGv_i64 fp1
= tcg_temp_new_i64();
12787 TCGv_i64 fp2
= tcg_temp_new_i64();
12789 gen_load_fpr64(ctx
, fp0
, fs
);
12790 gen_load_fpr64(ctx
, fp1
, ft
);
12791 gen_load_fpr64(ctx
, fp2
, fr
);
12792 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12793 tcg_temp_free_i64(fp0
);
12794 tcg_temp_free_i64(fp1
);
12795 gen_store_fpr64(ctx
, fp2
, fd
);
12796 tcg_temp_free_i64(fp2
);
12802 TCGv_i64 fp0
= tcg_temp_new_i64();
12803 TCGv_i64 fp1
= tcg_temp_new_i64();
12804 TCGv_i64 fp2
= tcg_temp_new_i64();
12806 gen_load_fpr64(ctx
, fp0
, fs
);
12807 gen_load_fpr64(ctx
, fp1
, ft
);
12808 gen_load_fpr64(ctx
, fp2
, fr
);
12809 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
12810 tcg_temp_free_i64(fp0
);
12811 tcg_temp_free_i64(fp1
);
12812 gen_store_fpr64(ctx
, fp2
, fd
);
12813 tcg_temp_free_i64(fp2
);
12817 MIPS_INVAL("flt3_arith");
12818 generate_exception_end(ctx
, EXCP_RI
);
12823 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
12827 #if !defined(CONFIG_USER_ONLY)
12829 * The Linux kernel will emulate rdhwr if it's not supported natively.
12830 * Therefore only check the ISA in system mode.
12832 check_insn(ctx
, ISA_MIPS32R2
);
12834 t0
= tcg_temp_new();
12838 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
12839 gen_store_gpr(t0
, rt
);
12842 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
12843 gen_store_gpr(t0
, rt
);
12846 if (tb_cflags(ctx
->base
.tb
) & CF_USE_ICOUNT
) {
12849 gen_helper_rdhwr_cc(t0
, cpu_env
);
12850 gen_store_gpr(t0
, rt
);
12852 * Break the TB to be able to take timer interrupts immediately
12853 * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12854 * we break completely out of translated code.
12856 gen_save_pc(ctx
->base
.pc_next
+ 4);
12857 ctx
->base
.is_jmp
= DISAS_EXIT
;
12860 gen_helper_rdhwr_ccres(t0
, cpu_env
);
12861 gen_store_gpr(t0
, rt
);
12864 check_insn(ctx
, ISA_MIPS32R6
);
12867 * Performance counter registers are not implemented other than
12868 * control register 0.
12870 generate_exception(ctx
, EXCP_RI
);
12872 gen_helper_rdhwr_performance(t0
, cpu_env
);
12873 gen_store_gpr(t0
, rt
);
12876 check_insn(ctx
, ISA_MIPS32R6
);
12877 gen_helper_rdhwr_xnp(t0
, cpu_env
);
12878 gen_store_gpr(t0
, rt
);
12881 #if defined(CONFIG_USER_ONLY)
12882 tcg_gen_ld_tl(t0
, cpu_env
,
12883 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12884 gen_store_gpr(t0
, rt
);
12887 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
12888 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
12889 tcg_gen_ld_tl(t0
, cpu_env
,
12890 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
12891 gen_store_gpr(t0
, rt
);
12893 generate_exception_end(ctx
, EXCP_RI
);
12897 default: /* Invalid */
12898 MIPS_INVAL("rdhwr");
12899 generate_exception_end(ctx
, EXCP_RI
);
12905 static inline void clear_branch_hflags(DisasContext
*ctx
)
12907 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
12908 if (ctx
->base
.is_jmp
== DISAS_NEXT
) {
12909 save_cpu_state(ctx
, 0);
12912 * It is not safe to save ctx->hflags as hflags may be changed
12913 * in execution time by the instruction in delay / forbidden slot.
12915 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
12919 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
12921 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12922 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
12923 /* Branches completion */
12924 clear_branch_hflags(ctx
);
12925 ctx
->base
.is_jmp
= DISAS_NORETURN
;
12926 /* FIXME: Need to clear can_do_io. */
12927 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
12928 case MIPS_HFLAG_FBNSLOT
:
12929 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ insn_bytes
);
12932 /* unconditional branch */
12933 if (proc_hflags
& MIPS_HFLAG_BX
) {
12934 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
12936 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12938 case MIPS_HFLAG_BL
:
12939 /* blikely taken case */
12940 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12942 case MIPS_HFLAG_BC
:
12943 /* Conditional branch */
12945 TCGLabel
*l1
= gen_new_label();
12947 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
12948 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ insn_bytes
);
12950 gen_goto_tb(ctx
, 0, ctx
->btarget
);
12953 case MIPS_HFLAG_BR
:
12954 /* unconditional branch to register */
12955 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
12956 TCGv t0
= tcg_temp_new();
12957 TCGv_i32 t1
= tcg_temp_new_i32();
12959 tcg_gen_andi_tl(t0
, btarget
, 0x1);
12960 tcg_gen_trunc_tl_i32(t1
, t0
);
12962 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
12963 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
12964 tcg_gen_or_i32(hflags
, hflags
, t1
);
12965 tcg_temp_free_i32(t1
);
12967 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
12969 tcg_gen_mov_tl(cpu_PC
, btarget
);
12971 if (ctx
->base
.singlestep_enabled
) {
12972 save_cpu_state(ctx
, 0);
12973 gen_helper_raise_exception_debug(cpu_env
);
12975 tcg_gen_lookup_and_goto_ptr();
12978 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
12984 /* Compact Branches */
12985 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
12986 int rs
, int rt
, int32_t offset
)
12988 int bcond_compute
= 0;
12989 TCGv t0
= tcg_temp_new();
12990 TCGv t1
= tcg_temp_new();
12991 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
12993 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12994 #ifdef MIPS_DEBUG_DISAS
12995 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12996 "\n", ctx
->base
.pc_next
);
12998 generate_exception_end(ctx
, EXCP_RI
);
13002 /* Load needed operands and calculate btarget */
13004 /* compact branch */
13005 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13006 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13007 gen_load_gpr(t0
, rs
);
13008 gen_load_gpr(t1
, rt
);
13010 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13011 if (rs
<= rt
&& rs
== 0) {
13012 /* OPC_BEQZALC, OPC_BNEZALC */
13013 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13016 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13017 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13018 gen_load_gpr(t0
, rs
);
13019 gen_load_gpr(t1
, rt
);
13021 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13023 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13024 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13025 if (rs
== 0 || rs
== rt
) {
13026 /* OPC_BLEZALC, OPC_BGEZALC */
13027 /* OPC_BGTZALC, OPC_BLTZALC */
13028 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13030 gen_load_gpr(t0
, rs
);
13031 gen_load_gpr(t1
, rt
);
13033 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13037 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13042 /* OPC_BEQZC, OPC_BNEZC */
13043 gen_load_gpr(t0
, rs
);
13045 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
13047 /* OPC_JIC, OPC_JIALC */
13048 TCGv tbase
= tcg_temp_new();
13049 TCGv toffset
= tcg_temp_new();
13051 gen_load_gpr(tbase
, rt
);
13052 tcg_gen_movi_tl(toffset
, offset
);
13053 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
13054 tcg_temp_free(tbase
);
13055 tcg_temp_free(toffset
);
13059 MIPS_INVAL("Compact branch/jump");
13060 generate_exception_end(ctx
, EXCP_RI
);
13064 if (bcond_compute
== 0) {
13065 /* Uncoditional compact branch */
13068 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13071 ctx
->hflags
|= MIPS_HFLAG_BR
;
13074 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4 + m16_lowbit
);
13077 ctx
->hflags
|= MIPS_HFLAG_B
;
13080 MIPS_INVAL("Compact branch/jump");
13081 generate_exception_end(ctx
, EXCP_RI
);
13085 /* Generating branch here as compact branches don't have delay slot */
13086 gen_branch(ctx
, 4);
13088 /* Conditional compact branch */
13089 TCGLabel
*fs
= gen_new_label();
13090 save_cpu_state(ctx
, 0);
13093 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
13094 if (rs
== 0 && rt
!= 0) {
13096 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13097 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13099 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13102 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
13105 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
13106 if (rs
== 0 && rt
!= 0) {
13108 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13109 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13111 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13114 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
13117 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
13118 if (rs
== 0 && rt
!= 0) {
13120 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
13121 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13123 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
13126 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
13129 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
13130 if (rs
== 0 && rt
!= 0) {
13132 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
13133 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
13135 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
13138 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
13141 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
13142 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
13144 /* OPC_BOVC, OPC_BNVC */
13145 TCGv t2
= tcg_temp_new();
13146 TCGv t3
= tcg_temp_new();
13147 TCGv t4
= tcg_temp_new();
13148 TCGv input_overflow
= tcg_temp_new();
13150 gen_load_gpr(t0
, rs
);
13151 gen_load_gpr(t1
, rt
);
13152 tcg_gen_ext32s_tl(t2
, t0
);
13153 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
13154 tcg_gen_ext32s_tl(t3
, t1
);
13155 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
13156 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
13158 tcg_gen_add_tl(t4
, t2
, t3
);
13159 tcg_gen_ext32s_tl(t4
, t4
);
13160 tcg_gen_xor_tl(t2
, t2
, t3
);
13161 tcg_gen_xor_tl(t3
, t4
, t3
);
13162 tcg_gen_andc_tl(t2
, t3
, t2
);
13163 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
13164 tcg_gen_or_tl(t4
, t4
, input_overflow
);
13165 if (opc
== OPC_BOVC
) {
13167 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
13170 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
13172 tcg_temp_free(input_overflow
);
13176 } else if (rs
< rt
&& rs
== 0) {
13177 /* OPC_BEQZALC, OPC_BNEZALC */
13178 if (opc
== OPC_BEQZALC
) {
13180 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
13183 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
13186 /* OPC_BEQC, OPC_BNEC */
13187 if (opc
== OPC_BEQC
) {
13189 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
13192 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
13197 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
13200 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
13203 MIPS_INVAL("Compact conditional branch/jump");
13204 generate_exception_end(ctx
, EXCP_RI
);
13208 /* Generating branch here as compact branches don't have delay slot */
13209 gen_goto_tb(ctx
, 1, ctx
->btarget
);
13212 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
13220 /* ISA extensions (ASEs) */
13221 /* MIPS16 extension to MIPS32 */
13223 /* MIPS16 major opcodes */
13225 M16_OPC_ADDIUSP
= 0x00,
13226 M16_OPC_ADDIUPC
= 0x01,
13228 M16_OPC_JAL
= 0x03,
13229 M16_OPC_BEQZ
= 0x04,
13230 M16_OPC_BNEQZ
= 0x05,
13231 M16_OPC_SHIFT
= 0x06,
13233 M16_OPC_RRIA
= 0x08,
13234 M16_OPC_ADDIU8
= 0x09,
13235 M16_OPC_SLTI
= 0x0a,
13236 M16_OPC_SLTIU
= 0x0b,
13239 M16_OPC_CMPI
= 0x0e,
13243 M16_OPC_LWSP
= 0x12,
13245 M16_OPC_LBU
= 0x14,
13246 M16_OPC_LHU
= 0x15,
13247 M16_OPC_LWPC
= 0x16,
13248 M16_OPC_LWU
= 0x17,
13251 M16_OPC_SWSP
= 0x1a,
13253 M16_OPC_RRR
= 0x1c,
13255 M16_OPC_EXTEND
= 0x1e,
13259 /* I8 funct field */
13278 /* RR funct field */
13312 /* I64 funct field */
13320 I64_DADDIUPC
= 0x6,
13324 /* RR ry field for CNVT */
13326 RR_RY_CNVT_ZEB
= 0x0,
13327 RR_RY_CNVT_ZEH
= 0x1,
13328 RR_RY_CNVT_ZEW
= 0x2,
13329 RR_RY_CNVT_SEB
= 0x4,
13330 RR_RY_CNVT_SEH
= 0x5,
13331 RR_RY_CNVT_SEW
= 0x6,
13334 static int xlat(int r
)
13336 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13341 static void gen_mips16_save(DisasContext
*ctx
,
13342 int xsregs
, int aregs
,
13343 int do_ra
, int do_s0
, int do_s1
,
13346 TCGv t0
= tcg_temp_new();
13347 TCGv t1
= tcg_temp_new();
13348 TCGv t2
= tcg_temp_new();
13378 generate_exception_end(ctx
, EXCP_RI
);
13384 gen_base_offset_addr(ctx
, t0
, 29, 12);
13385 gen_load_gpr(t1
, 7);
13386 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13389 gen_base_offset_addr(ctx
, t0
, 29, 8);
13390 gen_load_gpr(t1
, 6);
13391 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13394 gen_base_offset_addr(ctx
, t0
, 29, 4);
13395 gen_load_gpr(t1
, 5);
13396 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13399 gen_base_offset_addr(ctx
, t0
, 29, 0);
13400 gen_load_gpr(t1
, 4);
13401 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13404 gen_load_gpr(t0
, 29);
13406 #define DECR_AND_STORE(reg) do { \
13407 tcg_gen_movi_tl(t2, -4); \
13408 gen_op_addr_add(ctx, t0, t0, t2); \
13409 gen_load_gpr(t1, reg); \
13410 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13414 DECR_AND_STORE(31);
13419 DECR_AND_STORE(30);
13422 DECR_AND_STORE(23);
13425 DECR_AND_STORE(22);
13428 DECR_AND_STORE(21);
13431 DECR_AND_STORE(20);
13434 DECR_AND_STORE(19);
13437 DECR_AND_STORE(18);
13441 DECR_AND_STORE(17);
13444 DECR_AND_STORE(16);
13474 generate_exception_end(ctx
, EXCP_RI
);
13490 #undef DECR_AND_STORE
13492 tcg_gen_movi_tl(t2
, -framesize
);
13493 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13499 static void gen_mips16_restore(DisasContext
*ctx
,
13500 int xsregs
, int aregs
,
13501 int do_ra
, int do_s0
, int do_s1
,
13505 TCGv t0
= tcg_temp_new();
13506 TCGv t1
= tcg_temp_new();
13507 TCGv t2
= tcg_temp_new();
13509 tcg_gen_movi_tl(t2
, framesize
);
13510 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
13512 #define DECR_AND_LOAD(reg) do { \
13513 tcg_gen_movi_tl(t2, -4); \
13514 gen_op_addr_add(ctx, t0, t0, t2); \
13515 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13516 gen_store_gpr(t1, reg); \
13580 generate_exception_end(ctx
, EXCP_RI
);
13596 #undef DECR_AND_LOAD
13598 tcg_gen_movi_tl(t2
, framesize
);
13599 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
13605 static void gen_addiupc(DisasContext
*ctx
, int rx
, int imm
,
13606 int is_64_bit
, int extended
)
13610 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13611 generate_exception_end(ctx
, EXCP_RI
);
13615 t0
= tcg_temp_new();
13617 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
13618 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
13620 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
13626 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
13629 TCGv_i32 t0
= tcg_const_i32(op
);
13630 TCGv t1
= tcg_temp_new();
13631 gen_base_offset_addr(ctx
, t1
, base
, offset
);
13632 gen_helper_cache(cpu_env
, t1
, t0
);
13635 #if defined(TARGET_MIPS64)
13636 static void decode_i64_mips16(DisasContext
*ctx
,
13637 int ry
, int funct
, int16_t offset
,
13642 check_insn(ctx
, ISA_MIPS3
);
13643 check_mips_64(ctx
);
13644 offset
= extended
? offset
: offset
<< 3;
13645 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
13648 check_insn(ctx
, ISA_MIPS3
);
13649 check_mips_64(ctx
);
13650 offset
= extended
? offset
: offset
<< 3;
13651 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
13654 check_insn(ctx
, ISA_MIPS3
);
13655 check_mips_64(ctx
);
13656 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
13657 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
13660 check_insn(ctx
, ISA_MIPS3
);
13661 check_mips_64(ctx
);
13662 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
13663 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
13666 check_insn(ctx
, ISA_MIPS3
);
13667 check_mips_64(ctx
);
13668 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
13669 generate_exception_end(ctx
, EXCP_RI
);
13671 offset
= extended
? offset
: offset
<< 3;
13672 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
13676 check_insn(ctx
, ISA_MIPS3
);
13677 check_mips_64(ctx
);
13678 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
13679 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
13682 check_insn(ctx
, ISA_MIPS3
);
13683 check_mips_64(ctx
);
13684 offset
= extended
? offset
: offset
<< 2;
13685 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
13688 check_insn(ctx
, ISA_MIPS3
);
13689 check_mips_64(ctx
);
13690 offset
= extended
? offset
: offset
<< 2;
13691 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
13697 static int decode_extended_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13699 int extend
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
13700 int op
, rx
, ry
, funct
, sa
;
13701 int16_t imm
, offset
;
13703 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
13704 op
= (ctx
->opcode
>> 11) & 0x1f;
13705 sa
= (ctx
->opcode
>> 22) & 0x1f;
13706 funct
= (ctx
->opcode
>> 8) & 0x7;
13707 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13708 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13709 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
13710 | ((ctx
->opcode
>> 21) & 0x3f) << 5
13711 | (ctx
->opcode
& 0x1f));
13714 * The extended opcodes cleverly reuse the opcodes from their 16-bit
13718 case M16_OPC_ADDIUSP
:
13719 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13721 case M16_OPC_ADDIUPC
:
13722 gen_addiupc(ctx
, rx
, imm
, 0, 1);
13725 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
13726 /* No delay slot, so just process as a normal instruction */
13729 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
13730 /* No delay slot, so just process as a normal instruction */
13732 case M16_OPC_BNEQZ
:
13733 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
13734 /* No delay slot, so just process as a normal instruction */
13736 case M16_OPC_SHIFT
:
13737 switch (ctx
->opcode
& 0x3) {
13739 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13742 #if defined(TARGET_MIPS64)
13743 check_mips_64(ctx
);
13744 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13746 generate_exception_end(ctx
, EXCP_RI
);
13750 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13753 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13757 #if defined(TARGET_MIPS64)
13759 check_insn(ctx
, ISA_MIPS3
);
13760 check_mips_64(ctx
);
13761 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
13765 imm
= ctx
->opcode
& 0xf;
13766 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
13767 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
13768 imm
= (int16_t) (imm
<< 1) >> 1;
13769 if ((ctx
->opcode
>> 4) & 0x1) {
13770 #if defined(TARGET_MIPS64)
13771 check_mips_64(ctx
);
13772 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
13774 generate_exception_end(ctx
, EXCP_RI
);
13777 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
13780 case M16_OPC_ADDIU8
:
13781 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
13784 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
13786 case M16_OPC_SLTIU
:
13787 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
13792 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
13795 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
13798 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
13801 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
13804 check_insn(ctx
, ISA_MIPS32
);
13806 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
13807 int aregs
= (ctx
->opcode
>> 16) & 0xf;
13808 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
13809 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
13810 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
13811 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
13812 | (ctx
->opcode
& 0xf)) << 3;
13814 if (ctx
->opcode
& (1 << 7)) {
13815 gen_mips16_save(ctx
, xsregs
, aregs
,
13816 do_ra
, do_s0
, do_s1
,
13819 gen_mips16_restore(ctx
, xsregs
, aregs
,
13820 do_ra
, do_s0
, do_s1
,
13826 generate_exception_end(ctx
, EXCP_RI
);
13831 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
13834 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
13836 #if defined(TARGET_MIPS64)
13838 check_insn(ctx
, ISA_MIPS3
);
13839 check_mips_64(ctx
);
13840 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
13844 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
13847 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
13850 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
13853 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
13856 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
13859 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
13862 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
13864 #if defined(TARGET_MIPS64)
13866 check_insn(ctx
, ISA_MIPS3
);
13867 check_mips_64(ctx
);
13868 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
13872 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
13875 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
13878 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
13881 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
13883 #if defined(TARGET_MIPS64)
13885 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
13889 generate_exception_end(ctx
, EXCP_RI
);
13896 static inline bool is_uhi(int sdbbp_code
)
13898 #ifdef CONFIG_USER_ONLY
13901 return semihosting_enabled() && sdbbp_code
== 1;
13905 #ifdef CONFIG_USER_ONLY
13906 /* The above should dead-code away any calls to this..*/
13907 static inline void gen_helper_do_semihosting(void *env
)
13909 g_assert_not_reached();
13913 static int decode_mips16_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13917 int op
, cnvt_op
, op1
, offset
;
13921 op
= (ctx
->opcode
>> 11) & 0x1f;
13922 sa
= (ctx
->opcode
>> 2) & 0x7;
13923 sa
= sa
== 0 ? 8 : sa
;
13924 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
13925 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
13926 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
13927 op1
= offset
= ctx
->opcode
& 0x1f;
13932 case M16_OPC_ADDIUSP
:
13934 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
13936 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
13939 case M16_OPC_ADDIUPC
:
13940 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
13943 offset
= (ctx
->opcode
& 0x7ff) << 1;
13944 offset
= (int16_t)(offset
<< 4) >> 4;
13945 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
13946 /* No delay slot, so just process as a normal instruction */
13949 offset
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
13950 offset
= (((ctx
->opcode
& 0x1f) << 21)
13951 | ((ctx
->opcode
>> 5) & 0x1f) << 16
13953 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
13954 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
13958 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
13959 ((int8_t)ctx
->opcode
) << 1, 0);
13960 /* No delay slot, so just process as a normal instruction */
13962 case M16_OPC_BNEQZ
:
13963 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
13964 ((int8_t)ctx
->opcode
) << 1, 0);
13965 /* No delay slot, so just process as a normal instruction */
13967 case M16_OPC_SHIFT
:
13968 switch (ctx
->opcode
& 0x3) {
13970 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
13973 #if defined(TARGET_MIPS64)
13974 check_insn(ctx
, ISA_MIPS3
);
13975 check_mips_64(ctx
);
13976 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
13978 generate_exception_end(ctx
, EXCP_RI
);
13982 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
13985 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
13989 #if defined(TARGET_MIPS64)
13991 check_insn(ctx
, ISA_MIPS3
);
13992 check_mips_64(ctx
);
13993 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
13998 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
14000 if ((ctx
->opcode
>> 4) & 1) {
14001 #if defined(TARGET_MIPS64)
14002 check_insn(ctx
, ISA_MIPS3
);
14003 check_mips_64(ctx
);
14004 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
14006 generate_exception_end(ctx
, EXCP_RI
);
14009 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
14013 case M16_OPC_ADDIU8
:
14015 int16_t imm
= (int8_t) ctx
->opcode
;
14017 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
14022 int16_t imm
= (uint8_t) ctx
->opcode
;
14023 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
14026 case M16_OPC_SLTIU
:
14028 int16_t imm
= (uint8_t) ctx
->opcode
;
14029 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
14036 funct
= (ctx
->opcode
>> 8) & 0x7;
14039 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
14040 ((int8_t)ctx
->opcode
) << 1, 0);
14043 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
14044 ((int8_t)ctx
->opcode
) << 1, 0);
14047 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
14050 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
14051 ((int8_t)ctx
->opcode
) << 3);
14054 check_insn(ctx
, ISA_MIPS32
);
14056 int do_ra
= ctx
->opcode
& (1 << 6);
14057 int do_s0
= ctx
->opcode
& (1 << 5);
14058 int do_s1
= ctx
->opcode
& (1 << 4);
14059 int framesize
= ctx
->opcode
& 0xf;
14061 if (framesize
== 0) {
14064 framesize
= framesize
<< 3;
14067 if (ctx
->opcode
& (1 << 7)) {
14068 gen_mips16_save(ctx
, 0, 0,
14069 do_ra
, do_s0
, do_s1
, framesize
);
14071 gen_mips16_restore(ctx
, 0, 0,
14072 do_ra
, do_s0
, do_s1
, framesize
);
14078 int rz
= xlat(ctx
->opcode
& 0x7);
14080 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
14081 ((ctx
->opcode
>> 5) & 0x7);
14082 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
14086 reg32
= ctx
->opcode
& 0x1f;
14087 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
14090 generate_exception_end(ctx
, EXCP_RI
);
14097 int16_t imm
= (uint8_t) ctx
->opcode
;
14099 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
14104 int16_t imm
= (uint8_t) ctx
->opcode
;
14105 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
14108 #if defined(TARGET_MIPS64)
14110 check_insn(ctx
, ISA_MIPS3
);
14111 check_mips_64(ctx
);
14112 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
14116 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
14119 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
14122 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14125 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
14128 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
14131 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
14134 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
14136 #if defined(TARGET_MIPS64)
14138 check_insn(ctx
, ISA_MIPS3
);
14139 check_mips_64(ctx
);
14140 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
14144 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
14147 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
14150 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
14153 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
14157 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
14160 switch (ctx
->opcode
& 0x3) {
14162 mips32_op
= OPC_ADDU
;
14165 mips32_op
= OPC_SUBU
;
14167 #if defined(TARGET_MIPS64)
14169 mips32_op
= OPC_DADDU
;
14170 check_insn(ctx
, ISA_MIPS3
);
14171 check_mips_64(ctx
);
14174 mips32_op
= OPC_DSUBU
;
14175 check_insn(ctx
, ISA_MIPS3
);
14176 check_mips_64(ctx
);
14180 generate_exception_end(ctx
, EXCP_RI
);
14184 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
14193 int nd
= (ctx
->opcode
>> 7) & 0x1;
14194 int link
= (ctx
->opcode
>> 6) & 0x1;
14195 int ra
= (ctx
->opcode
>> 5) & 0x1;
14198 check_insn(ctx
, ISA_MIPS32
);
14207 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
14212 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
14213 gen_helper_do_semihosting(cpu_env
);
14216 * XXX: not clear which exception should be raised
14217 * when in debug mode...
14219 check_insn(ctx
, ISA_MIPS32
);
14220 generate_exception_end(ctx
, EXCP_DBp
);
14224 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
14227 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
14230 generate_exception_end(ctx
, EXCP_BREAK
);
14233 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
14236 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
14239 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
14241 #if defined(TARGET_MIPS64)
14243 check_insn(ctx
, ISA_MIPS3
);
14244 check_mips_64(ctx
);
14245 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
14249 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
14252 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
14255 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
14258 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
14261 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
14264 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
14267 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
14270 check_insn(ctx
, ISA_MIPS32
);
14272 case RR_RY_CNVT_ZEB
:
14273 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14275 case RR_RY_CNVT_ZEH
:
14276 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14278 case RR_RY_CNVT_SEB
:
14279 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14281 case RR_RY_CNVT_SEH
:
14282 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14284 #if defined(TARGET_MIPS64)
14285 case RR_RY_CNVT_ZEW
:
14286 check_insn(ctx
, ISA_MIPS64
);
14287 check_mips_64(ctx
);
14288 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14290 case RR_RY_CNVT_SEW
:
14291 check_insn(ctx
, ISA_MIPS64
);
14292 check_mips_64(ctx
);
14293 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
14297 generate_exception_end(ctx
, EXCP_RI
);
14302 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
14304 #if defined(TARGET_MIPS64)
14306 check_insn(ctx
, ISA_MIPS3
);
14307 check_mips_64(ctx
);
14308 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
14311 check_insn(ctx
, ISA_MIPS3
);
14312 check_mips_64(ctx
);
14313 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
14316 check_insn(ctx
, ISA_MIPS3
);
14317 check_mips_64(ctx
);
14318 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
14321 check_insn(ctx
, ISA_MIPS3
);
14322 check_mips_64(ctx
);
14323 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
14327 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
14330 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
14333 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
14336 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
14338 #if defined(TARGET_MIPS64)
14340 check_insn(ctx
, ISA_MIPS3
);
14341 check_mips_64(ctx
);
14342 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
14345 check_insn(ctx
, ISA_MIPS3
);
14346 check_mips_64(ctx
);
14347 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
14350 check_insn(ctx
, ISA_MIPS3
);
14351 check_mips_64(ctx
);
14352 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
14355 check_insn(ctx
, ISA_MIPS3
);
14356 check_mips_64(ctx
);
14357 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
14361 generate_exception_end(ctx
, EXCP_RI
);
14365 case M16_OPC_EXTEND
:
14366 decode_extended_mips16_opc(env
, ctx
);
14369 #if defined(TARGET_MIPS64)
14371 funct
= (ctx
->opcode
>> 8) & 0x7;
14372 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
14376 generate_exception_end(ctx
, EXCP_RI
);
14383 /* microMIPS extension to MIPS32/MIPS64 */
14386 * microMIPS32/microMIPS64 major opcodes
14388 * 1. MIPS Architecture for Programmers Volume II-B:
14389 * The microMIPS32 Instruction Set (Revision 3.05)
14391 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
14393 * 2. MIPS Architecture For Programmers Volume II-A:
14394 * The MIPS64 Instruction Set (Revision 3.51)
14424 POOL32S
= 0x16, /* MIPS64 */
14425 DADDIU32
= 0x17, /* MIPS64 */
14454 /* 0x29 is reserved */
14467 /* 0x31 is reserved */
14480 SD32
= 0x36, /* MIPS64 */
14481 LD32
= 0x37, /* MIPS64 */
14483 /* 0x39 is reserved */
14499 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14521 /* POOL32A encoding of minor opcode field */
14525 * These opcodes are distinguished only by bits 9..6; those bits are
14526 * what are recorded below.
14564 /* The following can be distinguished by their lower 6 bits. */
14574 /* POOL32AXF encoding of minor opcode field extension */
14577 * 1. MIPS Architecture for Programmers Volume II-B:
14578 * The microMIPS32 Instruction Set (Revision 3.05)
14580 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14582 * 2. MIPS Architecture for Programmers VolumeIV-e:
14583 * The MIPS DSP Application-Specific Extension
14584 * to the microMIPS32 Architecture (Revision 2.34)
14586 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14601 /* begin of microMIPS32 DSP */
14603 /* bits 13..12 for 0x01 */
14609 /* bits 13..12 for 0x2a */
14615 /* bits 13..12 for 0x32 */
14619 /* end of microMIPS32 DSP */
14621 /* bits 15..12 for 0x2c */
14638 /* bits 15..12 for 0x34 */
14646 /* bits 15..12 for 0x3c */
14648 JR
= 0x0, /* alias */
14656 /* bits 15..12 for 0x05 */
14660 /* bits 15..12 for 0x0d */
14672 /* bits 15..12 for 0x15 */
14678 /* bits 15..12 for 0x1d */
14682 /* bits 15..12 for 0x2d */
14687 /* bits 15..12 for 0x35 */
14694 /* POOL32B encoding of minor opcode field (bits 15..12) */
14710 /* POOL32C encoding of minor opcode field (bits 15..12) */
14731 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14744 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14757 /* POOL32F encoding of minor opcode field (bits 5..0) */
14760 /* These are the bit 7..6 values */
14769 /* These are the bit 8..6 values */
14794 MOVZ_FMT_05
= 0x05,
14828 CABS_COND_FMT
= 0x1c, /* MIPS3D */
14835 /* POOL32Fxf encoding of minor opcode extension field */
14873 /* POOL32I encoding of minor opcode field (bits 25..21) */
14903 /* These overlap and are distinguished by bit16 of the instruction */
14912 /* POOL16A encoding of minor opcode field */
14919 /* POOL16B encoding of minor opcode field */
14926 /* POOL16C encoding of minor opcode field */
14946 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14970 /* POOL16D encoding of minor opcode field */
14977 /* POOL16E encoding of minor opcode field */
14984 static int mmreg(int r
)
14986 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14991 /* Used for 16-bit store instructions. */
14992 static int mmreg2(int r
)
14994 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14999 #define uMIPS_RD(op) ((op >> 7) & 0x7)
15000 #define uMIPS_RS(op) ((op >> 4) & 0x7)
15001 #define uMIPS_RS2(op) uMIPS_RS(op)
15002 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
15003 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
15004 #define uMIPS_RS5(op) (op & 0x1f)
15006 /* Signed immediate */
15007 #define SIMM(op, start, width) \
15008 ((int32_t)(((op >> start) & ((~0U) >> (32 - width))) \
15011 /* Zero-extended immediate */
15012 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
15014 static void gen_addiur1sp(DisasContext
*ctx
)
15016 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15018 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
15021 static void gen_addiur2(DisasContext
*ctx
)
15023 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
15024 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15025 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15027 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
15030 static void gen_addiusp(DisasContext
*ctx
)
15032 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
15035 if (encoded
<= 1) {
15036 decoded
= 256 + encoded
;
15037 } else if (encoded
<= 255) {
15039 } else if (encoded
<= 509) {
15040 decoded
= encoded
- 512;
15042 decoded
= encoded
- 768;
15045 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
15048 static void gen_addius5(DisasContext
*ctx
)
15050 int imm
= SIMM(ctx
->opcode
, 1, 4);
15051 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15053 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
15056 static void gen_andi16(DisasContext
*ctx
)
15058 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
15059 31, 32, 63, 64, 255, 32768, 65535 };
15060 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15061 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15062 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
15064 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
15067 static void gen_ldst_multiple(DisasContext
*ctx
, uint32_t opc
, int reglist
,
15068 int base
, int16_t offset
)
15073 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15074 generate_exception_end(ctx
, EXCP_RI
);
15078 t0
= tcg_temp_new();
15080 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15082 t1
= tcg_const_tl(reglist
);
15083 t2
= tcg_const_i32(ctx
->mem_idx
);
15085 save_cpu_state(ctx
, 1);
15088 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
15091 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
15093 #ifdef TARGET_MIPS64
15095 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
15098 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
15104 tcg_temp_free_i32(t2
);
15108 static void gen_pool16c_insn(DisasContext
*ctx
)
15110 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
15111 int rs
= mmreg(ctx
->opcode
& 0x7);
15113 switch (((ctx
->opcode
) >> 4) & 0x3f) {
15118 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
15124 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
15130 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
15136 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
15143 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15144 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15146 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
15155 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
15156 int offset
= ZIMM(ctx
->opcode
, 0, 4);
15158 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
15165 int reg
= ctx
->opcode
& 0x1f;
15167 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
15173 int reg
= ctx
->opcode
& 0x1f;
15174 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
15176 * Let normal delay slot handling in our caller take us
15177 * to the branch target.
15183 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
15184 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15188 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
15189 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15193 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
15197 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
15200 generate_exception_end(ctx
, EXCP_BREAK
);
15203 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
15204 gen_helper_do_semihosting(cpu_env
);
15207 * XXX: not clear which exception should be raised
15208 * when in debug mode...
15210 check_insn(ctx
, ISA_MIPS32
);
15211 generate_exception_end(ctx
, EXCP_DBp
);
15214 case JRADDIUSP
+ 0:
15215 case JRADDIUSP
+ 1:
15217 int imm
= ZIMM(ctx
->opcode
, 0, 5);
15218 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15219 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15221 * Let normal delay slot handling in our caller take us
15222 * to the branch target.
15227 generate_exception_end(ctx
, EXCP_RI
);
15232 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
15235 int rd
, rs
, re
, rt
;
15236 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15237 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15238 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15239 rd
= rd_enc
[enc_dest
];
15240 re
= re_enc
[enc_dest
];
15241 rs
= rs_rt_enc
[enc_rs
];
15242 rt
= rs_rt_enc
[enc_rt
];
15244 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
15246 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
15249 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
15251 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
15255 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
15257 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
15258 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
15260 switch (ctx
->opcode
& 0xf) {
15262 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
15265 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
15269 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15270 int offset
= extract32(ctx
->opcode
, 4, 4);
15271 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
15274 case R6_JRC16
: /* JRCADDIUSP */
15275 if ((ctx
->opcode
>> 4) & 1) {
15277 int imm
= extract32(ctx
->opcode
, 5, 5);
15278 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
15279 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
15282 rs
= extract32(ctx
->opcode
, 5, 5);
15283 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
15295 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15296 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15297 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
15298 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15302 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
15305 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
15309 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
15310 int offset
= extract32(ctx
->opcode
, 4, 4);
15311 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
15314 case JALRC16
: /* BREAK16, SDBBP16 */
15315 switch (ctx
->opcode
& 0x3f) {
15317 case JALRC16
+ 0x20:
15319 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
15324 generate_exception(ctx
, EXCP_BREAK
);
15328 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
15329 gen_helper_do_semihosting(cpu_env
);
15331 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15332 generate_exception(ctx
, EXCP_RI
);
15334 generate_exception(ctx
, EXCP_DBp
);
15341 generate_exception(ctx
, EXCP_RI
);
15346 static void gen_ldxs(DisasContext
*ctx
, int base
, int index
, int rd
)
15348 TCGv t0
= tcg_temp_new();
15349 TCGv t1
= tcg_temp_new();
15351 gen_load_gpr(t0
, base
);
15354 gen_load_gpr(t1
, index
);
15355 tcg_gen_shli_tl(t1
, t1
, 2);
15356 gen_op_addr_add(ctx
, t0
, t1
, t0
);
15359 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15360 gen_store_gpr(t1
, rd
);
15366 static void gen_ldst_pair(DisasContext
*ctx
, uint32_t opc
, int rd
,
15367 int base
, int16_t offset
)
15371 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
15372 generate_exception_end(ctx
, EXCP_RI
);
15376 t0
= tcg_temp_new();
15377 t1
= tcg_temp_new();
15379 gen_base_offset_addr(ctx
, t0
, base
, offset
);
15384 generate_exception_end(ctx
, EXCP_RI
);
15387 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15388 gen_store_gpr(t1
, rd
);
15389 tcg_gen_movi_tl(t1
, 4);
15390 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15391 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
15392 gen_store_gpr(t1
, rd
+ 1);
15395 gen_load_gpr(t1
, rd
);
15396 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15397 tcg_gen_movi_tl(t1
, 4);
15398 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15399 gen_load_gpr(t1
, rd
+ 1);
15400 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
15402 #ifdef TARGET_MIPS64
15405 generate_exception_end(ctx
, EXCP_RI
);
15408 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15409 gen_store_gpr(t1
, rd
);
15410 tcg_gen_movi_tl(t1
, 8);
15411 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15412 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15413 gen_store_gpr(t1
, rd
+ 1);
15416 gen_load_gpr(t1
, rd
);
15417 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15418 tcg_gen_movi_tl(t1
, 8);
15419 gen_op_addr_add(ctx
, t0
, t0
, t1
);
15420 gen_load_gpr(t1
, rd
+ 1);
15421 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
15429 static void gen_sync(int stype
)
15431 TCGBar tcg_mo
= TCG_BAR_SC
;
15434 case 0x4: /* SYNC_WMB */
15435 tcg_mo
|= TCG_MO_ST_ST
;
15437 case 0x10: /* SYNC_MB */
15438 tcg_mo
|= TCG_MO_ALL
;
15440 case 0x11: /* SYNC_ACQUIRE */
15441 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
15443 case 0x12: /* SYNC_RELEASE */
15444 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
15446 case 0x13: /* SYNC_RMB */
15447 tcg_mo
|= TCG_MO_LD_LD
;
15450 tcg_mo
|= TCG_MO_ALL
;
15454 tcg_gen_mb(tcg_mo
);
15457 static void gen_pool32axf(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
15459 int extension
= (ctx
->opcode
>> 6) & 0x3f;
15460 int minor
= (ctx
->opcode
>> 12) & 0xf;
15461 uint32_t mips32_op
;
15463 switch (extension
) {
15465 mips32_op
= OPC_TEQ
;
15468 mips32_op
= OPC_TGE
;
15471 mips32_op
= OPC_TGEU
;
15474 mips32_op
= OPC_TLT
;
15477 mips32_op
= OPC_TLTU
;
15480 mips32_op
= OPC_TNE
;
15482 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
15484 #ifndef CONFIG_USER_ONLY
15487 check_cp0_enabled(ctx
);
15489 /* Treat as NOP. */
15492 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
15496 check_cp0_enabled(ctx
);
15498 TCGv t0
= tcg_temp_new();
15500 gen_load_gpr(t0
, rt
);
15501 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
15507 switch (minor
& 3) {
15509 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15512 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15515 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15518 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15521 goto pool32axf_invalid
;
15525 switch (minor
& 3) {
15527 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15530 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
15533 goto pool32axf_invalid
;
15539 check_insn(ctx
, ISA_MIPS32R6
);
15540 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
15543 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
15546 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
15549 mips32_op
= OPC_CLO
;
15552 mips32_op
= OPC_CLZ
;
15554 check_insn(ctx
, ISA_MIPS32
);
15555 gen_cl(ctx
, mips32_op
, rt
, rs
);
15558 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15559 gen_rdhwr(ctx
, rt
, rs
, 0);
15562 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
15565 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15566 mips32_op
= OPC_MULT
;
15569 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15570 mips32_op
= OPC_MULTU
;
15573 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15574 mips32_op
= OPC_DIV
;
15577 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15578 mips32_op
= OPC_DIVU
;
15581 check_insn(ctx
, ISA_MIPS32
);
15582 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15585 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15586 mips32_op
= OPC_MADD
;
15589 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15590 mips32_op
= OPC_MADDU
;
15593 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15594 mips32_op
= OPC_MSUB
;
15597 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15598 mips32_op
= OPC_MSUBU
;
15600 check_insn(ctx
, ISA_MIPS32
);
15601 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
15604 goto pool32axf_invalid
;
15615 generate_exception_err(ctx
, EXCP_CpU
, 2);
15618 goto pool32axf_invalid
;
15623 case JALR
: /* JALRC */
15624 case JALR_HB
: /* JALRC_HB */
15625 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15626 /* JALRC, JALRC_HB */
15627 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
15629 /* JALR, JALR_HB */
15630 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
15631 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15636 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15637 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
15638 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15641 goto pool32axf_invalid
;
15647 check_cp0_enabled(ctx
);
15648 check_insn(ctx
, ISA_MIPS32R2
);
15649 gen_load_srsgpr(rs
, rt
);
15652 check_cp0_enabled(ctx
);
15653 check_insn(ctx
, ISA_MIPS32R2
);
15654 gen_store_srsgpr(rs
, rt
);
15657 goto pool32axf_invalid
;
15660 #ifndef CONFIG_USER_ONLY
15664 mips32_op
= OPC_TLBP
;
15667 mips32_op
= OPC_TLBR
;
15670 mips32_op
= OPC_TLBWI
;
15673 mips32_op
= OPC_TLBWR
;
15676 mips32_op
= OPC_TLBINV
;
15679 mips32_op
= OPC_TLBINVF
;
15682 mips32_op
= OPC_WAIT
;
15685 mips32_op
= OPC_DERET
;
15688 mips32_op
= OPC_ERET
;
15690 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
15693 goto pool32axf_invalid
;
15699 check_cp0_enabled(ctx
);
15701 TCGv t0
= tcg_temp_new();
15703 save_cpu_state(ctx
, 1);
15704 gen_helper_di(t0
, cpu_env
);
15705 gen_store_gpr(t0
, rs
);
15707 * Stop translation as we may have switched the execution
15710 ctx
->base
.is_jmp
= DISAS_STOP
;
15715 check_cp0_enabled(ctx
);
15717 TCGv t0
= tcg_temp_new();
15719 save_cpu_state(ctx
, 1);
15720 gen_helper_ei(t0
, cpu_env
);
15721 gen_store_gpr(t0
, rs
);
15723 * DISAS_STOP isn't sufficient, we need to ensure we break out
15724 * of translated code to check for pending interrupts.
15726 gen_save_pc(ctx
->base
.pc_next
+ 4);
15727 ctx
->base
.is_jmp
= DISAS_EXIT
;
15732 goto pool32axf_invalid
;
15739 gen_sync(extract32(ctx
->opcode
, 16, 5));
15742 generate_exception_end(ctx
, EXCP_SYSCALL
);
15745 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
15746 gen_helper_do_semihosting(cpu_env
);
15748 check_insn(ctx
, ISA_MIPS32
);
15749 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
15750 generate_exception_end(ctx
, EXCP_RI
);
15752 generate_exception_end(ctx
, EXCP_DBp
);
15757 goto pool32axf_invalid
;
15761 switch (minor
& 3) {
15763 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
15766 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
15769 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
15772 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
15775 goto pool32axf_invalid
;
15779 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15782 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
15785 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
15788 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
15791 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
15794 goto pool32axf_invalid
;
15799 MIPS_INVAL("pool32axf");
15800 generate_exception_end(ctx
, EXCP_RI
);
15806 * Values for microMIPS fmt field. Variable-width, depending on which
15807 * formats the instruction supports.
15826 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
15828 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
15829 uint32_t mips32_op
;
15831 #define FLOAT_1BIT_FMT(opc, fmt) ((fmt << 8) | opc)
15832 #define FLOAT_2BIT_FMT(opc, fmt) ((fmt << 7) | opc)
15833 #define COND_FLOAT_MOV(opc, cond) ((cond << 7) | opc)
15835 switch (extension
) {
15836 case FLOAT_1BIT_FMT(CFC1
, 0):
15837 mips32_op
= OPC_CFC1
;
15839 case FLOAT_1BIT_FMT(CTC1
, 0):
15840 mips32_op
= OPC_CTC1
;
15842 case FLOAT_1BIT_FMT(MFC1
, 0):
15843 mips32_op
= OPC_MFC1
;
15845 case FLOAT_1BIT_FMT(MTC1
, 0):
15846 mips32_op
= OPC_MTC1
;
15848 case FLOAT_1BIT_FMT(MFHC1
, 0):
15849 mips32_op
= OPC_MFHC1
;
15851 case FLOAT_1BIT_FMT(MTHC1
, 0):
15852 mips32_op
= OPC_MTHC1
;
15854 gen_cp1(ctx
, mips32_op
, rt
, rs
);
15857 /* Reciprocal square root */
15858 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
15859 mips32_op
= OPC_RSQRT_S
;
15861 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
15862 mips32_op
= OPC_RSQRT_D
;
15866 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
15867 mips32_op
= OPC_SQRT_S
;
15869 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
15870 mips32_op
= OPC_SQRT_D
;
15874 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
15875 mips32_op
= OPC_RECIP_S
;
15877 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
15878 mips32_op
= OPC_RECIP_D
;
15882 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
15883 mips32_op
= OPC_FLOOR_L_S
;
15885 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
15886 mips32_op
= OPC_FLOOR_L_D
;
15888 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
15889 mips32_op
= OPC_FLOOR_W_S
;
15891 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
15892 mips32_op
= OPC_FLOOR_W_D
;
15896 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
15897 mips32_op
= OPC_CEIL_L_S
;
15899 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
15900 mips32_op
= OPC_CEIL_L_D
;
15902 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
15903 mips32_op
= OPC_CEIL_W_S
;
15905 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
15906 mips32_op
= OPC_CEIL_W_D
;
15910 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
15911 mips32_op
= OPC_TRUNC_L_S
;
15913 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
15914 mips32_op
= OPC_TRUNC_L_D
;
15916 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
15917 mips32_op
= OPC_TRUNC_W_S
;
15919 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
15920 mips32_op
= OPC_TRUNC_W_D
;
15924 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
15925 mips32_op
= OPC_ROUND_L_S
;
15927 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
15928 mips32_op
= OPC_ROUND_L_D
;
15930 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
15931 mips32_op
= OPC_ROUND_W_S
;
15933 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
15934 mips32_op
= OPC_ROUND_W_D
;
15937 /* Integer to floating-point conversion */
15938 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
15939 mips32_op
= OPC_CVT_L_S
;
15941 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
15942 mips32_op
= OPC_CVT_L_D
;
15944 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
15945 mips32_op
= OPC_CVT_W_S
;
15947 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
15948 mips32_op
= OPC_CVT_W_D
;
15951 /* Paired-foo conversions */
15952 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
15953 mips32_op
= OPC_CVT_S_PL
;
15955 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
15956 mips32_op
= OPC_CVT_S_PU
;
15958 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
15959 mips32_op
= OPC_CVT_PW_PS
;
15961 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
15962 mips32_op
= OPC_CVT_PS_PW
;
15965 /* Floating-point moves */
15966 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
15967 mips32_op
= OPC_MOV_S
;
15969 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
15970 mips32_op
= OPC_MOV_D
;
15972 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
15973 mips32_op
= OPC_MOV_PS
;
15976 /* Absolute value */
15977 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
15978 mips32_op
= OPC_ABS_S
;
15980 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
15981 mips32_op
= OPC_ABS_D
;
15983 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
15984 mips32_op
= OPC_ABS_PS
;
15988 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
15989 mips32_op
= OPC_NEG_S
;
15991 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
15992 mips32_op
= OPC_NEG_D
;
15994 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
15995 mips32_op
= OPC_NEG_PS
;
15998 /* Reciprocal square root step */
15999 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
16000 mips32_op
= OPC_RSQRT1_S
;
16002 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
16003 mips32_op
= OPC_RSQRT1_D
;
16005 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
16006 mips32_op
= OPC_RSQRT1_PS
;
16009 /* Reciprocal step */
16010 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
16011 mips32_op
= OPC_RECIP1_S
;
16013 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
16014 mips32_op
= OPC_RECIP1_S
;
16016 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
16017 mips32_op
= OPC_RECIP1_PS
;
16020 /* Conversions from double */
16021 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
16022 mips32_op
= OPC_CVT_D_S
;
16024 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
16025 mips32_op
= OPC_CVT_D_W
;
16027 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
16028 mips32_op
= OPC_CVT_D_L
;
16031 /* Conversions from single */
16032 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
16033 mips32_op
= OPC_CVT_S_D
;
16035 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
16036 mips32_op
= OPC_CVT_S_W
;
16038 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
16039 mips32_op
= OPC_CVT_S_L
;
16041 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
16044 /* Conditional moves on floating-point codes */
16045 case COND_FLOAT_MOV(MOVT
, 0):
16046 case COND_FLOAT_MOV(MOVT
, 1):
16047 case COND_FLOAT_MOV(MOVT
, 2):
16048 case COND_FLOAT_MOV(MOVT
, 3):
16049 case COND_FLOAT_MOV(MOVT
, 4):
16050 case COND_FLOAT_MOV(MOVT
, 5):
16051 case COND_FLOAT_MOV(MOVT
, 6):
16052 case COND_FLOAT_MOV(MOVT
, 7):
16053 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16054 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
16056 case COND_FLOAT_MOV(MOVF
, 0):
16057 case COND_FLOAT_MOV(MOVF
, 1):
16058 case COND_FLOAT_MOV(MOVF
, 2):
16059 case COND_FLOAT_MOV(MOVF
, 3):
16060 case COND_FLOAT_MOV(MOVF
, 4):
16061 case COND_FLOAT_MOV(MOVF
, 5):
16062 case COND_FLOAT_MOV(MOVF
, 6):
16063 case COND_FLOAT_MOV(MOVF
, 7):
16064 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16065 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
16068 MIPS_INVAL("pool32fxf");
16069 generate_exception_end(ctx
, EXCP_RI
);
16074 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
16078 int rt
, rs
, rd
, rr
;
16080 uint32_t op
, minor
, minor2
, mips32_op
;
16081 uint32_t cond
, fmt
, cc
;
16083 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
16084 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
16086 rt
= (ctx
->opcode
>> 21) & 0x1f;
16087 rs
= (ctx
->opcode
>> 16) & 0x1f;
16088 rd
= (ctx
->opcode
>> 11) & 0x1f;
16089 rr
= (ctx
->opcode
>> 6) & 0x1f;
16090 imm
= (int16_t) ctx
->opcode
;
16092 op
= (ctx
->opcode
>> 26) & 0x3f;
16095 minor
= ctx
->opcode
& 0x3f;
16098 minor
= (ctx
->opcode
>> 6) & 0xf;
16101 mips32_op
= OPC_SLL
;
16104 mips32_op
= OPC_SRA
;
16107 mips32_op
= OPC_SRL
;
16110 mips32_op
= OPC_ROTR
;
16112 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
16115 check_insn(ctx
, ISA_MIPS32R6
);
16116 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
16119 check_insn(ctx
, ISA_MIPS32R6
);
16120 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
16123 check_insn(ctx
, ISA_MIPS32R6
);
16124 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
16127 goto pool32a_invalid
;
16131 minor
= (ctx
->opcode
>> 6) & 0xf;
16135 mips32_op
= OPC_ADD
;
16138 mips32_op
= OPC_ADDU
;
16141 mips32_op
= OPC_SUB
;
16144 mips32_op
= OPC_SUBU
;
16147 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16148 mips32_op
= OPC_MUL
;
16150 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
16154 mips32_op
= OPC_SLLV
;
16157 mips32_op
= OPC_SRLV
;
16160 mips32_op
= OPC_SRAV
;
16163 mips32_op
= OPC_ROTRV
;
16165 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
16167 /* Logical operations */
16169 mips32_op
= OPC_AND
;
16172 mips32_op
= OPC_OR
;
16175 mips32_op
= OPC_NOR
;
16178 mips32_op
= OPC_XOR
;
16180 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
16182 /* Set less than */
16184 mips32_op
= OPC_SLT
;
16187 mips32_op
= OPC_SLTU
;
16189 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
16192 goto pool32a_invalid
;
16196 minor
= (ctx
->opcode
>> 6) & 0xf;
16198 /* Conditional moves */
16199 case MOVN
: /* MUL */
16200 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16202 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
16205 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
16208 case MOVZ
: /* MUH */
16209 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16211 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
16214 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
16218 check_insn(ctx
, ISA_MIPS32R6
);
16219 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
16222 check_insn(ctx
, ISA_MIPS32R6
);
16223 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
16225 case LWXS
: /* DIV */
16226 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16228 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
16231 gen_ldxs(ctx
, rs
, rt
, rd
);
16235 check_insn(ctx
, ISA_MIPS32R6
);
16236 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
16239 check_insn(ctx
, ISA_MIPS32R6
);
16240 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
16243 check_insn(ctx
, ISA_MIPS32R6
);
16244 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
16247 goto pool32a_invalid
;
16251 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
16254 check_insn(ctx
, ISA_MIPS32R6
);
16255 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
16256 extract32(ctx
->opcode
, 9, 2));
16259 check_insn(ctx
, ISA_MIPS32R6
);
16260 gen_align(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 9, 2));
16263 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
16266 gen_pool32axf(env
, ctx
, rt
, rs
);
16269 generate_exception_end(ctx
, EXCP_BREAK
);
16272 check_insn(ctx
, ISA_MIPS32R6
);
16273 generate_exception_end(ctx
, EXCP_RI
);
16277 MIPS_INVAL("pool32a");
16278 generate_exception_end(ctx
, EXCP_RI
);
16283 minor
= (ctx
->opcode
>> 12) & 0xf;
16286 check_cp0_enabled(ctx
);
16287 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
16288 gen_cache_operation(ctx
, rt
, rs
, imm
);
16293 /* COP2: Not implemented. */
16294 generate_exception_err(ctx
, EXCP_CpU
, 2);
16296 #ifdef TARGET_MIPS64
16299 check_insn(ctx
, ISA_MIPS3
);
16300 check_mips_64(ctx
);
16305 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16307 #ifdef TARGET_MIPS64
16310 check_insn(ctx
, ISA_MIPS3
);
16311 check_mips_64(ctx
);
16316 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
16319 MIPS_INVAL("pool32b");
16320 generate_exception_end(ctx
, EXCP_RI
);
16325 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
16326 minor
= ctx
->opcode
& 0x3f;
16327 check_cp1_enabled(ctx
);
16330 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16331 mips32_op
= OPC_ALNV_PS
;
16334 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16335 mips32_op
= OPC_MADD_S
;
16338 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16339 mips32_op
= OPC_MADD_D
;
16342 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16343 mips32_op
= OPC_MADD_PS
;
16346 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16347 mips32_op
= OPC_MSUB_S
;
16350 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16351 mips32_op
= OPC_MSUB_D
;
16354 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16355 mips32_op
= OPC_MSUB_PS
;
16358 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16359 mips32_op
= OPC_NMADD_S
;
16362 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16363 mips32_op
= OPC_NMADD_D
;
16366 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16367 mips32_op
= OPC_NMADD_PS
;
16370 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16371 mips32_op
= OPC_NMSUB_S
;
16374 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16375 mips32_op
= OPC_NMSUB_D
;
16378 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16379 mips32_op
= OPC_NMSUB_PS
;
16381 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
16383 case CABS_COND_FMT
:
16384 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16385 cond
= (ctx
->opcode
>> 6) & 0xf;
16386 cc
= (ctx
->opcode
>> 13) & 0x7;
16387 fmt
= (ctx
->opcode
>> 10) & 0x3;
16390 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
16393 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
16396 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
16399 goto pool32f_invalid
;
16403 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16404 cond
= (ctx
->opcode
>> 6) & 0xf;
16405 cc
= (ctx
->opcode
>> 13) & 0x7;
16406 fmt
= (ctx
->opcode
>> 10) & 0x3;
16409 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
16412 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
16415 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
16418 goto pool32f_invalid
;
16422 check_insn(ctx
, ISA_MIPS32R6
);
16423 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16426 check_insn(ctx
, ISA_MIPS32R6
);
16427 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
16430 gen_pool32fxf(ctx
, rt
, rs
);
16434 switch ((ctx
->opcode
>> 6) & 0x7) {
16436 mips32_op
= OPC_PLL_PS
;
16439 mips32_op
= OPC_PLU_PS
;
16442 mips32_op
= OPC_PUL_PS
;
16445 mips32_op
= OPC_PUU_PS
;
16448 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16449 mips32_op
= OPC_CVT_PS_S
;
16451 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16454 goto pool32f_invalid
;
16458 check_insn(ctx
, ISA_MIPS32R6
);
16459 switch ((ctx
->opcode
>> 9) & 0x3) {
16461 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
16464 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
16467 goto pool32f_invalid
;
16472 switch ((ctx
->opcode
>> 6) & 0x7) {
16474 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16475 mips32_op
= OPC_LWXC1
;
16478 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16479 mips32_op
= OPC_SWXC1
;
16482 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16483 mips32_op
= OPC_LDXC1
;
16486 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16487 mips32_op
= OPC_SDXC1
;
16490 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16491 mips32_op
= OPC_LUXC1
;
16494 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16495 mips32_op
= OPC_SUXC1
;
16497 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
16500 goto pool32f_invalid
;
16504 check_insn(ctx
, ISA_MIPS32R6
);
16505 switch ((ctx
->opcode
>> 9) & 0x3) {
16507 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
16510 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
16513 goto pool32f_invalid
;
16518 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16519 fmt
= (ctx
->opcode
>> 9) & 0x3;
16520 switch ((ctx
->opcode
>> 6) & 0x7) {
16524 mips32_op
= OPC_RSQRT2_S
;
16527 mips32_op
= OPC_RSQRT2_D
;
16530 mips32_op
= OPC_RSQRT2_PS
;
16533 goto pool32f_invalid
;
16539 mips32_op
= OPC_RECIP2_S
;
16542 mips32_op
= OPC_RECIP2_D
;
16545 mips32_op
= OPC_RECIP2_PS
;
16548 goto pool32f_invalid
;
16552 mips32_op
= OPC_ADDR_PS
;
16555 mips32_op
= OPC_MULR_PS
;
16557 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16560 goto pool32f_invalid
;
16564 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16565 cc
= (ctx
->opcode
>> 13) & 0x7;
16566 fmt
= (ctx
->opcode
>> 9) & 0x3;
16567 switch ((ctx
->opcode
>> 6) & 0x7) {
16568 case MOVF_FMT
: /* RINT_FMT */
16569 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16573 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
16576 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
16579 goto pool32f_invalid
;
16585 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
16588 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
16592 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
16595 goto pool32f_invalid
;
16599 case MOVT_FMT
: /* CLASS_FMT */
16600 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16604 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
16607 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
16610 goto pool32f_invalid
;
16616 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
16619 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
16623 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
16626 goto pool32f_invalid
;
16631 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16634 goto pool32f_invalid
;
16637 #define FINSN_3ARG_SDPS(prfx) \
16638 switch ((ctx->opcode >> 8) & 0x3) { \
16640 mips32_op = OPC_##prfx##_S; \
16643 mips32_op = OPC_##prfx##_D; \
16645 case FMT_SDPS_PS: \
16647 mips32_op = OPC_##prfx##_PS; \
16650 goto pool32f_invalid; \
16653 check_insn(ctx
, ISA_MIPS32R6
);
16654 switch ((ctx
->opcode
>> 9) & 0x3) {
16656 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
16659 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
16662 goto pool32f_invalid
;
16666 check_insn(ctx
, ISA_MIPS32R6
);
16667 switch ((ctx
->opcode
>> 9) & 0x3) {
16669 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
16672 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
16675 goto pool32f_invalid
;
16679 /* regular FP ops */
16680 switch ((ctx
->opcode
>> 6) & 0x3) {
16682 FINSN_3ARG_SDPS(ADD
);
16685 FINSN_3ARG_SDPS(SUB
);
16688 FINSN_3ARG_SDPS(MUL
);
16691 fmt
= (ctx
->opcode
>> 8) & 0x3;
16693 mips32_op
= OPC_DIV_D
;
16694 } else if (fmt
== 0) {
16695 mips32_op
= OPC_DIV_S
;
16697 goto pool32f_invalid
;
16701 goto pool32f_invalid
;
16706 switch ((ctx
->opcode
>> 6) & 0x7) {
16707 case MOVN_FMT
: /* SELEQZ_FMT */
16708 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16710 switch ((ctx
->opcode
>> 9) & 0x3) {
16712 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
16715 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
16718 goto pool32f_invalid
;
16722 FINSN_3ARG_SDPS(MOVN
);
16726 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16727 FINSN_3ARG_SDPS(MOVN
);
16729 case MOVZ_FMT
: /* SELNEZ_FMT */
16730 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16732 switch ((ctx
->opcode
>> 9) & 0x3) {
16734 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
16737 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
16740 goto pool32f_invalid
;
16744 FINSN_3ARG_SDPS(MOVZ
);
16748 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16749 FINSN_3ARG_SDPS(MOVZ
);
16752 check_insn(ctx
, ISA_MIPS32R6
);
16753 switch ((ctx
->opcode
>> 9) & 0x3) {
16755 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
16758 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
16761 goto pool32f_invalid
;
16765 check_insn(ctx
, ISA_MIPS32R6
);
16766 switch ((ctx
->opcode
>> 9) & 0x3) {
16768 mips32_op
= OPC_MADDF_S
;
16771 mips32_op
= OPC_MADDF_D
;
16774 goto pool32f_invalid
;
16778 check_insn(ctx
, ISA_MIPS32R6
);
16779 switch ((ctx
->opcode
>> 9) & 0x3) {
16781 mips32_op
= OPC_MSUBF_S
;
16784 mips32_op
= OPC_MSUBF_D
;
16787 goto pool32f_invalid
;
16791 goto pool32f_invalid
;
16795 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
16799 MIPS_INVAL("pool32f");
16800 generate_exception_end(ctx
, EXCP_RI
);
16804 generate_exception_err(ctx
, EXCP_CpU
, 1);
16808 minor
= (ctx
->opcode
>> 21) & 0x1f;
16811 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16812 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
16815 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16816 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
16817 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16820 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16821 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
16822 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16825 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16826 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
16829 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16830 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
16831 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16834 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16835 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
16836 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
16839 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16840 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
16843 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16844 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
16848 case TLTI
: /* BC1EQZC */
16849 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16851 check_cp1_enabled(ctx
);
16852 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
16855 mips32_op
= OPC_TLTI
;
16859 case TGEI
: /* BC1NEZC */
16860 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16862 check_cp1_enabled(ctx
);
16863 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
16866 mips32_op
= OPC_TGEI
;
16871 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16872 mips32_op
= OPC_TLTIU
;
16875 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16876 mips32_op
= OPC_TGEIU
;
16878 case TNEI
: /* SYNCI */
16879 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16882 * Break the TB to be able to sync copied instructions
16885 ctx
->base
.is_jmp
= DISAS_STOP
;
16888 mips32_op
= OPC_TNEI
;
16893 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16894 mips32_op
= OPC_TEQI
;
16896 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
16901 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16902 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
16903 4, rs
, 0, imm
<< 1, 0);
16905 * Compact branches don't have a delay slot, so just let
16906 * the normal delay slot handling take us to the branch
16911 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16912 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
16915 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16917 * Break the TB to be able to sync copied instructions
16920 ctx
->base
.is_jmp
= DISAS_STOP
;
16924 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16925 /* COP2: Not implemented. */
16926 generate_exception_err(ctx
, EXCP_CpU
, 2);
16929 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16930 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
16933 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16934 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
16937 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16938 mips32_op
= OPC_BC1FANY4
;
16941 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16942 mips32_op
= OPC_BC1TANY4
;
16945 check_insn(ctx
, ASE_MIPS3D
);
16948 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16949 check_cp1_enabled(ctx
);
16950 gen_compute_branch1(ctx
, mips32_op
,
16951 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
16953 generate_exception_err(ctx
, EXCP_CpU
, 1);
16958 /* MIPS DSP: not implemented */
16961 MIPS_INVAL("pool32i");
16962 generate_exception_end(ctx
, EXCP_RI
);
16967 minor
= (ctx
->opcode
>> 12) & 0xf;
16968 offset
= sextract32(ctx
->opcode
, 0,
16969 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
16972 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16973 mips32_op
= OPC_LWL
;
16976 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16977 mips32_op
= OPC_SWL
;
16980 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16981 mips32_op
= OPC_LWR
;
16984 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16985 mips32_op
= OPC_SWR
;
16987 #if defined(TARGET_MIPS64)
16989 check_insn(ctx
, ISA_MIPS3
);
16990 check_mips_64(ctx
);
16991 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16992 mips32_op
= OPC_LDL
;
16995 check_insn(ctx
, ISA_MIPS3
);
16996 check_mips_64(ctx
);
16997 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16998 mips32_op
= OPC_SDL
;
17001 check_insn(ctx
, ISA_MIPS3
);
17002 check_mips_64(ctx
);
17003 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17004 mips32_op
= OPC_LDR
;
17007 check_insn(ctx
, ISA_MIPS3
);
17008 check_mips_64(ctx
);
17009 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17010 mips32_op
= OPC_SDR
;
17013 check_insn(ctx
, ISA_MIPS3
);
17014 check_mips_64(ctx
);
17015 mips32_op
= OPC_LWU
;
17018 check_insn(ctx
, ISA_MIPS3
);
17019 check_mips_64(ctx
);
17020 mips32_op
= OPC_LLD
;
17024 mips32_op
= OPC_LL
;
17027 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
17030 gen_st(ctx
, mips32_op
, rt
, rs
, offset
);
17033 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, false);
17035 #if defined(TARGET_MIPS64)
17037 check_insn(ctx
, ISA_MIPS3
);
17038 check_mips_64(ctx
);
17039 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TEQ
, false);
17044 MIPS_INVAL("pool32c ld-eva");
17045 generate_exception_end(ctx
, EXCP_RI
);
17048 check_cp0_enabled(ctx
);
17050 minor2
= (ctx
->opcode
>> 9) & 0x7;
17051 offset
= sextract32(ctx
->opcode
, 0, 9);
17054 mips32_op
= OPC_LBUE
;
17057 mips32_op
= OPC_LHUE
;
17060 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17061 mips32_op
= OPC_LWLE
;
17064 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17065 mips32_op
= OPC_LWRE
;
17068 mips32_op
= OPC_LBE
;
17071 mips32_op
= OPC_LHE
;
17074 mips32_op
= OPC_LLE
;
17077 mips32_op
= OPC_LWE
;
17083 MIPS_INVAL("pool32c st-eva");
17084 generate_exception_end(ctx
, EXCP_RI
);
17087 check_cp0_enabled(ctx
);
17089 minor2
= (ctx
->opcode
>> 9) & 0x7;
17090 offset
= sextract32(ctx
->opcode
, 0, 9);
17093 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17094 mips32_op
= OPC_SWLE
;
17097 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17098 mips32_op
= OPC_SWRE
;
17101 /* Treat as no-op */
17102 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17103 /* hint codes 24-31 are reserved and signal RI */
17104 generate_exception(ctx
, EXCP_RI
);
17108 /* Treat as no-op */
17109 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17110 gen_cache_operation(ctx
, rt
, rs
, offset
);
17114 mips32_op
= OPC_SBE
;
17117 mips32_op
= OPC_SHE
;
17120 gen_st_cond(ctx
, rt
, rs
, offset
, MO_TESL
, true);
17123 mips32_op
= OPC_SWE
;
17128 /* Treat as no-op */
17129 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
17130 /* hint codes 24-31 are reserved and signal RI */
17131 generate_exception(ctx
, EXCP_RI
);
17135 MIPS_INVAL("pool32c");
17136 generate_exception_end(ctx
, EXCP_RI
);
17140 case ADDI32
: /* AUI, LUI */
17141 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17143 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
17146 mips32_op
= OPC_ADDI
;
17151 mips32_op
= OPC_ADDIU
;
17153 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17156 /* Logical operations */
17158 mips32_op
= OPC_ORI
;
17161 mips32_op
= OPC_XORI
;
17164 mips32_op
= OPC_ANDI
;
17166 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17169 /* Set less than immediate */
17171 mips32_op
= OPC_SLTI
;
17174 mips32_op
= OPC_SLTIU
;
17176 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
17179 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17180 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17181 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
17182 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17184 case JALS32
: /* BOVC, BEQC, BEQZALC */
17185 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17188 mips32_op
= OPC_BOVC
;
17189 } else if (rs
< rt
&& rs
== 0) {
17191 mips32_op
= OPC_BEQZALC
;
17194 mips32_op
= OPC_BEQC
;
17196 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17199 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
17200 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
17201 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17204 case BEQ32
: /* BC */
17205 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17207 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
17208 sextract32(ctx
->opcode
<< 1, 0, 27));
17211 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
17214 case BNE32
: /* BALC */
17215 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17217 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
17218 sextract32(ctx
->opcode
<< 1, 0, 27));
17221 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
17224 case J32
: /* BGTZC, BLTZC, BLTC */
17225 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17226 if (rs
== 0 && rt
!= 0) {
17228 mips32_op
= OPC_BGTZC
;
17229 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17231 mips32_op
= OPC_BLTZC
;
17234 mips32_op
= OPC_BLTC
;
17236 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17239 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
17240 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17243 case JAL32
: /* BLEZC, BGEZC, BGEC */
17244 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17245 if (rs
== 0 && rt
!= 0) {
17247 mips32_op
= OPC_BLEZC
;
17248 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17250 mips32_op
= OPC_BGEZC
;
17253 mips32_op
= OPC_BGEC
;
17255 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17258 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
17259 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
17260 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
17263 /* Floating point (COP1) */
17265 mips32_op
= OPC_LWC1
;
17268 mips32_op
= OPC_LDC1
;
17271 mips32_op
= OPC_SWC1
;
17274 mips32_op
= OPC_SDC1
;
17276 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
17278 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17279 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17280 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17281 switch ((ctx
->opcode
>> 16) & 0x1f) {
17290 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17293 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->base
.pc_next
, rt
);
17296 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->base
.pc_next
, rt
);
17306 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->base
.pc_next
& ~0x3, rt
);
17309 generate_exception(ctx
, EXCP_RI
);
17314 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
17315 offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
17317 gen_addiupc(ctx
, reg
, offset
, 0, 0);
17320 case BNVC
: /* BNEC, BNEZALC */
17321 check_insn(ctx
, ISA_MIPS32R6
);
17324 mips32_op
= OPC_BNVC
;
17325 } else if (rs
< rt
&& rs
== 0) {
17327 mips32_op
= OPC_BNEZALC
;
17330 mips32_op
= OPC_BNEC
;
17332 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17334 case R6_BNEZC
: /* JIALC */
17335 check_insn(ctx
, ISA_MIPS32R6
);
17338 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
17339 sextract32(ctx
->opcode
<< 1, 0, 22));
17342 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
17345 case R6_BEQZC
: /* JIC */
17346 check_insn(ctx
, ISA_MIPS32R6
);
17349 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
17350 sextract32(ctx
->opcode
<< 1, 0, 22));
17353 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
17356 case BLEZALC
: /* BGEZALC, BGEUC */
17357 check_insn(ctx
, ISA_MIPS32R6
);
17358 if (rs
== 0 && rt
!= 0) {
17360 mips32_op
= OPC_BLEZALC
;
17361 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17363 mips32_op
= OPC_BGEZALC
;
17366 mips32_op
= OPC_BGEUC
;
17368 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17370 case BGTZALC
: /* BLTZALC, BLTUC */
17371 check_insn(ctx
, ISA_MIPS32R6
);
17372 if (rs
== 0 && rt
!= 0) {
17374 mips32_op
= OPC_BGTZALC
;
17375 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
17377 mips32_op
= OPC_BLTZALC
;
17380 mips32_op
= OPC_BLTUC
;
17382 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
17384 /* Loads and stores */
17386 mips32_op
= OPC_LB
;
17389 mips32_op
= OPC_LBU
;
17392 mips32_op
= OPC_LH
;
17395 mips32_op
= OPC_LHU
;
17398 mips32_op
= OPC_LW
;
17400 #ifdef TARGET_MIPS64
17402 check_insn(ctx
, ISA_MIPS3
);
17403 check_mips_64(ctx
);
17404 mips32_op
= OPC_LD
;
17407 check_insn(ctx
, ISA_MIPS3
);
17408 check_mips_64(ctx
);
17409 mips32_op
= OPC_SD
;
17413 mips32_op
= OPC_SB
;
17416 mips32_op
= OPC_SH
;
17419 mips32_op
= OPC_SW
;
17422 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
17425 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
17428 generate_exception_end(ctx
, EXCP_RI
);
17433 static int decode_micromips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
17437 /* make sure instructions are on a halfword boundary */
17438 if (ctx
->base
.pc_next
& 0x1) {
17439 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
17440 generate_exception_end(ctx
, EXCP_AdEL
);
17444 op
= (ctx
->opcode
>> 10) & 0x3f;
17445 /* Enforce properly-sized instructions in a delay slot */
17446 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
17447 switch (op
& 0x7) { /* MSB-3..MSB-5 */
17449 /* POOL32A, POOL32B, POOL32I, POOL32C */
17451 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17453 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17455 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17457 /* LB32, LH32, LWC132, LDC132, LW32 */
17458 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
17459 generate_exception_end(ctx
, EXCP_RI
);
17464 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17466 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17468 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17469 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
17470 generate_exception_end(ctx
, EXCP_RI
);
17480 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17481 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
17482 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
17485 switch (ctx
->opcode
& 0x1) {
17493 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17495 * In the Release 6, the register number location in
17496 * the instruction encoding has changed.
17498 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
17500 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
17506 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17507 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
17508 int amount
= (ctx
->opcode
>> 1) & 0x7;
17510 amount
= amount
== 0 ? 8 : amount
;
17512 switch (ctx
->opcode
& 0x1) {
17521 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
17525 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17526 gen_pool16c_r6_insn(ctx
);
17528 gen_pool16c_insn(ctx
);
17533 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17534 int rb
= 28; /* GP */
17535 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
17537 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17541 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17542 if (ctx
->opcode
& 1) {
17543 generate_exception_end(ctx
, EXCP_RI
);
17546 int enc_dest
= uMIPS_RD(ctx
->opcode
);
17547 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
17548 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
17549 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
17554 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17555 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17556 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17557 offset
= (offset
== 0xf ? -1 : offset
);
17559 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
17564 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17565 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17566 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17568 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
17573 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17574 int rb
= 29; /* SP */
17575 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17577 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17582 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
17583 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17584 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17586 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
17591 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17592 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17593 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
17595 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
17600 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17601 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17602 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
17604 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
17609 int rd
= (ctx
->opcode
>> 5) & 0x1f;
17610 int rb
= 29; /* SP */
17611 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
17613 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17618 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
17619 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
17620 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
17622 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
17627 int rd
= uMIPS_RD5(ctx
->opcode
);
17628 int rs
= uMIPS_RS5(ctx
->opcode
);
17630 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
17637 switch (ctx
->opcode
& 0x1) {
17647 switch (ctx
->opcode
& 0x1) {
17652 gen_addiur1sp(ctx
);
17656 case B16
: /* BC16 */
17657 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
17658 sextract32(ctx
->opcode
, 0, 10) << 1,
17659 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
17661 case BNEZ16
: /* BNEZC16 */
17662 case BEQZ16
: /* BEQZC16 */
17663 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
17664 mmreg(uMIPS_RD(ctx
->opcode
)),
17665 0, sextract32(ctx
->opcode
, 0, 7) << 1,
17666 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
17671 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
17672 int imm
= ZIMM(ctx
->opcode
, 0, 7);
17674 imm
= (imm
== 0x7f ? -1 : imm
);
17675 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
17681 generate_exception_end(ctx
, EXCP_RI
);
17684 decode_micromips32_opc(env
, ctx
);
17697 /* MAJOR, P16, and P32 pools opcodes */
17701 NM_MOVE_BALC
= 0x02,
17709 NM_P16_SHIFT
= 0x0c,
17727 NM_P_LS_U12
= 0x21,
17737 NM_P16_ADDU
= 0x2c,
17751 NM_MOVEPREV
= 0x3f,
17754 /* POOL32A instruction pool */
17756 NM_POOL32A0
= 0x00,
17757 NM_SPECIAL2
= 0x01,
17760 NM_POOL32A5
= 0x05,
17761 NM_POOL32A7
= 0x07,
17764 /* P.GP.W instruction pool */
17766 NM_ADDIUGP_W
= 0x00,
17771 /* P48I instruction pool */
17775 NM_ADDIUGP48
= 0x02,
17776 NM_ADDIUPC48
= 0x03,
17781 /* P.U12 instruction pool */
17790 NM_ADDIUNEG
= 0x08,
17797 /* POOL32F instruction pool */
17799 NM_POOL32F_0
= 0x00,
17800 NM_POOL32F_3
= 0x03,
17801 NM_POOL32F_5
= 0x05,
17804 /* POOL32S instruction pool */
17806 NM_POOL32S_0
= 0x00,
17807 NM_POOL32S_4
= 0x04,
17810 /* P.LUI instruction pool */
17816 /* P.GP.BH instruction pool */
17821 NM_ADDIUGP_B
= 0x03,
17824 NM_P_GP_CP1
= 0x06,
17827 /* P.LS.U12 instruction pool */
17832 NM_P_PREFU12
= 0x03,
17845 /* P.LS.S9 instruction pool */
17851 NM_P_LS_UAWM
= 0x05,
17854 /* P.BAL instruction pool */
17860 /* P.J instruction pool */
17863 NM_JALRC_HB
= 0x01,
17864 NM_P_BALRSC
= 0x08,
17867 /* P.BR1 instruction pool */
17875 /* P.BR2 instruction pool */
17882 /* P.BRI instruction pool */
17894 /* P16.SHIFT instruction pool */
17900 /* POOL16C instruction pool */
17902 NM_POOL16C_0
= 0x00,
17906 /* P16.A1 instruction pool */
17908 NM_ADDIUR1SP
= 0x01,
17911 /* P16.A2 instruction pool */
17914 NM_P_ADDIURS5
= 0x01,
17917 /* P16.ADDU instruction pool */
17923 /* P16.SR instruction pool */
17926 NM_RESTORE_JRC16
= 0x01,
17929 /* P16.4X4 instruction pool */
17935 /* P16.LB instruction pool */
17942 /* P16.LH instruction pool */
17949 /* P.RI instruction pool */
17952 NM_P_SYSCALL
= 0x01,
17957 /* POOL32A0 instruction pool */
17992 NM_D_E_MT_VPE
= 0x56,
18000 /* CRC32 instruction pool */
18010 /* POOL32A5 instruction pool */
18012 NM_CMP_EQ_PH
= 0x00,
18013 NM_CMP_LT_PH
= 0x08,
18014 NM_CMP_LE_PH
= 0x10,
18015 NM_CMPGU_EQ_QB
= 0x18,
18016 NM_CMPGU_LT_QB
= 0x20,
18017 NM_CMPGU_LE_QB
= 0x28,
18018 NM_CMPGDU_EQ_QB
= 0x30,
18019 NM_CMPGDU_LT_QB
= 0x38,
18020 NM_CMPGDU_LE_QB
= 0x40,
18021 NM_CMPU_EQ_QB
= 0x48,
18022 NM_CMPU_LT_QB
= 0x50,
18023 NM_CMPU_LE_QB
= 0x58,
18024 NM_ADDQ_S_W
= 0x60,
18025 NM_SUBQ_S_W
= 0x68,
18029 NM_ADDQ_S_PH
= 0x01,
18030 NM_ADDQH_R_PH
= 0x09,
18031 NM_ADDQH_R_W
= 0x11,
18032 NM_ADDU_S_QB
= 0x19,
18033 NM_ADDU_S_PH
= 0x21,
18034 NM_ADDUH_R_QB
= 0x29,
18035 NM_SHRAV_R_PH
= 0x31,
18036 NM_SHRAV_R_QB
= 0x39,
18037 NM_SUBQ_S_PH
= 0x41,
18038 NM_SUBQH_R_PH
= 0x49,
18039 NM_SUBQH_R_W
= 0x51,
18040 NM_SUBU_S_QB
= 0x59,
18041 NM_SUBU_S_PH
= 0x61,
18042 NM_SUBUH_R_QB
= 0x69,
18043 NM_SHLLV_S_PH
= 0x71,
18044 NM_PRECR_SRA_R_PH_W
= 0x79,
18046 NM_MULEU_S_PH_QBL
= 0x12,
18047 NM_MULEU_S_PH_QBR
= 0x1a,
18048 NM_MULQ_RS_PH
= 0x22,
18049 NM_MULQ_S_PH
= 0x2a,
18050 NM_MULQ_RS_W
= 0x32,
18051 NM_MULQ_S_W
= 0x3a,
18054 NM_SHRAV_R_W
= 0x5a,
18055 NM_SHRLV_PH
= 0x62,
18056 NM_SHRLV_QB
= 0x6a,
18057 NM_SHLLV_QB
= 0x72,
18058 NM_SHLLV_S_W
= 0x7a,
18062 NM_MULEQ_S_W_PHL
= 0x04,
18063 NM_MULEQ_S_W_PHR
= 0x0c,
18065 NM_MUL_S_PH
= 0x05,
18066 NM_PRECR_QB_PH
= 0x0d,
18067 NM_PRECRQ_QB_PH
= 0x15,
18068 NM_PRECRQ_PH_W
= 0x1d,
18069 NM_PRECRQ_RS_PH_W
= 0x25,
18070 NM_PRECRQU_S_QB_PH
= 0x2d,
18071 NM_PACKRL_PH
= 0x35,
18075 NM_SHRA_R_W
= 0x5e,
18076 NM_SHRA_R_PH
= 0x66,
18077 NM_SHLL_S_PH
= 0x76,
18078 NM_SHLL_S_W
= 0x7e,
18083 /* POOL32A7 instruction pool */
18088 NM_POOL32AXF
= 0x07,
18091 /* P.SR instruction pool */
18097 /* P.SHIFT instruction pool */
18105 /* P.ROTX instruction pool */
18110 /* P.INS instruction pool */
18115 /* P.EXT instruction pool */
18120 /* POOL32F_0 (fmt) instruction pool */
18125 NM_SELEQZ_S
= 0x07,
18126 NM_SELEQZ_D
= 0x47,
18130 NM_SELNEZ_S
= 0x0f,
18131 NM_SELNEZ_D
= 0x4f,
18146 /* POOL32F_3 instruction pool */
18150 NM_MINA_FMT
= 0x04,
18151 NM_MAXA_FMT
= 0x05,
18152 NM_POOL32FXF
= 0x07,
18155 /* POOL32F_5 instruction pool */
18157 NM_CMP_CONDN_S
= 0x00,
18158 NM_CMP_CONDN_D
= 0x02,
18161 /* P.GP.LH instruction pool */
18167 /* P.GP.SH instruction pool */
18172 /* P.GP.CP1 instruction pool */
18180 /* P.LS.S0 instruction pool */
18197 NM_P_PREFS9
= 0x03,
18203 /* P.LS.S1 instruction pool */
18205 NM_ASET_ACLR
= 0x02,
18213 /* P.LS.E0 instruction pool */
18229 /* P.PREFE instruction pool */
18235 /* P.LLE instruction pool */
18241 /* P.SCE instruction pool */
18247 /* P.LS.WM instruction pool */
18253 /* P.LS.UAWM instruction pool */
18259 /* P.BR3A instruction pool */
18265 NM_BPOSGE32C
= 0x04,
18268 /* P16.RI instruction pool */
18270 NM_P16_SYSCALL
= 0x01,
18275 /* POOL16C_0 instruction pool */
18277 NM_POOL16C_00
= 0x00,
18280 /* P16.JRC instruction pool */
18286 /* P.SYSCALL instruction pool */
18292 /* P.TRAP instruction pool */
18298 /* P.CMOVE instruction pool */
18304 /* POOL32Axf instruction pool */
18306 NM_POOL32AXF_1
= 0x01,
18307 NM_POOL32AXF_2
= 0x02,
18308 NM_POOL32AXF_4
= 0x04,
18309 NM_POOL32AXF_5
= 0x05,
18310 NM_POOL32AXF_7
= 0x07,
18313 /* POOL32Axf_1 instruction pool */
18315 NM_POOL32AXF_1_0
= 0x00,
18316 NM_POOL32AXF_1_1
= 0x01,
18317 NM_POOL32AXF_1_3
= 0x03,
18318 NM_POOL32AXF_1_4
= 0x04,
18319 NM_POOL32AXF_1_5
= 0x05,
18320 NM_POOL32AXF_1_7
= 0x07,
18323 /* POOL32Axf_2 instruction pool */
18325 NM_POOL32AXF_2_0_7
= 0x00,
18326 NM_POOL32AXF_2_8_15
= 0x01,
18327 NM_POOL32AXF_2_16_23
= 0x02,
18328 NM_POOL32AXF_2_24_31
= 0x03,
18331 /* POOL32Axf_7 instruction pool */
18333 NM_SHRA_R_QB
= 0x0,
18338 /* POOL32Axf_1_0 instruction pool */
18346 /* POOL32Axf_1_1 instruction pool */
18352 /* POOL32Axf_1_3 instruction pool */
18360 /* POOL32Axf_1_4 instruction pool */
18366 /* POOL32Axf_1_5 instruction pool */
18368 NM_MAQ_S_W_PHR
= 0x0,
18369 NM_MAQ_S_W_PHL
= 0x1,
18370 NM_MAQ_SA_W_PHR
= 0x2,
18371 NM_MAQ_SA_W_PHL
= 0x3,
18374 /* POOL32Axf_1_7 instruction pool */
18378 NM_EXTR_RS_W
= 0x2,
18382 /* POOL32Axf_2_0_7 instruction pool */
18385 NM_DPAQ_S_W_PH
= 0x1,
18387 NM_DPSQ_S_W_PH
= 0x3,
18394 /* POOL32Axf_2_8_15 instruction pool */
18396 NM_DPAX_W_PH
= 0x0,
18397 NM_DPAQ_SA_L_W
= 0x1,
18398 NM_DPSX_W_PH
= 0x2,
18399 NM_DPSQ_SA_L_W
= 0x3,
18402 NM_EXTRV_R_W
= 0x7,
18405 /* POOL32Axf_2_16_23 instruction pool */
18407 NM_DPAU_H_QBL
= 0x0,
18408 NM_DPAQX_S_W_PH
= 0x1,
18409 NM_DPSU_H_QBL
= 0x2,
18410 NM_DPSQX_S_W_PH
= 0x3,
18413 NM_MULSA_W_PH
= 0x6,
18414 NM_EXTRV_RS_W
= 0x7,
18417 /* POOL32Axf_2_24_31 instruction pool */
18419 NM_DPAU_H_QBR
= 0x0,
18420 NM_DPAQX_SA_W_PH
= 0x1,
18421 NM_DPSU_H_QBR
= 0x2,
18422 NM_DPSQX_SA_W_PH
= 0x3,
18425 NM_MULSAQ_S_W_PH
= 0x6,
18426 NM_EXTRV_S_H
= 0x7,
18429 /* POOL32Axf_{4, 5} instruction pool */
18448 /* nanoMIPS DSP instructions */
18449 NM_ABSQ_S_QB
= 0x00,
18450 NM_ABSQ_S_PH
= 0x08,
18451 NM_ABSQ_S_W
= 0x10,
18452 NM_PRECEQ_W_PHL
= 0x28,
18453 NM_PRECEQ_W_PHR
= 0x30,
18454 NM_PRECEQU_PH_QBL
= 0x38,
18455 NM_PRECEQU_PH_QBR
= 0x48,
18456 NM_PRECEU_PH_QBL
= 0x58,
18457 NM_PRECEU_PH_QBR
= 0x68,
18458 NM_PRECEQU_PH_QBLA
= 0x39,
18459 NM_PRECEQU_PH_QBRA
= 0x49,
18460 NM_PRECEU_PH_QBLA
= 0x59,
18461 NM_PRECEU_PH_QBRA
= 0x69,
18462 NM_REPLV_PH
= 0x01,
18463 NM_REPLV_QB
= 0x09,
18466 NM_RADDU_W_QB
= 0x78,
18472 /* PP.SR instruction pool */
18476 NM_RESTORE_JRC
= 0x03,
18479 /* P.SR.F instruction pool */
18482 NM_RESTOREF
= 0x01,
18485 /* P16.SYSCALL instruction pool */
18487 NM_SYSCALL16
= 0x00,
18488 NM_HYPCALL16
= 0x01,
18491 /* POOL16C_00 instruction pool */
18499 /* PP.LSX and PP.LSXS instruction pool */
18537 /* ERETx instruction pool */
18543 /* POOL32FxF_{0, 1} insturction pool */
18552 NM_CVT_S_PL
= 0x84,
18553 NM_CVT_S_PU
= 0xa4,
18555 NM_CVT_L_S
= 0x004,
18556 NM_CVT_L_D
= 0x104,
18557 NM_CVT_W_S
= 0x024,
18558 NM_CVT_W_D
= 0x124,
18560 NM_RSQRT_S
= 0x008,
18561 NM_RSQRT_D
= 0x108,
18566 NM_RECIP_S
= 0x048,
18567 NM_RECIP_D
= 0x148,
18569 NM_FLOOR_L_S
= 0x00c,
18570 NM_FLOOR_L_D
= 0x10c,
18572 NM_FLOOR_W_S
= 0x02c,
18573 NM_FLOOR_W_D
= 0x12c,
18575 NM_CEIL_L_S
= 0x04c,
18576 NM_CEIL_L_D
= 0x14c,
18577 NM_CEIL_W_S
= 0x06c,
18578 NM_CEIL_W_D
= 0x16c,
18579 NM_TRUNC_L_S
= 0x08c,
18580 NM_TRUNC_L_D
= 0x18c,
18581 NM_TRUNC_W_S
= 0x0ac,
18582 NM_TRUNC_W_D
= 0x1ac,
18583 NM_ROUND_L_S
= 0x0cc,
18584 NM_ROUND_L_D
= 0x1cc,
18585 NM_ROUND_W_S
= 0x0ec,
18586 NM_ROUND_W_D
= 0x1ec,
18594 NM_CVT_D_S
= 0x04d,
18595 NM_CVT_D_W
= 0x0cd,
18596 NM_CVT_D_L
= 0x14d,
18597 NM_CVT_S_D
= 0x06d,
18598 NM_CVT_S_W
= 0x0ed,
18599 NM_CVT_S_L
= 0x16d,
18602 /* P.LL instruction pool */
18608 /* P.SC instruction pool */
18614 /* P.DVP instruction pool */
18623 * nanoMIPS decoding engine
18628 /* extraction utilities */
18630 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18631 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18632 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18633 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18634 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18636 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18637 static inline int decode_gpr_gpr3(int r
)
18639 static const int map
[] = { 16, 17, 18, 19, 4, 5, 6, 7 };
18641 return map
[r
& 0x7];
18644 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18645 static inline int decode_gpr_gpr3_src_store(int r
)
18647 static const int map
[] = { 0, 17, 18, 19, 4, 5, 6, 7 };
18649 return map
[r
& 0x7];
18652 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18653 static inline int decode_gpr_gpr4(int r
)
18655 static const int map
[] = { 8, 9, 10, 11, 4, 5, 6, 7,
18656 16, 17, 18, 19, 20, 21, 22, 23 };
18658 return map
[r
& 0xf];
18661 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18662 static inline int decode_gpr_gpr4_zero(int r
)
18664 static const int map
[] = { 8, 9, 10, 0, 4, 5, 6, 7,
18665 16, 17, 18, 19, 20, 21, 22, 23 };
18667 return map
[r
& 0xf];
18671 static void gen_adjust_sp(DisasContext
*ctx
, int u
)
18673 gen_op_addr_addi(ctx
, cpu_gpr
[29], cpu_gpr
[29], u
);
18676 static void gen_save(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18677 uint8_t gp
, uint16_t u
)
18680 TCGv va
= tcg_temp_new();
18681 TCGv t0
= tcg_temp_new();
18683 while (counter
!= count
) {
18684 bool use_gp
= gp
&& (counter
== count
- 1);
18685 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18686 int this_offset
= -((counter
+ 1) << 2);
18687 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18688 gen_load_gpr(t0
, this_rt
);
18689 tcg_gen_qemu_st_tl(t0
, va
, ctx
->mem_idx
,
18690 (MO_TEUL
| ctx
->default_tcg_memop_mask
));
18694 /* adjust stack pointer */
18695 gen_adjust_sp(ctx
, -u
);
18701 static void gen_restore(DisasContext
*ctx
, uint8_t rt
, uint8_t count
,
18702 uint8_t gp
, uint16_t u
)
18705 TCGv va
= tcg_temp_new();
18706 TCGv t0
= tcg_temp_new();
18708 while (counter
!= count
) {
18709 bool use_gp
= gp
&& (counter
== count
- 1);
18710 int this_rt
= use_gp
? 28 : (rt
& 0x10) | ((rt
+ counter
) & 0x1f);
18711 int this_offset
= u
- ((counter
+ 1) << 2);
18712 gen_base_offset_addr(ctx
, va
, 29, this_offset
);
18713 tcg_gen_qemu_ld_tl(t0
, va
, ctx
->mem_idx
, MO_TESL
|
18714 ctx
->default_tcg_memop_mask
);
18715 tcg_gen_ext32s_tl(t0
, t0
);
18716 gen_store_gpr(t0
, this_rt
);
18720 /* adjust stack pointer */
18721 gen_adjust_sp(ctx
, u
);
18727 static void gen_pool16c_nanomips_insn(DisasContext
*ctx
)
18729 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
18730 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
18732 switch (extract32(ctx
->opcode
, 2, 2)) {
18734 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
18737 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
18740 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
18743 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
18748 static void gen_pool32a0_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
18750 int rt
= extract32(ctx
->opcode
, 21, 5);
18751 int rs
= extract32(ctx
->opcode
, 16, 5);
18752 int rd
= extract32(ctx
->opcode
, 11, 5);
18754 switch (extract32(ctx
->opcode
, 3, 7)) {
18756 switch (extract32(ctx
->opcode
, 10, 1)) {
18759 gen_trap(ctx
, OPC_TEQ
, rs
, rt
, -1);
18763 gen_trap(ctx
, OPC_TNE
, rs
, rt
, -1);
18769 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
18773 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
18776 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
18779 gen_shift(ctx
, OPC_SLLV
, rd
, rt
, rs
);
18782 gen_shift(ctx
, OPC_SRLV
, rd
, rt
, rs
);
18785 gen_shift(ctx
, OPC_SRAV
, rd
, rt
, rs
);
18788 gen_shift(ctx
, OPC_ROTRV
, rd
, rt
, rs
);
18791 gen_arith(ctx
, OPC_ADD
, rd
, rs
, rt
);
18794 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
18798 gen_arith(ctx
, OPC_SUB
, rd
, rs
, rt
);
18801 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
18804 switch (extract32(ctx
->opcode
, 10, 1)) {
18806 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
18809 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
18814 gen_logic(ctx
, OPC_AND
, rd
, rs
, rt
);
18817 gen_logic(ctx
, OPC_OR
, rd
, rs
, rt
);
18820 gen_logic(ctx
, OPC_NOR
, rd
, rs
, rt
);
18823 gen_logic(ctx
, OPC_XOR
, rd
, rs
, rt
);
18826 gen_slt(ctx
, OPC_SLT
, rd
, rs
, rt
);
18831 #ifndef CONFIG_USER_ONLY
18832 TCGv t0
= tcg_temp_new();
18833 switch (extract32(ctx
->opcode
, 10, 1)) {
18836 check_cp0_enabled(ctx
);
18837 gen_helper_dvp(t0
, cpu_env
);
18838 gen_store_gpr(t0
, rt
);
18843 check_cp0_enabled(ctx
);
18844 gen_helper_evp(t0
, cpu_env
);
18845 gen_store_gpr(t0
, rt
);
18852 gen_slt(ctx
, OPC_SLTU
, rd
, rs
, rt
);
18857 TCGv t0
= tcg_temp_new();
18858 TCGv t1
= tcg_temp_new();
18859 TCGv t2
= tcg_temp_new();
18861 gen_load_gpr(t1
, rs
);
18862 gen_load_gpr(t2
, rt
);
18863 tcg_gen_add_tl(t0
, t1
, t2
);
18864 tcg_gen_ext32s_tl(t0
, t0
);
18865 tcg_gen_xor_tl(t1
, t1
, t2
);
18866 tcg_gen_xor_tl(t2
, t0
, t2
);
18867 tcg_gen_andc_tl(t1
, t2
, t1
);
18869 /* operands of same sign, result different sign */
18870 tcg_gen_setcondi_tl(TCG_COND_LT
, t0
, t1
, 0);
18871 gen_store_gpr(t0
, rd
);
18879 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
18882 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
18885 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
18888 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
18891 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
18894 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
18897 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
18900 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
18902 #ifndef CONFIG_USER_ONLY
18904 check_cp0_enabled(ctx
);
18906 /* Treat as NOP. */
18909 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, extract32(ctx
->opcode
, 11, 3));
18912 check_cp0_enabled(ctx
);
18914 TCGv t0
= tcg_temp_new();
18916 gen_load_gpr(t0
, rt
);
18917 gen_mtc0(ctx
, t0
, rs
, extract32(ctx
->opcode
, 11, 3));
18921 case NM_D_E_MT_VPE
:
18923 uint8_t sc
= extract32(ctx
->opcode
, 10, 1);
18924 TCGv t0
= tcg_temp_new();
18931 gen_helper_dmt(t0
);
18932 gen_store_gpr(t0
, rt
);
18933 } else if (rs
== 0) {
18936 gen_helper_dvpe(t0
, cpu_env
);
18937 gen_store_gpr(t0
, rt
);
18939 generate_exception_end(ctx
, EXCP_RI
);
18946 gen_helper_emt(t0
);
18947 gen_store_gpr(t0
, rt
);
18948 } else if (rs
== 0) {
18951 gen_helper_evpe(t0
, cpu_env
);
18952 gen_store_gpr(t0
, rt
);
18954 generate_exception_end(ctx
, EXCP_RI
);
18965 TCGv t0
= tcg_temp_new();
18966 TCGv t1
= tcg_temp_new();
18968 gen_load_gpr(t0
, rt
);
18969 gen_load_gpr(t1
, rs
);
18970 gen_helper_fork(t0
, t1
);
18977 check_cp0_enabled(ctx
);
18979 /* Treat as NOP. */
18982 gen_mftr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18983 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18987 check_cp0_enabled(ctx
);
18988 gen_mttr(env
, ctx
, rs
, rt
, extract32(ctx
->opcode
, 10, 1),
18989 extract32(ctx
->opcode
, 11, 5), extract32(ctx
->opcode
, 3, 1));
18994 TCGv t0
= tcg_temp_new();
18996 gen_load_gpr(t0
, rs
);
18997 gen_helper_yield(t0
, cpu_env
, t0
);
18998 gen_store_gpr(t0
, rt
);
19004 generate_exception_end(ctx
, EXCP_RI
);
19010 static void gen_pool32axf_1_5_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19011 int ret
, int v1
, int v2
)
19017 t0
= tcg_temp_new_i32();
19019 v0_t
= tcg_temp_new();
19020 v1_t
= tcg_temp_new();
19022 tcg_gen_movi_i32(t0
, v2
>> 3);
19024 gen_load_gpr(v0_t
, ret
);
19025 gen_load_gpr(v1_t
, v1
);
19028 case NM_MAQ_S_W_PHR
:
19030 gen_helper_maq_s_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19032 case NM_MAQ_S_W_PHL
:
19034 gen_helper_maq_s_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19036 case NM_MAQ_SA_W_PHR
:
19038 gen_helper_maq_sa_w_phr(t0
, v1_t
, v0_t
, cpu_env
);
19040 case NM_MAQ_SA_W_PHL
:
19042 gen_helper_maq_sa_w_phl(t0
, v1_t
, v0_t
, cpu_env
);
19045 generate_exception_end(ctx
, EXCP_RI
);
19049 tcg_temp_free_i32(t0
);
19051 tcg_temp_free(v0_t
);
19052 tcg_temp_free(v1_t
);
19056 static void gen_pool32axf_1_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19057 int ret
, int v1
, int v2
)
19060 TCGv t0
= tcg_temp_new();
19061 TCGv t1
= tcg_temp_new();
19062 TCGv v0_t
= tcg_temp_new();
19064 gen_load_gpr(v0_t
, v1
);
19067 case NM_POOL32AXF_1_0
:
19069 switch (extract32(ctx
->opcode
, 12, 2)) {
19071 gen_HILO(ctx
, OPC_MFHI
, v2
>> 3, ret
);
19074 gen_HILO(ctx
, OPC_MFLO
, v2
>> 3, ret
);
19077 gen_HILO(ctx
, OPC_MTHI
, v2
>> 3, v1
);
19080 gen_HILO(ctx
, OPC_MTLO
, v2
>> 3, v1
);
19084 case NM_POOL32AXF_1_1
:
19086 switch (extract32(ctx
->opcode
, 12, 2)) {
19088 tcg_gen_movi_tl(t0
, v2
);
19089 gen_helper_mthlip(t0
, v0_t
, cpu_env
);
19092 tcg_gen_movi_tl(t0
, v2
>> 3);
19093 gen_helper_shilo(t0
, v0_t
, cpu_env
);
19096 generate_exception_end(ctx
, EXCP_RI
);
19100 case NM_POOL32AXF_1_3
:
19102 imm
= extract32(ctx
->opcode
, 14, 7);
19103 switch (extract32(ctx
->opcode
, 12, 2)) {
19105 tcg_gen_movi_tl(t0
, imm
);
19106 gen_helper_rddsp(t0
, t0
, cpu_env
);
19107 gen_store_gpr(t0
, ret
);
19110 gen_load_gpr(t0
, ret
);
19111 tcg_gen_movi_tl(t1
, imm
);
19112 gen_helper_wrdsp(t0
, t1
, cpu_env
);
19115 tcg_gen_movi_tl(t0
, v2
>> 3);
19116 tcg_gen_movi_tl(t1
, v1
);
19117 gen_helper_extp(t0
, t0
, t1
, cpu_env
);
19118 gen_store_gpr(t0
, ret
);
19121 tcg_gen_movi_tl(t0
, v2
>> 3);
19122 tcg_gen_movi_tl(t1
, v1
);
19123 gen_helper_extpdp(t0
, t0
, t1
, cpu_env
);
19124 gen_store_gpr(t0
, ret
);
19128 case NM_POOL32AXF_1_4
:
19130 tcg_gen_movi_tl(t0
, v2
>> 2);
19131 switch (extract32(ctx
->opcode
, 12, 1)) {
19133 gen_helper_shll_qb(t0
, t0
, v0_t
, cpu_env
);
19134 gen_store_gpr(t0
, ret
);
19137 gen_helper_shrl_qb(t0
, t0
, v0_t
);
19138 gen_store_gpr(t0
, ret
);
19142 case NM_POOL32AXF_1_5
:
19143 opc
= extract32(ctx
->opcode
, 12, 2);
19144 gen_pool32axf_1_5_nanomips_insn(ctx
, opc
, ret
, v1
, v2
);
19146 case NM_POOL32AXF_1_7
:
19148 tcg_gen_movi_tl(t0
, v2
>> 3);
19149 tcg_gen_movi_tl(t1
, v1
);
19150 switch (extract32(ctx
->opcode
, 12, 2)) {
19152 gen_helper_extr_w(t0
, t0
, t1
, cpu_env
);
19153 gen_store_gpr(t0
, ret
);
19156 gen_helper_extr_r_w(t0
, t0
, t1
, cpu_env
);
19157 gen_store_gpr(t0
, ret
);
19160 gen_helper_extr_rs_w(t0
, t0
, t1
, cpu_env
);
19161 gen_store_gpr(t0
, ret
);
19164 gen_helper_extr_s_h(t0
, t0
, t1
, cpu_env
);
19165 gen_store_gpr(t0
, ret
);
19170 generate_exception_end(ctx
, EXCP_RI
);
19176 tcg_temp_free(v0_t
);
19179 static void gen_pool32axf_2_multiply(DisasContext
*ctx
, uint32_t opc
,
19180 TCGv v0
, TCGv v1
, int rd
)
19184 t0
= tcg_temp_new_i32();
19186 tcg_gen_movi_i32(t0
, rd
>> 3);
19189 case NM_POOL32AXF_2_0_7
:
19190 switch (extract32(ctx
->opcode
, 9, 3)) {
19193 gen_helper_dpa_w_ph(t0
, v1
, v0
, cpu_env
);
19195 case NM_DPAQ_S_W_PH
:
19197 gen_helper_dpaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19201 gen_helper_dps_w_ph(t0
, v1
, v0
, cpu_env
);
19203 case NM_DPSQ_S_W_PH
:
19205 gen_helper_dpsq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19208 generate_exception_end(ctx
, EXCP_RI
);
19212 case NM_POOL32AXF_2_8_15
:
19213 switch (extract32(ctx
->opcode
, 9, 3)) {
19216 gen_helper_dpax_w_ph(t0
, v0
, v1
, cpu_env
);
19218 case NM_DPAQ_SA_L_W
:
19220 gen_helper_dpaq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19224 gen_helper_dpsx_w_ph(t0
, v0
, v1
, cpu_env
);
19226 case NM_DPSQ_SA_L_W
:
19228 gen_helper_dpsq_sa_l_w(t0
, v0
, v1
, cpu_env
);
19231 generate_exception_end(ctx
, EXCP_RI
);
19235 case NM_POOL32AXF_2_16_23
:
19236 switch (extract32(ctx
->opcode
, 9, 3)) {
19237 case NM_DPAU_H_QBL
:
19239 gen_helper_dpau_h_qbl(t0
, v0
, v1
, cpu_env
);
19241 case NM_DPAQX_S_W_PH
:
19243 gen_helper_dpaqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19245 case NM_DPSU_H_QBL
:
19247 gen_helper_dpsu_h_qbl(t0
, v0
, v1
, cpu_env
);
19249 case NM_DPSQX_S_W_PH
:
19251 gen_helper_dpsqx_s_w_ph(t0
, v0
, v1
, cpu_env
);
19253 case NM_MULSA_W_PH
:
19255 gen_helper_mulsa_w_ph(t0
, v0
, v1
, cpu_env
);
19258 generate_exception_end(ctx
, EXCP_RI
);
19262 case NM_POOL32AXF_2_24_31
:
19263 switch (extract32(ctx
->opcode
, 9, 3)) {
19264 case NM_DPAU_H_QBR
:
19266 gen_helper_dpau_h_qbr(t0
, v1
, v0
, cpu_env
);
19268 case NM_DPAQX_SA_W_PH
:
19270 gen_helper_dpaqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19272 case NM_DPSU_H_QBR
:
19274 gen_helper_dpsu_h_qbr(t0
, v1
, v0
, cpu_env
);
19276 case NM_DPSQX_SA_W_PH
:
19278 gen_helper_dpsqx_sa_w_ph(t0
, v1
, v0
, cpu_env
);
19280 case NM_MULSAQ_S_W_PH
:
19282 gen_helper_mulsaq_s_w_ph(t0
, v1
, v0
, cpu_env
);
19285 generate_exception_end(ctx
, EXCP_RI
);
19290 generate_exception_end(ctx
, EXCP_RI
);
19294 tcg_temp_free_i32(t0
);
19297 static void gen_pool32axf_2_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19298 int rt
, int rs
, int rd
)
19301 TCGv t0
= tcg_temp_new();
19302 TCGv t1
= tcg_temp_new();
19303 TCGv v0_t
= tcg_temp_new();
19304 TCGv v1_t
= tcg_temp_new();
19306 gen_load_gpr(v0_t
, rt
);
19307 gen_load_gpr(v1_t
, rs
);
19310 case NM_POOL32AXF_2_0_7
:
19311 switch (extract32(ctx
->opcode
, 9, 3)) {
19313 case NM_DPAQ_S_W_PH
:
19315 case NM_DPSQ_S_W_PH
:
19316 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19321 gen_load_gpr(t0
, rs
);
19323 if (rd
!= 0 && rd
!= 2) {
19324 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 8 * rd
);
19325 tcg_gen_ext32u_tl(t0
, t0
);
19326 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - rd
));
19327 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
19329 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
19335 int acc
= extract32(ctx
->opcode
, 14, 2);
19336 TCGv_i64 t2
= tcg_temp_new_i64();
19337 TCGv_i64 t3
= tcg_temp_new_i64();
19339 gen_load_gpr(t0
, rt
);
19340 gen_load_gpr(t1
, rs
);
19341 tcg_gen_ext_tl_i64(t2
, t0
);
19342 tcg_gen_ext_tl_i64(t3
, t1
);
19343 tcg_gen_mul_i64(t2
, t2
, t3
);
19344 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19345 tcg_gen_add_i64(t2
, t2
, t3
);
19346 tcg_temp_free_i64(t3
);
19347 gen_move_low32(cpu_LO
[acc
], t2
);
19348 gen_move_high32(cpu_HI
[acc
], t2
);
19349 tcg_temp_free_i64(t2
);
19355 int acc
= extract32(ctx
->opcode
, 14, 2);
19356 TCGv_i32 t2
= tcg_temp_new_i32();
19357 TCGv_i32 t3
= tcg_temp_new_i32();
19359 gen_load_gpr(t0
, rs
);
19360 gen_load_gpr(t1
, rt
);
19361 tcg_gen_trunc_tl_i32(t2
, t0
);
19362 tcg_gen_trunc_tl_i32(t3
, t1
);
19363 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
19364 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19365 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19366 tcg_temp_free_i32(t2
);
19367 tcg_temp_free_i32(t3
);
19372 gen_load_gpr(v1_t
, rs
);
19373 tcg_gen_movi_tl(t0
, rd
>> 3);
19374 gen_helper_extr_w(t0
, t0
, v1_t
, cpu_env
);
19375 gen_store_gpr(t0
, ret
);
19379 case NM_POOL32AXF_2_8_15
:
19380 switch (extract32(ctx
->opcode
, 9, 3)) {
19382 case NM_DPAQ_SA_L_W
:
19384 case NM_DPSQ_SA_L_W
:
19385 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19390 int acc
= extract32(ctx
->opcode
, 14, 2);
19391 TCGv_i64 t2
= tcg_temp_new_i64();
19392 TCGv_i64 t3
= tcg_temp_new_i64();
19394 gen_load_gpr(t0
, rs
);
19395 gen_load_gpr(t1
, rt
);
19396 tcg_gen_ext32u_tl(t0
, t0
);
19397 tcg_gen_ext32u_tl(t1
, t1
);
19398 tcg_gen_extu_tl_i64(t2
, t0
);
19399 tcg_gen_extu_tl_i64(t3
, t1
);
19400 tcg_gen_mul_i64(t2
, t2
, t3
);
19401 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19402 tcg_gen_add_i64(t2
, t2
, t3
);
19403 tcg_temp_free_i64(t3
);
19404 gen_move_low32(cpu_LO
[acc
], t2
);
19405 gen_move_high32(cpu_HI
[acc
], t2
);
19406 tcg_temp_free_i64(t2
);
19412 int acc
= extract32(ctx
->opcode
, 14, 2);
19413 TCGv_i32 t2
= tcg_temp_new_i32();
19414 TCGv_i32 t3
= tcg_temp_new_i32();
19416 gen_load_gpr(t0
, rs
);
19417 gen_load_gpr(t1
, rt
);
19418 tcg_gen_trunc_tl_i32(t2
, t0
);
19419 tcg_gen_trunc_tl_i32(t3
, t1
);
19420 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
19421 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
19422 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
19423 tcg_temp_free_i32(t2
);
19424 tcg_temp_free_i32(t3
);
19429 tcg_gen_movi_tl(t0
, rd
>> 3);
19430 gen_helper_extr_r_w(t0
, t0
, v1_t
, cpu_env
);
19431 gen_store_gpr(t0
, ret
);
19434 generate_exception_end(ctx
, EXCP_RI
);
19438 case NM_POOL32AXF_2_16_23
:
19439 switch (extract32(ctx
->opcode
, 9, 3)) {
19440 case NM_DPAU_H_QBL
:
19441 case NM_DPAQX_S_W_PH
:
19442 case NM_DPSU_H_QBL
:
19443 case NM_DPSQX_S_W_PH
:
19444 case NM_MULSA_W_PH
:
19445 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19449 tcg_gen_movi_tl(t0
, rd
>> 3);
19450 gen_helper_extp(t0
, t0
, v1_t
, cpu_env
);
19451 gen_store_gpr(t0
, ret
);
19456 int acc
= extract32(ctx
->opcode
, 14, 2);
19457 TCGv_i64 t2
= tcg_temp_new_i64();
19458 TCGv_i64 t3
= tcg_temp_new_i64();
19460 gen_load_gpr(t0
, rs
);
19461 gen_load_gpr(t1
, rt
);
19462 tcg_gen_ext_tl_i64(t2
, t0
);
19463 tcg_gen_ext_tl_i64(t3
, t1
);
19464 tcg_gen_mul_i64(t2
, t2
, t3
);
19465 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19466 tcg_gen_sub_i64(t2
, t3
, t2
);
19467 tcg_temp_free_i64(t3
);
19468 gen_move_low32(cpu_LO
[acc
], t2
);
19469 gen_move_high32(cpu_HI
[acc
], t2
);
19470 tcg_temp_free_i64(t2
);
19473 case NM_EXTRV_RS_W
:
19475 tcg_gen_movi_tl(t0
, rd
>> 3);
19476 gen_helper_extr_rs_w(t0
, t0
, v1_t
, cpu_env
);
19477 gen_store_gpr(t0
, ret
);
19481 case NM_POOL32AXF_2_24_31
:
19482 switch (extract32(ctx
->opcode
, 9, 3)) {
19483 case NM_DPAU_H_QBR
:
19484 case NM_DPAQX_SA_W_PH
:
19485 case NM_DPSU_H_QBR
:
19486 case NM_DPSQX_SA_W_PH
:
19487 case NM_MULSAQ_S_W_PH
:
19488 gen_pool32axf_2_multiply(ctx
, opc
, v0_t
, v1_t
, rd
);
19492 tcg_gen_movi_tl(t0
, rd
>> 3);
19493 gen_helper_extpdp(t0
, t0
, v1_t
, cpu_env
);
19494 gen_store_gpr(t0
, ret
);
19499 int acc
= extract32(ctx
->opcode
, 14, 2);
19500 TCGv_i64 t2
= tcg_temp_new_i64();
19501 TCGv_i64 t3
= tcg_temp_new_i64();
19503 gen_load_gpr(t0
, rs
);
19504 gen_load_gpr(t1
, rt
);
19505 tcg_gen_ext32u_tl(t0
, t0
);
19506 tcg_gen_ext32u_tl(t1
, t1
);
19507 tcg_gen_extu_tl_i64(t2
, t0
);
19508 tcg_gen_extu_tl_i64(t3
, t1
);
19509 tcg_gen_mul_i64(t2
, t2
, t3
);
19510 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
19511 tcg_gen_sub_i64(t2
, t3
, t2
);
19512 tcg_temp_free_i64(t3
);
19513 gen_move_low32(cpu_LO
[acc
], t2
);
19514 gen_move_high32(cpu_HI
[acc
], t2
);
19515 tcg_temp_free_i64(t2
);
19520 tcg_gen_movi_tl(t0
, rd
>> 3);
19521 gen_helper_extr_s_h(t0
, t0
, v0_t
, cpu_env
);
19522 gen_store_gpr(t0
, ret
);
19527 generate_exception_end(ctx
, EXCP_RI
);
19534 tcg_temp_free(v0_t
);
19535 tcg_temp_free(v1_t
);
19538 static void gen_pool32axf_4_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19542 TCGv t0
= tcg_temp_new();
19543 TCGv v0_t
= tcg_temp_new();
19545 gen_load_gpr(v0_t
, rs
);
19550 gen_helper_absq_s_qb(v0_t
, v0_t
, cpu_env
);
19551 gen_store_gpr(v0_t
, ret
);
19555 gen_helper_absq_s_ph(v0_t
, v0_t
, cpu_env
);
19556 gen_store_gpr(v0_t
, ret
);
19560 gen_helper_absq_s_w(v0_t
, v0_t
, cpu_env
);
19561 gen_store_gpr(v0_t
, ret
);
19563 case NM_PRECEQ_W_PHL
:
19565 tcg_gen_andi_tl(v0_t
, v0_t
, 0xFFFF0000);
19566 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19567 gen_store_gpr(v0_t
, ret
);
19569 case NM_PRECEQ_W_PHR
:
19571 tcg_gen_andi_tl(v0_t
, v0_t
, 0x0000FFFF);
19572 tcg_gen_shli_tl(v0_t
, v0_t
, 16);
19573 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19574 gen_store_gpr(v0_t
, ret
);
19576 case NM_PRECEQU_PH_QBL
:
19578 gen_helper_precequ_ph_qbl(v0_t
, v0_t
);
19579 gen_store_gpr(v0_t
, ret
);
19581 case NM_PRECEQU_PH_QBR
:
19583 gen_helper_precequ_ph_qbr(v0_t
, v0_t
);
19584 gen_store_gpr(v0_t
, ret
);
19586 case NM_PRECEQU_PH_QBLA
:
19588 gen_helper_precequ_ph_qbla(v0_t
, v0_t
);
19589 gen_store_gpr(v0_t
, ret
);
19591 case NM_PRECEQU_PH_QBRA
:
19593 gen_helper_precequ_ph_qbra(v0_t
, v0_t
);
19594 gen_store_gpr(v0_t
, ret
);
19596 case NM_PRECEU_PH_QBL
:
19598 gen_helper_preceu_ph_qbl(v0_t
, v0_t
);
19599 gen_store_gpr(v0_t
, ret
);
19601 case NM_PRECEU_PH_QBR
:
19603 gen_helper_preceu_ph_qbr(v0_t
, v0_t
);
19604 gen_store_gpr(v0_t
, ret
);
19606 case NM_PRECEU_PH_QBLA
:
19608 gen_helper_preceu_ph_qbla(v0_t
, v0_t
);
19609 gen_store_gpr(v0_t
, ret
);
19611 case NM_PRECEU_PH_QBRA
:
19613 gen_helper_preceu_ph_qbra(v0_t
, v0_t
);
19614 gen_store_gpr(v0_t
, ret
);
19618 tcg_gen_ext16u_tl(v0_t
, v0_t
);
19619 tcg_gen_shli_tl(t0
, v0_t
, 16);
19620 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19621 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19622 gen_store_gpr(v0_t
, ret
);
19626 tcg_gen_ext8u_tl(v0_t
, v0_t
);
19627 tcg_gen_shli_tl(t0
, v0_t
, 8);
19628 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19629 tcg_gen_shli_tl(t0
, v0_t
, 16);
19630 tcg_gen_or_tl(v0_t
, v0_t
, t0
);
19631 tcg_gen_ext32s_tl(v0_t
, v0_t
);
19632 gen_store_gpr(v0_t
, ret
);
19636 gen_helper_bitrev(v0_t
, v0_t
);
19637 gen_store_gpr(v0_t
, ret
);
19642 TCGv tv0
= tcg_temp_new();
19644 gen_load_gpr(tv0
, rt
);
19645 gen_helper_insv(v0_t
, cpu_env
, v0_t
, tv0
);
19646 gen_store_gpr(v0_t
, ret
);
19647 tcg_temp_free(tv0
);
19650 case NM_RADDU_W_QB
:
19652 gen_helper_raddu_w_qb(v0_t
, v0_t
);
19653 gen_store_gpr(v0_t
, ret
);
19656 gen_bitswap(ctx
, OPC_BITSWAP
, ret
, rs
);
19660 gen_cl(ctx
, OPC_CLO
, ret
, rs
);
19664 gen_cl(ctx
, OPC_CLZ
, ret
, rs
);
19667 gen_bshfl(ctx
, OPC_WSBH
, ret
, rs
);
19670 generate_exception_end(ctx
, EXCP_RI
);
19674 tcg_temp_free(v0_t
);
19678 static void gen_pool32axf_7_nanomips_insn(DisasContext
*ctx
, uint32_t opc
,
19679 int rt
, int rs
, int rd
)
19681 TCGv t0
= tcg_temp_new();
19682 TCGv rs_t
= tcg_temp_new();
19684 gen_load_gpr(rs_t
, rs
);
19689 tcg_gen_movi_tl(t0
, rd
>> 2);
19690 switch (extract32(ctx
->opcode
, 12, 1)) {
19693 gen_helper_shra_qb(t0
, t0
, rs_t
);
19694 gen_store_gpr(t0
, rt
);
19698 gen_helper_shra_r_qb(t0
, t0
, rs_t
);
19699 gen_store_gpr(t0
, rt
);
19705 tcg_gen_movi_tl(t0
, rd
>> 1);
19706 gen_helper_shrl_ph(t0
, t0
, rs_t
);
19707 gen_store_gpr(t0
, rt
);
19713 target_long result
;
19714 imm
= extract32(ctx
->opcode
, 13, 8);
19715 result
= (uint32_t)imm
<< 24 |
19716 (uint32_t)imm
<< 16 |
19717 (uint32_t)imm
<< 8 |
19719 result
= (int32_t)result
;
19720 tcg_gen_movi_tl(t0
, result
);
19721 gen_store_gpr(t0
, rt
);
19725 generate_exception_end(ctx
, EXCP_RI
);
19729 tcg_temp_free(rs_t
);
19733 static void gen_pool32axf_nanomips_insn(CPUMIPSState
*env
, DisasContext
*ctx
)
19735 int rt
= extract32(ctx
->opcode
, 21, 5);
19736 int rs
= extract32(ctx
->opcode
, 16, 5);
19737 int rd
= extract32(ctx
->opcode
, 11, 5);
19739 switch (extract32(ctx
->opcode
, 6, 3)) {
19740 case NM_POOL32AXF_1
:
19742 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19743 gen_pool32axf_1_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19746 case NM_POOL32AXF_2
:
19748 int32_t op1
= extract32(ctx
->opcode
, 12, 2);
19749 gen_pool32axf_2_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19752 case NM_POOL32AXF_4
:
19754 int32_t op1
= extract32(ctx
->opcode
, 9, 7);
19755 gen_pool32axf_4_nanomips_insn(ctx
, op1
, rt
, rs
);
19758 case NM_POOL32AXF_5
:
19759 switch (extract32(ctx
->opcode
, 9, 7)) {
19760 #ifndef CONFIG_USER_ONLY
19762 gen_cp0(env
, ctx
, OPC_TLBP
, 0, 0);
19765 gen_cp0(env
, ctx
, OPC_TLBR
, 0, 0);
19768 gen_cp0(env
, ctx
, OPC_TLBWI
, 0, 0);
19771 gen_cp0(env
, ctx
, OPC_TLBWR
, 0, 0);
19774 gen_cp0(env
, ctx
, OPC_TLBINV
, 0, 0);
19777 gen_cp0(env
, ctx
, OPC_TLBINVF
, 0, 0);
19780 check_cp0_enabled(ctx
);
19782 TCGv t0
= tcg_temp_new();
19784 save_cpu_state(ctx
, 1);
19785 gen_helper_di(t0
, cpu_env
);
19786 gen_store_gpr(t0
, rt
);
19787 /* Stop translation as we may have switched the execution mode */
19788 ctx
->base
.is_jmp
= DISAS_STOP
;
19793 check_cp0_enabled(ctx
);
19795 TCGv t0
= tcg_temp_new();
19797 save_cpu_state(ctx
, 1);
19798 gen_helper_ei(t0
, cpu_env
);
19799 gen_store_gpr(t0
, rt
);
19800 /* Stop translation as we may have switched the execution mode */
19801 ctx
->base
.is_jmp
= DISAS_STOP
;
19806 gen_load_srsgpr(rs
, rt
);
19809 gen_store_srsgpr(rs
, rt
);
19812 gen_cp0(env
, ctx
, OPC_WAIT
, 0, 0);
19815 gen_cp0(env
, ctx
, OPC_DERET
, 0, 0);
19818 gen_cp0(env
, ctx
, OPC_ERET
, 0, 0);
19822 generate_exception_end(ctx
, EXCP_RI
);
19826 case NM_POOL32AXF_7
:
19828 int32_t op1
= extract32(ctx
->opcode
, 9, 3);
19829 gen_pool32axf_7_nanomips_insn(ctx
, op1
, rt
, rs
, rd
);
19833 generate_exception_end(ctx
, EXCP_RI
);
19838 /* Immediate Value Compact Branches */
19839 static void gen_compute_imm_branch(DisasContext
*ctx
, uint32_t opc
,
19840 int rt
, int32_t imm
, int32_t offset
)
19843 int bcond_compute
= 0;
19844 TCGv t0
= tcg_temp_new();
19845 TCGv t1
= tcg_temp_new();
19847 gen_load_gpr(t0
, rt
);
19848 tcg_gen_movi_tl(t1
, imm
);
19849 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
19851 /* Load needed operands and calculate btarget */
19854 if (rt
== 0 && imm
== 0) {
19855 /* Unconditional branch */
19856 } else if (rt
== 0 && imm
!= 0) {
19861 cond
= TCG_COND_EQ
;
19867 if (imm
>= 32 && !(ctx
->hflags
& MIPS_HFLAG_64
)) {
19868 generate_exception_end(ctx
, EXCP_RI
);
19870 } else if (rt
== 0 && opc
== NM_BBEQZC
) {
19871 /* Unconditional branch */
19872 } else if (rt
== 0 && opc
== NM_BBNEZC
) {
19876 tcg_gen_shri_tl(t0
, t0
, imm
);
19877 tcg_gen_andi_tl(t0
, t0
, 1);
19878 tcg_gen_movi_tl(t1
, 0);
19880 if (opc
== NM_BBEQZC
) {
19881 cond
= TCG_COND_EQ
;
19883 cond
= TCG_COND_NE
;
19888 if (rt
== 0 && imm
== 0) {
19891 } else if (rt
== 0 && imm
!= 0) {
19892 /* Unconditional branch */
19895 cond
= TCG_COND_NE
;
19899 if (rt
== 0 && imm
== 0) {
19900 /* Unconditional branch */
19903 cond
= TCG_COND_GE
;
19908 cond
= TCG_COND_LT
;
19911 if (rt
== 0 && imm
== 0) {
19912 /* Unconditional branch */
19915 cond
= TCG_COND_GEU
;
19920 cond
= TCG_COND_LTU
;
19923 MIPS_INVAL("Immediate Value Compact branch");
19924 generate_exception_end(ctx
, EXCP_RI
);
19928 /* branch completion */
19929 clear_branch_hflags(ctx
);
19930 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19932 if (bcond_compute
== 0) {
19933 /* Uncoditional compact branch */
19934 gen_goto_tb(ctx
, 0, ctx
->btarget
);
19936 /* Conditional compact branch */
19937 TCGLabel
*fs
= gen_new_label();
19939 tcg_gen_brcond_tl(tcg_invert_cond(cond
), t0
, t1
, fs
);
19941 gen_goto_tb(ctx
, 1, ctx
->btarget
);
19944 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
19952 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19953 static void gen_compute_nanomips_pbalrsc_branch(DisasContext
*ctx
, int rs
,
19956 TCGv t0
= tcg_temp_new();
19957 TCGv t1
= tcg_temp_new();
19960 gen_load_gpr(t0
, rs
);
19964 tcg_gen_movi_tl(cpu_gpr
[rt
], ctx
->base
.pc_next
+ 4);
19967 /* calculate btarget */
19968 tcg_gen_shli_tl(t0
, t0
, 1);
19969 tcg_gen_movi_tl(t1
, ctx
->base
.pc_next
+ 4);
19970 gen_op_addr_add(ctx
, btarget
, t1
, t0
);
19972 /* branch completion */
19973 clear_branch_hflags(ctx
);
19974 ctx
->base
.is_jmp
= DISAS_NORETURN
;
19976 /* unconditional branch to register */
19977 tcg_gen_mov_tl(cpu_PC
, btarget
);
19978 tcg_gen_lookup_and_goto_ptr();
19984 /* nanoMIPS Branches */
19985 static void gen_compute_compact_branch_nm(DisasContext
*ctx
, uint32_t opc
,
19986 int rs
, int rt
, int32_t offset
)
19988 int bcond_compute
= 0;
19989 TCGv t0
= tcg_temp_new();
19990 TCGv t1
= tcg_temp_new();
19992 /* Load needed operands and calculate btarget */
19994 /* compact branch */
19997 gen_load_gpr(t0
, rs
);
19998 gen_load_gpr(t1
, rt
);
20000 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20004 if (rs
== 0 || rs
== rt
) {
20005 /* OPC_BLEZALC, OPC_BGEZALC */
20006 /* OPC_BGTZALC, OPC_BLTZALC */
20007 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->base
.pc_next
+ 4);
20009 gen_load_gpr(t0
, rs
);
20010 gen_load_gpr(t1
, rt
);
20012 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20015 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20019 /* OPC_BEQZC, OPC_BNEZC */
20020 gen_load_gpr(t0
, rs
);
20022 ctx
->btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20024 /* OPC_JIC, OPC_JIALC */
20025 TCGv tbase
= tcg_temp_new();
20026 TCGv toffset
= tcg_temp_new();
20028 gen_load_gpr(tbase
, rt
);
20029 tcg_gen_movi_tl(toffset
, offset
);
20030 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
20031 tcg_temp_free(tbase
);
20032 tcg_temp_free(toffset
);
20036 MIPS_INVAL("Compact branch/jump");
20037 generate_exception_end(ctx
, EXCP_RI
);
20041 if (bcond_compute
== 0) {
20042 /* Uncoditional compact branch */
20045 gen_goto_tb(ctx
, 0, ctx
->btarget
);
20048 MIPS_INVAL("Compact branch/jump");
20049 generate_exception_end(ctx
, EXCP_RI
);
20053 /* Conditional compact branch */
20054 TCGLabel
*fs
= gen_new_label();
20058 if (rs
== 0 && rt
!= 0) {
20060 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20061 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20063 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20066 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
20070 if (rs
== 0 && rt
!= 0) {
20072 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20073 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20075 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20078 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
20082 if (rs
== 0 && rt
!= 0) {
20084 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
20085 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20087 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
20090 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
20094 if (rs
== 0 && rt
!= 0) {
20096 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
20097 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
20099 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
20102 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
20106 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
20109 MIPS_INVAL("Compact conditional branch/jump");
20110 generate_exception_end(ctx
, EXCP_RI
);
20114 /* branch completion */
20115 clear_branch_hflags(ctx
);
20116 ctx
->base
.is_jmp
= DISAS_NORETURN
;
20118 /* Generating branch here as compact branches don't have delay slot */
20119 gen_goto_tb(ctx
, 1, ctx
->btarget
);
20122 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
+ 4);
20131 /* nanoMIPS CP1 Branches */
20132 static void gen_compute_branch_cp1_nm(DisasContext
*ctx
, uint32_t op
,
20133 int32_t ft
, int32_t offset
)
20135 target_ulong btarget
;
20136 TCGv_i64 t0
= tcg_temp_new_i64();
20138 gen_load_fpr64(ctx
, t0
, ft
);
20139 tcg_gen_andi_i64(t0
, t0
, 1);
20141 btarget
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
20145 tcg_gen_xori_i64(t0
, t0
, 1);
20146 ctx
->hflags
|= MIPS_HFLAG_BC
;
20149 /* t0 already set */
20150 ctx
->hflags
|= MIPS_HFLAG_BC
;
20153 MIPS_INVAL("cp1 cond branch");
20154 generate_exception_end(ctx
, EXCP_RI
);
20158 tcg_gen_trunc_i64_tl(bcond
, t0
);
20160 ctx
->btarget
= btarget
;
20163 tcg_temp_free_i64(t0
);
20167 static void gen_p_lsx(DisasContext
*ctx
, int rd
, int rs
, int rt
)
20170 t0
= tcg_temp_new();
20171 t1
= tcg_temp_new();
20173 gen_load_gpr(t0
, rs
);
20174 gen_load_gpr(t1
, rt
);
20176 if ((extract32(ctx
->opcode
, 6, 1)) == 1) {
20177 /* PP.LSXS instructions require shifting */
20178 switch (extract32(ctx
->opcode
, 7, 4)) {
20184 tcg_gen_shli_tl(t0
, t0
, 1);
20192 tcg_gen_shli_tl(t0
, t0
, 2);
20196 tcg_gen_shli_tl(t0
, t0
, 3);
20200 gen_op_addr_add(ctx
, t0
, t0
, t1
);
20202 switch (extract32(ctx
->opcode
, 7, 4)) {
20204 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20206 gen_store_gpr(t0
, rd
);
20210 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20212 gen_store_gpr(t0
, rd
);
20216 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20218 gen_store_gpr(t0
, rd
);
20221 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20223 gen_store_gpr(t0
, rd
);
20227 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
,
20229 gen_store_gpr(t0
, rd
);
20233 gen_load_gpr(t1
, rd
);
20234 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20240 gen_load_gpr(t1
, rd
);
20241 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20247 gen_load_gpr(t1
, rd
);
20248 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
,
20252 /*case NM_LWC1XS:*/
20254 /*case NM_LDC1XS:*/
20256 /*case NM_SWC1XS:*/
20258 /*case NM_SDC1XS:*/
20259 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20260 check_cp1_enabled(ctx
);
20261 switch (extract32(ctx
->opcode
, 7, 4)) {
20263 /*case NM_LWC1XS:*/
20264 gen_flt_ldst(ctx
, OPC_LWC1
, rd
, t0
);
20267 /*case NM_LDC1XS:*/
20268 gen_flt_ldst(ctx
, OPC_LDC1
, rd
, t0
);
20271 /*case NM_SWC1XS:*/
20272 gen_flt_ldst(ctx
, OPC_SWC1
, rd
, t0
);
20275 /*case NM_SDC1XS:*/
20276 gen_flt_ldst(ctx
, OPC_SDC1
, rd
, t0
);
20280 generate_exception_err(ctx
, EXCP_CpU
, 1);
20284 generate_exception_end(ctx
, EXCP_RI
);
20292 static void gen_pool32f_nanomips_insn(DisasContext
*ctx
)
20296 rt
= extract32(ctx
->opcode
, 21, 5);
20297 rs
= extract32(ctx
->opcode
, 16, 5);
20298 rd
= extract32(ctx
->opcode
, 11, 5);
20300 if (!(ctx
->CP0_Config1
& (1 << CP0C1_FP
))) {
20301 generate_exception_end(ctx
, EXCP_RI
);
20304 check_cp1_enabled(ctx
);
20305 switch (extract32(ctx
->opcode
, 0, 3)) {
20307 switch (extract32(ctx
->opcode
, 3, 7)) {
20309 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
20312 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
20315 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
20318 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
20321 gen_farith(ctx
, OPC_ADD_S
, rt
, rs
, rd
, 0);
20324 gen_farith(ctx
, OPC_ADD_D
, rt
, rs
, rd
, 0);
20327 gen_farith(ctx
, OPC_SUB_S
, rt
, rs
, rd
, 0);
20330 gen_farith(ctx
, OPC_SUB_D
, rt
, rs
, rd
, 0);
20333 gen_farith(ctx
, OPC_MUL_S
, rt
, rs
, rd
, 0);
20336 gen_farith(ctx
, OPC_MUL_D
, rt
, rs
, rd
, 0);
20339 gen_farith(ctx
, OPC_DIV_S
, rt
, rs
, rd
, 0);
20342 gen_farith(ctx
, OPC_DIV_D
, rt
, rs
, rd
, 0);
20345 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
20348 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
20351 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
20354 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
20357 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
20360 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
20363 gen_farith(ctx
, OPC_MADDF_S
, rt
, rs
, rd
, 0);
20366 gen_farith(ctx
, OPC_MADDF_D
, rt
, rs
, rd
, 0);
20369 gen_farith(ctx
, OPC_MSUBF_S
, rt
, rs
, rd
, 0);
20372 gen_farith(ctx
, OPC_MSUBF_D
, rt
, rs
, rd
, 0);
20375 generate_exception_end(ctx
, EXCP_RI
);
20380 switch (extract32(ctx
->opcode
, 3, 3)) {
20382 switch (extract32(ctx
->opcode
, 9, 1)) {
20384 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
20387 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
20392 switch (extract32(ctx
->opcode
, 9, 1)) {
20394 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
20397 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
20402 switch (extract32(ctx
->opcode
, 9, 1)) {
20404 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
20407 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
20412 switch (extract32(ctx
->opcode
, 9, 1)) {
20414 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
20417 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
20422 switch (extract32(ctx
->opcode
, 6, 8)) {
20424 gen_cp1(ctx
, OPC_CFC1
, rt
, rs
);
20427 gen_cp1(ctx
, OPC_CTC1
, rt
, rs
);
20430 gen_cp1(ctx
, OPC_MFC1
, rt
, rs
);
20433 gen_cp1(ctx
, OPC_MTC1
, rt
, rs
);
20436 gen_cp1(ctx
, OPC_MFHC1
, rt
, rs
);
20439 gen_cp1(ctx
, OPC_MTHC1
, rt
, rs
);
20442 gen_farith(ctx
, OPC_CVT_S_PL
, -1, rs
, rt
, 0);
20445 gen_farith(ctx
, OPC_CVT_S_PU
, -1, rs
, rt
, 0);
20448 switch (extract32(ctx
->opcode
, 6, 9)) {
20450 gen_farith(ctx
, OPC_CVT_L_S
, -1, rs
, rt
, 0);
20453 gen_farith(ctx
, OPC_CVT_L_D
, -1, rs
, rt
, 0);
20456 gen_farith(ctx
, OPC_CVT_W_S
, -1, rs
, rt
, 0);
20459 gen_farith(ctx
, OPC_CVT_W_D
, -1, rs
, rt
, 0);
20462 gen_farith(ctx
, OPC_RSQRT_S
, -1, rs
, rt
, 0);
20465 gen_farith(ctx
, OPC_RSQRT_D
, -1, rs
, rt
, 0);
20468 gen_farith(ctx
, OPC_SQRT_S
, -1, rs
, rt
, 0);
20471 gen_farith(ctx
, OPC_SQRT_D
, -1, rs
, rt
, 0);
20474 gen_farith(ctx
, OPC_RECIP_S
, -1, rs
, rt
, 0);
20477 gen_farith(ctx
, OPC_RECIP_D
, -1, rs
, rt
, 0);
20480 gen_farith(ctx
, OPC_FLOOR_L_S
, -1, rs
, rt
, 0);
20483 gen_farith(ctx
, OPC_FLOOR_L_D
, -1, rs
, rt
, 0);
20486 gen_farith(ctx
, OPC_FLOOR_W_S
, -1, rs
, rt
, 0);
20489 gen_farith(ctx
, OPC_FLOOR_W_D
, -1, rs
, rt
, 0);
20492 gen_farith(ctx
, OPC_CEIL_L_S
, -1, rs
, rt
, 0);
20495 gen_farith(ctx
, OPC_CEIL_L_D
, -1, rs
, rt
, 0);
20498 gen_farith(ctx
, OPC_CEIL_W_S
, -1, rs
, rt
, 0);
20501 gen_farith(ctx
, OPC_CEIL_W_D
, -1, rs
, rt
, 0);
20504 gen_farith(ctx
, OPC_TRUNC_L_S
, -1, rs
, rt
, 0);
20507 gen_farith(ctx
, OPC_TRUNC_L_D
, -1, rs
, rt
, 0);
20510 gen_farith(ctx
, OPC_TRUNC_W_S
, -1, rs
, rt
, 0);
20513 gen_farith(ctx
, OPC_TRUNC_W_D
, -1, rs
, rt
, 0);
20516 gen_farith(ctx
, OPC_ROUND_L_S
, -1, rs
, rt
, 0);
20519 gen_farith(ctx
, OPC_ROUND_L_D
, -1, rs
, rt
, 0);
20522 gen_farith(ctx
, OPC_ROUND_W_S
, -1, rs
, rt
, 0);
20525 gen_farith(ctx
, OPC_ROUND_W_D
, -1, rs
, rt
, 0);
20528 gen_farith(ctx
, OPC_MOV_S
, -1, rs
, rt
, 0);
20531 gen_farith(ctx
, OPC_MOV_D
, -1, rs
, rt
, 0);
20534 gen_farith(ctx
, OPC_ABS_S
, -1, rs
, rt
, 0);
20537 gen_farith(ctx
, OPC_ABS_D
, -1, rs
, rt
, 0);
20540 gen_farith(ctx
, OPC_NEG_S
, -1, rs
, rt
, 0);
20543 gen_farith(ctx
, OPC_NEG_D
, -1, rs
, rt
, 0);
20546 gen_farith(ctx
, OPC_CVT_D_S
, -1, rs
, rt
, 0);
20549 gen_farith(ctx
, OPC_CVT_D_W
, -1, rs
, rt
, 0);
20552 gen_farith(ctx
, OPC_CVT_D_L
, -1, rs
, rt
, 0);
20555 gen_farith(ctx
, OPC_CVT_S_D
, -1, rs
, rt
, 0);
20558 gen_farith(ctx
, OPC_CVT_S_W
, -1, rs
, rt
, 0);
20561 gen_farith(ctx
, OPC_CVT_S_L
, -1, rs
, rt
, 0);
20564 generate_exception_end(ctx
, EXCP_RI
);
20573 switch (extract32(ctx
->opcode
, 3, 3)) {
20574 case NM_CMP_CONDN_S
:
20575 gen_r6_cmp_s(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20577 case NM_CMP_CONDN_D
:
20578 gen_r6_cmp_d(ctx
, extract32(ctx
->opcode
, 6, 5), rt
, rs
, rd
);
20581 generate_exception_end(ctx
, EXCP_RI
);
20586 generate_exception_end(ctx
, EXCP_RI
);
20591 static void gen_pool32a5_nanomips_insn(DisasContext
*ctx
, int opc
,
20592 int rd
, int rs
, int rt
)
20595 TCGv t0
= tcg_temp_new();
20596 TCGv v1_t
= tcg_temp_new();
20597 TCGv v2_t
= tcg_temp_new();
20599 gen_load_gpr(v1_t
, rs
);
20600 gen_load_gpr(v2_t
, rt
);
20605 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
20609 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
20613 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
20615 case NM_CMPU_EQ_QB
:
20617 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
20619 case NM_CMPU_LT_QB
:
20621 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
20623 case NM_CMPU_LE_QB
:
20625 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
20627 case NM_CMPGU_EQ_QB
:
20629 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20630 gen_store_gpr(v1_t
, ret
);
20632 case NM_CMPGU_LT_QB
:
20634 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20635 gen_store_gpr(v1_t
, ret
);
20637 case NM_CMPGU_LE_QB
:
20639 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20640 gen_store_gpr(v1_t
, ret
);
20642 case NM_CMPGDU_EQ_QB
:
20644 gen_helper_cmpgu_eq_qb(v1_t
, v1_t
, v2_t
);
20645 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20646 gen_store_gpr(v1_t
, ret
);
20648 case NM_CMPGDU_LT_QB
:
20650 gen_helper_cmpgu_lt_qb(v1_t
, v1_t
, v2_t
);
20651 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20652 gen_store_gpr(v1_t
, ret
);
20654 case NM_CMPGDU_LE_QB
:
20656 gen_helper_cmpgu_le_qb(v1_t
, v1_t
, v2_t
);
20657 tcg_gen_deposit_tl(cpu_dspctrl
, cpu_dspctrl
, v1_t
, 24, 4);
20658 gen_store_gpr(v1_t
, ret
);
20662 gen_helper_packrl_ph(v1_t
, v1_t
, v2_t
);
20663 gen_store_gpr(v1_t
, ret
);
20667 gen_helper_pick_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20668 gen_store_gpr(v1_t
, ret
);
20672 gen_helper_pick_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20673 gen_store_gpr(v1_t
, ret
);
20677 gen_helper_addq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20678 gen_store_gpr(v1_t
, ret
);
20682 gen_helper_subq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20683 gen_store_gpr(v1_t
, ret
);
20687 gen_helper_addsc(v1_t
, v1_t
, v2_t
, cpu_env
);
20688 gen_store_gpr(v1_t
, ret
);
20692 gen_helper_addwc(v1_t
, v1_t
, v2_t
, cpu_env
);
20693 gen_store_gpr(v1_t
, ret
);
20697 switch (extract32(ctx
->opcode
, 10, 1)) {
20700 gen_helper_addq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20701 gen_store_gpr(v1_t
, ret
);
20705 gen_helper_addq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20706 gen_store_gpr(v1_t
, ret
);
20710 case NM_ADDQH_R_PH
:
20712 switch (extract32(ctx
->opcode
, 10, 1)) {
20715 gen_helper_addqh_ph(v1_t
, v1_t
, v2_t
);
20716 gen_store_gpr(v1_t
, ret
);
20720 gen_helper_addqh_r_ph(v1_t
, v1_t
, v2_t
);
20721 gen_store_gpr(v1_t
, ret
);
20727 switch (extract32(ctx
->opcode
, 10, 1)) {
20730 gen_helper_addqh_w(v1_t
, v1_t
, v2_t
);
20731 gen_store_gpr(v1_t
, ret
);
20735 gen_helper_addqh_r_w(v1_t
, v1_t
, v2_t
);
20736 gen_store_gpr(v1_t
, ret
);
20742 switch (extract32(ctx
->opcode
, 10, 1)) {
20745 gen_helper_addu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20746 gen_store_gpr(v1_t
, ret
);
20750 gen_helper_addu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20751 gen_store_gpr(v1_t
, ret
);
20757 switch (extract32(ctx
->opcode
, 10, 1)) {
20760 gen_helper_addu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20761 gen_store_gpr(v1_t
, ret
);
20765 gen_helper_addu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20766 gen_store_gpr(v1_t
, ret
);
20770 case NM_ADDUH_R_QB
:
20772 switch (extract32(ctx
->opcode
, 10, 1)) {
20775 gen_helper_adduh_qb(v1_t
, v1_t
, v2_t
);
20776 gen_store_gpr(v1_t
, ret
);
20780 gen_helper_adduh_r_qb(v1_t
, v1_t
, v2_t
);
20781 gen_store_gpr(v1_t
, ret
);
20785 case NM_SHRAV_R_PH
:
20787 switch (extract32(ctx
->opcode
, 10, 1)) {
20790 gen_helper_shra_ph(v1_t
, v1_t
, v2_t
);
20791 gen_store_gpr(v1_t
, ret
);
20795 gen_helper_shra_r_ph(v1_t
, v1_t
, v2_t
);
20796 gen_store_gpr(v1_t
, ret
);
20800 case NM_SHRAV_R_QB
:
20802 switch (extract32(ctx
->opcode
, 10, 1)) {
20805 gen_helper_shra_qb(v1_t
, v1_t
, v2_t
);
20806 gen_store_gpr(v1_t
, ret
);
20810 gen_helper_shra_r_qb(v1_t
, v1_t
, v2_t
);
20811 gen_store_gpr(v1_t
, ret
);
20817 switch (extract32(ctx
->opcode
, 10, 1)) {
20820 gen_helper_subq_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20821 gen_store_gpr(v1_t
, ret
);
20825 gen_helper_subq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20826 gen_store_gpr(v1_t
, ret
);
20830 case NM_SUBQH_R_PH
:
20832 switch (extract32(ctx
->opcode
, 10, 1)) {
20835 gen_helper_subqh_ph(v1_t
, v1_t
, v2_t
);
20836 gen_store_gpr(v1_t
, ret
);
20840 gen_helper_subqh_r_ph(v1_t
, v1_t
, v2_t
);
20841 gen_store_gpr(v1_t
, ret
);
20847 switch (extract32(ctx
->opcode
, 10, 1)) {
20850 gen_helper_subqh_w(v1_t
, v1_t
, v2_t
);
20851 gen_store_gpr(v1_t
, ret
);
20855 gen_helper_subqh_r_w(v1_t
, v1_t
, v2_t
);
20856 gen_store_gpr(v1_t
, ret
);
20862 switch (extract32(ctx
->opcode
, 10, 1)) {
20865 gen_helper_subu_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20866 gen_store_gpr(v1_t
, ret
);
20870 gen_helper_subu_s_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
20871 gen_store_gpr(v1_t
, ret
);
20877 switch (extract32(ctx
->opcode
, 10, 1)) {
20880 gen_helper_subu_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20881 gen_store_gpr(v1_t
, ret
);
20885 gen_helper_subu_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20886 gen_store_gpr(v1_t
, ret
);
20890 case NM_SUBUH_R_QB
:
20892 switch (extract32(ctx
->opcode
, 10, 1)) {
20895 gen_helper_subuh_qb(v1_t
, v1_t
, v2_t
);
20896 gen_store_gpr(v1_t
, ret
);
20900 gen_helper_subuh_r_qb(v1_t
, v1_t
, v2_t
);
20901 gen_store_gpr(v1_t
, ret
);
20905 case NM_SHLLV_S_PH
:
20907 switch (extract32(ctx
->opcode
, 10, 1)) {
20910 gen_helper_shll_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20911 gen_store_gpr(v1_t
, ret
);
20915 gen_helper_shll_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20916 gen_store_gpr(v1_t
, ret
);
20920 case NM_PRECR_SRA_R_PH_W
:
20922 switch (extract32(ctx
->opcode
, 10, 1)) {
20924 /* PRECR_SRA_PH_W */
20926 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20927 gen_helper_precr_sra_ph_w(v1_t
, sa_t
, v1_t
,
20929 gen_store_gpr(v1_t
, rt
);
20930 tcg_temp_free_i32(sa_t
);
20934 /* PRECR_SRA_R_PH_W */
20936 TCGv_i32 sa_t
= tcg_const_i32(rd
);
20937 gen_helper_precr_sra_r_ph_w(v1_t
, sa_t
, v1_t
,
20939 gen_store_gpr(v1_t
, rt
);
20940 tcg_temp_free_i32(sa_t
);
20945 case NM_MULEU_S_PH_QBL
:
20947 gen_helper_muleu_s_ph_qbl(v1_t
, v1_t
, v2_t
, cpu_env
);
20948 gen_store_gpr(v1_t
, ret
);
20950 case NM_MULEU_S_PH_QBR
:
20952 gen_helper_muleu_s_ph_qbr(v1_t
, v1_t
, v2_t
, cpu_env
);
20953 gen_store_gpr(v1_t
, ret
);
20955 case NM_MULQ_RS_PH
:
20957 gen_helper_mulq_rs_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20958 gen_store_gpr(v1_t
, ret
);
20962 gen_helper_mulq_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
20963 gen_store_gpr(v1_t
, ret
);
20967 gen_helper_mulq_rs_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20968 gen_store_gpr(v1_t
, ret
);
20972 gen_helper_mulq_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
20973 gen_store_gpr(v1_t
, ret
);
20977 gen_load_gpr(t0
, rs
);
20979 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], rd
, 32 - rd
);
20981 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
20985 gen_helper_modsub(v1_t
, v1_t
, v2_t
);
20986 gen_store_gpr(v1_t
, ret
);
20990 gen_helper_shra_r_w(v1_t
, v1_t
, v2_t
);
20991 gen_store_gpr(v1_t
, ret
);
20995 gen_helper_shrl_ph(v1_t
, v1_t
, v2_t
);
20996 gen_store_gpr(v1_t
, ret
);
21000 gen_helper_shrl_qb(v1_t
, v1_t
, v2_t
);
21001 gen_store_gpr(v1_t
, ret
);
21005 gen_helper_shll_qb(v1_t
, v1_t
, v2_t
, cpu_env
);
21006 gen_store_gpr(v1_t
, ret
);
21010 gen_helper_shll_s_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21011 gen_store_gpr(v1_t
, ret
);
21016 TCGv tv0
= tcg_temp_new();
21017 TCGv tv1
= tcg_temp_new();
21018 int16_t imm
= extract32(ctx
->opcode
, 16, 7);
21020 tcg_gen_movi_tl(tv0
, rd
>> 3);
21021 tcg_gen_movi_tl(tv1
, imm
);
21022 gen_helper_shilo(tv0
, tv1
, cpu_env
);
21025 case NM_MULEQ_S_W_PHL
:
21027 gen_helper_muleq_s_w_phl(v1_t
, v1_t
, v2_t
, cpu_env
);
21028 gen_store_gpr(v1_t
, ret
);
21030 case NM_MULEQ_S_W_PHR
:
21032 gen_helper_muleq_s_w_phr(v1_t
, v1_t
, v2_t
, cpu_env
);
21033 gen_store_gpr(v1_t
, ret
);
21037 switch (extract32(ctx
->opcode
, 10, 1)) {
21040 gen_helper_mul_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21041 gen_store_gpr(v1_t
, ret
);
21045 gen_helper_mul_s_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21046 gen_store_gpr(v1_t
, ret
);
21050 case NM_PRECR_QB_PH
:
21052 gen_helper_precr_qb_ph(v1_t
, v1_t
, v2_t
);
21053 gen_store_gpr(v1_t
, ret
);
21055 case NM_PRECRQ_QB_PH
:
21057 gen_helper_precrq_qb_ph(v1_t
, v1_t
, v2_t
);
21058 gen_store_gpr(v1_t
, ret
);
21060 case NM_PRECRQ_PH_W
:
21062 gen_helper_precrq_ph_w(v1_t
, v1_t
, v2_t
);
21063 gen_store_gpr(v1_t
, ret
);
21065 case NM_PRECRQ_RS_PH_W
:
21067 gen_helper_precrq_rs_ph_w(v1_t
, v1_t
, v2_t
, cpu_env
);
21068 gen_store_gpr(v1_t
, ret
);
21070 case NM_PRECRQU_S_QB_PH
:
21072 gen_helper_precrqu_s_qb_ph(v1_t
, v1_t
, v2_t
, cpu_env
);
21073 gen_store_gpr(v1_t
, ret
);
21077 tcg_gen_movi_tl(t0
, rd
);
21078 gen_helper_shra_r_w(v1_t
, t0
, v1_t
);
21079 gen_store_gpr(v1_t
, rt
);
21083 tcg_gen_movi_tl(t0
, rd
>> 1);
21084 switch (extract32(ctx
->opcode
, 10, 1)) {
21087 gen_helper_shra_ph(v1_t
, t0
, v1_t
);
21088 gen_store_gpr(v1_t
, rt
);
21092 gen_helper_shra_r_ph(v1_t
, t0
, v1_t
);
21093 gen_store_gpr(v1_t
, rt
);
21099 tcg_gen_movi_tl(t0
, rd
>> 1);
21100 switch (extract32(ctx
->opcode
, 10, 2)) {
21103 gen_helper_shll_ph(v1_t
, t0
, v1_t
, cpu_env
);
21104 gen_store_gpr(v1_t
, rt
);
21108 gen_helper_shll_s_ph(v1_t
, t0
, v1_t
, cpu_env
);
21109 gen_store_gpr(v1_t
, rt
);
21112 generate_exception_end(ctx
, EXCP_RI
);
21118 tcg_gen_movi_tl(t0
, rd
);
21119 gen_helper_shll_s_w(v1_t
, t0
, v1_t
, cpu_env
);
21120 gen_store_gpr(v1_t
, rt
);
21126 imm
= sextract32(ctx
->opcode
, 11, 11);
21127 imm
= (int16_t)(imm
<< 6) >> 6;
21129 tcg_gen_movi_tl(cpu_gpr
[rt
], dup_const(MO_16
, imm
));
21134 generate_exception_end(ctx
, EXCP_RI
);
21139 static int decode_nanomips_32_48_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
21147 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 2);
21148 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
21150 rt
= extract32(ctx
->opcode
, 21, 5);
21151 rs
= extract32(ctx
->opcode
, 16, 5);
21152 rd
= extract32(ctx
->opcode
, 11, 5);
21154 op
= extract32(ctx
->opcode
, 26, 6);
21159 switch (extract32(ctx
->opcode
, 19, 2)) {
21162 generate_exception_end(ctx
, EXCP_RI
);
21165 if ((extract32(ctx
->opcode
, 18, 1)) == NM_SYSCALL
) {
21166 generate_exception_end(ctx
, EXCP_SYSCALL
);
21168 generate_exception_end(ctx
, EXCP_RI
);
21172 generate_exception_end(ctx
, EXCP_BREAK
);
21175 if (is_uhi(extract32(ctx
->opcode
, 0, 19))) {
21176 gen_helper_do_semihosting(cpu_env
);
21178 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
21179 generate_exception_end(ctx
, EXCP_RI
);
21181 generate_exception_end(ctx
, EXCP_DBp
);
21188 imm
= extract32(ctx
->opcode
, 0, 16);
21190 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
);
21192 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
21194 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21199 offset
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21200 extract32(ctx
->opcode
, 1, 20) << 1;
21201 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21202 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21206 switch (ctx
->opcode
& 0x07) {
21208 gen_pool32a0_nanomips_insn(env
, ctx
);
21212 int32_t op1
= extract32(ctx
->opcode
, 3, 7);
21213 gen_pool32a5_nanomips_insn(ctx
, op1
, rd
, rs
, rt
);
21217 switch (extract32(ctx
->opcode
, 3, 3)) {
21219 gen_p_lsx(ctx
, rd
, rs
, rt
);
21223 * In nanoMIPS, the shift field directly encodes the shift
21224 * amount, meaning that the supported shift values are in
21225 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
21227 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
21228 extract32(ctx
->opcode
, 9, 2) - 1);
21231 gen_ext(ctx
, 32, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 5));
21234 gen_pool32axf_nanomips_insn(env
, ctx
);
21237 generate_exception_end(ctx
, EXCP_RI
);
21242 generate_exception_end(ctx
, EXCP_RI
);
21247 switch (ctx
->opcode
& 0x03) {
21250 offset
= extract32(ctx
->opcode
, 0, 21);
21251 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], offset
);
21255 gen_ld(ctx
, OPC_LW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21258 gen_st(ctx
, OPC_SW
, rt
, 28, extract32(ctx
->opcode
, 2, 19) << 2);
21261 generate_exception_end(ctx
, EXCP_RI
);
21267 insn
= cpu_lduw_code(env
, ctx
->base
.pc_next
+ 4);
21268 target_long addr_off
= extract32(ctx
->opcode
, 0, 16) | insn
<< 16;
21269 switch (extract32(ctx
->opcode
, 16, 5)) {
21273 tcg_gen_movi_tl(cpu_gpr
[rt
], addr_off
);
21279 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], addr_off
);
21280 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
21286 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], addr_off
);
21292 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21295 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21302 t0
= tcg_temp_new();
21304 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21307 tcg_gen_movi_tl(t0
, addr
);
21308 tcg_gen_qemu_ld_tl(cpu_gpr
[rt
], t0
, ctx
->mem_idx
, MO_TESL
);
21316 t0
= tcg_temp_new();
21317 t1
= tcg_temp_new();
21319 target_long addr
= addr_add(ctx
, ctx
->base
.pc_next
+ 6,
21322 tcg_gen_movi_tl(t0
, addr
);
21323 gen_load_gpr(t1
, rt
);
21325 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
21332 generate_exception_end(ctx
, EXCP_RI
);
21338 switch (extract32(ctx
->opcode
, 12, 4)) {
21340 gen_logic_imm(ctx
, OPC_ORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21343 gen_logic_imm(ctx
, OPC_XORI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21346 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21349 switch (extract32(ctx
->opcode
, 20, 1)) {
21351 switch (ctx
->opcode
& 3) {
21353 gen_save(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21354 extract32(ctx
->opcode
, 2, 1),
21355 extract32(ctx
->opcode
, 3, 9) << 3);
21358 case NM_RESTORE_JRC
:
21359 gen_restore(ctx
, rt
, extract32(ctx
->opcode
, 16, 4),
21360 extract32(ctx
->opcode
, 2, 1),
21361 extract32(ctx
->opcode
, 3, 9) << 3);
21362 if ((ctx
->opcode
& 3) == NM_RESTORE_JRC
) {
21363 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
21367 generate_exception_end(ctx
, EXCP_RI
);
21372 generate_exception_end(ctx
, EXCP_RI
);
21377 gen_slt_imm(ctx
, OPC_SLTI
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21380 gen_slt_imm(ctx
, OPC_SLTIU
, rt
, rs
, extract32(ctx
->opcode
, 0, 12));
21384 TCGv t0
= tcg_temp_new();
21386 imm
= extract32(ctx
->opcode
, 0, 12);
21387 gen_load_gpr(t0
, rs
);
21388 tcg_gen_setcondi_tl(TCG_COND_EQ
, t0
, t0
, imm
);
21389 gen_store_gpr(t0
, rt
);
21395 imm
= (int16_t) extract32(ctx
->opcode
, 0, 12);
21396 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, -imm
);
21400 int shift
= extract32(ctx
->opcode
, 0, 5);
21401 switch (extract32(ctx
->opcode
, 5, 4)) {
21403 if (rt
== 0 && shift
== 0) {
21405 } else if (rt
== 0 && shift
== 3) {
21406 /* EHB - treat as NOP */
21407 } else if (rt
== 0 && shift
== 5) {
21408 /* PAUSE - treat as NOP */
21409 } else if (rt
== 0 && shift
== 6) {
21411 gen_sync(extract32(ctx
->opcode
, 16, 5));
21414 gen_shift_imm(ctx
, OPC_SLL
, rt
, rs
,
21415 extract32(ctx
->opcode
, 0, 5));
21419 gen_shift_imm(ctx
, OPC_SRL
, rt
, rs
,
21420 extract32(ctx
->opcode
, 0, 5));
21423 gen_shift_imm(ctx
, OPC_SRA
, rt
, rs
,
21424 extract32(ctx
->opcode
, 0, 5));
21427 gen_shift_imm(ctx
, OPC_ROTR
, rt
, rs
,
21428 extract32(ctx
->opcode
, 0, 5));
21436 TCGv t0
= tcg_temp_new();
21437 TCGv_i32 shift
= tcg_const_i32(extract32(ctx
->opcode
, 0, 5));
21438 TCGv_i32 shiftx
= tcg_const_i32(extract32(ctx
->opcode
, 7, 4)
21440 TCGv_i32 stripe
= tcg_const_i32(extract32(ctx
->opcode
, 6, 1));
21442 gen_load_gpr(t0
, rs
);
21443 gen_helper_rotx(cpu_gpr
[rt
], t0
, shift
, shiftx
, stripe
);
21446 tcg_temp_free_i32(shift
);
21447 tcg_temp_free_i32(shiftx
);
21448 tcg_temp_free_i32(stripe
);
21452 switch (((ctx
->opcode
>> 10) & 2) |
21453 (extract32(ctx
->opcode
, 5, 1))) {
21456 gen_bitops(ctx
, OPC_INS
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21457 extract32(ctx
->opcode
, 6, 5));
21460 generate_exception_end(ctx
, EXCP_RI
);
21465 switch (((ctx
->opcode
>> 10) & 2) |
21466 (extract32(ctx
->opcode
, 5, 1))) {
21469 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, extract32(ctx
->opcode
, 0, 5),
21470 extract32(ctx
->opcode
, 6, 5));
21473 generate_exception_end(ctx
, EXCP_RI
);
21478 generate_exception_end(ctx
, EXCP_RI
);
21483 gen_pool32f_nanomips_insn(ctx
);
21488 switch (extract32(ctx
->opcode
, 1, 1)) {
21491 tcg_gen_movi_tl(cpu_gpr
[rt
],
21492 sextract32(ctx
->opcode
, 0, 1) << 31 |
21493 extract32(ctx
->opcode
, 2, 10) << 21 |
21494 extract32(ctx
->opcode
, 12, 9) << 12);
21499 offset
= sextract32(ctx
->opcode
, 0, 1) << 31 |
21500 extract32(ctx
->opcode
, 2, 10) << 21 |
21501 extract32(ctx
->opcode
, 12, 9) << 12;
21503 addr
= ~0xFFF & addr_add(ctx
, ctx
->base
.pc_next
+ 4, offset
);
21504 tcg_gen_movi_tl(cpu_gpr
[rt
], addr
);
21511 uint32_t u
= extract32(ctx
->opcode
, 0, 18);
21513 switch (extract32(ctx
->opcode
, 18, 3)) {
21515 gen_ld(ctx
, OPC_LB
, rt
, 28, u
);
21518 gen_st(ctx
, OPC_SB
, rt
, 28, u
);
21521 gen_ld(ctx
, OPC_LBU
, rt
, 28, u
);
21525 gen_op_addr_addi(ctx
, cpu_gpr
[rt
], cpu_gpr
[28], u
);
21530 switch (ctx
->opcode
& 1) {
21532 gen_ld(ctx
, OPC_LH
, rt
, 28, u
);
21535 gen_ld(ctx
, OPC_LHU
, rt
, 28, u
);
21541 switch (ctx
->opcode
& 1) {
21543 gen_st(ctx
, OPC_SH
, rt
, 28, u
);
21546 generate_exception_end(ctx
, EXCP_RI
);
21552 switch (ctx
->opcode
& 0x3) {
21554 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, 28, u
);
21557 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, 28, u
);
21560 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, 28, u
);
21563 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, 28, u
);
21568 generate_exception_end(ctx
, EXCP_RI
);
21575 uint32_t u
= extract32(ctx
->opcode
, 0, 12);
21577 switch (extract32(ctx
->opcode
, 12, 4)) {
21582 * Break the TB to be able to sync copied instructions
21585 ctx
->base
.is_jmp
= DISAS_STOP
;
21588 /* Treat as NOP. */
21592 gen_ld(ctx
, OPC_LB
, rt
, rs
, u
);
21595 gen_ld(ctx
, OPC_LH
, rt
, rs
, u
);
21598 gen_ld(ctx
, OPC_LW
, rt
, rs
, u
);
21601 gen_ld(ctx
, OPC_LBU
, rt
, rs
, u
);
21604 gen_ld(ctx
, OPC_LHU
, rt
, rs
, u
);
21607 gen_st(ctx
, OPC_SB
, rt
, rs
, u
);
21610 gen_st(ctx
, OPC_SH
, rt
, rs
, u
);
21613 gen_st(ctx
, OPC_SW
, rt
, rs
, u
);
21616 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, u
);
21619 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, u
);
21622 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, u
);
21625 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, u
);
21628 generate_exception_end(ctx
, EXCP_RI
);
21635 int32_t s
= (sextract32(ctx
->opcode
, 15, 1) << 8) |
21636 extract32(ctx
->opcode
, 0, 8);
21638 switch (extract32(ctx
->opcode
, 8, 3)) {
21640 switch (extract32(ctx
->opcode
, 11, 4)) {
21642 gen_ld(ctx
, OPC_LB
, rt
, rs
, s
);
21645 gen_ld(ctx
, OPC_LH
, rt
, rs
, s
);
21648 gen_ld(ctx
, OPC_LW
, rt
, rs
, s
);
21651 gen_ld(ctx
, OPC_LBU
, rt
, rs
, s
);
21654 gen_ld(ctx
, OPC_LHU
, rt
, rs
, s
);
21657 gen_st(ctx
, OPC_SB
, rt
, rs
, s
);
21660 gen_st(ctx
, OPC_SH
, rt
, rs
, s
);
21663 gen_st(ctx
, OPC_SW
, rt
, rs
, s
);
21666 gen_cop1_ldst(ctx
, OPC_LWC1
, rt
, rs
, s
);
21669 gen_cop1_ldst(ctx
, OPC_LDC1
, rt
, rs
, s
);
21672 gen_cop1_ldst(ctx
, OPC_SWC1
, rt
, rs
, s
);
21675 gen_cop1_ldst(ctx
, OPC_SDC1
, rt
, rs
, s
);
21681 * Break the TB to be able to sync copied instructions
21684 ctx
->base
.is_jmp
= DISAS_STOP
;
21687 /* Treat as NOP. */
21691 generate_exception_end(ctx
, EXCP_RI
);
21696 switch (extract32(ctx
->opcode
, 11, 4)) {
21701 TCGv t0
= tcg_temp_new();
21702 TCGv t1
= tcg_temp_new();
21704 gen_base_offset_addr(ctx
, t0
, rs
, s
);
21706 switch (extract32(ctx
->opcode
, 11, 4)) {
21708 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
21710 gen_store_gpr(t0
, rt
);
21713 gen_load_gpr(t1
, rt
);
21714 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
21723 switch (ctx
->opcode
& 0x03) {
21725 gen_ld(ctx
, OPC_LL
, rt
, rs
, s
);
21729 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21734 switch (ctx
->opcode
& 0x03) {
21736 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, false);
21740 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21746 check_cp0_enabled(ctx
);
21747 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
21748 gen_cache_operation(ctx
, rt
, rs
, s
);
21754 switch (extract32(ctx
->opcode
, 11, 4)) {
21757 check_cp0_enabled(ctx
);
21758 gen_ld(ctx
, OPC_LBE
, rt
, rs
, s
);
21762 check_cp0_enabled(ctx
);
21763 gen_st(ctx
, OPC_SBE
, rt
, rs
, s
);
21767 check_cp0_enabled(ctx
);
21768 gen_ld(ctx
, OPC_LBUE
, rt
, rs
, s
);
21772 /* case NM_SYNCIE */
21774 check_cp0_enabled(ctx
);
21776 * Break the TB to be able to sync copied instructions
21779 ctx
->base
.is_jmp
= DISAS_STOP
;
21781 /* case NM_PREFE */
21783 check_cp0_enabled(ctx
);
21784 /* Treat as NOP. */
21789 check_cp0_enabled(ctx
);
21790 gen_ld(ctx
, OPC_LHE
, rt
, rs
, s
);
21794 check_cp0_enabled(ctx
);
21795 gen_st(ctx
, OPC_SHE
, rt
, rs
, s
);
21799 check_cp0_enabled(ctx
);
21800 gen_ld(ctx
, OPC_LHUE
, rt
, rs
, s
);
21803 check_nms_dl_il_sl_tl_l2c(ctx
);
21804 gen_cache_operation(ctx
, rt
, rs
, s
);
21808 check_cp0_enabled(ctx
);
21809 gen_ld(ctx
, OPC_LWE
, rt
, rs
, s
);
21813 check_cp0_enabled(ctx
);
21814 gen_st(ctx
, OPC_SWE
, rt
, rs
, s
);
21817 switch (extract32(ctx
->opcode
, 2, 2)) {
21821 check_cp0_enabled(ctx
);
21822 gen_ld(ctx
, OPC_LLE
, rt
, rs
, s
);
21827 check_cp0_enabled(ctx
);
21828 gen_llwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5));
21831 generate_exception_end(ctx
, EXCP_RI
);
21836 switch (extract32(ctx
->opcode
, 2, 2)) {
21840 check_cp0_enabled(ctx
);
21841 gen_st_cond(ctx
, rt
, rs
, s
, MO_TESL
, true);
21846 check_cp0_enabled(ctx
);
21847 gen_scwp(ctx
, rs
, 0, rt
, extract32(ctx
->opcode
, 3, 5),
21851 generate_exception_end(ctx
, EXCP_RI
);
21861 int count
= extract32(ctx
->opcode
, 12, 3);
21864 offset
= sextract32(ctx
->opcode
, 15, 1) << 8 |
21865 extract32(ctx
->opcode
, 0, 8);
21866 TCGv va
= tcg_temp_new();
21867 TCGv t1
= tcg_temp_new();
21868 MemOp memop
= (extract32(ctx
->opcode
, 8, 3)) ==
21869 NM_P_LS_UAWM
? MO_UNALN
: 0;
21871 count
= (count
== 0) ? 8 : count
;
21872 while (counter
!= count
) {
21873 int this_rt
= ((rt
+ counter
) & 0x1f) | (rt
& 0x10);
21874 int this_offset
= offset
+ (counter
<< 2);
21876 gen_base_offset_addr(ctx
, va
, rs
, this_offset
);
21878 switch (extract32(ctx
->opcode
, 11, 1)) {
21880 tcg_gen_qemu_ld_tl(t1
, va
, ctx
->mem_idx
,
21882 gen_store_gpr(t1
, this_rt
);
21883 if ((this_rt
== rs
) &&
21884 (counter
!= (count
- 1))) {
21885 /* UNPREDICTABLE */
21889 this_rt
= (rt
== 0) ? 0 : this_rt
;
21890 gen_load_gpr(t1
, this_rt
);
21891 tcg_gen_qemu_st_tl(t1
, va
, ctx
->mem_idx
,
21902 generate_exception_end(ctx
, EXCP_RI
);
21910 TCGv t0
= tcg_temp_new();
21911 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 21 |
21912 extract32(ctx
->opcode
, 1, 20) << 1;
21913 rd
= (extract32(ctx
->opcode
, 24, 1)) == 0 ? 4 : 5;
21914 rt
= decode_gpr_gpr4_zero(extract32(ctx
->opcode
, 25, 1) << 3 |
21915 extract32(ctx
->opcode
, 21, 3));
21916 gen_load_gpr(t0
, rt
);
21917 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
21918 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21924 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 25 |
21925 extract32(ctx
->opcode
, 1, 24) << 1;
21927 if ((extract32(ctx
->opcode
, 25, 1)) == 0) {
21929 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, 0, 0, s
);
21932 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 4, 0, 0, s
);
21937 switch (extract32(ctx
->opcode
, 12, 4)) {
21940 gen_compute_branch_nm(ctx
, OPC_JALR
, 4, rs
, rt
, 0);
21943 gen_compute_nanomips_pbalrsc_branch(ctx
, rs
, rt
);
21946 generate_exception_end(ctx
, EXCP_RI
);
21952 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21953 extract32(ctx
->opcode
, 1, 13) << 1;
21954 switch (extract32(ctx
->opcode
, 14, 2)) {
21957 gen_compute_branch_nm(ctx
, OPC_BEQ
, 4, rs
, rt
, s
);
21960 s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
21961 extract32(ctx
->opcode
, 1, 13) << 1;
21962 check_cp1_enabled(ctx
);
21963 switch (extract32(ctx
->opcode
, 16, 5)) {
21965 gen_compute_branch_cp1_nm(ctx
, OPC_BC1EQZ
, rt
, s
);
21968 gen_compute_branch_cp1_nm(ctx
, OPC_BC1NEZ
, rt
, s
);
21973 int32_t imm
= extract32(ctx
->opcode
, 1, 13) |
21974 extract32(ctx
->opcode
, 0, 1) << 13;
21976 gen_compute_branch_nm(ctx
, OPC_BPOSGE32
, 4, -1, -2,
21981 generate_exception_end(ctx
, EXCP_RI
);
21987 gen_compute_compact_branch_nm(ctx
, OPC_BC
, rs
, rt
, s
);
21989 gen_compute_compact_branch_nm(ctx
, OPC_BGEC
, rs
, rt
, s
);
21993 if (rs
== rt
|| rt
== 0) {
21994 gen_compute_compact_branch_nm(ctx
, OPC_BC
, 0, 0, s
);
21995 } else if (rs
== 0) {
21996 gen_compute_compact_branch_nm(ctx
, OPC_BEQZC
, rt
, 0, s
);
21998 gen_compute_compact_branch_nm(ctx
, OPC_BGEUC
, rs
, rt
, s
);
22006 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 14 |
22007 extract32(ctx
->opcode
, 1, 13) << 1;
22008 switch (extract32(ctx
->opcode
, 14, 2)) {
22011 gen_compute_branch_nm(ctx
, OPC_BNE
, 4, rs
, rt
, s
);
22014 if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
22016 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22018 gen_compute_compact_branch_nm(ctx
, OPC_BLTC
, rs
, rt
, s
);
22022 if (rs
== 0 || rs
== rt
) {
22024 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
22026 gen_compute_compact_branch_nm(ctx
, OPC_BLTUC
, rs
, rt
, s
);
22030 generate_exception_end(ctx
, EXCP_RI
);
22037 int32_t s
= sextract32(ctx
->opcode
, 0, 1) << 11 |
22038 extract32(ctx
->opcode
, 1, 10) << 1;
22039 uint32_t u
= extract32(ctx
->opcode
, 11, 7);
22041 gen_compute_imm_branch(ctx
, extract32(ctx
->opcode
, 18, 3),
22046 generate_exception_end(ctx
, EXCP_RI
);
22052 static int decode_nanomips_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
22055 int rt
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22056 int rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22057 int rd
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx
->opcode
));
22061 /* make sure instructions are on a halfword boundary */
22062 if (ctx
->base
.pc_next
& 0x1) {
22063 TCGv tmp
= tcg_const_tl(ctx
->base
.pc_next
);
22064 tcg_gen_st_tl(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
22065 tcg_temp_free(tmp
);
22066 generate_exception_end(ctx
, EXCP_AdEL
);
22070 op
= extract32(ctx
->opcode
, 10, 6);
22073 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22076 rs
= NANOMIPS_EXTRACT_RS5(ctx
->opcode
);
22077 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, 0);
22080 switch (extract32(ctx
->opcode
, 3, 2)) {
22081 case NM_P16_SYSCALL
:
22082 if (extract32(ctx
->opcode
, 2, 1) == 0) {
22083 generate_exception_end(ctx
, EXCP_SYSCALL
);
22085 generate_exception_end(ctx
, EXCP_RI
);
22089 generate_exception_end(ctx
, EXCP_BREAK
);
22092 if (is_uhi(extract32(ctx
->opcode
, 0, 3))) {
22093 gen_helper_do_semihosting(cpu_env
);
22095 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
22096 generate_exception_end(ctx
, EXCP_RI
);
22098 generate_exception_end(ctx
, EXCP_DBp
);
22103 generate_exception_end(ctx
, EXCP_RI
);
22110 int shift
= extract32(ctx
->opcode
, 0, 3);
22112 shift
= (shift
== 0) ? 8 : shift
;
22114 switch (extract32(ctx
->opcode
, 3, 1)) {
22122 gen_shift_imm(ctx
, opc
, rt
, rs
, shift
);
22126 switch (ctx
->opcode
& 1) {
22128 gen_pool16c_nanomips_insn(ctx
);
22131 gen_ldxs(ctx
, rt
, rs
, rd
);
22136 switch (extract32(ctx
->opcode
, 6, 1)) {
22138 imm
= extract32(ctx
->opcode
, 0, 6) << 2;
22139 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, 29, imm
);
22142 generate_exception_end(ctx
, EXCP_RI
);
22147 switch (extract32(ctx
->opcode
, 3, 1)) {
22149 imm
= extract32(ctx
->opcode
, 0, 3) << 2;
22150 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rs
, imm
);
22152 case NM_P_ADDIURS5
:
22153 rt
= extract32(ctx
->opcode
, 5, 5);
22155 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
22156 imm
= (sextract32(ctx
->opcode
, 4, 1) << 3) |
22157 (extract32(ctx
->opcode
, 0, 3));
22158 gen_arith_imm(ctx
, OPC_ADDIU
, rt
, rt
, imm
);
22164 switch (ctx
->opcode
& 0x1) {
22166 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, rt
);
22169 gen_arith(ctx
, OPC_SUBU
, rd
, rs
, rt
);
22174 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22175 extract32(ctx
->opcode
, 5, 3);
22176 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22177 extract32(ctx
->opcode
, 0, 3);
22178 rt
= decode_gpr_gpr4(rt
);
22179 rs
= decode_gpr_gpr4(rs
);
22180 switch ((extract32(ctx
->opcode
, 7, 2) & 0x2) |
22181 (extract32(ctx
->opcode
, 3, 1))) {
22184 gen_arith(ctx
, OPC_ADDU
, rt
, rs
, rt
);
22188 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rt
, rs
, rt
);
22191 generate_exception_end(ctx
, EXCP_RI
);
22197 int imm
= extract32(ctx
->opcode
, 0, 7);
22198 imm
= (imm
== 0x7f ? -1 : imm
);
22200 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
);
22206 uint32_t u
= extract32(ctx
->opcode
, 0, 4);
22207 u
= (u
== 12) ? 0xff :
22208 (u
== 13) ? 0xffff : u
;
22209 gen_logic_imm(ctx
, OPC_ANDI
, rt
, rs
, u
);
22213 offset
= extract32(ctx
->opcode
, 0, 2);
22214 switch (extract32(ctx
->opcode
, 2, 2)) {
22216 gen_ld(ctx
, OPC_LB
, rt
, rs
, offset
);
22219 rt
= decode_gpr_gpr3_src_store(
22220 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22221 gen_st(ctx
, OPC_SB
, rt
, rs
, offset
);
22224 gen_ld(ctx
, OPC_LBU
, rt
, rs
, offset
);
22227 generate_exception_end(ctx
, EXCP_RI
);
22232 offset
= extract32(ctx
->opcode
, 1, 2) << 1;
22233 switch ((extract32(ctx
->opcode
, 3, 1) << 1) | (ctx
->opcode
& 1)) {
22235 gen_ld(ctx
, OPC_LH
, rt
, rs
, offset
);
22238 rt
= decode_gpr_gpr3_src_store(
22239 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22240 gen_st(ctx
, OPC_SH
, rt
, rs
, offset
);
22243 gen_ld(ctx
, OPC_LHU
, rt
, rs
, offset
);
22246 generate_exception_end(ctx
, EXCP_RI
);
22251 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22252 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22255 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22256 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22257 gen_ld(ctx
, OPC_LW
, rt
, 29, offset
);
22261 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22262 extract32(ctx
->opcode
, 5, 3);
22263 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22264 extract32(ctx
->opcode
, 0, 3);
22265 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22266 (extract32(ctx
->opcode
, 8, 1) << 2);
22267 rt
= decode_gpr_gpr4(rt
);
22268 rs
= decode_gpr_gpr4(rs
);
22269 gen_ld(ctx
, OPC_LW
, rt
, rs
, offset
);
22273 rt
= (extract32(ctx
->opcode
, 9, 1) << 3) |
22274 extract32(ctx
->opcode
, 5, 3);
22275 rs
= (extract32(ctx
->opcode
, 4, 1) << 3) |
22276 extract32(ctx
->opcode
, 0, 3);
22277 offset
= (extract32(ctx
->opcode
, 3, 1) << 3) |
22278 (extract32(ctx
->opcode
, 8, 1) << 2);
22279 rt
= decode_gpr_gpr4_zero(rt
);
22280 rs
= decode_gpr_gpr4(rs
);
22281 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22284 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22285 gen_ld(ctx
, OPC_LW
, rt
, 28, offset
);
22288 rt
= NANOMIPS_EXTRACT_RD5(ctx
->opcode
);
22289 offset
= extract32(ctx
->opcode
, 0, 5) << 2;
22290 gen_st(ctx
, OPC_SW
, rt
, 29, offset
);
22293 rt
= decode_gpr_gpr3_src_store(
22294 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22295 rs
= decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx
->opcode
));
22296 offset
= extract32(ctx
->opcode
, 0, 4) << 2;
22297 gen_st(ctx
, OPC_SW
, rt
, rs
, offset
);
22300 rt
= decode_gpr_gpr3_src_store(
22301 NANOMIPS_EXTRACT_RT3(ctx
->opcode
));
22302 offset
= extract32(ctx
->opcode
, 0, 7) << 2;
22303 gen_st(ctx
, OPC_SW
, rt
, 28, offset
);
22306 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, 0, 0,
22307 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22308 (extract32(ctx
->opcode
, 1, 9) << 1));
22311 gen_compute_branch_nm(ctx
, OPC_BGEZAL
, 2, 0, 0,
22312 (sextract32(ctx
->opcode
, 0, 1) << 10) |
22313 (extract32(ctx
->opcode
, 1, 9) << 1));
22316 gen_compute_branch_nm(ctx
, OPC_BEQ
, 2, rt
, 0,
22317 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22318 (extract32(ctx
->opcode
, 1, 6) << 1));
22321 gen_compute_branch_nm(ctx
, OPC_BNE
, 2, rt
, 0,
22322 (sextract32(ctx
->opcode
, 0, 1) << 7) |
22323 (extract32(ctx
->opcode
, 1, 6) << 1));
22326 switch (ctx
->opcode
& 0xf) {
22329 switch (extract32(ctx
->opcode
, 4, 1)) {
22331 gen_compute_branch_nm(ctx
, OPC_JR
, 2,
22332 extract32(ctx
->opcode
, 5, 5), 0, 0);
22335 gen_compute_branch_nm(ctx
, OPC_JALR
, 2,
22336 extract32(ctx
->opcode
, 5, 5), 31, 0);
22343 uint32_t opc
= extract32(ctx
->opcode
, 4, 3) <
22344 extract32(ctx
->opcode
, 7, 3) ? OPC_BEQ
: OPC_BNE
;
22345 gen_compute_branch_nm(ctx
, opc
, 2, rs
, rt
,
22346 extract32(ctx
->opcode
, 0, 4) << 1);
22353 int count
= extract32(ctx
->opcode
, 0, 4);
22354 int u
= extract32(ctx
->opcode
, 4, 4) << 4;
22356 rt
= 30 + extract32(ctx
->opcode
, 9, 1);
22357 switch (extract32(ctx
->opcode
, 8, 1)) {
22359 gen_save(ctx
, rt
, count
, 0, u
);
22361 case NM_RESTORE_JRC16
:
22362 gen_restore(ctx
, rt
, count
, 0, u
);
22363 gen_compute_branch_nm(ctx
, OPC_JR
, 2, 31, 0, 0);
22372 static const int gpr2reg1
[] = {4, 5, 6, 7};
22373 static const int gpr2reg2
[] = {5, 6, 7, 8};
22375 int rd2
= extract32(ctx
->opcode
, 3, 1) << 1 |
22376 extract32(ctx
->opcode
, 8, 1);
22377 int r1
= gpr2reg1
[rd2
];
22378 int r2
= gpr2reg2
[rd2
];
22379 int r3
= extract32(ctx
->opcode
, 4, 1) << 3 |
22380 extract32(ctx
->opcode
, 0, 3);
22381 int r4
= extract32(ctx
->opcode
, 9, 1) << 3 |
22382 extract32(ctx
->opcode
, 5, 3);
22383 TCGv t0
= tcg_temp_new();
22384 TCGv t1
= tcg_temp_new();
22385 if (op
== NM_MOVEP
) {
22388 rs
= decode_gpr_gpr4_zero(r3
);
22389 rt
= decode_gpr_gpr4_zero(r4
);
22391 rd
= decode_gpr_gpr4(r3
);
22392 re
= decode_gpr_gpr4(r4
);
22396 gen_load_gpr(t0
, rs
);
22397 gen_load_gpr(t1
, rt
);
22398 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
22399 tcg_gen_mov_tl(cpu_gpr
[re
], t1
);
22405 return decode_nanomips_32_48_opc(env
, ctx
);
22412 /* SmartMIPS extension to MIPS32 */
22414 #if defined(TARGET_MIPS64)
22416 /* MDMX extension to MIPS64 */
22420 /* MIPSDSP functions. */
22421 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
22422 int rd
, int base
, int offset
)
22427 t0
= tcg_temp_new();
22430 gen_load_gpr(t0
, offset
);
22431 } else if (offset
== 0) {
22432 gen_load_gpr(t0
, base
);
22434 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
22439 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
22440 gen_store_gpr(t0
, rd
);
22443 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
22444 gen_store_gpr(t0
, rd
);
22447 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
22448 gen_store_gpr(t0
, rd
);
22450 #if defined(TARGET_MIPS64)
22452 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
22453 gen_store_gpr(t0
, rd
);
22460 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
22461 int ret
, int v1
, int v2
)
22467 /* Treat as NOP. */
22471 v1_t
= tcg_temp_new();
22472 v2_t
= tcg_temp_new();
22474 gen_load_gpr(v1_t
, v1
);
22475 gen_load_gpr(v2_t
, v2
);
22478 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22479 case OPC_MULT_G_2E
:
22483 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22485 case OPC_ADDUH_R_QB
:
22486 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22489 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22491 case OPC_ADDQH_R_PH
:
22492 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22495 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22497 case OPC_ADDQH_R_W
:
22498 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22501 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22503 case OPC_SUBUH_R_QB
:
22504 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22507 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22509 case OPC_SUBQH_R_PH
:
22510 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22513 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22515 case OPC_SUBQH_R_W
:
22516 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22520 case OPC_ABSQ_S_PH_DSP
:
22522 case OPC_ABSQ_S_QB
:
22524 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
22526 case OPC_ABSQ_S_PH
:
22528 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
22532 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
22534 case OPC_PRECEQ_W_PHL
:
22536 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
22537 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22539 case OPC_PRECEQ_W_PHR
:
22541 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
22542 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
22543 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
22545 case OPC_PRECEQU_PH_QBL
:
22547 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
22549 case OPC_PRECEQU_PH_QBR
:
22551 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
22553 case OPC_PRECEQU_PH_QBLA
:
22555 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
22557 case OPC_PRECEQU_PH_QBRA
:
22559 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
22561 case OPC_PRECEU_PH_QBL
:
22563 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
22565 case OPC_PRECEU_PH_QBR
:
22567 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
22569 case OPC_PRECEU_PH_QBLA
:
22571 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
22573 case OPC_PRECEU_PH_QBRA
:
22575 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
22579 case OPC_ADDU_QB_DSP
:
22583 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22585 case OPC_ADDQ_S_PH
:
22587 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22591 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22595 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22597 case OPC_ADDU_S_QB
:
22599 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22603 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22605 case OPC_ADDU_S_PH
:
22607 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22611 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22613 case OPC_SUBQ_S_PH
:
22615 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22619 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22623 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22625 case OPC_SUBU_S_QB
:
22627 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22631 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22633 case OPC_SUBU_S_PH
:
22635 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22639 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22643 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22647 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
22649 case OPC_RADDU_W_QB
:
22651 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
22655 case OPC_CMPU_EQ_QB_DSP
:
22657 case OPC_PRECR_QB_PH
:
22659 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22661 case OPC_PRECRQ_QB_PH
:
22663 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22665 case OPC_PRECR_SRA_PH_W
:
22668 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22669 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22671 tcg_temp_free_i32(sa_t
);
22674 case OPC_PRECR_SRA_R_PH_W
:
22677 TCGv_i32 sa_t
= tcg_const_i32(v2
);
22678 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
22680 tcg_temp_free_i32(sa_t
);
22683 case OPC_PRECRQ_PH_W
:
22685 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
22687 case OPC_PRECRQ_RS_PH_W
:
22689 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22691 case OPC_PRECRQU_S_QB_PH
:
22693 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22697 #ifdef TARGET_MIPS64
22698 case OPC_ABSQ_S_QH_DSP
:
22700 case OPC_PRECEQ_L_PWL
:
22702 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
22704 case OPC_PRECEQ_L_PWR
:
22706 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
22708 case OPC_PRECEQ_PW_QHL
:
22710 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
22712 case OPC_PRECEQ_PW_QHR
:
22714 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
22716 case OPC_PRECEQ_PW_QHLA
:
22718 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
22720 case OPC_PRECEQ_PW_QHRA
:
22722 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
22724 case OPC_PRECEQU_QH_OBL
:
22726 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
22728 case OPC_PRECEQU_QH_OBR
:
22730 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
22732 case OPC_PRECEQU_QH_OBLA
:
22734 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
22736 case OPC_PRECEQU_QH_OBRA
:
22738 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
22740 case OPC_PRECEU_QH_OBL
:
22742 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
22744 case OPC_PRECEU_QH_OBR
:
22746 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
22748 case OPC_PRECEU_QH_OBLA
:
22750 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
22752 case OPC_PRECEU_QH_OBRA
:
22754 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
22756 case OPC_ABSQ_S_OB
:
22758 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
22760 case OPC_ABSQ_S_PW
:
22762 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
22764 case OPC_ABSQ_S_QH
:
22766 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
22770 case OPC_ADDU_OB_DSP
:
22772 case OPC_RADDU_L_OB
:
22774 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
22778 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22780 case OPC_SUBQ_S_PW
:
22782 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22786 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22788 case OPC_SUBQ_S_QH
:
22790 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22794 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22796 case OPC_SUBU_S_OB
:
22798 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22802 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22804 case OPC_SUBU_S_QH
:
22806 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22810 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22812 case OPC_SUBUH_R_OB
:
22814 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22818 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22820 case OPC_ADDQ_S_PW
:
22822 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22826 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22828 case OPC_ADDQ_S_QH
:
22830 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22834 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22836 case OPC_ADDU_S_OB
:
22838 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22842 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22844 case OPC_ADDU_S_QH
:
22846 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22850 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22852 case OPC_ADDUH_R_OB
:
22854 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
22858 case OPC_CMPU_EQ_OB_DSP
:
22860 case OPC_PRECR_OB_QH
:
22862 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22864 case OPC_PRECR_SRA_QH_PW
:
22867 TCGv_i32 ret_t
= tcg_const_i32(ret
);
22868 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
22869 tcg_temp_free_i32(ret_t
);
22872 case OPC_PRECR_SRA_R_QH_PW
:
22875 TCGv_i32 sa_v
= tcg_const_i32(ret
);
22876 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
22877 tcg_temp_free_i32(sa_v
);
22880 case OPC_PRECRQ_OB_QH
:
22882 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
22884 case OPC_PRECRQ_PW_L
:
22886 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
22888 case OPC_PRECRQ_QH_PW
:
22890 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
22892 case OPC_PRECRQ_RS_QH_PW
:
22894 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22896 case OPC_PRECRQU_S_OB_QH
:
22898 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22905 tcg_temp_free(v1_t
);
22906 tcg_temp_free(v2_t
);
22909 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
22910 int ret
, int v1
, int v2
)
22918 /* Treat as NOP. */
22922 t0
= tcg_temp_new();
22923 v1_t
= tcg_temp_new();
22924 v2_t
= tcg_temp_new();
22926 tcg_gen_movi_tl(t0
, v1
);
22927 gen_load_gpr(v1_t
, v1
);
22928 gen_load_gpr(v2_t
, v2
);
22931 case OPC_SHLL_QB_DSP
:
22933 op2
= MASK_SHLL_QB(ctx
->opcode
);
22937 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22941 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22945 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22949 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22951 case OPC_SHLL_S_PH
:
22953 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22955 case OPC_SHLLV_S_PH
:
22957 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22961 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
22963 case OPC_SHLLV_S_W
:
22965 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
22969 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
22973 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22977 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
22981 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
22985 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
22987 case OPC_SHRA_R_QB
:
22989 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
22993 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
22995 case OPC_SHRAV_R_QB
:
22997 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23001 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
23003 case OPC_SHRA_R_PH
:
23005 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
23009 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23011 case OPC_SHRAV_R_PH
:
23013 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23017 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
23019 case OPC_SHRAV_R_W
:
23021 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
23023 default: /* Invalid */
23024 MIPS_INVAL("MASK SHLL.QB");
23025 generate_exception_end(ctx
, EXCP_RI
);
23030 #ifdef TARGET_MIPS64
23031 case OPC_SHLL_OB_DSP
:
23032 op2
= MASK_SHLL_OB(ctx
->opcode
);
23036 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23040 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23042 case OPC_SHLL_S_PW
:
23044 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23046 case OPC_SHLLV_S_PW
:
23048 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23052 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23056 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23060 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23064 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23066 case OPC_SHLL_S_QH
:
23068 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
23070 case OPC_SHLLV_S_QH
:
23072 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
23076 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
23080 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23082 case OPC_SHRA_R_OB
:
23084 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
23086 case OPC_SHRAV_R_OB
:
23088 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23092 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
23096 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23098 case OPC_SHRA_R_PW
:
23100 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
23102 case OPC_SHRAV_R_PW
:
23104 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
23108 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
23112 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23114 case OPC_SHRA_R_QH
:
23116 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
23118 case OPC_SHRAV_R_QH
:
23120 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23124 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
23128 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
23132 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
23136 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
23138 default: /* Invalid */
23139 MIPS_INVAL("MASK SHLL.OB");
23140 generate_exception_end(ctx
, EXCP_RI
);
23148 tcg_temp_free(v1_t
);
23149 tcg_temp_free(v2_t
);
23152 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23153 int ret
, int v1
, int v2
, int check_ret
)
23159 if ((ret
== 0) && (check_ret
== 1)) {
23160 /* Treat as NOP. */
23164 t0
= tcg_temp_new_i32();
23165 v1_t
= tcg_temp_new();
23166 v2_t
= tcg_temp_new();
23168 tcg_gen_movi_i32(t0
, ret
);
23169 gen_load_gpr(v1_t
, v1
);
23170 gen_load_gpr(v2_t
, v2
);
23174 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23175 * the same mask and op1.
23177 case OPC_MULT_G_2E
:
23181 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23184 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23187 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23189 case OPC_MULQ_RS_W
:
23190 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23194 case OPC_DPA_W_PH_DSP
:
23196 case OPC_DPAU_H_QBL
:
23198 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23200 case OPC_DPAU_H_QBR
:
23202 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23204 case OPC_DPSU_H_QBL
:
23206 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
23208 case OPC_DPSU_H_QBR
:
23210 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
23214 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23216 case OPC_DPAX_W_PH
:
23218 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23220 case OPC_DPAQ_S_W_PH
:
23222 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23224 case OPC_DPAQX_S_W_PH
:
23226 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23228 case OPC_DPAQX_SA_W_PH
:
23230 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23234 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23236 case OPC_DPSX_W_PH
:
23238 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23240 case OPC_DPSQ_S_W_PH
:
23242 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23244 case OPC_DPSQX_S_W_PH
:
23246 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23248 case OPC_DPSQX_SA_W_PH
:
23250 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23252 case OPC_MULSAQ_S_W_PH
:
23254 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23256 case OPC_DPAQ_SA_L_W
:
23258 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23260 case OPC_DPSQ_SA_L_W
:
23262 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
23264 case OPC_MAQ_S_W_PHL
:
23266 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23268 case OPC_MAQ_S_W_PHR
:
23270 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23272 case OPC_MAQ_SA_W_PHL
:
23274 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
23276 case OPC_MAQ_SA_W_PHR
:
23278 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
23280 case OPC_MULSA_W_PH
:
23282 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
23286 #ifdef TARGET_MIPS64
23287 case OPC_DPAQ_W_QH_DSP
:
23289 int ac
= ret
& 0x03;
23290 tcg_gen_movi_i32(t0
, ac
);
23295 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
23299 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
23303 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
23307 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
23311 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23313 case OPC_DPAQ_S_W_QH
:
23315 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23317 case OPC_DPAQ_SA_L_PW
:
23319 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23321 case OPC_DPAU_H_OBL
:
23323 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23325 case OPC_DPAU_H_OBR
:
23327 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23331 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23333 case OPC_DPSQ_S_W_QH
:
23335 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23337 case OPC_DPSQ_SA_L_PW
:
23339 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23341 case OPC_DPSU_H_OBL
:
23343 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
23345 case OPC_DPSU_H_OBR
:
23347 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
23349 case OPC_MAQ_S_L_PWL
:
23351 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
23353 case OPC_MAQ_S_L_PWR
:
23355 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
23357 case OPC_MAQ_S_W_QHLL
:
23359 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23361 case OPC_MAQ_SA_W_QHLL
:
23363 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
23365 case OPC_MAQ_S_W_QHLR
:
23367 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23369 case OPC_MAQ_SA_W_QHLR
:
23371 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
23373 case OPC_MAQ_S_W_QHRL
:
23375 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23377 case OPC_MAQ_SA_W_QHRL
:
23379 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
23381 case OPC_MAQ_S_W_QHRR
:
23383 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23385 case OPC_MAQ_SA_W_QHRR
:
23387 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
23389 case OPC_MULSAQ_S_L_PW
:
23391 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
23393 case OPC_MULSAQ_S_W_QH
:
23395 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
23401 case OPC_ADDU_QB_DSP
:
23403 case OPC_MULEU_S_PH_QBL
:
23405 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23407 case OPC_MULEU_S_PH_QBR
:
23409 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23411 case OPC_MULQ_RS_PH
:
23413 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23415 case OPC_MULEQ_S_W_PHL
:
23417 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23419 case OPC_MULEQ_S_W_PHR
:
23421 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23423 case OPC_MULQ_S_PH
:
23425 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23429 #ifdef TARGET_MIPS64
23430 case OPC_ADDU_OB_DSP
:
23432 case OPC_MULEQ_S_PW_QHL
:
23434 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23436 case OPC_MULEQ_S_PW_QHR
:
23438 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23440 case OPC_MULEU_S_QH_OBL
:
23442 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23444 case OPC_MULEU_S_QH_OBR
:
23446 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23448 case OPC_MULQ_RS_QH
:
23450 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23457 tcg_temp_free_i32(t0
);
23458 tcg_temp_free(v1_t
);
23459 tcg_temp_free(v2_t
);
23462 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23470 /* Treat as NOP. */
23474 t0
= tcg_temp_new();
23475 val_t
= tcg_temp_new();
23476 gen_load_gpr(val_t
, val
);
23479 case OPC_ABSQ_S_PH_DSP
:
23483 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
23488 target_long result
;
23489 imm
= (ctx
->opcode
>> 16) & 0xFF;
23490 result
= (uint32_t)imm
<< 24 |
23491 (uint32_t)imm
<< 16 |
23492 (uint32_t)imm
<< 8 |
23494 result
= (int32_t)result
;
23495 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
23500 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23501 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23502 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23503 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23504 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23505 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23510 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23511 imm
= (int16_t)(imm
<< 6) >> 6;
23512 tcg_gen_movi_tl(cpu_gpr
[ret
], \
23513 (target_long
)((int32_t)imm
<< 16 | \
23519 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23520 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23521 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23522 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
23526 #ifdef TARGET_MIPS64
23527 case OPC_ABSQ_S_QH_DSP
:
23534 imm
= (ctx
->opcode
>> 16) & 0xFF;
23535 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
23536 temp
= (temp
<< 16) | temp
;
23537 temp
= (temp
<< 32) | temp
;
23538 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23546 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23547 imm
= (int16_t)(imm
<< 6) >> 6;
23548 temp
= ((target_long
)imm
<< 32) \
23549 | ((target_long
)imm
& 0xFFFFFFFF);
23550 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23558 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23559 imm
= (int16_t)(imm
<< 6) >> 6;
23561 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
23562 ((uint64_t)(uint16_t)imm
<< 32) |
23563 ((uint64_t)(uint16_t)imm
<< 16) |
23564 (uint64_t)(uint16_t)imm
;
23565 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
23570 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
23571 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
23572 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23573 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23574 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23575 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23576 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23580 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
23581 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23582 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23586 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
23587 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
23588 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23589 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
23590 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
23597 tcg_temp_free(val_t
);
23600 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
23601 uint32_t op1
, uint32_t op2
,
23602 int ret
, int v1
, int v2
, int check_ret
)
23608 if ((ret
== 0) && (check_ret
== 1)) {
23609 /* Treat as NOP. */
23613 t1
= tcg_temp_new();
23614 v1_t
= tcg_temp_new();
23615 v2_t
= tcg_temp_new();
23617 gen_load_gpr(v1_t
, v1
);
23618 gen_load_gpr(v2_t
, v2
);
23621 case OPC_CMPU_EQ_QB_DSP
:
23623 case OPC_CMPU_EQ_QB
:
23625 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
23627 case OPC_CMPU_LT_QB
:
23629 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
23631 case OPC_CMPU_LE_QB
:
23633 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
23635 case OPC_CMPGU_EQ_QB
:
23637 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23639 case OPC_CMPGU_LT_QB
:
23641 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23643 case OPC_CMPGU_LE_QB
:
23645 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
23647 case OPC_CMPGDU_EQ_QB
:
23649 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
23650 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23651 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23652 tcg_gen_shli_tl(t1
, t1
, 24);
23653 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23655 case OPC_CMPGDU_LT_QB
:
23657 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
23658 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23659 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23660 tcg_gen_shli_tl(t1
, t1
, 24);
23661 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23663 case OPC_CMPGDU_LE_QB
:
23665 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
23666 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
23667 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
23668 tcg_gen_shli_tl(t1
, t1
, 24);
23669 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
23671 case OPC_CMP_EQ_PH
:
23673 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
23675 case OPC_CMP_LT_PH
:
23677 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
23679 case OPC_CMP_LE_PH
:
23681 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
23685 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23689 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23691 case OPC_PACKRL_PH
:
23693 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
23697 #ifdef TARGET_MIPS64
23698 case OPC_CMPU_EQ_OB_DSP
:
23700 case OPC_CMP_EQ_PW
:
23702 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
23704 case OPC_CMP_LT_PW
:
23706 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
23708 case OPC_CMP_LE_PW
:
23710 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
23712 case OPC_CMP_EQ_QH
:
23714 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
23716 case OPC_CMP_LT_QH
:
23718 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
23720 case OPC_CMP_LE_QH
:
23722 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
23724 case OPC_CMPGDU_EQ_OB
:
23726 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23728 case OPC_CMPGDU_LT_OB
:
23730 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23732 case OPC_CMPGDU_LE_OB
:
23734 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23736 case OPC_CMPGU_EQ_OB
:
23738 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23740 case OPC_CMPGU_LT_OB
:
23742 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23744 case OPC_CMPGU_LE_OB
:
23746 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
23748 case OPC_CMPU_EQ_OB
:
23750 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
23752 case OPC_CMPU_LT_OB
:
23754 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
23756 case OPC_CMPU_LE_OB
:
23758 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
23760 case OPC_PACKRL_PW
:
23762 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
23766 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23770 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23774 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
23782 tcg_temp_free(v1_t
);
23783 tcg_temp_free(v2_t
);
23786 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
23787 uint32_t op1
, int rt
, int rs
, int sa
)
23794 /* Treat as NOP. */
23798 t0
= tcg_temp_new();
23799 gen_load_gpr(t0
, rs
);
23802 case OPC_APPEND_DSP
:
23803 switch (MASK_APPEND(ctx
->opcode
)) {
23806 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
23808 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23812 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23813 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23814 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
23815 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23817 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23821 if (sa
!= 0 && sa
!= 2) {
23822 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23823 tcg_gen_ext32u_tl(t0
, t0
);
23824 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
23825 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23827 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
23829 default: /* Invalid */
23830 MIPS_INVAL("MASK APPEND");
23831 generate_exception_end(ctx
, EXCP_RI
);
23835 #ifdef TARGET_MIPS64
23836 case OPC_DAPPEND_DSP
:
23837 switch (MASK_DAPPEND(ctx
->opcode
)) {
23840 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
23844 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
23845 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
23846 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
23850 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
23851 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
23852 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23857 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
23858 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
23859 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
23860 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
23863 default: /* Invalid */
23864 MIPS_INVAL("MASK DAPPEND");
23865 generate_exception_end(ctx
, EXCP_RI
);
23874 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
23875 int ret
, int v1
, int v2
, int check_ret
)
23884 if ((ret
== 0) && (check_ret
== 1)) {
23885 /* Treat as NOP. */
23889 t0
= tcg_temp_new();
23890 t1
= tcg_temp_new();
23891 v1_t
= tcg_temp_new();
23892 v2_t
= tcg_temp_new();
23894 gen_load_gpr(v1_t
, v1
);
23895 gen_load_gpr(v2_t
, v2
);
23898 case OPC_EXTR_W_DSP
:
23902 tcg_gen_movi_tl(t0
, v2
);
23903 tcg_gen_movi_tl(t1
, v1
);
23904 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23907 tcg_gen_movi_tl(t0
, v2
);
23908 tcg_gen_movi_tl(t1
, v1
);
23909 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23911 case OPC_EXTR_RS_W
:
23912 tcg_gen_movi_tl(t0
, v2
);
23913 tcg_gen_movi_tl(t1
, v1
);
23914 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23917 tcg_gen_movi_tl(t0
, v2
);
23918 tcg_gen_movi_tl(t1
, v1
);
23919 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23921 case OPC_EXTRV_S_H
:
23922 tcg_gen_movi_tl(t0
, v2
);
23923 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23926 tcg_gen_movi_tl(t0
, v2
);
23927 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23929 case OPC_EXTRV_R_W
:
23930 tcg_gen_movi_tl(t0
, v2
);
23931 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23933 case OPC_EXTRV_RS_W
:
23934 tcg_gen_movi_tl(t0
, v2
);
23935 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23938 tcg_gen_movi_tl(t0
, v2
);
23939 tcg_gen_movi_tl(t1
, v1
);
23940 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23943 tcg_gen_movi_tl(t0
, v2
);
23944 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23947 tcg_gen_movi_tl(t0
, v2
);
23948 tcg_gen_movi_tl(t1
, v1
);
23949 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
23952 tcg_gen_movi_tl(t0
, v2
);
23953 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
23956 imm
= (ctx
->opcode
>> 20) & 0x3F;
23957 tcg_gen_movi_tl(t0
, ret
);
23958 tcg_gen_movi_tl(t1
, imm
);
23959 gen_helper_shilo(t0
, t1
, cpu_env
);
23962 tcg_gen_movi_tl(t0
, ret
);
23963 gen_helper_shilo(t0
, v1_t
, cpu_env
);
23966 tcg_gen_movi_tl(t0
, ret
);
23967 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
23970 imm
= (ctx
->opcode
>> 11) & 0x3FF;
23971 tcg_gen_movi_tl(t0
, imm
);
23972 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
23975 imm
= (ctx
->opcode
>> 16) & 0x03FF;
23976 tcg_gen_movi_tl(t0
, imm
);
23977 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
23981 #ifdef TARGET_MIPS64
23982 case OPC_DEXTR_W_DSP
:
23986 tcg_gen_movi_tl(t0
, ret
);
23987 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
23991 int shift
= (ctx
->opcode
>> 19) & 0x7F;
23992 int ac
= (ctx
->opcode
>> 11) & 0x03;
23993 tcg_gen_movi_tl(t0
, shift
);
23994 tcg_gen_movi_tl(t1
, ac
);
23995 gen_helper_dshilo(t0
, t1
, cpu_env
);
24000 int ac
= (ctx
->opcode
>> 11) & 0x03;
24001 tcg_gen_movi_tl(t0
, ac
);
24002 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
24006 tcg_gen_movi_tl(t0
, v2
);
24007 tcg_gen_movi_tl(t1
, v1
);
24009 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24012 tcg_gen_movi_tl(t0
, v2
);
24013 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24016 tcg_gen_movi_tl(t0
, v2
);
24017 tcg_gen_movi_tl(t1
, v1
);
24018 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24021 tcg_gen_movi_tl(t0
, v2
);
24022 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24025 tcg_gen_movi_tl(t0
, v2
);
24026 tcg_gen_movi_tl(t1
, v1
);
24027 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24029 case OPC_DEXTR_R_L
:
24030 tcg_gen_movi_tl(t0
, v2
);
24031 tcg_gen_movi_tl(t1
, v1
);
24032 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24034 case OPC_DEXTR_RS_L
:
24035 tcg_gen_movi_tl(t0
, v2
);
24036 tcg_gen_movi_tl(t1
, v1
);
24037 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24040 tcg_gen_movi_tl(t0
, v2
);
24041 tcg_gen_movi_tl(t1
, v1
);
24042 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24044 case OPC_DEXTR_R_W
:
24045 tcg_gen_movi_tl(t0
, v2
);
24046 tcg_gen_movi_tl(t1
, v1
);
24047 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24049 case OPC_DEXTR_RS_W
:
24050 tcg_gen_movi_tl(t0
, v2
);
24051 tcg_gen_movi_tl(t1
, v1
);
24052 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24054 case OPC_DEXTR_S_H
:
24055 tcg_gen_movi_tl(t0
, v2
);
24056 tcg_gen_movi_tl(t1
, v1
);
24057 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24059 case OPC_DEXTRV_S_H
:
24060 tcg_gen_movi_tl(t0
, v2
);
24061 tcg_gen_movi_tl(t1
, v1
);
24062 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
24065 tcg_gen_movi_tl(t0
, v2
);
24066 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24068 case OPC_DEXTRV_R_L
:
24069 tcg_gen_movi_tl(t0
, v2
);
24070 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24072 case OPC_DEXTRV_RS_L
:
24073 tcg_gen_movi_tl(t0
, v2
);
24074 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24077 tcg_gen_movi_tl(t0
, v2
);
24078 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24080 case OPC_DEXTRV_R_W
:
24081 tcg_gen_movi_tl(t0
, v2
);
24082 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24084 case OPC_DEXTRV_RS_W
:
24085 tcg_gen_movi_tl(t0
, v2
);
24086 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
24095 tcg_temp_free(v1_t
);
24096 tcg_temp_free(v2_t
);
24099 /* End MIPSDSP functions. */
24101 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
24103 int rs
, rt
, rd
, sa
;
24106 rs
= (ctx
->opcode
>> 21) & 0x1f;
24107 rt
= (ctx
->opcode
>> 16) & 0x1f;
24108 rd
= (ctx
->opcode
>> 11) & 0x1f;
24109 sa
= (ctx
->opcode
>> 6) & 0x1f;
24111 op1
= MASK_SPECIAL(ctx
->opcode
);
24114 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24120 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24130 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24133 MIPS_INVAL("special_r6 muldiv");
24134 generate_exception_end(ctx
, EXCP_RI
);
24140 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24144 if (rt
== 0 && sa
== 1) {
24146 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24147 * We need additionally to check other fields.
24149 gen_cl(ctx
, op1
, rd
, rs
);
24151 generate_exception_end(ctx
, EXCP_RI
);
24155 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
24156 gen_helper_do_semihosting(cpu_env
);
24158 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
24159 generate_exception_end(ctx
, EXCP_RI
);
24161 generate_exception_end(ctx
, EXCP_DBp
);
24165 #if defined(TARGET_MIPS64)
24167 check_mips_64(ctx
);
24168 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
24172 if (rt
== 0 && sa
== 1) {
24174 * Major opcode and function field is shared with preR6 MFHI/MTHI.
24175 * We need additionally to check other fields.
24177 check_mips_64(ctx
);
24178 gen_cl(ctx
, op1
, rd
, rs
);
24180 generate_exception_end(ctx
, EXCP_RI
);
24188 op2
= MASK_R6_MULDIV(ctx
->opcode
);
24198 check_mips_64(ctx
);
24199 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
24202 MIPS_INVAL("special_r6 muldiv");
24203 generate_exception_end(ctx
, EXCP_RI
);
24208 default: /* Invalid */
24209 MIPS_INVAL("special_r6");
24210 generate_exception_end(ctx
, EXCP_RI
);
24215 static void decode_opc_special_tx79(CPUMIPSState
*env
, DisasContext
*ctx
)
24217 int rs
= extract32(ctx
->opcode
, 21, 5);
24218 int rt
= extract32(ctx
->opcode
, 16, 5);
24219 int rd
= extract32(ctx
->opcode
, 11, 5);
24220 uint32_t op1
= MASK_SPECIAL(ctx
->opcode
);
24223 case OPC_MOVN
: /* Conditional move */
24225 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24227 case OPC_MFHI
: /* Move from HI/LO */
24229 gen_HILO(ctx
, op1
, 0, rd
);
24232 case OPC_MTLO
: /* Move to HI/LO */
24233 gen_HILO(ctx
, op1
, 0, rs
);
24237 gen_mul_txx9(ctx
, op1
, rd
, rs
, rt
);
24241 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24243 #if defined(TARGET_MIPS64)
24248 check_insn_opc_user_only(ctx
, INSN_R5900
);
24249 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24253 gen_compute_branch(ctx
, op1
, 4, rs
, 0, 0, 4);
24255 default: /* Invalid */
24256 MIPS_INVAL("special_tx79");
24257 generate_exception_end(ctx
, EXCP_RI
);
24262 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
24264 int rs
, rt
, rd
, sa
;
24267 rs
= (ctx
->opcode
>> 21) & 0x1f;
24268 rt
= (ctx
->opcode
>> 16) & 0x1f;
24269 rd
= (ctx
->opcode
>> 11) & 0x1f;
24270 sa
= (ctx
->opcode
>> 6) & 0x1f;
24272 op1
= MASK_SPECIAL(ctx
->opcode
);
24274 case OPC_MOVN
: /* Conditional move */
24276 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
24277 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
24278 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
24280 case OPC_MFHI
: /* Move from HI/LO */
24282 gen_HILO(ctx
, op1
, rs
& 3, rd
);
24285 case OPC_MTLO
: /* Move to HI/LO */
24286 gen_HILO(ctx
, op1
, rd
& 3, rs
);
24289 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
24290 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
24291 check_cp1_enabled(ctx
);
24292 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
24293 (ctx
->opcode
>> 16) & 1);
24295 generate_exception_err(ctx
, EXCP_CpU
, 1);
24301 check_insn(ctx
, INSN_VR54XX
);
24302 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
24303 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
24305 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
24310 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24312 #if defined(TARGET_MIPS64)
24317 check_insn(ctx
, ISA_MIPS3
);
24318 check_mips_64(ctx
);
24319 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
24323 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24326 #ifdef MIPS_STRICT_STANDARD
24327 MIPS_INVAL("SPIM");
24328 generate_exception_end(ctx
, EXCP_RI
);
24330 /* Implemented as RI exception for now. */
24331 MIPS_INVAL("spim (unofficial)");
24332 generate_exception_end(ctx
, EXCP_RI
);
24335 default: /* Invalid */
24336 MIPS_INVAL("special_legacy");
24337 generate_exception_end(ctx
, EXCP_RI
);
24342 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
24344 int rs
, rt
, rd
, sa
;
24347 rs
= (ctx
->opcode
>> 21) & 0x1f;
24348 rt
= (ctx
->opcode
>> 16) & 0x1f;
24349 rd
= (ctx
->opcode
>> 11) & 0x1f;
24350 sa
= (ctx
->opcode
>> 6) & 0x1f;
24352 op1
= MASK_SPECIAL(ctx
->opcode
);
24354 case OPC_SLL
: /* Shift with immediate */
24355 if (sa
== 5 && rd
== 0 &&
24356 rs
== 0 && rt
== 0) { /* PAUSE */
24357 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
24358 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
24359 generate_exception_end(ctx
, EXCP_RI
);
24365 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24368 switch ((ctx
->opcode
>> 21) & 0x1f) {
24370 /* rotr is decoded as srl on non-R2 CPUs */
24371 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24376 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24379 generate_exception_end(ctx
, EXCP_RI
);
24387 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24389 case OPC_SLLV
: /* Shifts */
24391 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24394 switch ((ctx
->opcode
>> 6) & 0x1f) {
24396 /* rotrv is decoded as srlv on non-R2 CPUs */
24397 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24402 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24405 generate_exception_end(ctx
, EXCP_RI
);
24409 case OPC_SLT
: /* Set on less than */
24411 gen_slt(ctx
, op1
, rd
, rs
, rt
);
24413 case OPC_AND
: /* Logic*/
24417 gen_logic(ctx
, op1
, rd
, rs
, rt
);
24420 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
24422 case OPC_TGE
: /* Traps */
24428 check_insn(ctx
, ISA_MIPS2
);
24429 gen_trap(ctx
, op1
, rs
, rt
, -1);
24431 case OPC_LSA
: /* OPC_PMON */
24432 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
24433 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
24434 decode_opc_special_r6(env
, ctx
);
24436 /* Pmon entry point, also R4010 selsl */
24437 #ifdef MIPS_STRICT_STANDARD
24438 MIPS_INVAL("PMON / selsl");
24439 generate_exception_end(ctx
, EXCP_RI
);
24441 gen_helper_0e0i(pmon
, sa
);
24446 generate_exception_end(ctx
, EXCP_SYSCALL
);
24449 generate_exception_end(ctx
, EXCP_BREAK
);
24452 check_insn(ctx
, ISA_MIPS2
);
24453 gen_sync(extract32(ctx
->opcode
, 6, 5));
24456 #if defined(TARGET_MIPS64)
24457 /* MIPS64 specific opcodes */
24462 check_insn(ctx
, ISA_MIPS3
);
24463 check_mips_64(ctx
);
24464 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24467 switch ((ctx
->opcode
>> 21) & 0x1f) {
24469 /* drotr is decoded as dsrl on non-R2 CPUs */
24470 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24475 check_insn(ctx
, ISA_MIPS3
);
24476 check_mips_64(ctx
);
24477 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24480 generate_exception_end(ctx
, EXCP_RI
);
24485 switch ((ctx
->opcode
>> 21) & 0x1f) {
24487 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24488 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24493 check_insn(ctx
, ISA_MIPS3
);
24494 check_mips_64(ctx
);
24495 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
24498 generate_exception_end(ctx
, EXCP_RI
);
24506 check_insn(ctx
, ISA_MIPS3
);
24507 check_mips_64(ctx
);
24508 gen_arith(ctx
, op1
, rd
, rs
, rt
);
24512 check_insn(ctx
, ISA_MIPS3
);
24513 check_mips_64(ctx
);
24514 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24517 switch ((ctx
->opcode
>> 6) & 0x1f) {
24519 /* drotrv is decoded as dsrlv on non-R2 CPUs */
24520 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
24525 check_insn(ctx
, ISA_MIPS3
);
24526 check_mips_64(ctx
);
24527 gen_shift(ctx
, op1
, rd
, rs
, rt
);
24530 generate_exception_end(ctx
, EXCP_RI
);
24535 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
24536 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
24537 decode_opc_special_r6(env
, ctx
);
24542 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
24543 decode_opc_special_r6(env
, ctx
);
24544 } else if (ctx
->insn_flags
& INSN_R5900
) {
24545 decode_opc_special_tx79(env
, ctx
);
24547 decode_opc_special_legacy(env
, ctx
);
24553 #if defined(TARGET_MIPS64)
24557 * MMI (MultiMedia Interface) ASE instructions
24558 * ===========================================
24562 * MMI instructions category: data communication
24563 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24565 * PCPYH PEXCH PEXTLB PINTH PPACB PEXT5 PREVH
24566 * PCPYLD PEXCW PEXTLH PINTEH PPACH PPAC5 PROT3W
24567 * PCPYUD PEXEH PEXTLW PPACW
24576 * Parallel Copy Halfword
24578 * 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
24579 * +-----------+---------+---------+---------+---------+-----------+
24580 * | MMI |0 0 0 0 0| rt | rd | PCPYH | MMI3 |
24581 * +-----------+---------+---------+---------+---------+-----------+
24583 static void gen_mmi_pcpyh(DisasContext
*ctx
)
24585 uint32_t pd
, rt
, rd
;
24588 opcode
= ctx
->opcode
;
24590 pd
= extract32(opcode
, 21, 5);
24591 rt
= extract32(opcode
, 16, 5);
24592 rd
= extract32(opcode
, 11, 5);
24594 if (unlikely(pd
!= 0)) {
24595 generate_exception_end(ctx
, EXCP_RI
);
24596 } else if (rd
== 0) {
24598 } else if (rt
== 0) {
24599 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24600 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24602 TCGv_i64 t0
= tcg_temp_new();
24603 TCGv_i64 t1
= tcg_temp_new();
24604 uint64_t mask
= (1ULL << 16) - 1;
24606 tcg_gen_andi_i64(t0
, cpu_gpr
[rt
], mask
);
24607 tcg_gen_movi_i64(t1
, 0);
24608 tcg_gen_or_i64(t1
, t0
, t1
);
24609 tcg_gen_shli_i64(t0
, t0
, 16);
24610 tcg_gen_or_i64(t1
, t0
, t1
);
24611 tcg_gen_shli_i64(t0
, t0
, 16);
24612 tcg_gen_or_i64(t1
, t0
, t1
);
24613 tcg_gen_shli_i64(t0
, t0
, 16);
24614 tcg_gen_or_i64(t1
, t0
, t1
);
24616 tcg_gen_mov_i64(cpu_gpr
[rd
], t1
);
24618 tcg_gen_andi_i64(t0
, cpu_mmr
[rt
], mask
);
24619 tcg_gen_movi_i64(t1
, 0);
24620 tcg_gen_or_i64(t1
, t0
, t1
);
24621 tcg_gen_shli_i64(t0
, t0
, 16);
24622 tcg_gen_or_i64(t1
, t0
, t1
);
24623 tcg_gen_shli_i64(t0
, t0
, 16);
24624 tcg_gen_or_i64(t1
, t0
, t1
);
24625 tcg_gen_shli_i64(t0
, t0
, 16);
24626 tcg_gen_or_i64(t1
, t0
, t1
);
24628 tcg_gen_mov_i64(cpu_mmr
[rd
], t1
);
24636 * PCPYLD rd, rs, rt
24638 * Parallel Copy Lower Doubleword
24640 * 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
24641 * +-----------+---------+---------+---------+---------+-----------+
24642 * | MMI | rs | rt | rd | PCPYLD | MMI2 |
24643 * +-----------+---------+---------+---------+---------+-----------+
24645 static void gen_mmi_pcpyld(DisasContext
*ctx
)
24647 uint32_t rs
, rt
, rd
;
24650 opcode
= ctx
->opcode
;
24652 rs
= extract32(opcode
, 21, 5);
24653 rt
= extract32(opcode
, 16, 5);
24654 rd
= extract32(opcode
, 11, 5);
24660 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24662 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_gpr
[rs
]);
24665 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24668 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_gpr
[rt
]);
24675 * PCPYUD rd, rs, rt
24677 * Parallel Copy Upper Doubleword
24679 * 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
24680 * +-----------+---------+---------+---------+---------+-----------+
24681 * | MMI | rs | rt | rd | PCPYUD | MMI3 |
24682 * +-----------+---------+---------+---------+---------+-----------+
24684 static void gen_mmi_pcpyud(DisasContext
*ctx
)
24686 uint32_t rs
, rt
, rd
;
24689 opcode
= ctx
->opcode
;
24691 rs
= extract32(opcode
, 21, 5);
24692 rt
= extract32(opcode
, 16, 5);
24693 rd
= extract32(opcode
, 11, 5);
24699 tcg_gen_movi_i64(cpu_gpr
[rd
], 0);
24701 tcg_gen_mov_i64(cpu_gpr
[rd
], cpu_mmr
[rs
]);
24704 tcg_gen_movi_i64(cpu_mmr
[rd
], 0);
24707 tcg_gen_mov_i64(cpu_mmr
[rd
], cpu_mmr
[rt
]);
24716 #if !defined(TARGET_MIPS64)
24718 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24719 #define MXU_APTN1_A 0
24720 #define MXU_APTN1_S 1
24722 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24723 #define MXU_APTN2_AA 0
24724 #define MXU_APTN2_AS 1
24725 #define MXU_APTN2_SA 2
24726 #define MXU_APTN2_SS 3
24728 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24729 #define MXU_EPTN2_AA 0
24730 #define MXU_EPTN2_AS 1
24731 #define MXU_EPTN2_SA 2
24732 #define MXU_EPTN2_SS 3
24734 /* MXU operand getting pattern 'optn2' */
24735 #define MXU_OPTN2_PTN0 0
24736 #define MXU_OPTN2_PTN1 1
24737 #define MXU_OPTN2_PTN2 2
24738 #define MXU_OPTN2_PTN3 3
24739 /* alternative naming scheme for 'optn2' */
24740 #define MXU_OPTN2_WW 0
24741 #define MXU_OPTN2_LW 1
24742 #define MXU_OPTN2_HW 2
24743 #define MXU_OPTN2_XW 3
24745 /* MXU operand getting pattern 'optn3' */
24746 #define MXU_OPTN3_PTN0 0
24747 #define MXU_OPTN3_PTN1 1
24748 #define MXU_OPTN3_PTN2 2
24749 #define MXU_OPTN3_PTN3 3
24750 #define MXU_OPTN3_PTN4 4
24751 #define MXU_OPTN3_PTN5 5
24752 #define MXU_OPTN3_PTN6 6
24753 #define MXU_OPTN3_PTN7 7
24757 * S32I2M XRa, rb - Register move from GRF to XRF
24759 static void gen_mxu_s32i2m(DisasContext
*ctx
)
24764 t0
= tcg_temp_new();
24766 XRa
= extract32(ctx
->opcode
, 6, 5);
24767 Rb
= extract32(ctx
->opcode
, 16, 5);
24769 gen_load_gpr(t0
, Rb
);
24771 gen_store_mxu_gpr(t0
, XRa
);
24772 } else if (XRa
== 16) {
24773 gen_store_mxu_cr(t0
);
24780 * S32M2I XRa, rb - Register move from XRF to GRF
24782 static void gen_mxu_s32m2i(DisasContext
*ctx
)
24787 t0
= tcg_temp_new();
24789 XRa
= extract32(ctx
->opcode
, 6, 5);
24790 Rb
= extract32(ctx
->opcode
, 16, 5);
24793 gen_load_mxu_gpr(t0
, XRa
);
24794 } else if (XRa
== 16) {
24795 gen_load_mxu_cr(t0
);
24798 gen_store_gpr(t0
, Rb
);
24804 * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24806 static void gen_mxu_s8ldd(DisasContext
*ctx
)
24809 uint32_t XRa
, Rb
, s8
, optn3
;
24811 t0
= tcg_temp_new();
24812 t1
= tcg_temp_new();
24814 XRa
= extract32(ctx
->opcode
, 6, 4);
24815 s8
= extract32(ctx
->opcode
, 10, 8);
24816 optn3
= extract32(ctx
->opcode
, 18, 3);
24817 Rb
= extract32(ctx
->opcode
, 21, 5);
24819 gen_load_gpr(t0
, Rb
);
24820 tcg_gen_addi_tl(t0
, t0
, (int8_t)s8
);
24823 /* XRa[7:0] = tmp8 */
24824 case MXU_OPTN3_PTN0
:
24825 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24826 gen_load_mxu_gpr(t0
, XRa
);
24827 tcg_gen_deposit_tl(t0
, t0
, t1
, 0, 8);
24829 /* XRa[15:8] = tmp8 */
24830 case MXU_OPTN3_PTN1
:
24831 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24832 gen_load_mxu_gpr(t0
, XRa
);
24833 tcg_gen_deposit_tl(t0
, t0
, t1
, 8, 8);
24835 /* XRa[23:16] = tmp8 */
24836 case MXU_OPTN3_PTN2
:
24837 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24838 gen_load_mxu_gpr(t0
, XRa
);
24839 tcg_gen_deposit_tl(t0
, t0
, t1
, 16, 8);
24841 /* XRa[31:24] = tmp8 */
24842 case MXU_OPTN3_PTN3
:
24843 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24844 gen_load_mxu_gpr(t0
, XRa
);
24845 tcg_gen_deposit_tl(t0
, t0
, t1
, 24, 8);
24847 /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24848 case MXU_OPTN3_PTN4
:
24849 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24850 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
24852 /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24853 case MXU_OPTN3_PTN5
:
24854 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24855 tcg_gen_shli_tl(t1
, t1
, 8);
24856 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
24858 /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24859 case MXU_OPTN3_PTN6
:
24860 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_SB
);
24861 tcg_gen_mov_tl(t0
, t1
);
24862 tcg_gen_andi_tl(t0
, t0
, 0xFF00FFFF);
24863 tcg_gen_shli_tl(t1
, t1
, 16);
24864 tcg_gen_or_tl(t0
, t0
, t1
);
24866 /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24867 case MXU_OPTN3_PTN7
:
24868 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
24869 tcg_gen_deposit_tl(t1
, t1
, t1
, 8, 8);
24870 tcg_gen_deposit_tl(t0
, t1
, t1
, 16, 16);
24874 gen_store_mxu_gpr(t0
, XRa
);
24881 * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24883 static void gen_mxu_d16mul(DisasContext
*ctx
)
24885 TCGv t0
, t1
, t2
, t3
;
24886 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
;
24888 t0
= tcg_temp_new();
24889 t1
= tcg_temp_new();
24890 t2
= tcg_temp_new();
24891 t3
= tcg_temp_new();
24893 XRa
= extract32(ctx
->opcode
, 6, 4);
24894 XRb
= extract32(ctx
->opcode
, 10, 4);
24895 XRc
= extract32(ctx
->opcode
, 14, 4);
24896 XRd
= extract32(ctx
->opcode
, 18, 4);
24897 optn2
= extract32(ctx
->opcode
, 22, 2);
24899 gen_load_mxu_gpr(t1
, XRb
);
24900 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
24901 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
24902 gen_load_mxu_gpr(t3
, XRc
);
24903 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
24904 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
24907 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24908 tcg_gen_mul_tl(t3
, t1
, t3
);
24909 tcg_gen_mul_tl(t2
, t0
, t2
);
24911 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24912 tcg_gen_mul_tl(t3
, t0
, t3
);
24913 tcg_gen_mul_tl(t2
, t0
, t2
);
24915 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24916 tcg_gen_mul_tl(t3
, t1
, t3
);
24917 tcg_gen_mul_tl(t2
, t1
, t2
);
24919 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24920 tcg_gen_mul_tl(t3
, t0
, t3
);
24921 tcg_gen_mul_tl(t2
, t1
, t2
);
24924 gen_store_mxu_gpr(t3
, XRa
);
24925 gen_store_mxu_gpr(t2
, XRd
);
24934 * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24937 static void gen_mxu_d16mac(DisasContext
*ctx
)
24939 TCGv t0
, t1
, t2
, t3
;
24940 uint32_t XRa
, XRb
, XRc
, XRd
, optn2
, aptn2
;
24942 t0
= tcg_temp_new();
24943 t1
= tcg_temp_new();
24944 t2
= tcg_temp_new();
24945 t3
= tcg_temp_new();
24947 XRa
= extract32(ctx
->opcode
, 6, 4);
24948 XRb
= extract32(ctx
->opcode
, 10, 4);
24949 XRc
= extract32(ctx
->opcode
, 14, 4);
24950 XRd
= extract32(ctx
->opcode
, 18, 4);
24951 optn2
= extract32(ctx
->opcode
, 22, 2);
24952 aptn2
= extract32(ctx
->opcode
, 24, 2);
24954 gen_load_mxu_gpr(t1
, XRb
);
24955 tcg_gen_sextract_tl(t0
, t1
, 0, 16);
24956 tcg_gen_sextract_tl(t1
, t1
, 16, 16);
24958 gen_load_mxu_gpr(t3
, XRc
);
24959 tcg_gen_sextract_tl(t2
, t3
, 0, 16);
24960 tcg_gen_sextract_tl(t3
, t3
, 16, 16);
24963 case MXU_OPTN2_WW
: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24964 tcg_gen_mul_tl(t3
, t1
, t3
);
24965 tcg_gen_mul_tl(t2
, t0
, t2
);
24967 case MXU_OPTN2_LW
: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24968 tcg_gen_mul_tl(t3
, t0
, t3
);
24969 tcg_gen_mul_tl(t2
, t0
, t2
);
24971 case MXU_OPTN2_HW
: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24972 tcg_gen_mul_tl(t3
, t1
, t3
);
24973 tcg_gen_mul_tl(t2
, t1
, t2
);
24975 case MXU_OPTN2_XW
: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24976 tcg_gen_mul_tl(t3
, t0
, t3
);
24977 tcg_gen_mul_tl(t2
, t1
, t2
);
24980 gen_load_mxu_gpr(t0
, XRa
);
24981 gen_load_mxu_gpr(t1
, XRd
);
24985 tcg_gen_add_tl(t3
, t0
, t3
);
24986 tcg_gen_add_tl(t2
, t1
, t2
);
24989 tcg_gen_add_tl(t3
, t0
, t3
);
24990 tcg_gen_sub_tl(t2
, t1
, t2
);
24993 tcg_gen_sub_tl(t3
, t0
, t3
);
24994 tcg_gen_add_tl(t2
, t1
, t2
);
24997 tcg_gen_sub_tl(t3
, t0
, t3
);
24998 tcg_gen_sub_tl(t2
, t1
, t2
);
25001 gen_store_mxu_gpr(t3
, XRa
);
25002 gen_store_mxu_gpr(t2
, XRd
);
25011 * Q8MUL XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
25012 * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
25014 static void gen_mxu_q8mul_q8mulsu(DisasContext
*ctx
)
25016 TCGv t0
, t1
, t2
, t3
, t4
, t5
, t6
, t7
;
25017 uint32_t XRa
, XRb
, XRc
, XRd
, sel
;
25019 t0
= tcg_temp_new();
25020 t1
= tcg_temp_new();
25021 t2
= tcg_temp_new();
25022 t3
= tcg_temp_new();
25023 t4
= tcg_temp_new();
25024 t5
= tcg_temp_new();
25025 t6
= tcg_temp_new();
25026 t7
= tcg_temp_new();
25028 XRa
= extract32(ctx
->opcode
, 6, 4);
25029 XRb
= extract32(ctx
->opcode
, 10, 4);
25030 XRc
= extract32(ctx
->opcode
, 14, 4);
25031 XRd
= extract32(ctx
->opcode
, 18, 4);
25032 sel
= extract32(ctx
->opcode
, 22, 2);
25034 gen_load_mxu_gpr(t3
, XRb
);
25035 gen_load_mxu_gpr(t7
, XRc
);
25039 tcg_gen_ext8s_tl(t0
, t3
);
25040 tcg_gen_shri_tl(t3
, t3
, 8);
25041 tcg_gen_ext8s_tl(t1
, t3
);
25042 tcg_gen_shri_tl(t3
, t3
, 8);
25043 tcg_gen_ext8s_tl(t2
, t3
);
25044 tcg_gen_shri_tl(t3
, t3
, 8);
25045 tcg_gen_ext8s_tl(t3
, t3
);
25048 tcg_gen_ext8u_tl(t0
, t3
);
25049 tcg_gen_shri_tl(t3
, t3
, 8);
25050 tcg_gen_ext8u_tl(t1
, t3
);
25051 tcg_gen_shri_tl(t3
, t3
, 8);
25052 tcg_gen_ext8u_tl(t2
, t3
);
25053 tcg_gen_shri_tl(t3
, t3
, 8);
25054 tcg_gen_ext8u_tl(t3
, t3
);
25057 tcg_gen_ext8u_tl(t4
, t7
);
25058 tcg_gen_shri_tl(t7
, t7
, 8);
25059 tcg_gen_ext8u_tl(t5
, t7
);
25060 tcg_gen_shri_tl(t7
, t7
, 8);
25061 tcg_gen_ext8u_tl(t6
, t7
);
25062 tcg_gen_shri_tl(t7
, t7
, 8);
25063 tcg_gen_ext8u_tl(t7
, t7
);
25065 tcg_gen_mul_tl(t0
, t0
, t4
);
25066 tcg_gen_mul_tl(t1
, t1
, t5
);
25067 tcg_gen_mul_tl(t2
, t2
, t6
);
25068 tcg_gen_mul_tl(t3
, t3
, t7
);
25070 tcg_gen_andi_tl(t0
, t0
, 0xFFFF);
25071 tcg_gen_andi_tl(t1
, t1
, 0xFFFF);
25072 tcg_gen_andi_tl(t2
, t2
, 0xFFFF);
25073 tcg_gen_andi_tl(t3
, t3
, 0xFFFF);
25075 tcg_gen_shli_tl(t1
, t1
, 16);
25076 tcg_gen_shli_tl(t3
, t3
, 16);
25078 tcg_gen_or_tl(t0
, t0
, t1
);
25079 tcg_gen_or_tl(t1
, t2
, t3
);
25081 gen_store_mxu_gpr(t0
, XRd
);
25082 gen_store_mxu_gpr(t1
, XRa
);
25095 * S32LDD XRa, Rb, S12 - Load a word from memory to XRF
25096 * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
25098 static void gen_mxu_s32ldd_s32lddr(DisasContext
*ctx
)
25101 uint32_t XRa
, Rb
, s12
, sel
;
25103 t0
= tcg_temp_new();
25104 t1
= tcg_temp_new();
25106 XRa
= extract32(ctx
->opcode
, 6, 4);
25107 s12
= extract32(ctx
->opcode
, 10, 10);
25108 sel
= extract32(ctx
->opcode
, 20, 1);
25109 Rb
= extract32(ctx
->opcode
, 21, 5);
25111 gen_load_gpr(t0
, Rb
);
25113 tcg_gen_movi_tl(t1
, s12
);
25114 tcg_gen_shli_tl(t1
, t1
, 2);
25116 tcg_gen_ori_tl(t1
, t1
, 0xFFFFF000);
25118 tcg_gen_add_tl(t1
, t0
, t1
);
25119 tcg_gen_qemu_ld_tl(t1
, t1
, ctx
->mem_idx
, MO_SL
);
25123 tcg_gen_bswap32_tl(t1
, t1
);
25125 gen_store_mxu_gpr(t1
, XRa
);
25133 * MXU instruction category: logic
25134 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25136 * S32NOR S32AND S32OR S32XOR
25140 * S32NOR XRa, XRb, XRc
25141 * Update XRa with the result of logical bitwise 'nor' operation
25142 * applied to the content of XRb and XRc.
25144 * 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
25145 * +-----------+---------+-----+-------+-------+-------+-----------+
25146 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25147 * +-----------+---------+-----+-------+-------+-------+-----------+
25149 static void gen_mxu_S32NOR(DisasContext
*ctx
)
25151 uint32_t pad
, XRc
, XRb
, XRa
;
25153 pad
= extract32(ctx
->opcode
, 21, 5);
25154 XRc
= extract32(ctx
->opcode
, 14, 4);
25155 XRb
= extract32(ctx
->opcode
, 10, 4);
25156 XRa
= extract32(ctx
->opcode
, 6, 4);
25158 if (unlikely(pad
!= 0)) {
25159 /* opcode padding incorrect -> do nothing */
25160 } else if (unlikely(XRa
== 0)) {
25161 /* destination is zero register -> do nothing */
25162 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25163 /* both operands zero registers -> just set destination to all 1s */
25164 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0xFFFFFFFF);
25165 } else if (unlikely(XRb
== 0)) {
25166 /* XRb zero register -> just set destination to the negation of XRc */
25167 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25168 } else if (unlikely(XRc
== 0)) {
25169 /* XRa zero register -> just set destination to the negation of XRb */
25170 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25171 } else if (unlikely(XRb
== XRc
)) {
25172 /* both operands same -> just set destination to the negation of XRb */
25173 tcg_gen_not_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25175 /* the most general case */
25176 tcg_gen_nor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25181 * S32AND XRa, XRb, XRc
25182 * Update XRa with the result of logical bitwise 'and' operation
25183 * applied to the content of XRb and XRc.
25185 * 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
25186 * +-----------+---------+-----+-------+-------+-------+-----------+
25187 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25188 * +-----------+---------+-----+-------+-------+-------+-----------+
25190 static void gen_mxu_S32AND(DisasContext
*ctx
)
25192 uint32_t pad
, XRc
, XRb
, XRa
;
25194 pad
= extract32(ctx
->opcode
, 21, 5);
25195 XRc
= extract32(ctx
->opcode
, 14, 4);
25196 XRb
= extract32(ctx
->opcode
, 10, 4);
25197 XRa
= extract32(ctx
->opcode
, 6, 4);
25199 if (unlikely(pad
!= 0)) {
25200 /* opcode padding incorrect -> do nothing */
25201 } else if (unlikely(XRa
== 0)) {
25202 /* destination is zero register -> do nothing */
25203 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25204 /* one of operands zero register -> just set destination to all 0s */
25205 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25206 } else if (unlikely(XRb
== XRc
)) {
25207 /* both operands same -> just set destination to one of them */
25208 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25210 /* the most general case */
25211 tcg_gen_and_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25216 * S32OR XRa, XRb, XRc
25217 * Update XRa with the result of logical bitwise 'or' operation
25218 * applied to the content of XRb and XRc.
25220 * 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
25221 * +-----------+---------+-----+-------+-------+-------+-----------+
25222 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25223 * +-----------+---------+-----+-------+-------+-------+-----------+
25225 static void gen_mxu_S32OR(DisasContext
*ctx
)
25227 uint32_t pad
, XRc
, XRb
, XRa
;
25229 pad
= extract32(ctx
->opcode
, 21, 5);
25230 XRc
= extract32(ctx
->opcode
, 14, 4);
25231 XRb
= extract32(ctx
->opcode
, 10, 4);
25232 XRa
= extract32(ctx
->opcode
, 6, 4);
25234 if (unlikely(pad
!= 0)) {
25235 /* opcode padding incorrect -> do nothing */
25236 } else if (unlikely(XRa
== 0)) {
25237 /* destination is zero register -> do nothing */
25238 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25239 /* both operands zero registers -> just set destination to all 0s */
25240 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25241 } else if (unlikely(XRb
== 0)) {
25242 /* XRb zero register -> just set destination to the content of XRc */
25243 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25244 } else if (unlikely(XRc
== 0)) {
25245 /* XRc zero register -> just set destination to the content of XRb */
25246 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25247 } else if (unlikely(XRb
== XRc
)) {
25248 /* both operands same -> just set destination to one of them */
25249 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25251 /* the most general case */
25252 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25257 * S32XOR XRa, XRb, XRc
25258 * Update XRa with the result of logical bitwise 'xor' operation
25259 * applied to the content of XRb and XRc.
25261 * 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
25262 * +-----------+---------+-----+-------+-------+-------+-----------+
25263 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL16|
25264 * +-----------+---------+-----+-------+-------+-------+-----------+
25266 static void gen_mxu_S32XOR(DisasContext
*ctx
)
25268 uint32_t pad
, XRc
, XRb
, XRa
;
25270 pad
= extract32(ctx
->opcode
, 21, 5);
25271 XRc
= extract32(ctx
->opcode
, 14, 4);
25272 XRb
= extract32(ctx
->opcode
, 10, 4);
25273 XRa
= extract32(ctx
->opcode
, 6, 4);
25275 if (unlikely(pad
!= 0)) {
25276 /* opcode padding incorrect -> do nothing */
25277 } else if (unlikely(XRa
== 0)) {
25278 /* destination is zero register -> do nothing */
25279 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25280 /* both operands zero registers -> just set destination to all 0s */
25281 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25282 } else if (unlikely(XRb
== 0)) {
25283 /* XRb zero register -> just set destination to the content of XRc */
25284 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25285 } else if (unlikely(XRc
== 0)) {
25286 /* XRc zero register -> just set destination to the content of XRb */
25287 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25288 } else if (unlikely(XRb
== XRc
)) {
25289 /* both operands same -> just set destination to all 0s */
25290 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25292 /* the most general case */
25293 tcg_gen_xor_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], mxu_gpr
[XRc
- 1]);
25299 * MXU instruction category max/min
25300 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25302 * S32MAX D16MAX Q8MAX
25303 * S32MIN D16MIN Q8MIN
25307 * S32MAX XRa, XRb, XRc
25308 * Update XRa with the maximum of signed 32-bit integers contained
25311 * S32MIN XRa, XRb, XRc
25312 * Update XRa with the minimum of signed 32-bit integers contained
25315 * 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
25316 * +-----------+---------+-----+-------+-------+-------+-----------+
25317 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25318 * +-----------+---------+-----+-------+-------+-------+-----------+
25320 static void gen_mxu_S32MAX_S32MIN(DisasContext
*ctx
)
25322 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25324 pad
= extract32(ctx
->opcode
, 21, 5);
25325 opc
= extract32(ctx
->opcode
, 18, 3);
25326 XRc
= extract32(ctx
->opcode
, 14, 4);
25327 XRb
= extract32(ctx
->opcode
, 10, 4);
25328 XRa
= extract32(ctx
->opcode
, 6, 4);
25330 if (unlikely(pad
!= 0)) {
25331 /* opcode padding incorrect -> do nothing */
25332 } else if (unlikely(XRa
== 0)) {
25333 /* destination is zero register -> do nothing */
25334 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25335 /* both operands zero registers -> just set destination to zero */
25336 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25337 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25338 /* exactly one operand is zero register - find which one is not...*/
25339 uint32_t XRx
= XRb
? XRb
: XRc
;
25340 /* ...and do max/min operation with one operand 0 */
25341 if (opc
== OPC_MXU_S32MAX
) {
25342 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25344 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRx
- 1], 0);
25346 } else if (unlikely(XRb
== XRc
)) {
25347 /* both operands same -> just set destination to one of them */
25348 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25350 /* the most general case */
25351 if (opc
== OPC_MXU_S32MAX
) {
25352 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25355 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1],
25363 * Update XRa with the 16-bit-wise maximums of signed integers
25364 * contained in XRb and XRc.
25367 * Update XRa with the 16-bit-wise minimums of signed integers
25368 * contained in XRb and XRc.
25370 * 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
25371 * +-----------+---------+-----+-------+-------+-------+-----------+
25372 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25373 * +-----------+---------+-----+-------+-------+-------+-----------+
25375 static void gen_mxu_D16MAX_D16MIN(DisasContext
*ctx
)
25377 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25379 pad
= extract32(ctx
->opcode
, 21, 5);
25380 opc
= extract32(ctx
->opcode
, 18, 3);
25381 XRc
= extract32(ctx
->opcode
, 14, 4);
25382 XRb
= extract32(ctx
->opcode
, 10, 4);
25383 XRa
= extract32(ctx
->opcode
, 6, 4);
25385 if (unlikely(pad
!= 0)) {
25386 /* opcode padding incorrect -> do nothing */
25387 } else if (unlikely(XRc
== 0)) {
25388 /* destination is zero register -> do nothing */
25389 } else if (unlikely((XRb
== 0) && (XRa
== 0))) {
25390 /* both operands zero registers -> just set destination to zero */
25391 tcg_gen_movi_i32(mxu_gpr
[XRc
- 1], 0);
25392 } else if (unlikely((XRb
== 0) || (XRa
== 0))) {
25393 /* exactly one operand is zero register - find which one is not...*/
25394 uint32_t XRx
= XRb
? XRb
: XRc
;
25395 /* ...and do half-word-wise max/min with one operand 0 */
25396 TCGv_i32 t0
= tcg_temp_new();
25397 TCGv_i32 t1
= tcg_const_i32(0);
25399 /* the left half-word first */
25400 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFFFF0000);
25401 if (opc
== OPC_MXU_D16MAX
) {
25402 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25404 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25407 /* the right half-word */
25408 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0x0000FFFF);
25409 /* move half-words to the leftmost position */
25410 tcg_gen_shli_i32(t0
, t0
, 16);
25411 /* t0 will be max/min of t0 and t1 */
25412 if (opc
== OPC_MXU_D16MAX
) {
25413 tcg_gen_smax_i32(t0
, t0
, t1
);
25415 tcg_gen_smin_i32(t0
, t0
, t1
);
25417 /* return resulting half-words to its original position */
25418 tcg_gen_shri_i32(t0
, t0
, 16);
25419 /* finaly update the destination */
25420 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25424 } else if (unlikely(XRb
== XRc
)) {
25425 /* both operands same -> just set destination to one of them */
25426 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25428 /* the most general case */
25429 TCGv_i32 t0
= tcg_temp_new();
25430 TCGv_i32 t1
= tcg_temp_new();
25432 /* the left half-word first */
25433 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFFFF0000);
25434 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25435 if (opc
== OPC_MXU_D16MAX
) {
25436 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25438 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25441 /* the right half-word */
25442 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25443 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0x0000FFFF);
25444 /* move half-words to the leftmost position */
25445 tcg_gen_shli_i32(t0
, t0
, 16);
25446 tcg_gen_shli_i32(t1
, t1
, 16);
25447 /* t0 will be max/min of t0 and t1 */
25448 if (opc
== OPC_MXU_D16MAX
) {
25449 tcg_gen_smax_i32(t0
, t0
, t1
);
25451 tcg_gen_smin_i32(t0
, t0
, t1
);
25453 /* return resulting half-words to its original position */
25454 tcg_gen_shri_i32(t0
, t0
, 16);
25455 /* finaly update the destination */
25456 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25465 * Update XRa with the 8-bit-wise maximums of signed integers
25466 * contained in XRb and XRc.
25469 * Update XRa with the 8-bit-wise minimums of signed integers
25470 * contained in XRb and XRc.
25472 * 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
25473 * +-----------+---------+-----+-------+-------+-------+-----------+
25474 * | SPECIAL2 |0 0 0 0 0| opc | XRc | XRb | XRa |MXU__POOL00|
25475 * +-----------+---------+-----+-------+-------+-------+-----------+
25477 static void gen_mxu_Q8MAX_Q8MIN(DisasContext
*ctx
)
25479 uint32_t pad
, opc
, XRc
, XRb
, XRa
;
25481 pad
= extract32(ctx
->opcode
, 21, 5);
25482 opc
= extract32(ctx
->opcode
, 18, 3);
25483 XRc
= extract32(ctx
->opcode
, 14, 4);
25484 XRb
= extract32(ctx
->opcode
, 10, 4);
25485 XRa
= extract32(ctx
->opcode
, 6, 4);
25487 if (unlikely(pad
!= 0)) {
25488 /* opcode padding incorrect -> do nothing */
25489 } else if (unlikely(XRa
== 0)) {
25490 /* destination is zero register -> do nothing */
25491 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25492 /* both operands zero registers -> just set destination to zero */
25493 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25494 } else if (unlikely((XRb
== 0) || (XRc
== 0))) {
25495 /* exactly one operand is zero register - make it be the first...*/
25496 uint32_t XRx
= XRb
? XRb
: XRc
;
25497 /* ...and do byte-wise max/min with one operand 0 */
25498 TCGv_i32 t0
= tcg_temp_new();
25499 TCGv_i32 t1
= tcg_const_i32(0);
25502 /* the leftmost byte (byte 3) first */
25503 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF000000);
25504 if (opc
== OPC_MXU_Q8MAX
) {
25505 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25507 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25510 /* bytes 2, 1, 0 */
25511 for (i
= 2; i
>= 0; i
--) {
25512 /* extract the byte */
25513 tcg_gen_andi_i32(t0
, mxu_gpr
[XRx
- 1], 0xFF << (8 * i
));
25514 /* move the byte to the leftmost position */
25515 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25516 /* t0 will be max/min of t0 and t1 */
25517 if (opc
== OPC_MXU_Q8MAX
) {
25518 tcg_gen_smax_i32(t0
, t0
, t1
);
25520 tcg_gen_smin_i32(t0
, t0
, t1
);
25522 /* return resulting byte to its original position */
25523 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25524 /* finaly update the destination */
25525 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25530 } else if (unlikely(XRb
== XRc
)) {
25531 /* both operands same -> just set destination to one of them */
25532 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25534 /* the most general case */
25535 TCGv_i32 t0
= tcg_temp_new();
25536 TCGv_i32 t1
= tcg_temp_new();
25539 /* the leftmost bytes (bytes 3) first */
25540 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF000000);
25541 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25542 if (opc
== OPC_MXU_Q8MAX
) {
25543 tcg_gen_smax_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25545 tcg_gen_smin_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25548 /* bytes 2, 1, 0 */
25549 for (i
= 2; i
>= 0; i
--) {
25550 /* extract corresponding bytes */
25551 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0xFF << (8 * i
));
25552 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF << (8 * i
));
25553 /* move the bytes to the leftmost position */
25554 tcg_gen_shli_i32(t0
, t0
, 8 * (3 - i
));
25555 tcg_gen_shli_i32(t1
, t1
, 8 * (3 - i
));
25556 /* t0 will be max/min of t0 and t1 */
25557 if (opc
== OPC_MXU_Q8MAX
) {
25558 tcg_gen_smax_i32(t0
, t0
, t1
);
25560 tcg_gen_smin_i32(t0
, t0
, t1
);
25562 /* return resulting byte to its original position */
25563 tcg_gen_shri_i32(t0
, t0
, 8 * (3 - i
));
25564 /* finaly update the destination */
25565 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRa
- 1], t0
);
25575 * MXU instruction category: align
25576 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25582 * S32ALNI XRc, XRb, XRa, optn3
25583 * Arrange bytes from XRb and XRc according to one of five sets of
25584 * rules determined by optn3, and place the result in XRa.
25586 * 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
25587 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25588 * | SPECIAL2 |optn3|0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
25589 * +-----------+-----+---+-----+-------+-------+-------+-----------+
25592 static void gen_mxu_S32ALNI(DisasContext
*ctx
)
25594 uint32_t optn3
, pad
, XRc
, XRb
, XRa
;
25596 optn3
= extract32(ctx
->opcode
, 23, 3);
25597 pad
= extract32(ctx
->opcode
, 21, 2);
25598 XRc
= extract32(ctx
->opcode
, 14, 4);
25599 XRb
= extract32(ctx
->opcode
, 10, 4);
25600 XRa
= extract32(ctx
->opcode
, 6, 4);
25602 if (unlikely(pad
!= 0)) {
25603 /* opcode padding incorrect -> do nothing */
25604 } else if (unlikely(XRa
== 0)) {
25605 /* destination is zero register -> do nothing */
25606 } else if (unlikely((XRb
== 0) && (XRc
== 0))) {
25607 /* both operands zero registers -> just set destination to all 0s */
25608 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25609 } else if (unlikely(XRb
== 0)) {
25610 /* XRb zero register -> just appropriatelly shift XRc into XRa */
25612 case MXU_OPTN3_PTN0
:
25613 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25615 case MXU_OPTN3_PTN1
:
25616 case MXU_OPTN3_PTN2
:
25617 case MXU_OPTN3_PTN3
:
25618 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1],
25621 case MXU_OPTN3_PTN4
:
25622 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25625 } else if (unlikely(XRc
== 0)) {
25626 /* XRc zero register -> just appropriatelly shift XRb into XRa */
25628 case MXU_OPTN3_PTN0
:
25629 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25631 case MXU_OPTN3_PTN1
:
25632 case MXU_OPTN3_PTN2
:
25633 case MXU_OPTN3_PTN3
:
25634 tcg_gen_shri_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25636 case MXU_OPTN3_PTN4
:
25637 tcg_gen_movi_i32(mxu_gpr
[XRa
- 1], 0);
25640 } else if (unlikely(XRb
== XRc
)) {
25641 /* both operands same -> just rotation or moving from any of them */
25643 case MXU_OPTN3_PTN0
:
25644 case MXU_OPTN3_PTN4
:
25645 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25647 case MXU_OPTN3_PTN1
:
25648 case MXU_OPTN3_PTN2
:
25649 case MXU_OPTN3_PTN3
:
25650 tcg_gen_rotli_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1], 8 * optn3
);
25654 /* the most general case */
25656 case MXU_OPTN3_PTN0
:
25660 /* +---------------+ */
25661 /* | A B C D | E F G H */
25662 /* +-------+-------+ */
25667 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRb
- 1]);
25670 case MXU_OPTN3_PTN1
:
25674 /* +-------------------+ */
25675 /* A | B C D E | F G H */
25676 /* +---------+---------+ */
25681 TCGv_i32 t0
= tcg_temp_new();
25682 TCGv_i32 t1
= tcg_temp_new();
25684 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x00FFFFFF);
25685 tcg_gen_shli_i32(t0
, t0
, 8);
25687 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFF000000);
25688 tcg_gen_shri_i32(t1
, t1
, 24);
25690 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25696 case MXU_OPTN3_PTN2
:
25700 /* +-------------------+ */
25701 /* A B | C D E F | G H */
25702 /* +---------+---------+ */
25707 TCGv_i32 t0
= tcg_temp_new();
25708 TCGv_i32 t1
= tcg_temp_new();
25710 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x0000FFFF);
25711 tcg_gen_shli_i32(t0
, t0
, 16);
25713 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFF0000);
25714 tcg_gen_shri_i32(t1
, t1
, 16);
25716 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25722 case MXU_OPTN3_PTN3
:
25726 /* +-------------------+ */
25727 /* A B C | D E F G | H */
25728 /* +---------+---------+ */
25733 TCGv_i32 t0
= tcg_temp_new();
25734 TCGv_i32 t1
= tcg_temp_new();
25736 tcg_gen_andi_i32(t0
, mxu_gpr
[XRb
- 1], 0x000000FF);
25737 tcg_gen_shli_i32(t0
, t0
, 24);
25739 tcg_gen_andi_i32(t1
, mxu_gpr
[XRc
- 1], 0xFFFFFF00);
25740 tcg_gen_shri_i32(t1
, t1
, 8);
25742 tcg_gen_or_i32(mxu_gpr
[XRa
- 1], t0
, t1
);
25748 case MXU_OPTN3_PTN4
:
25752 /* +---------------+ */
25753 /* A B C D | E F G H | */
25754 /* +-------+-------+ */
25759 tcg_gen_mov_i32(mxu_gpr
[XRa
- 1], mxu_gpr
[XRc
- 1]);
25768 * Decoding engine for MXU
25769 * =======================
25774 * Decode MXU pool00
25776 * 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
25777 * +-----------+---------+-----+-------+-------+-------+-----------+
25778 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL00|
25779 * +-----------+---------+-----+-------+-------+-------+-----------+
25782 static void decode_opc_mxu__pool00(CPUMIPSState
*env
, DisasContext
*ctx
)
25784 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25787 case OPC_MXU_S32MAX
:
25788 case OPC_MXU_S32MIN
:
25789 gen_mxu_S32MAX_S32MIN(ctx
);
25791 case OPC_MXU_D16MAX
:
25792 case OPC_MXU_D16MIN
:
25793 gen_mxu_D16MAX_D16MIN(ctx
);
25795 case OPC_MXU_Q8MAX
:
25796 case OPC_MXU_Q8MIN
:
25797 gen_mxu_Q8MAX_Q8MIN(ctx
);
25799 case OPC_MXU_Q8SLT
:
25800 /* TODO: Implement emulation of Q8SLT instruction. */
25801 MIPS_INVAL("OPC_MXU_Q8SLT");
25802 generate_exception_end(ctx
, EXCP_RI
);
25804 case OPC_MXU_Q8SLTU
:
25805 /* TODO: Implement emulation of Q8SLTU instruction. */
25806 MIPS_INVAL("OPC_MXU_Q8SLTU");
25807 generate_exception_end(ctx
, EXCP_RI
);
25810 MIPS_INVAL("decode_opc_mxu");
25811 generate_exception_end(ctx
, EXCP_RI
);
25818 * Decode MXU pool01
25820 * S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25821 * 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
25822 * +-----------+---------+-----+-------+-------+-------+-----------+
25823 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25824 * +-----------+---------+-----+-------+-------+-------+-----------+
25827 * 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
25828 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25829 * | SPECIAL2 |en2|0 0 0|x x x| XRc | XRb | XRa |MXU__POOL01|
25830 * +-----------+---+-----+-----+-------+-------+-------+-----------+
25833 static void decode_opc_mxu__pool01(CPUMIPSState
*env
, DisasContext
*ctx
)
25835 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25838 case OPC_MXU_S32SLT
:
25839 /* TODO: Implement emulation of S32SLT instruction. */
25840 MIPS_INVAL("OPC_MXU_S32SLT");
25841 generate_exception_end(ctx
, EXCP_RI
);
25843 case OPC_MXU_D16SLT
:
25844 /* TODO: Implement emulation of D16SLT instruction. */
25845 MIPS_INVAL("OPC_MXU_D16SLT");
25846 generate_exception_end(ctx
, EXCP_RI
);
25848 case OPC_MXU_D16AVG
:
25849 /* TODO: Implement emulation of D16AVG instruction. */
25850 MIPS_INVAL("OPC_MXU_D16AVG");
25851 generate_exception_end(ctx
, EXCP_RI
);
25853 case OPC_MXU_D16AVGR
:
25854 /* TODO: Implement emulation of D16AVGR instruction. */
25855 MIPS_INVAL("OPC_MXU_D16AVGR");
25856 generate_exception_end(ctx
, EXCP_RI
);
25858 case OPC_MXU_Q8AVG
:
25859 /* TODO: Implement emulation of Q8AVG instruction. */
25860 MIPS_INVAL("OPC_MXU_Q8AVG");
25861 generate_exception_end(ctx
, EXCP_RI
);
25863 case OPC_MXU_Q8AVGR
:
25864 /* TODO: Implement emulation of Q8AVGR instruction. */
25865 MIPS_INVAL("OPC_MXU_Q8AVGR");
25866 generate_exception_end(ctx
, EXCP_RI
);
25868 case OPC_MXU_Q8ADD
:
25869 /* TODO: Implement emulation of Q8ADD instruction. */
25870 MIPS_INVAL("OPC_MXU_Q8ADD");
25871 generate_exception_end(ctx
, EXCP_RI
);
25874 MIPS_INVAL("decode_opc_mxu");
25875 generate_exception_end(ctx
, EXCP_RI
);
25882 * Decode MXU pool02
25884 * 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
25885 * +-----------+---------+-----+-------+-------+-------+-----------+
25886 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL02|
25887 * +-----------+---------+-----+-------+-------+-------+-----------+
25890 static void decode_opc_mxu__pool02(CPUMIPSState
*env
, DisasContext
*ctx
)
25892 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
25895 case OPC_MXU_S32CPS
:
25896 /* TODO: Implement emulation of S32CPS instruction. */
25897 MIPS_INVAL("OPC_MXU_S32CPS");
25898 generate_exception_end(ctx
, EXCP_RI
);
25900 case OPC_MXU_D16CPS
:
25901 /* TODO: Implement emulation of D16CPS instruction. */
25902 MIPS_INVAL("OPC_MXU_D16CPS");
25903 generate_exception_end(ctx
, EXCP_RI
);
25905 case OPC_MXU_Q8ABD
:
25906 /* TODO: Implement emulation of Q8ABD instruction. */
25907 MIPS_INVAL("OPC_MXU_Q8ABD");
25908 generate_exception_end(ctx
, EXCP_RI
);
25910 case OPC_MXU_Q16SAT
:
25911 /* TODO: Implement emulation of Q16SAT instruction. */
25912 MIPS_INVAL("OPC_MXU_Q16SAT");
25913 generate_exception_end(ctx
, EXCP_RI
);
25916 MIPS_INVAL("decode_opc_mxu");
25917 generate_exception_end(ctx
, EXCP_RI
);
25924 * Decode MXU pool03
25927 * 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
25928 * +-----------+---+---+-------+-------+-------+-------+-----------+
25929 * | SPECIAL2 |x x|on2|0 0 0 0| XRc | XRb | XRa |MXU__POOL03|
25930 * +-----------+---+---+-------+-------+-------+-------+-----------+
25933 * 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
25934 * +-----------+---+---+-------+-------+-------+-------+-----------+
25935 * | SPECIAL2 |x x|on2| Xd | XRc | XRb | XRa |MXU__POOL03|
25936 * +-----------+---+---+-------+-------+-------+-------+-----------+
25939 static void decode_opc_mxu__pool03(CPUMIPSState
*env
, DisasContext
*ctx
)
25941 uint32_t opcode
= extract32(ctx
->opcode
, 24, 2);
25944 case OPC_MXU_D16MULF
:
25945 /* TODO: Implement emulation of D16MULF instruction. */
25946 MIPS_INVAL("OPC_MXU_D16MULF");
25947 generate_exception_end(ctx
, EXCP_RI
);
25949 case OPC_MXU_D16MULE
:
25950 /* TODO: Implement emulation of D16MULE instruction. */
25951 MIPS_INVAL("OPC_MXU_D16MULE");
25952 generate_exception_end(ctx
, EXCP_RI
);
25955 MIPS_INVAL("decode_opc_mxu");
25956 generate_exception_end(ctx
, EXCP_RI
);
25963 * Decode MXU pool04
25965 * 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
25966 * +-----------+---------+-+-------------------+-------+-----------+
25967 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL04|
25968 * +-----------+---------+-+-------------------+-------+-----------+
25971 static void decode_opc_mxu__pool04(CPUMIPSState
*env
, DisasContext
*ctx
)
25973 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
25976 case OPC_MXU_S32LDD
:
25977 case OPC_MXU_S32LDDR
:
25978 gen_mxu_s32ldd_s32lddr(ctx
);
25981 MIPS_INVAL("decode_opc_mxu");
25982 generate_exception_end(ctx
, EXCP_RI
);
25989 * Decode MXU pool05
25991 * 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
25992 * +-----------+---------+-+-------------------+-------+-----------+
25993 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL05|
25994 * +-----------+---------+-+-------------------+-------+-----------+
25997 static void decode_opc_mxu__pool05(CPUMIPSState
*env
, DisasContext
*ctx
)
25999 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26002 case OPC_MXU_S32STD
:
26003 /* TODO: Implement emulation of S32STD instruction. */
26004 MIPS_INVAL("OPC_MXU_S32STD");
26005 generate_exception_end(ctx
, EXCP_RI
);
26007 case OPC_MXU_S32STDR
:
26008 /* TODO: Implement emulation of S32STDR instruction. */
26009 MIPS_INVAL("OPC_MXU_S32STDR");
26010 generate_exception_end(ctx
, EXCP_RI
);
26013 MIPS_INVAL("decode_opc_mxu");
26014 generate_exception_end(ctx
, EXCP_RI
);
26021 * Decode MXU pool06
26023 * 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
26024 * +-----------+---------+---------+---+-------+-------+-----------+
26025 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL06|
26026 * +-----------+---------+---------+---+-------+-------+-----------+
26029 static void decode_opc_mxu__pool06(CPUMIPSState
*env
, DisasContext
*ctx
)
26031 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26034 case OPC_MXU_S32LDDV
:
26035 /* TODO: Implement emulation of S32LDDV instruction. */
26036 MIPS_INVAL("OPC_MXU_S32LDDV");
26037 generate_exception_end(ctx
, EXCP_RI
);
26039 case OPC_MXU_S32LDDVR
:
26040 /* TODO: Implement emulation of S32LDDVR instruction. */
26041 MIPS_INVAL("OPC_MXU_S32LDDVR");
26042 generate_exception_end(ctx
, EXCP_RI
);
26045 MIPS_INVAL("decode_opc_mxu");
26046 generate_exception_end(ctx
, EXCP_RI
);
26053 * Decode MXU pool07
26055 * 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
26056 * +-----------+---------+---------+---+-------+-------+-----------+
26057 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL07|
26058 * +-----------+---------+---------+---+-------+-------+-----------+
26061 static void decode_opc_mxu__pool07(CPUMIPSState
*env
, DisasContext
*ctx
)
26063 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26066 case OPC_MXU_S32STDV
:
26067 /* TODO: Implement emulation of S32TDV instruction. */
26068 MIPS_INVAL("OPC_MXU_S32TDV");
26069 generate_exception_end(ctx
, EXCP_RI
);
26071 case OPC_MXU_S32STDVR
:
26072 /* TODO: Implement emulation of S32TDVR instruction. */
26073 MIPS_INVAL("OPC_MXU_S32TDVR");
26074 generate_exception_end(ctx
, EXCP_RI
);
26077 MIPS_INVAL("decode_opc_mxu");
26078 generate_exception_end(ctx
, EXCP_RI
);
26085 * Decode MXU pool08
26087 * 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
26088 * +-----------+---------+-+-------------------+-------+-----------+
26089 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL08|
26090 * +-----------+---------+-+-------------------+-------+-----------+
26093 static void decode_opc_mxu__pool08(CPUMIPSState
*env
, DisasContext
*ctx
)
26095 uint32_t opcode
= extract32(ctx
->opcode
, 20, 1);
26098 case OPC_MXU_S32LDI
:
26099 /* TODO: Implement emulation of S32LDI instruction. */
26100 MIPS_INVAL("OPC_MXU_S32LDI");
26101 generate_exception_end(ctx
, EXCP_RI
);
26103 case OPC_MXU_S32LDIR
:
26104 /* TODO: Implement emulation of S32LDIR instruction. */
26105 MIPS_INVAL("OPC_MXU_S32LDIR");
26106 generate_exception_end(ctx
, EXCP_RI
);
26109 MIPS_INVAL("decode_opc_mxu");
26110 generate_exception_end(ctx
, EXCP_RI
);
26117 * Decode MXU pool09
26119 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26120 * +-----------+---------+-+-------------------+-------+-----------+
26121 * | SPECIAL2 | rb |x| s12 | XRa |MXU__POOL09|
26122 * +-----------+---------+-+-------------------+-------+-----------+
26125 static void decode_opc_mxu__pool09(CPUMIPSState
*env
, DisasContext
*ctx
)
26127 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26130 case OPC_MXU_S32SDI
:
26131 /* TODO: Implement emulation of S32SDI instruction. */
26132 MIPS_INVAL("OPC_MXU_S32SDI");
26133 generate_exception_end(ctx
, EXCP_RI
);
26135 case OPC_MXU_S32SDIR
:
26136 /* TODO: Implement emulation of S32SDIR instruction. */
26137 MIPS_INVAL("OPC_MXU_S32SDIR");
26138 generate_exception_end(ctx
, EXCP_RI
);
26141 MIPS_INVAL("decode_opc_mxu");
26142 generate_exception_end(ctx
, EXCP_RI
);
26149 * Decode MXU pool10
26151 * 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
26152 * +-----------+---------+---------+---+-------+-------+-----------+
26153 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL10|
26154 * +-----------+---------+---------+---+-------+-------+-----------+
26157 static void decode_opc_mxu__pool10(CPUMIPSState
*env
, DisasContext
*ctx
)
26159 uint32_t opcode
= extract32(ctx
->opcode
, 5, 0);
26162 case OPC_MXU_S32LDIV
:
26163 /* TODO: Implement emulation of S32LDIV instruction. */
26164 MIPS_INVAL("OPC_MXU_S32LDIV");
26165 generate_exception_end(ctx
, EXCP_RI
);
26167 case OPC_MXU_S32LDIVR
:
26168 /* TODO: Implement emulation of S32LDIVR instruction. */
26169 MIPS_INVAL("OPC_MXU_S32LDIVR");
26170 generate_exception_end(ctx
, EXCP_RI
);
26173 MIPS_INVAL("decode_opc_mxu");
26174 generate_exception_end(ctx
, EXCP_RI
);
26181 * Decode MXU pool11
26183 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26184 * +-----------+---------+---------+---+-------+-------+-----------+
26185 * | SPECIAL2 | rb | rc |st2|x x x x| XRa |MXU__POOL11|
26186 * +-----------+---------+---------+---+-------+-------+-----------+
26189 static void decode_opc_mxu__pool11(CPUMIPSState
*env
, DisasContext
*ctx
)
26191 uint32_t opcode
= extract32(ctx
->opcode
, 10, 4);
26194 case OPC_MXU_S32SDIV
:
26195 /* TODO: Implement emulation of S32SDIV instruction. */
26196 MIPS_INVAL("OPC_MXU_S32SDIV");
26197 generate_exception_end(ctx
, EXCP_RI
);
26199 case OPC_MXU_S32SDIVR
:
26200 /* TODO: Implement emulation of S32SDIVR instruction. */
26201 MIPS_INVAL("OPC_MXU_S32SDIVR");
26202 generate_exception_end(ctx
, EXCP_RI
);
26205 MIPS_INVAL("decode_opc_mxu");
26206 generate_exception_end(ctx
, EXCP_RI
);
26213 * Decode MXU pool12
26215 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26216 * +-----------+---+---+-------+-------+-------+-------+-----------+
26217 * | SPECIAL2 |an2|x x| Xd | XRc | XRb | XRa |MXU__POOL12|
26218 * +-----------+---+---+-------+-------+-------+-------+-----------+
26221 static void decode_opc_mxu__pool12(CPUMIPSState
*env
, DisasContext
*ctx
)
26223 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26226 case OPC_MXU_D32ACC
:
26227 /* TODO: Implement emulation of D32ACC instruction. */
26228 MIPS_INVAL("OPC_MXU_D32ACC");
26229 generate_exception_end(ctx
, EXCP_RI
);
26231 case OPC_MXU_D32ACCM
:
26232 /* TODO: Implement emulation of D32ACCM instruction. */
26233 MIPS_INVAL("OPC_MXU_D32ACCM");
26234 generate_exception_end(ctx
, EXCP_RI
);
26236 case OPC_MXU_D32ASUM
:
26237 /* TODO: Implement emulation of D32ASUM instruction. */
26238 MIPS_INVAL("OPC_MXU_D32ASUM");
26239 generate_exception_end(ctx
, EXCP_RI
);
26242 MIPS_INVAL("decode_opc_mxu");
26243 generate_exception_end(ctx
, EXCP_RI
);
26250 * Decode MXU pool13
26252 * 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
26253 * +-----------+---+---+-------+-------+-------+-------+-----------+
26254 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL13|
26255 * +-----------+---+---+-------+-------+-------+-------+-----------+
26258 static void decode_opc_mxu__pool13(CPUMIPSState
*env
, DisasContext
*ctx
)
26260 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26263 case OPC_MXU_Q16ACC
:
26264 /* TODO: Implement emulation of Q16ACC instruction. */
26265 MIPS_INVAL("OPC_MXU_Q16ACC");
26266 generate_exception_end(ctx
, EXCP_RI
);
26268 case OPC_MXU_Q16ACCM
:
26269 /* TODO: Implement emulation of Q16ACCM instruction. */
26270 MIPS_INVAL("OPC_MXU_Q16ACCM");
26271 generate_exception_end(ctx
, EXCP_RI
);
26273 case OPC_MXU_Q16ASUM
:
26274 /* TODO: Implement emulation of Q16ASUM instruction. */
26275 MIPS_INVAL("OPC_MXU_Q16ASUM");
26276 generate_exception_end(ctx
, EXCP_RI
);
26279 MIPS_INVAL("decode_opc_mxu");
26280 generate_exception_end(ctx
, EXCP_RI
);
26287 * Decode MXU pool14
26290 * 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
26291 * +-----------+---+---+-------+-------+-------+-------+-----------+
26292 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL14|
26293 * +-----------+---+---+-------+-------+-------+-------+-----------+
26296 * 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
26297 * +-----------+---+---+-------+-------+-------+-------+-----------+
26298 * | SPECIAL2 |en2|x x|0 0 0 0| XRc | XRb | XRa |MXU__POOL14|
26299 * +-----------+---+---+-------+-------+-------+-------+-----------+
26302 static void decode_opc_mxu__pool14(CPUMIPSState
*env
, DisasContext
*ctx
)
26304 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26307 case OPC_MXU_Q8ADDE
:
26308 /* TODO: Implement emulation of Q8ADDE instruction. */
26309 MIPS_INVAL("OPC_MXU_Q8ADDE");
26310 generate_exception_end(ctx
, EXCP_RI
);
26312 case OPC_MXU_D8SUM
:
26313 /* TODO: Implement emulation of D8SUM instruction. */
26314 MIPS_INVAL("OPC_MXU_D8SUM");
26315 generate_exception_end(ctx
, EXCP_RI
);
26317 case OPC_MXU_D8SUMC
:
26318 /* TODO: Implement emulation of D8SUMC instruction. */
26319 MIPS_INVAL("OPC_MXU_D8SUMC");
26320 generate_exception_end(ctx
, EXCP_RI
);
26323 MIPS_INVAL("decode_opc_mxu");
26324 generate_exception_end(ctx
, EXCP_RI
);
26331 * Decode MXU pool15
26333 * S32MUL, S32MULU, S32EXTRV:
26334 * 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
26335 * +-----------+---------+---------+---+-------+-------+-----------+
26336 * | SPECIAL2 | rs | rt |x x| XRd | XRa |MXU__POOL15|
26337 * +-----------+---------+---------+---+-------+-------+-----------+
26340 * 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
26341 * +-----------+---------+---------+---+-------+-------+-----------+
26342 * | SPECIAL2 | rb | sft5 |x x| XRd | XRa |MXU__POOL15|
26343 * +-----------+---------+---------+---+-------+-------+-----------+
26346 static void decode_opc_mxu__pool15(CPUMIPSState
*env
, DisasContext
*ctx
)
26348 uint32_t opcode
= extract32(ctx
->opcode
, 14, 2);
26351 case OPC_MXU_S32MUL
:
26352 /* TODO: Implement emulation of S32MUL instruction. */
26353 MIPS_INVAL("OPC_MXU_S32MUL");
26354 generate_exception_end(ctx
, EXCP_RI
);
26356 case OPC_MXU_S32MULU
:
26357 /* TODO: Implement emulation of S32MULU instruction. */
26358 MIPS_INVAL("OPC_MXU_S32MULU");
26359 generate_exception_end(ctx
, EXCP_RI
);
26361 case OPC_MXU_S32EXTR
:
26362 /* TODO: Implement emulation of S32EXTR instruction. */
26363 MIPS_INVAL("OPC_MXU_S32EXTR");
26364 generate_exception_end(ctx
, EXCP_RI
);
26366 case OPC_MXU_S32EXTRV
:
26367 /* TODO: Implement emulation of S32EXTRV instruction. */
26368 MIPS_INVAL("OPC_MXU_S32EXTRV");
26369 generate_exception_end(ctx
, EXCP_RI
);
26372 MIPS_INVAL("decode_opc_mxu");
26373 generate_exception_end(ctx
, EXCP_RI
);
26380 * Decode MXU pool16
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 | rb |x x x| XRc | XRb | XRa |MXU__POOL16|
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 | rs |x x x| XRc | XRb | XRa |MXU__POOL16|
26392 * +-----------+---------+-----+-------+-------+-------+-----------+
26395 * 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
26396 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26397 * | SPECIAL2 | s3 |0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26398 * +-----------+-----+---+-----+-------+-------+-------+-----------+
26401 * 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
26402 * +-----------+-----+---+-----+-------+---------------+-----------+
26403 * | SPECIAL2 |optn3|0 0|x x x| XRc | s8 |MXU__POOL16|
26404 * +-----------+-----+---+-----+-------+---------------+-----------+
26406 * S32NOR, S32AND, S32OR, S32XOR:
26407 * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26408 * +-----------+---------+-----+-------+-------+-------+-----------+
26409 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL16|
26410 * +-----------+---------+-----+-------+-------+-------+-----------+
26413 static void decode_opc_mxu__pool16(CPUMIPSState
*env
, DisasContext
*ctx
)
26415 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26418 case OPC_MXU_D32SARW
:
26419 /* TODO: Implement emulation of D32SARW instruction. */
26420 MIPS_INVAL("OPC_MXU_D32SARW");
26421 generate_exception_end(ctx
, EXCP_RI
);
26423 case OPC_MXU_S32ALN
:
26424 /* TODO: Implement emulation of S32ALN instruction. */
26425 MIPS_INVAL("OPC_MXU_S32ALN");
26426 generate_exception_end(ctx
, EXCP_RI
);
26428 case OPC_MXU_S32ALNI
:
26429 gen_mxu_S32ALNI(ctx
);
26431 case OPC_MXU_S32LUI
:
26432 /* TODO: Implement emulation of S32LUI instruction. */
26433 MIPS_INVAL("OPC_MXU_S32LUI");
26434 generate_exception_end(ctx
, EXCP_RI
);
26436 case OPC_MXU_S32NOR
:
26437 gen_mxu_S32NOR(ctx
);
26439 case OPC_MXU_S32AND
:
26440 gen_mxu_S32AND(ctx
);
26442 case OPC_MXU_S32OR
:
26443 gen_mxu_S32OR(ctx
);
26445 case OPC_MXU_S32XOR
:
26446 gen_mxu_S32XOR(ctx
);
26449 MIPS_INVAL("decode_opc_mxu");
26450 generate_exception_end(ctx
, EXCP_RI
);
26457 * Decode MXU pool17
26459 * 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
26460 * +-----------+---------+---------+---+---------+-----+-----------+
26461 * | SPECIAL2 | rs | rt |0 0| rd |x x x|MXU__POOL15|
26462 * +-----------+---------+---------+---+---------+-----+-----------+
26465 static void decode_opc_mxu__pool17(CPUMIPSState
*env
, DisasContext
*ctx
)
26467 uint32_t opcode
= extract32(ctx
->opcode
, 6, 2);
26471 /* TODO: Implement emulation of LXW instruction. */
26472 MIPS_INVAL("OPC_MXU_LXW");
26473 generate_exception_end(ctx
, EXCP_RI
);
26476 /* TODO: Implement emulation of LXH instruction. */
26477 MIPS_INVAL("OPC_MXU_LXH");
26478 generate_exception_end(ctx
, EXCP_RI
);
26481 /* TODO: Implement emulation of LXHU instruction. */
26482 MIPS_INVAL("OPC_MXU_LXHU");
26483 generate_exception_end(ctx
, EXCP_RI
);
26486 /* TODO: Implement emulation of LXB instruction. */
26487 MIPS_INVAL("OPC_MXU_LXB");
26488 generate_exception_end(ctx
, EXCP_RI
);
26491 /* TODO: Implement emulation of LXBU instruction. */
26492 MIPS_INVAL("OPC_MXU_LXBU");
26493 generate_exception_end(ctx
, EXCP_RI
);
26496 MIPS_INVAL("decode_opc_mxu");
26497 generate_exception_end(ctx
, EXCP_RI
);
26503 * Decode MXU pool18
26505 * 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
26506 * +-----------+---------+-----+-------+-------+-------+-----------+
26507 * | SPECIAL2 | rb |x x x| XRd | XRa |0 0 0 0|MXU__POOL18|
26508 * +-----------+---------+-----+-------+-------+-------+-----------+
26511 static void decode_opc_mxu__pool18(CPUMIPSState
*env
, DisasContext
*ctx
)
26513 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26516 case OPC_MXU_D32SLLV
:
26517 /* TODO: Implement emulation of D32SLLV instruction. */
26518 MIPS_INVAL("OPC_MXU_D32SLLV");
26519 generate_exception_end(ctx
, EXCP_RI
);
26521 case OPC_MXU_D32SLRV
:
26522 /* TODO: Implement emulation of D32SLRV instruction. */
26523 MIPS_INVAL("OPC_MXU_D32SLRV");
26524 generate_exception_end(ctx
, EXCP_RI
);
26526 case OPC_MXU_D32SARV
:
26527 /* TODO: Implement emulation of D32SARV instruction. */
26528 MIPS_INVAL("OPC_MXU_D32SARV");
26529 generate_exception_end(ctx
, EXCP_RI
);
26531 case OPC_MXU_Q16SLLV
:
26532 /* TODO: Implement emulation of Q16SLLV instruction. */
26533 MIPS_INVAL("OPC_MXU_Q16SLLV");
26534 generate_exception_end(ctx
, EXCP_RI
);
26536 case OPC_MXU_Q16SLRV
:
26537 /* TODO: Implement emulation of Q16SLRV instruction. */
26538 MIPS_INVAL("OPC_MXU_Q16SLRV");
26539 generate_exception_end(ctx
, EXCP_RI
);
26541 case OPC_MXU_Q16SARV
:
26542 /* TODO: Implement emulation of Q16SARV instruction. */
26543 MIPS_INVAL("OPC_MXU_Q16SARV");
26544 generate_exception_end(ctx
, EXCP_RI
);
26547 MIPS_INVAL("decode_opc_mxu");
26548 generate_exception_end(ctx
, EXCP_RI
);
26555 * Decode MXU pool19
26557 * 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
26558 * +-----------+---+---+-------+-------+-------+-------+-----------+
26559 * | SPECIAL2 |0 0|x x| XRd | XRc | XRb | XRa |MXU__POOL19|
26560 * +-----------+---+---+-------+-------+-------+-------+-----------+
26563 static void decode_opc_mxu__pool19(CPUMIPSState
*env
, DisasContext
*ctx
)
26565 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26568 case OPC_MXU_Q8MUL
:
26569 case OPC_MXU_Q8MULSU
:
26570 gen_mxu_q8mul_q8mulsu(ctx
);
26573 MIPS_INVAL("decode_opc_mxu");
26574 generate_exception_end(ctx
, EXCP_RI
);
26581 * Decode MXU pool20
26583 * 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
26584 * +-----------+---------+-----+-------+-------+-------+-----------+
26585 * | SPECIAL2 |0 0 0 0 0|x x x| XRc | XRb | XRa |MXU__POOL20|
26586 * +-----------+---------+-----+-------+-------+-------+-----------+
26589 static void decode_opc_mxu__pool20(CPUMIPSState
*env
, DisasContext
*ctx
)
26591 uint32_t opcode
= extract32(ctx
->opcode
, 18, 3);
26594 case OPC_MXU_Q8MOVZ
:
26595 /* TODO: Implement emulation of Q8MOVZ instruction. */
26596 MIPS_INVAL("OPC_MXU_Q8MOVZ");
26597 generate_exception_end(ctx
, EXCP_RI
);
26599 case OPC_MXU_Q8MOVN
:
26600 /* TODO: Implement emulation of Q8MOVN instruction. */
26601 MIPS_INVAL("OPC_MXU_Q8MOVN");
26602 generate_exception_end(ctx
, EXCP_RI
);
26604 case OPC_MXU_D16MOVZ
:
26605 /* TODO: Implement emulation of D16MOVZ instruction. */
26606 MIPS_INVAL("OPC_MXU_D16MOVZ");
26607 generate_exception_end(ctx
, EXCP_RI
);
26609 case OPC_MXU_D16MOVN
:
26610 /* TODO: Implement emulation of D16MOVN instruction. */
26611 MIPS_INVAL("OPC_MXU_D16MOVN");
26612 generate_exception_end(ctx
, EXCP_RI
);
26614 case OPC_MXU_S32MOVZ
:
26615 /* TODO: Implement emulation of S32MOVZ instruction. */
26616 MIPS_INVAL("OPC_MXU_S32MOVZ");
26617 generate_exception_end(ctx
, EXCP_RI
);
26619 case OPC_MXU_S32MOVN
:
26620 /* TODO: Implement emulation of S32MOVN instruction. */
26621 MIPS_INVAL("OPC_MXU_S32MOVN");
26622 generate_exception_end(ctx
, EXCP_RI
);
26625 MIPS_INVAL("decode_opc_mxu");
26626 generate_exception_end(ctx
, EXCP_RI
);
26633 * Decode MXU pool21
26635 * 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
26636 * +-----------+---+---+-------+-------+-------+-------+-----------+
26637 * | SPECIAL2 |an2|x x| XRd | XRc | XRb | XRa |MXU__POOL21|
26638 * +-----------+---+---+-------+-------+-------+-------+-----------+
26641 static void decode_opc_mxu__pool21(CPUMIPSState
*env
, DisasContext
*ctx
)
26643 uint32_t opcode
= extract32(ctx
->opcode
, 22, 2);
26646 case OPC_MXU_Q8MAC
:
26647 /* TODO: Implement emulation of Q8MAC instruction. */
26648 MIPS_INVAL("OPC_MXU_Q8MAC");
26649 generate_exception_end(ctx
, EXCP_RI
);
26651 case OPC_MXU_Q8MACSU
:
26652 /* TODO: Implement emulation of Q8MACSU instruction. */
26653 MIPS_INVAL("OPC_MXU_Q8MACSU");
26654 generate_exception_end(ctx
, EXCP_RI
);
26657 MIPS_INVAL("decode_opc_mxu");
26658 generate_exception_end(ctx
, EXCP_RI
);
26665 * Main MXU decoding function
26667 * 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
26668 * +-----------+---------------------------------------+-----------+
26669 * | SPECIAL2 | |x x x x x x|
26670 * +-----------+---------------------------------------+-----------+
26673 static void decode_opc_mxu(CPUMIPSState
*env
, DisasContext
*ctx
)
26676 * TODO: Investigate necessity of including handling of
26677 * CLZ, CLO, SDBB in this function, as they belong to
26678 * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26680 uint32_t opcode
= extract32(ctx
->opcode
, 0, 6);
26682 if (opcode
== OPC__MXU_MUL
) {
26683 uint32_t rs
, rt
, rd
, op1
;
26685 rs
= extract32(ctx
->opcode
, 21, 5);
26686 rt
= extract32(ctx
->opcode
, 16, 5);
26687 rd
= extract32(ctx
->opcode
, 11, 5);
26688 op1
= MASK_SPECIAL2(ctx
->opcode
);
26690 gen_arith(ctx
, op1
, rd
, rs
, rt
);
26695 if (opcode
== OPC_MXU_S32M2I
) {
26696 gen_mxu_s32m2i(ctx
);
26700 if (opcode
== OPC_MXU_S32I2M
) {
26701 gen_mxu_s32i2m(ctx
);
26706 TCGv t_mxu_cr
= tcg_temp_new();
26707 TCGLabel
*l_exit
= gen_new_label();
26709 gen_load_mxu_cr(t_mxu_cr
);
26710 tcg_gen_andi_tl(t_mxu_cr
, t_mxu_cr
, MXU_CR_MXU_EN
);
26711 tcg_gen_brcondi_tl(TCG_COND_NE
, t_mxu_cr
, MXU_CR_MXU_EN
, l_exit
);
26714 case OPC_MXU_S32MADD
:
26715 /* TODO: Implement emulation of S32MADD instruction. */
26716 MIPS_INVAL("OPC_MXU_S32MADD");
26717 generate_exception_end(ctx
, EXCP_RI
);
26719 case OPC_MXU_S32MADDU
:
26720 /* TODO: Implement emulation of S32MADDU instruction. */
26721 MIPS_INVAL("OPC_MXU_S32MADDU");
26722 generate_exception_end(ctx
, EXCP_RI
);
26724 case OPC_MXU__POOL00
:
26725 decode_opc_mxu__pool00(env
, ctx
);
26727 case OPC_MXU_S32MSUB
:
26728 /* TODO: Implement emulation of S32MSUB instruction. */
26729 MIPS_INVAL("OPC_MXU_S32MSUB");
26730 generate_exception_end(ctx
, EXCP_RI
);
26732 case OPC_MXU_S32MSUBU
:
26733 /* TODO: Implement emulation of S32MSUBU instruction. */
26734 MIPS_INVAL("OPC_MXU_S32MSUBU");
26735 generate_exception_end(ctx
, EXCP_RI
);
26737 case OPC_MXU__POOL01
:
26738 decode_opc_mxu__pool01(env
, ctx
);
26740 case OPC_MXU__POOL02
:
26741 decode_opc_mxu__pool02(env
, ctx
);
26743 case OPC_MXU_D16MUL
:
26744 gen_mxu_d16mul(ctx
);
26746 case OPC_MXU__POOL03
:
26747 decode_opc_mxu__pool03(env
, ctx
);
26749 case OPC_MXU_D16MAC
:
26750 gen_mxu_d16mac(ctx
);
26752 case OPC_MXU_D16MACF
:
26753 /* TODO: Implement emulation of D16MACF instruction. */
26754 MIPS_INVAL("OPC_MXU_D16MACF");
26755 generate_exception_end(ctx
, EXCP_RI
);
26757 case OPC_MXU_D16MADL
:
26758 /* TODO: Implement emulation of D16MADL instruction. */
26759 MIPS_INVAL("OPC_MXU_D16MADL");
26760 generate_exception_end(ctx
, EXCP_RI
);
26762 case OPC_MXU_S16MAD
:
26763 /* TODO: Implement emulation of S16MAD instruction. */
26764 MIPS_INVAL("OPC_MXU_S16MAD");
26765 generate_exception_end(ctx
, EXCP_RI
);
26767 case OPC_MXU_Q16ADD
:
26768 /* TODO: Implement emulation of Q16ADD instruction. */
26769 MIPS_INVAL("OPC_MXU_Q16ADD");
26770 generate_exception_end(ctx
, EXCP_RI
);
26772 case OPC_MXU_D16MACE
:
26773 /* TODO: Implement emulation of D16MACE instruction. */
26774 MIPS_INVAL("OPC_MXU_D16MACE");
26775 generate_exception_end(ctx
, EXCP_RI
);
26777 case OPC_MXU__POOL04
:
26778 decode_opc_mxu__pool04(env
, ctx
);
26780 case OPC_MXU__POOL05
:
26781 decode_opc_mxu__pool05(env
, ctx
);
26783 case OPC_MXU__POOL06
:
26784 decode_opc_mxu__pool06(env
, ctx
);
26786 case OPC_MXU__POOL07
:
26787 decode_opc_mxu__pool07(env
, ctx
);
26789 case OPC_MXU__POOL08
:
26790 decode_opc_mxu__pool08(env
, ctx
);
26792 case OPC_MXU__POOL09
:
26793 decode_opc_mxu__pool09(env
, ctx
);
26795 case OPC_MXU__POOL10
:
26796 decode_opc_mxu__pool10(env
, ctx
);
26798 case OPC_MXU__POOL11
:
26799 decode_opc_mxu__pool11(env
, ctx
);
26801 case OPC_MXU_D32ADD
:
26802 /* TODO: Implement emulation of D32ADD instruction. */
26803 MIPS_INVAL("OPC_MXU_D32ADD");
26804 generate_exception_end(ctx
, EXCP_RI
);
26806 case OPC_MXU__POOL12
:
26807 decode_opc_mxu__pool12(env
, ctx
);
26809 case OPC_MXU__POOL13
:
26810 decode_opc_mxu__pool13(env
, ctx
);
26812 case OPC_MXU__POOL14
:
26813 decode_opc_mxu__pool14(env
, ctx
);
26815 case OPC_MXU_Q8ACCE
:
26816 /* TODO: Implement emulation of Q8ACCE instruction. */
26817 MIPS_INVAL("OPC_MXU_Q8ACCE");
26818 generate_exception_end(ctx
, EXCP_RI
);
26820 case OPC_MXU_S8LDD
:
26821 gen_mxu_s8ldd(ctx
);
26823 case OPC_MXU_S8STD
:
26824 /* TODO: Implement emulation of S8STD instruction. */
26825 MIPS_INVAL("OPC_MXU_S8STD");
26826 generate_exception_end(ctx
, EXCP_RI
);
26828 case OPC_MXU_S8LDI
:
26829 /* TODO: Implement emulation of S8LDI instruction. */
26830 MIPS_INVAL("OPC_MXU_S8LDI");
26831 generate_exception_end(ctx
, EXCP_RI
);
26833 case OPC_MXU_S8SDI
:
26834 /* TODO: Implement emulation of S8SDI instruction. */
26835 MIPS_INVAL("OPC_MXU_S8SDI");
26836 generate_exception_end(ctx
, EXCP_RI
);
26838 case OPC_MXU__POOL15
:
26839 decode_opc_mxu__pool15(env
, ctx
);
26841 case OPC_MXU__POOL16
:
26842 decode_opc_mxu__pool16(env
, ctx
);
26844 case OPC_MXU__POOL17
:
26845 decode_opc_mxu__pool17(env
, ctx
);
26847 case OPC_MXU_S16LDD
:
26848 /* TODO: Implement emulation of S16LDD instruction. */
26849 MIPS_INVAL("OPC_MXU_S16LDD");
26850 generate_exception_end(ctx
, EXCP_RI
);
26852 case OPC_MXU_S16STD
:
26853 /* TODO: Implement emulation of S16STD instruction. */
26854 MIPS_INVAL("OPC_MXU_S16STD");
26855 generate_exception_end(ctx
, EXCP_RI
);
26857 case OPC_MXU_S16LDI
:
26858 /* TODO: Implement emulation of S16LDI instruction. */
26859 MIPS_INVAL("OPC_MXU_S16LDI");
26860 generate_exception_end(ctx
, EXCP_RI
);
26862 case OPC_MXU_S16SDI
:
26863 /* TODO: Implement emulation of S16SDI instruction. */
26864 MIPS_INVAL("OPC_MXU_S16SDI");
26865 generate_exception_end(ctx
, EXCP_RI
);
26867 case OPC_MXU_D32SLL
:
26868 /* TODO: Implement emulation of D32SLL instruction. */
26869 MIPS_INVAL("OPC_MXU_D32SLL");
26870 generate_exception_end(ctx
, EXCP_RI
);
26872 case OPC_MXU_D32SLR
:
26873 /* TODO: Implement emulation of D32SLR instruction. */
26874 MIPS_INVAL("OPC_MXU_D32SLR");
26875 generate_exception_end(ctx
, EXCP_RI
);
26877 case OPC_MXU_D32SARL
:
26878 /* TODO: Implement emulation of D32SARL instruction. */
26879 MIPS_INVAL("OPC_MXU_D32SARL");
26880 generate_exception_end(ctx
, EXCP_RI
);
26882 case OPC_MXU_D32SAR
:
26883 /* TODO: Implement emulation of D32SAR instruction. */
26884 MIPS_INVAL("OPC_MXU_D32SAR");
26885 generate_exception_end(ctx
, EXCP_RI
);
26887 case OPC_MXU_Q16SLL
:
26888 /* TODO: Implement emulation of Q16SLL instruction. */
26889 MIPS_INVAL("OPC_MXU_Q16SLL");
26890 generate_exception_end(ctx
, EXCP_RI
);
26892 case OPC_MXU_Q16SLR
:
26893 /* TODO: Implement emulation of Q16SLR instruction. */
26894 MIPS_INVAL("OPC_MXU_Q16SLR");
26895 generate_exception_end(ctx
, EXCP_RI
);
26897 case OPC_MXU__POOL18
:
26898 decode_opc_mxu__pool18(env
, ctx
);
26900 case OPC_MXU_Q16SAR
:
26901 /* TODO: Implement emulation of Q16SAR instruction. */
26902 MIPS_INVAL("OPC_MXU_Q16SAR");
26903 generate_exception_end(ctx
, EXCP_RI
);
26905 case OPC_MXU__POOL19
:
26906 decode_opc_mxu__pool19(env
, ctx
);
26908 case OPC_MXU__POOL20
:
26909 decode_opc_mxu__pool20(env
, ctx
);
26911 case OPC_MXU__POOL21
:
26912 decode_opc_mxu__pool21(env
, ctx
);
26914 case OPC_MXU_Q16SCOP
:
26915 /* TODO: Implement emulation of Q16SCOP instruction. */
26916 MIPS_INVAL("OPC_MXU_Q16SCOP");
26917 generate_exception_end(ctx
, EXCP_RI
);
26919 case OPC_MXU_Q8MADL
:
26920 /* TODO: Implement emulation of Q8MADL instruction. */
26921 MIPS_INVAL("OPC_MXU_Q8MADL");
26922 generate_exception_end(ctx
, EXCP_RI
);
26924 case OPC_MXU_S32SFL
:
26925 /* TODO: Implement emulation of S32SFL instruction. */
26926 MIPS_INVAL("OPC_MXU_S32SFL");
26927 generate_exception_end(ctx
, EXCP_RI
);
26929 case OPC_MXU_Q8SAD
:
26930 /* TODO: Implement emulation of Q8SAD instruction. */
26931 MIPS_INVAL("OPC_MXU_Q8SAD");
26932 generate_exception_end(ctx
, EXCP_RI
);
26935 MIPS_INVAL("decode_opc_mxu");
26936 generate_exception_end(ctx
, EXCP_RI
);
26939 gen_set_label(l_exit
);
26940 tcg_temp_free(t_mxu_cr
);
26944 #endif /* !defined(TARGET_MIPS64) */
26947 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
26952 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
26954 rs
= (ctx
->opcode
>> 21) & 0x1f;
26955 rt
= (ctx
->opcode
>> 16) & 0x1f;
26956 rd
= (ctx
->opcode
>> 11) & 0x1f;
26958 op1
= MASK_SPECIAL2(ctx
->opcode
);
26960 case OPC_MADD
: /* Multiply and add/sub */
26964 check_insn(ctx
, ISA_MIPS32
);
26965 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
26968 gen_arith(ctx
, op1
, rd
, rs
, rt
);
26971 case OPC_DIVU_G_2F
:
26972 case OPC_MULT_G_2F
:
26973 case OPC_MULTU_G_2F
:
26975 case OPC_MODU_G_2F
:
26976 check_insn(ctx
, INSN_LOONGSON2F
);
26977 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
26981 check_insn(ctx
, ISA_MIPS32
);
26982 gen_cl(ctx
, op1
, rd
, rs
);
26985 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
26986 gen_helper_do_semihosting(cpu_env
);
26989 * XXX: not clear which exception should be raised
26990 * when in debug mode...
26992 check_insn(ctx
, ISA_MIPS32
);
26993 generate_exception_end(ctx
, EXCP_DBp
);
26996 #if defined(TARGET_MIPS64)
26999 check_insn(ctx
, ISA_MIPS64
);
27000 check_mips_64(ctx
);
27001 gen_cl(ctx
, op1
, rd
, rs
);
27003 case OPC_DMULT_G_2F
:
27004 case OPC_DMULTU_G_2F
:
27005 case OPC_DDIV_G_2F
:
27006 case OPC_DDIVU_G_2F
:
27007 case OPC_DMOD_G_2F
:
27008 case OPC_DMODU_G_2F
:
27009 check_insn(ctx
, INSN_LOONGSON2F
);
27010 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27013 default: /* Invalid */
27014 MIPS_INVAL("special2_legacy");
27015 generate_exception_end(ctx
, EXCP_RI
);
27020 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
27022 int rs
, rt
, rd
, sa
;
27026 rs
= (ctx
->opcode
>> 21) & 0x1f;
27027 rt
= (ctx
->opcode
>> 16) & 0x1f;
27028 rd
= (ctx
->opcode
>> 11) & 0x1f;
27029 sa
= (ctx
->opcode
>> 6) & 0x1f;
27030 imm
= (int16_t)ctx
->opcode
>> 7;
27032 op1
= MASK_SPECIAL3(ctx
->opcode
);
27036 /* hint codes 24-31 are reserved and signal RI */
27037 generate_exception_end(ctx
, EXCP_RI
);
27039 /* Treat as NOP. */
27042 check_cp0_enabled(ctx
);
27043 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27044 gen_cache_operation(ctx
, rt
, rs
, imm
);
27048 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
27051 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27056 /* Treat as NOP. */
27059 op2
= MASK_BSHFL(ctx
->opcode
);
27065 gen_align(ctx
, 32, rd
, rs
, rt
, sa
& 3);
27068 gen_bitswap(ctx
, op2
, rd
, rt
);
27073 #if defined(TARGET_MIPS64)
27075 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
27078 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27081 check_mips_64(ctx
);
27084 /* Treat as NOP. */
27087 op2
= MASK_DBSHFL(ctx
->opcode
);
27097 gen_align(ctx
, 64, rd
, rs
, rt
, sa
& 7);
27100 gen_bitswap(ctx
, op2
, rd
, rt
);
27107 default: /* Invalid */
27108 MIPS_INVAL("special3_r6");
27109 generate_exception_end(ctx
, EXCP_RI
);
27114 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
27119 rs
= (ctx
->opcode
>> 21) & 0x1f;
27120 rt
= (ctx
->opcode
>> 16) & 0x1f;
27121 rd
= (ctx
->opcode
>> 11) & 0x1f;
27123 op1
= MASK_SPECIAL3(ctx
->opcode
);
27126 case OPC_DIVU_G_2E
:
27128 case OPC_MODU_G_2E
:
27129 case OPC_MULT_G_2E
:
27130 case OPC_MULTU_G_2E
:
27132 * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
27133 * the same mask and op1.
27135 if ((ctx
->insn_flags
& ASE_DSP_R2
) && (op1
== OPC_MULT_G_2E
)) {
27136 op2
= MASK_ADDUH_QB(ctx
->opcode
);
27139 case OPC_ADDUH_R_QB
:
27141 case OPC_ADDQH_R_PH
:
27143 case OPC_ADDQH_R_W
:
27145 case OPC_SUBUH_R_QB
:
27147 case OPC_SUBQH_R_PH
:
27149 case OPC_SUBQH_R_W
:
27150 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27155 case OPC_MULQ_RS_W
:
27156 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27159 MIPS_INVAL("MASK ADDUH.QB");
27160 generate_exception_end(ctx
, EXCP_RI
);
27163 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
27164 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27166 generate_exception_end(ctx
, EXCP_RI
);
27170 op2
= MASK_LX(ctx
->opcode
);
27172 #if defined(TARGET_MIPS64)
27178 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
27180 default: /* Invalid */
27181 MIPS_INVAL("MASK LX");
27182 generate_exception_end(ctx
, EXCP_RI
);
27186 case OPC_ABSQ_S_PH_DSP
:
27187 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
27189 case OPC_ABSQ_S_QB
:
27190 case OPC_ABSQ_S_PH
:
27192 case OPC_PRECEQ_W_PHL
:
27193 case OPC_PRECEQ_W_PHR
:
27194 case OPC_PRECEQU_PH_QBL
:
27195 case OPC_PRECEQU_PH_QBR
:
27196 case OPC_PRECEQU_PH_QBLA
:
27197 case OPC_PRECEQU_PH_QBRA
:
27198 case OPC_PRECEU_PH_QBL
:
27199 case OPC_PRECEU_PH_QBR
:
27200 case OPC_PRECEU_PH_QBLA
:
27201 case OPC_PRECEU_PH_QBRA
:
27202 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27209 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27212 MIPS_INVAL("MASK ABSQ_S.PH");
27213 generate_exception_end(ctx
, EXCP_RI
);
27217 case OPC_ADDU_QB_DSP
:
27218 op2
= MASK_ADDU_QB(ctx
->opcode
);
27221 case OPC_ADDQ_S_PH
:
27224 case OPC_ADDU_S_QB
:
27226 case OPC_ADDU_S_PH
:
27228 case OPC_SUBQ_S_PH
:
27231 case OPC_SUBU_S_QB
:
27233 case OPC_SUBU_S_PH
:
27237 case OPC_RADDU_W_QB
:
27238 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27240 case OPC_MULEU_S_PH_QBL
:
27241 case OPC_MULEU_S_PH_QBR
:
27242 case OPC_MULQ_RS_PH
:
27243 case OPC_MULEQ_S_W_PHL
:
27244 case OPC_MULEQ_S_W_PHR
:
27245 case OPC_MULQ_S_PH
:
27246 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27248 default: /* Invalid */
27249 MIPS_INVAL("MASK ADDU.QB");
27250 generate_exception_end(ctx
, EXCP_RI
);
27255 case OPC_CMPU_EQ_QB_DSP
:
27256 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
27258 case OPC_PRECR_SRA_PH_W
:
27259 case OPC_PRECR_SRA_R_PH_W
:
27260 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27262 case OPC_PRECR_QB_PH
:
27263 case OPC_PRECRQ_QB_PH
:
27264 case OPC_PRECRQ_PH_W
:
27265 case OPC_PRECRQ_RS_PH_W
:
27266 case OPC_PRECRQU_S_QB_PH
:
27267 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27269 case OPC_CMPU_EQ_QB
:
27270 case OPC_CMPU_LT_QB
:
27271 case OPC_CMPU_LE_QB
:
27272 case OPC_CMP_EQ_PH
:
27273 case OPC_CMP_LT_PH
:
27274 case OPC_CMP_LE_PH
:
27275 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27277 case OPC_CMPGU_EQ_QB
:
27278 case OPC_CMPGU_LT_QB
:
27279 case OPC_CMPGU_LE_QB
:
27280 case OPC_CMPGDU_EQ_QB
:
27281 case OPC_CMPGDU_LT_QB
:
27282 case OPC_CMPGDU_LE_QB
:
27285 case OPC_PACKRL_PH
:
27286 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27288 default: /* Invalid */
27289 MIPS_INVAL("MASK CMPU.EQ.QB");
27290 generate_exception_end(ctx
, EXCP_RI
);
27294 case OPC_SHLL_QB_DSP
:
27295 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27297 case OPC_DPA_W_PH_DSP
:
27298 op2
= MASK_DPA_W_PH(ctx
->opcode
);
27300 case OPC_DPAU_H_QBL
:
27301 case OPC_DPAU_H_QBR
:
27302 case OPC_DPSU_H_QBL
:
27303 case OPC_DPSU_H_QBR
:
27305 case OPC_DPAX_W_PH
:
27306 case OPC_DPAQ_S_W_PH
:
27307 case OPC_DPAQX_S_W_PH
:
27308 case OPC_DPAQX_SA_W_PH
:
27310 case OPC_DPSX_W_PH
:
27311 case OPC_DPSQ_S_W_PH
:
27312 case OPC_DPSQX_S_W_PH
:
27313 case OPC_DPSQX_SA_W_PH
:
27314 case OPC_MULSAQ_S_W_PH
:
27315 case OPC_DPAQ_SA_L_W
:
27316 case OPC_DPSQ_SA_L_W
:
27317 case OPC_MAQ_S_W_PHL
:
27318 case OPC_MAQ_S_W_PHR
:
27319 case OPC_MAQ_SA_W_PHL
:
27320 case OPC_MAQ_SA_W_PHR
:
27321 case OPC_MULSA_W_PH
:
27322 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27324 default: /* Invalid */
27325 MIPS_INVAL("MASK DPAW.PH");
27326 generate_exception_end(ctx
, EXCP_RI
);
27331 op2
= MASK_INSV(ctx
->opcode
);
27342 t0
= tcg_temp_new();
27343 t1
= tcg_temp_new();
27345 gen_load_gpr(t0
, rt
);
27346 gen_load_gpr(t1
, rs
);
27348 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27354 default: /* Invalid */
27355 MIPS_INVAL("MASK INSV");
27356 generate_exception_end(ctx
, EXCP_RI
);
27360 case OPC_APPEND_DSP
:
27361 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27363 case OPC_EXTR_W_DSP
:
27364 op2
= MASK_EXTR_W(ctx
->opcode
);
27368 case OPC_EXTR_RS_W
:
27370 case OPC_EXTRV_S_H
:
27372 case OPC_EXTRV_R_W
:
27373 case OPC_EXTRV_RS_W
:
27378 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27381 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27387 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27389 default: /* Invalid */
27390 MIPS_INVAL("MASK EXTR.W");
27391 generate_exception_end(ctx
, EXCP_RI
);
27395 #if defined(TARGET_MIPS64)
27396 case OPC_DDIV_G_2E
:
27397 case OPC_DDIVU_G_2E
:
27398 case OPC_DMULT_G_2E
:
27399 case OPC_DMULTU_G_2E
:
27400 case OPC_DMOD_G_2E
:
27401 case OPC_DMODU_G_2E
:
27402 check_insn(ctx
, INSN_LOONGSON2E
);
27403 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
27405 case OPC_ABSQ_S_QH_DSP
:
27406 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
27408 case OPC_PRECEQ_L_PWL
:
27409 case OPC_PRECEQ_L_PWR
:
27410 case OPC_PRECEQ_PW_QHL
:
27411 case OPC_PRECEQ_PW_QHR
:
27412 case OPC_PRECEQ_PW_QHLA
:
27413 case OPC_PRECEQ_PW_QHRA
:
27414 case OPC_PRECEQU_QH_OBL
:
27415 case OPC_PRECEQU_QH_OBR
:
27416 case OPC_PRECEQU_QH_OBLA
:
27417 case OPC_PRECEQU_QH_OBRA
:
27418 case OPC_PRECEU_QH_OBL
:
27419 case OPC_PRECEU_QH_OBR
:
27420 case OPC_PRECEU_QH_OBLA
:
27421 case OPC_PRECEU_QH_OBRA
:
27422 case OPC_ABSQ_S_OB
:
27423 case OPC_ABSQ_S_PW
:
27424 case OPC_ABSQ_S_QH
:
27425 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27433 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
27435 default: /* Invalid */
27436 MIPS_INVAL("MASK ABSQ_S.QH");
27437 generate_exception_end(ctx
, EXCP_RI
);
27441 case OPC_ADDU_OB_DSP
:
27442 op2
= MASK_ADDU_OB(ctx
->opcode
);
27444 case OPC_RADDU_L_OB
:
27446 case OPC_SUBQ_S_PW
:
27448 case OPC_SUBQ_S_QH
:
27450 case OPC_SUBU_S_OB
:
27452 case OPC_SUBU_S_QH
:
27454 case OPC_SUBUH_R_OB
:
27456 case OPC_ADDQ_S_PW
:
27458 case OPC_ADDQ_S_QH
:
27460 case OPC_ADDU_S_OB
:
27462 case OPC_ADDU_S_QH
:
27464 case OPC_ADDUH_R_OB
:
27465 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27467 case OPC_MULEQ_S_PW_QHL
:
27468 case OPC_MULEQ_S_PW_QHR
:
27469 case OPC_MULEU_S_QH_OBL
:
27470 case OPC_MULEU_S_QH_OBR
:
27471 case OPC_MULQ_RS_QH
:
27472 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27474 default: /* Invalid */
27475 MIPS_INVAL("MASK ADDU.OB");
27476 generate_exception_end(ctx
, EXCP_RI
);
27480 case OPC_CMPU_EQ_OB_DSP
:
27481 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
27483 case OPC_PRECR_SRA_QH_PW
:
27484 case OPC_PRECR_SRA_R_QH_PW
:
27485 /* Return value is rt. */
27486 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
27488 case OPC_PRECR_OB_QH
:
27489 case OPC_PRECRQ_OB_QH
:
27490 case OPC_PRECRQ_PW_L
:
27491 case OPC_PRECRQ_QH_PW
:
27492 case OPC_PRECRQ_RS_QH_PW
:
27493 case OPC_PRECRQU_S_OB_QH
:
27494 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
27496 case OPC_CMPU_EQ_OB
:
27497 case OPC_CMPU_LT_OB
:
27498 case OPC_CMPU_LE_OB
:
27499 case OPC_CMP_EQ_QH
:
27500 case OPC_CMP_LT_QH
:
27501 case OPC_CMP_LE_QH
:
27502 case OPC_CMP_EQ_PW
:
27503 case OPC_CMP_LT_PW
:
27504 case OPC_CMP_LE_PW
:
27505 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27507 case OPC_CMPGDU_EQ_OB
:
27508 case OPC_CMPGDU_LT_OB
:
27509 case OPC_CMPGDU_LE_OB
:
27510 case OPC_CMPGU_EQ_OB
:
27511 case OPC_CMPGU_LT_OB
:
27512 case OPC_CMPGU_LE_OB
:
27513 case OPC_PACKRL_PW
:
27517 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
27519 default: /* Invalid */
27520 MIPS_INVAL("MASK CMPU_EQ.OB");
27521 generate_exception_end(ctx
, EXCP_RI
);
27525 case OPC_DAPPEND_DSP
:
27526 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
27528 case OPC_DEXTR_W_DSP
:
27529 op2
= MASK_DEXTR_W(ctx
->opcode
);
27536 case OPC_DEXTR_R_L
:
27537 case OPC_DEXTR_RS_L
:
27539 case OPC_DEXTR_R_W
:
27540 case OPC_DEXTR_RS_W
:
27541 case OPC_DEXTR_S_H
:
27543 case OPC_DEXTRV_R_L
:
27544 case OPC_DEXTRV_RS_L
:
27545 case OPC_DEXTRV_S_H
:
27547 case OPC_DEXTRV_R_W
:
27548 case OPC_DEXTRV_RS_W
:
27549 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
27554 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27556 default: /* Invalid */
27557 MIPS_INVAL("MASK EXTR.W");
27558 generate_exception_end(ctx
, EXCP_RI
);
27562 case OPC_DPAQ_W_QH_DSP
:
27563 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
27565 case OPC_DPAU_H_OBL
:
27566 case OPC_DPAU_H_OBR
:
27567 case OPC_DPSU_H_OBL
:
27568 case OPC_DPSU_H_OBR
:
27570 case OPC_DPAQ_S_W_QH
:
27572 case OPC_DPSQ_S_W_QH
:
27573 case OPC_MULSAQ_S_W_QH
:
27574 case OPC_DPAQ_SA_L_PW
:
27575 case OPC_DPSQ_SA_L_PW
:
27576 case OPC_MULSAQ_S_L_PW
:
27577 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27579 case OPC_MAQ_S_W_QHLL
:
27580 case OPC_MAQ_S_W_QHLR
:
27581 case OPC_MAQ_S_W_QHRL
:
27582 case OPC_MAQ_S_W_QHRR
:
27583 case OPC_MAQ_SA_W_QHLL
:
27584 case OPC_MAQ_SA_W_QHLR
:
27585 case OPC_MAQ_SA_W_QHRL
:
27586 case OPC_MAQ_SA_W_QHRR
:
27587 case OPC_MAQ_S_L_PWL
:
27588 case OPC_MAQ_S_L_PWR
:
27593 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
27595 default: /* Invalid */
27596 MIPS_INVAL("MASK DPAQ.W.QH");
27597 generate_exception_end(ctx
, EXCP_RI
);
27601 case OPC_DINSV_DSP
:
27602 op2
= MASK_INSV(ctx
->opcode
);
27613 t0
= tcg_temp_new();
27614 t1
= tcg_temp_new();
27616 gen_load_gpr(t0
, rt
);
27617 gen_load_gpr(t1
, rs
);
27619 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
27625 default: /* Invalid */
27626 MIPS_INVAL("MASK DINSV");
27627 generate_exception_end(ctx
, EXCP_RI
);
27631 case OPC_SHLL_OB_DSP
:
27632 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
27635 default: /* Invalid */
27636 MIPS_INVAL("special3_legacy");
27637 generate_exception_end(ctx
, EXCP_RI
);
27643 #if defined(TARGET_MIPS64)
27645 static void decode_mmi0(CPUMIPSState
*env
, DisasContext
*ctx
)
27647 uint32_t opc
= MASK_MMI0(ctx
->opcode
);
27650 case MMI_OPC_0_PADDW
: /* TODO: MMI_OPC_0_PADDW */
27651 case MMI_OPC_0_PSUBW
: /* TODO: MMI_OPC_0_PSUBW */
27652 case MMI_OPC_0_PCGTW
: /* TODO: MMI_OPC_0_PCGTW */
27653 case MMI_OPC_0_PMAXW
: /* TODO: MMI_OPC_0_PMAXW */
27654 case MMI_OPC_0_PADDH
: /* TODO: MMI_OPC_0_PADDH */
27655 case MMI_OPC_0_PSUBH
: /* TODO: MMI_OPC_0_PSUBH */
27656 case MMI_OPC_0_PCGTH
: /* TODO: MMI_OPC_0_PCGTH */
27657 case MMI_OPC_0_PMAXH
: /* TODO: MMI_OPC_0_PMAXH */
27658 case MMI_OPC_0_PADDB
: /* TODO: MMI_OPC_0_PADDB */
27659 case MMI_OPC_0_PSUBB
: /* TODO: MMI_OPC_0_PSUBB */
27660 case MMI_OPC_0_PCGTB
: /* TODO: MMI_OPC_0_PCGTB */
27661 case MMI_OPC_0_PADDSW
: /* TODO: MMI_OPC_0_PADDSW */
27662 case MMI_OPC_0_PSUBSW
: /* TODO: MMI_OPC_0_PSUBSW */
27663 case MMI_OPC_0_PEXTLW
: /* TODO: MMI_OPC_0_PEXTLW */
27664 case MMI_OPC_0_PPACW
: /* TODO: MMI_OPC_0_PPACW */
27665 case MMI_OPC_0_PADDSH
: /* TODO: MMI_OPC_0_PADDSH */
27666 case MMI_OPC_0_PSUBSH
: /* TODO: MMI_OPC_0_PSUBSH */
27667 case MMI_OPC_0_PEXTLH
: /* TODO: MMI_OPC_0_PEXTLH */
27668 case MMI_OPC_0_PPACH
: /* TODO: MMI_OPC_0_PPACH */
27669 case MMI_OPC_0_PADDSB
: /* TODO: MMI_OPC_0_PADDSB */
27670 case MMI_OPC_0_PSUBSB
: /* TODO: MMI_OPC_0_PSUBSB */
27671 case MMI_OPC_0_PEXTLB
: /* TODO: MMI_OPC_0_PEXTLB */
27672 case MMI_OPC_0_PPACB
: /* TODO: MMI_OPC_0_PPACB */
27673 case MMI_OPC_0_PEXT5
: /* TODO: MMI_OPC_0_PEXT5 */
27674 case MMI_OPC_0_PPAC5
: /* TODO: MMI_OPC_0_PPAC5 */
27675 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI0 */
27678 MIPS_INVAL("TX79 MMI class MMI0");
27679 generate_exception_end(ctx
, EXCP_RI
);
27684 static void decode_mmi1(CPUMIPSState
*env
, DisasContext
*ctx
)
27686 uint32_t opc
= MASK_MMI1(ctx
->opcode
);
27689 case MMI_OPC_1_PABSW
: /* TODO: MMI_OPC_1_PABSW */
27690 case MMI_OPC_1_PCEQW
: /* TODO: MMI_OPC_1_PCEQW */
27691 case MMI_OPC_1_PMINW
: /* TODO: MMI_OPC_1_PMINW */
27692 case MMI_OPC_1_PADSBH
: /* TODO: MMI_OPC_1_PADSBH */
27693 case MMI_OPC_1_PABSH
: /* TODO: MMI_OPC_1_PABSH */
27694 case MMI_OPC_1_PCEQH
: /* TODO: MMI_OPC_1_PCEQH */
27695 case MMI_OPC_1_PMINH
: /* TODO: MMI_OPC_1_PMINH */
27696 case MMI_OPC_1_PCEQB
: /* TODO: MMI_OPC_1_PCEQB */
27697 case MMI_OPC_1_PADDUW
: /* TODO: MMI_OPC_1_PADDUW */
27698 case MMI_OPC_1_PSUBUW
: /* TODO: MMI_OPC_1_PSUBUW */
27699 case MMI_OPC_1_PEXTUW
: /* TODO: MMI_OPC_1_PEXTUW */
27700 case MMI_OPC_1_PADDUH
: /* TODO: MMI_OPC_1_PADDUH */
27701 case MMI_OPC_1_PSUBUH
: /* TODO: MMI_OPC_1_PSUBUH */
27702 case MMI_OPC_1_PEXTUH
: /* TODO: MMI_OPC_1_PEXTUH */
27703 case MMI_OPC_1_PADDUB
: /* TODO: MMI_OPC_1_PADDUB */
27704 case MMI_OPC_1_PSUBUB
: /* TODO: MMI_OPC_1_PSUBUB */
27705 case MMI_OPC_1_PEXTUB
: /* TODO: MMI_OPC_1_PEXTUB */
27706 case MMI_OPC_1_QFSRV
: /* TODO: MMI_OPC_1_QFSRV */
27707 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI1 */
27710 MIPS_INVAL("TX79 MMI class MMI1");
27711 generate_exception_end(ctx
, EXCP_RI
);
27716 static void decode_mmi2(CPUMIPSState
*env
, DisasContext
*ctx
)
27718 uint32_t opc
= MASK_MMI2(ctx
->opcode
);
27721 case MMI_OPC_2_PMADDW
: /* TODO: MMI_OPC_2_PMADDW */
27722 case MMI_OPC_2_PSLLVW
: /* TODO: MMI_OPC_2_PSLLVW */
27723 case MMI_OPC_2_PSRLVW
: /* TODO: MMI_OPC_2_PSRLVW */
27724 case MMI_OPC_2_PMSUBW
: /* TODO: MMI_OPC_2_PMSUBW */
27725 case MMI_OPC_2_PMFHI
: /* TODO: MMI_OPC_2_PMFHI */
27726 case MMI_OPC_2_PMFLO
: /* TODO: MMI_OPC_2_PMFLO */
27727 case MMI_OPC_2_PINTH
: /* TODO: MMI_OPC_2_PINTH */
27728 case MMI_OPC_2_PMULTW
: /* TODO: MMI_OPC_2_PMULTW */
27729 case MMI_OPC_2_PDIVW
: /* TODO: MMI_OPC_2_PDIVW */
27730 case MMI_OPC_2_PMADDH
: /* TODO: MMI_OPC_2_PMADDH */
27731 case MMI_OPC_2_PHMADH
: /* TODO: MMI_OPC_2_PHMADH */
27732 case MMI_OPC_2_PAND
: /* TODO: MMI_OPC_2_PAND */
27733 case MMI_OPC_2_PXOR
: /* TODO: MMI_OPC_2_PXOR */
27734 case MMI_OPC_2_PMSUBH
: /* TODO: MMI_OPC_2_PMSUBH */
27735 case MMI_OPC_2_PHMSBH
: /* TODO: MMI_OPC_2_PHMSBH */
27736 case MMI_OPC_2_PEXEH
: /* TODO: MMI_OPC_2_PEXEH */
27737 case MMI_OPC_2_PREVH
: /* TODO: MMI_OPC_2_PREVH */
27738 case MMI_OPC_2_PMULTH
: /* TODO: MMI_OPC_2_PMULTH */
27739 case MMI_OPC_2_PDIVBW
: /* TODO: MMI_OPC_2_PDIVBW */
27740 case MMI_OPC_2_PEXEW
: /* TODO: MMI_OPC_2_PEXEW */
27741 case MMI_OPC_2_PROT3W
: /* TODO: MMI_OPC_2_PROT3W */
27742 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI2 */
27744 case MMI_OPC_2_PCPYLD
:
27745 gen_mmi_pcpyld(ctx
);
27748 MIPS_INVAL("TX79 MMI class MMI2");
27749 generate_exception_end(ctx
, EXCP_RI
);
27754 static void decode_mmi3(CPUMIPSState
*env
, DisasContext
*ctx
)
27756 uint32_t opc
= MASK_MMI3(ctx
->opcode
);
27759 case MMI_OPC_3_PMADDUW
: /* TODO: MMI_OPC_3_PMADDUW */
27760 case MMI_OPC_3_PSRAVW
: /* TODO: MMI_OPC_3_PSRAVW */
27761 case MMI_OPC_3_PMTHI
: /* TODO: MMI_OPC_3_PMTHI */
27762 case MMI_OPC_3_PMTLO
: /* TODO: MMI_OPC_3_PMTLO */
27763 case MMI_OPC_3_PINTEH
: /* TODO: MMI_OPC_3_PINTEH */
27764 case MMI_OPC_3_PMULTUW
: /* TODO: MMI_OPC_3_PMULTUW */
27765 case MMI_OPC_3_PDIVUW
: /* TODO: MMI_OPC_3_PDIVUW */
27766 case MMI_OPC_3_POR
: /* TODO: MMI_OPC_3_POR */
27767 case MMI_OPC_3_PNOR
: /* TODO: MMI_OPC_3_PNOR */
27768 case MMI_OPC_3_PEXCH
: /* TODO: MMI_OPC_3_PEXCH */
27769 case MMI_OPC_3_PEXCW
: /* TODO: MMI_OPC_3_PEXCW */
27770 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI3 */
27772 case MMI_OPC_3_PCPYH
:
27773 gen_mmi_pcpyh(ctx
);
27775 case MMI_OPC_3_PCPYUD
:
27776 gen_mmi_pcpyud(ctx
);
27779 MIPS_INVAL("TX79 MMI class MMI3");
27780 generate_exception_end(ctx
, EXCP_RI
);
27785 static void decode_mmi(CPUMIPSState
*env
, DisasContext
*ctx
)
27787 uint32_t opc
= MASK_MMI(ctx
->opcode
);
27788 int rs
= extract32(ctx
->opcode
, 21, 5);
27789 int rt
= extract32(ctx
->opcode
, 16, 5);
27790 int rd
= extract32(ctx
->opcode
, 11, 5);
27793 case MMI_OPC_CLASS_MMI0
:
27794 decode_mmi0(env
, ctx
);
27796 case MMI_OPC_CLASS_MMI1
:
27797 decode_mmi1(env
, ctx
);
27799 case MMI_OPC_CLASS_MMI2
:
27800 decode_mmi2(env
, ctx
);
27802 case MMI_OPC_CLASS_MMI3
:
27803 decode_mmi3(env
, ctx
);
27805 case MMI_OPC_MULT1
:
27806 case MMI_OPC_MULTU1
:
27808 case MMI_OPC_MADDU
:
27809 case MMI_OPC_MADD1
:
27810 case MMI_OPC_MADDU1
:
27811 gen_mul_txx9(ctx
, opc
, rd
, rs
, rt
);
27814 case MMI_OPC_DIVU1
:
27815 gen_div1_tx79(ctx
, opc
, rs
, rt
);
27817 case MMI_OPC_MTLO1
:
27818 case MMI_OPC_MTHI1
:
27819 gen_HILO1_tx79(ctx
, opc
, rs
);
27821 case MMI_OPC_MFLO1
:
27822 case MMI_OPC_MFHI1
:
27823 gen_HILO1_tx79(ctx
, opc
, rd
);
27825 case MMI_OPC_PLZCW
: /* TODO: MMI_OPC_PLZCW */
27826 case MMI_OPC_PMFHL
: /* TODO: MMI_OPC_PMFHL */
27827 case MMI_OPC_PMTHL
: /* TODO: MMI_OPC_PMTHL */
27828 case MMI_OPC_PSLLH
: /* TODO: MMI_OPC_PSLLH */
27829 case MMI_OPC_PSRLH
: /* TODO: MMI_OPC_PSRLH */
27830 case MMI_OPC_PSRAH
: /* TODO: MMI_OPC_PSRAH */
27831 case MMI_OPC_PSLLW
: /* TODO: MMI_OPC_PSLLW */
27832 case MMI_OPC_PSRLW
: /* TODO: MMI_OPC_PSRLW */
27833 case MMI_OPC_PSRAW
: /* TODO: MMI_OPC_PSRAW */
27834 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_CLASS_MMI */
27837 MIPS_INVAL("TX79 MMI class");
27838 generate_exception_end(ctx
, EXCP_RI
);
27843 static void gen_mmi_lq(CPUMIPSState
*env
, DisasContext
*ctx
)
27845 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_LQ */
27848 static void gen_mmi_sq(DisasContext
*ctx
, int base
, int rt
, int offset
)
27850 generate_exception_end(ctx
, EXCP_RI
); /* TODO: MMI_OPC_SQ */
27854 * The TX79-specific instruction Store Quadword
27856 * +--------+-------+-------+------------------------+
27857 * | 011111 | base | rt | offset | SQ
27858 * +--------+-------+-------+------------------------+
27861 * has the same opcode as the Read Hardware Register instruction
27863 * +--------+-------+-------+-------+-------+--------+
27864 * | 011111 | 00000 | rt | rd | 00000 | 111011 | RDHWR
27865 * +--------+-------+-------+-------+-------+--------+
27868 * that is required, trapped and emulated by the Linux kernel. However, all
27869 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27870 * offset is odd. Therefore all valid SQ instructions can execute normally.
27871 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27872 * between SQ and RDHWR, as the Linux kernel does.
27874 static void decode_mmi_sq(CPUMIPSState
*env
, DisasContext
*ctx
)
27876 int base
= extract32(ctx
->opcode
, 21, 5);
27877 int rt
= extract32(ctx
->opcode
, 16, 5);
27878 int offset
= extract32(ctx
->opcode
, 0, 16);
27880 #ifdef CONFIG_USER_ONLY
27881 uint32_t op1
= MASK_SPECIAL3(ctx
->opcode
);
27882 uint32_t op2
= extract32(ctx
->opcode
, 6, 5);
27884 if (base
== 0 && op2
== 0 && op1
== OPC_RDHWR
) {
27885 int rd
= extract32(ctx
->opcode
, 11, 5);
27887 gen_rdhwr(ctx
, rt
, rd
, 0);
27892 gen_mmi_sq(ctx
, base
, rt
, offset
);
27897 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
27899 int rs
, rt
, rd
, sa
;
27903 rs
= (ctx
->opcode
>> 21) & 0x1f;
27904 rt
= (ctx
->opcode
>> 16) & 0x1f;
27905 rd
= (ctx
->opcode
>> 11) & 0x1f;
27906 sa
= (ctx
->opcode
>> 6) & 0x1f;
27907 imm
= sextract32(ctx
->opcode
, 7, 9);
27909 op1
= MASK_SPECIAL3(ctx
->opcode
);
27912 * EVA loads and stores overlap Loongson 2E instructions decoded by
27913 * decode_opc_special3_legacy(), so be careful to allow their decoding when
27920 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
27928 check_cp0_enabled(ctx
);
27929 gen_ld(ctx
, op1
, rt
, rs
, imm
);
27933 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
27938 check_cp0_enabled(ctx
);
27939 gen_st(ctx
, op1
, rt
, rs
, imm
);
27942 check_cp0_enabled(ctx
);
27943 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, true);
27946 check_cp0_enabled(ctx
);
27947 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
27948 gen_cache_operation(ctx
, rt
, rs
, imm
);
27950 /* Treat as NOP. */
27953 check_cp0_enabled(ctx
);
27954 /* Treat as NOP. */
27962 check_insn(ctx
, ISA_MIPS32R2
);
27963 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
27966 op2
= MASK_BSHFL(ctx
->opcode
);
27973 check_insn(ctx
, ISA_MIPS32R6
);
27974 decode_opc_special3_r6(env
, ctx
);
27977 check_insn(ctx
, ISA_MIPS32R2
);
27978 gen_bshfl(ctx
, op2
, rt
, rd
);
27982 #if defined(TARGET_MIPS64)
27989 check_insn(ctx
, ISA_MIPS64R2
);
27990 check_mips_64(ctx
);
27991 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
27994 op2
= MASK_DBSHFL(ctx
->opcode
);
28005 check_insn(ctx
, ISA_MIPS32R6
);
28006 decode_opc_special3_r6(env
, ctx
);
28009 check_insn(ctx
, ISA_MIPS64R2
);
28010 check_mips_64(ctx
);
28011 op2
= MASK_DBSHFL(ctx
->opcode
);
28012 gen_bshfl(ctx
, op2
, rt
, rd
);
28018 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
28023 TCGv t0
= tcg_temp_new();
28024 TCGv t1
= tcg_temp_new();
28026 gen_load_gpr(t0
, rt
);
28027 gen_load_gpr(t1
, rs
);
28028 gen_helper_fork(t0
, t1
);
28036 TCGv t0
= tcg_temp_new();
28038 gen_load_gpr(t0
, rs
);
28039 gen_helper_yield(t0
, cpu_env
, t0
);
28040 gen_store_gpr(t0
, rd
);
28045 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
28046 decode_opc_special3_r6(env
, ctx
);
28048 decode_opc_special3_legacy(env
, ctx
);
28053 /* MIPS SIMD Architecture (MSA) */
28054 static inline int check_msa_access(DisasContext
*ctx
)
28056 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
28057 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
28058 generate_exception_end(ctx
, EXCP_RI
);
28062 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
28063 if (ctx
->insn_flags
& ASE_MSA
) {
28064 generate_exception_end(ctx
, EXCP_MSADIS
);
28067 generate_exception_end(ctx
, EXCP_RI
);
28074 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
28076 /* generates tcg ops to check if any element is 0 */
28077 /* Note this function only works with MSA_WRLEN = 128 */
28078 uint64_t eval_zero_or_big
= 0;
28079 uint64_t eval_big
= 0;
28080 TCGv_i64 t0
= tcg_temp_new_i64();
28081 TCGv_i64 t1
= tcg_temp_new_i64();
28084 eval_zero_or_big
= 0x0101010101010101ULL
;
28085 eval_big
= 0x8080808080808080ULL
;
28088 eval_zero_or_big
= 0x0001000100010001ULL
;
28089 eval_big
= 0x8000800080008000ULL
;
28092 eval_zero_or_big
= 0x0000000100000001ULL
;
28093 eval_big
= 0x8000000080000000ULL
;
28096 eval_zero_or_big
= 0x0000000000000001ULL
;
28097 eval_big
= 0x8000000000000000ULL
;
28100 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<< 1], eval_zero_or_big
);
28101 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<< 1]);
28102 tcg_gen_andi_i64(t0
, t0
, eval_big
);
28103 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<< 1) + 1], eval_zero_or_big
);
28104 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<< 1) + 1]);
28105 tcg_gen_andi_i64(t1
, t1
, eval_big
);
28106 tcg_gen_or_i64(t0
, t0
, t1
);
28107 /* if all bits are zero then all elements are not zero */
28108 /* if some bit is non-zero then some element is zero */
28109 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
28110 tcg_gen_trunc_i64_tl(tresult
, t0
);
28111 tcg_temp_free_i64(t0
);
28112 tcg_temp_free_i64(t1
);
28115 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
28117 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28118 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28119 int64_t s16
= (int16_t)ctx
->opcode
;
28121 check_msa_access(ctx
);
28123 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
28124 generate_exception_end(ctx
, EXCP_RI
);
28131 TCGv_i64 t0
= tcg_temp_new_i64();
28132 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<< 1], msa_wr_d
[(wt
<< 1) + 1]);
28133 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
28134 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
28135 tcg_gen_trunc_i64_tl(bcond
, t0
);
28136 tcg_temp_free_i64(t0
);
28143 gen_check_zero_element(bcond
, df
, wt
);
28149 gen_check_zero_element(bcond
, df
, wt
);
28150 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
28154 ctx
->btarget
= ctx
->base
.pc_next
+ (s16
<< 2) + 4;
28156 ctx
->hflags
|= MIPS_HFLAG_BC
;
28157 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
28160 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
28162 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
28163 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
28164 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28165 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28167 TCGv_i32 twd
= tcg_const_i32(wd
);
28168 TCGv_i32 tws
= tcg_const_i32(ws
);
28169 TCGv_i32 ti8
= tcg_const_i32(i8
);
28171 switch (MASK_MSA_I8(ctx
->opcode
)) {
28173 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
28176 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
28179 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
28182 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
28185 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
28188 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
28191 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
28197 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
28198 if (df
== DF_DOUBLE
) {
28199 generate_exception_end(ctx
, EXCP_RI
);
28201 TCGv_i32 tdf
= tcg_const_i32(df
);
28202 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
28203 tcg_temp_free_i32(tdf
);
28208 MIPS_INVAL("MSA instruction");
28209 generate_exception_end(ctx
, EXCP_RI
);
28213 tcg_temp_free_i32(twd
);
28214 tcg_temp_free_i32(tws
);
28215 tcg_temp_free_i32(ti8
);
28218 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
28220 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28221 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28222 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
28223 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
28224 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28225 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28227 TCGv_i32 tdf
= tcg_const_i32(df
);
28228 TCGv_i32 twd
= tcg_const_i32(wd
);
28229 TCGv_i32 tws
= tcg_const_i32(ws
);
28230 TCGv_i32 timm
= tcg_temp_new_i32();
28231 tcg_gen_movi_i32(timm
, u5
);
28233 switch (MASK_MSA_I5(ctx
->opcode
)) {
28235 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28238 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28240 case OPC_MAXI_S_df
:
28241 tcg_gen_movi_i32(timm
, s5
);
28242 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28244 case OPC_MAXI_U_df
:
28245 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28247 case OPC_MINI_S_df
:
28248 tcg_gen_movi_i32(timm
, s5
);
28249 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28251 case OPC_MINI_U_df
:
28252 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28255 tcg_gen_movi_i32(timm
, s5
);
28256 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
28258 case OPC_CLTI_S_df
:
28259 tcg_gen_movi_i32(timm
, s5
);
28260 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28262 case OPC_CLTI_U_df
:
28263 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28265 case OPC_CLEI_S_df
:
28266 tcg_gen_movi_i32(timm
, s5
);
28267 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
28269 case OPC_CLEI_U_df
:
28270 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
28274 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
28275 tcg_gen_movi_i32(timm
, s10
);
28276 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
28280 MIPS_INVAL("MSA instruction");
28281 generate_exception_end(ctx
, EXCP_RI
);
28285 tcg_temp_free_i32(tdf
);
28286 tcg_temp_free_i32(twd
);
28287 tcg_temp_free_i32(tws
);
28288 tcg_temp_free_i32(timm
);
28291 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
28293 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28294 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
28295 uint32_t df
= 0, m
= 0;
28296 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28297 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28304 if ((dfm
& 0x40) == 0x00) {
28307 } else if ((dfm
& 0x60) == 0x40) {
28310 } else if ((dfm
& 0x70) == 0x60) {
28313 } else if ((dfm
& 0x78) == 0x70) {
28317 generate_exception_end(ctx
, EXCP_RI
);
28321 tdf
= tcg_const_i32(df
);
28322 tm
= tcg_const_i32(m
);
28323 twd
= tcg_const_i32(wd
);
28324 tws
= tcg_const_i32(ws
);
28326 switch (MASK_MSA_BIT(ctx
->opcode
)) {
28328 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28331 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
28334 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28337 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28340 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
28343 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
28345 case OPC_BINSLI_df
:
28346 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
28348 case OPC_BINSRI_df
:
28349 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28352 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
28355 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
28358 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
28361 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
28364 MIPS_INVAL("MSA instruction");
28365 generate_exception_end(ctx
, EXCP_RI
);
28369 tcg_temp_free_i32(tdf
);
28370 tcg_temp_free_i32(tm
);
28371 tcg_temp_free_i32(twd
);
28372 tcg_temp_free_i32(tws
);
28375 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
28377 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28378 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
28379 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
28380 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28381 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28383 TCGv_i32 tdf
= tcg_const_i32(df
);
28384 TCGv_i32 twd
= tcg_const_i32(wd
);
28385 TCGv_i32 tws
= tcg_const_i32(ws
);
28386 TCGv_i32 twt
= tcg_const_i32(wt
);
28388 switch (MASK_MSA_3R(ctx
->opcode
)) {
28392 gen_helper_msa_binsl_b(cpu_env
, twd
, tws
, twt
);
28395 gen_helper_msa_binsl_h(cpu_env
, twd
, tws
, twt
);
28398 gen_helper_msa_binsl_w(cpu_env
, twd
, tws
, twt
);
28401 gen_helper_msa_binsl_d(cpu_env
, twd
, tws
, twt
);
28408 gen_helper_msa_binsr_b(cpu_env
, twd
, tws
, twt
);
28411 gen_helper_msa_binsr_h(cpu_env
, twd
, tws
, twt
);
28414 gen_helper_msa_binsr_w(cpu_env
, twd
, tws
, twt
);
28417 gen_helper_msa_binsr_d(cpu_env
, twd
, tws
, twt
);
28424 gen_helper_msa_bclr_b(cpu_env
, twd
, tws
, twt
);
28427 gen_helper_msa_bclr_h(cpu_env
, twd
, tws
, twt
);
28430 gen_helper_msa_bclr_w(cpu_env
, twd
, tws
, twt
);
28433 gen_helper_msa_bclr_d(cpu_env
, twd
, tws
, twt
);
28440 gen_helper_msa_bneg_b(cpu_env
, twd
, tws
, twt
);
28443 gen_helper_msa_bneg_h(cpu_env
, twd
, tws
, twt
);
28446 gen_helper_msa_bneg_w(cpu_env
, twd
, tws
, twt
);
28449 gen_helper_msa_bneg_d(cpu_env
, twd
, tws
, twt
);
28456 gen_helper_msa_bset_b(cpu_env
, twd
, tws
, twt
);
28459 gen_helper_msa_bset_h(cpu_env
, twd
, tws
, twt
);
28462 gen_helper_msa_bset_w(cpu_env
, twd
, tws
, twt
);
28465 gen_helper_msa_bset_d(cpu_env
, twd
, tws
, twt
);
28472 gen_helper_msa_ave_s_b(cpu_env
, twd
, tws
, twt
);
28475 gen_helper_msa_ave_s_h(cpu_env
, twd
, tws
, twt
);
28478 gen_helper_msa_ave_s_w(cpu_env
, twd
, tws
, twt
);
28481 gen_helper_msa_ave_s_d(cpu_env
, twd
, tws
, twt
);
28488 gen_helper_msa_ave_u_b(cpu_env
, twd
, tws
, twt
);
28491 gen_helper_msa_ave_u_h(cpu_env
, twd
, tws
, twt
);
28494 gen_helper_msa_ave_u_w(cpu_env
, twd
, tws
, twt
);
28497 gen_helper_msa_ave_u_d(cpu_env
, twd
, tws
, twt
);
28501 case OPC_AVER_S_df
:
28504 gen_helper_msa_aver_s_b(cpu_env
, twd
, tws
, twt
);
28507 gen_helper_msa_aver_s_h(cpu_env
, twd
, tws
, twt
);
28510 gen_helper_msa_aver_s_w(cpu_env
, twd
, tws
, twt
);
28513 gen_helper_msa_aver_s_d(cpu_env
, twd
, tws
, twt
);
28517 case OPC_AVER_U_df
:
28520 gen_helper_msa_aver_u_b(cpu_env
, twd
, tws
, twt
);
28523 gen_helper_msa_aver_u_h(cpu_env
, twd
, tws
, twt
);
28526 gen_helper_msa_aver_u_w(cpu_env
, twd
, tws
, twt
);
28529 gen_helper_msa_aver_u_d(cpu_env
, twd
, tws
, twt
);
28536 gen_helper_msa_ceq_b(cpu_env
, twd
, tws
, twt
);
28539 gen_helper_msa_ceq_h(cpu_env
, twd
, tws
, twt
);
28542 gen_helper_msa_ceq_w(cpu_env
, twd
, tws
, twt
);
28545 gen_helper_msa_ceq_d(cpu_env
, twd
, tws
, twt
);
28552 gen_helper_msa_cle_s_b(cpu_env
, twd
, tws
, twt
);
28555 gen_helper_msa_cle_s_h(cpu_env
, twd
, tws
, twt
);
28558 gen_helper_msa_cle_s_w(cpu_env
, twd
, tws
, twt
);
28561 gen_helper_msa_cle_s_d(cpu_env
, twd
, tws
, twt
);
28568 gen_helper_msa_cle_u_b(cpu_env
, twd
, tws
, twt
);
28571 gen_helper_msa_cle_u_h(cpu_env
, twd
, tws
, twt
);
28574 gen_helper_msa_cle_u_w(cpu_env
, twd
, tws
, twt
);
28577 gen_helper_msa_cle_u_d(cpu_env
, twd
, tws
, twt
);
28584 gen_helper_msa_clt_s_b(cpu_env
, twd
, tws
, twt
);
28587 gen_helper_msa_clt_s_h(cpu_env
, twd
, tws
, twt
);
28590 gen_helper_msa_clt_s_w(cpu_env
, twd
, tws
, twt
);
28593 gen_helper_msa_clt_s_d(cpu_env
, twd
, tws
, twt
);
28600 gen_helper_msa_clt_u_b(cpu_env
, twd
, tws
, twt
);
28603 gen_helper_msa_clt_u_h(cpu_env
, twd
, tws
, twt
);
28606 gen_helper_msa_clt_u_w(cpu_env
, twd
, tws
, twt
);
28609 gen_helper_msa_clt_u_d(cpu_env
, twd
, tws
, twt
);
28616 gen_helper_msa_div_s_b(cpu_env
, twd
, tws
, twt
);
28619 gen_helper_msa_div_s_h(cpu_env
, twd
, tws
, twt
);
28622 gen_helper_msa_div_s_w(cpu_env
, twd
, tws
, twt
);
28625 gen_helper_msa_div_s_d(cpu_env
, twd
, tws
, twt
);
28632 gen_helper_msa_div_u_b(cpu_env
, twd
, tws
, twt
);
28635 gen_helper_msa_div_u_h(cpu_env
, twd
, tws
, twt
);
28638 gen_helper_msa_div_u_w(cpu_env
, twd
, tws
, twt
);
28641 gen_helper_msa_div_u_d(cpu_env
, twd
, tws
, twt
);
28648 gen_helper_msa_mod_s_b(cpu_env
, twd
, tws
, twt
);
28651 gen_helper_msa_mod_s_h(cpu_env
, twd
, tws
, twt
);
28654 gen_helper_msa_mod_s_w(cpu_env
, twd
, tws
, twt
);
28657 gen_helper_msa_mod_s_d(cpu_env
, twd
, tws
, twt
);
28664 gen_helper_msa_mod_u_b(cpu_env
, twd
, tws
, twt
);
28667 gen_helper_msa_mod_u_h(cpu_env
, twd
, tws
, twt
);
28670 gen_helper_msa_mod_u_w(cpu_env
, twd
, tws
, twt
);
28673 gen_helper_msa_mod_u_d(cpu_env
, twd
, tws
, twt
);
28678 gen_helper_msa_sll_df(cpu_env
, tdf
, twd
, tws
, twt
);
28681 gen_helper_msa_addv_df(cpu_env
, tdf
, twd
, tws
, twt
);
28684 gen_helper_msa_add_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
28686 case OPC_SUBS_S_df
:
28687 gen_helper_msa_subs_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28690 gen_helper_msa_mulv_df(cpu_env
, tdf
, twd
, tws
, twt
);
28693 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
28696 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
28699 gen_helper_msa_sra_df(cpu_env
, tdf
, twd
, tws
, twt
);
28702 gen_helper_msa_subv_df(cpu_env
, tdf
, twd
, tws
, twt
);
28704 case OPC_ADDS_A_df
:
28705 gen_helper_msa_adds_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
28707 case OPC_SUBS_U_df
:
28708 gen_helper_msa_subs_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28711 gen_helper_msa_maddv_df(cpu_env
, tdf
, twd
, tws
, twt
);
28714 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
28717 gen_helper_msa_srar_df(cpu_env
, tdf
, twd
, tws
, twt
);
28720 gen_helper_msa_srl_df(cpu_env
, tdf
, twd
, tws
, twt
);
28723 gen_helper_msa_max_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28725 case OPC_ADDS_S_df
:
28726 gen_helper_msa_adds_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28728 case OPC_SUBSUS_U_df
:
28729 gen_helper_msa_subsus_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28732 gen_helper_msa_msubv_df(cpu_env
, tdf
, twd
, tws
, twt
);
28735 gen_helper_msa_pckev_df(cpu_env
, tdf
, twd
, tws
, twt
);
28738 gen_helper_msa_srlr_df(cpu_env
, tdf
, twd
, tws
, twt
);
28741 gen_helper_msa_max_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28743 case OPC_ADDS_U_df
:
28744 gen_helper_msa_adds_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28746 case OPC_SUBSUU_S_df
:
28747 gen_helper_msa_subsuu_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28750 gen_helper_msa_pckod_df(cpu_env
, tdf
, twd
, tws
, twt
);
28753 gen_helper_msa_min_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28755 case OPC_ASUB_S_df
:
28756 gen_helper_msa_asub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28759 gen_helper_msa_ilvl_df(cpu_env
, tdf
, twd
, tws
, twt
);
28762 gen_helper_msa_min_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28764 case OPC_ASUB_U_df
:
28765 gen_helper_msa_asub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28768 gen_helper_msa_ilvr_df(cpu_env
, tdf
, twd
, tws
, twt
);
28771 gen_helper_msa_max_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
28774 gen_helper_msa_ilvev_df(cpu_env
, tdf
, twd
, tws
, twt
);
28777 gen_helper_msa_min_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
28780 gen_helper_msa_ilvod_df(cpu_env
, tdf
, twd
, tws
, twt
);
28783 case OPC_DOTP_S_df
:
28784 case OPC_DOTP_U_df
:
28785 case OPC_DPADD_S_df
:
28786 case OPC_DPADD_U_df
:
28787 case OPC_DPSUB_S_df
:
28788 case OPC_HADD_S_df
:
28789 case OPC_DPSUB_U_df
:
28790 case OPC_HADD_U_df
:
28791 case OPC_HSUB_S_df
:
28792 case OPC_HSUB_U_df
:
28793 if (df
== DF_BYTE
) {
28794 generate_exception_end(ctx
, EXCP_RI
);
28797 switch (MASK_MSA_3R(ctx
->opcode
)) {
28798 case OPC_DOTP_S_df
:
28799 gen_helper_msa_dotp_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28801 case OPC_DOTP_U_df
:
28802 gen_helper_msa_dotp_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28804 case OPC_DPADD_S_df
:
28805 gen_helper_msa_dpadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28807 case OPC_DPADD_U_df
:
28808 gen_helper_msa_dpadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28810 case OPC_DPSUB_S_df
:
28811 gen_helper_msa_dpsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28813 case OPC_HADD_S_df
:
28814 gen_helper_msa_hadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28816 case OPC_DPSUB_U_df
:
28817 gen_helper_msa_dpsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28819 case OPC_HADD_U_df
:
28820 gen_helper_msa_hadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28822 case OPC_HSUB_S_df
:
28823 gen_helper_msa_hsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
28825 case OPC_HSUB_U_df
:
28826 gen_helper_msa_hsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
28831 MIPS_INVAL("MSA instruction");
28832 generate_exception_end(ctx
, EXCP_RI
);
28835 tcg_temp_free_i32(twd
);
28836 tcg_temp_free_i32(tws
);
28837 tcg_temp_free_i32(twt
);
28838 tcg_temp_free_i32(tdf
);
28841 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
28843 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28844 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
28845 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
28846 TCGv telm
= tcg_temp_new();
28847 TCGv_i32 tsr
= tcg_const_i32(source
);
28848 TCGv_i32 tdt
= tcg_const_i32(dest
);
28850 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
28852 gen_load_gpr(telm
, source
);
28853 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
28856 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
28857 gen_store_gpr(telm
, dest
);
28860 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
28863 MIPS_INVAL("MSA instruction");
28864 generate_exception_end(ctx
, EXCP_RI
);
28868 tcg_temp_free(telm
);
28869 tcg_temp_free_i32(tdt
);
28870 tcg_temp_free_i32(tsr
);
28873 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
28876 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28877 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
28878 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
28880 TCGv_i32 tws
= tcg_const_i32(ws
);
28881 TCGv_i32 twd
= tcg_const_i32(wd
);
28882 TCGv_i32 tn
= tcg_const_i32(n
);
28883 TCGv_i32 tdf
= tcg_const_i32(df
);
28885 switch (MASK_MSA_ELM(ctx
->opcode
)) {
28887 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
28889 case OPC_SPLATI_df
:
28890 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
28893 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
28895 case OPC_COPY_S_df
:
28896 case OPC_COPY_U_df
:
28897 case OPC_INSERT_df
:
28898 #if !defined(TARGET_MIPS64)
28899 /* Double format valid only for MIPS64 */
28900 if (df
== DF_DOUBLE
) {
28901 generate_exception_end(ctx
, EXCP_RI
);
28904 if ((MASK_MSA_ELM(ctx
->opcode
) == OPC_COPY_U_df
) &&
28906 generate_exception_end(ctx
, EXCP_RI
);
28910 switch (MASK_MSA_ELM(ctx
->opcode
)) {
28911 case OPC_COPY_S_df
:
28912 if (likely(wd
!= 0)) {
28915 gen_helper_msa_copy_s_b(cpu_env
, twd
, tws
, tn
);
28918 gen_helper_msa_copy_s_h(cpu_env
, twd
, tws
, tn
);
28921 gen_helper_msa_copy_s_w(cpu_env
, twd
, tws
, tn
);
28923 #if defined(TARGET_MIPS64)
28925 gen_helper_msa_copy_s_d(cpu_env
, twd
, tws
, tn
);
28933 case OPC_COPY_U_df
:
28934 if (likely(wd
!= 0)) {
28937 gen_helper_msa_copy_u_b(cpu_env
, twd
, tws
, tn
);
28940 gen_helper_msa_copy_u_h(cpu_env
, twd
, tws
, tn
);
28942 #if defined(TARGET_MIPS64)
28944 gen_helper_msa_copy_u_w(cpu_env
, twd
, tws
, tn
);
28952 case OPC_INSERT_df
:
28955 gen_helper_msa_insert_b(cpu_env
, twd
, tws
, tn
);
28958 gen_helper_msa_insert_h(cpu_env
, twd
, tws
, tn
);
28961 gen_helper_msa_insert_w(cpu_env
, twd
, tws
, tn
);
28963 #if defined(TARGET_MIPS64)
28965 gen_helper_msa_insert_d(cpu_env
, twd
, tws
, tn
);
28975 MIPS_INVAL("MSA instruction");
28976 generate_exception_end(ctx
, EXCP_RI
);
28978 tcg_temp_free_i32(twd
);
28979 tcg_temp_free_i32(tws
);
28980 tcg_temp_free_i32(tn
);
28981 tcg_temp_free_i32(tdf
);
28984 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
28986 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
28987 uint32_t df
= 0, n
= 0;
28989 if ((dfn
& 0x30) == 0x00) {
28992 } else if ((dfn
& 0x38) == 0x20) {
28995 } else if ((dfn
& 0x3c) == 0x30) {
28998 } else if ((dfn
& 0x3e) == 0x38) {
29001 } else if (dfn
== 0x3E) {
29002 /* CTCMSA, CFCMSA, MOVE.V */
29003 gen_msa_elm_3e(env
, ctx
);
29006 generate_exception_end(ctx
, EXCP_RI
);
29010 gen_msa_elm_df(env
, ctx
, df
, n
);
29013 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
29015 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
29016 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
29017 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29018 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29019 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29021 TCGv_i32 twd
= tcg_const_i32(wd
);
29022 TCGv_i32 tws
= tcg_const_i32(ws
);
29023 TCGv_i32 twt
= tcg_const_i32(wt
);
29024 TCGv_i32 tdf
= tcg_temp_new_i32();
29026 /* adjust df value for floating-point instruction */
29027 tcg_gen_movi_i32(tdf
, df
+ 2);
29029 switch (MASK_MSA_3RF(ctx
->opcode
)) {
29031 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29034 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
29037 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
29040 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
29043 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
29046 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29049 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
29052 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
29055 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29058 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
29061 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
29064 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
29067 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
29070 tcg_gen_movi_i32(tdf
, df
+ 1);
29071 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29074 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
29077 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
29079 case OPC_MADD_Q_df
:
29080 tcg_gen_movi_i32(tdf
, df
+ 1);
29081 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29084 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
29086 case OPC_MSUB_Q_df
:
29087 tcg_gen_movi_i32(tdf
, df
+ 1);
29088 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29091 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
29094 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
29097 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
29100 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
29103 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
29106 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
29109 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29112 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29115 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
29118 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
29121 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
29124 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
29127 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
29129 case OPC_MULR_Q_df
:
29130 tcg_gen_movi_i32(tdf
, df
+ 1);
29131 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29134 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
29136 case OPC_FMIN_A_df
:
29137 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
29139 case OPC_MADDR_Q_df
:
29140 tcg_gen_movi_i32(tdf
, df
+ 1);
29141 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29144 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
29147 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
29149 case OPC_MSUBR_Q_df
:
29150 tcg_gen_movi_i32(tdf
, df
+ 1);
29151 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
29154 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
29156 case OPC_FMAX_A_df
:
29157 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
29160 MIPS_INVAL("MSA instruction");
29161 generate_exception_end(ctx
, EXCP_RI
);
29165 tcg_temp_free_i32(twd
);
29166 tcg_temp_free_i32(tws
);
29167 tcg_temp_free_i32(twt
);
29168 tcg_temp_free_i32(tdf
);
29171 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
29173 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29174 (op & (0x7 << 18)))
29175 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29176 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29177 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29178 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
29179 TCGv_i32 twd
= tcg_const_i32(wd
);
29180 TCGv_i32 tws
= tcg_const_i32(ws
);
29181 TCGv_i32 twt
= tcg_const_i32(wt
);
29182 TCGv_i32 tdf
= tcg_const_i32(df
);
29184 switch (MASK_MSA_2R(ctx
->opcode
)) {
29186 #if !defined(TARGET_MIPS64)
29187 /* Double format valid only for MIPS64 */
29188 if (df
== DF_DOUBLE
) {
29189 generate_exception_end(ctx
, EXCP_RI
);
29193 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
29198 gen_helper_msa_nloc_b(cpu_env
, twd
, tws
);
29201 gen_helper_msa_nloc_h(cpu_env
, twd
, tws
);
29204 gen_helper_msa_nloc_w(cpu_env
, twd
, tws
);
29207 gen_helper_msa_nloc_d(cpu_env
, twd
, tws
);
29214 gen_helper_msa_nlzc_b(cpu_env
, twd
, tws
);
29217 gen_helper_msa_nlzc_h(cpu_env
, twd
, tws
);
29220 gen_helper_msa_nlzc_w(cpu_env
, twd
, tws
);
29223 gen_helper_msa_nlzc_d(cpu_env
, twd
, tws
);
29230 gen_helper_msa_pcnt_b(cpu_env
, twd
, tws
);
29233 gen_helper_msa_pcnt_h(cpu_env
, twd
, tws
);
29236 gen_helper_msa_pcnt_w(cpu_env
, twd
, tws
);
29239 gen_helper_msa_pcnt_d(cpu_env
, twd
, tws
);
29244 MIPS_INVAL("MSA instruction");
29245 generate_exception_end(ctx
, EXCP_RI
);
29249 tcg_temp_free_i32(twd
);
29250 tcg_temp_free_i32(tws
);
29251 tcg_temp_free_i32(twt
);
29252 tcg_temp_free_i32(tdf
);
29255 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
29257 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
29258 (op & (0xf << 17)))
29259 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29260 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29261 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29262 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
29263 TCGv_i32 twd
= tcg_const_i32(wd
);
29264 TCGv_i32 tws
= tcg_const_i32(ws
);
29265 TCGv_i32 twt
= tcg_const_i32(wt
);
29266 /* adjust df value for floating-point instruction */
29267 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
29269 switch (MASK_MSA_2RF(ctx
->opcode
)) {
29270 case OPC_FCLASS_df
:
29271 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
29273 case OPC_FTRUNC_S_df
:
29274 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
29276 case OPC_FTRUNC_U_df
:
29277 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
29280 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
29282 case OPC_FRSQRT_df
:
29283 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
29286 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
29289 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
29292 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
29294 case OPC_FEXUPL_df
:
29295 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
29297 case OPC_FEXUPR_df
:
29298 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
29301 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
29304 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
29306 case OPC_FTINT_S_df
:
29307 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
29309 case OPC_FTINT_U_df
:
29310 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
29312 case OPC_FFINT_S_df
:
29313 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
29315 case OPC_FFINT_U_df
:
29316 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
29320 tcg_temp_free_i32(twd
);
29321 tcg_temp_free_i32(tws
);
29322 tcg_temp_free_i32(twt
);
29323 tcg_temp_free_i32(tdf
);
29326 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
29328 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
29329 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
29330 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
29331 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29332 TCGv_i32 twd
= tcg_const_i32(wd
);
29333 TCGv_i32 tws
= tcg_const_i32(ws
);
29334 TCGv_i32 twt
= tcg_const_i32(wt
);
29336 switch (MASK_MSA_VEC(ctx
->opcode
)) {
29338 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
29341 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
29344 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
29347 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
29350 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
29353 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
29356 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
29359 MIPS_INVAL("MSA instruction");
29360 generate_exception_end(ctx
, EXCP_RI
);
29364 tcg_temp_free_i32(twd
);
29365 tcg_temp_free_i32(tws
);
29366 tcg_temp_free_i32(twt
);
29369 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
29371 switch (MASK_MSA_VEC(ctx
->opcode
)) {
29379 gen_msa_vec_v(env
, ctx
);
29382 gen_msa_2r(env
, ctx
);
29385 gen_msa_2rf(env
, ctx
);
29388 MIPS_INVAL("MSA instruction");
29389 generate_exception_end(ctx
, EXCP_RI
);
29394 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
29396 uint32_t opcode
= ctx
->opcode
;
29397 check_insn(ctx
, ASE_MSA
);
29398 check_msa_access(ctx
);
29400 switch (MASK_MSA_MINOR(opcode
)) {
29401 case OPC_MSA_I8_00
:
29402 case OPC_MSA_I8_01
:
29403 case OPC_MSA_I8_02
:
29404 gen_msa_i8(env
, ctx
);
29406 case OPC_MSA_I5_06
:
29407 case OPC_MSA_I5_07
:
29408 gen_msa_i5(env
, ctx
);
29410 case OPC_MSA_BIT_09
:
29411 case OPC_MSA_BIT_0A
:
29412 gen_msa_bit(env
, ctx
);
29414 case OPC_MSA_3R_0D
:
29415 case OPC_MSA_3R_0E
:
29416 case OPC_MSA_3R_0F
:
29417 case OPC_MSA_3R_10
:
29418 case OPC_MSA_3R_11
:
29419 case OPC_MSA_3R_12
:
29420 case OPC_MSA_3R_13
:
29421 case OPC_MSA_3R_14
:
29422 case OPC_MSA_3R_15
:
29423 gen_msa_3r(env
, ctx
);
29426 gen_msa_elm(env
, ctx
);
29428 case OPC_MSA_3RF_1A
:
29429 case OPC_MSA_3RF_1B
:
29430 case OPC_MSA_3RF_1C
:
29431 gen_msa_3rf(env
, ctx
);
29434 gen_msa_vec(env
, ctx
);
29445 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
29446 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
29447 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
29448 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
29450 TCGv_i32 twd
= tcg_const_i32(wd
);
29451 TCGv taddr
= tcg_temp_new();
29452 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
29454 switch (MASK_MSA_MINOR(opcode
)) {
29456 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
29459 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
29462 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
29465 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
29468 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
29471 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
29474 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
29477 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
29481 tcg_temp_free_i32(twd
);
29482 tcg_temp_free(taddr
);
29486 MIPS_INVAL("MSA instruction");
29487 generate_exception_end(ctx
, EXCP_RI
);
29493 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
29496 int rs
, rt
, rd
, sa
;
29500 /* make sure instructions are on a word boundary */
29501 if (ctx
->base
.pc_next
& 0x3) {
29502 env
->CP0_BadVAddr
= ctx
->base
.pc_next
;
29503 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
29507 /* Handle blikely not taken case */
29508 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
29509 TCGLabel
*l1
= gen_new_label();
29511 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
29512 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
29513 gen_goto_tb(ctx
, 1, ctx
->base
.pc_next
+ 4);
29517 op
= MASK_OP_MAJOR(ctx
->opcode
);
29518 rs
= (ctx
->opcode
>> 21) & 0x1f;
29519 rt
= (ctx
->opcode
>> 16) & 0x1f;
29520 rd
= (ctx
->opcode
>> 11) & 0x1f;
29521 sa
= (ctx
->opcode
>> 6) & 0x1f;
29522 imm
= (int16_t)ctx
->opcode
;
29525 decode_opc_special(env
, ctx
);
29528 #if defined(TARGET_MIPS64)
29529 if ((ctx
->insn_flags
& INSN_R5900
) && (ctx
->insn_flags
& ASE_MMI
)) {
29530 decode_mmi(env
, ctx
);
29532 if (ctx
->insn_flags
& ASE_MXU
) {
29533 decode_opc_mxu(env
, ctx
);
29536 decode_opc_special2_legacy(env
, ctx
);
29540 #if defined(TARGET_MIPS64)
29541 if (ctx
->insn_flags
& INSN_R5900
) {
29542 decode_mmi_sq(env
, ctx
); /* MMI_OPC_SQ */
29544 decode_opc_special3(env
, ctx
);
29547 decode_opc_special3(env
, ctx
);
29551 op1
= MASK_REGIMM(ctx
->opcode
);
29553 case OPC_BLTZL
: /* REGIMM branches */
29557 check_insn(ctx
, ISA_MIPS2
);
29558 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
29562 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
29566 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
29568 /* OPC_NAL, OPC_BAL */
29569 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
29571 generate_exception_end(ctx
, EXCP_RI
);
29574 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
29577 case OPC_TGEI
: /* REGIMM traps */
29584 check_insn(ctx
, ISA_MIPS2
);
29585 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
29586 gen_trap(ctx
, op1
, rs
, -1, imm
);
29589 check_insn(ctx
, ISA_MIPS32R6
);
29590 generate_exception_end(ctx
, EXCP_RI
);
29593 check_insn(ctx
, ISA_MIPS32R2
);
29595 * Break the TB to be able to sync copied instructions
29598 ctx
->base
.is_jmp
= DISAS_STOP
;
29600 case OPC_BPOSGE32
: /* MIPS DSP branch */
29601 #if defined(TARGET_MIPS64)
29605 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
29607 #if defined(TARGET_MIPS64)
29609 check_insn(ctx
, ISA_MIPS32R6
);
29610 check_mips_64(ctx
);
29612 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
29616 check_insn(ctx
, ISA_MIPS32R6
);
29617 check_mips_64(ctx
);
29619 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
29623 default: /* Invalid */
29624 MIPS_INVAL("regimm");
29625 generate_exception_end(ctx
, EXCP_RI
);
29630 check_cp0_enabled(ctx
);
29631 op1
= MASK_CP0(ctx
->opcode
);
29639 #if defined(TARGET_MIPS64)
29643 #ifndef CONFIG_USER_ONLY
29644 gen_cp0(env
, ctx
, op1
, rt
, rd
);
29645 #endif /* !CONFIG_USER_ONLY */
29663 #ifndef CONFIG_USER_ONLY
29664 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
29665 #endif /* !CONFIG_USER_ONLY */
29668 #ifndef CONFIG_USER_ONLY
29671 TCGv t0
= tcg_temp_new();
29673 op2
= MASK_MFMC0(ctx
->opcode
);
29677 gen_helper_dmt(t0
);
29678 gen_store_gpr(t0
, rt
);
29682 gen_helper_emt(t0
);
29683 gen_store_gpr(t0
, rt
);
29687 gen_helper_dvpe(t0
, cpu_env
);
29688 gen_store_gpr(t0
, rt
);
29692 gen_helper_evpe(t0
, cpu_env
);
29693 gen_store_gpr(t0
, rt
);
29696 check_insn(ctx
, ISA_MIPS32R6
);
29698 gen_helper_dvp(t0
, cpu_env
);
29699 gen_store_gpr(t0
, rt
);
29703 check_insn(ctx
, ISA_MIPS32R6
);
29705 gen_helper_evp(t0
, cpu_env
);
29706 gen_store_gpr(t0
, rt
);
29710 check_insn(ctx
, ISA_MIPS32R2
);
29711 save_cpu_state(ctx
, 1);
29712 gen_helper_di(t0
, cpu_env
);
29713 gen_store_gpr(t0
, rt
);
29715 * Stop translation as we may have switched
29716 * the execution mode.
29718 ctx
->base
.is_jmp
= DISAS_STOP
;
29721 check_insn(ctx
, ISA_MIPS32R2
);
29722 save_cpu_state(ctx
, 1);
29723 gen_helper_ei(t0
, cpu_env
);
29724 gen_store_gpr(t0
, rt
);
29726 * DISAS_STOP isn't sufficient, we need to ensure we break
29727 * out of translated code to check for pending interrupts.
29729 gen_save_pc(ctx
->base
.pc_next
+ 4);
29730 ctx
->base
.is_jmp
= DISAS_EXIT
;
29732 default: /* Invalid */
29733 MIPS_INVAL("mfmc0");
29734 generate_exception_end(ctx
, EXCP_RI
);
29739 #endif /* !CONFIG_USER_ONLY */
29742 check_insn(ctx
, ISA_MIPS32R2
);
29743 gen_load_srsgpr(rt
, rd
);
29746 check_insn(ctx
, ISA_MIPS32R2
);
29747 gen_store_srsgpr(rt
, rd
);
29751 generate_exception_end(ctx
, EXCP_RI
);
29755 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29756 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
29757 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29758 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
29761 /* Arithmetic with immediate opcode */
29762 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
29766 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
29768 case OPC_SLTI
: /* Set on less than with immediate opcode */
29770 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
29772 case OPC_ANDI
: /* Arithmetic with immediate opcode */
29773 case OPC_LUI
: /* OPC_AUI */
29776 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
29778 case OPC_J
: /* Jump */
29780 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
29781 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
29784 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29785 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
29787 generate_exception_end(ctx
, EXCP_RI
);
29790 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29791 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
29794 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
29797 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29798 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
29800 generate_exception_end(ctx
, EXCP_RI
);
29803 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29804 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
29807 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
29810 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29813 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
29815 check_insn(ctx
, ISA_MIPS32R6
);
29816 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29817 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
29820 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29823 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
29825 check_insn(ctx
, ISA_MIPS32R6
);
29826 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29827 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
29832 check_insn(ctx
, ISA_MIPS2
);
29833 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
29837 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
29839 case OPC_LL
: /* Load and stores */
29840 check_insn(ctx
, ISA_MIPS2
);
29841 if (ctx
->insn_flags
& INSN_R5900
) {
29842 check_insn_opc_user_only(ctx
, INSN_R5900
);
29847 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
29855 gen_ld(ctx
, op
, rt
, rs
, imm
);
29859 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
29864 gen_st(ctx
, op
, rt
, rs
, imm
);
29867 check_insn(ctx
, ISA_MIPS2
);
29868 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
29869 if (ctx
->insn_flags
& INSN_R5900
) {
29870 check_insn_opc_user_only(ctx
, INSN_R5900
);
29872 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TESL
, false);
29875 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
29876 check_cp0_enabled(ctx
);
29877 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
29878 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
29879 gen_cache_operation(ctx
, rt
, rs
, imm
);
29881 /* Treat as NOP. */
29884 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
29885 if (ctx
->insn_flags
& INSN_R5900
) {
29886 /* Treat as NOP. */
29888 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
29889 /* Treat as NOP. */
29893 /* Floating point (COP1). */
29898 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
29902 op1
= MASK_CP1(ctx
->opcode
);
29907 check_cp1_enabled(ctx
);
29908 check_insn(ctx
, ISA_MIPS32R2
);
29914 check_cp1_enabled(ctx
);
29915 gen_cp1(ctx
, op1
, rt
, rd
);
29917 #if defined(TARGET_MIPS64)
29920 check_cp1_enabled(ctx
);
29921 check_insn(ctx
, ISA_MIPS3
);
29922 check_mips_64(ctx
);
29923 gen_cp1(ctx
, op1
, rt
, rd
);
29926 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
29927 check_cp1_enabled(ctx
);
29928 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
29930 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
29935 check_insn(ctx
, ASE_MIPS3D
);
29936 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
29937 (rt
>> 2) & 0x7, imm
<< 2);
29941 check_cp1_enabled(ctx
);
29942 check_insn(ctx
, ISA_MIPS32R6
);
29943 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
29947 check_cp1_enabled(ctx
);
29948 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
29950 check_insn(ctx
, ASE_MIPS3D
);
29953 check_cp1_enabled(ctx
);
29954 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
29955 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
29956 (rt
>> 2) & 0x7, imm
<< 2);
29963 check_cp1_enabled(ctx
);
29964 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
29970 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
29971 check_cp1_enabled(ctx
);
29972 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
29974 case R6_OPC_CMP_AF_S
:
29975 case R6_OPC_CMP_UN_S
:
29976 case R6_OPC_CMP_EQ_S
:
29977 case R6_OPC_CMP_UEQ_S
:
29978 case R6_OPC_CMP_LT_S
:
29979 case R6_OPC_CMP_ULT_S
:
29980 case R6_OPC_CMP_LE_S
:
29981 case R6_OPC_CMP_ULE_S
:
29982 case R6_OPC_CMP_SAF_S
:
29983 case R6_OPC_CMP_SUN_S
:
29984 case R6_OPC_CMP_SEQ_S
:
29985 case R6_OPC_CMP_SEUQ_S
:
29986 case R6_OPC_CMP_SLT_S
:
29987 case R6_OPC_CMP_SULT_S
:
29988 case R6_OPC_CMP_SLE_S
:
29989 case R6_OPC_CMP_SULE_S
:
29990 case R6_OPC_CMP_OR_S
:
29991 case R6_OPC_CMP_UNE_S
:
29992 case R6_OPC_CMP_NE_S
:
29993 case R6_OPC_CMP_SOR_S
:
29994 case R6_OPC_CMP_SUNE_S
:
29995 case R6_OPC_CMP_SNE_S
:
29996 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
29998 case R6_OPC_CMP_AF_D
:
29999 case R6_OPC_CMP_UN_D
:
30000 case R6_OPC_CMP_EQ_D
:
30001 case R6_OPC_CMP_UEQ_D
:
30002 case R6_OPC_CMP_LT_D
:
30003 case R6_OPC_CMP_ULT_D
:
30004 case R6_OPC_CMP_LE_D
:
30005 case R6_OPC_CMP_ULE_D
:
30006 case R6_OPC_CMP_SAF_D
:
30007 case R6_OPC_CMP_SUN_D
:
30008 case R6_OPC_CMP_SEQ_D
:
30009 case R6_OPC_CMP_SEUQ_D
:
30010 case R6_OPC_CMP_SLT_D
:
30011 case R6_OPC_CMP_SULT_D
:
30012 case R6_OPC_CMP_SLE_D
:
30013 case R6_OPC_CMP_SULE_D
:
30014 case R6_OPC_CMP_OR_D
:
30015 case R6_OPC_CMP_UNE_D
:
30016 case R6_OPC_CMP_NE_D
:
30017 case R6_OPC_CMP_SOR_D
:
30018 case R6_OPC_CMP_SUNE_D
:
30019 case R6_OPC_CMP_SNE_D
:
30020 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
30023 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
30024 rt
, rd
, sa
, (imm
>> 8) & 0x7);
30029 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
30044 check_insn(ctx
, ASE_MSA
);
30045 gen_msa_branch(env
, ctx
, op1
);
30049 generate_exception_end(ctx
, EXCP_RI
);
30054 /* Compact branches [R6] and COP2 [non-R6] */
30055 case OPC_BC
: /* OPC_LWC2 */
30056 case OPC_BALC
: /* OPC_SWC2 */
30057 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30058 /* OPC_BC, OPC_BALC */
30059 gen_compute_compact_branch(ctx
, op
, 0, 0,
30060 sextract32(ctx
->opcode
<< 2, 0, 28));
30062 /* OPC_LWC2, OPC_SWC2 */
30063 /* COP2: Not implemented. */
30064 generate_exception_err(ctx
, EXCP_CpU
, 2);
30067 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
30068 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
30069 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30071 /* OPC_BEQZC, OPC_BNEZC */
30072 gen_compute_compact_branch(ctx
, op
, rs
, 0,
30073 sextract32(ctx
->opcode
<< 2, 0, 23));
30075 /* OPC_JIC, OPC_JIALC */
30076 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
30079 /* OPC_LWC2, OPC_SWC2 */
30080 /* COP2: Not implemented. */
30081 generate_exception_err(ctx
, EXCP_CpU
, 2);
30085 check_insn(ctx
, INSN_LOONGSON2F
);
30086 /* Note that these instructions use different fields. */
30087 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
30091 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30092 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
30093 check_cp1_enabled(ctx
);
30094 op1
= MASK_CP3(ctx
->opcode
);
30098 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
30104 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30105 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
30108 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30109 /* Treat as NOP. */
30112 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
30126 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
30127 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
30131 generate_exception_end(ctx
, EXCP_RI
);
30135 generate_exception_err(ctx
, EXCP_CpU
, 1);
30139 #if defined(TARGET_MIPS64)
30140 /* MIPS64 opcodes */
30142 if (ctx
->insn_flags
& INSN_R5900
) {
30143 check_insn_opc_user_only(ctx
, INSN_R5900
);
30148 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30152 check_insn(ctx
, ISA_MIPS3
);
30153 check_mips_64(ctx
);
30154 gen_ld(ctx
, op
, rt
, rs
, imm
);
30158 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30161 check_insn(ctx
, ISA_MIPS3
);
30162 check_mips_64(ctx
);
30163 gen_st(ctx
, op
, rt
, rs
, imm
);
30166 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
30167 check_insn(ctx
, ISA_MIPS3
);
30168 if (ctx
->insn_flags
& INSN_R5900
) {
30169 check_insn_opc_user_only(ctx
, INSN_R5900
);
30171 check_mips_64(ctx
);
30172 gen_st_cond(ctx
, rt
, rs
, imm
, MO_TEQ
, false);
30174 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
30175 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30176 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
30177 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30180 check_insn(ctx
, ISA_MIPS3
);
30181 check_mips_64(ctx
);
30182 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30186 check_insn(ctx
, ISA_MIPS3
);
30187 check_mips_64(ctx
);
30188 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
30191 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
30192 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30193 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
30195 MIPS_INVAL("major opcode");
30196 generate_exception_end(ctx
, EXCP_RI
);
30200 case OPC_DAUI
: /* OPC_JALX */
30201 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
30202 #if defined(TARGET_MIPS64)
30204 check_mips_64(ctx
);
30206 generate_exception(ctx
, EXCP_RI
);
30207 } else if (rt
!= 0) {
30208 TCGv t0
= tcg_temp_new();
30209 gen_load_gpr(t0
, rs
);
30210 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
30214 generate_exception_end(ctx
, EXCP_RI
);
30215 MIPS_INVAL("major opcode");
30219 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
30220 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
30221 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
30224 case OPC_MSA
: /* OPC_MDMX */
30225 if (ctx
->insn_flags
& INSN_R5900
) {
30226 #if defined(TARGET_MIPS64)
30227 gen_mmi_lq(env
, ctx
); /* MMI_OPC_LQ */
30230 /* MDMX: Not implemented. */
30235 check_insn(ctx
, ISA_MIPS32R6
);
30236 gen_pcrel(ctx
, ctx
->opcode
, ctx
->base
.pc_next
, rs
);
30238 default: /* Invalid */
30239 MIPS_INVAL("major opcode");
30240 generate_exception_end(ctx
, EXCP_RI
);
30245 static void mips_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
30247 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30248 CPUMIPSState
*env
= cs
->env_ptr
;
30250 ctx
->page_start
= ctx
->base
.pc_first
& TARGET_PAGE_MASK
;
30251 ctx
->saved_pc
= -1;
30252 ctx
->insn_flags
= env
->insn_flags
;
30253 ctx
->CP0_Config1
= env
->CP0_Config1
;
30254 ctx
->CP0_Config2
= env
->CP0_Config2
;
30255 ctx
->CP0_Config3
= env
->CP0_Config3
;
30256 ctx
->CP0_Config5
= env
->CP0_Config5
;
30258 ctx
->kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
30259 ctx
->rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
30260 ctx
->ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
30261 ctx
->bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
30262 ctx
->bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
30263 ctx
->PAMask
= env
->PAMask
;
30264 ctx
->mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
30265 ctx
->eva
= (env
->CP0_Config5
>> CP0C5_EVA
) & 1;
30266 ctx
->sc
= (env
->CP0_Config3
>> CP0C3_SC
) & 1;
30267 ctx
->CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
30268 ctx
->cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
30269 /* Restore delay slot state from the tb context. */
30270 ctx
->hflags
= (uint32_t)ctx
->base
.tb
->flags
; /* FIXME: maybe use 64 bits? */
30271 ctx
->ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
30272 ctx
->ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
30273 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
30274 ctx
->vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
30275 ctx
->mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
30276 ctx
->nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
30277 ctx
->abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
30278 restore_cpu_state(env
, ctx
);
30279 #ifdef CONFIG_USER_ONLY
30280 ctx
->mem_idx
= MIPS_HFLAG_UM
;
30282 ctx
->mem_idx
= hflags_mmu_index(ctx
->hflags
);
30284 ctx
->default_tcg_memop_mask
= (ctx
->insn_flags
& ISA_MIPS32R6
) ?
30285 MO_UNALN
: MO_ALIGN
;
30287 LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx
->base
.tb
, ctx
->mem_idx
,
30291 static void mips_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cs
)
30295 static void mips_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cs
)
30297 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30299 tcg_gen_insn_start(ctx
->base
.pc_next
, ctx
->hflags
& MIPS_HFLAG_BMASK
,
30303 static bool mips_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cs
,
30304 const CPUBreakpoint
*bp
)
30306 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30308 save_cpu_state(ctx
, 1);
30309 ctx
->base
.is_jmp
= DISAS_NORETURN
;
30310 gen_helper_raise_exception_debug(cpu_env
);
30312 * The address covered by the breakpoint must be included in
30313 * [tb->pc, tb->pc + tb->size) in order to for it to be
30314 * properly cleared -- thus we increment the PC here so that
30315 * the logic setting tb->size below does the right thing.
30317 ctx
->base
.pc_next
+= 4;
30321 static void mips_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cs
)
30323 CPUMIPSState
*env
= cs
->env_ptr
;
30324 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30328 is_slot
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
30329 if (ctx
->insn_flags
& ISA_NANOMIPS32
) {
30330 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30331 insn_bytes
= decode_nanomips_opc(env
, ctx
);
30332 } else if (!(ctx
->hflags
& MIPS_HFLAG_M16
)) {
30333 ctx
->opcode
= cpu_ldl_code(env
, ctx
->base
.pc_next
);
30335 decode_opc(env
, ctx
);
30336 } else if (ctx
->insn_flags
& ASE_MICROMIPS
) {
30337 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30338 insn_bytes
= decode_micromips_opc(env
, ctx
);
30339 } else if (ctx
->insn_flags
& ASE_MIPS16
) {
30340 ctx
->opcode
= cpu_lduw_code(env
, ctx
->base
.pc_next
);
30341 insn_bytes
= decode_mips16_opc(env
, ctx
);
30343 generate_exception_end(ctx
, EXCP_RI
);
30344 g_assert(ctx
->base
.is_jmp
== DISAS_NORETURN
);
30348 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
30349 if (!(ctx
->hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
30350 MIPS_HFLAG_FBNSLOT
))) {
30352 * Force to generate branch as there is neither delay nor
30357 if ((ctx
->hflags
& MIPS_HFLAG_M16
) &&
30358 (ctx
->hflags
& MIPS_HFLAG_FBNSLOT
)) {
30360 * Force to generate branch as microMIPS R6 doesn't restrict
30361 * branches in the forbidden slot.
30367 gen_branch(ctx
, insn_bytes
);
30369 ctx
->base
.pc_next
+= insn_bytes
;
30371 if (ctx
->base
.is_jmp
!= DISAS_NEXT
) {
30375 * Execute a branch and its delay slot as a single instruction.
30376 * This is what GDB expects and is consistent with what the
30377 * hardware does (e.g. if a delay slot instruction faults, the
30378 * reported PC is the PC of the branch).
30380 if (ctx
->base
.singlestep_enabled
&&
30381 (ctx
->hflags
& MIPS_HFLAG_BMASK
) == 0) {
30382 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
30384 if (ctx
->base
.pc_next
- ctx
->page_start
>= TARGET_PAGE_SIZE
) {
30385 ctx
->base
.is_jmp
= DISAS_TOO_MANY
;
30389 static void mips_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cs
)
30391 DisasContext
*ctx
= container_of(dcbase
, DisasContext
, base
);
30393 if (ctx
->base
.singlestep_enabled
&& ctx
->base
.is_jmp
!= DISAS_NORETURN
) {
30394 save_cpu_state(ctx
, ctx
->base
.is_jmp
!= DISAS_EXIT
);
30395 gen_helper_raise_exception_debug(cpu_env
);
30397 switch (ctx
->base
.is_jmp
) {
30399 gen_save_pc(ctx
->base
.pc_next
);
30400 tcg_gen_lookup_and_goto_ptr();
30403 case DISAS_TOO_MANY
:
30404 save_cpu_state(ctx
, 0);
30405 gen_goto_tb(ctx
, 0, ctx
->base
.pc_next
);
30408 tcg_gen_exit_tb(NULL
, 0);
30410 case DISAS_NORETURN
:
30413 g_assert_not_reached();
30418 static void mips_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cs
)
30420 qemu_log("IN: %s\n", lookup_symbol(dcbase
->pc_first
));
30421 log_target_disas(cs
, dcbase
->pc_first
, dcbase
->tb
->size
);
30424 static const TranslatorOps mips_tr_ops
= {
30425 .init_disas_context
= mips_tr_init_disas_context
,
30426 .tb_start
= mips_tr_tb_start
,
30427 .insn_start
= mips_tr_insn_start
,
30428 .breakpoint_check
= mips_tr_breakpoint_check
,
30429 .translate_insn
= mips_tr_translate_insn
,
30430 .tb_stop
= mips_tr_tb_stop
,
30431 .disas_log
= mips_tr_disas_log
,
30434 void gen_intermediate_code(CPUState
*cs
, TranslationBlock
*tb
, int max_insns
)
30438 translator_loop(&mips_tr_ops
, &ctx
.base
, cs
, tb
, max_insns
);
30441 static void fpu_dump_state(CPUMIPSState
*env
, FILE * f
, int flags
)
30444 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
30446 #define printfpr(fp) \
30449 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
30450 " fd:%13g fs:%13g psu: %13g\n", \
30451 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
30452 (double)(fp)->fd, \
30453 (double)(fp)->fs[FP_ENDIAN_IDX], \
30454 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
30457 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
30458 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
30459 qemu_fprintf(f, "w:%08x d:%016" PRIx64 \
30460 " fd:%13g fs:%13g psu:%13g\n", \
30461 tmp.w[FP_ENDIAN_IDX], tmp.d, \
30463 (double)tmp.fs[FP_ENDIAN_IDX], \
30464 (double)tmp.fs[!FP_ENDIAN_IDX]); \
30470 "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
30471 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
30472 get_float_exception_flags(&env
->active_fpu
.fp_status
));
30473 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
30474 qemu_fprintf(f
, "%3s: ", fregnames
[i
]);
30475 printfpr(&env
->active_fpu
.fpr
[i
]);
30481 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, int flags
)
30483 MIPSCPU
*cpu
= MIPS_CPU(cs
);
30484 CPUMIPSState
*env
= &cpu
->env
;
30487 qemu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
30488 " LO=0x" TARGET_FMT_lx
" ds %04x "
30489 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
30490 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
30491 env
->hflags
, env
->btarget
, env
->bcond
);
30492 for (i
= 0; i
< 32; i
++) {
30493 if ((i
& 3) == 0) {
30494 qemu_fprintf(f
, "GPR%02d:", i
);
30496 qemu_fprintf(f
, " %s " TARGET_FMT_lx
,
30497 regnames
[i
], env
->active_tc
.gpr
[i
]);
30498 if ((i
& 3) == 3) {
30499 qemu_fprintf(f
, "\n");
30503 qemu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x"
30504 TARGET_FMT_lx
"\n",
30505 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
30506 qemu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
30508 env
->CP0_Config0
, env
->CP0_Config1
, env
->CP0_LLAddr
);
30509 qemu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
30510 env
->CP0_Config2
, env
->CP0_Config3
);
30511 qemu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
30512 env
->CP0_Config4
, env
->CP0_Config5
);
30513 if ((flags
& CPU_DUMP_FPU
) && (env
->hflags
& MIPS_HFLAG_FPU
)) {
30514 fpu_dump_state(env
, f
, flags
);
30518 void mips_tcg_init(void)
30523 for (i
= 1; i
< 32; i
++)
30524 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
30525 offsetof(CPUMIPSState
,
30529 for (i
= 0; i
< 32; i
++) {
30530 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
30532 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
30534 * The scalar floating-point unit (FPU) registers are mapped on
30535 * the MSA vector registers.
30537 fpu_f64
[i
] = msa_wr_d
[i
* 2];
30538 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
30539 msa_wr_d
[i
* 2 + 1] =
30540 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
30543 cpu_PC
= tcg_global_mem_new(cpu_env
,
30544 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
30545 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
30546 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
30547 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
30549 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
30550 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
30553 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
30554 offsetof(CPUMIPSState
,
30555 active_tc
.DSPControl
),
30557 bcond
= tcg_global_mem_new(cpu_env
,
30558 offsetof(CPUMIPSState
, bcond
), "bcond");
30559 btarget
= tcg_global_mem_new(cpu_env
,
30560 offsetof(CPUMIPSState
, btarget
), "btarget");
30561 hflags
= tcg_global_mem_new_i32(cpu_env
,
30562 offsetof(CPUMIPSState
, hflags
), "hflags");
30564 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
30565 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
30567 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
30568 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
30570 cpu_lladdr
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, lladdr
),
30572 cpu_llval
= tcg_global_mem_new(cpu_env
, offsetof(CPUMIPSState
, llval
),
30575 #if defined(TARGET_MIPS64)
30577 for (i
= 1; i
< 32; i
++) {
30578 cpu_mmr
[i
] = tcg_global_mem_new_i64(cpu_env
,
30579 offsetof(CPUMIPSState
,
30585 #if !defined(TARGET_MIPS64)
30586 for (i
= 0; i
< NUMBER_OF_MXU_REGISTERS
- 1; i
++) {
30587 mxu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
30588 offsetof(CPUMIPSState
,
30589 active_tc
.mxu_gpr
[i
]),
30593 mxu_CR
= tcg_global_mem_new(cpu_env
,
30594 offsetof(CPUMIPSState
, active_tc
.mxu_cr
),
30595 mxuregnames
[NUMBER_OF_MXU_REGISTERS
- 1]);
30599 #include "translate_init.inc.c"
30601 void cpu_mips_realize_env(CPUMIPSState
*env
)
30603 env
->exception_base
= (int32_t)0xBFC00000;
30605 #ifndef CONFIG_USER_ONLY
30606 mmu_init(env
, env
->cpu_model
);
30608 fpu_init(env
, env
->cpu_model
);
30609 mvp_init(env
, env
->cpu_model
);
30612 bool cpu_supports_cps_smp(const char *cpu_type
)
30614 const MIPSCPUClass
*mcc
= MIPS_CPU_CLASS(object_class_by_name(cpu_type
));
30615 return (mcc
->cpu_def
->CP0_Config3
& (1 << CP0C3_CMGCR
)) != 0;
30618 bool cpu_supports_isa(const char *cpu_type
, uint64_t isa
)
30620 const MIPSCPUClass
*mcc
= MIPS_CPU_CLASS(object_class_by_name(cpu_type
));
30621 return (mcc
->cpu_def
->insn_flags
& isa
) != 0;
30624 void cpu_set_exception_base(int vp_index
, target_ulong address
)
30626 MIPSCPU
*vp
= MIPS_CPU(qemu_get_cpu(vp_index
));
30627 vp
->env
.exception_base
= address
;
30630 void cpu_state_reset(CPUMIPSState
*env
)
30632 CPUState
*cs
= env_cpu(env
);
30634 /* Reset registers to their default values */
30635 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
30636 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
30637 #ifdef TARGET_WORDS_BIGENDIAN
30638 env
->CP0_Config0
|= (1 << CP0C0_BE
);
30640 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
30641 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
30642 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
30643 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
30644 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
30645 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
30646 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
30647 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
30648 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
30649 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
30650 << env
->cpu_model
->CP0_LLAddr_shift
;
30651 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
30652 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
30653 env
->CCRes
= env
->cpu_model
->CCRes
;
30654 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
30655 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
30656 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
30657 env
->current_tc
= 0;
30658 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
30659 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
30660 #if defined(TARGET_MIPS64)
30661 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
30662 env
->SEGMask
|= 3ULL << 62;
30665 env
->PABITS
= env
->cpu_model
->PABITS
;
30666 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
30667 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
30668 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
30669 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
30670 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
30671 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
30672 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
30673 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
30674 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
30675 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
30676 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
30677 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
30678 env
->CP0_EBaseWG_rw_bitmask
= env
->cpu_model
->CP0_EBaseWG_rw_bitmask
;
30679 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
30680 env
->active_fpu
.fcr31_rw_bitmask
= env
->cpu_model
->CP1_fcr31_rw_bitmask
;
30681 env
->active_fpu
.fcr31
= env
->cpu_model
->CP1_fcr31
;
30682 env
->msair
= env
->cpu_model
->MSAIR
;
30683 env
->insn_flags
= env
->cpu_model
->insn_flags
;
30685 #if defined(CONFIG_USER_ONLY)
30686 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
30687 # ifdef TARGET_MIPS64
30688 /* Enable 64-bit register mode. */
30689 env
->CP0_Status
|= (1 << CP0St_PX
);
30691 # ifdef TARGET_ABI_MIPSN64
30692 /* Enable 64-bit address mode. */
30693 env
->CP0_Status
|= (1 << CP0St_UX
);
30696 * Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
30697 * hardware registers.
30699 env
->CP0_HWREna
|= 0x0000000F;
30700 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
30701 env
->CP0_Status
|= (1 << CP0St_CU1
);
30703 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
30704 env
->CP0_Status
|= (1 << CP0St_MX
);
30706 # if defined(TARGET_MIPS64)
30707 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
30708 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
30709 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
30710 env
->CP0_Status
|= (1 << CP0St_FR
);
30714 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
30716 * If the exception was raised from a delay slot,
30717 * come back to the jump.
30719 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
30720 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
30722 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
30724 env
->active_tc
.PC
= env
->exception_base
;
30725 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
30726 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
30727 env
->CP0_Wired
= 0;
30728 env
->CP0_GlobalNumber
= (cs
->cpu_index
& 0xFF) << CP0GN_VPId
;
30729 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
30730 if (mips_um_ksegs_enabled()) {
30731 env
->CP0_EBase
|= 0x40000000;
30733 env
->CP0_EBase
|= (int32_t)0x80000000;
30735 if (env
->CP0_Config3
& (1 << CP0C3_CMGCR
)) {
30736 env
->CP0_CMGCRBase
= 0x1fbf8000 >> 4;
30738 env
->CP0_EntryHi_ASID_mask
= (env
->CP0_Config4
& (1 << CP0C4_AE
)) ?
30740 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
30742 * Vectored interrupts not implemented, timer on int 7,
30743 * no performance counters.
30745 env
->CP0_IntCtl
= 0xe0000000;
30749 for (i
= 0; i
< 7; i
++) {
30750 env
->CP0_WatchLo
[i
] = 0;
30751 env
->CP0_WatchHi
[i
] = 0x80000000;
30753 env
->CP0_WatchLo
[7] = 0;
30754 env
->CP0_WatchHi
[7] = 0;
30756 /* Count register increments in debug mode, EJTAG version 1 */
30757 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
30759 cpu_mips_store_count(env
, 1);
30761 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
30764 /* Only TC0 on VPE 0 starts as active. */
30765 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
30766 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
30767 env
->tcs
[i
].CP0_TCHalt
= 1;
30769 env
->active_tc
.CP0_TCHalt
= 1;
30772 if (cs
->cpu_index
== 0) {
30773 /* VPE0 starts up enabled. */
30774 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
30775 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
30777 /* TC0 starts up unhalted. */
30779 env
->active_tc
.CP0_TCHalt
= 0;
30780 env
->tcs
[0].CP0_TCHalt
= 0;
30781 /* With thread 0 active. */
30782 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
30783 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
30788 * Configure default legacy segmentation control. We use this regardless of
30789 * whether segmentation control is presented to the guest.
30791 /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30792 env
->CP0_SegCtl0
= (CP0SC_AM_MK
<< CP0SC_AM
);
30793 /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30794 env
->CP0_SegCtl0
|= ((CP0SC_AM_MSK
<< CP0SC_AM
)) << 16;
30795 /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30796 env
->CP0_SegCtl1
= (0 << CP0SC_PA
) | (CP0SC_AM_UK
<< CP0SC_AM
) |
30798 /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30799 env
->CP0_SegCtl1
|= ((0 << CP0SC_PA
) | (CP0SC_AM_UK
<< CP0SC_AM
) |
30800 (3 << CP0SC_C
)) << 16;
30801 /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30802 env
->CP0_SegCtl2
= (2 << CP0SC_PA
) | (CP0SC_AM_MUSK
<< CP0SC_AM
) |
30803 (1 << CP0SC_EU
) | (2 << CP0SC_C
);
30804 /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30805 env
->CP0_SegCtl2
|= ((0 << CP0SC_PA
) | (CP0SC_AM_MUSK
<< CP0SC_AM
) |
30806 (1 << CP0SC_EU
) | (2 << CP0SC_C
)) << 16;
30807 /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30808 env
->CP0_SegCtl1
|= (CP0SC_AM_UK
<< CP0SC1_XAM
);
30810 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
30811 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
30812 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30813 env
->CP0_Status
|= (1 << CP0St_FR
);
30816 if (env
->insn_flags
& ISA_MIPS32R6
) {
30818 env
->CP0_PWSize
= 0x40;
30824 env
->CP0_PWField
= 0x0C30C302;
30831 env
->CP0_PWField
= 0x02;
30834 if (env
->CP0_Config3
& (1 << CP0C3_ISA
) & (1 << (CP0C3_ISA
+ 1))) {
30835 /* microMIPS on reset when Config3.ISA is 3 */
30836 env
->hflags
|= MIPS_HFLAG_M16
;
30840 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
30844 compute_hflags(env
);
30845 restore_fp_status(env
);
30846 restore_pamask(env
);
30847 cs
->exception_index
= EXCP_NONE
;
30849 if (semihosting_get_argc()) {
30850 /* UHI interface can be used to obtain argc and argv */
30851 env
->active_tc
.gpr
[4] = -1;
30855 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
30856 target_ulong
*data
)
30858 env
->active_tc
.PC
= data
[0];
30859 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
30860 env
->hflags
|= data
[1];
30861 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
30862 case MIPS_HFLAG_BR
:
30864 case MIPS_HFLAG_BC
:
30865 case MIPS_HFLAG_BL
:
30867 env
->btarget
= data
[2];