2 * MIPS32 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/>.
25 #include "disas/disas.h"
27 #include "exec/cpu_ldst.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 #include "sysemu/kvm.h"
33 #include "trace-tcg.h"
36 #define MIPS_DEBUG_DISAS 0
37 //#define MIPS_DEBUG_SIGN_EXTENSIONS
39 /* MIPS major opcodes */
40 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
43 /* indirect opcode tables */
44 OPC_SPECIAL
= (0x00 << 26),
45 OPC_REGIMM
= (0x01 << 26),
46 OPC_CP0
= (0x10 << 26),
47 OPC_CP1
= (0x11 << 26),
48 OPC_CP2
= (0x12 << 26),
49 OPC_CP3
= (0x13 << 26),
50 OPC_SPECIAL2
= (0x1C << 26),
51 OPC_SPECIAL3
= (0x1F << 26),
52 /* arithmetic with immediate */
53 OPC_ADDI
= (0x08 << 26),
54 OPC_ADDIU
= (0x09 << 26),
55 OPC_SLTI
= (0x0A << 26),
56 OPC_SLTIU
= (0x0B << 26),
57 /* logic with immediate */
58 OPC_ANDI
= (0x0C << 26),
59 OPC_ORI
= (0x0D << 26),
60 OPC_XORI
= (0x0E << 26),
61 OPC_LUI
= (0x0F << 26),
62 /* arithmetic with immediate */
63 OPC_DADDI
= (0x18 << 26),
64 OPC_DADDIU
= (0x19 << 26),
65 /* Jump and branches */
67 OPC_JAL
= (0x03 << 26),
68 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
69 OPC_BEQL
= (0x14 << 26),
70 OPC_BNE
= (0x05 << 26),
71 OPC_BNEL
= (0x15 << 26),
72 OPC_BLEZ
= (0x06 << 26),
73 OPC_BLEZL
= (0x16 << 26),
74 OPC_BGTZ
= (0x07 << 26),
75 OPC_BGTZL
= (0x17 << 26),
76 OPC_JALX
= (0x1D << 26),
77 OPC_DAUI
= (0x1D << 26),
79 OPC_LDL
= (0x1A << 26),
80 OPC_LDR
= (0x1B << 26),
81 OPC_LB
= (0x20 << 26),
82 OPC_LH
= (0x21 << 26),
83 OPC_LWL
= (0x22 << 26),
84 OPC_LW
= (0x23 << 26),
85 OPC_LWPC
= OPC_LW
| 0x5,
86 OPC_LBU
= (0x24 << 26),
87 OPC_LHU
= (0x25 << 26),
88 OPC_LWR
= (0x26 << 26),
89 OPC_LWU
= (0x27 << 26),
90 OPC_SB
= (0x28 << 26),
91 OPC_SH
= (0x29 << 26),
92 OPC_SWL
= (0x2A << 26),
93 OPC_SW
= (0x2B << 26),
94 OPC_SDL
= (0x2C << 26),
95 OPC_SDR
= (0x2D << 26),
96 OPC_SWR
= (0x2E << 26),
97 OPC_LL
= (0x30 << 26),
98 OPC_LLD
= (0x34 << 26),
99 OPC_LD
= (0x37 << 26),
100 OPC_LDPC
= OPC_LD
| 0x5,
101 OPC_SC
= (0x38 << 26),
102 OPC_SCD
= (0x3C << 26),
103 OPC_SD
= (0x3F << 26),
104 /* Floating point load/store */
105 OPC_LWC1
= (0x31 << 26),
106 OPC_LWC2
= (0x32 << 26),
107 OPC_LDC1
= (0x35 << 26),
108 OPC_LDC2
= (0x36 << 26),
109 OPC_SWC1
= (0x39 << 26),
110 OPC_SWC2
= (0x3A << 26),
111 OPC_SDC1
= (0x3D << 26),
112 OPC_SDC2
= (0x3E << 26),
113 /* Compact Branches */
114 OPC_BLEZALC
= (0x06 << 26),
115 OPC_BGEZALC
= (0x06 << 26),
116 OPC_BGEUC
= (0x06 << 26),
117 OPC_BGTZALC
= (0x07 << 26),
118 OPC_BLTZALC
= (0x07 << 26),
119 OPC_BLTUC
= (0x07 << 26),
120 OPC_BOVC
= (0x08 << 26),
121 OPC_BEQZALC
= (0x08 << 26),
122 OPC_BEQC
= (0x08 << 26),
123 OPC_BLEZC
= (0x16 << 26),
124 OPC_BGEZC
= (0x16 << 26),
125 OPC_BGEC
= (0x16 << 26),
126 OPC_BGTZC
= (0x17 << 26),
127 OPC_BLTZC
= (0x17 << 26),
128 OPC_BLTC
= (0x17 << 26),
129 OPC_BNVC
= (0x18 << 26),
130 OPC_BNEZALC
= (0x18 << 26),
131 OPC_BNEC
= (0x18 << 26),
132 OPC_BC
= (0x32 << 26),
133 OPC_BEQZC
= (0x36 << 26),
134 OPC_JIC
= (0x36 << 26),
135 OPC_BALC
= (0x3A << 26),
136 OPC_BNEZC
= (0x3E << 26),
137 OPC_JIALC
= (0x3E << 26),
138 /* MDMX ASE specific */
139 OPC_MDMX
= (0x1E << 26),
140 /* MSA ASE, same as MDMX */
142 /* Cache and prefetch */
143 OPC_CACHE
= (0x2F << 26),
144 OPC_PREF
= (0x33 << 26),
145 /* PC-relative address computation / loads */
146 OPC_PCREL
= (0x3B << 26),
149 /* PC-relative address computation / loads */
150 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
151 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
153 /* Instructions determined by bits 19 and 20 */
154 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
155 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
156 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
158 /* Instructions determined by bits 16 ... 20 */
159 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
160 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
163 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
166 /* MIPS special opcodes */
167 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
171 OPC_SLL
= 0x00 | OPC_SPECIAL
,
172 /* NOP is SLL r0, r0, 0 */
173 /* SSNOP is SLL r0, r0, 1 */
174 /* EHB is SLL r0, r0, 3 */
175 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
176 OPC_ROTR
= OPC_SRL
| (1 << 21),
177 OPC_SRA
= 0x03 | OPC_SPECIAL
,
178 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
179 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
180 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
181 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
182 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
183 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
184 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
185 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
186 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
187 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
188 OPC_DROTR
= OPC_DSRL
| (1 << 21),
189 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
190 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
191 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
192 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
193 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
194 /* Multiplication / division */
195 OPC_MULT
= 0x18 | OPC_SPECIAL
,
196 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
197 OPC_DIV
= 0x1A | OPC_SPECIAL
,
198 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
199 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
200 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
201 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
202 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
204 /* 2 registers arithmetic / logic */
205 OPC_ADD
= 0x20 | OPC_SPECIAL
,
206 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
207 OPC_SUB
= 0x22 | OPC_SPECIAL
,
208 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
209 OPC_AND
= 0x24 | OPC_SPECIAL
,
210 OPC_OR
= 0x25 | OPC_SPECIAL
,
211 OPC_XOR
= 0x26 | OPC_SPECIAL
,
212 OPC_NOR
= 0x27 | OPC_SPECIAL
,
213 OPC_SLT
= 0x2A | OPC_SPECIAL
,
214 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
215 OPC_DADD
= 0x2C | OPC_SPECIAL
,
216 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
217 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
218 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
220 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
221 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
223 OPC_TGE
= 0x30 | OPC_SPECIAL
,
224 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
225 OPC_TLT
= 0x32 | OPC_SPECIAL
,
226 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
227 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
228 OPC_TNE
= 0x36 | OPC_SPECIAL
,
229 /* HI / LO registers load & stores */
230 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
231 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
232 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
233 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
234 /* Conditional moves */
235 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
236 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
238 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
239 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
241 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
244 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
245 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
246 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
247 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
248 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
250 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
251 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
252 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
253 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
256 /* R6 Multiply and Divide instructions have the same Opcode
257 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
258 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
261 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
262 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
263 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
264 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
265 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
266 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
267 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
268 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
270 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
271 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
272 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
273 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
274 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
275 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
276 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
277 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
279 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
280 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
281 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
282 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
283 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
285 OPC_LSA
= 0x05 | OPC_SPECIAL
,
286 OPC_DLSA
= 0x15 | OPC_SPECIAL
,
289 /* Multiplication variants of the vr54xx. */
290 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
293 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
294 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
295 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
296 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
297 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
298 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
299 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
300 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
301 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
302 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
303 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
304 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
305 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
306 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
309 /* REGIMM (rt field) opcodes */
310 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
313 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
314 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
315 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
316 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
317 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
318 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
319 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
320 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
321 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
322 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
323 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
324 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
325 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
326 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
327 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
329 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
330 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
333 /* Special2 opcodes */
334 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
337 /* Multiply & xxx operations */
338 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
339 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
340 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
341 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
342 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
344 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
345 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
346 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
347 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
348 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
349 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
350 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
351 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
352 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
353 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
354 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
355 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
357 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
358 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
359 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
360 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
362 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
365 /* Special3 opcodes */
366 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
369 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
370 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
371 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
372 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
373 OPC_INS
= 0x04 | OPC_SPECIAL3
,
374 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
375 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
376 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
377 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
378 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
379 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
380 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
381 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
384 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
385 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
386 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
387 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
388 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
389 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
390 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
391 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
392 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
393 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
394 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
395 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
398 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
399 /* MIPS DSP Arithmetic */
400 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
401 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
402 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
403 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
404 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
405 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
406 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
407 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
408 /* MIPS DSP GPR-Based Shift Sub-class */
409 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
410 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
411 /* MIPS DSP Multiply Sub-class insns */
412 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
413 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
414 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
415 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
416 /* DSP Bit/Manipulation Sub-class */
417 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
418 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
419 /* MIPS DSP Append Sub-class */
420 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
421 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
422 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
423 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
424 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
427 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
428 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
429 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
430 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
431 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
432 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
436 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
439 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
440 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
441 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
442 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp */
443 OPC_ALIGN_END
= (0x0B << 6) | OPC_BSHFL
, /* 010.00 to 010.11 */
444 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
448 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
451 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
452 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
453 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp */
454 OPC_DALIGN_END
= (0x0F << 6) | OPC_DBSHFL
, /* 01.000 to 01.111 */
455 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
458 /* MIPS DSP REGIMM opcodes */
460 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
461 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
464 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
467 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
468 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
469 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
470 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
473 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
475 /* MIPS DSP Arithmetic Sub-class */
476 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
477 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
478 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
479 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
480 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
481 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
482 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
483 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
484 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
485 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
486 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
487 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
488 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
489 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
490 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
491 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
492 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
493 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
494 /* MIPS DSP Multiply Sub-class insns */
495 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
496 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
497 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
498 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
499 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
500 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
503 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
504 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
506 /* MIPS DSP Arithmetic Sub-class */
507 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
508 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
509 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
510 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
511 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
512 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
513 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
514 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
515 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
516 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
517 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
518 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
519 /* MIPS DSP Multiply Sub-class insns */
520 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
521 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
522 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
523 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
526 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
528 /* MIPS DSP Arithmetic Sub-class */
529 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
530 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
531 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
532 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
533 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
534 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
535 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
536 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
537 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
538 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
539 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
540 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
541 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
542 /* DSP Bit/Manipulation Sub-class */
543 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
544 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
545 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
546 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
547 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
550 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
552 /* MIPS DSP Arithmetic Sub-class */
553 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
554 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
555 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
556 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
557 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
558 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
559 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
560 /* DSP Compare-Pick Sub-class */
561 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
562 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
563 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
564 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
565 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
566 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
567 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
568 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
569 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
570 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
571 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
572 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
573 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
574 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
575 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
578 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
580 /* MIPS DSP GPR-Based Shift Sub-class */
581 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
582 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
583 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
584 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
585 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
586 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
587 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
588 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
589 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
590 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
591 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
592 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
593 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
594 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
595 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
596 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
597 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
598 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
599 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
600 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
601 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
602 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
605 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
607 /* MIPS DSP Multiply Sub-class insns */
608 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
609 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
610 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
611 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
612 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
613 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
614 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
615 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
616 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
617 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
618 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
619 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
620 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
621 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
622 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
623 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
624 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
625 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
626 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
627 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
628 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
629 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
632 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
634 /* DSP Bit/Manipulation Sub-class */
635 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
638 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
640 /* MIPS DSP Append Sub-class */
641 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
642 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
643 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
646 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
648 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
649 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
650 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
651 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
652 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
653 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
654 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
655 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
656 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
657 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
658 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
659 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
660 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
661 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
662 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
663 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
664 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
665 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
668 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* MIPS DSP Arithmetic Sub-class */
671 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
672 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
673 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
674 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
675 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
676 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
677 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
678 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
679 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
680 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
681 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
682 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
683 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
684 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
685 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
686 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
687 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
688 /* DSP Bit/Manipulation Sub-class */
689 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
690 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
691 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
692 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
693 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
694 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
697 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
699 /* MIPS DSP Multiply Sub-class insns */
700 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
701 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
702 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
703 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
704 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
705 /* MIPS DSP Arithmetic Sub-class */
706 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
707 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
708 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
709 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
710 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
711 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
712 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
713 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
714 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
715 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
716 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
717 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
718 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
719 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
720 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
721 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
722 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
723 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
724 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
725 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
726 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
729 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
731 /* DSP Compare-Pick Sub-class */
732 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
733 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
734 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
735 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
736 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
737 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
738 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
739 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
740 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
741 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
742 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
743 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
744 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
745 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
746 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
747 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
748 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
749 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
750 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
751 /* MIPS DSP Arithmetic Sub-class */
752 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
753 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
754 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
755 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
756 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
757 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
758 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
759 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
762 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
764 /* DSP Append Sub-class */
765 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
766 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
767 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
768 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
771 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
773 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
774 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
775 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
776 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
777 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
778 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
779 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
780 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
781 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
782 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
783 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
784 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
785 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
786 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
787 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
788 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
789 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
790 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
791 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
792 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
793 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
794 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
797 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
799 /* DSP Bit/Manipulation Sub-class */
800 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
803 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
805 /* MIPS DSP Multiply Sub-class insns */
806 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
807 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
808 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
809 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
810 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
811 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
812 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
813 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
814 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
815 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
816 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
817 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
818 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
819 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
820 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
821 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
822 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
823 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
824 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
825 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
826 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
827 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
828 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
829 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
830 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
831 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
834 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
836 /* MIPS DSP GPR-Based Shift Sub-class */
837 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
838 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
839 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
840 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
841 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
842 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
843 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
844 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
845 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
846 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
847 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
848 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
849 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
850 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
851 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
852 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
853 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
854 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
855 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
856 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
857 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
858 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
859 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
860 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
861 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
862 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
865 /* Coprocessor 0 (rs field) */
866 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
869 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
870 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
871 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
872 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
873 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
874 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
875 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
876 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
877 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
878 OPC_C0
= (0x10 << 21) | OPC_CP0
,
879 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
880 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
884 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
887 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
888 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
889 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
890 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
891 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
892 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
895 /* Coprocessor 0 (with rs == C0) */
896 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
899 OPC_TLBR
= 0x01 | OPC_C0
,
900 OPC_TLBWI
= 0x02 | OPC_C0
,
901 OPC_TLBINV
= 0x03 | OPC_C0
,
902 OPC_TLBINVF
= 0x04 | OPC_C0
,
903 OPC_TLBWR
= 0x06 | OPC_C0
,
904 OPC_TLBP
= 0x08 | OPC_C0
,
905 OPC_RFE
= 0x10 | OPC_C0
,
906 OPC_ERET
= 0x18 | OPC_C0
,
907 OPC_DERET
= 0x1F | OPC_C0
,
908 OPC_WAIT
= 0x20 | OPC_C0
,
911 /* Coprocessor 1 (rs field) */
912 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
914 /* Values for the fmt field in FP instructions */
916 /* 0 - 15 are reserved */
917 FMT_S
= 16, /* single fp */
918 FMT_D
= 17, /* double fp */
919 FMT_E
= 18, /* extended fp */
920 FMT_Q
= 19, /* quad fp */
921 FMT_W
= 20, /* 32-bit fixed */
922 FMT_L
= 21, /* 64-bit fixed */
923 FMT_PS
= 22, /* paired single fp */
924 /* 23 - 31 are reserved */
928 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
929 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
930 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
931 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
932 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
933 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
934 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
935 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
936 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
937 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
938 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
939 OPC_BZ_V
= (0x0B << 21) | OPC_CP1
,
940 OPC_BNZ_V
= (0x0F << 21) | OPC_CP1
,
941 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
942 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
943 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
944 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
945 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
946 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
947 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
948 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
949 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
950 OPC_BZ_B
= (0x18 << 21) | OPC_CP1
,
951 OPC_BZ_H
= (0x19 << 21) | OPC_CP1
,
952 OPC_BZ_W
= (0x1A << 21) | OPC_CP1
,
953 OPC_BZ_D
= (0x1B << 21) | OPC_CP1
,
954 OPC_BNZ_B
= (0x1C << 21) | OPC_CP1
,
955 OPC_BNZ_H
= (0x1D << 21) | OPC_CP1
,
956 OPC_BNZ_W
= (0x1E << 21) | OPC_CP1
,
957 OPC_BNZ_D
= (0x1F << 21) | OPC_CP1
,
960 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
961 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
964 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
965 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
966 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
967 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
971 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
972 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
976 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
977 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
980 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
983 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
984 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
985 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
986 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
987 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
988 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
989 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
990 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
991 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
992 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
993 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
996 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
999 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1000 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1001 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1002 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1003 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1004 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1005 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1006 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1008 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1009 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1010 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1011 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1012 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1013 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1014 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1015 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1017 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1018 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1019 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1020 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1021 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1022 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1023 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1024 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1026 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1027 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1028 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1029 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1030 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1031 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1032 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1033 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1035 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1036 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1037 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1038 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1039 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1040 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1042 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1043 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1044 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1045 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1046 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1047 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1049 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1050 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1051 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1052 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1053 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1054 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1056 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1057 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1058 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1059 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1060 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1061 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1063 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1064 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1065 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1066 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1067 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1068 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1070 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1071 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1072 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1073 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1074 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1075 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1077 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1078 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1079 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1080 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1081 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1082 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1084 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1085 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1086 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1087 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1088 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1089 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1093 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1096 OPC_LWXC1
= 0x00 | OPC_CP3
,
1097 OPC_LDXC1
= 0x01 | OPC_CP3
,
1098 OPC_LUXC1
= 0x05 | OPC_CP3
,
1099 OPC_SWXC1
= 0x08 | OPC_CP3
,
1100 OPC_SDXC1
= 0x09 | OPC_CP3
,
1101 OPC_SUXC1
= 0x0D | OPC_CP3
,
1102 OPC_PREFX
= 0x0F | OPC_CP3
,
1103 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1104 OPC_MADD_S
= 0x20 | OPC_CP3
,
1105 OPC_MADD_D
= 0x21 | OPC_CP3
,
1106 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1107 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1108 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1109 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1110 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1111 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1112 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1113 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1114 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1115 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1119 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1121 OPC_MSA_I8_00
= 0x00 | OPC_MSA
,
1122 OPC_MSA_I8_01
= 0x01 | OPC_MSA
,
1123 OPC_MSA_I8_02
= 0x02 | OPC_MSA
,
1124 OPC_MSA_I5_06
= 0x06 | OPC_MSA
,
1125 OPC_MSA_I5_07
= 0x07 | OPC_MSA
,
1126 OPC_MSA_BIT_09
= 0x09 | OPC_MSA
,
1127 OPC_MSA_BIT_0A
= 0x0A | OPC_MSA
,
1128 OPC_MSA_3R_0D
= 0x0D | OPC_MSA
,
1129 OPC_MSA_3R_0E
= 0x0E | OPC_MSA
,
1130 OPC_MSA_3R_0F
= 0x0F | OPC_MSA
,
1131 OPC_MSA_3R_10
= 0x10 | OPC_MSA
,
1132 OPC_MSA_3R_11
= 0x11 | OPC_MSA
,
1133 OPC_MSA_3R_12
= 0x12 | OPC_MSA
,
1134 OPC_MSA_3R_13
= 0x13 | OPC_MSA
,
1135 OPC_MSA_3R_14
= 0x14 | OPC_MSA
,
1136 OPC_MSA_3R_15
= 0x15 | OPC_MSA
,
1137 OPC_MSA_ELM
= 0x19 | OPC_MSA
,
1138 OPC_MSA_3RF_1A
= 0x1A | OPC_MSA
,
1139 OPC_MSA_3RF_1B
= 0x1B | OPC_MSA
,
1140 OPC_MSA_3RF_1C
= 0x1C | OPC_MSA
,
1141 OPC_MSA_VEC
= 0x1E | OPC_MSA
,
1143 /* MI10 instruction */
1144 OPC_LD_B
= (0x20) | OPC_MSA
,
1145 OPC_LD_H
= (0x21) | OPC_MSA
,
1146 OPC_LD_W
= (0x22) | OPC_MSA
,
1147 OPC_LD_D
= (0x23) | OPC_MSA
,
1148 OPC_ST_B
= (0x24) | OPC_MSA
,
1149 OPC_ST_H
= (0x25) | OPC_MSA
,
1150 OPC_ST_W
= (0x26) | OPC_MSA
,
1151 OPC_ST_D
= (0x27) | OPC_MSA
,
1155 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1156 OPC_ADDVI_df
= (0x0 << 23) | OPC_MSA_I5_06
,
1157 OPC_CEQI_df
= (0x0 << 23) | OPC_MSA_I5_07
,
1158 OPC_SUBVI_df
= (0x1 << 23) | OPC_MSA_I5_06
,
1159 OPC_MAXI_S_df
= (0x2 << 23) | OPC_MSA_I5_06
,
1160 OPC_CLTI_S_df
= (0x2 << 23) | OPC_MSA_I5_07
,
1161 OPC_MAXI_U_df
= (0x3 << 23) | OPC_MSA_I5_06
,
1162 OPC_CLTI_U_df
= (0x3 << 23) | OPC_MSA_I5_07
,
1163 OPC_MINI_S_df
= (0x4 << 23) | OPC_MSA_I5_06
,
1164 OPC_CLEI_S_df
= (0x4 << 23) | OPC_MSA_I5_07
,
1165 OPC_MINI_U_df
= (0x5 << 23) | OPC_MSA_I5_06
,
1166 OPC_CLEI_U_df
= (0x5 << 23) | OPC_MSA_I5_07
,
1167 OPC_LDI_df
= (0x6 << 23) | OPC_MSA_I5_07
,
1169 /* I8 instruction */
1170 OPC_ANDI_B
= (0x0 << 24) | OPC_MSA_I8_00
,
1171 OPC_BMNZI_B
= (0x0 << 24) | OPC_MSA_I8_01
,
1172 OPC_SHF_B
= (0x0 << 24) | OPC_MSA_I8_02
,
1173 OPC_ORI_B
= (0x1 << 24) | OPC_MSA_I8_00
,
1174 OPC_BMZI_B
= (0x1 << 24) | OPC_MSA_I8_01
,
1175 OPC_SHF_H
= (0x1 << 24) | OPC_MSA_I8_02
,
1176 OPC_NORI_B
= (0x2 << 24) | OPC_MSA_I8_00
,
1177 OPC_BSELI_B
= (0x2 << 24) | OPC_MSA_I8_01
,
1178 OPC_SHF_W
= (0x2 << 24) | OPC_MSA_I8_02
,
1179 OPC_XORI_B
= (0x3 << 24) | OPC_MSA_I8_00
,
1181 /* VEC/2R/2RF instruction */
1182 OPC_AND_V
= (0x00 << 21) | OPC_MSA_VEC
,
1183 OPC_OR_V
= (0x01 << 21) | OPC_MSA_VEC
,
1184 OPC_NOR_V
= (0x02 << 21) | OPC_MSA_VEC
,
1185 OPC_XOR_V
= (0x03 << 21) | OPC_MSA_VEC
,
1186 OPC_BMNZ_V
= (0x04 << 21) | OPC_MSA_VEC
,
1187 OPC_BMZ_V
= (0x05 << 21) | OPC_MSA_VEC
,
1188 OPC_BSEL_V
= (0x06 << 21) | OPC_MSA_VEC
,
1190 OPC_MSA_2R
= (0x18 << 21) | OPC_MSA_VEC
,
1191 OPC_MSA_2RF
= (0x19 << 21) | OPC_MSA_VEC
,
1193 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1194 OPC_FILL_df
= (0x00 << 18) | OPC_MSA_2R
,
1195 OPC_PCNT_df
= (0x01 << 18) | OPC_MSA_2R
,
1196 OPC_NLOC_df
= (0x02 << 18) | OPC_MSA_2R
,
1197 OPC_NLZC_df
= (0x03 << 18) | OPC_MSA_2R
,
1199 /* 2RF instruction df(bit 16) = _w, _d */
1200 OPC_FCLASS_df
= (0x00 << 17) | OPC_MSA_2RF
,
1201 OPC_FTRUNC_S_df
= (0x01 << 17) | OPC_MSA_2RF
,
1202 OPC_FTRUNC_U_df
= (0x02 << 17) | OPC_MSA_2RF
,
1203 OPC_FSQRT_df
= (0x03 << 17) | OPC_MSA_2RF
,
1204 OPC_FRSQRT_df
= (0x04 << 17) | OPC_MSA_2RF
,
1205 OPC_FRCP_df
= (0x05 << 17) | OPC_MSA_2RF
,
1206 OPC_FRINT_df
= (0x06 << 17) | OPC_MSA_2RF
,
1207 OPC_FLOG2_df
= (0x07 << 17) | OPC_MSA_2RF
,
1208 OPC_FEXUPL_df
= (0x08 << 17) | OPC_MSA_2RF
,
1209 OPC_FEXUPR_df
= (0x09 << 17) | OPC_MSA_2RF
,
1210 OPC_FFQL_df
= (0x0A << 17) | OPC_MSA_2RF
,
1211 OPC_FFQR_df
= (0x0B << 17) | OPC_MSA_2RF
,
1212 OPC_FTINT_S_df
= (0x0C << 17) | OPC_MSA_2RF
,
1213 OPC_FTINT_U_df
= (0x0D << 17) | OPC_MSA_2RF
,
1214 OPC_FFINT_S_df
= (0x0E << 17) | OPC_MSA_2RF
,
1215 OPC_FFINT_U_df
= (0x0F << 17) | OPC_MSA_2RF
,
1217 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1218 OPC_SLL_df
= (0x0 << 23) | OPC_MSA_3R_0D
,
1219 OPC_ADDV_df
= (0x0 << 23) | OPC_MSA_3R_0E
,
1220 OPC_CEQ_df
= (0x0 << 23) | OPC_MSA_3R_0F
,
1221 OPC_ADD_A_df
= (0x0 << 23) | OPC_MSA_3R_10
,
1222 OPC_SUBS_S_df
= (0x0 << 23) | OPC_MSA_3R_11
,
1223 OPC_MULV_df
= (0x0 << 23) | OPC_MSA_3R_12
,
1224 OPC_DOTP_S_df
= (0x0 << 23) | OPC_MSA_3R_13
,
1225 OPC_SLD_df
= (0x0 << 23) | OPC_MSA_3R_14
,
1226 OPC_VSHF_df
= (0x0 << 23) | OPC_MSA_3R_15
,
1227 OPC_SRA_df
= (0x1 << 23) | OPC_MSA_3R_0D
,
1228 OPC_SUBV_df
= (0x1 << 23) | OPC_MSA_3R_0E
,
1229 OPC_ADDS_A_df
= (0x1 << 23) | OPC_MSA_3R_10
,
1230 OPC_SUBS_U_df
= (0x1 << 23) | OPC_MSA_3R_11
,
1231 OPC_MADDV_df
= (0x1 << 23) | OPC_MSA_3R_12
,
1232 OPC_DOTP_U_df
= (0x1 << 23) | OPC_MSA_3R_13
,
1233 OPC_SPLAT_df
= (0x1 << 23) | OPC_MSA_3R_14
,
1234 OPC_SRAR_df
= (0x1 << 23) | OPC_MSA_3R_15
,
1235 OPC_SRL_df
= (0x2 << 23) | OPC_MSA_3R_0D
,
1236 OPC_MAX_S_df
= (0x2 << 23) | OPC_MSA_3R_0E
,
1237 OPC_CLT_S_df
= (0x2 << 23) | OPC_MSA_3R_0F
,
1238 OPC_ADDS_S_df
= (0x2 << 23) | OPC_MSA_3R_10
,
1239 OPC_SUBSUS_U_df
= (0x2 << 23) | OPC_MSA_3R_11
,
1240 OPC_MSUBV_df
= (0x2 << 23) | OPC_MSA_3R_12
,
1241 OPC_DPADD_S_df
= (0x2 << 23) | OPC_MSA_3R_13
,
1242 OPC_PCKEV_df
= (0x2 << 23) | OPC_MSA_3R_14
,
1243 OPC_SRLR_df
= (0x2 << 23) | OPC_MSA_3R_15
,
1244 OPC_BCLR_df
= (0x3 << 23) | OPC_MSA_3R_0D
,
1245 OPC_MAX_U_df
= (0x3 << 23) | OPC_MSA_3R_0E
,
1246 OPC_CLT_U_df
= (0x3 << 23) | OPC_MSA_3R_0F
,
1247 OPC_ADDS_U_df
= (0x3 << 23) | OPC_MSA_3R_10
,
1248 OPC_SUBSUU_S_df
= (0x3 << 23) | OPC_MSA_3R_11
,
1249 OPC_DPADD_U_df
= (0x3 << 23) | OPC_MSA_3R_13
,
1250 OPC_PCKOD_df
= (0x3 << 23) | OPC_MSA_3R_14
,
1251 OPC_BSET_df
= (0x4 << 23) | OPC_MSA_3R_0D
,
1252 OPC_MIN_S_df
= (0x4 << 23) | OPC_MSA_3R_0E
,
1253 OPC_CLE_S_df
= (0x4 << 23) | OPC_MSA_3R_0F
,
1254 OPC_AVE_S_df
= (0x4 << 23) | OPC_MSA_3R_10
,
1255 OPC_ASUB_S_df
= (0x4 << 23) | OPC_MSA_3R_11
,
1256 OPC_DIV_S_df
= (0x4 << 23) | OPC_MSA_3R_12
,
1257 OPC_DPSUB_S_df
= (0x4 << 23) | OPC_MSA_3R_13
,
1258 OPC_ILVL_df
= (0x4 << 23) | OPC_MSA_3R_14
,
1259 OPC_HADD_S_df
= (0x4 << 23) | OPC_MSA_3R_15
,
1260 OPC_BNEG_df
= (0x5 << 23) | OPC_MSA_3R_0D
,
1261 OPC_MIN_U_df
= (0x5 << 23) | OPC_MSA_3R_0E
,
1262 OPC_CLE_U_df
= (0x5 << 23) | OPC_MSA_3R_0F
,
1263 OPC_AVE_U_df
= (0x5 << 23) | OPC_MSA_3R_10
,
1264 OPC_ASUB_U_df
= (0x5 << 23) | OPC_MSA_3R_11
,
1265 OPC_DIV_U_df
= (0x5 << 23) | OPC_MSA_3R_12
,
1266 OPC_DPSUB_U_df
= (0x5 << 23) | OPC_MSA_3R_13
,
1267 OPC_ILVR_df
= (0x5 << 23) | OPC_MSA_3R_14
,
1268 OPC_HADD_U_df
= (0x5 << 23) | OPC_MSA_3R_15
,
1269 OPC_BINSL_df
= (0x6 << 23) | OPC_MSA_3R_0D
,
1270 OPC_MAX_A_df
= (0x6 << 23) | OPC_MSA_3R_0E
,
1271 OPC_AVER_S_df
= (0x6 << 23) | OPC_MSA_3R_10
,
1272 OPC_MOD_S_df
= (0x6 << 23) | OPC_MSA_3R_12
,
1273 OPC_ILVEV_df
= (0x6 << 23) | OPC_MSA_3R_14
,
1274 OPC_HSUB_S_df
= (0x6 << 23) | OPC_MSA_3R_15
,
1275 OPC_BINSR_df
= (0x7 << 23) | OPC_MSA_3R_0D
,
1276 OPC_MIN_A_df
= (0x7 << 23) | OPC_MSA_3R_0E
,
1277 OPC_AVER_U_df
= (0x7 << 23) | OPC_MSA_3R_10
,
1278 OPC_MOD_U_df
= (0x7 << 23) | OPC_MSA_3R_12
,
1279 OPC_ILVOD_df
= (0x7 << 23) | OPC_MSA_3R_14
,
1280 OPC_HSUB_U_df
= (0x7 << 23) | OPC_MSA_3R_15
,
1282 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1283 OPC_SLDI_df
= (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1284 OPC_CTCMSA
= (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1285 OPC_SPLATI_df
= (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1286 OPC_CFCMSA
= (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1287 OPC_COPY_S_df
= (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1288 OPC_MOVE_V
= (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1289 OPC_COPY_U_df
= (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1290 OPC_INSERT_df
= (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1291 OPC_INSVE_df
= (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1293 /* 3RF instruction _df(bit 21) = _w, _d */
1294 OPC_FCAF_df
= (0x0 << 22) | OPC_MSA_3RF_1A
,
1295 OPC_FADD_df
= (0x0 << 22) | OPC_MSA_3RF_1B
,
1296 OPC_FCUN_df
= (0x1 << 22) | OPC_MSA_3RF_1A
,
1297 OPC_FSUB_df
= (0x1 << 22) | OPC_MSA_3RF_1B
,
1298 OPC_FCOR_df
= (0x1 << 22) | OPC_MSA_3RF_1C
,
1299 OPC_FCEQ_df
= (0x2 << 22) | OPC_MSA_3RF_1A
,
1300 OPC_FMUL_df
= (0x2 << 22) | OPC_MSA_3RF_1B
,
1301 OPC_FCUNE_df
= (0x2 << 22) | OPC_MSA_3RF_1C
,
1302 OPC_FCUEQ_df
= (0x3 << 22) | OPC_MSA_3RF_1A
,
1303 OPC_FDIV_df
= (0x3 << 22) | OPC_MSA_3RF_1B
,
1304 OPC_FCNE_df
= (0x3 << 22) | OPC_MSA_3RF_1C
,
1305 OPC_FCLT_df
= (0x4 << 22) | OPC_MSA_3RF_1A
,
1306 OPC_FMADD_df
= (0x4 << 22) | OPC_MSA_3RF_1B
,
1307 OPC_MUL_Q_df
= (0x4 << 22) | OPC_MSA_3RF_1C
,
1308 OPC_FCULT_df
= (0x5 << 22) | OPC_MSA_3RF_1A
,
1309 OPC_FMSUB_df
= (0x5 << 22) | OPC_MSA_3RF_1B
,
1310 OPC_MADD_Q_df
= (0x5 << 22) | OPC_MSA_3RF_1C
,
1311 OPC_FCLE_df
= (0x6 << 22) | OPC_MSA_3RF_1A
,
1312 OPC_MSUB_Q_df
= (0x6 << 22) | OPC_MSA_3RF_1C
,
1313 OPC_FCULE_df
= (0x7 << 22) | OPC_MSA_3RF_1A
,
1314 OPC_FEXP2_df
= (0x7 << 22) | OPC_MSA_3RF_1B
,
1315 OPC_FSAF_df
= (0x8 << 22) | OPC_MSA_3RF_1A
,
1316 OPC_FEXDO_df
= (0x8 << 22) | OPC_MSA_3RF_1B
,
1317 OPC_FSUN_df
= (0x9 << 22) | OPC_MSA_3RF_1A
,
1318 OPC_FSOR_df
= (0x9 << 22) | OPC_MSA_3RF_1C
,
1319 OPC_FSEQ_df
= (0xA << 22) | OPC_MSA_3RF_1A
,
1320 OPC_FTQ_df
= (0xA << 22) | OPC_MSA_3RF_1B
,
1321 OPC_FSUNE_df
= (0xA << 22) | OPC_MSA_3RF_1C
,
1322 OPC_FSUEQ_df
= (0xB << 22) | OPC_MSA_3RF_1A
,
1323 OPC_FSNE_df
= (0xB << 22) | OPC_MSA_3RF_1C
,
1324 OPC_FSLT_df
= (0xC << 22) | OPC_MSA_3RF_1A
,
1325 OPC_FMIN_df
= (0xC << 22) | OPC_MSA_3RF_1B
,
1326 OPC_MULR_Q_df
= (0xC << 22) | OPC_MSA_3RF_1C
,
1327 OPC_FSULT_df
= (0xD << 22) | OPC_MSA_3RF_1A
,
1328 OPC_FMIN_A_df
= (0xD << 22) | OPC_MSA_3RF_1B
,
1329 OPC_MADDR_Q_df
= (0xD << 22) | OPC_MSA_3RF_1C
,
1330 OPC_FSLE_df
= (0xE << 22) | OPC_MSA_3RF_1A
,
1331 OPC_FMAX_df
= (0xE << 22) | OPC_MSA_3RF_1B
,
1332 OPC_MSUBR_Q_df
= (0xE << 22) | OPC_MSA_3RF_1C
,
1333 OPC_FSULE_df
= (0xF << 22) | OPC_MSA_3RF_1A
,
1334 OPC_FMAX_A_df
= (0xF << 22) | OPC_MSA_3RF_1B
,
1336 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1337 OPC_SLLI_df
= (0x0 << 23) | OPC_MSA_BIT_09
,
1338 OPC_SAT_S_df
= (0x0 << 23) | OPC_MSA_BIT_0A
,
1339 OPC_SRAI_df
= (0x1 << 23) | OPC_MSA_BIT_09
,
1340 OPC_SAT_U_df
= (0x1 << 23) | OPC_MSA_BIT_0A
,
1341 OPC_SRLI_df
= (0x2 << 23) | OPC_MSA_BIT_09
,
1342 OPC_SRARI_df
= (0x2 << 23) | OPC_MSA_BIT_0A
,
1343 OPC_BCLRI_df
= (0x3 << 23) | OPC_MSA_BIT_09
,
1344 OPC_SRLRI_df
= (0x3 << 23) | OPC_MSA_BIT_0A
,
1345 OPC_BSETI_df
= (0x4 << 23) | OPC_MSA_BIT_09
,
1346 OPC_BNEGI_df
= (0x5 << 23) | OPC_MSA_BIT_09
,
1347 OPC_BINSLI_df
= (0x6 << 23) | OPC_MSA_BIT_09
,
1348 OPC_BINSRI_df
= (0x7 << 23) | OPC_MSA_BIT_09
,
1351 /* global register indices */
1352 static TCGv_ptr cpu_env
;
1353 static TCGv cpu_gpr
[32], cpu_PC
;
1354 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1355 static TCGv cpu_dspctrl
, btarget
, bcond
;
1356 static TCGv_i32 hflags
;
1357 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1358 static TCGv_i64 fpu_f64
[32];
1359 static TCGv_i64 msa_wr_d
[64];
1361 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1362 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1364 #include "exec/gen-icount.h"
1366 #define gen_helper_0e0i(name, arg) do { \
1367 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1368 gen_helper_##name(cpu_env, helper_tmp); \
1369 tcg_temp_free_i32(helper_tmp); \
1372 #define gen_helper_0e1i(name, arg1, arg2) do { \
1373 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1374 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1375 tcg_temp_free_i32(helper_tmp); \
1378 #define gen_helper_1e0i(name, ret, arg1) do { \
1379 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1380 gen_helper_##name(ret, cpu_env, helper_tmp); \
1381 tcg_temp_free_i32(helper_tmp); \
1384 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1385 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1386 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1387 tcg_temp_free_i32(helper_tmp); \
1390 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1391 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1392 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1393 tcg_temp_free_i32(helper_tmp); \
1396 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1397 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1398 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1399 tcg_temp_free_i32(helper_tmp); \
1402 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1403 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1404 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1405 tcg_temp_free_i32(helper_tmp); \
1408 typedef struct DisasContext
{
1409 struct TranslationBlock
*tb
;
1410 target_ulong pc
, saved_pc
;
1412 int singlestep_enabled
;
1414 int32_t CP0_Config1
;
1415 /* Routine used to access memory */
1417 uint32_t hflags
, saved_hflags
;
1419 target_ulong btarget
;
1429 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1430 * exception condition */
1431 BS_STOP
= 1, /* We want to stop translation for any reason */
1432 BS_BRANCH
= 2, /* We reached a branch condition */
1433 BS_EXCP
= 3, /* We reached an exception condition */
1436 static const char * const regnames
[] = {
1437 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1438 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1439 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1440 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1443 static const char * const regnames_HI
[] = {
1444 "HI0", "HI1", "HI2", "HI3",
1447 static const char * const regnames_LO
[] = {
1448 "LO0", "LO1", "LO2", "LO3",
1451 static const char * const fregnames
[] = {
1452 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1453 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1454 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1455 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1458 static const char * const msaregnames
[] = {
1459 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1460 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1461 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1462 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1463 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1464 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1465 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1466 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1467 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1468 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1469 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1470 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1471 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1472 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1473 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1474 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1477 #define MIPS_DEBUG(fmt, ...) \
1479 if (MIPS_DEBUG_DISAS) { \
1480 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1481 TARGET_FMT_lx ": %08x " fmt "\n", \
1482 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1486 #define LOG_DISAS(...) \
1488 if (MIPS_DEBUG_DISAS) { \
1489 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1493 #define MIPS_INVAL(op) \
1494 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1495 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1497 /* General purpose registers moves. */
1498 static inline void gen_load_gpr (TCGv t
, int reg
)
1501 tcg_gen_movi_tl(t
, 0);
1503 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1506 static inline void gen_store_gpr (TCGv t
, int reg
)
1509 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1512 /* Moves to/from shadow registers. */
1513 static inline void gen_load_srsgpr (int from
, int to
)
1515 TCGv t0
= tcg_temp_new();
1518 tcg_gen_movi_tl(t0
, 0);
1520 TCGv_i32 t2
= tcg_temp_new_i32();
1521 TCGv_ptr addr
= tcg_temp_new_ptr();
1523 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1524 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1525 tcg_gen_andi_i32(t2
, t2
, 0xf);
1526 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1527 tcg_gen_ext_i32_ptr(addr
, t2
);
1528 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1530 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1531 tcg_temp_free_ptr(addr
);
1532 tcg_temp_free_i32(t2
);
1534 gen_store_gpr(t0
, to
);
1538 static inline void gen_store_srsgpr (int from
, int to
)
1541 TCGv t0
= tcg_temp_new();
1542 TCGv_i32 t2
= tcg_temp_new_i32();
1543 TCGv_ptr addr
= tcg_temp_new_ptr();
1545 gen_load_gpr(t0
, from
);
1546 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1547 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1548 tcg_gen_andi_i32(t2
, t2
, 0xf);
1549 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1550 tcg_gen_ext_i32_ptr(addr
, t2
);
1551 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1553 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1554 tcg_temp_free_ptr(addr
);
1555 tcg_temp_free_i32(t2
);
1560 /* Floating point register moves. */
1561 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1563 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1566 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1568 TCGv_i64 t64
= tcg_temp_new_i64();
1569 tcg_gen_extu_i32_i64(t64
, t
);
1570 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1571 tcg_temp_free_i64(t64
);
1574 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1576 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1577 TCGv_i64 t64
= tcg_temp_new_i64();
1578 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1579 tcg_gen_trunc_i64_i32(t
, t64
);
1580 tcg_temp_free_i64(t64
);
1582 gen_load_fpr32(t
, reg
| 1);
1586 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1588 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1589 TCGv_i64 t64
= tcg_temp_new_i64();
1590 tcg_gen_extu_i32_i64(t64
, t
);
1591 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1592 tcg_temp_free_i64(t64
);
1594 gen_store_fpr32(t
, reg
| 1);
1598 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1600 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1601 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1603 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1607 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1609 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1610 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1613 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1614 t0
= tcg_temp_new_i64();
1615 tcg_gen_shri_i64(t0
, t
, 32);
1616 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1617 tcg_temp_free_i64(t0
);
1621 static inline int get_fp_bit (int cc
)
1630 static inline void gen_save_pc(target_ulong pc
)
1632 tcg_gen_movi_tl(cpu_PC
, pc
);
1635 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1637 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1638 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1639 gen_save_pc(ctx
->pc
);
1640 ctx
->saved_pc
= ctx
->pc
;
1642 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1643 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1644 ctx
->saved_hflags
= ctx
->hflags
;
1645 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1651 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1657 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1659 ctx
->saved_hflags
= ctx
->hflags
;
1660 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1666 ctx
->btarget
= env
->btarget
;
1672 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1674 TCGv_i32 texcp
= tcg_const_i32(excp
);
1675 TCGv_i32 terr
= tcg_const_i32(err
);
1676 save_cpu_state(ctx
, 1);
1677 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1678 tcg_temp_free_i32(terr
);
1679 tcg_temp_free_i32(texcp
);
1683 generate_exception (DisasContext
*ctx
, int excp
)
1685 save_cpu_state(ctx
, 1);
1686 gen_helper_0e0i(raise_exception
, excp
);
1689 /* Addresses computation */
1690 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1692 tcg_gen_add_tl(ret
, arg0
, arg1
);
1694 #if defined(TARGET_MIPS64)
1695 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1696 tcg_gen_ext32s_i64(ret
, ret
);
1701 /* Addresses computation (translation time) */
1702 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1705 target_long sum
= base
+ offset
;
1707 #if defined(TARGET_MIPS64)
1708 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1715 static inline void check_cp0_enabled(DisasContext
*ctx
)
1717 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1718 generate_exception_err(ctx
, EXCP_CpU
, 0);
1721 static inline void check_cp1_enabled(DisasContext
*ctx
)
1723 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1724 generate_exception_err(ctx
, EXCP_CpU
, 1);
1727 /* Verify that the processor is running with COP1X instructions enabled.
1728 This is associated with the nabla symbol in the MIPS32 and MIPS64
1731 static inline void check_cop1x(DisasContext
*ctx
)
1733 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1734 generate_exception(ctx
, EXCP_RI
);
1737 /* Verify that the processor is running with 64-bit floating-point
1738 operations enabled. */
1740 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1742 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1743 generate_exception(ctx
, EXCP_RI
);
1747 * Verify if floating point register is valid; an operation is not defined
1748 * if bit 0 of any register specification is set and the FR bit in the
1749 * Status register equals zero, since the register numbers specify an
1750 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1751 * in the Status register equals one, both even and odd register numbers
1752 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1754 * Multiple 64 bit wide registers can be checked by calling
1755 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1757 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1759 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1760 generate_exception(ctx
, EXCP_RI
);
1763 /* Verify that the processor is running with DSP instructions enabled.
1764 This is enabled by CP0 Status register MX(24) bit.
1767 static inline void check_dsp(DisasContext
*ctx
)
1769 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1770 if (ctx
->insn_flags
& ASE_DSP
) {
1771 generate_exception(ctx
, EXCP_DSPDIS
);
1773 generate_exception(ctx
, EXCP_RI
);
1778 static inline void check_dspr2(DisasContext
*ctx
)
1780 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1781 if (ctx
->insn_flags
& ASE_DSP
) {
1782 generate_exception(ctx
, EXCP_DSPDIS
);
1784 generate_exception(ctx
, EXCP_RI
);
1789 /* This code generates a "reserved instruction" exception if the
1790 CPU does not support the instruction set corresponding to flags. */
1791 static inline void check_insn(DisasContext
*ctx
, int flags
)
1793 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1794 generate_exception(ctx
, EXCP_RI
);
1798 /* This code generates a "reserved instruction" exception if the
1799 CPU has corresponding flag set which indicates that the instruction
1800 has been removed. */
1801 static inline void check_insn_opc_removed(DisasContext
*ctx
, int flags
)
1803 if (unlikely(ctx
->insn_flags
& flags
)) {
1804 generate_exception(ctx
, EXCP_RI
);
1808 #ifdef TARGET_MIPS64
1809 /* This code generates a "reserved instruction" exception if 64-bit
1810 instructions are not enabled. */
1811 static inline void check_mips_64(DisasContext
*ctx
)
1813 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1814 generate_exception(ctx
, EXCP_RI
);
1818 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1819 calling interface for 32 and 64-bit FPRs. No sense in changing
1820 all callers for gen_load_fpr32 when we need the CTX parameter for
1822 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1823 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1824 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1825 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1826 int ft, int fs, int cc) \
1828 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1829 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1832 check_cp1_64bitmode(ctx); \
1838 check_cp1_registers(ctx, fs | ft); \
1846 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1847 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1849 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1850 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1851 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1852 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1853 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1854 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1855 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1856 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1857 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1858 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1859 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1860 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1861 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1862 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1863 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1864 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1867 tcg_temp_free_i##bits (fp0); \
1868 tcg_temp_free_i##bits (fp1); \
1871 FOP_CONDS(, 0, d
, FMT_D
, 64)
1872 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1873 FOP_CONDS(, 0, s
, FMT_S
, 32)
1874 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1875 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1876 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1879 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1880 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1881 int ft, int fs, int fd) \
1883 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1884 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1885 if (ifmt == FMT_D) { \
1886 check_cp1_registers(ctx, fs | ft | fd); \
1888 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1889 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1892 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1895 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1898 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1901 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1904 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1907 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1910 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1913 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1916 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1919 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1922 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1925 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1928 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1931 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1934 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1937 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1940 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1943 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1946 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1949 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1952 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1955 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1961 tcg_temp_free_i ## bits (fp0); \
1962 tcg_temp_free_i ## bits (fp1); \
1965 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
1966 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(fp0
, fd
))
1968 #undef gen_ldcmp_fpr32
1969 #undef gen_ldcmp_fpr64
1971 /* load/store instructions. */
1972 #ifdef CONFIG_USER_ONLY
1973 #define OP_LD_ATOMIC(insn,fname) \
1974 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1976 TCGv t0 = tcg_temp_new(); \
1977 tcg_gen_mov_tl(t0, arg1); \
1978 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1979 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1980 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1981 tcg_temp_free(t0); \
1984 #define OP_LD_ATOMIC(insn,fname) \
1985 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1987 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1990 OP_LD_ATOMIC(ll
,ld32s
);
1991 #if defined(TARGET_MIPS64)
1992 OP_LD_ATOMIC(lld
,ld64
);
1996 #ifdef CONFIG_USER_ONLY
1997 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1998 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2000 TCGv t0 = tcg_temp_new(); \
2001 TCGLabel *l1 = gen_new_label(); \
2002 TCGLabel *l2 = gen_new_label(); \
2004 tcg_gen_andi_tl(t0, arg2, almask); \
2005 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2006 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2007 generate_exception(ctx, EXCP_AdES); \
2008 gen_set_label(l1); \
2009 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2010 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2011 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2012 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2013 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2014 gen_helper_0e0i(raise_exception, EXCP_SC); \
2015 gen_set_label(l2); \
2016 tcg_gen_movi_tl(t0, 0); \
2017 gen_store_gpr(t0, rt); \
2018 tcg_temp_free(t0); \
2021 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2022 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2024 TCGv t0 = tcg_temp_new(); \
2025 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2026 gen_store_gpr(t0, rt); \
2027 tcg_temp_free(t0); \
2030 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
2031 #if defined(TARGET_MIPS64)
2032 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
2036 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
2037 int base
, int16_t offset
)
2040 tcg_gen_movi_tl(addr
, offset
);
2041 } else if (offset
== 0) {
2042 gen_load_gpr(addr
, base
);
2044 tcg_gen_movi_tl(addr
, offset
);
2045 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2049 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
2051 target_ulong pc
= ctx
->pc
;
2053 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2054 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2059 pc
&= ~(target_ulong
)3;
2064 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2065 int rt
, int base
, int16_t offset
)
2067 const char *opn
= "ld";
2070 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
2071 /* Loongson CPU uses a load to zero register for prefetch.
2072 We emulate it as a NOP. On other CPU we must perform the
2073 actual memory access. */
2078 t0
= tcg_temp_new();
2079 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2082 #if defined(TARGET_MIPS64)
2084 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2085 gen_store_gpr(t0
, rt
);
2089 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2090 gen_store_gpr(t0
, rt
);
2095 save_cpu_state(ctx
, 1);
2096 op_ld_lld(t0
, t0
, ctx
);
2097 gen_store_gpr(t0
, rt
);
2101 t1
= tcg_temp_new();
2102 tcg_gen_andi_tl(t1
, t0
, 7);
2103 #ifndef TARGET_WORDS_BIGENDIAN
2104 tcg_gen_xori_tl(t1
, t1
, 7);
2106 tcg_gen_shli_tl(t1
, t1
, 3);
2107 tcg_gen_andi_tl(t0
, t0
, ~7);
2108 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2109 tcg_gen_shl_tl(t0
, t0
, t1
);
2110 tcg_gen_xori_tl(t1
, t1
, 63);
2111 t2
= tcg_const_tl(0x7fffffffffffffffull
);
2112 tcg_gen_shr_tl(t2
, t2
, t1
);
2113 gen_load_gpr(t1
, rt
);
2114 tcg_gen_and_tl(t1
, t1
, t2
);
2116 tcg_gen_or_tl(t0
, t0
, t1
);
2118 gen_store_gpr(t0
, rt
);
2122 t1
= tcg_temp_new();
2123 tcg_gen_andi_tl(t1
, t0
, 7);
2124 #ifdef TARGET_WORDS_BIGENDIAN
2125 tcg_gen_xori_tl(t1
, t1
, 7);
2127 tcg_gen_shli_tl(t1
, t1
, 3);
2128 tcg_gen_andi_tl(t0
, t0
, ~7);
2129 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2130 tcg_gen_shr_tl(t0
, t0
, t1
);
2131 tcg_gen_xori_tl(t1
, t1
, 63);
2132 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2133 tcg_gen_shl_tl(t2
, t2
, t1
);
2134 gen_load_gpr(t1
, rt
);
2135 tcg_gen_and_tl(t1
, t1
, t2
);
2137 tcg_gen_or_tl(t0
, t0
, t1
);
2139 gen_store_gpr(t0
, rt
);
2143 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2144 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2146 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2147 gen_store_gpr(t0
, rt
);
2152 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2153 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2155 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
2156 gen_store_gpr(t0
, rt
);
2160 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
2161 gen_store_gpr(t0
, rt
);
2165 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
2166 gen_store_gpr(t0
, rt
);
2170 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
2171 gen_store_gpr(t0
, rt
);
2175 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
2176 gen_store_gpr(t0
, rt
);
2180 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
2181 gen_store_gpr(t0
, rt
);
2185 t1
= tcg_temp_new();
2186 tcg_gen_andi_tl(t1
, t0
, 3);
2187 #ifndef TARGET_WORDS_BIGENDIAN
2188 tcg_gen_xori_tl(t1
, t1
, 3);
2190 tcg_gen_shli_tl(t1
, t1
, 3);
2191 tcg_gen_andi_tl(t0
, t0
, ~3);
2192 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2193 tcg_gen_shl_tl(t0
, t0
, t1
);
2194 tcg_gen_xori_tl(t1
, t1
, 31);
2195 t2
= tcg_const_tl(0x7fffffffull
);
2196 tcg_gen_shr_tl(t2
, t2
, t1
);
2197 gen_load_gpr(t1
, rt
);
2198 tcg_gen_and_tl(t1
, t1
, t2
);
2200 tcg_gen_or_tl(t0
, t0
, t1
);
2202 tcg_gen_ext32s_tl(t0
, t0
);
2203 gen_store_gpr(t0
, rt
);
2207 t1
= tcg_temp_new();
2208 tcg_gen_andi_tl(t1
, t0
, 3);
2209 #ifdef TARGET_WORDS_BIGENDIAN
2210 tcg_gen_xori_tl(t1
, t1
, 3);
2212 tcg_gen_shli_tl(t1
, t1
, 3);
2213 tcg_gen_andi_tl(t0
, t0
, ~3);
2214 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2215 tcg_gen_shr_tl(t0
, t0
, t1
);
2216 tcg_gen_xori_tl(t1
, t1
, 31);
2217 t2
= tcg_const_tl(0xfffffffeull
);
2218 tcg_gen_shl_tl(t2
, t2
, t1
);
2219 gen_load_gpr(t1
, rt
);
2220 tcg_gen_and_tl(t1
, t1
, t2
);
2222 tcg_gen_or_tl(t0
, t0
, t1
);
2224 tcg_gen_ext32s_tl(t0
, t0
);
2225 gen_store_gpr(t0
, rt
);
2230 save_cpu_state(ctx
, 1);
2231 op_ld_ll(t0
, t0
, ctx
);
2232 gen_store_gpr(t0
, rt
);
2236 (void)opn
; /* avoid a compiler warning */
2237 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2242 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
2243 int base
, int16_t offset
)
2245 const char *opn
= "st";
2246 TCGv t0
= tcg_temp_new();
2247 TCGv t1
= tcg_temp_new();
2249 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2250 gen_load_gpr(t1
, rt
);
2252 #if defined(TARGET_MIPS64)
2254 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
2258 save_cpu_state(ctx
, 1);
2259 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
2263 save_cpu_state(ctx
, 1);
2264 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
2269 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
2273 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
2277 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
2281 save_cpu_state(ctx
, 1);
2282 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
2286 save_cpu_state(ctx
, 1);
2287 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
2291 (void)opn
; /* avoid a compiler warning */
2292 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2298 /* Store conditional */
2299 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
2300 int base
, int16_t offset
)
2302 const char *opn
= "st_cond";
2305 #ifdef CONFIG_USER_ONLY
2306 t0
= tcg_temp_local_new();
2307 t1
= tcg_temp_local_new();
2309 t0
= tcg_temp_new();
2310 t1
= tcg_temp_new();
2312 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2313 gen_load_gpr(t1
, rt
);
2315 #if defined(TARGET_MIPS64)
2318 save_cpu_state(ctx
, 1);
2319 op_st_scd(t1
, t0
, rt
, ctx
);
2325 save_cpu_state(ctx
, 1);
2326 op_st_sc(t1
, t0
, rt
, ctx
);
2330 (void)opn
; /* avoid a compiler warning */
2331 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2336 /* Load and store */
2337 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
2338 int base
, int16_t offset
)
2340 const char *opn
= "flt_ldst";
2341 TCGv t0
= tcg_temp_new();
2343 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2344 /* Don't do NOP if destination is zero: we must perform the actual
2349 TCGv_i32 fp0
= tcg_temp_new_i32();
2350 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
2351 gen_store_fpr32(fp0
, ft
);
2352 tcg_temp_free_i32(fp0
);
2358 TCGv_i32 fp0
= tcg_temp_new_i32();
2359 gen_load_fpr32(fp0
, ft
);
2360 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2361 tcg_temp_free_i32(fp0
);
2367 TCGv_i64 fp0
= tcg_temp_new_i64();
2368 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2369 gen_store_fpr64(ctx
, fp0
, ft
);
2370 tcg_temp_free_i64(fp0
);
2376 TCGv_i64 fp0
= tcg_temp_new_i64();
2377 gen_load_fpr64(ctx
, fp0
, ft
);
2378 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2379 tcg_temp_free_i64(fp0
);
2385 generate_exception(ctx
, EXCP_RI
);
2388 (void)opn
; /* avoid a compiler warning */
2389 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
2394 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2395 int rs
, int16_t imm
)
2397 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2398 check_cp1_enabled(ctx
);
2402 check_insn(ctx
, ISA_MIPS2
);
2405 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
2408 generate_exception_err(ctx
, EXCP_CpU
, 1);
2412 /* Arithmetic with immediate operand */
2413 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2414 int rt
, int rs
, int16_t imm
)
2416 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2417 const char *opn
= "imm arith";
2419 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2420 /* If no destination, treat it as a NOP.
2421 For addi, we must generate the overflow exception when needed. */
2428 TCGv t0
= tcg_temp_local_new();
2429 TCGv t1
= tcg_temp_new();
2430 TCGv t2
= tcg_temp_new();
2431 TCGLabel
*l1
= gen_new_label();
2433 gen_load_gpr(t1
, rs
);
2434 tcg_gen_addi_tl(t0
, t1
, uimm
);
2435 tcg_gen_ext32s_tl(t0
, t0
);
2437 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2438 tcg_gen_xori_tl(t2
, t0
, uimm
);
2439 tcg_gen_and_tl(t1
, t1
, t2
);
2441 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2443 /* operands of same sign, result different sign */
2444 generate_exception(ctx
, EXCP_OVERFLOW
);
2446 tcg_gen_ext32s_tl(t0
, t0
);
2447 gen_store_gpr(t0
, rt
);
2454 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2455 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2457 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2461 #if defined(TARGET_MIPS64)
2464 TCGv t0
= tcg_temp_local_new();
2465 TCGv t1
= tcg_temp_new();
2466 TCGv t2
= tcg_temp_new();
2467 TCGLabel
*l1
= gen_new_label();
2469 gen_load_gpr(t1
, rs
);
2470 tcg_gen_addi_tl(t0
, t1
, uimm
);
2472 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2473 tcg_gen_xori_tl(t2
, t0
, uimm
);
2474 tcg_gen_and_tl(t1
, t1
, t2
);
2476 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2478 /* operands of same sign, result different sign */
2479 generate_exception(ctx
, EXCP_OVERFLOW
);
2481 gen_store_gpr(t0
, rt
);
2488 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2490 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2496 (void)opn
; /* avoid a compiler warning */
2497 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2500 /* Logic with immediate operand */
2501 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2502 int rt
, int rs
, int16_t imm
)
2507 /* If no destination, treat it as a NOP. */
2511 uimm
= (uint16_t)imm
;
2514 if (likely(rs
!= 0))
2515 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2517 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2518 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2519 regnames
[rs
], uimm
);
2523 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2525 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2526 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2527 regnames
[rs
], uimm
);
2530 if (likely(rs
!= 0))
2531 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2533 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2534 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2535 regnames
[rs
], uimm
);
2538 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
2540 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2541 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2542 MIPS_DEBUG("aui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
2544 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2545 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2550 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2555 /* Set on less than with immediate operand */
2556 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2557 int rt
, int rs
, int16_t imm
)
2559 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2560 const char *opn
= "imm arith";
2564 /* If no destination, treat it as a NOP. */
2568 t0
= tcg_temp_new();
2569 gen_load_gpr(t0
, rs
);
2572 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2576 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2580 (void)opn
; /* avoid a compiler warning */
2581 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2585 /* Shifts with immediate operand */
2586 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2587 int rt
, int rs
, int16_t imm
)
2589 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2590 const char *opn
= "imm shift";
2594 /* If no destination, treat it as a NOP. */
2599 t0
= tcg_temp_new();
2600 gen_load_gpr(t0
, rs
);
2603 tcg_gen_shli_tl(t0
, t0
, uimm
);
2604 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2608 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2613 tcg_gen_ext32u_tl(t0
, t0
);
2614 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2616 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2622 TCGv_i32 t1
= tcg_temp_new_i32();
2624 tcg_gen_trunc_tl_i32(t1
, t0
);
2625 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2626 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2627 tcg_temp_free_i32(t1
);
2629 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2633 #if defined(TARGET_MIPS64)
2635 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2639 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2643 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2648 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2650 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2655 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2659 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2663 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2667 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2672 (void)opn
; /* avoid a compiler warning */
2673 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2678 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2679 int rd
, int rs
, int rt
)
2681 const char *opn
= "arith";
2683 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2684 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2685 /* If no destination, treat it as a NOP.
2686 For add & sub, we must generate the overflow exception when needed. */
2694 TCGv t0
= tcg_temp_local_new();
2695 TCGv t1
= tcg_temp_new();
2696 TCGv t2
= tcg_temp_new();
2697 TCGLabel
*l1
= gen_new_label();
2699 gen_load_gpr(t1
, rs
);
2700 gen_load_gpr(t2
, rt
);
2701 tcg_gen_add_tl(t0
, t1
, t2
);
2702 tcg_gen_ext32s_tl(t0
, t0
);
2703 tcg_gen_xor_tl(t1
, t1
, t2
);
2704 tcg_gen_xor_tl(t2
, t0
, t2
);
2705 tcg_gen_andc_tl(t1
, t2
, t1
);
2707 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2709 /* operands of same sign, result different sign */
2710 generate_exception(ctx
, EXCP_OVERFLOW
);
2712 gen_store_gpr(t0
, rd
);
2718 if (rs
!= 0 && rt
!= 0) {
2719 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2720 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2721 } else if (rs
== 0 && rt
!= 0) {
2722 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2723 } else if (rs
!= 0 && rt
== 0) {
2724 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2726 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2732 TCGv t0
= tcg_temp_local_new();
2733 TCGv t1
= tcg_temp_new();
2734 TCGv t2
= tcg_temp_new();
2735 TCGLabel
*l1
= gen_new_label();
2737 gen_load_gpr(t1
, rs
);
2738 gen_load_gpr(t2
, rt
);
2739 tcg_gen_sub_tl(t0
, t1
, t2
);
2740 tcg_gen_ext32s_tl(t0
, t0
);
2741 tcg_gen_xor_tl(t2
, t1
, t2
);
2742 tcg_gen_xor_tl(t1
, t0
, t1
);
2743 tcg_gen_and_tl(t1
, t1
, t2
);
2745 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2747 /* operands of different sign, first operand and result different sign */
2748 generate_exception(ctx
, EXCP_OVERFLOW
);
2750 gen_store_gpr(t0
, rd
);
2756 if (rs
!= 0 && rt
!= 0) {
2757 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2758 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2759 } else if (rs
== 0 && rt
!= 0) {
2760 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2761 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2762 } else if (rs
!= 0 && rt
== 0) {
2763 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2765 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2769 #if defined(TARGET_MIPS64)
2772 TCGv t0
= tcg_temp_local_new();
2773 TCGv t1
= tcg_temp_new();
2774 TCGv t2
= tcg_temp_new();
2775 TCGLabel
*l1
= gen_new_label();
2777 gen_load_gpr(t1
, rs
);
2778 gen_load_gpr(t2
, rt
);
2779 tcg_gen_add_tl(t0
, t1
, t2
);
2780 tcg_gen_xor_tl(t1
, t1
, t2
);
2781 tcg_gen_xor_tl(t2
, t0
, t2
);
2782 tcg_gen_andc_tl(t1
, t2
, t1
);
2784 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2786 /* operands of same sign, result different sign */
2787 generate_exception(ctx
, EXCP_OVERFLOW
);
2789 gen_store_gpr(t0
, rd
);
2795 if (rs
!= 0 && rt
!= 0) {
2796 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2797 } else if (rs
== 0 && rt
!= 0) {
2798 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2799 } else if (rs
!= 0 && rt
== 0) {
2800 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2802 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2808 TCGv t0
= tcg_temp_local_new();
2809 TCGv t1
= tcg_temp_new();
2810 TCGv t2
= tcg_temp_new();
2811 TCGLabel
*l1
= gen_new_label();
2813 gen_load_gpr(t1
, rs
);
2814 gen_load_gpr(t2
, rt
);
2815 tcg_gen_sub_tl(t0
, t1
, t2
);
2816 tcg_gen_xor_tl(t2
, t1
, t2
);
2817 tcg_gen_xor_tl(t1
, t0
, t1
);
2818 tcg_gen_and_tl(t1
, t1
, t2
);
2820 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2822 /* operands of different sign, first operand and result different sign */
2823 generate_exception(ctx
, EXCP_OVERFLOW
);
2825 gen_store_gpr(t0
, rd
);
2831 if (rs
!= 0 && rt
!= 0) {
2832 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2833 } else if (rs
== 0 && rt
!= 0) {
2834 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2835 } else if (rs
!= 0 && rt
== 0) {
2836 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2838 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2844 if (likely(rs
!= 0 && rt
!= 0)) {
2845 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2846 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2848 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2853 (void)opn
; /* avoid a compiler warning */
2854 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2857 /* Conditional move */
2858 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2859 int rd
, int rs
, int rt
)
2861 const char *opn
= "cond move";
2865 /* If no destination, treat it as a NOP. */
2870 t0
= tcg_temp_new();
2871 gen_load_gpr(t0
, rt
);
2872 t1
= tcg_const_tl(0);
2873 t2
= tcg_temp_new();
2874 gen_load_gpr(t2
, rs
);
2877 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2881 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2885 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2889 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2897 (void)opn
; /* avoid a compiler warning */
2898 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2902 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2903 int rd
, int rs
, int rt
)
2905 const char *opn
= "logic";
2908 /* If no destination, treat it as a NOP. */
2915 if (likely(rs
!= 0 && rt
!= 0)) {
2916 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2918 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2923 if (rs
!= 0 && rt
!= 0) {
2924 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2925 } else if (rs
== 0 && rt
!= 0) {
2926 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2927 } else if (rs
!= 0 && rt
== 0) {
2928 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2930 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2935 if (likely(rs
!= 0 && rt
!= 0)) {
2936 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2937 } else if (rs
== 0 && rt
!= 0) {
2938 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2939 } else if (rs
!= 0 && rt
== 0) {
2940 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2942 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2947 if (likely(rs
!= 0 && rt
!= 0)) {
2948 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2949 } else if (rs
== 0 && rt
!= 0) {
2950 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2951 } else if (rs
!= 0 && rt
== 0) {
2952 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2954 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2959 (void)opn
; /* avoid a compiler warning */
2960 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2963 /* Set on lower than */
2964 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2965 int rd
, int rs
, int rt
)
2967 const char *opn
= "slt";
2971 /* If no destination, treat it as a NOP. */
2976 t0
= tcg_temp_new();
2977 t1
= tcg_temp_new();
2978 gen_load_gpr(t0
, rs
);
2979 gen_load_gpr(t1
, rt
);
2982 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2986 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2990 (void)opn
; /* avoid a compiler warning */
2991 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2997 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2998 int rd
, int rs
, int rt
)
3000 const char *opn
= "shifts";
3004 /* If no destination, treat it as a NOP.
3005 For add & sub, we must generate the overflow exception when needed. */
3010 t0
= tcg_temp_new();
3011 t1
= tcg_temp_new();
3012 gen_load_gpr(t0
, rs
);
3013 gen_load_gpr(t1
, rt
);
3016 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3017 tcg_gen_shl_tl(t0
, t1
, t0
);
3018 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3022 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3023 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3027 tcg_gen_ext32u_tl(t1
, t1
);
3028 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3029 tcg_gen_shr_tl(t0
, t1
, t0
);
3030 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3035 TCGv_i32 t2
= tcg_temp_new_i32();
3036 TCGv_i32 t3
= tcg_temp_new_i32();
3038 tcg_gen_trunc_tl_i32(t2
, t0
);
3039 tcg_gen_trunc_tl_i32(t3
, t1
);
3040 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3041 tcg_gen_rotr_i32(t2
, t3
, t2
);
3042 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3043 tcg_temp_free_i32(t2
);
3044 tcg_temp_free_i32(t3
);
3048 #if defined(TARGET_MIPS64)
3050 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3051 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3055 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3056 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3060 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3061 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3065 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3066 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3071 (void)opn
; /* avoid a compiler warning */
3072 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3077 /* Arithmetic on HI/LO registers */
3078 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3080 const char *opn
= "hilo";
3082 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3094 #if defined(TARGET_MIPS64)
3096 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3100 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3105 #if defined(TARGET_MIPS64)
3107 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3111 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3117 #if defined(TARGET_MIPS64)
3119 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3123 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3126 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3132 #if defined(TARGET_MIPS64)
3134 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3138 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3141 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3146 (void)opn
; /* avoid a compiler warning */
3147 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
3150 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3153 TCGv t0
= tcg_const_tl(addr
);
3154 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3155 gen_store_gpr(t0
, reg
);
3159 static inline void gen_pcrel(DisasContext
*ctx
, int rs
, int16_t imm
)
3164 switch (MASK_OPC_PCREL_TOP2BITS(ctx
->opcode
)) {
3167 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3168 addr
= addr_add(ctx
, ctx
->pc
, offset
);
3169 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3173 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3174 addr
= addr_add(ctx
, ctx
->pc
, offset
);
3175 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3177 #if defined(TARGET_MIPS64)
3180 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3181 addr
= addr_add(ctx
, ctx
->pc
, offset
);
3182 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3186 switch (MASK_OPC_PCREL_TOP5BITS(ctx
->opcode
)) {
3190 addr
= addr_add(ctx
, ctx
->pc
, offset
);
3191 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3197 addr
= ~0xFFFF & addr_add(ctx
, ctx
->pc
, offset
);
3198 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3201 #if defined(TARGET_MIPS64)
3202 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3203 case R6_OPC_LDPC
+ (1 << 16):
3204 case R6_OPC_LDPC
+ (2 << 16):
3205 case R6_OPC_LDPC
+ (3 << 16):
3207 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3208 addr
= addr_add(ctx
, (ctx
->pc
& ~0x7), offset
);
3209 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3213 MIPS_INVAL("OPC_PCREL");
3214 generate_exception(ctx
, EXCP_RI
);
3221 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3223 const char *opn
= "r6 mul/div";
3232 t0
= tcg_temp_new();
3233 t1
= tcg_temp_new();
3235 gen_load_gpr(t0
, rs
);
3236 gen_load_gpr(t1
, rt
);
3241 TCGv t2
= tcg_temp_new();
3242 TCGv t3
= tcg_temp_new();
3243 tcg_gen_ext32s_tl(t0
, t0
);
3244 tcg_gen_ext32s_tl(t1
, t1
);
3245 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3246 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3247 tcg_gen_and_tl(t2
, t2
, t3
);
3248 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3249 tcg_gen_or_tl(t2
, t2
, t3
);
3250 tcg_gen_movi_tl(t3
, 0);
3251 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3252 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3253 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3261 TCGv t2
= tcg_temp_new();
3262 TCGv t3
= tcg_temp_new();
3263 tcg_gen_ext32s_tl(t0
, t0
);
3264 tcg_gen_ext32s_tl(t1
, t1
);
3265 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3266 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3267 tcg_gen_and_tl(t2
, t2
, t3
);
3268 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3269 tcg_gen_or_tl(t2
, t2
, t3
);
3270 tcg_gen_movi_tl(t3
, 0);
3271 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3272 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3273 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3281 TCGv t2
= tcg_const_tl(0);
3282 TCGv t3
= tcg_const_tl(1);
3283 tcg_gen_ext32u_tl(t0
, t0
);
3284 tcg_gen_ext32u_tl(t1
, t1
);
3285 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3286 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3287 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3295 TCGv t2
= tcg_const_tl(0);
3296 TCGv t3
= tcg_const_tl(1);
3297 tcg_gen_ext32u_tl(t0
, t0
);
3298 tcg_gen_ext32u_tl(t1
, t1
);
3299 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3300 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3301 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3309 TCGv_i32 t2
= tcg_temp_new_i32();
3310 TCGv_i32 t3
= tcg_temp_new_i32();
3311 tcg_gen_trunc_tl_i32(t2
, t0
);
3312 tcg_gen_trunc_tl_i32(t3
, t1
);
3313 tcg_gen_mul_i32(t2
, t2
, t3
);
3314 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3315 tcg_temp_free_i32(t2
);
3316 tcg_temp_free_i32(t3
);
3322 TCGv_i32 t2
= tcg_temp_new_i32();
3323 TCGv_i32 t3
= tcg_temp_new_i32();
3324 tcg_gen_trunc_tl_i32(t2
, t0
);
3325 tcg_gen_trunc_tl_i32(t3
, t1
);
3326 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3327 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3328 tcg_temp_free_i32(t2
);
3329 tcg_temp_free_i32(t3
);
3335 TCGv_i32 t2
= tcg_temp_new_i32();
3336 TCGv_i32 t3
= tcg_temp_new_i32();
3337 tcg_gen_trunc_tl_i32(t2
, t0
);
3338 tcg_gen_trunc_tl_i32(t3
, t1
);
3339 tcg_gen_mul_i32(t2
, t2
, t3
);
3340 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3341 tcg_temp_free_i32(t2
);
3342 tcg_temp_free_i32(t3
);
3348 TCGv_i32 t2
= tcg_temp_new_i32();
3349 TCGv_i32 t3
= tcg_temp_new_i32();
3350 tcg_gen_trunc_tl_i32(t2
, t0
);
3351 tcg_gen_trunc_tl_i32(t3
, t1
);
3352 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3353 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3354 tcg_temp_free_i32(t2
);
3355 tcg_temp_free_i32(t3
);
3359 #if defined(TARGET_MIPS64)
3362 TCGv t2
= tcg_temp_new();
3363 TCGv t3
= tcg_temp_new();
3364 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3365 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3366 tcg_gen_and_tl(t2
, t2
, t3
);
3367 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3368 tcg_gen_or_tl(t2
, t2
, t3
);
3369 tcg_gen_movi_tl(t3
, 0);
3370 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3371 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3379 TCGv t2
= tcg_temp_new();
3380 TCGv t3
= tcg_temp_new();
3381 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3382 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3383 tcg_gen_and_tl(t2
, t2
, t3
);
3384 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3385 tcg_gen_or_tl(t2
, t2
, t3
);
3386 tcg_gen_movi_tl(t3
, 0);
3387 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3388 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3396 TCGv t2
= tcg_const_tl(0);
3397 TCGv t3
= tcg_const_tl(1);
3398 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3399 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3407 TCGv t2
= tcg_const_tl(0);
3408 TCGv t3
= tcg_const_tl(1);
3409 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3410 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3417 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3422 TCGv t2
= tcg_temp_new();
3423 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3429 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3434 TCGv t2
= tcg_temp_new();
3435 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3443 generate_exception(ctx
, EXCP_RI
);
3446 (void)opn
; /* avoid a compiler warning */
3447 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3453 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3454 int acc
, int rs
, int rt
)
3456 const char *opn
= "mul/div";
3459 t0
= tcg_temp_new();
3460 t1
= tcg_temp_new();
3462 gen_load_gpr(t0
, rs
);
3463 gen_load_gpr(t1
, rt
);
3472 TCGv t2
= tcg_temp_new();
3473 TCGv t3
= tcg_temp_new();
3474 tcg_gen_ext32s_tl(t0
, t0
);
3475 tcg_gen_ext32s_tl(t1
, t1
);
3476 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3477 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3478 tcg_gen_and_tl(t2
, t2
, t3
);
3479 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3480 tcg_gen_or_tl(t2
, t2
, t3
);
3481 tcg_gen_movi_tl(t3
, 0);
3482 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3483 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3484 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3485 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3486 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3494 TCGv t2
= tcg_const_tl(0);
3495 TCGv t3
= tcg_const_tl(1);
3496 tcg_gen_ext32u_tl(t0
, t0
);
3497 tcg_gen_ext32u_tl(t1
, t1
);
3498 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3499 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3500 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3501 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3502 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3510 TCGv_i32 t2
= tcg_temp_new_i32();
3511 TCGv_i32 t3
= tcg_temp_new_i32();
3512 tcg_gen_trunc_tl_i32(t2
, t0
);
3513 tcg_gen_trunc_tl_i32(t3
, t1
);
3514 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3515 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3516 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3517 tcg_temp_free_i32(t2
);
3518 tcg_temp_free_i32(t3
);
3524 TCGv_i32 t2
= tcg_temp_new_i32();
3525 TCGv_i32 t3
= tcg_temp_new_i32();
3526 tcg_gen_trunc_tl_i32(t2
, t0
);
3527 tcg_gen_trunc_tl_i32(t3
, t1
);
3528 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3529 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3530 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3531 tcg_temp_free_i32(t2
);
3532 tcg_temp_free_i32(t3
);
3536 #if defined(TARGET_MIPS64)
3539 TCGv t2
= tcg_temp_new();
3540 TCGv t3
= tcg_temp_new();
3541 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3542 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3543 tcg_gen_and_tl(t2
, t2
, t3
);
3544 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3545 tcg_gen_or_tl(t2
, t2
, t3
);
3546 tcg_gen_movi_tl(t3
, 0);
3547 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3548 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3549 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3557 TCGv t2
= tcg_const_tl(0);
3558 TCGv t3
= tcg_const_tl(1);
3559 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3560 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3561 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3568 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3572 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3578 TCGv_i64 t2
= tcg_temp_new_i64();
3579 TCGv_i64 t3
= tcg_temp_new_i64();
3581 tcg_gen_ext_tl_i64(t2
, t0
);
3582 tcg_gen_ext_tl_i64(t3
, t1
);
3583 tcg_gen_mul_i64(t2
, t2
, t3
);
3584 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3585 tcg_gen_add_i64(t2
, t2
, t3
);
3586 tcg_temp_free_i64(t3
);
3587 tcg_gen_trunc_i64_tl(t0
, t2
);
3588 tcg_gen_shri_i64(t2
, t2
, 32);
3589 tcg_gen_trunc_i64_tl(t1
, t2
);
3590 tcg_temp_free_i64(t2
);
3591 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3592 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3598 TCGv_i64 t2
= tcg_temp_new_i64();
3599 TCGv_i64 t3
= tcg_temp_new_i64();
3601 tcg_gen_ext32u_tl(t0
, t0
);
3602 tcg_gen_ext32u_tl(t1
, t1
);
3603 tcg_gen_extu_tl_i64(t2
, t0
);
3604 tcg_gen_extu_tl_i64(t3
, t1
);
3605 tcg_gen_mul_i64(t2
, t2
, t3
);
3606 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3607 tcg_gen_add_i64(t2
, t2
, t3
);
3608 tcg_temp_free_i64(t3
);
3609 tcg_gen_trunc_i64_tl(t0
, t2
);
3610 tcg_gen_shri_i64(t2
, t2
, 32);
3611 tcg_gen_trunc_i64_tl(t1
, t2
);
3612 tcg_temp_free_i64(t2
);
3613 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3614 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3620 TCGv_i64 t2
= tcg_temp_new_i64();
3621 TCGv_i64 t3
= tcg_temp_new_i64();
3623 tcg_gen_ext_tl_i64(t2
, t0
);
3624 tcg_gen_ext_tl_i64(t3
, t1
);
3625 tcg_gen_mul_i64(t2
, t2
, t3
);
3626 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3627 tcg_gen_sub_i64(t2
, t3
, t2
);
3628 tcg_temp_free_i64(t3
);
3629 tcg_gen_trunc_i64_tl(t0
, t2
);
3630 tcg_gen_shri_i64(t2
, t2
, 32);
3631 tcg_gen_trunc_i64_tl(t1
, t2
);
3632 tcg_temp_free_i64(t2
);
3633 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3634 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3640 TCGv_i64 t2
= tcg_temp_new_i64();
3641 TCGv_i64 t3
= tcg_temp_new_i64();
3643 tcg_gen_ext32u_tl(t0
, t0
);
3644 tcg_gen_ext32u_tl(t1
, t1
);
3645 tcg_gen_extu_tl_i64(t2
, t0
);
3646 tcg_gen_extu_tl_i64(t3
, t1
);
3647 tcg_gen_mul_i64(t2
, t2
, t3
);
3648 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3649 tcg_gen_sub_i64(t2
, t3
, t2
);
3650 tcg_temp_free_i64(t3
);
3651 tcg_gen_trunc_i64_tl(t0
, t2
);
3652 tcg_gen_shri_i64(t2
, t2
, 32);
3653 tcg_gen_trunc_i64_tl(t1
, t2
);
3654 tcg_temp_free_i64(t2
);
3655 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3656 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3662 generate_exception(ctx
, EXCP_RI
);
3665 (void)opn
; /* avoid a compiler warning */
3666 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3672 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
3673 int rd
, int rs
, int rt
)
3675 const char *opn
= "mul vr54xx";
3676 TCGv t0
= tcg_temp_new();
3677 TCGv t1
= tcg_temp_new();
3679 gen_load_gpr(t0
, rs
);
3680 gen_load_gpr(t1
, rt
);
3683 case OPC_VR54XX_MULS
:
3684 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3687 case OPC_VR54XX_MULSU
:
3688 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3691 case OPC_VR54XX_MACC
:
3692 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3695 case OPC_VR54XX_MACCU
:
3696 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3699 case OPC_VR54XX_MSAC
:
3700 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3703 case OPC_VR54XX_MSACU
:
3704 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3707 case OPC_VR54XX_MULHI
:
3708 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3711 case OPC_VR54XX_MULHIU
:
3712 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3715 case OPC_VR54XX_MULSHI
:
3716 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3719 case OPC_VR54XX_MULSHIU
:
3720 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3723 case OPC_VR54XX_MACCHI
:
3724 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3727 case OPC_VR54XX_MACCHIU
:
3728 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3731 case OPC_VR54XX_MSACHI
:
3732 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3735 case OPC_VR54XX_MSACHIU
:
3736 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3740 MIPS_INVAL("mul vr54xx");
3741 generate_exception(ctx
, EXCP_RI
);
3744 gen_store_gpr(t0
, rd
);
3745 (void)opn
; /* avoid a compiler warning */
3746 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3753 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
3756 const char *opn
= "CLx";
3764 t0
= tcg_temp_new();
3765 gen_load_gpr(t0
, rs
);
3769 gen_helper_clo(cpu_gpr
[rd
], t0
);
3774 gen_helper_clz(cpu_gpr
[rd
], t0
);
3777 #if defined(TARGET_MIPS64)
3780 gen_helper_dclo(cpu_gpr
[rd
], t0
);
3785 gen_helper_dclz(cpu_gpr
[rd
], t0
);
3790 (void)opn
; /* avoid a compiler warning */
3791 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3795 /* Godson integer instructions */
3796 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3797 int rd
, int rs
, int rt
)
3799 const char *opn
= "loongson";
3811 case OPC_MULTU_G_2E
:
3812 case OPC_MULTU_G_2F
:
3813 #if defined(TARGET_MIPS64)
3814 case OPC_DMULT_G_2E
:
3815 case OPC_DMULT_G_2F
:
3816 case OPC_DMULTU_G_2E
:
3817 case OPC_DMULTU_G_2F
:
3819 t0
= tcg_temp_new();
3820 t1
= tcg_temp_new();
3823 t0
= tcg_temp_local_new();
3824 t1
= tcg_temp_local_new();
3828 gen_load_gpr(t0
, rs
);
3829 gen_load_gpr(t1
, rt
);
3834 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3835 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3838 case OPC_MULTU_G_2E
:
3839 case OPC_MULTU_G_2F
:
3840 tcg_gen_ext32u_tl(t0
, t0
);
3841 tcg_gen_ext32u_tl(t1
, t1
);
3842 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3843 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3849 TCGLabel
*l1
= gen_new_label();
3850 TCGLabel
*l2
= gen_new_label();
3851 TCGLabel
*l3
= gen_new_label();
3852 tcg_gen_ext32s_tl(t0
, t0
);
3853 tcg_gen_ext32s_tl(t1
, t1
);
3854 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3855 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3858 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3859 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3860 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3863 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3864 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3872 TCGLabel
*l1
= gen_new_label();
3873 TCGLabel
*l2
= gen_new_label();
3874 tcg_gen_ext32u_tl(t0
, t0
);
3875 tcg_gen_ext32u_tl(t1
, t1
);
3876 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3877 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3880 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3881 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3889 TCGLabel
*l1
= gen_new_label();
3890 TCGLabel
*l2
= gen_new_label();
3891 TCGLabel
*l3
= gen_new_label();
3892 tcg_gen_ext32u_tl(t0
, t0
);
3893 tcg_gen_ext32u_tl(t1
, t1
);
3894 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3895 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3896 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3898 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3901 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3902 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3910 TCGLabel
*l1
= gen_new_label();
3911 TCGLabel
*l2
= gen_new_label();
3912 tcg_gen_ext32u_tl(t0
, t0
);
3913 tcg_gen_ext32u_tl(t1
, t1
);
3914 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3915 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3918 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3919 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3924 #if defined(TARGET_MIPS64)
3925 case OPC_DMULT_G_2E
:
3926 case OPC_DMULT_G_2F
:
3927 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3930 case OPC_DMULTU_G_2E
:
3931 case OPC_DMULTU_G_2F
:
3932 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3938 TCGLabel
*l1
= gen_new_label();
3939 TCGLabel
*l2
= gen_new_label();
3940 TCGLabel
*l3
= gen_new_label();
3941 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3942 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3945 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3946 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3947 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3950 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3955 case OPC_DDIVU_G_2E
:
3956 case OPC_DDIVU_G_2F
:
3958 TCGLabel
*l1
= gen_new_label();
3959 TCGLabel
*l2
= gen_new_label();
3960 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3961 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3964 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3972 TCGLabel
*l1
= gen_new_label();
3973 TCGLabel
*l2
= gen_new_label();
3974 TCGLabel
*l3
= gen_new_label();
3975 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3976 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3977 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3979 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3982 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3987 case OPC_DMODU_G_2E
:
3988 case OPC_DMODU_G_2F
:
3990 TCGLabel
*l1
= gen_new_label();
3991 TCGLabel
*l2
= gen_new_label();
3992 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3993 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3996 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4004 (void)opn
; /* avoid a compiler warning */
4005 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
4010 /* Loongson multimedia instructions */
4011 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4013 const char *opn
= "loongson_cp2";
4014 uint32_t opc
, shift_max
;
4017 opc
= MASK_LMI(ctx
->opcode
);
4023 t0
= tcg_temp_local_new_i64();
4024 t1
= tcg_temp_local_new_i64();
4027 t0
= tcg_temp_new_i64();
4028 t1
= tcg_temp_new_i64();
4032 gen_load_fpr64(ctx
, t0
, rs
);
4033 gen_load_fpr64(ctx
, t1
, rt
);
4035 #define LMI_HELPER(UP, LO) \
4036 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4037 #define LMI_HELPER_1(UP, LO) \
4038 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4039 #define LMI_DIRECT(UP, LO, OP) \
4040 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4043 LMI_HELPER(PADDSH
, paddsh
);
4044 LMI_HELPER(PADDUSH
, paddush
);
4045 LMI_HELPER(PADDH
, paddh
);
4046 LMI_HELPER(PADDW
, paddw
);
4047 LMI_HELPER(PADDSB
, paddsb
);
4048 LMI_HELPER(PADDUSB
, paddusb
);
4049 LMI_HELPER(PADDB
, paddb
);
4051 LMI_HELPER(PSUBSH
, psubsh
);
4052 LMI_HELPER(PSUBUSH
, psubush
);
4053 LMI_HELPER(PSUBH
, psubh
);
4054 LMI_HELPER(PSUBW
, psubw
);
4055 LMI_HELPER(PSUBSB
, psubsb
);
4056 LMI_HELPER(PSUBUSB
, psubusb
);
4057 LMI_HELPER(PSUBB
, psubb
);
4059 LMI_HELPER(PSHUFH
, pshufh
);
4060 LMI_HELPER(PACKSSWH
, packsswh
);
4061 LMI_HELPER(PACKSSHB
, packsshb
);
4062 LMI_HELPER(PACKUSHB
, packushb
);
4064 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
4065 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
4066 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
4067 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
4068 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
4069 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
4071 LMI_HELPER(PAVGH
, pavgh
);
4072 LMI_HELPER(PAVGB
, pavgb
);
4073 LMI_HELPER(PMAXSH
, pmaxsh
);
4074 LMI_HELPER(PMINSH
, pminsh
);
4075 LMI_HELPER(PMAXUB
, pmaxub
);
4076 LMI_HELPER(PMINUB
, pminub
);
4078 LMI_HELPER(PCMPEQW
, pcmpeqw
);
4079 LMI_HELPER(PCMPGTW
, pcmpgtw
);
4080 LMI_HELPER(PCMPEQH
, pcmpeqh
);
4081 LMI_HELPER(PCMPGTH
, pcmpgth
);
4082 LMI_HELPER(PCMPEQB
, pcmpeqb
);
4083 LMI_HELPER(PCMPGTB
, pcmpgtb
);
4085 LMI_HELPER(PSLLW
, psllw
);
4086 LMI_HELPER(PSLLH
, psllh
);
4087 LMI_HELPER(PSRLW
, psrlw
);
4088 LMI_HELPER(PSRLH
, psrlh
);
4089 LMI_HELPER(PSRAW
, psraw
);
4090 LMI_HELPER(PSRAH
, psrah
);
4092 LMI_HELPER(PMULLH
, pmullh
);
4093 LMI_HELPER(PMULHH
, pmulhh
);
4094 LMI_HELPER(PMULHUH
, pmulhuh
);
4095 LMI_HELPER(PMADDHW
, pmaddhw
);
4097 LMI_HELPER(PASUBUB
, pasubub
);
4098 LMI_HELPER_1(BIADD
, biadd
);
4099 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
4101 LMI_DIRECT(PADDD
, paddd
, add
);
4102 LMI_DIRECT(PSUBD
, psubd
, sub
);
4103 LMI_DIRECT(XOR_CP2
, xor, xor);
4104 LMI_DIRECT(NOR_CP2
, nor
, nor
);
4105 LMI_DIRECT(AND_CP2
, and, and);
4106 LMI_DIRECT(PANDN
, pandn
, andc
);
4107 LMI_DIRECT(OR
, or, or);
4110 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
4114 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
4118 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
4122 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
4127 tcg_gen_andi_i64(t1
, t1
, 3);
4128 tcg_gen_shli_i64(t1
, t1
, 4);
4129 tcg_gen_shr_i64(t0
, t0
, t1
);
4130 tcg_gen_ext16u_i64(t0
, t0
);
4135 tcg_gen_add_i64(t0
, t0
, t1
);
4136 tcg_gen_ext32s_i64(t0
, t0
);
4140 tcg_gen_sub_i64(t0
, t0
, t1
);
4141 tcg_gen_ext32s_i64(t0
, t0
);
4170 /* Make sure shift count isn't TCG undefined behaviour. */
4171 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4176 tcg_gen_shl_i64(t0
, t0
, t1
);
4180 /* Since SRA is UndefinedResult without sign-extended inputs,
4181 we can treat SRA and DSRA the same. */
4182 tcg_gen_sar_i64(t0
, t0
, t1
);
4185 /* We want to shift in zeros for SRL; zero-extend first. */
4186 tcg_gen_ext32u_i64(t0
, t0
);
4189 tcg_gen_shr_i64(t0
, t0
, t1
);
4193 if (shift_max
== 32) {
4194 tcg_gen_ext32s_i64(t0
, t0
);
4197 /* Shifts larger than MAX produce zero. */
4198 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4199 tcg_gen_neg_i64(t1
, t1
);
4200 tcg_gen_and_i64(t0
, t0
, t1
);
4206 TCGv_i64 t2
= tcg_temp_new_i64();
4207 TCGLabel
*lab
= gen_new_label();
4209 tcg_gen_mov_i64(t2
, t0
);
4210 tcg_gen_add_i64(t0
, t1
, t2
);
4211 if (opc
== OPC_ADD_CP2
) {
4212 tcg_gen_ext32s_i64(t0
, t0
);
4214 tcg_gen_xor_i64(t1
, t1
, t2
);
4215 tcg_gen_xor_i64(t2
, t2
, t0
);
4216 tcg_gen_andc_i64(t1
, t2
, t1
);
4217 tcg_temp_free_i64(t2
);
4218 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4219 generate_exception(ctx
, EXCP_OVERFLOW
);
4222 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
4229 TCGv_i64 t2
= tcg_temp_new_i64();
4230 TCGLabel
*lab
= gen_new_label();
4232 tcg_gen_mov_i64(t2
, t0
);
4233 tcg_gen_sub_i64(t0
, t1
, t2
);
4234 if (opc
== OPC_SUB_CP2
) {
4235 tcg_gen_ext32s_i64(t0
, t0
);
4237 tcg_gen_xor_i64(t1
, t1
, t2
);
4238 tcg_gen_xor_i64(t2
, t2
, t0
);
4239 tcg_gen_and_i64(t1
, t1
, t2
);
4240 tcg_temp_free_i64(t2
);
4241 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4242 generate_exception(ctx
, EXCP_OVERFLOW
);
4245 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
4250 tcg_gen_ext32u_i64(t0
, t0
);
4251 tcg_gen_ext32u_i64(t1
, t1
);
4252 tcg_gen_mul_i64(t0
, t0
, t1
);
4262 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4263 FD field is the CC field? */
4266 generate_exception(ctx
, EXCP_RI
);
4273 gen_store_fpr64(ctx
, t0
, rd
);
4275 (void)opn
; /* avoid a compiler warning */
4276 MIPS_DEBUG("%s %s, %s, %s", opn
,
4277 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
4278 tcg_temp_free_i64(t0
);
4279 tcg_temp_free_i64(t1
);
4283 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
4284 int rs
, int rt
, int16_t imm
)
4287 TCGv t0
= tcg_temp_new();
4288 TCGv t1
= tcg_temp_new();
4291 /* Load needed operands */
4299 /* Compare two registers */
4301 gen_load_gpr(t0
, rs
);
4302 gen_load_gpr(t1
, rt
);
4312 /* Compare register to immediate */
4313 if (rs
!= 0 || imm
!= 0) {
4314 gen_load_gpr(t0
, rs
);
4315 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4322 case OPC_TEQ
: /* rs == rs */
4323 case OPC_TEQI
: /* r0 == 0 */
4324 case OPC_TGE
: /* rs >= rs */
4325 case OPC_TGEI
: /* r0 >= 0 */
4326 case OPC_TGEU
: /* rs >= rs unsigned */
4327 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4329 generate_exception(ctx
, EXCP_TRAP
);
4331 case OPC_TLT
: /* rs < rs */
4332 case OPC_TLTI
: /* r0 < 0 */
4333 case OPC_TLTU
: /* rs < rs unsigned */
4334 case OPC_TLTIU
: /* r0 < 0 unsigned */
4335 case OPC_TNE
: /* rs != rs */
4336 case OPC_TNEI
: /* r0 != 0 */
4337 /* Never trap: treat as NOP. */
4341 TCGLabel
*l1
= gen_new_label();
4346 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4350 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4354 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
4358 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
4362 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
4366 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
4369 generate_exception(ctx
, EXCP_TRAP
);
4376 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
4378 TranslationBlock
*tb
;
4380 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
4381 likely(!ctx
->singlestep_enabled
)) {
4384 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
4387 if (ctx
->singlestep_enabled
) {
4388 save_cpu_state(ctx
, 0);
4389 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
4395 /* Branches (before delay slot) */
4396 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
4398 int rs
, int rt
, int32_t offset
,
4401 target_ulong btgt
= -1;
4403 int bcond_compute
= 0;
4404 TCGv t0
= tcg_temp_new();
4405 TCGv t1
= tcg_temp_new();
4407 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
4408 #ifdef MIPS_DEBUG_DISAS
4409 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4410 TARGET_FMT_lx
"\n", ctx
->pc
);
4412 generate_exception(ctx
, EXCP_RI
);
4416 /* Load needed operands */
4422 /* Compare two registers */
4424 gen_load_gpr(t0
, rs
);
4425 gen_load_gpr(t1
, rt
);
4428 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4442 /* Compare to zero */
4444 gen_load_gpr(t0
, rs
);
4447 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4450 #if defined(TARGET_MIPS64)
4452 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
4454 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
4457 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4462 /* Jump to immediate */
4463 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
4467 /* Jump to register */
4468 if (offset
!= 0 && offset
!= 16) {
4469 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4470 others are reserved. */
4471 MIPS_INVAL("jump hint");
4472 generate_exception(ctx
, EXCP_RI
);
4475 gen_load_gpr(btarget
, rs
);
4478 MIPS_INVAL("branch/jump");
4479 generate_exception(ctx
, EXCP_RI
);
4482 if (bcond_compute
== 0) {
4483 /* No condition to be computed */
4485 case OPC_BEQ
: /* rx == rx */
4486 case OPC_BEQL
: /* rx == rx likely */
4487 case OPC_BGEZ
: /* 0 >= 0 */
4488 case OPC_BGEZL
: /* 0 >= 0 likely */
4489 case OPC_BLEZ
: /* 0 <= 0 */
4490 case OPC_BLEZL
: /* 0 <= 0 likely */
4492 ctx
->hflags
|= MIPS_HFLAG_B
;
4493 MIPS_DEBUG("balways");
4495 case OPC_BGEZAL
: /* 0 >= 0 */
4496 case OPC_BGEZALL
: /* 0 >= 0 likely */
4497 /* Always take and link */
4499 ctx
->hflags
|= MIPS_HFLAG_B
;
4500 MIPS_DEBUG("balways and link");
4502 case OPC_BNE
: /* rx != rx */
4503 case OPC_BGTZ
: /* 0 > 0 */
4504 case OPC_BLTZ
: /* 0 < 0 */
4506 MIPS_DEBUG("bnever (NOP)");
4508 case OPC_BLTZAL
: /* 0 < 0 */
4509 /* Handle as an unconditional branch to get correct delay
4512 btgt
= ctx
->pc
+ insn_bytes
+ delayslot_size
;
4513 ctx
->hflags
|= MIPS_HFLAG_B
;
4514 MIPS_DEBUG("bnever and link");
4516 case OPC_BLTZALL
: /* 0 < 0 likely */
4517 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
4518 /* Skip the instruction in the delay slot */
4519 MIPS_DEBUG("bnever, link and skip");
4522 case OPC_BNEL
: /* rx != rx likely */
4523 case OPC_BGTZL
: /* 0 > 0 likely */
4524 case OPC_BLTZL
: /* 0 < 0 likely */
4525 /* Skip the instruction in the delay slot */
4526 MIPS_DEBUG("bnever and skip");
4530 ctx
->hflags
|= MIPS_HFLAG_B
;
4531 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
4534 ctx
->hflags
|= MIPS_HFLAG_BX
;
4538 ctx
->hflags
|= MIPS_HFLAG_B
;
4539 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
4542 ctx
->hflags
|= MIPS_HFLAG_BR
;
4543 MIPS_DEBUG("jr %s", regnames
[rs
]);
4547 ctx
->hflags
|= MIPS_HFLAG_BR
;
4548 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
4551 MIPS_INVAL("branch/jump");
4552 generate_exception(ctx
, EXCP_RI
);
4558 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4559 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
4560 regnames
[rs
], regnames
[rt
], btgt
);
4563 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4564 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
4565 regnames
[rs
], regnames
[rt
], btgt
);
4568 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4569 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
4570 regnames
[rs
], regnames
[rt
], btgt
);
4573 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4574 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
4575 regnames
[rs
], regnames
[rt
], btgt
);
4578 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4579 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4582 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4583 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4586 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4587 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4591 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4593 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4596 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4597 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4600 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4601 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4604 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4605 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4608 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4609 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4612 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4613 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4616 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4617 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4620 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
4621 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
4623 #if defined(TARGET_MIPS64)
4625 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
4626 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
4630 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4632 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4634 ctx
->hflags
|= MIPS_HFLAG_BC
;
4637 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4639 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4641 ctx
->hflags
|= MIPS_HFLAG_BL
;
4644 MIPS_INVAL("conditional branch/jump");
4645 generate_exception(ctx
, EXCP_RI
);
4649 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
4650 blink
, ctx
->hflags
, btgt
);
4652 ctx
->btarget
= btgt
;
4654 switch (delayslot_size
) {
4656 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
4659 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
4664 int post_delay
= insn_bytes
+ delayslot_size
;
4665 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
4667 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
4671 if (insn_bytes
== 2)
4672 ctx
->hflags
|= MIPS_HFLAG_B16
;
4677 /* special3 bitfield operations */
4678 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
4679 int rs
, int lsb
, int msb
)
4681 TCGv t0
= tcg_temp_new();
4682 TCGv t1
= tcg_temp_new();
4684 gen_load_gpr(t1
, rs
);
4689 tcg_gen_shri_tl(t0
, t1
, lsb
);
4691 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
4693 tcg_gen_ext32s_tl(t0
, t0
);
4696 #if defined(TARGET_MIPS64)
4698 tcg_gen_shri_tl(t0
, t1
, lsb
);
4700 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
4704 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
4705 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4708 tcg_gen_shri_tl(t0
, t1
, lsb
);
4709 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4715 gen_load_gpr(t0
, rt
);
4716 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4717 tcg_gen_ext32s_tl(t0
, t0
);
4719 #if defined(TARGET_MIPS64)
4721 gen_load_gpr(t0
, rt
);
4722 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
4725 gen_load_gpr(t0
, rt
);
4726 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
4729 gen_load_gpr(t0
, rt
);
4730 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4735 MIPS_INVAL("bitops");
4736 generate_exception(ctx
, EXCP_RI
);
4741 gen_store_gpr(t0
, rt
);
4746 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4751 /* If no destination, treat it as a NOP. */
4756 t0
= tcg_temp_new();
4757 gen_load_gpr(t0
, rt
);
4761 TCGv t1
= tcg_temp_new();
4763 tcg_gen_shri_tl(t1
, t0
, 8);
4764 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4765 tcg_gen_shli_tl(t0
, t0
, 8);
4766 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4767 tcg_gen_or_tl(t0
, t0
, t1
);
4769 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4773 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4776 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4778 #if defined(TARGET_MIPS64)
4781 TCGv t1
= tcg_temp_new();
4783 tcg_gen_shri_tl(t1
, t0
, 8);
4784 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4785 tcg_gen_shli_tl(t0
, t0
, 8);
4786 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4787 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4793 TCGv t1
= tcg_temp_new();
4795 tcg_gen_shri_tl(t1
, t0
, 16);
4796 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4797 tcg_gen_shli_tl(t0
, t0
, 16);
4798 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4799 tcg_gen_or_tl(t0
, t0
, t1
);
4800 tcg_gen_shri_tl(t1
, t0
, 32);
4801 tcg_gen_shli_tl(t0
, t0
, 32);
4802 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4808 MIPS_INVAL("bsfhl");
4809 generate_exception(ctx
, EXCP_RI
);
4816 #ifndef CONFIG_USER_ONLY
4817 /* CP0 (MMU and control) */
4818 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4820 TCGv_i32 t0
= tcg_temp_new_i32();
4822 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4823 tcg_gen_ext_i32_tl(arg
, t0
);
4824 tcg_temp_free_i32(t0
);
4827 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4829 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4830 tcg_gen_ext32s_tl(arg
, arg
);
4833 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4835 TCGv_i32 t0
= tcg_temp_new_i32();
4837 tcg_gen_trunc_tl_i32(t0
, arg
);
4838 tcg_gen_st_i32(t0
, cpu_env
, off
);
4839 tcg_temp_free_i32(t0
);
4842 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4844 tcg_gen_ext32s_tl(arg
, arg
);
4845 tcg_gen_st_tl(arg
, cpu_env
, off
);
4848 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
4850 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
4851 tcg_gen_movi_tl(arg
, 0);
4853 tcg_gen_movi_tl(arg
, ~0);
4857 #define CP0_CHECK(c) \
4860 goto cp0_unimplemented; \
4864 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4866 const char *rn
= "invalid";
4869 check_insn(ctx
, ISA_MIPS32
);
4875 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4879 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4880 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4884 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4885 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4889 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4890 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4894 goto cp0_unimplemented
;
4900 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
4901 gen_helper_mfc0_random(arg
, cpu_env
);
4905 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4906 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4910 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4911 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4915 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4916 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4920 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4921 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4925 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4926 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4930 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4931 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4932 rn
= "VPEScheFBack";
4935 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4936 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4940 goto cp0_unimplemented
;
4946 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4947 #if defined(TARGET_MIPS64)
4949 TCGv tmp
= tcg_temp_new();
4950 tcg_gen_andi_tl(tmp
, arg
, (3ull << CP0EnLo_XI
));
4951 tcg_gen_shri_tl(tmp
, tmp
, 32);
4952 tcg_gen_or_tl(arg
, arg
, tmp
);
4956 tcg_gen_ext32s_tl(arg
, arg
);
4960 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4961 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4965 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4966 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4970 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4971 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4975 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4976 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4980 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4981 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4985 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4986 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4990 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4991 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4995 goto cp0_unimplemented
;
5001 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5002 #if defined(TARGET_MIPS64)
5004 TCGv tmp
= tcg_temp_new();
5005 tcg_gen_andi_tl(tmp
, arg
, (3ull << CP0EnLo_XI
));
5006 tcg_gen_shri_tl(tmp
, tmp
, 32);
5007 tcg_gen_or_tl(arg
, arg
, tmp
);
5011 tcg_gen_ext32s_tl(arg
, arg
);
5015 goto cp0_unimplemented
;
5021 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5022 tcg_gen_ext32s_tl(arg
, arg
);
5026 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5027 rn
= "ContextConfig";
5028 goto cp0_unimplemented
;
5031 CP0_CHECK(ctx
->ulri
);
5032 tcg_gen_ld32s_tl(arg
, cpu_env
,
5033 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5037 goto cp0_unimplemented
;
5043 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5047 check_insn(ctx
, ISA_MIPS32R2
);
5048 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5052 goto cp0_unimplemented
;
5058 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5062 check_insn(ctx
, ISA_MIPS32R2
);
5063 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5067 check_insn(ctx
, ISA_MIPS32R2
);
5068 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5072 check_insn(ctx
, ISA_MIPS32R2
);
5073 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5077 check_insn(ctx
, ISA_MIPS32R2
);
5078 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5082 check_insn(ctx
, ISA_MIPS32R2
);
5083 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5087 goto cp0_unimplemented
;
5093 check_insn(ctx
, ISA_MIPS32R2
);
5094 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5098 goto cp0_unimplemented
;
5104 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5105 tcg_gen_ext32s_tl(arg
, arg
);
5110 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
5115 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
5119 goto cp0_unimplemented
;
5125 /* Mark as an IO operation because we read the time. */
5126 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5129 gen_helper_mfc0_count(arg
, cpu_env
);
5130 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5133 /* Break the TB to be able to take timer interrupts immediately
5134 after reading count. */
5135 ctx
->bstate
= BS_STOP
;
5138 /* 6,7 are implementation dependent */
5140 goto cp0_unimplemented
;
5146 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5147 tcg_gen_ext32s_tl(arg
, arg
);
5151 goto cp0_unimplemented
;
5157 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5160 /* 6,7 are implementation dependent */
5162 goto cp0_unimplemented
;
5168 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5172 check_insn(ctx
, ISA_MIPS32R2
);
5173 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5177 check_insn(ctx
, ISA_MIPS32R2
);
5178 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5182 check_insn(ctx
, ISA_MIPS32R2
);
5183 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5187 goto cp0_unimplemented
;
5193 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5197 goto cp0_unimplemented
;
5203 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5204 tcg_gen_ext32s_tl(arg
, arg
);
5208 goto cp0_unimplemented
;
5214 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5218 check_insn(ctx
, ISA_MIPS32R2
);
5219 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5223 goto cp0_unimplemented
;
5229 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5233 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5237 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5241 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5245 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
5249 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
5252 /* 6,7 are implementation dependent */
5254 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5258 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5262 goto cp0_unimplemented
;
5268 gen_helper_mfc0_lladdr(arg
, cpu_env
);
5272 goto cp0_unimplemented
;
5278 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
5282 goto cp0_unimplemented
;
5288 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5292 goto cp0_unimplemented
;
5298 #if defined(TARGET_MIPS64)
5299 check_insn(ctx
, ISA_MIPS3
);
5300 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5301 tcg_gen_ext32s_tl(arg
, arg
);
5306 goto cp0_unimplemented
;
5310 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5311 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5314 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5318 goto cp0_unimplemented
;
5322 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5323 rn
= "'Diagnostic"; /* implementation dependent */
5328 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5332 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5333 rn
= "TraceControl";
5336 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5337 rn
= "TraceControl2";
5340 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5341 rn
= "UserTraceData";
5344 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5348 goto cp0_unimplemented
;
5355 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5356 tcg_gen_ext32s_tl(arg
, arg
);
5360 goto cp0_unimplemented
;
5366 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5367 rn
= "Performance0";
5370 // gen_helper_mfc0_performance1(arg);
5371 rn
= "Performance1";
5374 // gen_helper_mfc0_performance2(arg);
5375 rn
= "Performance2";
5378 // gen_helper_mfc0_performance3(arg);
5379 rn
= "Performance3";
5382 // gen_helper_mfc0_performance4(arg);
5383 rn
= "Performance4";
5386 // gen_helper_mfc0_performance5(arg);
5387 rn
= "Performance5";
5390 // gen_helper_mfc0_performance6(arg);
5391 rn
= "Performance6";
5394 // gen_helper_mfc0_performance7(arg);
5395 rn
= "Performance7";
5398 goto cp0_unimplemented
;
5402 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5408 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5412 goto cp0_unimplemented
;
5421 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5428 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5432 goto cp0_unimplemented
;
5441 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5448 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5452 goto cp0_unimplemented
;
5458 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5459 tcg_gen_ext32s_tl(arg
, arg
);
5463 goto cp0_unimplemented
;
5470 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5474 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
5475 tcg_gen_ld_tl(arg
, cpu_env
,
5476 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
5477 tcg_gen_ext32s_tl(arg
, arg
);
5481 goto cp0_unimplemented
;
5485 goto cp0_unimplemented
;
5487 (void)rn
; /* avoid a compiler warning */
5488 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5492 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5493 gen_mfc0_unimplemented(ctx
, arg
);
5496 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5498 const char *rn
= "invalid";
5501 check_insn(ctx
, ISA_MIPS32
);
5503 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5511 gen_helper_mtc0_index(cpu_env
, arg
);
5515 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5516 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5520 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5525 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5530 goto cp0_unimplemented
;
5540 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5541 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5545 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5546 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5550 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5551 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5555 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5556 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5560 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5561 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5565 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5566 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5567 rn
= "VPEScheFBack";
5570 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5571 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5575 goto cp0_unimplemented
;
5581 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5585 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5586 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5590 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5591 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5595 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5596 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5600 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5601 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5605 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5606 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5610 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5611 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5615 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5616 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5620 goto cp0_unimplemented
;
5626 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5630 goto cp0_unimplemented
;
5636 gen_helper_mtc0_context(cpu_env
, arg
);
5640 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5641 rn
= "ContextConfig";
5642 goto cp0_unimplemented
;
5645 CP0_CHECK(ctx
->ulri
);
5646 tcg_gen_st_tl(arg
, cpu_env
,
5647 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5651 goto cp0_unimplemented
;
5657 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5661 check_insn(ctx
, ISA_MIPS32R2
);
5662 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5666 goto cp0_unimplemented
;
5672 gen_helper_mtc0_wired(cpu_env
, arg
);
5676 check_insn(ctx
, ISA_MIPS32R2
);
5677 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5681 check_insn(ctx
, ISA_MIPS32R2
);
5682 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
5686 check_insn(ctx
, ISA_MIPS32R2
);
5687 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
5691 check_insn(ctx
, ISA_MIPS32R2
);
5692 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
5696 check_insn(ctx
, ISA_MIPS32R2
);
5697 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
5701 goto cp0_unimplemented
;
5707 check_insn(ctx
, ISA_MIPS32R2
);
5708 gen_helper_mtc0_hwrena(cpu_env
, arg
);
5709 ctx
->bstate
= BS_STOP
;
5713 goto cp0_unimplemented
;
5731 goto cp0_unimplemented
;
5737 gen_helper_mtc0_count(cpu_env
, arg
);
5740 /* 6,7 are implementation dependent */
5742 goto cp0_unimplemented
;
5748 gen_helper_mtc0_entryhi(cpu_env
, arg
);
5752 goto cp0_unimplemented
;
5758 gen_helper_mtc0_compare(cpu_env
, arg
);
5761 /* 6,7 are implementation dependent */
5763 goto cp0_unimplemented
;
5769 save_cpu_state(ctx
, 1);
5770 gen_helper_mtc0_status(cpu_env
, arg
);
5771 /* BS_STOP isn't good enough here, hflags may have changed. */
5772 gen_save_pc(ctx
->pc
+ 4);
5773 ctx
->bstate
= BS_EXCP
;
5777 check_insn(ctx
, ISA_MIPS32R2
);
5778 gen_helper_mtc0_intctl(cpu_env
, arg
);
5779 /* Stop translation as we may have switched the execution mode */
5780 ctx
->bstate
= BS_STOP
;
5784 check_insn(ctx
, ISA_MIPS32R2
);
5785 gen_helper_mtc0_srsctl(cpu_env
, arg
);
5786 /* Stop translation as we may have switched the execution mode */
5787 ctx
->bstate
= BS_STOP
;
5791 check_insn(ctx
, ISA_MIPS32R2
);
5792 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5793 /* Stop translation as we may have switched the execution mode */
5794 ctx
->bstate
= BS_STOP
;
5798 goto cp0_unimplemented
;
5804 save_cpu_state(ctx
, 1);
5805 gen_helper_mtc0_cause(cpu_env
, arg
);
5809 goto cp0_unimplemented
;
5815 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
5819 goto cp0_unimplemented
;
5829 check_insn(ctx
, ISA_MIPS32R2
);
5830 gen_helper_mtc0_ebase(cpu_env
, arg
);
5834 goto cp0_unimplemented
;
5840 gen_helper_mtc0_config0(cpu_env
, arg
);
5842 /* Stop translation as we may have switched the execution mode */
5843 ctx
->bstate
= BS_STOP
;
5846 /* ignored, read only */
5850 gen_helper_mtc0_config2(cpu_env
, arg
);
5852 /* Stop translation as we may have switched the execution mode */
5853 ctx
->bstate
= BS_STOP
;
5856 gen_helper_mtc0_config3(cpu_env
, arg
);
5858 /* Stop translation as we may have switched the execution mode */
5859 ctx
->bstate
= BS_STOP
;
5862 gen_helper_mtc0_config4(cpu_env
, arg
);
5864 ctx
->bstate
= BS_STOP
;
5867 gen_helper_mtc0_config5(cpu_env
, arg
);
5869 /* Stop translation as we may have switched the execution mode */
5870 ctx
->bstate
= BS_STOP
;
5872 /* 6,7 are implementation dependent */
5882 rn
= "Invalid config selector";
5883 goto cp0_unimplemented
;
5889 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5893 goto cp0_unimplemented
;
5899 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5903 goto cp0_unimplemented
;
5909 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5913 goto cp0_unimplemented
;
5919 #if defined(TARGET_MIPS64)
5920 check_insn(ctx
, ISA_MIPS3
);
5921 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5926 goto cp0_unimplemented
;
5930 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5931 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5934 gen_helper_mtc0_framemask(cpu_env
, arg
);
5938 goto cp0_unimplemented
;
5943 rn
= "Diagnostic"; /* implementation dependent */
5948 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5949 /* BS_STOP isn't good enough here, hflags may have changed. */
5950 gen_save_pc(ctx
->pc
+ 4);
5951 ctx
->bstate
= BS_EXCP
;
5955 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5956 rn
= "TraceControl";
5957 /* Stop translation as we may have switched the execution mode */
5958 ctx
->bstate
= BS_STOP
;
5961 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5962 rn
= "TraceControl2";
5963 /* Stop translation as we may have switched the execution mode */
5964 ctx
->bstate
= BS_STOP
;
5967 /* Stop translation as we may have switched the execution mode */
5968 ctx
->bstate
= BS_STOP
;
5969 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5970 rn
= "UserTraceData";
5971 /* Stop translation as we may have switched the execution mode */
5972 ctx
->bstate
= BS_STOP
;
5975 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5976 /* Stop translation as we may have switched the execution mode */
5977 ctx
->bstate
= BS_STOP
;
5981 goto cp0_unimplemented
;
5988 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5992 goto cp0_unimplemented
;
5998 gen_helper_mtc0_performance0(cpu_env
, arg
);
5999 rn
= "Performance0";
6002 // gen_helper_mtc0_performance1(arg);
6003 rn
= "Performance1";
6006 // gen_helper_mtc0_performance2(arg);
6007 rn
= "Performance2";
6010 // gen_helper_mtc0_performance3(arg);
6011 rn
= "Performance3";
6014 // gen_helper_mtc0_performance4(arg);
6015 rn
= "Performance4";
6018 // gen_helper_mtc0_performance5(arg);
6019 rn
= "Performance5";
6022 // gen_helper_mtc0_performance6(arg);
6023 rn
= "Performance6";
6026 // gen_helper_mtc0_performance7(arg);
6027 rn
= "Performance7";
6030 goto cp0_unimplemented
;
6044 goto cp0_unimplemented
;
6053 gen_helper_mtc0_taglo(cpu_env
, arg
);
6060 gen_helper_mtc0_datalo(cpu_env
, arg
);
6064 goto cp0_unimplemented
;
6073 gen_helper_mtc0_taghi(cpu_env
, arg
);
6080 gen_helper_mtc0_datahi(cpu_env
, arg
);
6085 goto cp0_unimplemented
;
6091 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6095 goto cp0_unimplemented
;
6102 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6106 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6107 tcg_gen_st_tl(arg
, cpu_env
,
6108 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6112 goto cp0_unimplemented
;
6114 /* Stop translation as we may have switched the execution mode */
6115 ctx
->bstate
= BS_STOP
;
6118 goto cp0_unimplemented
;
6120 (void)rn
; /* avoid a compiler warning */
6121 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6122 /* For simplicity assume that all writes can cause interrupts. */
6123 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6125 ctx
->bstate
= BS_STOP
;
6130 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6133 #if defined(TARGET_MIPS64)
6134 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6136 const char *rn
= "invalid";
6139 check_insn(ctx
, ISA_MIPS64
);
6145 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6149 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6150 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6154 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6155 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6159 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6160 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6164 goto cp0_unimplemented
;
6170 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6171 gen_helper_mfc0_random(arg
, cpu_env
);
6175 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6176 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6180 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6181 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6185 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6186 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6190 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6191 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
6195 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6196 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6200 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6201 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6202 rn
= "VPEScheFBack";
6205 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6206 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6210 goto cp0_unimplemented
;
6216 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6220 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6221 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6225 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6226 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6230 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6231 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
6235 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6236 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
6240 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6241 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
6245 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6246 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
6250 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6251 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
6255 goto cp0_unimplemented
;
6261 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6265 goto cp0_unimplemented
;
6271 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6275 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6276 rn
= "ContextConfig";
6277 goto cp0_unimplemented
;
6280 CP0_CHECK(ctx
->ulri
);
6281 tcg_gen_ld_tl(arg
, cpu_env
,
6282 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6286 goto cp0_unimplemented
;
6292 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6296 check_insn(ctx
, ISA_MIPS32R2
);
6297 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6301 goto cp0_unimplemented
;
6307 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6311 check_insn(ctx
, ISA_MIPS32R2
);
6312 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6316 check_insn(ctx
, ISA_MIPS32R2
);
6317 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6321 check_insn(ctx
, ISA_MIPS32R2
);
6322 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6326 check_insn(ctx
, ISA_MIPS32R2
);
6327 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6331 check_insn(ctx
, ISA_MIPS32R2
);
6332 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6336 goto cp0_unimplemented
;
6342 check_insn(ctx
, ISA_MIPS32R2
);
6343 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6347 goto cp0_unimplemented
;
6353 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6358 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6363 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6367 goto cp0_unimplemented
;
6373 /* Mark as an IO operation because we read the time. */
6374 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6377 gen_helper_mfc0_count(arg
, cpu_env
);
6378 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6381 /* Break the TB to be able to take timer interrupts immediately
6382 after reading count. */
6383 ctx
->bstate
= BS_STOP
;
6386 /* 6,7 are implementation dependent */
6388 goto cp0_unimplemented
;
6394 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6398 goto cp0_unimplemented
;
6404 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6407 /* 6,7 are implementation dependent */
6409 goto cp0_unimplemented
;
6415 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6419 check_insn(ctx
, ISA_MIPS32R2
);
6420 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6424 check_insn(ctx
, ISA_MIPS32R2
);
6425 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6429 check_insn(ctx
, ISA_MIPS32R2
);
6430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6434 goto cp0_unimplemented
;
6440 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6444 goto cp0_unimplemented
;
6450 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6454 goto cp0_unimplemented
;
6460 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6464 check_insn(ctx
, ISA_MIPS32R2
);
6465 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
6469 goto cp0_unimplemented
;
6475 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6479 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6483 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6487 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6491 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6495 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6498 /* 6,7 are implementation dependent */
6500 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6504 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6508 goto cp0_unimplemented
;
6514 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
6518 goto cp0_unimplemented
;
6524 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
6528 goto cp0_unimplemented
;
6534 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6538 goto cp0_unimplemented
;
6544 check_insn(ctx
, ISA_MIPS3
);
6545 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6549 goto cp0_unimplemented
;
6553 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6554 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6557 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6561 goto cp0_unimplemented
;
6565 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6566 rn
= "'Diagnostic"; /* implementation dependent */
6571 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6575 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6576 rn
= "TraceControl";
6579 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6580 rn
= "TraceControl2";
6583 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6584 rn
= "UserTraceData";
6587 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6591 goto cp0_unimplemented
;
6598 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6602 goto cp0_unimplemented
;
6608 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6609 rn
= "Performance0";
6612 // gen_helper_dmfc0_performance1(arg);
6613 rn
= "Performance1";
6616 // gen_helper_dmfc0_performance2(arg);
6617 rn
= "Performance2";
6620 // gen_helper_dmfc0_performance3(arg);
6621 rn
= "Performance3";
6624 // gen_helper_dmfc0_performance4(arg);
6625 rn
= "Performance4";
6628 // gen_helper_dmfc0_performance5(arg);
6629 rn
= "Performance5";
6632 // gen_helper_dmfc0_performance6(arg);
6633 rn
= "Performance6";
6636 // gen_helper_dmfc0_performance7(arg);
6637 rn
= "Performance7";
6640 goto cp0_unimplemented
;
6644 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6651 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6655 goto cp0_unimplemented
;
6664 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6671 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6675 goto cp0_unimplemented
;
6684 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6691 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6695 goto cp0_unimplemented
;
6701 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6705 goto cp0_unimplemented
;
6712 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6716 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6717 tcg_gen_ld_tl(arg
, cpu_env
,
6718 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6722 goto cp0_unimplemented
;
6726 goto cp0_unimplemented
;
6728 (void)rn
; /* avoid a compiler warning */
6729 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6733 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6734 gen_mfc0_unimplemented(ctx
, arg
);
6737 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6739 const char *rn
= "invalid";
6742 check_insn(ctx
, ISA_MIPS64
);
6744 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6752 gen_helper_mtc0_index(cpu_env
, arg
);
6756 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6757 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6761 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6766 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6771 goto cp0_unimplemented
;
6781 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6782 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6786 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6787 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6791 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6792 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6796 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6797 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6801 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6802 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6806 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6807 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6808 rn
= "VPEScheFBack";
6811 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6812 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6816 goto cp0_unimplemented
;
6822 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
6826 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6827 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6831 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6832 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6836 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6837 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
6841 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6842 gen_helper_mtc0_tchalt(cpu_env
, arg
);
6846 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6847 gen_helper_mtc0_tccontext(cpu_env
, arg
);
6851 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6852 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
6856 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6857 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6861 goto cp0_unimplemented
;
6867 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
6871 goto cp0_unimplemented
;
6877 gen_helper_mtc0_context(cpu_env
, arg
);
6881 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6882 rn
= "ContextConfig";
6883 goto cp0_unimplemented
;
6886 CP0_CHECK(ctx
->ulri
);
6887 tcg_gen_st_tl(arg
, cpu_env
,
6888 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6892 goto cp0_unimplemented
;
6898 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6902 check_insn(ctx
, ISA_MIPS32R2
);
6903 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6907 goto cp0_unimplemented
;
6913 gen_helper_mtc0_wired(cpu_env
, arg
);
6917 check_insn(ctx
, ISA_MIPS32R2
);
6918 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6922 check_insn(ctx
, ISA_MIPS32R2
);
6923 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6927 check_insn(ctx
, ISA_MIPS32R2
);
6928 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6932 check_insn(ctx
, ISA_MIPS32R2
);
6933 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6937 check_insn(ctx
, ISA_MIPS32R2
);
6938 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6942 goto cp0_unimplemented
;
6948 check_insn(ctx
, ISA_MIPS32R2
);
6949 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6950 ctx
->bstate
= BS_STOP
;
6954 goto cp0_unimplemented
;
6972 goto cp0_unimplemented
;
6978 gen_helper_mtc0_count(cpu_env
, arg
);
6981 /* 6,7 are implementation dependent */
6983 goto cp0_unimplemented
;
6985 /* Stop translation as we may have switched the execution mode */
6986 ctx
->bstate
= BS_STOP
;
6991 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6995 goto cp0_unimplemented
;
7001 gen_helper_mtc0_compare(cpu_env
, arg
);
7004 /* 6,7 are implementation dependent */
7006 goto cp0_unimplemented
;
7008 /* Stop translation as we may have switched the execution mode */
7009 ctx
->bstate
= BS_STOP
;
7014 save_cpu_state(ctx
, 1);
7015 gen_helper_mtc0_status(cpu_env
, arg
);
7016 /* BS_STOP isn't good enough here, hflags may have changed. */
7017 gen_save_pc(ctx
->pc
+ 4);
7018 ctx
->bstate
= BS_EXCP
;
7022 check_insn(ctx
, ISA_MIPS32R2
);
7023 gen_helper_mtc0_intctl(cpu_env
, arg
);
7024 /* Stop translation as we may have switched the execution mode */
7025 ctx
->bstate
= BS_STOP
;
7029 check_insn(ctx
, ISA_MIPS32R2
);
7030 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7031 /* Stop translation as we may have switched the execution mode */
7032 ctx
->bstate
= BS_STOP
;
7036 check_insn(ctx
, ISA_MIPS32R2
);
7037 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7038 /* Stop translation as we may have switched the execution mode */
7039 ctx
->bstate
= BS_STOP
;
7043 goto cp0_unimplemented
;
7049 save_cpu_state(ctx
, 1);
7050 /* Mark as an IO operation because we may trigger a software
7052 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7055 gen_helper_mtc0_cause(cpu_env
, arg
);
7056 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7059 /* Stop translation as we may have triggered an intetrupt */
7060 ctx
->bstate
= BS_STOP
;
7064 goto cp0_unimplemented
;
7070 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7074 goto cp0_unimplemented
;
7084 check_insn(ctx
, ISA_MIPS32R2
);
7085 gen_helper_mtc0_ebase(cpu_env
, arg
);
7089 goto cp0_unimplemented
;
7095 gen_helper_mtc0_config0(cpu_env
, arg
);
7097 /* Stop translation as we may have switched the execution mode */
7098 ctx
->bstate
= BS_STOP
;
7101 /* ignored, read only */
7105 gen_helper_mtc0_config2(cpu_env
, arg
);
7107 /* Stop translation as we may have switched the execution mode */
7108 ctx
->bstate
= BS_STOP
;
7111 gen_helper_mtc0_config3(cpu_env
, arg
);
7113 /* Stop translation as we may have switched the execution mode */
7114 ctx
->bstate
= BS_STOP
;
7117 /* currently ignored */
7121 gen_helper_mtc0_config5(cpu_env
, arg
);
7123 /* Stop translation as we may have switched the execution mode */
7124 ctx
->bstate
= BS_STOP
;
7126 /* 6,7 are implementation dependent */
7128 rn
= "Invalid config selector";
7129 goto cp0_unimplemented
;
7135 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7139 goto cp0_unimplemented
;
7145 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7149 goto cp0_unimplemented
;
7155 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7159 goto cp0_unimplemented
;
7165 check_insn(ctx
, ISA_MIPS3
);
7166 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7170 goto cp0_unimplemented
;
7174 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7175 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7178 gen_helper_mtc0_framemask(cpu_env
, arg
);
7182 goto cp0_unimplemented
;
7187 rn
= "Diagnostic"; /* implementation dependent */
7192 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7193 /* BS_STOP isn't good enough here, hflags may have changed. */
7194 gen_save_pc(ctx
->pc
+ 4);
7195 ctx
->bstate
= BS_EXCP
;
7199 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7200 /* Stop translation as we may have switched the execution mode */
7201 ctx
->bstate
= BS_STOP
;
7202 rn
= "TraceControl";
7205 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7206 /* Stop translation as we may have switched the execution mode */
7207 ctx
->bstate
= BS_STOP
;
7208 rn
= "TraceControl2";
7211 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7212 /* Stop translation as we may have switched the execution mode */
7213 ctx
->bstate
= BS_STOP
;
7214 rn
= "UserTraceData";
7217 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7218 /* Stop translation as we may have switched the execution mode */
7219 ctx
->bstate
= BS_STOP
;
7223 goto cp0_unimplemented
;
7230 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7234 goto cp0_unimplemented
;
7240 gen_helper_mtc0_performance0(cpu_env
, arg
);
7241 rn
= "Performance0";
7244 // gen_helper_mtc0_performance1(cpu_env, arg);
7245 rn
= "Performance1";
7248 // gen_helper_mtc0_performance2(cpu_env, arg);
7249 rn
= "Performance2";
7252 // gen_helper_mtc0_performance3(cpu_env, arg);
7253 rn
= "Performance3";
7256 // gen_helper_mtc0_performance4(cpu_env, arg);
7257 rn
= "Performance4";
7260 // gen_helper_mtc0_performance5(cpu_env, arg);
7261 rn
= "Performance5";
7264 // gen_helper_mtc0_performance6(cpu_env, arg);
7265 rn
= "Performance6";
7268 // gen_helper_mtc0_performance7(cpu_env, arg);
7269 rn
= "Performance7";
7272 goto cp0_unimplemented
;
7286 goto cp0_unimplemented
;
7295 gen_helper_mtc0_taglo(cpu_env
, arg
);
7302 gen_helper_mtc0_datalo(cpu_env
, arg
);
7306 goto cp0_unimplemented
;
7315 gen_helper_mtc0_taghi(cpu_env
, arg
);
7322 gen_helper_mtc0_datahi(cpu_env
, arg
);
7327 goto cp0_unimplemented
;
7333 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7337 goto cp0_unimplemented
;
7344 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7348 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7349 tcg_gen_st_tl(arg
, cpu_env
,
7350 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7354 goto cp0_unimplemented
;
7356 /* Stop translation as we may have switched the execution mode */
7357 ctx
->bstate
= BS_STOP
;
7360 goto cp0_unimplemented
;
7362 (void)rn
; /* avoid a compiler warning */
7363 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7364 /* For simplicity assume that all writes can cause interrupts. */
7365 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7367 ctx
->bstate
= BS_STOP
;
7372 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7374 #endif /* TARGET_MIPS64 */
7376 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
7377 int u
, int sel
, int h
)
7379 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7380 TCGv t0
= tcg_temp_local_new();
7382 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7383 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7384 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7385 tcg_gen_movi_tl(t0
, -1);
7386 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7387 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7388 tcg_gen_movi_tl(t0
, -1);
7394 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
7397 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
7407 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
7410 gen_helper_mftc0_tcbind(t0
, cpu_env
);
7413 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
7416 gen_helper_mftc0_tchalt(t0
, cpu_env
);
7419 gen_helper_mftc0_tccontext(t0
, cpu_env
);
7422 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
7425 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
7428 gen_mfc0(ctx
, t0
, rt
, sel
);
7435 gen_helper_mftc0_entryhi(t0
, cpu_env
);
7438 gen_mfc0(ctx
, t0
, rt
, sel
);
7444 gen_helper_mftc0_status(t0
, cpu_env
);
7447 gen_mfc0(ctx
, t0
, rt
, sel
);
7453 gen_helper_mftc0_cause(t0
, cpu_env
);
7463 gen_helper_mftc0_epc(t0
, cpu_env
);
7473 gen_helper_mftc0_ebase(t0
, cpu_env
);
7483 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
7493 gen_helper_mftc0_debug(t0
, cpu_env
);
7496 gen_mfc0(ctx
, t0
, rt
, sel
);
7501 gen_mfc0(ctx
, t0
, rt
, sel
);
7503 } else switch (sel
) {
7504 /* GPR registers. */
7506 gen_helper_1e0i(mftgpr
, t0
, rt
);
7508 /* Auxiliary CPU registers */
7512 gen_helper_1e0i(mftlo
, t0
, 0);
7515 gen_helper_1e0i(mfthi
, t0
, 0);
7518 gen_helper_1e0i(mftacx
, t0
, 0);
7521 gen_helper_1e0i(mftlo
, t0
, 1);
7524 gen_helper_1e0i(mfthi
, t0
, 1);
7527 gen_helper_1e0i(mftacx
, t0
, 1);
7530 gen_helper_1e0i(mftlo
, t0
, 2);
7533 gen_helper_1e0i(mfthi
, t0
, 2);
7536 gen_helper_1e0i(mftacx
, t0
, 2);
7539 gen_helper_1e0i(mftlo
, t0
, 3);
7542 gen_helper_1e0i(mfthi
, t0
, 3);
7545 gen_helper_1e0i(mftacx
, t0
, 3);
7548 gen_helper_mftdsp(t0
, cpu_env
);
7554 /* Floating point (COP1). */
7556 /* XXX: For now we support only a single FPU context. */
7558 TCGv_i32 fp0
= tcg_temp_new_i32();
7560 gen_load_fpr32(fp0
, rt
);
7561 tcg_gen_ext_i32_tl(t0
, fp0
);
7562 tcg_temp_free_i32(fp0
);
7564 TCGv_i32 fp0
= tcg_temp_new_i32();
7566 gen_load_fpr32h(ctx
, fp0
, rt
);
7567 tcg_gen_ext_i32_tl(t0
, fp0
);
7568 tcg_temp_free_i32(fp0
);
7572 /* XXX: For now we support only a single FPU context. */
7573 gen_helper_1e0i(cfc1
, t0
, rt
);
7575 /* COP2: Not implemented. */
7582 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7583 gen_store_gpr(t0
, rd
);
7589 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7590 generate_exception(ctx
, EXCP_RI
);
7593 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
7594 int u
, int sel
, int h
)
7596 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7597 TCGv t0
= tcg_temp_local_new();
7599 gen_load_gpr(t0
, rt
);
7600 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7601 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7602 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7604 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7605 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7612 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
7615 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
7625 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
7628 gen_helper_mttc0_tcbind(cpu_env
, t0
);
7631 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
7634 gen_helper_mttc0_tchalt(cpu_env
, t0
);
7637 gen_helper_mttc0_tccontext(cpu_env
, t0
);
7640 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
7643 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
7646 gen_mtc0(ctx
, t0
, rd
, sel
);
7653 gen_helper_mttc0_entryhi(cpu_env
, t0
);
7656 gen_mtc0(ctx
, t0
, rd
, sel
);
7662 gen_helper_mttc0_status(cpu_env
, t0
);
7665 gen_mtc0(ctx
, t0
, rd
, sel
);
7671 gen_helper_mttc0_cause(cpu_env
, t0
);
7681 gen_helper_mttc0_ebase(cpu_env
, t0
);
7691 gen_helper_mttc0_debug(cpu_env
, t0
);
7694 gen_mtc0(ctx
, t0
, rd
, sel
);
7699 gen_mtc0(ctx
, t0
, rd
, sel
);
7701 } else switch (sel
) {
7702 /* GPR registers. */
7704 gen_helper_0e1i(mttgpr
, t0
, rd
);
7706 /* Auxiliary CPU registers */
7710 gen_helper_0e1i(mttlo
, t0
, 0);
7713 gen_helper_0e1i(mtthi
, t0
, 0);
7716 gen_helper_0e1i(mttacx
, t0
, 0);
7719 gen_helper_0e1i(mttlo
, t0
, 1);
7722 gen_helper_0e1i(mtthi
, t0
, 1);
7725 gen_helper_0e1i(mttacx
, t0
, 1);
7728 gen_helper_0e1i(mttlo
, t0
, 2);
7731 gen_helper_0e1i(mtthi
, t0
, 2);
7734 gen_helper_0e1i(mttacx
, t0
, 2);
7737 gen_helper_0e1i(mttlo
, t0
, 3);
7740 gen_helper_0e1i(mtthi
, t0
, 3);
7743 gen_helper_0e1i(mttacx
, t0
, 3);
7746 gen_helper_mttdsp(cpu_env
, t0
);
7752 /* Floating point (COP1). */
7754 /* XXX: For now we support only a single FPU context. */
7756 TCGv_i32 fp0
= tcg_temp_new_i32();
7758 tcg_gen_trunc_tl_i32(fp0
, t0
);
7759 gen_store_fpr32(fp0
, rd
);
7760 tcg_temp_free_i32(fp0
);
7762 TCGv_i32 fp0
= tcg_temp_new_i32();
7764 tcg_gen_trunc_tl_i32(fp0
, t0
);
7765 gen_store_fpr32h(ctx
, fp0
, rd
);
7766 tcg_temp_free_i32(fp0
);
7770 /* XXX: For now we support only a single FPU context. */
7771 save_cpu_state(ctx
, 1);
7773 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
7775 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7776 tcg_temp_free_i32(fs_tmp
);
7778 /* Stop translation as we may have changed hflags */
7779 ctx
->bstate
= BS_STOP
;
7781 /* COP2: Not implemented. */
7788 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
7794 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
7795 generate_exception(ctx
, EXCP_RI
);
7798 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
7800 const char *opn
= "ldst";
7802 check_cp0_enabled(ctx
);
7809 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
7814 TCGv t0
= tcg_temp_new();
7816 gen_load_gpr(t0
, rt
);
7817 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
7822 #if defined(TARGET_MIPS64)
7824 check_insn(ctx
, ISA_MIPS3
);
7829 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
7833 check_insn(ctx
, ISA_MIPS3
);
7835 TCGv t0
= tcg_temp_new();
7837 gen_load_gpr(t0
, rt
);
7838 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
7845 check_insn(ctx
, ASE_MT
);
7850 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
7851 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
7855 check_insn(ctx
, ASE_MT
);
7856 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
7857 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
7862 if (!env
->tlb
->helper_tlbwi
)
7864 gen_helper_tlbwi(cpu_env
);
7869 if (!env
->tlb
->helper_tlbinv
) {
7872 gen_helper_tlbinv(cpu_env
);
7873 } /* treat as nop if TLBINV not supported */
7878 if (!env
->tlb
->helper_tlbinvf
) {
7881 gen_helper_tlbinvf(cpu_env
);
7882 } /* treat as nop if TLBINV not supported */
7886 if (!env
->tlb
->helper_tlbwr
)
7888 gen_helper_tlbwr(cpu_env
);
7892 if (!env
->tlb
->helper_tlbp
)
7894 gen_helper_tlbp(cpu_env
);
7898 if (!env
->tlb
->helper_tlbr
)
7900 gen_helper_tlbr(cpu_env
);
7904 check_insn(ctx
, ISA_MIPS2
);
7905 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
7906 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
7907 MIPS_DEBUG("CTI in delay / forbidden slot");
7910 gen_helper_eret(cpu_env
);
7911 ctx
->bstate
= BS_EXCP
;
7915 check_insn(ctx
, ISA_MIPS32
);
7916 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
7917 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
7918 MIPS_DEBUG("CTI in delay / forbidden slot");
7921 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
7923 generate_exception(ctx
, EXCP_RI
);
7925 gen_helper_deret(cpu_env
);
7926 ctx
->bstate
= BS_EXCP
;
7931 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
7932 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
7933 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
7934 MIPS_DEBUG("CTI in delay / forbidden slot");
7937 /* If we get an exception, we want to restart at next instruction */
7939 save_cpu_state(ctx
, 1);
7941 gen_helper_wait(cpu_env
);
7942 ctx
->bstate
= BS_EXCP
;
7947 generate_exception(ctx
, EXCP_RI
);
7950 (void)opn
; /* avoid a compiler warning */
7951 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
7953 #endif /* !CONFIG_USER_ONLY */
7955 /* CP1 Branches (before delay slot) */
7956 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
7957 int32_t cc
, int32_t offset
)
7959 target_ulong btarget
;
7960 const char *opn
= "cp1 cond branch";
7961 TCGv_i32 t0
= tcg_temp_new_i32();
7963 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
7964 MIPS_DEBUG("CTI in delay / forbidden slot");
7965 generate_exception(ctx
, EXCP_RI
);
7970 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
7972 btarget
= ctx
->pc
+ 4 + offset
;
7976 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7977 tcg_gen_not_i32(t0
, t0
);
7978 tcg_gen_andi_i32(t0
, t0
, 1);
7979 tcg_gen_extu_i32_tl(bcond
, t0
);
7983 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7984 tcg_gen_not_i32(t0
, t0
);
7985 tcg_gen_andi_i32(t0
, t0
, 1);
7986 tcg_gen_extu_i32_tl(bcond
, t0
);
7990 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7991 tcg_gen_andi_i32(t0
, t0
, 1);
7992 tcg_gen_extu_i32_tl(bcond
, t0
);
7996 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7997 tcg_gen_andi_i32(t0
, t0
, 1);
7998 tcg_gen_extu_i32_tl(bcond
, t0
);
8001 ctx
->hflags
|= MIPS_HFLAG_BL
;
8005 TCGv_i32 t1
= tcg_temp_new_i32();
8006 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8007 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8008 tcg_gen_nand_i32(t0
, t0
, t1
);
8009 tcg_temp_free_i32(t1
);
8010 tcg_gen_andi_i32(t0
, t0
, 1);
8011 tcg_gen_extu_i32_tl(bcond
, t0
);
8017 TCGv_i32 t1
= tcg_temp_new_i32();
8018 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8019 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8020 tcg_gen_or_i32(t0
, t0
, t1
);
8021 tcg_temp_free_i32(t1
);
8022 tcg_gen_andi_i32(t0
, t0
, 1);
8023 tcg_gen_extu_i32_tl(bcond
, t0
);
8029 TCGv_i32 t1
= tcg_temp_new_i32();
8030 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8031 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8032 tcg_gen_and_i32(t0
, t0
, t1
);
8033 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8034 tcg_gen_and_i32(t0
, t0
, t1
);
8035 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8036 tcg_gen_nand_i32(t0
, t0
, t1
);
8037 tcg_temp_free_i32(t1
);
8038 tcg_gen_andi_i32(t0
, t0
, 1);
8039 tcg_gen_extu_i32_tl(bcond
, t0
);
8045 TCGv_i32 t1
= tcg_temp_new_i32();
8046 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8047 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8048 tcg_gen_or_i32(t0
, t0
, t1
);
8049 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8050 tcg_gen_or_i32(t0
, t0
, t1
);
8051 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8052 tcg_gen_or_i32(t0
, t0
, t1
);
8053 tcg_temp_free_i32(t1
);
8054 tcg_gen_andi_i32(t0
, t0
, 1);
8055 tcg_gen_extu_i32_tl(bcond
, t0
);
8059 ctx
->hflags
|= MIPS_HFLAG_BC
;
8063 generate_exception (ctx
, EXCP_RI
);
8066 (void)opn
; /* avoid a compiler warning */
8067 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
8068 ctx
->hflags
, btarget
);
8069 ctx
->btarget
= btarget
;
8070 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8072 tcg_temp_free_i32(t0
);
8075 /* R6 CP1 Branches */
8076 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
8077 int32_t ft
, int32_t offset
)
8079 target_ulong btarget
;
8080 const char *opn
= "cp1 cond branch";
8081 TCGv_i64 t0
= tcg_temp_new_i64();
8083 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
8084 #ifdef MIPS_DEBUG_DISAS
8085 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8088 generate_exception(ctx
, EXCP_RI
);
8092 gen_load_fpr64(ctx
, t0
, ft
);
8093 tcg_gen_andi_i64(t0
, t0
, 1);
8095 btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
8099 tcg_gen_xori_i64(t0
, t0
, 1);
8101 ctx
->hflags
|= MIPS_HFLAG_BC
;
8104 /* t0 already set */
8106 ctx
->hflags
|= MIPS_HFLAG_BC
;
8110 generate_exception(ctx
, EXCP_RI
);
8114 tcg_gen_trunc_i64_tl(bcond
, t0
);
8116 (void)opn
; /* avoid a compiler warning */
8117 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
8118 ctx
->hflags
, btarget
);
8119 ctx
->btarget
= btarget
;
8120 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8123 tcg_temp_free_i64(t0
);
8126 /* Coprocessor 1 (FPU) */
8128 #define FOP(func, fmt) (((fmt) << 21) | (func))
8131 OPC_ADD_S
= FOP(0, FMT_S
),
8132 OPC_SUB_S
= FOP(1, FMT_S
),
8133 OPC_MUL_S
= FOP(2, FMT_S
),
8134 OPC_DIV_S
= FOP(3, FMT_S
),
8135 OPC_SQRT_S
= FOP(4, FMT_S
),
8136 OPC_ABS_S
= FOP(5, FMT_S
),
8137 OPC_MOV_S
= FOP(6, FMT_S
),
8138 OPC_NEG_S
= FOP(7, FMT_S
),
8139 OPC_ROUND_L_S
= FOP(8, FMT_S
),
8140 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
8141 OPC_CEIL_L_S
= FOP(10, FMT_S
),
8142 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
8143 OPC_ROUND_W_S
= FOP(12, FMT_S
),
8144 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
8145 OPC_CEIL_W_S
= FOP(14, FMT_S
),
8146 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
8147 OPC_SEL_S
= FOP(16, FMT_S
),
8148 OPC_MOVCF_S
= FOP(17, FMT_S
),
8149 OPC_MOVZ_S
= FOP(18, FMT_S
),
8150 OPC_MOVN_S
= FOP(19, FMT_S
),
8151 OPC_SELEQZ_S
= FOP(20, FMT_S
),
8152 OPC_RECIP_S
= FOP(21, FMT_S
),
8153 OPC_RSQRT_S
= FOP(22, FMT_S
),
8154 OPC_SELNEZ_S
= FOP(23, FMT_S
),
8155 OPC_MADDF_S
= FOP(24, FMT_S
),
8156 OPC_MSUBF_S
= FOP(25, FMT_S
),
8157 OPC_RINT_S
= FOP(26, FMT_S
),
8158 OPC_CLASS_S
= FOP(27, FMT_S
),
8159 OPC_MIN_S
= FOP(28, FMT_S
),
8160 OPC_RECIP2_S
= FOP(28, FMT_S
),
8161 OPC_MINA_S
= FOP(29, FMT_S
),
8162 OPC_RECIP1_S
= FOP(29, FMT_S
),
8163 OPC_MAX_S
= FOP(30, FMT_S
),
8164 OPC_RSQRT1_S
= FOP(30, FMT_S
),
8165 OPC_MAXA_S
= FOP(31, FMT_S
),
8166 OPC_RSQRT2_S
= FOP(31, FMT_S
),
8167 OPC_CVT_D_S
= FOP(33, FMT_S
),
8168 OPC_CVT_W_S
= FOP(36, FMT_S
),
8169 OPC_CVT_L_S
= FOP(37, FMT_S
),
8170 OPC_CVT_PS_S
= FOP(38, FMT_S
),
8171 OPC_CMP_F_S
= FOP (48, FMT_S
),
8172 OPC_CMP_UN_S
= FOP (49, FMT_S
),
8173 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
8174 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
8175 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
8176 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
8177 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
8178 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
8179 OPC_CMP_SF_S
= FOP (56, FMT_S
),
8180 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
8181 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
8182 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
8183 OPC_CMP_LT_S
= FOP (60, FMT_S
),
8184 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
8185 OPC_CMP_LE_S
= FOP (62, FMT_S
),
8186 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
8188 OPC_ADD_D
= FOP(0, FMT_D
),
8189 OPC_SUB_D
= FOP(1, FMT_D
),
8190 OPC_MUL_D
= FOP(2, FMT_D
),
8191 OPC_DIV_D
= FOP(3, FMT_D
),
8192 OPC_SQRT_D
= FOP(4, FMT_D
),
8193 OPC_ABS_D
= FOP(5, FMT_D
),
8194 OPC_MOV_D
= FOP(6, FMT_D
),
8195 OPC_NEG_D
= FOP(7, FMT_D
),
8196 OPC_ROUND_L_D
= FOP(8, FMT_D
),
8197 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
8198 OPC_CEIL_L_D
= FOP(10, FMT_D
),
8199 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
8200 OPC_ROUND_W_D
= FOP(12, FMT_D
),
8201 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
8202 OPC_CEIL_W_D
= FOP(14, FMT_D
),
8203 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
8204 OPC_SEL_D
= FOP(16, FMT_D
),
8205 OPC_MOVCF_D
= FOP(17, FMT_D
),
8206 OPC_MOVZ_D
= FOP(18, FMT_D
),
8207 OPC_MOVN_D
= FOP(19, FMT_D
),
8208 OPC_SELEQZ_D
= FOP(20, FMT_D
),
8209 OPC_RECIP_D
= FOP(21, FMT_D
),
8210 OPC_RSQRT_D
= FOP(22, FMT_D
),
8211 OPC_SELNEZ_D
= FOP(23, FMT_D
),
8212 OPC_MADDF_D
= FOP(24, FMT_D
),
8213 OPC_MSUBF_D
= FOP(25, FMT_D
),
8214 OPC_RINT_D
= FOP(26, FMT_D
),
8215 OPC_CLASS_D
= FOP(27, FMT_D
),
8216 OPC_MIN_D
= FOP(28, FMT_D
),
8217 OPC_RECIP2_D
= FOP(28, FMT_D
),
8218 OPC_MINA_D
= FOP(29, FMT_D
),
8219 OPC_RECIP1_D
= FOP(29, FMT_D
),
8220 OPC_MAX_D
= FOP(30, FMT_D
),
8221 OPC_RSQRT1_D
= FOP(30, FMT_D
),
8222 OPC_MAXA_D
= FOP(31, FMT_D
),
8223 OPC_RSQRT2_D
= FOP(31, FMT_D
),
8224 OPC_CVT_S_D
= FOP(32, FMT_D
),
8225 OPC_CVT_W_D
= FOP(36, FMT_D
),
8226 OPC_CVT_L_D
= FOP(37, FMT_D
),
8227 OPC_CMP_F_D
= FOP (48, FMT_D
),
8228 OPC_CMP_UN_D
= FOP (49, FMT_D
),
8229 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
8230 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
8231 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
8232 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
8233 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
8234 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
8235 OPC_CMP_SF_D
= FOP (56, FMT_D
),
8236 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
8237 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
8238 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
8239 OPC_CMP_LT_D
= FOP (60, FMT_D
),
8240 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
8241 OPC_CMP_LE_D
= FOP (62, FMT_D
),
8242 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
8244 OPC_CVT_S_W
= FOP(32, FMT_W
),
8245 OPC_CVT_D_W
= FOP(33, FMT_W
),
8246 OPC_CVT_S_L
= FOP(32, FMT_L
),
8247 OPC_CVT_D_L
= FOP(33, FMT_L
),
8248 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
8250 OPC_ADD_PS
= FOP(0, FMT_PS
),
8251 OPC_SUB_PS
= FOP(1, FMT_PS
),
8252 OPC_MUL_PS
= FOP(2, FMT_PS
),
8253 OPC_DIV_PS
= FOP(3, FMT_PS
),
8254 OPC_ABS_PS
= FOP(5, FMT_PS
),
8255 OPC_MOV_PS
= FOP(6, FMT_PS
),
8256 OPC_NEG_PS
= FOP(7, FMT_PS
),
8257 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
8258 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
8259 OPC_MOVN_PS
= FOP(19, FMT_PS
),
8260 OPC_ADDR_PS
= FOP(24, FMT_PS
),
8261 OPC_MULR_PS
= FOP(26, FMT_PS
),
8262 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
8263 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
8264 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
8265 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
8267 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
8268 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
8269 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
8270 OPC_PLL_PS
= FOP(44, FMT_PS
),
8271 OPC_PLU_PS
= FOP(45, FMT_PS
),
8272 OPC_PUL_PS
= FOP(46, FMT_PS
),
8273 OPC_PUU_PS
= FOP(47, FMT_PS
),
8274 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
8275 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
8276 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
8277 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
8278 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
8279 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
8280 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
8281 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
8282 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
8283 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
8284 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
8285 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
8286 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
8287 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
8288 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
8289 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
8293 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
8294 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
8295 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
8296 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
8297 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
8298 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
8299 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
8300 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
8301 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
8302 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
8303 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
8304 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
8305 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
8306 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
8307 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
8308 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
8309 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
8310 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
8311 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
8312 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
8313 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
8314 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
8316 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
8317 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
8318 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
8319 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
8320 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
8321 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
8322 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
8323 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
8324 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
8325 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
8326 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
8327 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
8328 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
8329 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
8330 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
8331 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
8332 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
8333 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
8334 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
8335 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
8336 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
8337 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
8339 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
8341 const char *opn
= "cp1 move";
8342 TCGv t0
= tcg_temp_new();
8347 TCGv_i32 fp0
= tcg_temp_new_i32();
8349 gen_load_fpr32(fp0
, fs
);
8350 tcg_gen_ext_i32_tl(t0
, fp0
);
8351 tcg_temp_free_i32(fp0
);
8353 gen_store_gpr(t0
, rt
);
8357 gen_load_gpr(t0
, rt
);
8359 TCGv_i32 fp0
= tcg_temp_new_i32();
8361 tcg_gen_trunc_tl_i32(fp0
, t0
);
8362 gen_store_fpr32(fp0
, fs
);
8363 tcg_temp_free_i32(fp0
);
8368 gen_helper_1e0i(cfc1
, t0
, fs
);
8369 gen_store_gpr(t0
, rt
);
8373 gen_load_gpr(t0
, rt
);
8374 save_cpu_state(ctx
, 1);
8376 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
8378 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8379 tcg_temp_free_i32(fs_tmp
);
8381 /* Stop translation as we may have changed hflags */
8382 ctx
->bstate
= BS_STOP
;
8385 #if defined(TARGET_MIPS64)
8387 gen_load_fpr64(ctx
, t0
, fs
);
8388 gen_store_gpr(t0
, rt
);
8392 gen_load_gpr(t0
, rt
);
8393 gen_store_fpr64(ctx
, t0
, fs
);
8399 TCGv_i32 fp0
= tcg_temp_new_i32();
8401 gen_load_fpr32h(ctx
, fp0
, fs
);
8402 tcg_gen_ext_i32_tl(t0
, fp0
);
8403 tcg_temp_free_i32(fp0
);
8405 gen_store_gpr(t0
, rt
);
8409 gen_load_gpr(t0
, rt
);
8411 TCGv_i32 fp0
= tcg_temp_new_i32();
8413 tcg_gen_trunc_tl_i32(fp0
, t0
);
8414 gen_store_fpr32h(ctx
, fp0
, fs
);
8415 tcg_temp_free_i32(fp0
);
8421 generate_exception (ctx
, EXCP_RI
);
8424 (void)opn
; /* avoid a compiler warning */
8425 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
8431 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
8447 l1
= gen_new_label();
8448 t0
= tcg_temp_new_i32();
8449 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8450 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8451 tcg_temp_free_i32(t0
);
8453 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
8455 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
8460 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
8463 TCGv_i32 t0
= tcg_temp_new_i32();
8464 TCGLabel
*l1
= gen_new_label();
8471 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8472 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8473 gen_load_fpr32(t0
, fs
);
8474 gen_store_fpr32(t0
, fd
);
8476 tcg_temp_free_i32(t0
);
8479 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
8482 TCGv_i32 t0
= tcg_temp_new_i32();
8484 TCGLabel
*l1
= gen_new_label();
8491 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8492 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8493 tcg_temp_free_i32(t0
);
8494 fp0
= tcg_temp_new_i64();
8495 gen_load_fpr64(ctx
, fp0
, fs
);
8496 gen_store_fpr64(ctx
, fp0
, fd
);
8497 tcg_temp_free_i64(fp0
);
8501 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
8505 TCGv_i32 t0
= tcg_temp_new_i32();
8506 TCGLabel
*l1
= gen_new_label();
8507 TCGLabel
*l2
= gen_new_label();
8514 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8515 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8516 gen_load_fpr32(t0
, fs
);
8517 gen_store_fpr32(t0
, fd
);
8520 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
8521 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
8522 gen_load_fpr32h(ctx
, t0
, fs
);
8523 gen_store_fpr32h(ctx
, t0
, fd
);
8524 tcg_temp_free_i32(t0
);
8528 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8531 TCGv_i32 t1
= tcg_const_i32(0);
8532 TCGv_i32 fp0
= tcg_temp_new_i32();
8533 TCGv_i32 fp1
= tcg_temp_new_i32();
8534 TCGv_i32 fp2
= tcg_temp_new_i32();
8535 gen_load_fpr32(fp0
, fd
);
8536 gen_load_fpr32(fp1
, ft
);
8537 gen_load_fpr32(fp2
, fs
);
8541 tcg_gen_andi_i32(fp0
, fp0
, 1);
8542 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8545 tcg_gen_andi_i32(fp1
, fp1
, 1);
8546 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8549 tcg_gen_andi_i32(fp1
, fp1
, 1);
8550 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8553 MIPS_INVAL("gen_sel_s");
8554 generate_exception (ctx
, EXCP_RI
);
8558 gen_store_fpr32(fp0
, fd
);
8559 tcg_temp_free_i32(fp2
);
8560 tcg_temp_free_i32(fp1
);
8561 tcg_temp_free_i32(fp0
);
8562 tcg_temp_free_i32(t1
);
8565 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8568 TCGv_i64 t1
= tcg_const_i64(0);
8569 TCGv_i64 fp0
= tcg_temp_new_i64();
8570 TCGv_i64 fp1
= tcg_temp_new_i64();
8571 TCGv_i64 fp2
= tcg_temp_new_i64();
8572 gen_load_fpr64(ctx
, fp0
, fd
);
8573 gen_load_fpr64(ctx
, fp1
, ft
);
8574 gen_load_fpr64(ctx
, fp2
, fs
);
8578 tcg_gen_andi_i64(fp0
, fp0
, 1);
8579 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8582 tcg_gen_andi_i64(fp1
, fp1
, 1);
8583 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8586 tcg_gen_andi_i64(fp1
, fp1
, 1);
8587 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8590 MIPS_INVAL("gen_sel_d");
8591 generate_exception (ctx
, EXCP_RI
);
8595 gen_store_fpr64(ctx
, fp0
, fd
);
8596 tcg_temp_free_i64(fp2
);
8597 tcg_temp_free_i64(fp1
);
8598 tcg_temp_free_i64(fp0
);
8599 tcg_temp_free_i64(t1
);
8602 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
8603 int ft
, int fs
, int fd
, int cc
)
8605 const char *opn
= "farith";
8606 const char *condnames
[] = {
8624 const char *condnames_abs
[] = {
8642 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
8643 uint32_t func
= ctx
->opcode
& 0x3f;
8648 TCGv_i32 fp0
= tcg_temp_new_i32();
8649 TCGv_i32 fp1
= tcg_temp_new_i32();
8651 gen_load_fpr32(fp0
, fs
);
8652 gen_load_fpr32(fp1
, ft
);
8653 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
8654 tcg_temp_free_i32(fp1
);
8655 gen_store_fpr32(fp0
, fd
);
8656 tcg_temp_free_i32(fp0
);
8663 TCGv_i32 fp0
= tcg_temp_new_i32();
8664 TCGv_i32 fp1
= tcg_temp_new_i32();
8666 gen_load_fpr32(fp0
, fs
);
8667 gen_load_fpr32(fp1
, ft
);
8668 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
8669 tcg_temp_free_i32(fp1
);
8670 gen_store_fpr32(fp0
, fd
);
8671 tcg_temp_free_i32(fp0
);
8678 TCGv_i32 fp0
= tcg_temp_new_i32();
8679 TCGv_i32 fp1
= tcg_temp_new_i32();
8681 gen_load_fpr32(fp0
, fs
);
8682 gen_load_fpr32(fp1
, ft
);
8683 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
8684 tcg_temp_free_i32(fp1
);
8685 gen_store_fpr32(fp0
, fd
);
8686 tcg_temp_free_i32(fp0
);
8693 TCGv_i32 fp0
= tcg_temp_new_i32();
8694 TCGv_i32 fp1
= tcg_temp_new_i32();
8696 gen_load_fpr32(fp0
, fs
);
8697 gen_load_fpr32(fp1
, ft
);
8698 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
8699 tcg_temp_free_i32(fp1
);
8700 gen_store_fpr32(fp0
, fd
);
8701 tcg_temp_free_i32(fp0
);
8708 TCGv_i32 fp0
= tcg_temp_new_i32();
8710 gen_load_fpr32(fp0
, fs
);
8711 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
8712 gen_store_fpr32(fp0
, fd
);
8713 tcg_temp_free_i32(fp0
);
8719 TCGv_i32 fp0
= tcg_temp_new_i32();
8721 gen_load_fpr32(fp0
, fs
);
8722 gen_helper_float_abs_s(fp0
, fp0
);
8723 gen_store_fpr32(fp0
, fd
);
8724 tcg_temp_free_i32(fp0
);
8730 TCGv_i32 fp0
= tcg_temp_new_i32();
8732 gen_load_fpr32(fp0
, fs
);
8733 gen_store_fpr32(fp0
, fd
);
8734 tcg_temp_free_i32(fp0
);
8740 TCGv_i32 fp0
= tcg_temp_new_i32();
8742 gen_load_fpr32(fp0
, fs
);
8743 gen_helper_float_chs_s(fp0
, fp0
);
8744 gen_store_fpr32(fp0
, fd
);
8745 tcg_temp_free_i32(fp0
);
8750 check_cp1_64bitmode(ctx
);
8752 TCGv_i32 fp32
= tcg_temp_new_i32();
8753 TCGv_i64 fp64
= tcg_temp_new_i64();
8755 gen_load_fpr32(fp32
, fs
);
8756 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
8757 tcg_temp_free_i32(fp32
);
8758 gen_store_fpr64(ctx
, fp64
, fd
);
8759 tcg_temp_free_i64(fp64
);
8764 check_cp1_64bitmode(ctx
);
8766 TCGv_i32 fp32
= tcg_temp_new_i32();
8767 TCGv_i64 fp64
= tcg_temp_new_i64();
8769 gen_load_fpr32(fp32
, fs
);
8770 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
8771 tcg_temp_free_i32(fp32
);
8772 gen_store_fpr64(ctx
, fp64
, fd
);
8773 tcg_temp_free_i64(fp64
);
8778 check_cp1_64bitmode(ctx
);
8780 TCGv_i32 fp32
= tcg_temp_new_i32();
8781 TCGv_i64 fp64
= tcg_temp_new_i64();
8783 gen_load_fpr32(fp32
, fs
);
8784 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
8785 tcg_temp_free_i32(fp32
);
8786 gen_store_fpr64(ctx
, fp64
, fd
);
8787 tcg_temp_free_i64(fp64
);
8792 check_cp1_64bitmode(ctx
);
8794 TCGv_i32 fp32
= tcg_temp_new_i32();
8795 TCGv_i64 fp64
= tcg_temp_new_i64();
8797 gen_load_fpr32(fp32
, fs
);
8798 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
8799 tcg_temp_free_i32(fp32
);
8800 gen_store_fpr64(ctx
, fp64
, fd
);
8801 tcg_temp_free_i64(fp64
);
8807 TCGv_i32 fp0
= tcg_temp_new_i32();
8809 gen_load_fpr32(fp0
, fs
);
8810 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
8811 gen_store_fpr32(fp0
, fd
);
8812 tcg_temp_free_i32(fp0
);
8818 TCGv_i32 fp0
= tcg_temp_new_i32();
8820 gen_load_fpr32(fp0
, fs
);
8821 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
8822 gen_store_fpr32(fp0
, fd
);
8823 tcg_temp_free_i32(fp0
);
8829 TCGv_i32 fp0
= tcg_temp_new_i32();
8831 gen_load_fpr32(fp0
, fs
);
8832 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
8833 gen_store_fpr32(fp0
, fd
);
8834 tcg_temp_free_i32(fp0
);
8840 TCGv_i32 fp0
= tcg_temp_new_i32();
8842 gen_load_fpr32(fp0
, fs
);
8843 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
8844 gen_store_fpr32(fp0
, fd
);
8845 tcg_temp_free_i32(fp0
);
8850 check_insn(ctx
, ISA_MIPS32R6
);
8851 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8855 check_insn(ctx
, ISA_MIPS32R6
);
8856 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8860 check_insn(ctx
, ISA_MIPS32R6
);
8861 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8865 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8866 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8870 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8872 TCGLabel
*l1
= gen_new_label();
8876 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8878 fp0
= tcg_temp_new_i32();
8879 gen_load_fpr32(fp0
, fs
);
8880 gen_store_fpr32(fp0
, fd
);
8881 tcg_temp_free_i32(fp0
);
8887 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8889 TCGLabel
*l1
= gen_new_label();
8893 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8894 fp0
= tcg_temp_new_i32();
8895 gen_load_fpr32(fp0
, fs
);
8896 gen_store_fpr32(fp0
, fd
);
8897 tcg_temp_free_i32(fp0
);
8906 TCGv_i32 fp0
= tcg_temp_new_i32();
8908 gen_load_fpr32(fp0
, fs
);
8909 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
8910 gen_store_fpr32(fp0
, fd
);
8911 tcg_temp_free_i32(fp0
);
8918 TCGv_i32 fp0
= tcg_temp_new_i32();
8920 gen_load_fpr32(fp0
, fs
);
8921 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
8922 gen_store_fpr32(fp0
, fd
);
8923 tcg_temp_free_i32(fp0
);
8928 check_insn(ctx
, ISA_MIPS32R6
);
8930 TCGv_i32 fp0
= tcg_temp_new_i32();
8931 TCGv_i32 fp1
= tcg_temp_new_i32();
8932 TCGv_i32 fp2
= tcg_temp_new_i32();
8933 gen_load_fpr32(fp0
, fs
);
8934 gen_load_fpr32(fp1
, ft
);
8935 gen_load_fpr32(fp2
, fd
);
8936 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8937 gen_store_fpr32(fp2
, fd
);
8938 tcg_temp_free_i32(fp2
);
8939 tcg_temp_free_i32(fp1
);
8940 tcg_temp_free_i32(fp0
);
8945 check_insn(ctx
, ISA_MIPS32R6
);
8947 TCGv_i32 fp0
= tcg_temp_new_i32();
8948 TCGv_i32 fp1
= tcg_temp_new_i32();
8949 TCGv_i32 fp2
= tcg_temp_new_i32();
8950 gen_load_fpr32(fp0
, fs
);
8951 gen_load_fpr32(fp1
, ft
);
8952 gen_load_fpr32(fp2
, fd
);
8953 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8954 gen_store_fpr32(fp2
, fd
);
8955 tcg_temp_free_i32(fp2
);
8956 tcg_temp_free_i32(fp1
);
8957 tcg_temp_free_i32(fp0
);
8962 check_insn(ctx
, ISA_MIPS32R6
);
8964 TCGv_i32 fp0
= tcg_temp_new_i32();
8965 gen_load_fpr32(fp0
, fs
);
8966 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
8967 gen_store_fpr32(fp0
, fd
);
8968 tcg_temp_free_i32(fp0
);
8973 check_insn(ctx
, ISA_MIPS32R6
);
8975 TCGv_i32 fp0
= tcg_temp_new_i32();
8976 gen_load_fpr32(fp0
, fs
);
8977 gen_helper_float_class_s(fp0
, fp0
);
8978 gen_store_fpr32(fp0
, fd
);
8979 tcg_temp_free_i32(fp0
);
8983 case OPC_MIN_S
: /* OPC_RECIP2_S */
8984 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8986 TCGv_i32 fp0
= tcg_temp_new_i32();
8987 TCGv_i32 fp1
= tcg_temp_new_i32();
8988 TCGv_i32 fp2
= tcg_temp_new_i32();
8989 gen_load_fpr32(fp0
, fs
);
8990 gen_load_fpr32(fp1
, ft
);
8991 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
8992 gen_store_fpr32(fp2
, fd
);
8993 tcg_temp_free_i32(fp2
);
8994 tcg_temp_free_i32(fp1
);
8995 tcg_temp_free_i32(fp0
);
8999 check_cp1_64bitmode(ctx
);
9001 TCGv_i32 fp0
= tcg_temp_new_i32();
9002 TCGv_i32 fp1
= tcg_temp_new_i32();
9004 gen_load_fpr32(fp0
, fs
);
9005 gen_load_fpr32(fp1
, ft
);
9006 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
9007 tcg_temp_free_i32(fp1
);
9008 gen_store_fpr32(fp0
, fd
);
9009 tcg_temp_free_i32(fp0
);
9014 case OPC_MINA_S
: /* OPC_RECIP1_S */
9015 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9017 TCGv_i32 fp0
= tcg_temp_new_i32();
9018 TCGv_i32 fp1
= tcg_temp_new_i32();
9019 TCGv_i32 fp2
= tcg_temp_new_i32();
9020 gen_load_fpr32(fp0
, fs
);
9021 gen_load_fpr32(fp1
, ft
);
9022 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
9023 gen_store_fpr32(fp2
, fd
);
9024 tcg_temp_free_i32(fp2
);
9025 tcg_temp_free_i32(fp1
);
9026 tcg_temp_free_i32(fp0
);
9030 check_cp1_64bitmode(ctx
);
9032 TCGv_i32 fp0
= tcg_temp_new_i32();
9034 gen_load_fpr32(fp0
, fs
);
9035 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
9036 gen_store_fpr32(fp0
, fd
);
9037 tcg_temp_free_i32(fp0
);
9042 case OPC_MAX_S
: /* OPC_RSQRT1_S */
9043 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9045 TCGv_i32 fp0
= tcg_temp_new_i32();
9046 TCGv_i32 fp1
= tcg_temp_new_i32();
9047 gen_load_fpr32(fp0
, fs
);
9048 gen_load_fpr32(fp1
, ft
);
9049 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
9050 gen_store_fpr32(fp1
, fd
);
9051 tcg_temp_free_i32(fp1
);
9052 tcg_temp_free_i32(fp0
);
9056 check_cp1_64bitmode(ctx
);
9058 TCGv_i32 fp0
= tcg_temp_new_i32();
9060 gen_load_fpr32(fp0
, fs
);
9061 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
9062 gen_store_fpr32(fp0
, fd
);
9063 tcg_temp_free_i32(fp0
);
9068 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
9069 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9071 TCGv_i32 fp0
= tcg_temp_new_i32();
9072 TCGv_i32 fp1
= tcg_temp_new_i32();
9073 gen_load_fpr32(fp0
, fs
);
9074 gen_load_fpr32(fp1
, ft
);
9075 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
9076 gen_store_fpr32(fp1
, fd
);
9077 tcg_temp_free_i32(fp1
);
9078 tcg_temp_free_i32(fp0
);
9082 check_cp1_64bitmode(ctx
);
9084 TCGv_i32 fp0
= tcg_temp_new_i32();
9085 TCGv_i32 fp1
= tcg_temp_new_i32();
9087 gen_load_fpr32(fp0
, fs
);
9088 gen_load_fpr32(fp1
, ft
);
9089 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
9090 tcg_temp_free_i32(fp1
);
9091 gen_store_fpr32(fp0
, fd
);
9092 tcg_temp_free_i32(fp0
);
9098 check_cp1_registers(ctx
, fd
);
9100 TCGv_i32 fp32
= tcg_temp_new_i32();
9101 TCGv_i64 fp64
= tcg_temp_new_i64();
9103 gen_load_fpr32(fp32
, fs
);
9104 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
9105 tcg_temp_free_i32(fp32
);
9106 gen_store_fpr64(ctx
, fp64
, fd
);
9107 tcg_temp_free_i64(fp64
);
9113 TCGv_i32 fp0
= tcg_temp_new_i32();
9115 gen_load_fpr32(fp0
, fs
);
9116 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
9117 gen_store_fpr32(fp0
, fd
);
9118 tcg_temp_free_i32(fp0
);
9123 check_cp1_64bitmode(ctx
);
9125 TCGv_i32 fp32
= tcg_temp_new_i32();
9126 TCGv_i64 fp64
= tcg_temp_new_i64();
9128 gen_load_fpr32(fp32
, fs
);
9129 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
9130 tcg_temp_free_i32(fp32
);
9131 gen_store_fpr64(ctx
, fp64
, fd
);
9132 tcg_temp_free_i64(fp64
);
9137 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9138 check_cp1_64bitmode(ctx
);
9140 TCGv_i64 fp64
= tcg_temp_new_i64();
9141 TCGv_i32 fp32_0
= tcg_temp_new_i32();
9142 TCGv_i32 fp32_1
= tcg_temp_new_i32();
9144 gen_load_fpr32(fp32_0
, fs
);
9145 gen_load_fpr32(fp32_1
, ft
);
9146 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
9147 tcg_temp_free_i32(fp32_1
);
9148 tcg_temp_free_i32(fp32_0
);
9149 gen_store_fpr64(ctx
, fp64
, fd
);
9150 tcg_temp_free_i64(fp64
);
9163 case OPC_CMP_NGLE_S
:
9170 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9171 if (ctx
->opcode
& (1 << 6)) {
9172 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
9173 opn
= condnames_abs
[func
-48];
9175 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
9176 opn
= condnames
[func
-48];
9180 check_cp1_registers(ctx
, fs
| ft
| fd
);
9182 TCGv_i64 fp0
= tcg_temp_new_i64();
9183 TCGv_i64 fp1
= tcg_temp_new_i64();
9185 gen_load_fpr64(ctx
, fp0
, fs
);
9186 gen_load_fpr64(ctx
, fp1
, ft
);
9187 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
9188 tcg_temp_free_i64(fp1
);
9189 gen_store_fpr64(ctx
, fp0
, fd
);
9190 tcg_temp_free_i64(fp0
);
9196 check_cp1_registers(ctx
, fs
| ft
| fd
);
9198 TCGv_i64 fp0
= tcg_temp_new_i64();
9199 TCGv_i64 fp1
= tcg_temp_new_i64();
9201 gen_load_fpr64(ctx
, fp0
, fs
);
9202 gen_load_fpr64(ctx
, fp1
, ft
);
9203 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
9204 tcg_temp_free_i64(fp1
);
9205 gen_store_fpr64(ctx
, fp0
, fd
);
9206 tcg_temp_free_i64(fp0
);
9212 check_cp1_registers(ctx
, fs
| ft
| fd
);
9214 TCGv_i64 fp0
= tcg_temp_new_i64();
9215 TCGv_i64 fp1
= tcg_temp_new_i64();
9217 gen_load_fpr64(ctx
, fp0
, fs
);
9218 gen_load_fpr64(ctx
, fp1
, ft
);
9219 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
9220 tcg_temp_free_i64(fp1
);
9221 gen_store_fpr64(ctx
, fp0
, fd
);
9222 tcg_temp_free_i64(fp0
);
9228 check_cp1_registers(ctx
, fs
| ft
| fd
);
9230 TCGv_i64 fp0
= tcg_temp_new_i64();
9231 TCGv_i64 fp1
= tcg_temp_new_i64();
9233 gen_load_fpr64(ctx
, fp0
, fs
);
9234 gen_load_fpr64(ctx
, fp1
, ft
);
9235 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
9236 tcg_temp_free_i64(fp1
);
9237 gen_store_fpr64(ctx
, fp0
, fd
);
9238 tcg_temp_free_i64(fp0
);
9244 check_cp1_registers(ctx
, fs
| fd
);
9246 TCGv_i64 fp0
= tcg_temp_new_i64();
9248 gen_load_fpr64(ctx
, fp0
, fs
);
9249 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
9250 gen_store_fpr64(ctx
, fp0
, fd
);
9251 tcg_temp_free_i64(fp0
);
9256 check_cp1_registers(ctx
, fs
| fd
);
9258 TCGv_i64 fp0
= tcg_temp_new_i64();
9260 gen_load_fpr64(ctx
, fp0
, fs
);
9261 gen_helper_float_abs_d(fp0
, fp0
);
9262 gen_store_fpr64(ctx
, fp0
, fd
);
9263 tcg_temp_free_i64(fp0
);
9268 check_cp1_registers(ctx
, fs
| fd
);
9270 TCGv_i64 fp0
= tcg_temp_new_i64();
9272 gen_load_fpr64(ctx
, fp0
, fs
);
9273 gen_store_fpr64(ctx
, fp0
, fd
);
9274 tcg_temp_free_i64(fp0
);
9279 check_cp1_registers(ctx
, fs
| fd
);
9281 TCGv_i64 fp0
= tcg_temp_new_i64();
9283 gen_load_fpr64(ctx
, fp0
, fs
);
9284 gen_helper_float_chs_d(fp0
, fp0
);
9285 gen_store_fpr64(ctx
, fp0
, fd
);
9286 tcg_temp_free_i64(fp0
);
9291 check_cp1_64bitmode(ctx
);
9293 TCGv_i64 fp0
= tcg_temp_new_i64();
9295 gen_load_fpr64(ctx
, fp0
, fs
);
9296 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
9297 gen_store_fpr64(ctx
, fp0
, fd
);
9298 tcg_temp_free_i64(fp0
);
9303 check_cp1_64bitmode(ctx
);
9305 TCGv_i64 fp0
= tcg_temp_new_i64();
9307 gen_load_fpr64(ctx
, fp0
, fs
);
9308 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
9309 gen_store_fpr64(ctx
, fp0
, fd
);
9310 tcg_temp_free_i64(fp0
);
9315 check_cp1_64bitmode(ctx
);
9317 TCGv_i64 fp0
= tcg_temp_new_i64();
9319 gen_load_fpr64(ctx
, fp0
, fs
);
9320 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
9321 gen_store_fpr64(ctx
, fp0
, fd
);
9322 tcg_temp_free_i64(fp0
);
9327 check_cp1_64bitmode(ctx
);
9329 TCGv_i64 fp0
= tcg_temp_new_i64();
9331 gen_load_fpr64(ctx
, fp0
, fs
);
9332 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
9333 gen_store_fpr64(ctx
, fp0
, fd
);
9334 tcg_temp_free_i64(fp0
);
9339 check_cp1_registers(ctx
, fs
);
9341 TCGv_i32 fp32
= tcg_temp_new_i32();
9342 TCGv_i64 fp64
= tcg_temp_new_i64();
9344 gen_load_fpr64(ctx
, fp64
, fs
);
9345 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
9346 tcg_temp_free_i64(fp64
);
9347 gen_store_fpr32(fp32
, fd
);
9348 tcg_temp_free_i32(fp32
);
9353 check_cp1_registers(ctx
, fs
);
9355 TCGv_i32 fp32
= tcg_temp_new_i32();
9356 TCGv_i64 fp64
= tcg_temp_new_i64();
9358 gen_load_fpr64(ctx
, fp64
, fs
);
9359 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
9360 tcg_temp_free_i64(fp64
);
9361 gen_store_fpr32(fp32
, fd
);
9362 tcg_temp_free_i32(fp32
);
9367 check_cp1_registers(ctx
, fs
);
9369 TCGv_i32 fp32
= tcg_temp_new_i32();
9370 TCGv_i64 fp64
= tcg_temp_new_i64();
9372 gen_load_fpr64(ctx
, fp64
, fs
);
9373 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
9374 tcg_temp_free_i64(fp64
);
9375 gen_store_fpr32(fp32
, fd
);
9376 tcg_temp_free_i32(fp32
);
9381 check_cp1_registers(ctx
, fs
);
9383 TCGv_i32 fp32
= tcg_temp_new_i32();
9384 TCGv_i64 fp64
= tcg_temp_new_i64();
9386 gen_load_fpr64(ctx
, fp64
, fs
);
9387 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
9388 tcg_temp_free_i64(fp64
);
9389 gen_store_fpr32(fp32
, fd
);
9390 tcg_temp_free_i32(fp32
);
9395 check_insn(ctx
, ISA_MIPS32R6
);
9396 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9400 check_insn(ctx
, ISA_MIPS32R6
);
9401 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9405 check_insn(ctx
, ISA_MIPS32R6
);
9406 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9410 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9411 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9415 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9417 TCGLabel
*l1
= gen_new_label();
9421 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9423 fp0
= tcg_temp_new_i64();
9424 gen_load_fpr64(ctx
, fp0
, fs
);
9425 gen_store_fpr64(ctx
, fp0
, fd
);
9426 tcg_temp_free_i64(fp0
);
9432 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9434 TCGLabel
*l1
= gen_new_label();
9438 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9439 fp0
= tcg_temp_new_i64();
9440 gen_load_fpr64(ctx
, fp0
, fs
);
9441 gen_store_fpr64(ctx
, fp0
, fd
);
9442 tcg_temp_free_i64(fp0
);
9449 check_cp1_64bitmode(ctx
);
9451 TCGv_i64 fp0
= tcg_temp_new_i64();
9453 gen_load_fpr64(ctx
, fp0
, fs
);
9454 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
9455 gen_store_fpr64(ctx
, fp0
, fd
);
9456 tcg_temp_free_i64(fp0
);
9461 check_cp1_64bitmode(ctx
);
9463 TCGv_i64 fp0
= tcg_temp_new_i64();
9465 gen_load_fpr64(ctx
, fp0
, fs
);
9466 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
9467 gen_store_fpr64(ctx
, fp0
, fd
);
9468 tcg_temp_free_i64(fp0
);
9473 check_insn(ctx
, ISA_MIPS32R6
);
9475 TCGv_i64 fp0
= tcg_temp_new_i64();
9476 TCGv_i64 fp1
= tcg_temp_new_i64();
9477 TCGv_i64 fp2
= tcg_temp_new_i64();
9478 gen_load_fpr64(ctx
, fp0
, fs
);
9479 gen_load_fpr64(ctx
, fp1
, ft
);
9480 gen_load_fpr64(ctx
, fp2
, fd
);
9481 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9482 gen_store_fpr64(ctx
, fp2
, fd
);
9483 tcg_temp_free_i64(fp2
);
9484 tcg_temp_free_i64(fp1
);
9485 tcg_temp_free_i64(fp0
);
9490 check_insn(ctx
, ISA_MIPS32R6
);
9492 TCGv_i64 fp0
= tcg_temp_new_i64();
9493 TCGv_i64 fp1
= tcg_temp_new_i64();
9494 TCGv_i64 fp2
= tcg_temp_new_i64();
9495 gen_load_fpr64(ctx
, fp0
, fs
);
9496 gen_load_fpr64(ctx
, fp1
, ft
);
9497 gen_load_fpr64(ctx
, fp2
, fd
);
9498 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9499 gen_store_fpr64(ctx
, fp2
, fd
);
9500 tcg_temp_free_i64(fp2
);
9501 tcg_temp_free_i64(fp1
);
9502 tcg_temp_free_i64(fp0
);
9507 check_insn(ctx
, ISA_MIPS32R6
);
9509 TCGv_i64 fp0
= tcg_temp_new_i64();
9510 gen_load_fpr64(ctx
, fp0
, fs
);
9511 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
9512 gen_store_fpr64(ctx
, fp0
, fd
);
9513 tcg_temp_free_i64(fp0
);
9518 check_insn(ctx
, ISA_MIPS32R6
);
9520 TCGv_i64 fp0
= tcg_temp_new_i64();
9521 gen_load_fpr64(ctx
, fp0
, fs
);
9522 gen_helper_float_class_d(fp0
, fp0
);
9523 gen_store_fpr64(ctx
, fp0
, fd
);
9524 tcg_temp_free_i64(fp0
);
9528 case OPC_MIN_D
: /* OPC_RECIP2_D */
9529 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9531 TCGv_i64 fp0
= tcg_temp_new_i64();
9532 TCGv_i64 fp1
= tcg_temp_new_i64();
9533 gen_load_fpr64(ctx
, fp0
, fs
);
9534 gen_load_fpr64(ctx
, fp1
, ft
);
9535 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
9536 gen_store_fpr64(ctx
, fp1
, fd
);
9537 tcg_temp_free_i64(fp1
);
9538 tcg_temp_free_i64(fp0
);
9542 check_cp1_64bitmode(ctx
);
9544 TCGv_i64 fp0
= tcg_temp_new_i64();
9545 TCGv_i64 fp1
= tcg_temp_new_i64();
9547 gen_load_fpr64(ctx
, fp0
, fs
);
9548 gen_load_fpr64(ctx
, fp1
, ft
);
9549 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
9550 tcg_temp_free_i64(fp1
);
9551 gen_store_fpr64(ctx
, fp0
, fd
);
9552 tcg_temp_free_i64(fp0
);
9557 case OPC_MINA_D
: /* OPC_RECIP1_D */
9558 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9560 TCGv_i64 fp0
= tcg_temp_new_i64();
9561 TCGv_i64 fp1
= tcg_temp_new_i64();
9562 gen_load_fpr64(ctx
, fp0
, fs
);
9563 gen_load_fpr64(ctx
, fp1
, ft
);
9564 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
9565 gen_store_fpr64(ctx
, fp1
, fd
);
9566 tcg_temp_free_i64(fp1
);
9567 tcg_temp_free_i64(fp0
);
9571 check_cp1_64bitmode(ctx
);
9573 TCGv_i64 fp0
= tcg_temp_new_i64();
9575 gen_load_fpr64(ctx
, fp0
, fs
);
9576 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
9577 gen_store_fpr64(ctx
, fp0
, fd
);
9578 tcg_temp_free_i64(fp0
);
9583 case OPC_MAX_D
: /* OPC_RSQRT1_D */
9584 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9586 TCGv_i64 fp0
= tcg_temp_new_i64();
9587 TCGv_i64 fp1
= tcg_temp_new_i64();
9588 gen_load_fpr64(ctx
, fp0
, fs
);
9589 gen_load_fpr64(ctx
, fp1
, ft
);
9590 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
9591 gen_store_fpr64(ctx
, fp1
, fd
);
9592 tcg_temp_free_i64(fp1
);
9593 tcg_temp_free_i64(fp0
);
9597 check_cp1_64bitmode(ctx
);
9599 TCGv_i64 fp0
= tcg_temp_new_i64();
9601 gen_load_fpr64(ctx
, fp0
, fs
);
9602 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
9603 gen_store_fpr64(ctx
, fp0
, fd
);
9604 tcg_temp_free_i64(fp0
);
9609 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
9610 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9612 TCGv_i64 fp0
= tcg_temp_new_i64();
9613 TCGv_i64 fp1
= tcg_temp_new_i64();
9614 gen_load_fpr64(ctx
, fp0
, fs
);
9615 gen_load_fpr64(ctx
, fp1
, ft
);
9616 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
9617 gen_store_fpr64(ctx
, fp1
, fd
);
9618 tcg_temp_free_i64(fp1
);
9619 tcg_temp_free_i64(fp0
);
9623 check_cp1_64bitmode(ctx
);
9625 TCGv_i64 fp0
= tcg_temp_new_i64();
9626 TCGv_i64 fp1
= tcg_temp_new_i64();
9628 gen_load_fpr64(ctx
, fp0
, fs
);
9629 gen_load_fpr64(ctx
, fp1
, ft
);
9630 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
9631 tcg_temp_free_i64(fp1
);
9632 gen_store_fpr64(ctx
, fp0
, fd
);
9633 tcg_temp_free_i64(fp0
);
9647 case OPC_CMP_NGLE_D
:
9654 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9655 if (ctx
->opcode
& (1 << 6)) {
9656 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
9657 opn
= condnames_abs
[func
-48];
9659 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
9660 opn
= condnames
[func
-48];
9664 check_cp1_registers(ctx
, fs
);
9666 TCGv_i32 fp32
= tcg_temp_new_i32();
9667 TCGv_i64 fp64
= tcg_temp_new_i64();
9669 gen_load_fpr64(ctx
, fp64
, fs
);
9670 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
9671 tcg_temp_free_i64(fp64
);
9672 gen_store_fpr32(fp32
, fd
);
9673 tcg_temp_free_i32(fp32
);
9678 check_cp1_registers(ctx
, fs
);
9680 TCGv_i32 fp32
= tcg_temp_new_i32();
9681 TCGv_i64 fp64
= tcg_temp_new_i64();
9683 gen_load_fpr64(ctx
, fp64
, fs
);
9684 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
9685 tcg_temp_free_i64(fp64
);
9686 gen_store_fpr32(fp32
, fd
);
9687 tcg_temp_free_i32(fp32
);
9692 check_cp1_64bitmode(ctx
);
9694 TCGv_i64 fp0
= tcg_temp_new_i64();
9696 gen_load_fpr64(ctx
, fp0
, fs
);
9697 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
9698 gen_store_fpr64(ctx
, fp0
, fd
);
9699 tcg_temp_free_i64(fp0
);
9705 TCGv_i32 fp0
= tcg_temp_new_i32();
9707 gen_load_fpr32(fp0
, fs
);
9708 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
9709 gen_store_fpr32(fp0
, fd
);
9710 tcg_temp_free_i32(fp0
);
9715 check_cp1_registers(ctx
, fd
);
9717 TCGv_i32 fp32
= tcg_temp_new_i32();
9718 TCGv_i64 fp64
= tcg_temp_new_i64();
9720 gen_load_fpr32(fp32
, fs
);
9721 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
9722 tcg_temp_free_i32(fp32
);
9723 gen_store_fpr64(ctx
, fp64
, fd
);
9724 tcg_temp_free_i64(fp64
);
9729 check_cp1_64bitmode(ctx
);
9731 TCGv_i32 fp32
= tcg_temp_new_i32();
9732 TCGv_i64 fp64
= tcg_temp_new_i64();
9734 gen_load_fpr64(ctx
, fp64
, fs
);
9735 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
9736 tcg_temp_free_i64(fp64
);
9737 gen_store_fpr32(fp32
, fd
);
9738 tcg_temp_free_i32(fp32
);
9743 check_cp1_64bitmode(ctx
);
9745 TCGv_i64 fp0
= tcg_temp_new_i64();
9747 gen_load_fpr64(ctx
, fp0
, fs
);
9748 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
9749 gen_store_fpr64(ctx
, fp0
, fd
);
9750 tcg_temp_free_i64(fp0
);
9755 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9756 check_cp1_64bitmode(ctx
);
9758 TCGv_i64 fp0
= tcg_temp_new_i64();
9760 gen_load_fpr64(ctx
, fp0
, fs
);
9761 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
9762 gen_store_fpr64(ctx
, fp0
, fd
);
9763 tcg_temp_free_i64(fp0
);
9768 check_cp1_64bitmode(ctx
);
9770 TCGv_i64 fp0
= tcg_temp_new_i64();
9771 TCGv_i64 fp1
= tcg_temp_new_i64();
9773 gen_load_fpr64(ctx
, fp0
, fs
);
9774 gen_load_fpr64(ctx
, fp1
, ft
);
9775 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
9776 tcg_temp_free_i64(fp1
);
9777 gen_store_fpr64(ctx
, fp0
, fd
);
9778 tcg_temp_free_i64(fp0
);
9783 check_cp1_64bitmode(ctx
);
9785 TCGv_i64 fp0
= tcg_temp_new_i64();
9786 TCGv_i64 fp1
= tcg_temp_new_i64();
9788 gen_load_fpr64(ctx
, fp0
, fs
);
9789 gen_load_fpr64(ctx
, fp1
, ft
);
9790 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
9791 tcg_temp_free_i64(fp1
);
9792 gen_store_fpr64(ctx
, fp0
, fd
);
9793 tcg_temp_free_i64(fp0
);
9798 check_cp1_64bitmode(ctx
);
9800 TCGv_i64 fp0
= tcg_temp_new_i64();
9801 TCGv_i64 fp1
= tcg_temp_new_i64();
9803 gen_load_fpr64(ctx
, fp0
, fs
);
9804 gen_load_fpr64(ctx
, fp1
, ft
);
9805 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
9806 tcg_temp_free_i64(fp1
);
9807 gen_store_fpr64(ctx
, fp0
, fd
);
9808 tcg_temp_free_i64(fp0
);
9813 check_cp1_64bitmode(ctx
);
9815 TCGv_i64 fp0
= tcg_temp_new_i64();
9817 gen_load_fpr64(ctx
, fp0
, fs
);
9818 gen_helper_float_abs_ps(fp0
, fp0
);
9819 gen_store_fpr64(ctx
, fp0
, fd
);
9820 tcg_temp_free_i64(fp0
);
9825 check_cp1_64bitmode(ctx
);
9827 TCGv_i64 fp0
= tcg_temp_new_i64();
9829 gen_load_fpr64(ctx
, fp0
, fs
);
9830 gen_store_fpr64(ctx
, fp0
, fd
);
9831 tcg_temp_free_i64(fp0
);
9836 check_cp1_64bitmode(ctx
);
9838 TCGv_i64 fp0
= tcg_temp_new_i64();
9840 gen_load_fpr64(ctx
, fp0
, fs
);
9841 gen_helper_float_chs_ps(fp0
, fp0
);
9842 gen_store_fpr64(ctx
, fp0
, fd
);
9843 tcg_temp_free_i64(fp0
);
9848 check_cp1_64bitmode(ctx
);
9849 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9853 check_cp1_64bitmode(ctx
);
9855 TCGLabel
*l1
= gen_new_label();
9859 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9860 fp0
= tcg_temp_new_i64();
9861 gen_load_fpr64(ctx
, fp0
, fs
);
9862 gen_store_fpr64(ctx
, fp0
, fd
);
9863 tcg_temp_free_i64(fp0
);
9869 check_cp1_64bitmode(ctx
);
9871 TCGLabel
*l1
= gen_new_label();
9875 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9876 fp0
= tcg_temp_new_i64();
9877 gen_load_fpr64(ctx
, fp0
, fs
);
9878 gen_store_fpr64(ctx
, fp0
, fd
);
9879 tcg_temp_free_i64(fp0
);
9886 check_cp1_64bitmode(ctx
);
9888 TCGv_i64 fp0
= tcg_temp_new_i64();
9889 TCGv_i64 fp1
= tcg_temp_new_i64();
9891 gen_load_fpr64(ctx
, fp0
, ft
);
9892 gen_load_fpr64(ctx
, fp1
, fs
);
9893 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
9894 tcg_temp_free_i64(fp1
);
9895 gen_store_fpr64(ctx
, fp0
, fd
);
9896 tcg_temp_free_i64(fp0
);
9901 check_cp1_64bitmode(ctx
);
9903 TCGv_i64 fp0
= tcg_temp_new_i64();
9904 TCGv_i64 fp1
= tcg_temp_new_i64();
9906 gen_load_fpr64(ctx
, fp0
, ft
);
9907 gen_load_fpr64(ctx
, fp1
, fs
);
9908 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
9909 tcg_temp_free_i64(fp1
);
9910 gen_store_fpr64(ctx
, fp0
, fd
);
9911 tcg_temp_free_i64(fp0
);
9916 check_cp1_64bitmode(ctx
);
9918 TCGv_i64 fp0
= tcg_temp_new_i64();
9919 TCGv_i64 fp1
= tcg_temp_new_i64();
9921 gen_load_fpr64(ctx
, fp0
, fs
);
9922 gen_load_fpr64(ctx
, fp1
, ft
);
9923 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
9924 tcg_temp_free_i64(fp1
);
9925 gen_store_fpr64(ctx
, fp0
, fd
);
9926 tcg_temp_free_i64(fp0
);
9931 check_cp1_64bitmode(ctx
);
9933 TCGv_i64 fp0
= tcg_temp_new_i64();
9935 gen_load_fpr64(ctx
, fp0
, fs
);
9936 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
9937 gen_store_fpr64(ctx
, fp0
, fd
);
9938 tcg_temp_free_i64(fp0
);
9943 check_cp1_64bitmode(ctx
);
9945 TCGv_i64 fp0
= tcg_temp_new_i64();
9947 gen_load_fpr64(ctx
, fp0
, fs
);
9948 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
9949 gen_store_fpr64(ctx
, fp0
, fd
);
9950 tcg_temp_free_i64(fp0
);
9955 check_cp1_64bitmode(ctx
);
9957 TCGv_i64 fp0
= tcg_temp_new_i64();
9958 TCGv_i64 fp1
= tcg_temp_new_i64();
9960 gen_load_fpr64(ctx
, fp0
, fs
);
9961 gen_load_fpr64(ctx
, fp1
, ft
);
9962 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
9963 tcg_temp_free_i64(fp1
);
9964 gen_store_fpr64(ctx
, fp0
, fd
);
9965 tcg_temp_free_i64(fp0
);
9970 check_cp1_64bitmode(ctx
);
9972 TCGv_i32 fp0
= tcg_temp_new_i32();
9974 gen_load_fpr32h(ctx
, fp0
, fs
);
9975 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
9976 gen_store_fpr32(fp0
, fd
);
9977 tcg_temp_free_i32(fp0
);
9982 check_cp1_64bitmode(ctx
);
9984 TCGv_i64 fp0
= tcg_temp_new_i64();
9986 gen_load_fpr64(ctx
, fp0
, fs
);
9987 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
9988 gen_store_fpr64(ctx
, fp0
, fd
);
9989 tcg_temp_free_i64(fp0
);
9994 check_cp1_64bitmode(ctx
);
9996 TCGv_i32 fp0
= tcg_temp_new_i32();
9998 gen_load_fpr32(fp0
, fs
);
9999 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
10000 gen_store_fpr32(fp0
, fd
);
10001 tcg_temp_free_i32(fp0
);
10006 check_cp1_64bitmode(ctx
);
10008 TCGv_i32 fp0
= tcg_temp_new_i32();
10009 TCGv_i32 fp1
= tcg_temp_new_i32();
10011 gen_load_fpr32(fp0
, fs
);
10012 gen_load_fpr32(fp1
, ft
);
10013 gen_store_fpr32h(ctx
, fp0
, fd
);
10014 gen_store_fpr32(fp1
, fd
);
10015 tcg_temp_free_i32(fp0
);
10016 tcg_temp_free_i32(fp1
);
10021 check_cp1_64bitmode(ctx
);
10023 TCGv_i32 fp0
= tcg_temp_new_i32();
10024 TCGv_i32 fp1
= tcg_temp_new_i32();
10026 gen_load_fpr32(fp0
, fs
);
10027 gen_load_fpr32h(ctx
, fp1
, ft
);
10028 gen_store_fpr32(fp1
, fd
);
10029 gen_store_fpr32h(ctx
, fp0
, fd
);
10030 tcg_temp_free_i32(fp0
);
10031 tcg_temp_free_i32(fp1
);
10036 check_cp1_64bitmode(ctx
);
10038 TCGv_i32 fp0
= tcg_temp_new_i32();
10039 TCGv_i32 fp1
= tcg_temp_new_i32();
10041 gen_load_fpr32h(ctx
, fp0
, fs
);
10042 gen_load_fpr32(fp1
, ft
);
10043 gen_store_fpr32(fp1
, fd
);
10044 gen_store_fpr32h(ctx
, fp0
, fd
);
10045 tcg_temp_free_i32(fp0
);
10046 tcg_temp_free_i32(fp1
);
10051 check_cp1_64bitmode(ctx
);
10053 TCGv_i32 fp0
= tcg_temp_new_i32();
10054 TCGv_i32 fp1
= tcg_temp_new_i32();
10056 gen_load_fpr32h(ctx
, fp0
, fs
);
10057 gen_load_fpr32h(ctx
, fp1
, ft
);
10058 gen_store_fpr32(fp1
, fd
);
10059 gen_store_fpr32h(ctx
, fp0
, fd
);
10060 tcg_temp_free_i32(fp0
);
10061 tcg_temp_free_i32(fp1
);
10066 case OPC_CMP_UN_PS
:
10067 case OPC_CMP_EQ_PS
:
10068 case OPC_CMP_UEQ_PS
:
10069 case OPC_CMP_OLT_PS
:
10070 case OPC_CMP_ULT_PS
:
10071 case OPC_CMP_OLE_PS
:
10072 case OPC_CMP_ULE_PS
:
10073 case OPC_CMP_SF_PS
:
10074 case OPC_CMP_NGLE_PS
:
10075 case OPC_CMP_SEQ_PS
:
10076 case OPC_CMP_NGL_PS
:
10077 case OPC_CMP_LT_PS
:
10078 case OPC_CMP_NGE_PS
:
10079 case OPC_CMP_LE_PS
:
10080 case OPC_CMP_NGT_PS
:
10081 if (ctx
->opcode
& (1 << 6)) {
10082 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
10083 opn
= condnames_abs
[func
-48];
10085 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
10086 opn
= condnames
[func
-48];
10091 generate_exception (ctx
, EXCP_RI
);
10094 (void)opn
; /* avoid a compiler warning */
10097 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
10100 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
10103 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
10108 /* Coprocessor 3 (FPU) */
10109 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
10110 int fd
, int fs
, int base
, int index
)
10112 const char *opn
= "extended float load/store";
10114 TCGv t0
= tcg_temp_new();
10117 gen_load_gpr(t0
, index
);
10118 } else if (index
== 0) {
10119 gen_load_gpr(t0
, base
);
10121 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
10123 /* Don't do NOP if destination is zero: we must perform the actual
10129 TCGv_i32 fp0
= tcg_temp_new_i32();
10131 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
10132 tcg_gen_trunc_tl_i32(fp0
, t0
);
10133 gen_store_fpr32(fp0
, fd
);
10134 tcg_temp_free_i32(fp0
);
10140 check_cp1_registers(ctx
, fd
);
10142 TCGv_i64 fp0
= tcg_temp_new_i64();
10143 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10144 gen_store_fpr64(ctx
, fp0
, fd
);
10145 tcg_temp_free_i64(fp0
);
10150 check_cp1_64bitmode(ctx
);
10151 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10153 TCGv_i64 fp0
= tcg_temp_new_i64();
10155 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10156 gen_store_fpr64(ctx
, fp0
, fd
);
10157 tcg_temp_free_i64(fp0
);
10164 TCGv_i32 fp0
= tcg_temp_new_i32();
10165 gen_load_fpr32(fp0
, fs
);
10166 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
10167 tcg_temp_free_i32(fp0
);
10174 check_cp1_registers(ctx
, fs
);
10176 TCGv_i64 fp0
= tcg_temp_new_i64();
10177 gen_load_fpr64(ctx
, fp0
, fs
);
10178 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10179 tcg_temp_free_i64(fp0
);
10185 check_cp1_64bitmode(ctx
);
10186 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10188 TCGv_i64 fp0
= tcg_temp_new_i64();
10189 gen_load_fpr64(ctx
, fp0
, fs
);
10190 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10191 tcg_temp_free_i64(fp0
);
10198 (void)opn
; (void)store
; /* avoid compiler warnings */
10199 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
10200 regnames
[index
], regnames
[base
]);
10203 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
10204 int fd
, int fr
, int fs
, int ft
)
10206 const char *opn
= "flt3_arith";
10210 check_cp1_64bitmode(ctx
);
10212 TCGv t0
= tcg_temp_local_new();
10213 TCGv_i32 fp
= tcg_temp_new_i32();
10214 TCGv_i32 fph
= tcg_temp_new_i32();
10215 TCGLabel
*l1
= gen_new_label();
10216 TCGLabel
*l2
= gen_new_label();
10218 gen_load_gpr(t0
, fr
);
10219 tcg_gen_andi_tl(t0
, t0
, 0x7);
10221 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
10222 gen_load_fpr32(fp
, fs
);
10223 gen_load_fpr32h(ctx
, fph
, fs
);
10224 gen_store_fpr32(fp
, fd
);
10225 gen_store_fpr32h(ctx
, fph
, fd
);
10228 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
10230 #ifdef TARGET_WORDS_BIGENDIAN
10231 gen_load_fpr32(fp
, fs
);
10232 gen_load_fpr32h(ctx
, fph
, ft
);
10233 gen_store_fpr32h(ctx
, fp
, fd
);
10234 gen_store_fpr32(fph
, fd
);
10236 gen_load_fpr32h(ctx
, fph
, fs
);
10237 gen_load_fpr32(fp
, ft
);
10238 gen_store_fpr32(fph
, fd
);
10239 gen_store_fpr32h(ctx
, fp
, fd
);
10242 tcg_temp_free_i32(fp
);
10243 tcg_temp_free_i32(fph
);
10250 TCGv_i32 fp0
= tcg_temp_new_i32();
10251 TCGv_i32 fp1
= tcg_temp_new_i32();
10252 TCGv_i32 fp2
= tcg_temp_new_i32();
10254 gen_load_fpr32(fp0
, fs
);
10255 gen_load_fpr32(fp1
, ft
);
10256 gen_load_fpr32(fp2
, fr
);
10257 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10258 tcg_temp_free_i32(fp0
);
10259 tcg_temp_free_i32(fp1
);
10260 gen_store_fpr32(fp2
, fd
);
10261 tcg_temp_free_i32(fp2
);
10267 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10269 TCGv_i64 fp0
= tcg_temp_new_i64();
10270 TCGv_i64 fp1
= tcg_temp_new_i64();
10271 TCGv_i64 fp2
= tcg_temp_new_i64();
10273 gen_load_fpr64(ctx
, fp0
, fs
);
10274 gen_load_fpr64(ctx
, fp1
, ft
);
10275 gen_load_fpr64(ctx
, fp2
, fr
);
10276 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10277 tcg_temp_free_i64(fp0
);
10278 tcg_temp_free_i64(fp1
);
10279 gen_store_fpr64(ctx
, fp2
, fd
);
10280 tcg_temp_free_i64(fp2
);
10285 check_cp1_64bitmode(ctx
);
10287 TCGv_i64 fp0
= tcg_temp_new_i64();
10288 TCGv_i64 fp1
= tcg_temp_new_i64();
10289 TCGv_i64 fp2
= tcg_temp_new_i64();
10291 gen_load_fpr64(ctx
, fp0
, fs
);
10292 gen_load_fpr64(ctx
, fp1
, ft
);
10293 gen_load_fpr64(ctx
, fp2
, fr
);
10294 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10295 tcg_temp_free_i64(fp0
);
10296 tcg_temp_free_i64(fp1
);
10297 gen_store_fpr64(ctx
, fp2
, fd
);
10298 tcg_temp_free_i64(fp2
);
10305 TCGv_i32 fp0
= tcg_temp_new_i32();
10306 TCGv_i32 fp1
= tcg_temp_new_i32();
10307 TCGv_i32 fp2
= tcg_temp_new_i32();
10309 gen_load_fpr32(fp0
, fs
);
10310 gen_load_fpr32(fp1
, ft
);
10311 gen_load_fpr32(fp2
, fr
);
10312 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10313 tcg_temp_free_i32(fp0
);
10314 tcg_temp_free_i32(fp1
);
10315 gen_store_fpr32(fp2
, fd
);
10316 tcg_temp_free_i32(fp2
);
10322 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10324 TCGv_i64 fp0
= tcg_temp_new_i64();
10325 TCGv_i64 fp1
= tcg_temp_new_i64();
10326 TCGv_i64 fp2
= tcg_temp_new_i64();
10328 gen_load_fpr64(ctx
, fp0
, fs
);
10329 gen_load_fpr64(ctx
, fp1
, ft
);
10330 gen_load_fpr64(ctx
, fp2
, fr
);
10331 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10332 tcg_temp_free_i64(fp0
);
10333 tcg_temp_free_i64(fp1
);
10334 gen_store_fpr64(ctx
, fp2
, fd
);
10335 tcg_temp_free_i64(fp2
);
10340 check_cp1_64bitmode(ctx
);
10342 TCGv_i64 fp0
= tcg_temp_new_i64();
10343 TCGv_i64 fp1
= tcg_temp_new_i64();
10344 TCGv_i64 fp2
= tcg_temp_new_i64();
10346 gen_load_fpr64(ctx
, fp0
, fs
);
10347 gen_load_fpr64(ctx
, fp1
, ft
);
10348 gen_load_fpr64(ctx
, fp2
, fr
);
10349 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10350 tcg_temp_free_i64(fp0
);
10351 tcg_temp_free_i64(fp1
);
10352 gen_store_fpr64(ctx
, fp2
, fd
);
10353 tcg_temp_free_i64(fp2
);
10360 TCGv_i32 fp0
= tcg_temp_new_i32();
10361 TCGv_i32 fp1
= tcg_temp_new_i32();
10362 TCGv_i32 fp2
= tcg_temp_new_i32();
10364 gen_load_fpr32(fp0
, fs
);
10365 gen_load_fpr32(fp1
, ft
);
10366 gen_load_fpr32(fp2
, fr
);
10367 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10368 tcg_temp_free_i32(fp0
);
10369 tcg_temp_free_i32(fp1
);
10370 gen_store_fpr32(fp2
, fd
);
10371 tcg_temp_free_i32(fp2
);
10377 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10379 TCGv_i64 fp0
= tcg_temp_new_i64();
10380 TCGv_i64 fp1
= tcg_temp_new_i64();
10381 TCGv_i64 fp2
= tcg_temp_new_i64();
10383 gen_load_fpr64(ctx
, fp0
, fs
);
10384 gen_load_fpr64(ctx
, fp1
, ft
);
10385 gen_load_fpr64(ctx
, fp2
, fr
);
10386 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10387 tcg_temp_free_i64(fp0
);
10388 tcg_temp_free_i64(fp1
);
10389 gen_store_fpr64(ctx
, fp2
, fd
);
10390 tcg_temp_free_i64(fp2
);
10395 check_cp1_64bitmode(ctx
);
10397 TCGv_i64 fp0
= tcg_temp_new_i64();
10398 TCGv_i64 fp1
= tcg_temp_new_i64();
10399 TCGv_i64 fp2
= tcg_temp_new_i64();
10401 gen_load_fpr64(ctx
, fp0
, fs
);
10402 gen_load_fpr64(ctx
, fp1
, ft
);
10403 gen_load_fpr64(ctx
, fp2
, fr
);
10404 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10405 tcg_temp_free_i64(fp0
);
10406 tcg_temp_free_i64(fp1
);
10407 gen_store_fpr64(ctx
, fp2
, fd
);
10408 tcg_temp_free_i64(fp2
);
10415 TCGv_i32 fp0
= tcg_temp_new_i32();
10416 TCGv_i32 fp1
= tcg_temp_new_i32();
10417 TCGv_i32 fp2
= tcg_temp_new_i32();
10419 gen_load_fpr32(fp0
, fs
);
10420 gen_load_fpr32(fp1
, ft
);
10421 gen_load_fpr32(fp2
, fr
);
10422 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10423 tcg_temp_free_i32(fp0
);
10424 tcg_temp_free_i32(fp1
);
10425 gen_store_fpr32(fp2
, fd
);
10426 tcg_temp_free_i32(fp2
);
10432 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10434 TCGv_i64 fp0
= tcg_temp_new_i64();
10435 TCGv_i64 fp1
= tcg_temp_new_i64();
10436 TCGv_i64 fp2
= tcg_temp_new_i64();
10438 gen_load_fpr64(ctx
, fp0
, fs
);
10439 gen_load_fpr64(ctx
, fp1
, ft
);
10440 gen_load_fpr64(ctx
, fp2
, fr
);
10441 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10442 tcg_temp_free_i64(fp0
);
10443 tcg_temp_free_i64(fp1
);
10444 gen_store_fpr64(ctx
, fp2
, fd
);
10445 tcg_temp_free_i64(fp2
);
10450 check_cp1_64bitmode(ctx
);
10452 TCGv_i64 fp0
= tcg_temp_new_i64();
10453 TCGv_i64 fp1
= tcg_temp_new_i64();
10454 TCGv_i64 fp2
= tcg_temp_new_i64();
10456 gen_load_fpr64(ctx
, fp0
, fs
);
10457 gen_load_fpr64(ctx
, fp1
, ft
);
10458 gen_load_fpr64(ctx
, fp2
, fr
);
10459 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10460 tcg_temp_free_i64(fp0
);
10461 tcg_temp_free_i64(fp1
);
10462 gen_store_fpr64(ctx
, fp2
, fd
);
10463 tcg_temp_free_i64(fp2
);
10469 generate_exception (ctx
, EXCP_RI
);
10472 (void)opn
; /* avoid a compiler warning */
10473 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
10474 fregnames
[fs
], fregnames
[ft
]);
10477 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
10481 #if !defined(CONFIG_USER_ONLY)
10482 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10483 Therefore only check the ISA in system mode. */
10484 check_insn(ctx
, ISA_MIPS32R2
);
10486 t0
= tcg_temp_new();
10490 save_cpu_state(ctx
, 1);
10491 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
10492 gen_store_gpr(t0
, rt
);
10495 save_cpu_state(ctx
, 1);
10496 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
10497 gen_store_gpr(t0
, rt
);
10500 save_cpu_state(ctx
, 1);
10501 gen_helper_rdhwr_cc(t0
, cpu_env
);
10502 gen_store_gpr(t0
, rt
);
10505 save_cpu_state(ctx
, 1);
10506 gen_helper_rdhwr_ccres(t0
, cpu_env
);
10507 gen_store_gpr(t0
, rt
);
10510 #if defined(CONFIG_USER_ONLY)
10511 tcg_gen_ld_tl(t0
, cpu_env
,
10512 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10513 gen_store_gpr(t0
, rt
);
10516 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
10517 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
10518 tcg_gen_ld_tl(t0
, cpu_env
,
10519 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10520 gen_store_gpr(t0
, rt
);
10522 generate_exception(ctx
, EXCP_RI
);
10526 default: /* Invalid */
10527 MIPS_INVAL("rdhwr");
10528 generate_exception(ctx
, EXCP_RI
);
10534 static inline void clear_branch_hflags(DisasContext
*ctx
)
10536 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
10537 if (ctx
->bstate
== BS_NONE
) {
10538 save_cpu_state(ctx
, 0);
10540 /* it is not safe to save ctx->hflags as hflags may be changed
10541 in execution time by the instruction in delay / forbidden slot. */
10542 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
10546 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
10548 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10549 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
10550 /* Branches completion */
10551 clear_branch_hflags(ctx
);
10552 ctx
->bstate
= BS_BRANCH
;
10553 /* FIXME: Need to clear can_do_io. */
10554 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
10555 case MIPS_HFLAG_FBNSLOT
:
10556 MIPS_DEBUG("forbidden slot");
10557 gen_goto_tb(ctx
, 0, ctx
->pc
+ insn_bytes
);
10560 /* unconditional branch */
10561 MIPS_DEBUG("unconditional branch");
10562 if (proc_hflags
& MIPS_HFLAG_BX
) {
10563 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
10565 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10567 case MIPS_HFLAG_BL
:
10568 /* blikely taken case */
10569 MIPS_DEBUG("blikely branch taken");
10570 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10572 case MIPS_HFLAG_BC
:
10573 /* Conditional branch */
10574 MIPS_DEBUG("conditional branch");
10576 TCGLabel
*l1
= gen_new_label();
10578 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
10579 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
10581 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10584 case MIPS_HFLAG_BR
:
10585 /* unconditional branch to register */
10586 MIPS_DEBUG("branch to register");
10587 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
10588 TCGv t0
= tcg_temp_new();
10589 TCGv_i32 t1
= tcg_temp_new_i32();
10591 tcg_gen_andi_tl(t0
, btarget
, 0x1);
10592 tcg_gen_trunc_tl_i32(t1
, t0
);
10594 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
10595 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
10596 tcg_gen_or_i32(hflags
, hflags
, t1
);
10597 tcg_temp_free_i32(t1
);
10599 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
10601 tcg_gen_mov_tl(cpu_PC
, btarget
);
10603 if (ctx
->singlestep_enabled
) {
10604 save_cpu_state(ctx
, 0);
10605 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
10607 tcg_gen_exit_tb(0);
10610 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
10616 /* ISA extensions (ASEs) */
10617 /* MIPS16 extension to MIPS32 */
10619 /* MIPS16 major opcodes */
10621 M16_OPC_ADDIUSP
= 0x00,
10622 M16_OPC_ADDIUPC
= 0x01,
10624 M16_OPC_JAL
= 0x03,
10625 M16_OPC_BEQZ
= 0x04,
10626 M16_OPC_BNEQZ
= 0x05,
10627 M16_OPC_SHIFT
= 0x06,
10629 M16_OPC_RRIA
= 0x08,
10630 M16_OPC_ADDIU8
= 0x09,
10631 M16_OPC_SLTI
= 0x0a,
10632 M16_OPC_SLTIU
= 0x0b,
10635 M16_OPC_CMPI
= 0x0e,
10639 M16_OPC_LWSP
= 0x12,
10641 M16_OPC_LBU
= 0x14,
10642 M16_OPC_LHU
= 0x15,
10643 M16_OPC_LWPC
= 0x16,
10644 M16_OPC_LWU
= 0x17,
10647 M16_OPC_SWSP
= 0x1a,
10649 M16_OPC_RRR
= 0x1c,
10651 M16_OPC_EXTEND
= 0x1e,
10655 /* I8 funct field */
10674 /* RR funct field */
10708 /* I64 funct field */
10716 I64_DADDIUPC
= 0x6,
10720 /* RR ry field for CNVT */
10722 RR_RY_CNVT_ZEB
= 0x0,
10723 RR_RY_CNVT_ZEH
= 0x1,
10724 RR_RY_CNVT_ZEW
= 0x2,
10725 RR_RY_CNVT_SEB
= 0x4,
10726 RR_RY_CNVT_SEH
= 0x5,
10727 RR_RY_CNVT_SEW
= 0x6,
10730 static int xlat (int r
)
10732 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10737 static void gen_mips16_save (DisasContext
*ctx
,
10738 int xsregs
, int aregs
,
10739 int do_ra
, int do_s0
, int do_s1
,
10742 TCGv t0
= tcg_temp_new();
10743 TCGv t1
= tcg_temp_new();
10744 TCGv t2
= tcg_temp_new();
10774 generate_exception(ctx
, EXCP_RI
);
10780 gen_base_offset_addr(ctx
, t0
, 29, 12);
10781 gen_load_gpr(t1
, 7);
10782 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10785 gen_base_offset_addr(ctx
, t0
, 29, 8);
10786 gen_load_gpr(t1
, 6);
10787 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10790 gen_base_offset_addr(ctx
, t0
, 29, 4);
10791 gen_load_gpr(t1
, 5);
10792 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10795 gen_base_offset_addr(ctx
, t0
, 29, 0);
10796 gen_load_gpr(t1
, 4);
10797 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10800 gen_load_gpr(t0
, 29);
10802 #define DECR_AND_STORE(reg) do { \
10803 tcg_gen_movi_tl(t2, -4); \
10804 gen_op_addr_add(ctx, t0, t0, t2); \
10805 gen_load_gpr(t1, reg); \
10806 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
10810 DECR_AND_STORE(31);
10815 DECR_AND_STORE(30);
10818 DECR_AND_STORE(23);
10821 DECR_AND_STORE(22);
10824 DECR_AND_STORE(21);
10827 DECR_AND_STORE(20);
10830 DECR_AND_STORE(19);
10833 DECR_AND_STORE(18);
10837 DECR_AND_STORE(17);
10840 DECR_AND_STORE(16);
10870 generate_exception(ctx
, EXCP_RI
);
10886 #undef DECR_AND_STORE
10888 tcg_gen_movi_tl(t2
, -framesize
);
10889 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
10895 static void gen_mips16_restore (DisasContext
*ctx
,
10896 int xsregs
, int aregs
,
10897 int do_ra
, int do_s0
, int do_s1
,
10901 TCGv t0
= tcg_temp_new();
10902 TCGv t1
= tcg_temp_new();
10903 TCGv t2
= tcg_temp_new();
10905 tcg_gen_movi_tl(t2
, framesize
);
10906 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
10908 #define DECR_AND_LOAD(reg) do { \
10909 tcg_gen_movi_tl(t2, -4); \
10910 gen_op_addr_add(ctx, t0, t0, t2); \
10911 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10912 gen_store_gpr(t1, reg); \
10976 generate_exception(ctx
, EXCP_RI
);
10992 #undef DECR_AND_LOAD
10994 tcg_gen_movi_tl(t2
, framesize
);
10995 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11001 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
11002 int is_64_bit
, int extended
)
11006 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11007 generate_exception(ctx
, EXCP_RI
);
11011 t0
= tcg_temp_new();
11013 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
11014 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
11016 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11022 #if defined(TARGET_MIPS64)
11023 static void decode_i64_mips16 (DisasContext
*ctx
,
11024 int ry
, int funct
, int16_t offset
,
11029 check_insn(ctx
, ISA_MIPS3
);
11030 check_mips_64(ctx
);
11031 offset
= extended
? offset
: offset
<< 3;
11032 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
11035 check_insn(ctx
, ISA_MIPS3
);
11036 check_mips_64(ctx
);
11037 offset
= extended
? offset
: offset
<< 3;
11038 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
11041 check_insn(ctx
, ISA_MIPS3
);
11042 check_mips_64(ctx
);
11043 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
11044 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
11047 check_insn(ctx
, ISA_MIPS3
);
11048 check_mips_64(ctx
);
11049 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
11050 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
11053 check_insn(ctx
, ISA_MIPS3
);
11054 check_mips_64(ctx
);
11055 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11056 generate_exception(ctx
, EXCP_RI
);
11058 offset
= extended
? offset
: offset
<< 3;
11059 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
11063 check_insn(ctx
, ISA_MIPS3
);
11064 check_mips_64(ctx
);
11065 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
11066 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
11069 check_insn(ctx
, ISA_MIPS3
);
11070 check_mips_64(ctx
);
11071 offset
= extended
? offset
: offset
<< 2;
11072 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
11075 check_insn(ctx
, ISA_MIPS3
);
11076 check_mips_64(ctx
);
11077 offset
= extended
? offset
: offset
<< 2;
11078 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
11084 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11086 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11087 int op
, rx
, ry
, funct
, sa
;
11088 int16_t imm
, offset
;
11090 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
11091 op
= (ctx
->opcode
>> 11) & 0x1f;
11092 sa
= (ctx
->opcode
>> 22) & 0x1f;
11093 funct
= (ctx
->opcode
>> 8) & 0x7;
11094 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11095 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11096 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
11097 | ((ctx
->opcode
>> 21) & 0x3f) << 5
11098 | (ctx
->opcode
& 0x1f));
11100 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11103 case M16_OPC_ADDIUSP
:
11104 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11106 case M16_OPC_ADDIUPC
:
11107 gen_addiupc(ctx
, rx
, imm
, 0, 1);
11110 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
11111 /* No delay slot, so just process as a normal instruction */
11114 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
11115 /* No delay slot, so just process as a normal instruction */
11117 case M16_OPC_BNEQZ
:
11118 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
11119 /* No delay slot, so just process as a normal instruction */
11121 case M16_OPC_SHIFT
:
11122 switch (ctx
->opcode
& 0x3) {
11124 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11127 #if defined(TARGET_MIPS64)
11128 check_mips_64(ctx
);
11129 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11131 generate_exception(ctx
, EXCP_RI
);
11135 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11138 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11142 #if defined(TARGET_MIPS64)
11144 check_insn(ctx
, ISA_MIPS3
);
11145 check_mips_64(ctx
);
11146 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
11150 imm
= ctx
->opcode
& 0xf;
11151 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
11152 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
11153 imm
= (int16_t) (imm
<< 1) >> 1;
11154 if ((ctx
->opcode
>> 4) & 0x1) {
11155 #if defined(TARGET_MIPS64)
11156 check_mips_64(ctx
);
11157 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11159 generate_exception(ctx
, EXCP_RI
);
11162 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11165 case M16_OPC_ADDIU8
:
11166 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11169 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11171 case M16_OPC_SLTIU
:
11172 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11177 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
11180 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
11183 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
11186 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
11189 check_insn(ctx
, ISA_MIPS32
);
11191 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
11192 int aregs
= (ctx
->opcode
>> 16) & 0xf;
11193 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
11194 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
11195 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
11196 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
11197 | (ctx
->opcode
& 0xf)) << 3;
11199 if (ctx
->opcode
& (1 << 7)) {
11200 gen_mips16_save(ctx
, xsregs
, aregs
,
11201 do_ra
, do_s0
, do_s1
,
11204 gen_mips16_restore(ctx
, xsregs
, aregs
,
11205 do_ra
, do_s0
, do_s1
,
11211 generate_exception(ctx
, EXCP_RI
);
11216 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
11219 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
11221 #if defined(TARGET_MIPS64)
11223 check_insn(ctx
, ISA_MIPS3
);
11224 check_mips_64(ctx
);
11225 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
11229 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11232 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
11235 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
11238 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
11241 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11244 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
11247 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
11249 #if defined(TARGET_MIPS64)
11251 check_insn(ctx
, ISA_MIPS3
);
11252 check_mips_64(ctx
);
11253 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
11257 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11260 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
11263 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
11266 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
11268 #if defined(TARGET_MIPS64)
11270 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
11274 generate_exception(ctx
, EXCP_RI
);
11281 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11285 int op
, cnvt_op
, op1
, offset
;
11289 op
= (ctx
->opcode
>> 11) & 0x1f;
11290 sa
= (ctx
->opcode
>> 2) & 0x7;
11291 sa
= sa
== 0 ? 8 : sa
;
11292 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11293 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
11294 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11295 op1
= offset
= ctx
->opcode
& 0x1f;
11300 case M16_OPC_ADDIUSP
:
11302 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
11304 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11307 case M16_OPC_ADDIUPC
:
11308 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
11311 offset
= (ctx
->opcode
& 0x7ff) << 1;
11312 offset
= (int16_t)(offset
<< 4) >> 4;
11313 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
11314 /* No delay slot, so just process as a normal instruction */
11317 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11318 offset
= (((ctx
->opcode
& 0x1f) << 21)
11319 | ((ctx
->opcode
>> 5) & 0x1f) << 16
11321 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
11322 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
11326 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
11327 ((int8_t)ctx
->opcode
) << 1, 0);
11328 /* No delay slot, so just process as a normal instruction */
11330 case M16_OPC_BNEQZ
:
11331 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
11332 ((int8_t)ctx
->opcode
) << 1, 0);
11333 /* No delay slot, so just process as a normal instruction */
11335 case M16_OPC_SHIFT
:
11336 switch (ctx
->opcode
& 0x3) {
11338 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11341 #if defined(TARGET_MIPS64)
11342 check_insn(ctx
, ISA_MIPS3
);
11343 check_mips_64(ctx
);
11344 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11346 generate_exception(ctx
, EXCP_RI
);
11350 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11353 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11357 #if defined(TARGET_MIPS64)
11359 check_insn(ctx
, ISA_MIPS3
);
11360 check_mips_64(ctx
);
11361 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
11366 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
11368 if ((ctx
->opcode
>> 4) & 1) {
11369 #if defined(TARGET_MIPS64)
11370 check_insn(ctx
, ISA_MIPS3
);
11371 check_mips_64(ctx
);
11372 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11374 generate_exception(ctx
, EXCP_RI
);
11377 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11381 case M16_OPC_ADDIU8
:
11383 int16_t imm
= (int8_t) ctx
->opcode
;
11385 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11390 int16_t imm
= (uint8_t) ctx
->opcode
;
11391 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11394 case M16_OPC_SLTIU
:
11396 int16_t imm
= (uint8_t) ctx
->opcode
;
11397 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11404 funct
= (ctx
->opcode
>> 8) & 0x7;
11407 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
11408 ((int8_t)ctx
->opcode
) << 1, 0);
11411 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
11412 ((int8_t)ctx
->opcode
) << 1, 0);
11415 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
11418 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
11419 ((int8_t)ctx
->opcode
) << 3);
11422 check_insn(ctx
, ISA_MIPS32
);
11424 int do_ra
= ctx
->opcode
& (1 << 6);
11425 int do_s0
= ctx
->opcode
& (1 << 5);
11426 int do_s1
= ctx
->opcode
& (1 << 4);
11427 int framesize
= ctx
->opcode
& 0xf;
11429 if (framesize
== 0) {
11432 framesize
= framesize
<< 3;
11435 if (ctx
->opcode
& (1 << 7)) {
11436 gen_mips16_save(ctx
, 0, 0,
11437 do_ra
, do_s0
, do_s1
, framesize
);
11439 gen_mips16_restore(ctx
, 0, 0,
11440 do_ra
, do_s0
, do_s1
, framesize
);
11446 int rz
= xlat(ctx
->opcode
& 0x7);
11448 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
11449 ((ctx
->opcode
>> 5) & 0x7);
11450 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
11454 reg32
= ctx
->opcode
& 0x1f;
11455 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
11458 generate_exception(ctx
, EXCP_RI
);
11465 int16_t imm
= (uint8_t) ctx
->opcode
;
11467 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
11472 int16_t imm
= (uint8_t) ctx
->opcode
;
11473 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
11476 #if defined(TARGET_MIPS64)
11478 check_insn(ctx
, ISA_MIPS3
);
11479 check_mips_64(ctx
);
11480 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
11484 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11487 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
11490 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11493 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
11496 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11499 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
11502 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
11504 #if defined (TARGET_MIPS64)
11506 check_insn(ctx
, ISA_MIPS3
);
11507 check_mips_64(ctx
);
11508 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
11512 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11515 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
11518 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11521 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
11525 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
11528 switch (ctx
->opcode
& 0x3) {
11530 mips32_op
= OPC_ADDU
;
11533 mips32_op
= OPC_SUBU
;
11535 #if defined(TARGET_MIPS64)
11537 mips32_op
= OPC_DADDU
;
11538 check_insn(ctx
, ISA_MIPS3
);
11539 check_mips_64(ctx
);
11542 mips32_op
= OPC_DSUBU
;
11543 check_insn(ctx
, ISA_MIPS3
);
11544 check_mips_64(ctx
);
11548 generate_exception(ctx
, EXCP_RI
);
11552 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
11561 int nd
= (ctx
->opcode
>> 7) & 0x1;
11562 int link
= (ctx
->opcode
>> 6) & 0x1;
11563 int ra
= (ctx
->opcode
>> 5) & 0x1;
11566 check_insn(ctx
, ISA_MIPS32
);
11575 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
11580 /* XXX: not clear which exception should be raised
11581 * when in debug mode...
11583 check_insn(ctx
, ISA_MIPS32
);
11584 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11585 generate_exception(ctx
, EXCP_DBp
);
11587 generate_exception(ctx
, EXCP_DBp
);
11591 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
11594 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
11597 generate_exception(ctx
, EXCP_BREAK
);
11600 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
11603 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
11606 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
11608 #if defined (TARGET_MIPS64)
11610 check_insn(ctx
, ISA_MIPS3
);
11611 check_mips_64(ctx
);
11612 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
11616 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
11619 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
11622 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
11625 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
11628 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
11631 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
11634 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
11637 check_insn(ctx
, ISA_MIPS32
);
11639 case RR_RY_CNVT_ZEB
:
11640 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11642 case RR_RY_CNVT_ZEH
:
11643 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11645 case RR_RY_CNVT_SEB
:
11646 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11648 case RR_RY_CNVT_SEH
:
11649 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11651 #if defined (TARGET_MIPS64)
11652 case RR_RY_CNVT_ZEW
:
11653 check_insn(ctx
, ISA_MIPS64
);
11654 check_mips_64(ctx
);
11655 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11657 case RR_RY_CNVT_SEW
:
11658 check_insn(ctx
, ISA_MIPS64
);
11659 check_mips_64(ctx
);
11660 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11664 generate_exception(ctx
, EXCP_RI
);
11669 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
11671 #if defined (TARGET_MIPS64)
11673 check_insn(ctx
, ISA_MIPS3
);
11674 check_mips_64(ctx
);
11675 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
11678 check_insn(ctx
, ISA_MIPS3
);
11679 check_mips_64(ctx
);
11680 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
11683 check_insn(ctx
, ISA_MIPS3
);
11684 check_mips_64(ctx
);
11685 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
11688 check_insn(ctx
, ISA_MIPS3
);
11689 check_mips_64(ctx
);
11690 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
11694 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
11697 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
11700 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
11703 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
11705 #if defined (TARGET_MIPS64)
11707 check_insn(ctx
, ISA_MIPS3
);
11708 check_mips_64(ctx
);
11709 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
11712 check_insn(ctx
, ISA_MIPS3
);
11713 check_mips_64(ctx
);
11714 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
11717 check_insn(ctx
, ISA_MIPS3
);
11718 check_mips_64(ctx
);
11719 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
11722 check_insn(ctx
, ISA_MIPS3
);
11723 check_mips_64(ctx
);
11724 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
11728 generate_exception(ctx
, EXCP_RI
);
11732 case M16_OPC_EXTEND
:
11733 decode_extended_mips16_opc(env
, ctx
);
11736 #if defined(TARGET_MIPS64)
11738 funct
= (ctx
->opcode
>> 8) & 0x7;
11739 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
11743 generate_exception(ctx
, EXCP_RI
);
11750 /* microMIPS extension to MIPS32/MIPS64 */
11753 * microMIPS32/microMIPS64 major opcodes
11755 * 1. MIPS Architecture for Programmers Volume II-B:
11756 * The microMIPS32 Instruction Set (Revision 3.05)
11758 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11760 * 2. MIPS Architecture For Programmers Volume II-A:
11761 * The MIPS64 Instruction Set (Revision 3.51)
11789 POOL32S
= 0x16, /* MIPS64 */
11790 DADDIU32
= 0x17, /* MIPS64 */
11792 /* 0x1f is reserved */
11801 /* 0x20 is reserved */
11811 /* 0x28 and 0x29 are reserved */
11821 /* 0x30 and 0x31 are reserved */
11828 SD32
= 0x36, /* MIPS64 */
11829 LD32
= 0x37, /* MIPS64 */
11831 /* 0x38 and 0x39 are reserved */
11842 /* POOL32A encoding of minor opcode field */
11845 /* These opcodes are distinguished only by bits 9..6; those bits are
11846 * what are recorded below. */
11872 /* The following can be distinguished by their lower 6 bits. */
11878 /* POOL32AXF encoding of minor opcode field extension */
11881 * 1. MIPS Architecture for Programmers Volume II-B:
11882 * The microMIPS32 Instruction Set (Revision 3.05)
11884 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11886 * 2. MIPS Architecture for Programmers VolumeIV-e:
11887 * The MIPS DSP Application-Specific Extension
11888 * to the microMIPS32 Architecture (Revision 2.34)
11890 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11905 /* begin of microMIPS32 DSP */
11907 /* bits 13..12 for 0x01 */
11913 /* bits 13..12 for 0x2a */
11919 /* bits 13..12 for 0x32 */
11923 /* end of microMIPS32 DSP */
11925 /* bits 15..12 for 0x2c */
11941 /* bits 15..12 for 0x34 */
11949 /* bits 15..12 for 0x3c */
11951 JR
= 0x0, /* alias */
11956 /* bits 15..12 for 0x05 */
11960 /* bits 15..12 for 0x0d */
11970 /* bits 15..12 for 0x15 */
11976 /* bits 15..12 for 0x1d */
11980 /* bits 15..12 for 0x2d */
11985 /* bits 15..12 for 0x35 */
11992 /* POOL32B encoding of minor opcode field (bits 15..12) */
12008 /* POOL32C encoding of minor opcode field (bits 15..12) */
12016 /* 0xa is reserved */
12023 /* 0x6 is reserved */
12029 /* POOL32F encoding of minor opcode field (bits 5..0) */
12032 /* These are the bit 7..6 values */
12043 /* These are the bit 8..6 values */
12087 CABS_COND_FMT
= 0x1c, /* MIPS3D */
12091 /* POOL32Fxf encoding of minor opcode extension field */
12129 /* POOL32I encoding of minor opcode field (bits 25..21) */
12154 /* These overlap and are distinguished by bit16 of the instruction */
12163 /* POOL16A encoding of minor opcode field */
12170 /* POOL16B encoding of minor opcode field */
12177 /* POOL16C encoding of minor opcode field */
12197 /* POOL16D encoding of minor opcode field */
12204 /* POOL16E encoding of minor opcode field */
12211 static int mmreg (int r
)
12213 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12218 /* Used for 16-bit store instructions. */
12219 static int mmreg2 (int r
)
12221 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12226 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12227 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12228 #define uMIPS_RS2(op) uMIPS_RS(op)
12229 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12230 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12231 #define uMIPS_RS5(op) (op & 0x1f)
12233 /* Signed immediate */
12234 #define SIMM(op, start, width) \
12235 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12238 /* Zero-extended immediate */
12239 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12241 static void gen_addiur1sp(DisasContext
*ctx
)
12243 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12245 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
12248 static void gen_addiur2(DisasContext
*ctx
)
12250 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12251 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12252 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12254 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
12257 static void gen_addiusp(DisasContext
*ctx
)
12259 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
12262 if (encoded
<= 1) {
12263 decoded
= 256 + encoded
;
12264 } else if (encoded
<= 255) {
12266 } else if (encoded
<= 509) {
12267 decoded
= encoded
- 512;
12269 decoded
= encoded
- 768;
12272 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
12275 static void gen_addius5(DisasContext
*ctx
)
12277 int imm
= SIMM(ctx
->opcode
, 1, 4);
12278 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12280 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
12283 static void gen_andi16(DisasContext
*ctx
)
12285 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12286 31, 32, 63, 64, 255, 32768, 65535 };
12287 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12288 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12289 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
12291 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
12294 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
12295 int base
, int16_t offset
)
12297 const char *opn
= "ldst_multiple";
12301 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12302 generate_exception(ctx
, EXCP_RI
);
12306 t0
= tcg_temp_new();
12308 gen_base_offset_addr(ctx
, t0
, base
, offset
);
12310 t1
= tcg_const_tl(reglist
);
12311 t2
= tcg_const_i32(ctx
->mem_idx
);
12313 save_cpu_state(ctx
, 1);
12316 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
12320 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
12323 #ifdef TARGET_MIPS64
12325 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
12329 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
12335 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
12338 tcg_temp_free_i32(t2
);
12342 static void gen_pool16c_insn(DisasContext
*ctx
)
12344 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
12345 int rs
= mmreg(ctx
->opcode
& 0x7);
12347 switch (((ctx
->opcode
) >> 4) & 0x3f) {
12352 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
12358 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
12364 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
12370 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
12377 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
12378 int offset
= ZIMM(ctx
->opcode
, 0, 4);
12380 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
12389 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
12390 int offset
= ZIMM(ctx
->opcode
, 0, 4);
12392 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
12399 int reg
= ctx
->opcode
& 0x1f;
12401 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
12407 int reg
= ctx
->opcode
& 0x1f;
12408 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
12409 /* Let normal delay slot handling in our caller take us
12410 to the branch target. */
12415 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
12416 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12420 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
12421 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12425 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
12429 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
12432 generate_exception(ctx
, EXCP_BREAK
);
12435 /* XXX: not clear which exception should be raised
12436 * when in debug mode...
12438 check_insn(ctx
, ISA_MIPS32
);
12439 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
12440 generate_exception(ctx
, EXCP_DBp
);
12442 generate_exception(ctx
, EXCP_DBp
);
12445 case JRADDIUSP
+ 0:
12446 case JRADDIUSP
+ 1:
12448 int imm
= ZIMM(ctx
->opcode
, 0, 5);
12449 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
12450 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
12451 /* Let normal delay slot handling in our caller take us
12452 to the branch target. */
12456 generate_exception(ctx
, EXCP_RI
);
12461 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
12463 TCGv t0
= tcg_temp_new();
12464 TCGv t1
= tcg_temp_new();
12466 gen_load_gpr(t0
, base
);
12469 gen_load_gpr(t1
, index
);
12470 tcg_gen_shli_tl(t1
, t1
, 2);
12471 gen_op_addr_add(ctx
, t0
, t1
, t0
);
12474 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12475 gen_store_gpr(t1
, rd
);
12481 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
12482 int base
, int16_t offset
)
12484 const char *opn
= "ldst_pair";
12487 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
12488 generate_exception(ctx
, EXCP_RI
);
12492 t0
= tcg_temp_new();
12493 t1
= tcg_temp_new();
12495 gen_base_offset_addr(ctx
, t0
, base
, offset
);
12500 generate_exception(ctx
, EXCP_RI
);
12503 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12504 gen_store_gpr(t1
, rd
);
12505 tcg_gen_movi_tl(t1
, 4);
12506 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12507 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12508 gen_store_gpr(t1
, rd
+1);
12512 gen_load_gpr(t1
, rd
);
12513 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12514 tcg_gen_movi_tl(t1
, 4);
12515 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12516 gen_load_gpr(t1
, rd
+1);
12517 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12520 #ifdef TARGET_MIPS64
12523 generate_exception(ctx
, EXCP_RI
);
12526 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12527 gen_store_gpr(t1
, rd
);
12528 tcg_gen_movi_tl(t1
, 8);
12529 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12530 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12531 gen_store_gpr(t1
, rd
+1);
12535 gen_load_gpr(t1
, rd
);
12536 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12537 tcg_gen_movi_tl(t1
, 8);
12538 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12539 gen_load_gpr(t1
, rd
+1);
12540 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12545 (void)opn
; /* avoid a compiler warning */
12546 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
12551 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
12553 int extension
= (ctx
->opcode
>> 6) & 0x3f;
12554 int minor
= (ctx
->opcode
>> 12) & 0xf;
12555 uint32_t mips32_op
;
12557 switch (extension
) {
12559 mips32_op
= OPC_TEQ
;
12562 mips32_op
= OPC_TGE
;
12565 mips32_op
= OPC_TGEU
;
12568 mips32_op
= OPC_TLT
;
12571 mips32_op
= OPC_TLTU
;
12574 mips32_op
= OPC_TNE
;
12576 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
12578 #ifndef CONFIG_USER_ONLY
12581 check_cp0_enabled(ctx
);
12583 /* Treat as NOP. */
12586 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
12590 check_cp0_enabled(ctx
);
12592 TCGv t0
= tcg_temp_new();
12594 gen_load_gpr(t0
, rt
);
12595 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
12601 switch (minor
& 3) {
12603 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12606 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12609 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12612 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12615 goto pool32axf_invalid
;
12619 switch (minor
& 3) {
12621 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12624 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12627 goto pool32axf_invalid
;
12633 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
12636 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
12639 mips32_op
= OPC_CLO
;
12642 mips32_op
= OPC_CLZ
;
12644 check_insn(ctx
, ISA_MIPS32
);
12645 gen_cl(ctx
, mips32_op
, rt
, rs
);
12648 gen_rdhwr(ctx
, rt
, rs
);
12651 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
12654 mips32_op
= OPC_MULT
;
12657 mips32_op
= OPC_MULTU
;
12660 mips32_op
= OPC_DIV
;
12663 mips32_op
= OPC_DIVU
;
12666 check_insn(ctx
, ISA_MIPS32
);
12667 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
12670 mips32_op
= OPC_MADD
;
12673 mips32_op
= OPC_MADDU
;
12676 mips32_op
= OPC_MSUB
;
12679 mips32_op
= OPC_MSUBU
;
12681 check_insn(ctx
, ISA_MIPS32
);
12682 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
12685 goto pool32axf_invalid
;
12696 generate_exception_err(ctx
, EXCP_CpU
, 2);
12699 goto pool32axf_invalid
;
12706 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
12707 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12711 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
12712 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12715 goto pool32axf_invalid
;
12721 check_cp0_enabled(ctx
);
12722 check_insn(ctx
, ISA_MIPS32R2
);
12723 gen_load_srsgpr(rt
, rs
);
12726 check_cp0_enabled(ctx
);
12727 check_insn(ctx
, ISA_MIPS32R2
);
12728 gen_store_srsgpr(rt
, rs
);
12731 goto pool32axf_invalid
;
12734 #ifndef CONFIG_USER_ONLY
12738 mips32_op
= OPC_TLBP
;
12741 mips32_op
= OPC_TLBR
;
12744 mips32_op
= OPC_TLBWI
;
12747 mips32_op
= OPC_TLBWR
;
12750 mips32_op
= OPC_WAIT
;
12753 mips32_op
= OPC_DERET
;
12756 mips32_op
= OPC_ERET
;
12758 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
12761 goto pool32axf_invalid
;
12767 check_cp0_enabled(ctx
);
12769 TCGv t0
= tcg_temp_new();
12771 save_cpu_state(ctx
, 1);
12772 gen_helper_di(t0
, cpu_env
);
12773 gen_store_gpr(t0
, rs
);
12774 /* Stop translation as we may have switched the execution mode */
12775 ctx
->bstate
= BS_STOP
;
12780 check_cp0_enabled(ctx
);
12782 TCGv t0
= tcg_temp_new();
12784 save_cpu_state(ctx
, 1);
12785 gen_helper_ei(t0
, cpu_env
);
12786 gen_store_gpr(t0
, rs
);
12787 /* Stop translation as we may have switched the execution mode */
12788 ctx
->bstate
= BS_STOP
;
12793 goto pool32axf_invalid
;
12803 generate_exception(ctx
, EXCP_SYSCALL
);
12804 ctx
->bstate
= BS_STOP
;
12807 check_insn(ctx
, ISA_MIPS32
);
12808 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
12809 generate_exception(ctx
, EXCP_DBp
);
12811 generate_exception(ctx
, EXCP_DBp
);
12815 goto pool32axf_invalid
;
12819 switch (minor
& 3) {
12821 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
12824 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
12827 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
12830 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
12833 goto pool32axf_invalid
;
12839 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
12842 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
12845 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
12848 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
12851 goto pool32axf_invalid
;
12856 MIPS_INVAL("pool32axf");
12857 generate_exception(ctx
, EXCP_RI
);
12862 /* Values for microMIPS fmt field. Variable-width, depending on which
12863 formats the instruction supports. */
12882 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
12884 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
12885 uint32_t mips32_op
;
12887 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12888 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12889 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12891 switch (extension
) {
12892 case FLOAT_1BIT_FMT(CFC1
, 0):
12893 mips32_op
= OPC_CFC1
;
12895 case FLOAT_1BIT_FMT(CTC1
, 0):
12896 mips32_op
= OPC_CTC1
;
12898 case FLOAT_1BIT_FMT(MFC1
, 0):
12899 mips32_op
= OPC_MFC1
;
12901 case FLOAT_1BIT_FMT(MTC1
, 0):
12902 mips32_op
= OPC_MTC1
;
12904 case FLOAT_1BIT_FMT(MFHC1
, 0):
12905 mips32_op
= OPC_MFHC1
;
12907 case FLOAT_1BIT_FMT(MTHC1
, 0):
12908 mips32_op
= OPC_MTHC1
;
12910 gen_cp1(ctx
, mips32_op
, rt
, rs
);
12913 /* Reciprocal square root */
12914 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
12915 mips32_op
= OPC_RSQRT_S
;
12917 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
12918 mips32_op
= OPC_RSQRT_D
;
12922 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
12923 mips32_op
= OPC_SQRT_S
;
12925 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
12926 mips32_op
= OPC_SQRT_D
;
12930 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
12931 mips32_op
= OPC_RECIP_S
;
12933 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
12934 mips32_op
= OPC_RECIP_D
;
12938 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
12939 mips32_op
= OPC_FLOOR_L_S
;
12941 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
12942 mips32_op
= OPC_FLOOR_L_D
;
12944 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
12945 mips32_op
= OPC_FLOOR_W_S
;
12947 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
12948 mips32_op
= OPC_FLOOR_W_D
;
12952 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
12953 mips32_op
= OPC_CEIL_L_S
;
12955 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
12956 mips32_op
= OPC_CEIL_L_D
;
12958 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
12959 mips32_op
= OPC_CEIL_W_S
;
12961 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
12962 mips32_op
= OPC_CEIL_W_D
;
12966 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
12967 mips32_op
= OPC_TRUNC_L_S
;
12969 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
12970 mips32_op
= OPC_TRUNC_L_D
;
12972 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
12973 mips32_op
= OPC_TRUNC_W_S
;
12975 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
12976 mips32_op
= OPC_TRUNC_W_D
;
12980 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
12981 mips32_op
= OPC_ROUND_L_S
;
12983 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
12984 mips32_op
= OPC_ROUND_L_D
;
12986 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
12987 mips32_op
= OPC_ROUND_W_S
;
12989 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
12990 mips32_op
= OPC_ROUND_W_D
;
12993 /* Integer to floating-point conversion */
12994 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
12995 mips32_op
= OPC_CVT_L_S
;
12997 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
12998 mips32_op
= OPC_CVT_L_D
;
13000 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
13001 mips32_op
= OPC_CVT_W_S
;
13003 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
13004 mips32_op
= OPC_CVT_W_D
;
13007 /* Paired-foo conversions */
13008 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
13009 mips32_op
= OPC_CVT_S_PL
;
13011 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
13012 mips32_op
= OPC_CVT_S_PU
;
13014 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
13015 mips32_op
= OPC_CVT_PW_PS
;
13017 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
13018 mips32_op
= OPC_CVT_PS_PW
;
13021 /* Floating-point moves */
13022 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
13023 mips32_op
= OPC_MOV_S
;
13025 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
13026 mips32_op
= OPC_MOV_D
;
13028 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
13029 mips32_op
= OPC_MOV_PS
;
13032 /* Absolute value */
13033 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
13034 mips32_op
= OPC_ABS_S
;
13036 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
13037 mips32_op
= OPC_ABS_D
;
13039 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
13040 mips32_op
= OPC_ABS_PS
;
13044 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
13045 mips32_op
= OPC_NEG_S
;
13047 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
13048 mips32_op
= OPC_NEG_D
;
13050 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
13051 mips32_op
= OPC_NEG_PS
;
13054 /* Reciprocal square root step */
13055 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
13056 mips32_op
= OPC_RSQRT1_S
;
13058 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
13059 mips32_op
= OPC_RSQRT1_D
;
13061 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
13062 mips32_op
= OPC_RSQRT1_PS
;
13065 /* Reciprocal step */
13066 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
13067 mips32_op
= OPC_RECIP1_S
;
13069 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
13070 mips32_op
= OPC_RECIP1_S
;
13072 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
13073 mips32_op
= OPC_RECIP1_PS
;
13076 /* Conversions from double */
13077 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
13078 mips32_op
= OPC_CVT_D_S
;
13080 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
13081 mips32_op
= OPC_CVT_D_W
;
13083 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
13084 mips32_op
= OPC_CVT_D_L
;
13087 /* Conversions from single */
13088 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
13089 mips32_op
= OPC_CVT_S_D
;
13091 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
13092 mips32_op
= OPC_CVT_S_W
;
13094 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
13095 mips32_op
= OPC_CVT_S_L
;
13097 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
13100 /* Conditional moves on floating-point codes */
13101 case COND_FLOAT_MOV(MOVT
, 0):
13102 case COND_FLOAT_MOV(MOVT
, 1):
13103 case COND_FLOAT_MOV(MOVT
, 2):
13104 case COND_FLOAT_MOV(MOVT
, 3):
13105 case COND_FLOAT_MOV(MOVT
, 4):
13106 case COND_FLOAT_MOV(MOVT
, 5):
13107 case COND_FLOAT_MOV(MOVT
, 6):
13108 case COND_FLOAT_MOV(MOVT
, 7):
13109 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
13111 case COND_FLOAT_MOV(MOVF
, 0):
13112 case COND_FLOAT_MOV(MOVF
, 1):
13113 case COND_FLOAT_MOV(MOVF
, 2):
13114 case COND_FLOAT_MOV(MOVF
, 3):
13115 case COND_FLOAT_MOV(MOVF
, 4):
13116 case COND_FLOAT_MOV(MOVF
, 5):
13117 case COND_FLOAT_MOV(MOVF
, 6):
13118 case COND_FLOAT_MOV(MOVF
, 7):
13119 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
13122 MIPS_INVAL("pool32fxf");
13123 generate_exception(ctx
, EXCP_RI
);
13128 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
13133 int rt
, rs
, rd
, rr
;
13135 uint32_t op
, minor
, mips32_op
;
13136 uint32_t cond
, fmt
, cc
;
13138 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
13139 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
13141 rt
= (ctx
->opcode
>> 21) & 0x1f;
13142 rs
= (ctx
->opcode
>> 16) & 0x1f;
13143 rd
= (ctx
->opcode
>> 11) & 0x1f;
13144 rr
= (ctx
->opcode
>> 6) & 0x1f;
13145 imm
= (int16_t) ctx
->opcode
;
13147 op
= (ctx
->opcode
>> 26) & 0x3f;
13150 minor
= ctx
->opcode
& 0x3f;
13153 minor
= (ctx
->opcode
>> 6) & 0xf;
13156 mips32_op
= OPC_SLL
;
13159 mips32_op
= OPC_SRA
;
13162 mips32_op
= OPC_SRL
;
13165 mips32_op
= OPC_ROTR
;
13167 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
13170 goto pool32a_invalid
;
13174 minor
= (ctx
->opcode
>> 6) & 0xf;
13178 mips32_op
= OPC_ADD
;
13181 mips32_op
= OPC_ADDU
;
13184 mips32_op
= OPC_SUB
;
13187 mips32_op
= OPC_SUBU
;
13190 mips32_op
= OPC_MUL
;
13192 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
13196 mips32_op
= OPC_SLLV
;
13199 mips32_op
= OPC_SRLV
;
13202 mips32_op
= OPC_SRAV
;
13205 mips32_op
= OPC_ROTRV
;
13207 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
13209 /* Logical operations */
13211 mips32_op
= OPC_AND
;
13214 mips32_op
= OPC_OR
;
13217 mips32_op
= OPC_NOR
;
13220 mips32_op
= OPC_XOR
;
13222 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
13224 /* Set less than */
13226 mips32_op
= OPC_SLT
;
13229 mips32_op
= OPC_SLTU
;
13231 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
13234 goto pool32a_invalid
;
13238 minor
= (ctx
->opcode
>> 6) & 0xf;
13240 /* Conditional moves */
13242 mips32_op
= OPC_MOVN
;
13245 mips32_op
= OPC_MOVZ
;
13247 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
13250 gen_ldxs(ctx
, rs
, rt
, rd
);
13253 goto pool32a_invalid
;
13257 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
13260 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
13263 gen_pool32axf(env
, ctx
, rt
, rs
);
13266 generate_exception(ctx
, EXCP_BREAK
);
13270 MIPS_INVAL("pool32a");
13271 generate_exception(ctx
, EXCP_RI
);
13276 minor
= (ctx
->opcode
>> 12) & 0xf;
13279 check_cp0_enabled(ctx
);
13280 /* Treat as no-op. */
13284 /* COP2: Not implemented. */
13285 generate_exception_err(ctx
, EXCP_CpU
, 2);
13287 #ifdef TARGET_MIPS64
13290 check_insn(ctx
, ISA_MIPS3
);
13291 check_mips_64(ctx
);
13296 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13298 #ifdef TARGET_MIPS64
13301 check_insn(ctx
, ISA_MIPS3
);
13302 check_mips_64(ctx
);
13307 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13310 MIPS_INVAL("pool32b");
13311 generate_exception(ctx
, EXCP_RI
);
13316 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
13317 minor
= ctx
->opcode
& 0x3f;
13318 check_cp1_enabled(ctx
);
13321 mips32_op
= OPC_ALNV_PS
;
13324 mips32_op
= OPC_MADD_S
;
13327 mips32_op
= OPC_MADD_D
;
13330 mips32_op
= OPC_MADD_PS
;
13333 mips32_op
= OPC_MSUB_S
;
13336 mips32_op
= OPC_MSUB_D
;
13339 mips32_op
= OPC_MSUB_PS
;
13342 mips32_op
= OPC_NMADD_S
;
13345 mips32_op
= OPC_NMADD_D
;
13348 mips32_op
= OPC_NMADD_PS
;
13351 mips32_op
= OPC_NMSUB_S
;
13354 mips32_op
= OPC_NMSUB_D
;
13357 mips32_op
= OPC_NMSUB_PS
;
13359 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
13361 case CABS_COND_FMT
:
13362 cond
= (ctx
->opcode
>> 6) & 0xf;
13363 cc
= (ctx
->opcode
>> 13) & 0x7;
13364 fmt
= (ctx
->opcode
>> 10) & 0x3;
13367 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
13370 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
13373 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
13376 goto pool32f_invalid
;
13380 cond
= (ctx
->opcode
>> 6) & 0xf;
13381 cc
= (ctx
->opcode
>> 13) & 0x7;
13382 fmt
= (ctx
->opcode
>> 10) & 0x3;
13385 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
13388 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
13391 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
13394 goto pool32f_invalid
;
13398 gen_pool32fxf(ctx
, rt
, rs
);
13402 switch ((ctx
->opcode
>> 6) & 0x7) {
13404 mips32_op
= OPC_PLL_PS
;
13407 mips32_op
= OPC_PLU_PS
;
13410 mips32_op
= OPC_PUL_PS
;
13413 mips32_op
= OPC_PUU_PS
;
13416 mips32_op
= OPC_CVT_PS_S
;
13418 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13421 goto pool32f_invalid
;
13426 switch ((ctx
->opcode
>> 6) & 0x7) {
13428 mips32_op
= OPC_LWXC1
;
13431 mips32_op
= OPC_SWXC1
;
13434 mips32_op
= OPC_LDXC1
;
13437 mips32_op
= OPC_SDXC1
;
13440 mips32_op
= OPC_LUXC1
;
13443 mips32_op
= OPC_SUXC1
;
13445 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
13448 goto pool32f_invalid
;
13453 fmt
= (ctx
->opcode
>> 9) & 0x3;
13454 switch ((ctx
->opcode
>> 6) & 0x7) {
13458 mips32_op
= OPC_RSQRT2_S
;
13461 mips32_op
= OPC_RSQRT2_D
;
13464 mips32_op
= OPC_RSQRT2_PS
;
13467 goto pool32f_invalid
;
13473 mips32_op
= OPC_RECIP2_S
;
13476 mips32_op
= OPC_RECIP2_D
;
13479 mips32_op
= OPC_RECIP2_PS
;
13482 goto pool32f_invalid
;
13486 mips32_op
= OPC_ADDR_PS
;
13489 mips32_op
= OPC_MULR_PS
;
13491 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13494 goto pool32f_invalid
;
13498 /* MOV[FT].fmt and PREFX */
13499 cc
= (ctx
->opcode
>> 13) & 0x7;
13500 fmt
= (ctx
->opcode
>> 9) & 0x3;
13501 switch ((ctx
->opcode
>> 6) & 0x7) {
13505 gen_movcf_s(rs
, rt
, cc
, 0);
13508 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
13511 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
13514 goto pool32f_invalid
;
13520 gen_movcf_s(rs
, rt
, cc
, 1);
13523 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
13526 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
13529 goto pool32f_invalid
;
13535 goto pool32f_invalid
;
13538 #define FINSN_3ARG_SDPS(prfx) \
13539 switch ((ctx->opcode >> 8) & 0x3) { \
13541 mips32_op = OPC_##prfx##_S; \
13544 mips32_op = OPC_##prfx##_D; \
13546 case FMT_SDPS_PS: \
13547 mips32_op = OPC_##prfx##_PS; \
13550 goto pool32f_invalid; \
13553 /* regular FP ops */
13554 switch ((ctx
->opcode
>> 6) & 0x3) {
13556 FINSN_3ARG_SDPS(ADD
);
13559 FINSN_3ARG_SDPS(SUB
);
13562 FINSN_3ARG_SDPS(MUL
);
13565 fmt
= (ctx
->opcode
>> 8) & 0x3;
13567 mips32_op
= OPC_DIV_D
;
13568 } else if (fmt
== 0) {
13569 mips32_op
= OPC_DIV_S
;
13571 goto pool32f_invalid
;
13575 goto pool32f_invalid
;
13580 switch ((ctx
->opcode
>> 6) & 0x3) {
13582 FINSN_3ARG_SDPS(MOVN
);
13585 FINSN_3ARG_SDPS(MOVZ
);
13588 goto pool32f_invalid
;
13592 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13596 MIPS_INVAL("pool32f");
13597 generate_exception(ctx
, EXCP_RI
);
13601 generate_exception_err(ctx
, EXCP_CpU
, 1);
13605 minor
= (ctx
->opcode
>> 21) & 0x1f;
13608 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
13611 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
13612 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13615 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
13616 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13619 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
13622 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
13623 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13626 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
13627 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13630 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
13633 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
13638 mips32_op
= OPC_TLTI
;
13641 mips32_op
= OPC_TGEI
;
13644 mips32_op
= OPC_TLTIU
;
13647 mips32_op
= OPC_TGEIU
;
13650 mips32_op
= OPC_TNEI
;
13653 mips32_op
= OPC_TEQI
;
13655 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
13660 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
13661 4, rs
, 0, imm
<< 1, 0);
13662 /* Compact branches don't have a delay slot, so just let
13663 the normal delay slot handling take us to the branch
13667 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
13670 /* Break the TB to be able to sync copied instructions
13672 ctx
->bstate
= BS_STOP
;
13676 /* COP2: Not implemented. */
13677 generate_exception_err(ctx
, EXCP_CpU
, 2);
13680 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
13683 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
13686 mips32_op
= OPC_BC1FANY4
;
13689 mips32_op
= OPC_BC1TANY4
;
13692 check_insn(ctx
, ASE_MIPS3D
);
13695 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
13696 check_cp1_enabled(ctx
);
13697 gen_compute_branch1(ctx
, mips32_op
,
13698 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
13700 generate_exception_err(ctx
, EXCP_CpU
, 1);
13705 /* MIPS DSP: not implemented */
13708 MIPS_INVAL("pool32i");
13709 generate_exception(ctx
, EXCP_RI
);
13714 minor
= (ctx
->opcode
>> 12) & 0xf;
13717 mips32_op
= OPC_LWL
;
13720 mips32_op
= OPC_SWL
;
13723 mips32_op
= OPC_LWR
;
13726 mips32_op
= OPC_SWR
;
13728 #if defined(TARGET_MIPS64)
13730 check_insn(ctx
, ISA_MIPS3
);
13731 check_mips_64(ctx
);
13732 mips32_op
= OPC_LDL
;
13735 check_insn(ctx
, ISA_MIPS3
);
13736 check_mips_64(ctx
);
13737 mips32_op
= OPC_SDL
;
13740 check_insn(ctx
, ISA_MIPS3
);
13741 check_mips_64(ctx
);
13742 mips32_op
= OPC_LDR
;
13745 check_insn(ctx
, ISA_MIPS3
);
13746 check_mips_64(ctx
);
13747 mips32_op
= OPC_SDR
;
13750 check_insn(ctx
, ISA_MIPS3
);
13751 check_mips_64(ctx
);
13752 mips32_op
= OPC_LWU
;
13755 check_insn(ctx
, ISA_MIPS3
);
13756 check_mips_64(ctx
);
13757 mips32_op
= OPC_LLD
;
13761 mips32_op
= OPC_LL
;
13764 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13767 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13770 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13772 #if defined(TARGET_MIPS64)
13774 check_insn(ctx
, ISA_MIPS3
);
13775 check_mips_64(ctx
);
13776 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13780 /* Treat as no-op */
13783 MIPS_INVAL("pool32c");
13784 generate_exception(ctx
, EXCP_RI
);
13789 mips32_op
= OPC_ADDI
;
13792 mips32_op
= OPC_ADDIU
;
13794 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13797 /* Logical operations */
13799 mips32_op
= OPC_ORI
;
13802 mips32_op
= OPC_XORI
;
13805 mips32_op
= OPC_ANDI
;
13807 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13810 /* Set less than immediate */
13812 mips32_op
= OPC_SLTI
;
13815 mips32_op
= OPC_SLTIU
;
13817 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13820 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
13821 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
13822 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13825 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
13826 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
13827 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13830 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
13833 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
13836 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
13837 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
13840 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
13841 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
13842 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13844 /* Floating point (COP1) */
13846 mips32_op
= OPC_LWC1
;
13849 mips32_op
= OPC_LDC1
;
13852 mips32_op
= OPC_SWC1
;
13855 mips32_op
= OPC_SDC1
;
13857 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
13861 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
13862 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
13864 gen_addiupc(ctx
, reg
, offset
, 0, 0);
13867 /* Loads and stores */
13869 mips32_op
= OPC_LB
;
13872 mips32_op
= OPC_LBU
;
13875 mips32_op
= OPC_LH
;
13878 mips32_op
= OPC_LHU
;
13881 mips32_op
= OPC_LW
;
13883 #ifdef TARGET_MIPS64
13885 check_insn(ctx
, ISA_MIPS3
);
13886 check_mips_64(ctx
);
13887 mips32_op
= OPC_LD
;
13890 check_insn(ctx
, ISA_MIPS3
);
13891 check_mips_64(ctx
);
13892 mips32_op
= OPC_SD
;
13896 mips32_op
= OPC_SB
;
13899 mips32_op
= OPC_SH
;
13902 mips32_op
= OPC_SW
;
13905 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
13908 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
13911 generate_exception(ctx
, EXCP_RI
);
13916 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
13920 /* make sure instructions are on a halfword boundary */
13921 if (ctx
->pc
& 0x1) {
13922 env
->CP0_BadVAddr
= ctx
->pc
;
13923 generate_exception(ctx
, EXCP_AdEL
);
13924 ctx
->bstate
= BS_STOP
;
13928 op
= (ctx
->opcode
>> 10) & 0x3f;
13929 /* Enforce properly-sized instructions in a delay slot */
13930 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
13931 switch (op
& 0x7) { /* MSB-3..MSB-5 */
13933 /* POOL32A, POOL32B, POOL32I, POOL32C */
13935 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13937 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13939 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13941 /* LB32, LH32, LWC132, LDC132, LW32 */
13942 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
13943 generate_exception(ctx
, EXCP_RI
);
13944 /* Just stop translation; the user is confused. */
13945 ctx
->bstate
= BS_STOP
;
13950 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13952 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13954 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13955 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
13956 generate_exception(ctx
, EXCP_RI
);
13957 /* Just stop translation; the user is confused. */
13958 ctx
->bstate
= BS_STOP
;
13968 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13969 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
13970 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
13973 switch (ctx
->opcode
& 0x1) {
13982 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
13987 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13988 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
13989 int amount
= (ctx
->opcode
>> 1) & 0x7;
13991 amount
= amount
== 0 ? 8 : amount
;
13993 switch (ctx
->opcode
& 0x1) {
14002 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
14006 gen_pool16c_insn(ctx
);
14010 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14011 int rb
= 28; /* GP */
14012 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
14014 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
14018 if (ctx
->opcode
& 1) {
14019 generate_exception(ctx
, EXCP_RI
);
14022 int enc_dest
= uMIPS_RD(ctx
->opcode
);
14023 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
14024 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
14025 int rd
, rs
, re
, rt
;
14026 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14027 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14028 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14030 rd
= rd_enc
[enc_dest
];
14031 re
= re_enc
[enc_dest
];
14032 rs
= rs_rt_enc
[enc_rs
];
14033 rt
= rs_rt_enc
[enc_rt
];
14035 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
14036 gen_arith(ctx
, OPC_ADDU
, re
, rt
, 0);
14041 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14042 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
14043 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
14044 offset
= (offset
== 0xf ? -1 : offset
);
14046 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
14051 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14052 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
14053 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
14055 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
14060 int rd
= (ctx
->opcode
>> 5) & 0x1f;
14061 int rb
= 29; /* SP */
14062 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
14064 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
14069 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
14070 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
14071 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
14073 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
14078 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
14079 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
14080 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
14082 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
14087 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
14088 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
14089 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
14091 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
14096 int rd
= (ctx
->opcode
>> 5) & 0x1f;
14097 int rb
= 29; /* SP */
14098 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
14100 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
14105 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
14106 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
14107 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
14109 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
14114 int rd
= uMIPS_RD5(ctx
->opcode
);
14115 int rs
= uMIPS_RS5(ctx
->opcode
);
14117 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
14124 switch (ctx
->opcode
& 0x1) {
14134 switch (ctx
->opcode
& 0x1) {
14139 gen_addiur1sp(ctx
);
14144 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
14145 SIMM(ctx
->opcode
, 0, 10) << 1, 4);
14149 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
14150 mmreg(uMIPS_RD(ctx
->opcode
)),
14151 0, SIMM(ctx
->opcode
, 0, 7) << 1, 4);
14155 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
14156 int imm
= ZIMM(ctx
->opcode
, 0, 7);
14158 imm
= (imm
== 0x7f ? -1 : imm
);
14159 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
14169 generate_exception(ctx
, EXCP_RI
);
14172 decode_micromips32_opc (env
, ctx
, op
);
14179 /* SmartMIPS extension to MIPS32 */
14181 #if defined(TARGET_MIPS64)
14183 /* MDMX extension to MIPS64 */
14187 /* MIPSDSP functions. */
14188 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
14189 int rd
, int base
, int offset
)
14191 const char *opn
= "ldx";
14195 t0
= tcg_temp_new();
14198 gen_load_gpr(t0
, offset
);
14199 } else if (offset
== 0) {
14200 gen_load_gpr(t0
, base
);
14202 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
14207 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
14208 gen_store_gpr(t0
, rd
);
14212 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
14213 gen_store_gpr(t0
, rd
);
14217 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
14218 gen_store_gpr(t0
, rd
);
14221 #if defined(TARGET_MIPS64)
14223 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
14224 gen_store_gpr(t0
, rd
);
14229 (void)opn
; /* avoid a compiler warning */
14230 MIPS_DEBUG("%s %s, %s(%s)", opn
,
14231 regnames
[rd
], regnames
[offset
], regnames
[base
]);
14235 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14236 int ret
, int v1
, int v2
)
14238 const char *opn
= "mipsdsp arith";
14243 /* Treat as NOP. */
14248 v1_t
= tcg_temp_new();
14249 v2_t
= tcg_temp_new();
14251 gen_load_gpr(v1_t
, v1
);
14252 gen_load_gpr(v2_t
, v2
);
14255 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
14256 case OPC_MULT_G_2E
:
14260 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14262 case OPC_ADDUH_R_QB
:
14263 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14266 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14268 case OPC_ADDQH_R_PH
:
14269 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14272 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14274 case OPC_ADDQH_R_W
:
14275 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14278 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14280 case OPC_SUBUH_R_QB
:
14281 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14284 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14286 case OPC_SUBQH_R_PH
:
14287 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14290 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14292 case OPC_SUBQH_R_W
:
14293 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14297 case OPC_ABSQ_S_PH_DSP
:
14299 case OPC_ABSQ_S_QB
:
14301 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
14303 case OPC_ABSQ_S_PH
:
14305 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
14309 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
14311 case OPC_PRECEQ_W_PHL
:
14313 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
14314 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
14316 case OPC_PRECEQ_W_PHR
:
14318 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
14319 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
14320 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
14322 case OPC_PRECEQU_PH_QBL
:
14324 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
14326 case OPC_PRECEQU_PH_QBR
:
14328 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
14330 case OPC_PRECEQU_PH_QBLA
:
14332 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
14334 case OPC_PRECEQU_PH_QBRA
:
14336 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
14338 case OPC_PRECEU_PH_QBL
:
14340 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
14342 case OPC_PRECEU_PH_QBR
:
14344 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
14346 case OPC_PRECEU_PH_QBLA
:
14348 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
14350 case OPC_PRECEU_PH_QBRA
:
14352 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
14356 case OPC_ADDU_QB_DSP
:
14360 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14362 case OPC_ADDQ_S_PH
:
14364 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14368 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14372 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14374 case OPC_ADDU_S_QB
:
14376 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14380 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14382 case OPC_ADDU_S_PH
:
14384 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14388 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14390 case OPC_SUBQ_S_PH
:
14392 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14396 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14400 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14402 case OPC_SUBU_S_QB
:
14404 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14408 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14410 case OPC_SUBU_S_PH
:
14412 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14416 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14420 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14424 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
14426 case OPC_RADDU_W_QB
:
14428 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
14432 case OPC_CMPU_EQ_QB_DSP
:
14434 case OPC_PRECR_QB_PH
:
14436 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14438 case OPC_PRECRQ_QB_PH
:
14440 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14442 case OPC_PRECR_SRA_PH_W
:
14445 TCGv_i32 sa_t
= tcg_const_i32(v2
);
14446 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
14448 tcg_temp_free_i32(sa_t
);
14451 case OPC_PRECR_SRA_R_PH_W
:
14454 TCGv_i32 sa_t
= tcg_const_i32(v2
);
14455 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
14457 tcg_temp_free_i32(sa_t
);
14460 case OPC_PRECRQ_PH_W
:
14462 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14464 case OPC_PRECRQ_RS_PH_W
:
14466 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14468 case OPC_PRECRQU_S_QB_PH
:
14470 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14474 #ifdef TARGET_MIPS64
14475 case OPC_ABSQ_S_QH_DSP
:
14477 case OPC_PRECEQ_L_PWL
:
14479 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
14481 case OPC_PRECEQ_L_PWR
:
14483 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
14485 case OPC_PRECEQ_PW_QHL
:
14487 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
14489 case OPC_PRECEQ_PW_QHR
:
14491 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
14493 case OPC_PRECEQ_PW_QHLA
:
14495 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
14497 case OPC_PRECEQ_PW_QHRA
:
14499 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
14501 case OPC_PRECEQU_QH_OBL
:
14503 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
14505 case OPC_PRECEQU_QH_OBR
:
14507 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
14509 case OPC_PRECEQU_QH_OBLA
:
14511 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
14513 case OPC_PRECEQU_QH_OBRA
:
14515 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
14517 case OPC_PRECEU_QH_OBL
:
14519 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
14521 case OPC_PRECEU_QH_OBR
:
14523 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
14525 case OPC_PRECEU_QH_OBLA
:
14527 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
14529 case OPC_PRECEU_QH_OBRA
:
14531 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
14533 case OPC_ABSQ_S_OB
:
14535 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
14537 case OPC_ABSQ_S_PW
:
14539 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
14541 case OPC_ABSQ_S_QH
:
14543 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
14547 case OPC_ADDU_OB_DSP
:
14549 case OPC_RADDU_L_OB
:
14551 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
14555 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14557 case OPC_SUBQ_S_PW
:
14559 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14563 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14565 case OPC_SUBQ_S_QH
:
14567 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14571 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14573 case OPC_SUBU_S_OB
:
14575 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14579 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14581 case OPC_SUBU_S_QH
:
14583 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14587 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14589 case OPC_SUBUH_R_OB
:
14591 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14595 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14597 case OPC_ADDQ_S_PW
:
14599 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14603 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14605 case OPC_ADDQ_S_QH
:
14607 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14611 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14613 case OPC_ADDU_S_OB
:
14615 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14619 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14621 case OPC_ADDU_S_QH
:
14623 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14627 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14629 case OPC_ADDUH_R_OB
:
14631 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14635 case OPC_CMPU_EQ_OB_DSP
:
14637 case OPC_PRECR_OB_QH
:
14639 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
14641 case OPC_PRECR_SRA_QH_PW
:
14644 TCGv_i32 ret_t
= tcg_const_i32(ret
);
14645 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
14646 tcg_temp_free_i32(ret_t
);
14649 case OPC_PRECR_SRA_R_QH_PW
:
14652 TCGv_i32 sa_v
= tcg_const_i32(ret
);
14653 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
14654 tcg_temp_free_i32(sa_v
);
14657 case OPC_PRECRQ_OB_QH
:
14659 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
14661 case OPC_PRECRQ_PW_L
:
14663 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
14665 case OPC_PRECRQ_QH_PW
:
14667 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14669 case OPC_PRECRQ_RS_QH_PW
:
14671 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14673 case OPC_PRECRQU_S_OB_QH
:
14675 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14682 tcg_temp_free(v1_t
);
14683 tcg_temp_free(v2_t
);
14685 (void)opn
; /* avoid a compiler warning */
14686 MIPS_DEBUG("%s", opn
);
14689 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
14690 int ret
, int v1
, int v2
)
14693 const char *opn
= "mipsdsp shift";
14699 /* Treat as NOP. */
14704 t0
= tcg_temp_new();
14705 v1_t
= tcg_temp_new();
14706 v2_t
= tcg_temp_new();
14708 tcg_gen_movi_tl(t0
, v1
);
14709 gen_load_gpr(v1_t
, v1
);
14710 gen_load_gpr(v2_t
, v2
);
14713 case OPC_SHLL_QB_DSP
:
14715 op2
= MASK_SHLL_QB(ctx
->opcode
);
14719 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14723 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14727 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14731 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14733 case OPC_SHLL_S_PH
:
14735 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14737 case OPC_SHLLV_S_PH
:
14739 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14743 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14745 case OPC_SHLLV_S_W
:
14747 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14751 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
14755 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14759 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
14763 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14767 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
14769 case OPC_SHRA_R_QB
:
14771 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
14775 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14777 case OPC_SHRAV_R_QB
:
14779 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14783 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
14785 case OPC_SHRA_R_PH
:
14787 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
14791 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14793 case OPC_SHRAV_R_PH
:
14795 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14799 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
14801 case OPC_SHRAV_R_W
:
14803 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14805 default: /* Invalid */
14806 MIPS_INVAL("MASK SHLL.QB");
14807 generate_exception(ctx
, EXCP_RI
);
14812 #ifdef TARGET_MIPS64
14813 case OPC_SHLL_OB_DSP
:
14814 op2
= MASK_SHLL_OB(ctx
->opcode
);
14818 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14822 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14824 case OPC_SHLL_S_PW
:
14826 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14828 case OPC_SHLLV_S_PW
:
14830 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14834 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14838 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14842 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14846 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14848 case OPC_SHLL_S_QH
:
14850 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14852 case OPC_SHLLV_S_QH
:
14854 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14858 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
14862 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14864 case OPC_SHRA_R_OB
:
14866 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
14868 case OPC_SHRAV_R_OB
:
14870 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14874 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
14878 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
14880 case OPC_SHRA_R_PW
:
14882 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
14884 case OPC_SHRAV_R_PW
:
14886 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
14890 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
14894 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14896 case OPC_SHRA_R_QH
:
14898 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
14900 case OPC_SHRAV_R_QH
:
14902 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14906 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
14910 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14914 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
14918 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14920 default: /* Invalid */
14921 MIPS_INVAL("MASK SHLL.OB");
14922 generate_exception(ctx
, EXCP_RI
);
14930 tcg_temp_free(v1_t
);
14931 tcg_temp_free(v2_t
);
14932 (void)opn
; /* avoid a compiler warning */
14933 MIPS_DEBUG("%s", opn
);
14936 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14937 int ret
, int v1
, int v2
, int check_ret
)
14939 const char *opn
= "mipsdsp multiply";
14944 if ((ret
== 0) && (check_ret
== 1)) {
14945 /* Treat as NOP. */
14950 t0
= tcg_temp_new_i32();
14951 v1_t
= tcg_temp_new();
14952 v2_t
= tcg_temp_new();
14954 tcg_gen_movi_i32(t0
, ret
);
14955 gen_load_gpr(v1_t
, v1
);
14956 gen_load_gpr(v2_t
, v2
);
14959 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14960 * the same mask and op1. */
14961 case OPC_MULT_G_2E
:
14965 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14968 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14971 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14973 case OPC_MULQ_RS_W
:
14974 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14978 case OPC_DPA_W_PH_DSP
:
14980 case OPC_DPAU_H_QBL
:
14982 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
14984 case OPC_DPAU_H_QBR
:
14986 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
14988 case OPC_DPSU_H_QBL
:
14990 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
14992 case OPC_DPSU_H_QBR
:
14994 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
14998 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15000 case OPC_DPAX_W_PH
:
15002 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15004 case OPC_DPAQ_S_W_PH
:
15006 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15008 case OPC_DPAQX_S_W_PH
:
15010 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15012 case OPC_DPAQX_SA_W_PH
:
15014 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15018 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15020 case OPC_DPSX_W_PH
:
15022 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15024 case OPC_DPSQ_S_W_PH
:
15026 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15028 case OPC_DPSQX_S_W_PH
:
15030 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15032 case OPC_DPSQX_SA_W_PH
:
15034 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15036 case OPC_MULSAQ_S_W_PH
:
15038 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15040 case OPC_DPAQ_SA_L_W
:
15042 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
15044 case OPC_DPSQ_SA_L_W
:
15046 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
15048 case OPC_MAQ_S_W_PHL
:
15050 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
15052 case OPC_MAQ_S_W_PHR
:
15054 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
15056 case OPC_MAQ_SA_W_PHL
:
15058 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
15060 case OPC_MAQ_SA_W_PHR
:
15062 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
15064 case OPC_MULSA_W_PH
:
15066 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
15070 #ifdef TARGET_MIPS64
15071 case OPC_DPAQ_W_QH_DSP
:
15073 int ac
= ret
& 0x03;
15074 tcg_gen_movi_i32(t0
, ac
);
15079 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
15083 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
15087 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
15091 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
15095 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
15097 case OPC_DPAQ_S_W_QH
:
15099 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
15101 case OPC_DPAQ_SA_L_PW
:
15103 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
15105 case OPC_DPAU_H_OBL
:
15107 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
15109 case OPC_DPAU_H_OBR
:
15111 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
15115 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
15117 case OPC_DPSQ_S_W_QH
:
15119 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
15121 case OPC_DPSQ_SA_L_PW
:
15123 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
15125 case OPC_DPSU_H_OBL
:
15127 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
15129 case OPC_DPSU_H_OBR
:
15131 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
15133 case OPC_MAQ_S_L_PWL
:
15135 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
15137 case OPC_MAQ_S_L_PWR
:
15139 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
15141 case OPC_MAQ_S_W_QHLL
:
15143 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
15145 case OPC_MAQ_SA_W_QHLL
:
15147 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
15149 case OPC_MAQ_S_W_QHLR
:
15151 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
15153 case OPC_MAQ_SA_W_QHLR
:
15155 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
15157 case OPC_MAQ_S_W_QHRL
:
15159 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
15161 case OPC_MAQ_SA_W_QHRL
:
15163 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
15165 case OPC_MAQ_S_W_QHRR
:
15167 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
15169 case OPC_MAQ_SA_W_QHRR
:
15171 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
15173 case OPC_MULSAQ_S_L_PW
:
15175 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
15177 case OPC_MULSAQ_S_W_QH
:
15179 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
15185 case OPC_ADDU_QB_DSP
:
15187 case OPC_MULEU_S_PH_QBL
:
15189 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15191 case OPC_MULEU_S_PH_QBR
:
15193 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15195 case OPC_MULQ_RS_PH
:
15197 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15199 case OPC_MULEQ_S_W_PHL
:
15201 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15203 case OPC_MULEQ_S_W_PHR
:
15205 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15207 case OPC_MULQ_S_PH
:
15209 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15213 #ifdef TARGET_MIPS64
15214 case OPC_ADDU_OB_DSP
:
15216 case OPC_MULEQ_S_PW_QHL
:
15218 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15220 case OPC_MULEQ_S_PW_QHR
:
15222 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15224 case OPC_MULEU_S_QH_OBL
:
15226 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15228 case OPC_MULEU_S_QH_OBR
:
15230 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15232 case OPC_MULQ_RS_QH
:
15234 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15241 tcg_temp_free_i32(t0
);
15242 tcg_temp_free(v1_t
);
15243 tcg_temp_free(v2_t
);
15245 (void)opn
; /* avoid a compiler warning */
15246 MIPS_DEBUG("%s", opn
);
15250 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15253 const char *opn
= "mipsdsp Bit/ Manipulation";
15259 /* Treat as NOP. */
15264 t0
= tcg_temp_new();
15265 val_t
= tcg_temp_new();
15266 gen_load_gpr(val_t
, val
);
15269 case OPC_ABSQ_S_PH_DSP
:
15273 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
15278 target_long result
;
15279 imm
= (ctx
->opcode
>> 16) & 0xFF;
15280 result
= (uint32_t)imm
<< 24 |
15281 (uint32_t)imm
<< 16 |
15282 (uint32_t)imm
<< 8 |
15284 result
= (int32_t)result
;
15285 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
15290 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
15291 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
15292 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15293 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
15294 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15295 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15300 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15301 imm
= (int16_t)(imm
<< 6) >> 6;
15302 tcg_gen_movi_tl(cpu_gpr
[ret
], \
15303 (target_long
)((int32_t)imm
<< 16 | \
15309 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
15310 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
15311 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15312 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15316 #ifdef TARGET_MIPS64
15317 case OPC_ABSQ_S_QH_DSP
:
15324 imm
= (ctx
->opcode
>> 16) & 0xFF;
15325 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
15326 temp
= (temp
<< 16) | temp
;
15327 temp
= (temp
<< 32) | temp
;
15328 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
15336 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15337 imm
= (int16_t)(imm
<< 6) >> 6;
15338 temp
= ((target_long
)imm
<< 32) \
15339 | ((target_long
)imm
& 0xFFFFFFFF);
15340 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
15348 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15349 imm
= (int16_t)(imm
<< 6) >> 6;
15351 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
15352 ((uint64_t)(uint16_t)imm
<< 32) |
15353 ((uint64_t)(uint16_t)imm
<< 16) |
15354 (uint64_t)(uint16_t)imm
;
15355 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
15360 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
15361 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
15362 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15363 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
15364 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15365 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
15366 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15370 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
15371 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
15372 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15376 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
15377 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
15378 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15379 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
15380 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15387 tcg_temp_free(val_t
);
15389 (void)opn
; /* avoid a compiler warning */
15390 MIPS_DEBUG("%s", opn
);
15393 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
15394 uint32_t op1
, uint32_t op2
,
15395 int ret
, int v1
, int v2
, int check_ret
)
15397 const char *opn
= "mipsdsp add compare pick";
15402 if ((ret
== 0) && (check_ret
== 1)) {
15403 /* Treat as NOP. */
15408 t1
= tcg_temp_new();
15409 v1_t
= tcg_temp_new();
15410 v2_t
= tcg_temp_new();
15412 gen_load_gpr(v1_t
, v1
);
15413 gen_load_gpr(v2_t
, v2
);
15416 case OPC_CMPU_EQ_QB_DSP
:
15418 case OPC_CMPU_EQ_QB
:
15420 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
15422 case OPC_CMPU_LT_QB
:
15424 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
15426 case OPC_CMPU_LE_QB
:
15428 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
15430 case OPC_CMPGU_EQ_QB
:
15432 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15434 case OPC_CMPGU_LT_QB
:
15436 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15438 case OPC_CMPGU_LE_QB
:
15440 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15442 case OPC_CMPGDU_EQ_QB
:
15444 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
15445 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
15446 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
15447 tcg_gen_shli_tl(t1
, t1
, 24);
15448 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
15450 case OPC_CMPGDU_LT_QB
:
15452 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
15453 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
15454 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
15455 tcg_gen_shli_tl(t1
, t1
, 24);
15456 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
15458 case OPC_CMPGDU_LE_QB
:
15460 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
15461 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
15462 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
15463 tcg_gen_shli_tl(t1
, t1
, 24);
15464 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
15466 case OPC_CMP_EQ_PH
:
15468 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
15470 case OPC_CMP_LT_PH
:
15472 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
15474 case OPC_CMP_LE_PH
:
15476 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
15480 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15484 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15486 case OPC_PACKRL_PH
:
15488 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15492 #ifdef TARGET_MIPS64
15493 case OPC_CMPU_EQ_OB_DSP
:
15495 case OPC_CMP_EQ_PW
:
15497 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
15499 case OPC_CMP_LT_PW
:
15501 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
15503 case OPC_CMP_LE_PW
:
15505 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
15507 case OPC_CMP_EQ_QH
:
15509 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
15511 case OPC_CMP_LT_QH
:
15513 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
15515 case OPC_CMP_LE_QH
:
15517 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
15519 case OPC_CMPGDU_EQ_OB
:
15521 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15523 case OPC_CMPGDU_LT_OB
:
15525 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15527 case OPC_CMPGDU_LE_OB
:
15529 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15531 case OPC_CMPGU_EQ_OB
:
15533 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15535 case OPC_CMPGU_LT_OB
:
15537 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15539 case OPC_CMPGU_LE_OB
:
15541 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15543 case OPC_CMPU_EQ_OB
:
15545 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
15547 case OPC_CMPU_LT_OB
:
15549 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
15551 case OPC_CMPU_LE_OB
:
15553 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
15555 case OPC_PACKRL_PW
:
15557 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
15561 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15565 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15569 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15577 tcg_temp_free(v1_t
);
15578 tcg_temp_free(v2_t
);
15580 (void)opn
; /* avoid a compiler warning */
15581 MIPS_DEBUG("%s", opn
);
15584 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
15585 uint32_t op1
, int rt
, int rs
, int sa
)
15587 const char *opn
= "mipsdsp append/dappend";
15593 /* Treat as NOP. */
15598 t0
= tcg_temp_new();
15599 gen_load_gpr(t0
, rs
);
15602 case OPC_APPEND_DSP
:
15603 switch (MASK_APPEND(ctx
->opcode
)) {
15606 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
15608 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15612 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15613 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
15614 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
15615 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15617 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15621 if (sa
!= 0 && sa
!= 2) {
15622 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
15623 tcg_gen_ext32u_tl(t0
, t0
);
15624 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
15625 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15627 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15629 default: /* Invalid */
15630 MIPS_INVAL("MASK APPEND");
15631 generate_exception(ctx
, EXCP_RI
);
15635 #ifdef TARGET_MIPS64
15636 case OPC_DAPPEND_DSP
:
15637 switch (MASK_DAPPEND(ctx
->opcode
)) {
15640 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
15644 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
15645 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
15646 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
15650 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
15651 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
15652 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15657 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
15658 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
15659 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
15660 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15663 default: /* Invalid */
15664 MIPS_INVAL("MASK DAPPEND");
15665 generate_exception(ctx
, EXCP_RI
);
15672 (void)opn
; /* avoid a compiler warning */
15673 MIPS_DEBUG("%s", opn
);
15676 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15677 int ret
, int v1
, int v2
, int check_ret
)
15680 const char *opn
= "mipsdsp accumulator";
15687 if ((ret
== 0) && (check_ret
== 1)) {
15688 /* Treat as NOP. */
15693 t0
= tcg_temp_new();
15694 t1
= tcg_temp_new();
15695 v1_t
= tcg_temp_new();
15696 v2_t
= tcg_temp_new();
15698 gen_load_gpr(v1_t
, v1
);
15699 gen_load_gpr(v2_t
, v2
);
15702 case OPC_EXTR_W_DSP
:
15706 tcg_gen_movi_tl(t0
, v2
);
15707 tcg_gen_movi_tl(t1
, v1
);
15708 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15711 tcg_gen_movi_tl(t0
, v2
);
15712 tcg_gen_movi_tl(t1
, v1
);
15713 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15715 case OPC_EXTR_RS_W
:
15716 tcg_gen_movi_tl(t0
, v2
);
15717 tcg_gen_movi_tl(t1
, v1
);
15718 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15721 tcg_gen_movi_tl(t0
, v2
);
15722 tcg_gen_movi_tl(t1
, v1
);
15723 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15725 case OPC_EXTRV_S_H
:
15726 tcg_gen_movi_tl(t0
, v2
);
15727 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15730 tcg_gen_movi_tl(t0
, v2
);
15731 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15733 case OPC_EXTRV_R_W
:
15734 tcg_gen_movi_tl(t0
, v2
);
15735 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15737 case OPC_EXTRV_RS_W
:
15738 tcg_gen_movi_tl(t0
, v2
);
15739 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15742 tcg_gen_movi_tl(t0
, v2
);
15743 tcg_gen_movi_tl(t1
, v1
);
15744 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15747 tcg_gen_movi_tl(t0
, v2
);
15748 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15751 tcg_gen_movi_tl(t0
, v2
);
15752 tcg_gen_movi_tl(t1
, v1
);
15753 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15756 tcg_gen_movi_tl(t0
, v2
);
15757 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15760 imm
= (ctx
->opcode
>> 20) & 0x3F;
15761 tcg_gen_movi_tl(t0
, ret
);
15762 tcg_gen_movi_tl(t1
, imm
);
15763 gen_helper_shilo(t0
, t1
, cpu_env
);
15766 tcg_gen_movi_tl(t0
, ret
);
15767 gen_helper_shilo(t0
, v1_t
, cpu_env
);
15770 tcg_gen_movi_tl(t0
, ret
);
15771 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
15774 imm
= (ctx
->opcode
>> 11) & 0x3FF;
15775 tcg_gen_movi_tl(t0
, imm
);
15776 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
15779 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15780 tcg_gen_movi_tl(t0
, imm
);
15781 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
15785 #ifdef TARGET_MIPS64
15786 case OPC_DEXTR_W_DSP
:
15790 tcg_gen_movi_tl(t0
, ret
);
15791 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
15795 int shift
= (ctx
->opcode
>> 19) & 0x7F;
15796 int ac
= (ctx
->opcode
>> 11) & 0x03;
15797 tcg_gen_movi_tl(t0
, shift
);
15798 tcg_gen_movi_tl(t1
, ac
);
15799 gen_helper_dshilo(t0
, t1
, cpu_env
);
15804 int ac
= (ctx
->opcode
>> 11) & 0x03;
15805 tcg_gen_movi_tl(t0
, ac
);
15806 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
15810 tcg_gen_movi_tl(t0
, v2
);
15811 tcg_gen_movi_tl(t1
, v1
);
15813 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15816 tcg_gen_movi_tl(t0
, v2
);
15817 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15820 tcg_gen_movi_tl(t0
, v2
);
15821 tcg_gen_movi_tl(t1
, v1
);
15822 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15825 tcg_gen_movi_tl(t0
, v2
);
15826 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15829 tcg_gen_movi_tl(t0
, v2
);
15830 tcg_gen_movi_tl(t1
, v1
);
15831 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15833 case OPC_DEXTR_R_L
:
15834 tcg_gen_movi_tl(t0
, v2
);
15835 tcg_gen_movi_tl(t1
, v1
);
15836 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15838 case OPC_DEXTR_RS_L
:
15839 tcg_gen_movi_tl(t0
, v2
);
15840 tcg_gen_movi_tl(t1
, v1
);
15841 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15844 tcg_gen_movi_tl(t0
, v2
);
15845 tcg_gen_movi_tl(t1
, v1
);
15846 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15848 case OPC_DEXTR_R_W
:
15849 tcg_gen_movi_tl(t0
, v2
);
15850 tcg_gen_movi_tl(t1
, v1
);
15851 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15853 case OPC_DEXTR_RS_W
:
15854 tcg_gen_movi_tl(t0
, v2
);
15855 tcg_gen_movi_tl(t1
, v1
);
15856 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15858 case OPC_DEXTR_S_H
:
15859 tcg_gen_movi_tl(t0
, v2
);
15860 tcg_gen_movi_tl(t1
, v1
);
15861 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15863 case OPC_DEXTRV_S_H
:
15864 tcg_gen_movi_tl(t0
, v2
);
15865 tcg_gen_movi_tl(t1
, v1
);
15866 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15869 tcg_gen_movi_tl(t0
, v2
);
15870 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15872 case OPC_DEXTRV_R_L
:
15873 tcg_gen_movi_tl(t0
, v2
);
15874 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15876 case OPC_DEXTRV_RS_L
:
15877 tcg_gen_movi_tl(t0
, v2
);
15878 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15881 tcg_gen_movi_tl(t0
, v2
);
15882 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15884 case OPC_DEXTRV_R_W
:
15885 tcg_gen_movi_tl(t0
, v2
);
15886 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15888 case OPC_DEXTRV_RS_W
:
15889 tcg_gen_movi_tl(t0
, v2
);
15890 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15899 tcg_temp_free(v1_t
);
15900 tcg_temp_free(v2_t
);
15902 (void)opn
; /* avoid a compiler warning */
15903 MIPS_DEBUG("%s", opn
);
15906 /* End MIPSDSP functions. */
15908 /* Compact Branches */
15909 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
15910 int rs
, int rt
, int32_t offset
)
15912 int bcond_compute
= 0;
15913 TCGv t0
= tcg_temp_new();
15914 TCGv t1
= tcg_temp_new();
15916 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15917 #ifdef MIPS_DEBUG_DISAS
15918 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
15921 generate_exception(ctx
, EXCP_RI
);
15925 /* Load needed operands and calculate btarget */
15927 /* compact branch */
15928 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
15929 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
15930 gen_load_gpr(t0
, rs
);
15931 gen_load_gpr(t1
, rt
);
15933 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15934 if (rs
<= rt
&& rs
== 0) {
15935 /* OPC_BEQZALC, OPC_BNEZALC */
15936 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15939 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
15940 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
15941 gen_load_gpr(t0
, rs
);
15942 gen_load_gpr(t1
, rt
);
15944 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15946 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
15947 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
15948 if (rs
== 0 || rs
== rt
) {
15949 /* OPC_BLEZALC, OPC_BGEZALC */
15950 /* OPC_BGTZALC, OPC_BLTZALC */
15951 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15953 gen_load_gpr(t0
, rs
);
15954 gen_load_gpr(t1
, rt
);
15956 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15960 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15965 /* OPC_BEQZC, OPC_BNEZC */
15966 gen_load_gpr(t0
, rs
);
15968 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15970 /* OPC_JIC, OPC_JIALC */
15971 TCGv tbase
= tcg_temp_new();
15972 TCGv toffset
= tcg_temp_new();
15974 gen_load_gpr(tbase
, rt
);
15975 tcg_gen_movi_tl(toffset
, offset
);
15976 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
15977 tcg_temp_free(tbase
);
15978 tcg_temp_free(toffset
);
15982 MIPS_INVAL("Compact branch/jump");
15983 generate_exception(ctx
, EXCP_RI
);
15987 if (bcond_compute
== 0) {
15988 /* Uncoditional compact branch */
15991 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15994 ctx
->hflags
|= MIPS_HFLAG_BR
;
15997 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
16000 ctx
->hflags
|= MIPS_HFLAG_B
;
16003 MIPS_INVAL("Compact branch/jump");
16004 generate_exception(ctx
, EXCP_RI
);
16008 /* Generating branch here as compact branches don't have delay slot */
16009 gen_branch(ctx
, 4);
16011 /* Conditional compact branch */
16012 TCGLabel
*fs
= gen_new_label();
16013 save_cpu_state(ctx
, 0);
16016 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
16017 if (rs
== 0 && rt
!= 0) {
16019 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
16020 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16022 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
16025 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
16028 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
16029 if (rs
== 0 && rt
!= 0) {
16031 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
16032 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16034 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
16037 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
16040 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
16041 if (rs
== 0 && rt
!= 0) {
16043 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
16044 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16046 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
16049 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
16052 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
16053 if (rs
== 0 && rt
!= 0) {
16055 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
16056 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
16058 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
16061 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
16064 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
16065 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
16067 /* OPC_BOVC, OPC_BNVC */
16068 TCGv t2
= tcg_temp_new();
16069 TCGv t3
= tcg_temp_new();
16070 TCGv t4
= tcg_temp_new();
16071 TCGv input_overflow
= tcg_temp_new();
16073 gen_load_gpr(t0
, rs
);
16074 gen_load_gpr(t1
, rt
);
16075 tcg_gen_ext32s_tl(t2
, t0
);
16076 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
16077 tcg_gen_ext32s_tl(t3
, t1
);
16078 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
16079 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
16081 tcg_gen_add_tl(t4
, t2
, t3
);
16082 tcg_gen_ext32s_tl(t4
, t4
);
16083 tcg_gen_xor_tl(t2
, t2
, t3
);
16084 tcg_gen_xor_tl(t3
, t4
, t3
);
16085 tcg_gen_andc_tl(t2
, t3
, t2
);
16086 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
16087 tcg_gen_or_tl(t4
, t4
, input_overflow
);
16088 if (opc
== OPC_BOVC
) {
16090 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
16093 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
16095 tcg_temp_free(input_overflow
);
16099 } else if (rs
< rt
&& rs
== 0) {
16100 /* OPC_BEQZALC, OPC_BNEZALC */
16101 if (opc
== OPC_BEQZALC
) {
16103 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
16106 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
16109 /* OPC_BEQC, OPC_BNEC */
16110 if (opc
== OPC_BEQC
) {
16112 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
16115 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
16120 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
16123 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
16126 MIPS_INVAL("Compact conditional branch/jump");
16127 generate_exception(ctx
, EXCP_RI
);
16131 /* Generating branch here as compact branches don't have delay slot */
16132 gen_goto_tb(ctx
, 1, ctx
->btarget
);
16135 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
16136 MIPS_DEBUG("Compact conditional branch");
16144 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
16146 int rs
, rt
, rd
, sa
;
16149 rs
= (ctx
->opcode
>> 21) & 0x1f;
16150 rt
= (ctx
->opcode
>> 16) & 0x1f;
16151 rd
= (ctx
->opcode
>> 11) & 0x1f;
16152 sa
= (ctx
->opcode
>> 6) & 0x1f;
16154 op1
= MASK_SPECIAL(ctx
->opcode
);
16158 int imm2
= extract32(ctx
->opcode
, 6, 3);
16159 TCGv t0
= tcg_temp_new();
16160 TCGv t1
= tcg_temp_new();
16161 gen_load_gpr(t0
, rs
);
16162 gen_load_gpr(t1
, rt
);
16163 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
16164 tcg_gen_add_tl(t0
, t0
, t1
);
16165 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
16170 case OPC_MULT
... OPC_DIVU
:
16171 op2
= MASK_R6_MULDIV(ctx
->opcode
);
16181 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
16184 MIPS_INVAL("special_r6 muldiv");
16185 generate_exception(ctx
, EXCP_RI
);
16191 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
16195 if (rt
== 0 && sa
== 1) {
16196 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16197 We need additionally to check other fields */
16198 gen_cl(ctx
, op1
, rd
, rs
);
16200 generate_exception(ctx
, EXCP_RI
);
16204 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
16205 generate_exception(ctx
, EXCP_RI
);
16207 generate_exception(ctx
, EXCP_DBp
);
16210 #if defined(TARGET_MIPS64)
16212 check_mips_64(ctx
);
16214 int imm2
= extract32(ctx
->opcode
, 6, 3);
16215 TCGv t0
= tcg_temp_new();
16216 TCGv t1
= tcg_temp_new();
16217 gen_load_gpr(t0
, rs
);
16218 gen_load_gpr(t1
, rt
);
16219 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
16220 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
16227 if (rt
== 0 && sa
== 1) {
16228 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16229 We need additionally to check other fields */
16230 check_mips_64(ctx
);
16231 gen_cl(ctx
, op1
, rd
, rs
);
16233 generate_exception(ctx
, EXCP_RI
);
16236 case OPC_DMULT
... OPC_DDIVU
:
16237 op2
= MASK_R6_MULDIV(ctx
->opcode
);
16247 check_mips_64(ctx
);
16248 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
16251 MIPS_INVAL("special_r6 muldiv");
16252 generate_exception(ctx
, EXCP_RI
);
16257 default: /* Invalid */
16258 MIPS_INVAL("special_r6");
16259 generate_exception(ctx
, EXCP_RI
);
16264 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16266 int rs
, rt
, rd
, sa
;
16269 rs
= (ctx
->opcode
>> 21) & 0x1f;
16270 rt
= (ctx
->opcode
>> 16) & 0x1f;
16271 rd
= (ctx
->opcode
>> 11) & 0x1f;
16272 sa
= (ctx
->opcode
>> 6) & 0x1f;
16274 op1
= MASK_SPECIAL(ctx
->opcode
);
16276 case OPC_MOVN
: /* Conditional move */
16278 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
16279 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
16280 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
16282 case OPC_MFHI
: /* Move from HI/LO */
16284 gen_HILO(ctx
, op1
, rs
& 3, rd
);
16287 case OPC_MTLO
: /* Move to HI/LO */
16288 gen_HILO(ctx
, op1
, rd
& 3, rs
);
16291 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
16292 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16293 check_cp1_enabled(ctx
);
16294 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
16295 (ctx
->opcode
>> 16) & 1);
16297 generate_exception_err(ctx
, EXCP_CpU
, 1);
16303 check_insn(ctx
, INSN_VR54XX
);
16304 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
16305 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
16307 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
16312 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
16314 #if defined(TARGET_MIPS64)
16315 case OPC_DMULT
... OPC_DDIVU
:
16316 check_insn(ctx
, ISA_MIPS3
);
16317 check_mips_64(ctx
);
16318 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
16322 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
16325 #ifdef MIPS_STRICT_STANDARD
16326 MIPS_INVAL("SPIM");
16327 generate_exception(ctx
, EXCP_RI
);
16329 /* Implemented as RI exception for now. */
16330 MIPS_INVAL("spim (unofficial)");
16331 generate_exception(ctx
, EXCP_RI
);
16334 default: /* Invalid */
16335 MIPS_INVAL("special_legacy");
16336 generate_exception(ctx
, EXCP_RI
);
16341 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
16343 int rs
, rt
, rd
, sa
;
16346 rs
= (ctx
->opcode
>> 21) & 0x1f;
16347 rt
= (ctx
->opcode
>> 16) & 0x1f;
16348 rd
= (ctx
->opcode
>> 11) & 0x1f;
16349 sa
= (ctx
->opcode
>> 6) & 0x1f;
16351 op1
= MASK_SPECIAL(ctx
->opcode
);
16353 case OPC_SLL
: /* Shift with immediate */
16354 if (sa
== 5 && rd
== 0 &&
16355 rs
== 0 && rt
== 0) { /* PAUSE */
16356 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
16357 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
16358 MIPS_DEBUG("CTI in delay / forbidden slot");
16359 generate_exception(ctx
, EXCP_RI
);
16365 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16368 switch ((ctx
->opcode
>> 21) & 0x1f) {
16370 /* rotr is decoded as srl on non-R2 CPUs */
16371 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16376 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16379 generate_exception(ctx
, EXCP_RI
);
16383 case OPC_ADD
... OPC_SUBU
:
16384 gen_arith(ctx
, op1
, rd
, rs
, rt
);
16386 case OPC_SLLV
: /* Shifts */
16388 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16391 switch ((ctx
->opcode
>> 6) & 0x1f) {
16393 /* rotrv is decoded as srlv on non-R2 CPUs */
16394 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16399 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16402 generate_exception(ctx
, EXCP_RI
);
16406 case OPC_SLT
: /* Set on less than */
16408 gen_slt(ctx
, op1
, rd
, rs
, rt
);
16410 case OPC_AND
: /* Logic*/
16414 gen_logic(ctx
, op1
, rd
, rs
, rt
);
16417 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
16419 case OPC_TGE
... OPC_TEQ
: /* Traps */
16421 check_insn(ctx
, ISA_MIPS2
);
16422 gen_trap(ctx
, op1
, rs
, rt
, -1);
16424 case OPC_LSA
: /* OPC_PMON */
16425 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
16426 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
16427 decode_opc_special_r6(env
, ctx
);
16429 /* Pmon entry point, also R4010 selsl */
16430 #ifdef MIPS_STRICT_STANDARD
16431 MIPS_INVAL("PMON / selsl");
16432 generate_exception(ctx
, EXCP_RI
);
16434 gen_helper_0e0i(pmon
, sa
);
16439 generate_exception(ctx
, EXCP_SYSCALL
);
16440 ctx
->bstate
= BS_STOP
;
16443 generate_exception(ctx
, EXCP_BREAK
);
16446 check_insn(ctx
, ISA_MIPS2
);
16447 /* Treat as NOP. */
16450 #if defined(TARGET_MIPS64)
16451 /* MIPS64 specific opcodes */
16456 check_insn(ctx
, ISA_MIPS3
);
16457 check_mips_64(ctx
);
16458 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16461 switch ((ctx
->opcode
>> 21) & 0x1f) {
16463 /* drotr is decoded as dsrl on non-R2 CPUs */
16464 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16469 check_insn(ctx
, ISA_MIPS3
);
16470 check_mips_64(ctx
);
16471 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16474 generate_exception(ctx
, EXCP_RI
);
16479 switch ((ctx
->opcode
>> 21) & 0x1f) {
16481 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16482 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16487 check_insn(ctx
, ISA_MIPS3
);
16488 check_mips_64(ctx
);
16489 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16492 generate_exception(ctx
, EXCP_RI
);
16496 case OPC_DADD
... OPC_DSUBU
:
16497 check_insn(ctx
, ISA_MIPS3
);
16498 check_mips_64(ctx
);
16499 gen_arith(ctx
, op1
, rd
, rs
, rt
);
16503 check_insn(ctx
, ISA_MIPS3
);
16504 check_mips_64(ctx
);
16505 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16508 switch ((ctx
->opcode
>> 6) & 0x1f) {
16510 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16511 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16516 check_insn(ctx
, ISA_MIPS3
);
16517 check_mips_64(ctx
);
16518 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16521 generate_exception(ctx
, EXCP_RI
);
16526 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
16527 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
16528 decode_opc_special_r6(env
, ctx
);
16533 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16534 decode_opc_special_r6(env
, ctx
);
16536 decode_opc_special_legacy(env
, ctx
);
16541 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16546 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16548 rs
= (ctx
->opcode
>> 21) & 0x1f;
16549 rt
= (ctx
->opcode
>> 16) & 0x1f;
16550 rd
= (ctx
->opcode
>> 11) & 0x1f;
16552 op1
= MASK_SPECIAL2(ctx
->opcode
);
16554 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
16555 case OPC_MSUB
... OPC_MSUBU
:
16556 check_insn(ctx
, ISA_MIPS32
);
16557 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
16560 gen_arith(ctx
, op1
, rd
, rs
, rt
);
16563 case OPC_DIVU_G_2F
:
16564 case OPC_MULT_G_2F
:
16565 case OPC_MULTU_G_2F
:
16567 case OPC_MODU_G_2F
:
16568 check_insn(ctx
, INSN_LOONGSON2F
);
16569 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16573 check_insn(ctx
, ISA_MIPS32
);
16574 gen_cl(ctx
, op1
, rd
, rs
);
16577 /* XXX: not clear which exception should be raised
16578 * when in debug mode...
16580 check_insn(ctx
, ISA_MIPS32
);
16581 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
16582 generate_exception(ctx
, EXCP_DBp
);
16584 generate_exception(ctx
, EXCP_DBp
);
16586 /* Treat as NOP. */
16588 #if defined(TARGET_MIPS64)
16591 check_insn(ctx
, ISA_MIPS64
);
16592 check_mips_64(ctx
);
16593 gen_cl(ctx
, op1
, rd
, rs
);
16595 case OPC_DMULT_G_2F
:
16596 case OPC_DMULTU_G_2F
:
16597 case OPC_DDIV_G_2F
:
16598 case OPC_DDIVU_G_2F
:
16599 case OPC_DMOD_G_2F
:
16600 case OPC_DMODU_G_2F
:
16601 check_insn(ctx
, INSN_LOONGSON2F
);
16602 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16605 default: /* Invalid */
16606 MIPS_INVAL("special2_legacy");
16607 generate_exception(ctx
, EXCP_RI
);
16612 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
16614 int rs
, rt
, rd
, sa
;
16618 rs
= (ctx
->opcode
>> 21) & 0x1f;
16619 rt
= (ctx
->opcode
>> 16) & 0x1f;
16620 rd
= (ctx
->opcode
>> 11) & 0x1f;
16621 sa
= (ctx
->opcode
>> 6) & 0x1f;
16622 imm
= (int16_t)ctx
->opcode
>> 7;
16624 op1
= MASK_SPECIAL3(ctx
->opcode
);
16628 /* hint codes 24-31 are reserved and signal RI */
16629 generate_exception(ctx
, EXCP_RI
);
16631 /* Treat as NOP. */
16634 /* Treat as NOP. */
16637 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
16640 gen_ld(ctx
, op1
, rt
, rs
, imm
);
16645 /* Treat as NOP. */
16648 TCGv t0
= tcg_temp_new();
16649 gen_load_gpr(t0
, rt
);
16651 op2
= MASK_BSHFL(ctx
->opcode
);
16653 case OPC_ALIGN
... OPC_ALIGN_END
:
16656 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
16658 TCGv t1
= tcg_temp_new();
16659 TCGv_i64 t2
= tcg_temp_new_i64();
16660 gen_load_gpr(t1
, rs
);
16661 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
16662 tcg_gen_shri_i64(t2
, t2
, 8 * (4 - sa
));
16663 #if defined(TARGET_MIPS64)
16664 tcg_gen_ext32s_i64(cpu_gpr
[rd
], t2
);
16666 tcg_gen_trunc_i64_i32(cpu_gpr
[rd
], t2
);
16668 tcg_temp_free_i64(t2
);
16673 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
16679 #if defined(TARGET_MIPS64)
16681 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
16684 gen_ld(ctx
, op1
, rt
, rs
, imm
);
16687 check_mips_64(ctx
);
16690 /* Treat as NOP. */
16693 TCGv t0
= tcg_temp_new();
16694 gen_load_gpr(t0
, rt
);
16696 op2
= MASK_DBSHFL(ctx
->opcode
);
16698 case OPC_DALIGN
... OPC_DALIGN_END
:
16701 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
16703 TCGv t1
= tcg_temp_new();
16704 gen_load_gpr(t1
, rs
);
16705 tcg_gen_shli_tl(t0
, t0
, 8 * sa
);
16706 tcg_gen_shri_tl(t1
, t1
, 8 * (8 - sa
));
16707 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
16712 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
16719 default: /* Invalid */
16720 MIPS_INVAL("special3_r6");
16721 generate_exception(ctx
, EXCP_RI
);
16726 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16731 rs
= (ctx
->opcode
>> 21) & 0x1f;
16732 rt
= (ctx
->opcode
>> 16) & 0x1f;
16733 rd
= (ctx
->opcode
>> 11) & 0x1f;
16735 op1
= MASK_SPECIAL3(ctx
->opcode
);
16737 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
16738 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
16739 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
16740 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16741 * the same mask and op1. */
16742 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
16743 op2
= MASK_ADDUH_QB(ctx
->opcode
);
16746 case OPC_ADDUH_R_QB
:
16748 case OPC_ADDQH_R_PH
:
16750 case OPC_ADDQH_R_W
:
16752 case OPC_SUBUH_R_QB
:
16754 case OPC_SUBQH_R_PH
:
16756 case OPC_SUBQH_R_W
:
16757 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16762 case OPC_MULQ_RS_W
:
16763 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16766 MIPS_INVAL("MASK ADDUH.QB");
16767 generate_exception(ctx
, EXCP_RI
);
16770 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
16771 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16773 generate_exception(ctx
, EXCP_RI
);
16777 op2
= MASK_LX(ctx
->opcode
);
16779 #if defined(TARGET_MIPS64)
16785 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
16787 default: /* Invalid */
16788 MIPS_INVAL("MASK LX");
16789 generate_exception(ctx
, EXCP_RI
);
16793 case OPC_ABSQ_S_PH_DSP
:
16794 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
16796 case OPC_ABSQ_S_QB
:
16797 case OPC_ABSQ_S_PH
:
16799 case OPC_PRECEQ_W_PHL
:
16800 case OPC_PRECEQ_W_PHR
:
16801 case OPC_PRECEQU_PH_QBL
:
16802 case OPC_PRECEQU_PH_QBR
:
16803 case OPC_PRECEQU_PH_QBLA
:
16804 case OPC_PRECEQU_PH_QBRA
:
16805 case OPC_PRECEU_PH_QBL
:
16806 case OPC_PRECEU_PH_QBR
:
16807 case OPC_PRECEU_PH_QBLA
:
16808 case OPC_PRECEU_PH_QBRA
:
16809 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16816 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
16819 MIPS_INVAL("MASK ABSQ_S.PH");
16820 generate_exception(ctx
, EXCP_RI
);
16824 case OPC_ADDU_QB_DSP
:
16825 op2
= MASK_ADDU_QB(ctx
->opcode
);
16828 case OPC_ADDQ_S_PH
:
16831 case OPC_ADDU_S_QB
:
16833 case OPC_ADDU_S_PH
:
16835 case OPC_SUBQ_S_PH
:
16838 case OPC_SUBU_S_QB
:
16840 case OPC_SUBU_S_PH
:
16844 case OPC_RADDU_W_QB
:
16845 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16847 case OPC_MULEU_S_PH_QBL
:
16848 case OPC_MULEU_S_PH_QBR
:
16849 case OPC_MULQ_RS_PH
:
16850 case OPC_MULEQ_S_W_PHL
:
16851 case OPC_MULEQ_S_W_PHR
:
16852 case OPC_MULQ_S_PH
:
16853 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16855 default: /* Invalid */
16856 MIPS_INVAL("MASK ADDU.QB");
16857 generate_exception(ctx
, EXCP_RI
);
16862 case OPC_CMPU_EQ_QB_DSP
:
16863 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
16865 case OPC_PRECR_SRA_PH_W
:
16866 case OPC_PRECR_SRA_R_PH_W
:
16867 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
16869 case OPC_PRECR_QB_PH
:
16870 case OPC_PRECRQ_QB_PH
:
16871 case OPC_PRECRQ_PH_W
:
16872 case OPC_PRECRQ_RS_PH_W
:
16873 case OPC_PRECRQU_S_QB_PH
:
16874 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16876 case OPC_CMPU_EQ_QB
:
16877 case OPC_CMPU_LT_QB
:
16878 case OPC_CMPU_LE_QB
:
16879 case OPC_CMP_EQ_PH
:
16880 case OPC_CMP_LT_PH
:
16881 case OPC_CMP_LE_PH
:
16882 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16884 case OPC_CMPGU_EQ_QB
:
16885 case OPC_CMPGU_LT_QB
:
16886 case OPC_CMPGU_LE_QB
:
16887 case OPC_CMPGDU_EQ_QB
:
16888 case OPC_CMPGDU_LT_QB
:
16889 case OPC_CMPGDU_LE_QB
:
16892 case OPC_PACKRL_PH
:
16893 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16895 default: /* Invalid */
16896 MIPS_INVAL("MASK CMPU.EQ.QB");
16897 generate_exception(ctx
, EXCP_RI
);
16901 case OPC_SHLL_QB_DSP
:
16902 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
16904 case OPC_DPA_W_PH_DSP
:
16905 op2
= MASK_DPA_W_PH(ctx
->opcode
);
16907 case OPC_DPAU_H_QBL
:
16908 case OPC_DPAU_H_QBR
:
16909 case OPC_DPSU_H_QBL
:
16910 case OPC_DPSU_H_QBR
:
16912 case OPC_DPAX_W_PH
:
16913 case OPC_DPAQ_S_W_PH
:
16914 case OPC_DPAQX_S_W_PH
:
16915 case OPC_DPAQX_SA_W_PH
:
16917 case OPC_DPSX_W_PH
:
16918 case OPC_DPSQ_S_W_PH
:
16919 case OPC_DPSQX_S_W_PH
:
16920 case OPC_DPSQX_SA_W_PH
:
16921 case OPC_MULSAQ_S_W_PH
:
16922 case OPC_DPAQ_SA_L_W
:
16923 case OPC_DPSQ_SA_L_W
:
16924 case OPC_MAQ_S_W_PHL
:
16925 case OPC_MAQ_S_W_PHR
:
16926 case OPC_MAQ_SA_W_PHL
:
16927 case OPC_MAQ_SA_W_PHR
:
16928 case OPC_MULSA_W_PH
:
16929 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16931 default: /* Invalid */
16932 MIPS_INVAL("MASK DPAW.PH");
16933 generate_exception(ctx
, EXCP_RI
);
16938 op2
= MASK_INSV(ctx
->opcode
);
16950 t0
= tcg_temp_new();
16951 t1
= tcg_temp_new();
16953 gen_load_gpr(t0
, rt
);
16954 gen_load_gpr(t1
, rs
);
16956 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
16962 default: /* Invalid */
16963 MIPS_INVAL("MASK INSV");
16964 generate_exception(ctx
, EXCP_RI
);
16968 case OPC_APPEND_DSP
:
16969 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
16971 case OPC_EXTR_W_DSP
:
16972 op2
= MASK_EXTR_W(ctx
->opcode
);
16976 case OPC_EXTR_RS_W
:
16978 case OPC_EXTRV_S_H
:
16980 case OPC_EXTRV_R_W
:
16981 case OPC_EXTRV_RS_W
:
16986 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
16989 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16995 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16997 default: /* Invalid */
16998 MIPS_INVAL("MASK EXTR.W");
16999 generate_exception(ctx
, EXCP_RI
);
17003 #if defined(TARGET_MIPS64)
17004 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
17005 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
17006 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
17007 check_insn(ctx
, INSN_LOONGSON2E
);
17008 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17010 case OPC_ABSQ_S_QH_DSP
:
17011 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
17013 case OPC_PRECEQ_L_PWL
:
17014 case OPC_PRECEQ_L_PWR
:
17015 case OPC_PRECEQ_PW_QHL
:
17016 case OPC_PRECEQ_PW_QHR
:
17017 case OPC_PRECEQ_PW_QHLA
:
17018 case OPC_PRECEQ_PW_QHRA
:
17019 case OPC_PRECEQU_QH_OBL
:
17020 case OPC_PRECEQU_QH_OBR
:
17021 case OPC_PRECEQU_QH_OBLA
:
17022 case OPC_PRECEQU_QH_OBRA
:
17023 case OPC_PRECEU_QH_OBL
:
17024 case OPC_PRECEU_QH_OBR
:
17025 case OPC_PRECEU_QH_OBLA
:
17026 case OPC_PRECEU_QH_OBRA
:
17027 case OPC_ABSQ_S_OB
:
17028 case OPC_ABSQ_S_PW
:
17029 case OPC_ABSQ_S_QH
:
17030 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17038 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
17040 default: /* Invalid */
17041 MIPS_INVAL("MASK ABSQ_S.QH");
17042 generate_exception(ctx
, EXCP_RI
);
17046 case OPC_ADDU_OB_DSP
:
17047 op2
= MASK_ADDU_OB(ctx
->opcode
);
17049 case OPC_RADDU_L_OB
:
17051 case OPC_SUBQ_S_PW
:
17053 case OPC_SUBQ_S_QH
:
17055 case OPC_SUBU_S_OB
:
17057 case OPC_SUBU_S_QH
:
17059 case OPC_SUBUH_R_OB
:
17061 case OPC_ADDQ_S_PW
:
17063 case OPC_ADDQ_S_QH
:
17065 case OPC_ADDU_S_OB
:
17067 case OPC_ADDU_S_QH
:
17069 case OPC_ADDUH_R_OB
:
17070 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17072 case OPC_MULEQ_S_PW_QHL
:
17073 case OPC_MULEQ_S_PW_QHR
:
17074 case OPC_MULEU_S_QH_OBL
:
17075 case OPC_MULEU_S_QH_OBR
:
17076 case OPC_MULQ_RS_QH
:
17077 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17079 default: /* Invalid */
17080 MIPS_INVAL("MASK ADDU.OB");
17081 generate_exception(ctx
, EXCP_RI
);
17085 case OPC_CMPU_EQ_OB_DSP
:
17086 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
17088 case OPC_PRECR_SRA_QH_PW
:
17089 case OPC_PRECR_SRA_R_QH_PW
:
17090 /* Return value is rt. */
17091 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
17093 case OPC_PRECR_OB_QH
:
17094 case OPC_PRECRQ_OB_QH
:
17095 case OPC_PRECRQ_PW_L
:
17096 case OPC_PRECRQ_QH_PW
:
17097 case OPC_PRECRQ_RS_QH_PW
:
17098 case OPC_PRECRQU_S_OB_QH
:
17099 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17101 case OPC_CMPU_EQ_OB
:
17102 case OPC_CMPU_LT_OB
:
17103 case OPC_CMPU_LE_OB
:
17104 case OPC_CMP_EQ_QH
:
17105 case OPC_CMP_LT_QH
:
17106 case OPC_CMP_LE_QH
:
17107 case OPC_CMP_EQ_PW
:
17108 case OPC_CMP_LT_PW
:
17109 case OPC_CMP_LE_PW
:
17110 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17112 case OPC_CMPGDU_EQ_OB
:
17113 case OPC_CMPGDU_LT_OB
:
17114 case OPC_CMPGDU_LE_OB
:
17115 case OPC_CMPGU_EQ_OB
:
17116 case OPC_CMPGU_LT_OB
:
17117 case OPC_CMPGU_LE_OB
:
17118 case OPC_PACKRL_PW
:
17122 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17124 default: /* Invalid */
17125 MIPS_INVAL("MASK CMPU_EQ.OB");
17126 generate_exception(ctx
, EXCP_RI
);
17130 case OPC_DAPPEND_DSP
:
17131 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
17133 case OPC_DEXTR_W_DSP
:
17134 op2
= MASK_DEXTR_W(ctx
->opcode
);
17141 case OPC_DEXTR_R_L
:
17142 case OPC_DEXTR_RS_L
:
17144 case OPC_DEXTR_R_W
:
17145 case OPC_DEXTR_RS_W
:
17146 case OPC_DEXTR_S_H
:
17148 case OPC_DEXTRV_R_L
:
17149 case OPC_DEXTRV_RS_L
:
17150 case OPC_DEXTRV_S_H
:
17152 case OPC_DEXTRV_R_W
:
17153 case OPC_DEXTRV_RS_W
:
17154 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
17159 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17161 default: /* Invalid */
17162 MIPS_INVAL("MASK EXTR.W");
17163 generate_exception(ctx
, EXCP_RI
);
17167 case OPC_DPAQ_W_QH_DSP
:
17168 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
17170 case OPC_DPAU_H_OBL
:
17171 case OPC_DPAU_H_OBR
:
17172 case OPC_DPSU_H_OBL
:
17173 case OPC_DPSU_H_OBR
:
17175 case OPC_DPAQ_S_W_QH
:
17177 case OPC_DPSQ_S_W_QH
:
17178 case OPC_MULSAQ_S_W_QH
:
17179 case OPC_DPAQ_SA_L_PW
:
17180 case OPC_DPSQ_SA_L_PW
:
17181 case OPC_MULSAQ_S_L_PW
:
17182 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17184 case OPC_MAQ_S_W_QHLL
:
17185 case OPC_MAQ_S_W_QHLR
:
17186 case OPC_MAQ_S_W_QHRL
:
17187 case OPC_MAQ_S_W_QHRR
:
17188 case OPC_MAQ_SA_W_QHLL
:
17189 case OPC_MAQ_SA_W_QHLR
:
17190 case OPC_MAQ_SA_W_QHRL
:
17191 case OPC_MAQ_SA_W_QHRR
:
17192 case OPC_MAQ_S_L_PWL
:
17193 case OPC_MAQ_S_L_PWR
:
17198 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17200 default: /* Invalid */
17201 MIPS_INVAL("MASK DPAQ.W.QH");
17202 generate_exception(ctx
, EXCP_RI
);
17206 case OPC_DINSV_DSP
:
17207 op2
= MASK_INSV(ctx
->opcode
);
17219 t0
= tcg_temp_new();
17220 t1
= tcg_temp_new();
17222 gen_load_gpr(t0
, rt
);
17223 gen_load_gpr(t1
, rs
);
17225 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
17231 default: /* Invalid */
17232 MIPS_INVAL("MASK DINSV");
17233 generate_exception(ctx
, EXCP_RI
);
17237 case OPC_SHLL_OB_DSP
:
17238 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
17241 default: /* Invalid */
17242 MIPS_INVAL("special3_legacy");
17243 generate_exception(ctx
, EXCP_RI
);
17248 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
17250 int rs
, rt
, rd
, sa
;
17253 rs
= (ctx
->opcode
>> 21) & 0x1f;
17254 rt
= (ctx
->opcode
>> 16) & 0x1f;
17255 rd
= (ctx
->opcode
>> 11) & 0x1f;
17256 sa
= (ctx
->opcode
>> 6) & 0x1f;
17258 op1
= MASK_SPECIAL3(ctx
->opcode
);
17262 check_insn(ctx
, ISA_MIPS32R2
);
17263 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
17266 op2
= MASK_BSHFL(ctx
->opcode
);
17268 case OPC_ALIGN
... OPC_ALIGN_END
:
17270 check_insn(ctx
, ISA_MIPS32R6
);
17271 decode_opc_special3_r6(env
, ctx
);
17274 check_insn(ctx
, ISA_MIPS32R2
);
17275 gen_bshfl(ctx
, op2
, rt
, rd
);
17279 #if defined(TARGET_MIPS64)
17280 case OPC_DEXTM
... OPC_DEXT
:
17281 case OPC_DINSM
... OPC_DINS
:
17282 check_insn(ctx
, ISA_MIPS64R2
);
17283 check_mips_64(ctx
);
17284 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
17287 op2
= MASK_DBSHFL(ctx
->opcode
);
17289 case OPC_DALIGN
... OPC_DALIGN_END
:
17291 check_insn(ctx
, ISA_MIPS32R6
);
17292 decode_opc_special3_r6(env
, ctx
);
17295 check_insn(ctx
, ISA_MIPS64R2
);
17296 check_mips_64(ctx
);
17297 op2
= MASK_DBSHFL(ctx
->opcode
);
17298 gen_bshfl(ctx
, op2
, rt
, rd
);
17304 gen_rdhwr(ctx
, rt
, rd
);
17307 check_insn(ctx
, ASE_MT
);
17309 TCGv t0
= tcg_temp_new();
17310 TCGv t1
= tcg_temp_new();
17312 gen_load_gpr(t0
, rt
);
17313 gen_load_gpr(t1
, rs
);
17314 gen_helper_fork(t0
, t1
);
17320 check_insn(ctx
, ASE_MT
);
17322 TCGv t0
= tcg_temp_new();
17324 save_cpu_state(ctx
, 1);
17325 gen_load_gpr(t0
, rs
);
17326 gen_helper_yield(t0
, cpu_env
, t0
);
17327 gen_store_gpr(t0
, rd
);
17332 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17333 decode_opc_special3_r6(env
, ctx
);
17335 decode_opc_special3_legacy(env
, ctx
);
17340 /* MIPS SIMD Architecture (MSA) */
17341 static inline int check_msa_access(DisasContext
*ctx
)
17343 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
17344 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
17345 generate_exception(ctx
, EXCP_RI
);
17349 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
17350 if (ctx
->insn_flags
& ASE_MSA
) {
17351 generate_exception(ctx
, EXCP_MSADIS
);
17354 generate_exception(ctx
, EXCP_RI
);
17361 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
17363 /* generates tcg ops to check if any element is 0 */
17364 /* Note this function only works with MSA_WRLEN = 128 */
17365 uint64_t eval_zero_or_big
= 0;
17366 uint64_t eval_big
= 0;
17367 TCGv_i64 t0
= tcg_temp_new_i64();
17368 TCGv_i64 t1
= tcg_temp_new_i64();
17371 eval_zero_or_big
= 0x0101010101010101ULL
;
17372 eval_big
= 0x8080808080808080ULL
;
17375 eval_zero_or_big
= 0x0001000100010001ULL
;
17376 eval_big
= 0x8000800080008000ULL
;
17379 eval_zero_or_big
= 0x0000000100000001ULL
;
17380 eval_big
= 0x8000000080000000ULL
;
17383 eval_zero_or_big
= 0x0000000000000001ULL
;
17384 eval_big
= 0x8000000000000000ULL
;
17387 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<<1], eval_zero_or_big
);
17388 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<<1]);
17389 tcg_gen_andi_i64(t0
, t0
, eval_big
);
17390 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<<1)+1], eval_zero_or_big
);
17391 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<<1)+1]);
17392 tcg_gen_andi_i64(t1
, t1
, eval_big
);
17393 tcg_gen_or_i64(t0
, t0
, t1
);
17394 /* if all bits are zero then all elements are not zero */
17395 /* if some bit is non-zero then some element is zero */
17396 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
17397 tcg_gen_trunc_i64_tl(tresult
, t0
);
17398 tcg_temp_free_i64(t0
);
17399 tcg_temp_free_i64(t1
);
17402 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
17404 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
17405 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
17406 int64_t s16
= (int16_t)ctx
->opcode
;
17408 check_msa_access(ctx
);
17410 if (ctx
->insn_flags
& ISA_MIPS32R6
&& ctx
->hflags
& MIPS_HFLAG_BMASK
) {
17411 MIPS_DEBUG("CTI in delay / forbidden slot");
17412 generate_exception(ctx
, EXCP_RI
);
17419 TCGv_i64 t0
= tcg_temp_new_i64();
17420 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<<1], msa_wr_d
[(wt
<<1)+1]);
17421 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
17422 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
17423 tcg_gen_trunc_i64_tl(bcond
, t0
);
17424 tcg_temp_free_i64(t0
);
17431 gen_check_zero_element(bcond
, df
, wt
);
17437 gen_check_zero_element(bcond
, df
, wt
);
17438 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
17442 ctx
->btarget
= ctx
->pc
+ (s16
<< 2) + 4;
17444 ctx
->hflags
|= MIPS_HFLAG_BC
;
17445 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
17448 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
17450 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17451 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
17452 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
17453 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
17455 TCGv_i32 twd
= tcg_const_i32(wd
);
17456 TCGv_i32 tws
= tcg_const_i32(ws
);
17457 TCGv_i32 ti8
= tcg_const_i32(i8
);
17459 switch (MASK_MSA_I8(ctx
->opcode
)) {
17461 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
17464 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
17467 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
17470 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
17473 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
17476 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
17479 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
17485 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
17486 if (df
== DF_DOUBLE
) {
17487 generate_exception(ctx
, EXCP_RI
);
17489 TCGv_i32 tdf
= tcg_const_i32(df
);
17490 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
17491 tcg_temp_free_i32(tdf
);
17496 MIPS_INVAL("MSA instruction");
17497 generate_exception(ctx
, EXCP_RI
);
17501 tcg_temp_free_i32(twd
);
17502 tcg_temp_free_i32(tws
);
17503 tcg_temp_free_i32(ti8
);
17506 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
17508 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17509 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
17510 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
17511 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
17512 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
17513 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
17515 TCGv_i32 tdf
= tcg_const_i32(df
);
17516 TCGv_i32 twd
= tcg_const_i32(wd
);
17517 TCGv_i32 tws
= tcg_const_i32(ws
);
17518 TCGv_i32 timm
= tcg_temp_new_i32();
17519 tcg_gen_movi_i32(timm
, u5
);
17521 switch (MASK_MSA_I5(ctx
->opcode
)) {
17523 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
17526 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
17528 case OPC_MAXI_S_df
:
17529 tcg_gen_movi_i32(timm
, s5
);
17530 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
17532 case OPC_MAXI_U_df
:
17533 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
17535 case OPC_MINI_S_df
:
17536 tcg_gen_movi_i32(timm
, s5
);
17537 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
17539 case OPC_MINI_U_df
:
17540 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
17543 tcg_gen_movi_i32(timm
, s5
);
17544 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
17546 case OPC_CLTI_S_df
:
17547 tcg_gen_movi_i32(timm
, s5
);
17548 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
17550 case OPC_CLTI_U_df
:
17551 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
17553 case OPC_CLEI_S_df
:
17554 tcg_gen_movi_i32(timm
, s5
);
17555 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
17557 case OPC_CLEI_U_df
:
17558 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
17562 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
17563 tcg_gen_movi_i32(timm
, s10
);
17564 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
17568 MIPS_INVAL("MSA instruction");
17569 generate_exception(ctx
, EXCP_RI
);
17573 tcg_temp_free_i32(tdf
);
17574 tcg_temp_free_i32(twd
);
17575 tcg_temp_free_i32(tws
);
17576 tcg_temp_free_i32(timm
);
17579 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
17581 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17582 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
17583 uint32_t df
= 0, m
= 0;
17584 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
17585 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
17592 if ((dfm
& 0x40) == 0x00) {
17595 } else if ((dfm
& 0x60) == 0x40) {
17598 } else if ((dfm
& 0x70) == 0x60) {
17601 } else if ((dfm
& 0x78) == 0x70) {
17605 generate_exception(ctx
, EXCP_RI
);
17609 tdf
= tcg_const_i32(df
);
17610 tm
= tcg_const_i32(m
);
17611 twd
= tcg_const_i32(wd
);
17612 tws
= tcg_const_i32(ws
);
17614 switch (MASK_MSA_BIT(ctx
->opcode
)) {
17616 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
17619 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
17622 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
17625 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
17628 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
17631 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
17633 case OPC_BINSLI_df
:
17634 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
17636 case OPC_BINSRI_df
:
17637 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
17640 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
17643 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
17646 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
17649 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
17652 MIPS_INVAL("MSA instruction");
17653 generate_exception(ctx
, EXCP_RI
);
17657 tcg_temp_free_i32(tdf
);
17658 tcg_temp_free_i32(tm
);
17659 tcg_temp_free_i32(twd
);
17660 tcg_temp_free_i32(tws
);
17663 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
17665 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17666 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
17667 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
17668 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
17669 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
17671 TCGv_i32 tdf
= tcg_const_i32(df
);
17672 TCGv_i32 twd
= tcg_const_i32(wd
);
17673 TCGv_i32 tws
= tcg_const_i32(ws
);
17674 TCGv_i32 twt
= tcg_const_i32(wt
);
17676 switch (MASK_MSA_3R(ctx
->opcode
)) {
17678 gen_helper_msa_sll_df(cpu_env
, tdf
, twd
, tws
, twt
);
17681 gen_helper_msa_addv_df(cpu_env
, tdf
, twd
, tws
, twt
);
17684 gen_helper_msa_ceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
17687 gen_helper_msa_add_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
17689 case OPC_SUBS_S_df
:
17690 gen_helper_msa_subs_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17693 gen_helper_msa_mulv_df(cpu_env
, tdf
, twd
, tws
, twt
);
17696 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
17699 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
17702 gen_helper_msa_sra_df(cpu_env
, tdf
, twd
, tws
, twt
);
17705 gen_helper_msa_subv_df(cpu_env
, tdf
, twd
, tws
, twt
);
17707 case OPC_ADDS_A_df
:
17708 gen_helper_msa_adds_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
17710 case OPC_SUBS_U_df
:
17711 gen_helper_msa_subs_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17714 gen_helper_msa_maddv_df(cpu_env
, tdf
, twd
, tws
, twt
);
17717 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
17720 gen_helper_msa_srar_df(cpu_env
, tdf
, twd
, tws
, twt
);
17723 gen_helper_msa_srl_df(cpu_env
, tdf
, twd
, tws
, twt
);
17726 gen_helper_msa_max_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17729 gen_helper_msa_clt_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17731 case OPC_ADDS_S_df
:
17732 gen_helper_msa_adds_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17734 case OPC_SUBSUS_U_df
:
17735 gen_helper_msa_subsus_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17738 gen_helper_msa_msubv_df(cpu_env
, tdf
, twd
, tws
, twt
);
17741 gen_helper_msa_pckev_df(cpu_env
, tdf
, twd
, tws
, twt
);
17744 gen_helper_msa_srlr_df(cpu_env
, tdf
, twd
, tws
, twt
);
17747 gen_helper_msa_bclr_df(cpu_env
, tdf
, twd
, tws
, twt
);
17750 gen_helper_msa_max_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17753 gen_helper_msa_clt_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17755 case OPC_ADDS_U_df
:
17756 gen_helper_msa_adds_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17758 case OPC_SUBSUU_S_df
:
17759 gen_helper_msa_subsuu_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17762 gen_helper_msa_pckod_df(cpu_env
, tdf
, twd
, tws
, twt
);
17765 gen_helper_msa_bset_df(cpu_env
, tdf
, twd
, tws
, twt
);
17768 gen_helper_msa_min_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17771 gen_helper_msa_cle_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17774 gen_helper_msa_ave_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17776 case OPC_ASUB_S_df
:
17777 gen_helper_msa_asub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17780 gen_helper_msa_div_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17783 gen_helper_msa_ilvl_df(cpu_env
, tdf
, twd
, tws
, twt
);
17786 gen_helper_msa_bneg_df(cpu_env
, tdf
, twd
, tws
, twt
);
17789 gen_helper_msa_min_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17792 gen_helper_msa_cle_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17795 gen_helper_msa_ave_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17797 case OPC_ASUB_U_df
:
17798 gen_helper_msa_asub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17801 gen_helper_msa_div_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17804 gen_helper_msa_ilvr_df(cpu_env
, tdf
, twd
, tws
, twt
);
17807 gen_helper_msa_binsl_df(cpu_env
, tdf
, twd
, tws
, twt
);
17810 gen_helper_msa_max_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
17812 case OPC_AVER_S_df
:
17813 gen_helper_msa_aver_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17816 gen_helper_msa_mod_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17819 gen_helper_msa_ilvev_df(cpu_env
, tdf
, twd
, tws
, twt
);
17822 gen_helper_msa_binsr_df(cpu_env
, tdf
, twd
, tws
, twt
);
17825 gen_helper_msa_min_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
17827 case OPC_AVER_U_df
:
17828 gen_helper_msa_aver_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17831 gen_helper_msa_mod_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17834 gen_helper_msa_ilvod_df(cpu_env
, tdf
, twd
, tws
, twt
);
17837 case OPC_DOTP_S_df
:
17838 case OPC_DOTP_U_df
:
17839 case OPC_DPADD_S_df
:
17840 case OPC_DPADD_U_df
:
17841 case OPC_DPSUB_S_df
:
17842 case OPC_HADD_S_df
:
17843 case OPC_DPSUB_U_df
:
17844 case OPC_HADD_U_df
:
17845 case OPC_HSUB_S_df
:
17846 case OPC_HSUB_U_df
:
17847 if (df
== DF_BYTE
) {
17848 generate_exception(ctx
, EXCP_RI
);
17850 switch (MASK_MSA_3R(ctx
->opcode
)) {
17851 case OPC_DOTP_S_df
:
17852 gen_helper_msa_dotp_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17854 case OPC_DOTP_U_df
:
17855 gen_helper_msa_dotp_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17857 case OPC_DPADD_S_df
:
17858 gen_helper_msa_dpadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17860 case OPC_DPADD_U_df
:
17861 gen_helper_msa_dpadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17863 case OPC_DPSUB_S_df
:
17864 gen_helper_msa_dpsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17866 case OPC_HADD_S_df
:
17867 gen_helper_msa_hadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17869 case OPC_DPSUB_U_df
:
17870 gen_helper_msa_dpsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17872 case OPC_HADD_U_df
:
17873 gen_helper_msa_hadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17875 case OPC_HSUB_S_df
:
17876 gen_helper_msa_hsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
17878 case OPC_HSUB_U_df
:
17879 gen_helper_msa_hsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
17884 MIPS_INVAL("MSA instruction");
17885 generate_exception(ctx
, EXCP_RI
);
17888 tcg_temp_free_i32(twd
);
17889 tcg_temp_free_i32(tws
);
17890 tcg_temp_free_i32(twt
);
17891 tcg_temp_free_i32(tdf
);
17894 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
17896 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
17897 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
17898 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
17899 TCGv telm
= tcg_temp_new();
17900 TCGv_i32 tsr
= tcg_const_i32(source
);
17901 TCGv_i32 tdt
= tcg_const_i32(dest
);
17903 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
17905 gen_load_gpr(telm
, source
);
17906 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
17909 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
17910 gen_store_gpr(telm
, dest
);
17913 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
17916 MIPS_INVAL("MSA instruction");
17917 generate_exception(ctx
, EXCP_RI
);
17921 tcg_temp_free(telm
);
17922 tcg_temp_free_i32(tdt
);
17923 tcg_temp_free_i32(tsr
);
17926 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
17929 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
17930 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
17931 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
17933 TCGv_i32 tws
= tcg_const_i32(ws
);
17934 TCGv_i32 twd
= tcg_const_i32(wd
);
17935 TCGv_i32 tn
= tcg_const_i32(n
);
17936 TCGv_i32 tdf
= tcg_const_i32(df
);
17938 switch (MASK_MSA_ELM(ctx
->opcode
)) {
17940 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
17942 case OPC_SPLATI_df
:
17943 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
17946 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
17948 case OPC_COPY_S_df
:
17949 case OPC_COPY_U_df
:
17950 case OPC_INSERT_df
:
17951 #if !defined(TARGET_MIPS64)
17952 /* Double format valid only for MIPS64 */
17953 if (df
== DF_DOUBLE
) {
17954 generate_exception(ctx
, EXCP_RI
);
17958 switch (MASK_MSA_ELM(ctx
->opcode
)) {
17959 case OPC_COPY_S_df
:
17960 gen_helper_msa_copy_s_df(cpu_env
, tdf
, twd
, tws
, tn
);
17962 case OPC_COPY_U_df
:
17963 gen_helper_msa_copy_u_df(cpu_env
, tdf
, twd
, tws
, tn
);
17965 case OPC_INSERT_df
:
17966 gen_helper_msa_insert_df(cpu_env
, tdf
, twd
, tws
, tn
);
17971 MIPS_INVAL("MSA instruction");
17972 generate_exception(ctx
, EXCP_RI
);
17974 tcg_temp_free_i32(twd
);
17975 tcg_temp_free_i32(tws
);
17976 tcg_temp_free_i32(tn
);
17977 tcg_temp_free_i32(tdf
);
17980 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
17982 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
17983 uint32_t df
= 0, n
= 0;
17985 if ((dfn
& 0x30) == 0x00) {
17988 } else if ((dfn
& 0x38) == 0x20) {
17991 } else if ((dfn
& 0x3c) == 0x30) {
17994 } else if ((dfn
& 0x3e) == 0x38) {
17997 } else if (dfn
== 0x3E) {
17998 /* CTCMSA, CFCMSA, MOVE.V */
17999 gen_msa_elm_3e(env
, ctx
);
18002 generate_exception(ctx
, EXCP_RI
);
18006 gen_msa_elm_df(env
, ctx
, df
, n
);
18009 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
18011 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18012 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
18013 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18014 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18015 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18017 TCGv_i32 twd
= tcg_const_i32(wd
);
18018 TCGv_i32 tws
= tcg_const_i32(ws
);
18019 TCGv_i32 twt
= tcg_const_i32(wt
);
18020 TCGv_i32 tdf
= tcg_temp_new_i32();
18022 /* adjust df value for floating-point instruction */
18023 tcg_gen_movi_i32(tdf
, df
+ 2);
18025 switch (MASK_MSA_3RF(ctx
->opcode
)) {
18027 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18030 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
18033 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
18036 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
18039 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
18042 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18045 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
18048 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
18051 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18054 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18057 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
18060 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
18063 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
18066 tcg_gen_movi_i32(tdf
, df
+ 1);
18067 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18070 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
18073 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
18075 case OPC_MADD_Q_df
:
18076 tcg_gen_movi_i32(tdf
, df
+ 1);
18077 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18080 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
18082 case OPC_MSUB_Q_df
:
18083 tcg_gen_movi_i32(tdf
, df
+ 1);
18084 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18087 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
18090 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
18093 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18096 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
18099 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
18102 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
18105 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18108 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18111 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
18114 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18117 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
18120 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
18123 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
18125 case OPC_MULR_Q_df
:
18126 tcg_gen_movi_i32(tdf
, df
+ 1);
18127 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18130 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
18132 case OPC_FMIN_A_df
:
18133 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18135 case OPC_MADDR_Q_df
:
18136 tcg_gen_movi_i32(tdf
, df
+ 1);
18137 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18140 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
18143 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
18145 case OPC_MSUBR_Q_df
:
18146 tcg_gen_movi_i32(tdf
, df
+ 1);
18147 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18150 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
18152 case OPC_FMAX_A_df
:
18153 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18156 MIPS_INVAL("MSA instruction");
18157 generate_exception(ctx
, EXCP_RI
);
18161 tcg_temp_free_i32(twd
);
18162 tcg_temp_free_i32(tws
);
18163 tcg_temp_free_i32(twt
);
18164 tcg_temp_free_i32(tdf
);
18167 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
18169 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18170 (op & (0x7 << 18)))
18171 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18172 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18173 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18174 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
18175 TCGv_i32 twd
= tcg_const_i32(wd
);
18176 TCGv_i32 tws
= tcg_const_i32(ws
);
18177 TCGv_i32 twt
= tcg_const_i32(wt
);
18178 TCGv_i32 tdf
= tcg_const_i32(df
);
18180 switch (MASK_MSA_2R(ctx
->opcode
)) {
18182 #if !defined(TARGET_MIPS64)
18183 /* Double format valid only for MIPS64 */
18184 if (df
== DF_DOUBLE
) {
18185 generate_exception(ctx
, EXCP_RI
);
18189 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
18192 gen_helper_msa_pcnt_df(cpu_env
, tdf
, twd
, tws
);
18195 gen_helper_msa_nloc_df(cpu_env
, tdf
, twd
, tws
);
18198 gen_helper_msa_nlzc_df(cpu_env
, tdf
, twd
, tws
);
18201 MIPS_INVAL("MSA instruction");
18202 generate_exception(ctx
, EXCP_RI
);
18206 tcg_temp_free_i32(twd
);
18207 tcg_temp_free_i32(tws
);
18208 tcg_temp_free_i32(twt
);
18209 tcg_temp_free_i32(tdf
);
18212 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
18214 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18215 (op & (0xf << 17)))
18216 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18217 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18218 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18219 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
18220 TCGv_i32 twd
= tcg_const_i32(wd
);
18221 TCGv_i32 tws
= tcg_const_i32(ws
);
18222 TCGv_i32 twt
= tcg_const_i32(wt
);
18223 /* adjust df value for floating-point instruction */
18224 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
18226 switch (MASK_MSA_2RF(ctx
->opcode
)) {
18227 case OPC_FCLASS_df
:
18228 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
18230 case OPC_FTRUNC_S_df
:
18231 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
18233 case OPC_FTRUNC_U_df
:
18234 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
18237 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
18239 case OPC_FRSQRT_df
:
18240 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
18243 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
18246 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
18249 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
18251 case OPC_FEXUPL_df
:
18252 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
18254 case OPC_FEXUPR_df
:
18255 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
18258 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
18261 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
18263 case OPC_FTINT_S_df
:
18264 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
18266 case OPC_FTINT_U_df
:
18267 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
18269 case OPC_FFINT_S_df
:
18270 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
18272 case OPC_FFINT_U_df
:
18273 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
18277 tcg_temp_free_i32(twd
);
18278 tcg_temp_free_i32(tws
);
18279 tcg_temp_free_i32(twt
);
18280 tcg_temp_free_i32(tdf
);
18283 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
18285 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
18286 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18287 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18288 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18289 TCGv_i32 twd
= tcg_const_i32(wd
);
18290 TCGv_i32 tws
= tcg_const_i32(ws
);
18291 TCGv_i32 twt
= tcg_const_i32(wt
);
18293 switch (MASK_MSA_VEC(ctx
->opcode
)) {
18295 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
18298 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
18301 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
18304 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
18307 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
18310 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
18313 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
18316 MIPS_INVAL("MSA instruction");
18317 generate_exception(ctx
, EXCP_RI
);
18321 tcg_temp_free_i32(twd
);
18322 tcg_temp_free_i32(tws
);
18323 tcg_temp_free_i32(twt
);
18326 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
18328 switch (MASK_MSA_VEC(ctx
->opcode
)) {
18336 gen_msa_vec_v(env
, ctx
);
18339 gen_msa_2r(env
, ctx
);
18342 gen_msa_2rf(env
, ctx
);
18345 MIPS_INVAL("MSA instruction");
18346 generate_exception(ctx
, EXCP_RI
);
18351 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
18353 uint32_t opcode
= ctx
->opcode
;
18354 check_insn(ctx
, ASE_MSA
);
18355 check_msa_access(ctx
);
18357 switch (MASK_MSA_MINOR(opcode
)) {
18358 case OPC_MSA_I8_00
:
18359 case OPC_MSA_I8_01
:
18360 case OPC_MSA_I8_02
:
18361 gen_msa_i8(env
, ctx
);
18363 case OPC_MSA_I5_06
:
18364 case OPC_MSA_I5_07
:
18365 gen_msa_i5(env
, ctx
);
18367 case OPC_MSA_BIT_09
:
18368 case OPC_MSA_BIT_0A
:
18369 gen_msa_bit(env
, ctx
);
18371 case OPC_MSA_3R_0D
:
18372 case OPC_MSA_3R_0E
:
18373 case OPC_MSA_3R_0F
:
18374 case OPC_MSA_3R_10
:
18375 case OPC_MSA_3R_11
:
18376 case OPC_MSA_3R_12
:
18377 case OPC_MSA_3R_13
:
18378 case OPC_MSA_3R_14
:
18379 case OPC_MSA_3R_15
:
18380 gen_msa_3r(env
, ctx
);
18383 gen_msa_elm(env
, ctx
);
18385 case OPC_MSA_3RF_1A
:
18386 case OPC_MSA_3RF_1B
:
18387 case OPC_MSA_3RF_1C
:
18388 gen_msa_3rf(env
, ctx
);
18391 gen_msa_vec(env
, ctx
);
18402 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
18403 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
18404 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18405 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
18407 TCGv_i32 tdf
= tcg_const_i32(df
);
18408 TCGv_i32 twd
= tcg_const_i32(wd
);
18409 TCGv_i32 trs
= tcg_const_i32(rs
);
18410 TCGv_i32 ts10
= tcg_const_i32(s10
);
18412 switch (MASK_MSA_MINOR(opcode
)) {
18417 save_cpu_state(ctx
, 1);
18418 gen_helper_msa_ld_df(cpu_env
, tdf
, twd
, trs
, ts10
);
18424 save_cpu_state(ctx
, 1);
18425 gen_helper_msa_st_df(cpu_env
, tdf
, twd
, trs
, ts10
);
18429 tcg_temp_free_i32(twd
);
18430 tcg_temp_free_i32(tdf
);
18431 tcg_temp_free_i32(trs
);
18432 tcg_temp_free_i32(ts10
);
18436 MIPS_INVAL("MSA instruction");
18437 generate_exception(ctx
, EXCP_RI
);
18443 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
18446 int rs
, rt
, rd
, sa
;
18450 /* make sure instructions are on a word boundary */
18451 if (ctx
->pc
& 0x3) {
18452 env
->CP0_BadVAddr
= ctx
->pc
;
18453 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
18454 ctx
->bstate
= BS_STOP
;
18458 /* Handle blikely not taken case */
18459 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
18460 TCGLabel
*l1
= gen_new_label();
18462 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
18463 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
18464 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
18465 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
18469 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
18470 tcg_gen_debug_insn_start(ctx
->pc
);
18473 op
= MASK_OP_MAJOR(ctx
->opcode
);
18474 rs
= (ctx
->opcode
>> 21) & 0x1f;
18475 rt
= (ctx
->opcode
>> 16) & 0x1f;
18476 rd
= (ctx
->opcode
>> 11) & 0x1f;
18477 sa
= (ctx
->opcode
>> 6) & 0x1f;
18478 imm
= (int16_t)ctx
->opcode
;
18481 decode_opc_special(env
, ctx
);
18484 decode_opc_special2_legacy(env
, ctx
);
18487 decode_opc_special3(env
, ctx
);
18490 op1
= MASK_REGIMM(ctx
->opcode
);
18492 case OPC_BLTZL
: /* REGIMM branches */
18496 check_insn(ctx
, ISA_MIPS2
);
18497 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18501 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
18505 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18507 /* OPC_NAL, OPC_BAL */
18508 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
18510 generate_exception(ctx
, EXCP_RI
);
18513 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
18516 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
18518 check_insn(ctx
, ISA_MIPS2
);
18519 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18520 gen_trap(ctx
, op1
, rs
, -1, imm
);
18523 check_insn(ctx
, ISA_MIPS32R2
);
18524 /* Break the TB to be able to sync copied instructions
18526 ctx
->bstate
= BS_STOP
;
18528 case OPC_BPOSGE32
: /* MIPS DSP branch */
18529 #if defined(TARGET_MIPS64)
18533 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
18535 #if defined(TARGET_MIPS64)
18537 check_insn(ctx
, ISA_MIPS32R6
);
18538 check_mips_64(ctx
);
18540 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
18542 MIPS_DEBUG("dahi %s, %04x", regnames
[rs
], imm
);
18545 check_insn(ctx
, ISA_MIPS32R6
);
18546 check_mips_64(ctx
);
18548 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
18550 MIPS_DEBUG("dati %s, %04x", regnames
[rs
], imm
);
18553 default: /* Invalid */
18554 MIPS_INVAL("regimm");
18555 generate_exception(ctx
, EXCP_RI
);
18560 check_cp0_enabled(ctx
);
18561 op1
= MASK_CP0(ctx
->opcode
);
18567 #if defined(TARGET_MIPS64)
18571 #ifndef CONFIG_USER_ONLY
18572 gen_cp0(env
, ctx
, op1
, rt
, rd
);
18573 #endif /* !CONFIG_USER_ONLY */
18575 case OPC_C0_FIRST
... OPC_C0_LAST
:
18576 #ifndef CONFIG_USER_ONLY
18577 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
18578 #endif /* !CONFIG_USER_ONLY */
18581 #ifndef CONFIG_USER_ONLY
18584 TCGv t0
= tcg_temp_new();
18586 op2
= MASK_MFMC0(ctx
->opcode
);
18589 check_insn(ctx
, ASE_MT
);
18590 gen_helper_dmt(t0
);
18591 gen_store_gpr(t0
, rt
);
18594 check_insn(ctx
, ASE_MT
);
18595 gen_helper_emt(t0
);
18596 gen_store_gpr(t0
, rt
);
18599 check_insn(ctx
, ASE_MT
);
18600 gen_helper_dvpe(t0
, cpu_env
);
18601 gen_store_gpr(t0
, rt
);
18604 check_insn(ctx
, ASE_MT
);
18605 gen_helper_evpe(t0
, cpu_env
);
18606 gen_store_gpr(t0
, rt
);
18609 check_insn(ctx
, ISA_MIPS32R2
);
18610 save_cpu_state(ctx
, 1);
18611 gen_helper_di(t0
, cpu_env
);
18612 gen_store_gpr(t0
, rt
);
18613 /* Stop translation as we may have switched
18614 the execution mode. */
18615 ctx
->bstate
= BS_STOP
;
18618 check_insn(ctx
, ISA_MIPS32R2
);
18619 save_cpu_state(ctx
, 1);
18620 gen_helper_ei(t0
, cpu_env
);
18621 gen_store_gpr(t0
, rt
);
18622 /* Stop translation as we may have switched
18623 the execution mode. */
18624 ctx
->bstate
= BS_STOP
;
18626 default: /* Invalid */
18627 MIPS_INVAL("mfmc0");
18628 generate_exception(ctx
, EXCP_RI
);
18633 #endif /* !CONFIG_USER_ONLY */
18636 check_insn(ctx
, ISA_MIPS32R2
);
18637 gen_load_srsgpr(rt
, rd
);
18640 check_insn(ctx
, ISA_MIPS32R2
);
18641 gen_store_srsgpr(rt
, rd
);
18645 generate_exception(ctx
, EXCP_RI
);
18649 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
18650 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18651 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
18652 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
18655 /* Arithmetic with immediate opcode */
18656 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
18660 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
18662 case OPC_SLTI
: /* Set on less than with immediate opcode */
18664 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
18666 case OPC_ANDI
: /* Arithmetic with immediate opcode */
18667 case OPC_LUI
: /* OPC_AUI */
18670 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
18672 case OPC_J
... OPC_JAL
: /* Jump */
18673 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
18674 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
18677 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
18678 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18680 generate_exception(ctx
, EXCP_RI
);
18683 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
18684 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
18687 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
18690 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
18691 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18693 generate_exception(ctx
, EXCP_RI
);
18696 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
18697 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
18700 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
18703 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
18706 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
18708 check_insn(ctx
, ISA_MIPS32R6
);
18709 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
18710 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
18713 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
18716 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
18718 check_insn(ctx
, ISA_MIPS32R6
);
18719 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
18720 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
18725 check_insn(ctx
, ISA_MIPS2
);
18726 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18730 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
18732 case OPC_LL
: /* Load and stores */
18733 check_insn(ctx
, ISA_MIPS2
);
18737 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18739 case OPC_LB
... OPC_LH
:
18740 case OPC_LW
... OPC_LHU
:
18741 gen_ld(ctx
, op
, rt
, rs
, imm
);
18745 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18747 case OPC_SB
... OPC_SH
:
18749 gen_st(ctx
, op
, rt
, rs
, imm
);
18752 check_insn(ctx
, ISA_MIPS2
);
18753 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18754 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
18757 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18758 check_cp0_enabled(ctx
);
18759 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
18760 /* Treat as NOP. */
18763 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18764 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
18765 /* Treat as NOP. */
18768 /* Floating point (COP1). */
18773 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
18777 op1
= MASK_CP1(ctx
->opcode
);
18782 check_cp1_enabled(ctx
);
18783 check_insn(ctx
, ISA_MIPS32R2
);
18788 check_cp1_enabled(ctx
);
18789 gen_cp1(ctx
, op1
, rt
, rd
);
18791 #if defined(TARGET_MIPS64)
18794 check_cp1_enabled(ctx
);
18795 check_insn(ctx
, ISA_MIPS3
);
18796 check_mips_64(ctx
);
18797 gen_cp1(ctx
, op1
, rt
, rd
);
18800 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
18801 check_cp1_enabled(ctx
);
18802 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18804 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
18809 check_insn(ctx
, ASE_MIPS3D
);
18810 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
18811 (rt
>> 2) & 0x7, imm
<< 2);
18815 check_cp1_enabled(ctx
);
18816 check_insn(ctx
, ISA_MIPS32R6
);
18817 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
18821 check_cp1_enabled(ctx
);
18822 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18824 check_insn(ctx
, ASE_MIPS3D
);
18827 check_cp1_enabled(ctx
);
18828 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18829 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
18830 (rt
>> 2) & 0x7, imm
<< 2);
18833 check_cp1_enabled(ctx
);
18834 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18838 check_cp1_enabled(ctx
);
18839 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
18845 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
18846 check_cp1_enabled(ctx
);
18847 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18849 case R6_OPC_CMP_AF_S
:
18850 case R6_OPC_CMP_UN_S
:
18851 case R6_OPC_CMP_EQ_S
:
18852 case R6_OPC_CMP_UEQ_S
:
18853 case R6_OPC_CMP_LT_S
:
18854 case R6_OPC_CMP_ULT_S
:
18855 case R6_OPC_CMP_LE_S
:
18856 case R6_OPC_CMP_ULE_S
:
18857 case R6_OPC_CMP_SAF_S
:
18858 case R6_OPC_CMP_SUN_S
:
18859 case R6_OPC_CMP_SEQ_S
:
18860 case R6_OPC_CMP_SEUQ_S
:
18861 case R6_OPC_CMP_SLT_S
:
18862 case R6_OPC_CMP_SULT_S
:
18863 case R6_OPC_CMP_SLE_S
:
18864 case R6_OPC_CMP_SULE_S
:
18865 case R6_OPC_CMP_OR_S
:
18866 case R6_OPC_CMP_UNE_S
:
18867 case R6_OPC_CMP_NE_S
:
18868 case R6_OPC_CMP_SOR_S
:
18869 case R6_OPC_CMP_SUNE_S
:
18870 case R6_OPC_CMP_SNE_S
:
18871 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
18873 case R6_OPC_CMP_AF_D
:
18874 case R6_OPC_CMP_UN_D
:
18875 case R6_OPC_CMP_EQ_D
:
18876 case R6_OPC_CMP_UEQ_D
:
18877 case R6_OPC_CMP_LT_D
:
18878 case R6_OPC_CMP_ULT_D
:
18879 case R6_OPC_CMP_LE_D
:
18880 case R6_OPC_CMP_ULE_D
:
18881 case R6_OPC_CMP_SAF_D
:
18882 case R6_OPC_CMP_SUN_D
:
18883 case R6_OPC_CMP_SEQ_D
:
18884 case R6_OPC_CMP_SEUQ_D
:
18885 case R6_OPC_CMP_SLT_D
:
18886 case R6_OPC_CMP_SULT_D
:
18887 case R6_OPC_CMP_SLE_D
:
18888 case R6_OPC_CMP_SULE_D
:
18889 case R6_OPC_CMP_OR_D
:
18890 case R6_OPC_CMP_UNE_D
:
18891 case R6_OPC_CMP_NE_D
:
18892 case R6_OPC_CMP_SOR_D
:
18893 case R6_OPC_CMP_SUNE_D
:
18894 case R6_OPC_CMP_SNE_D
:
18895 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
18898 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
18899 rt
, rd
, sa
, (imm
>> 8) & 0x7);
18904 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
18919 check_insn(ctx
, ASE_MSA
);
18920 gen_msa_branch(env
, ctx
, op1
);
18924 generate_exception(ctx
, EXCP_RI
);
18929 /* Compact branches [R6] and COP2 [non-R6] */
18930 case OPC_BC
: /* OPC_LWC2 */
18931 case OPC_BALC
: /* OPC_SWC2 */
18932 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18933 /* OPC_BC, OPC_BALC */
18934 gen_compute_compact_branch(ctx
, op
, 0, 0,
18935 sextract32(ctx
->opcode
<< 2, 0, 28));
18937 /* OPC_LWC2, OPC_SWC2 */
18938 /* COP2: Not implemented. */
18939 generate_exception_err(ctx
, EXCP_CpU
, 2);
18942 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
18943 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
18944 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18946 /* OPC_BEQZC, OPC_BNEZC */
18947 gen_compute_compact_branch(ctx
, op
, rs
, 0,
18948 sextract32(ctx
->opcode
<< 2, 0, 23));
18950 /* OPC_JIC, OPC_JIALC */
18951 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
18954 /* OPC_LWC2, OPC_SWC2 */
18955 /* COP2: Not implemented. */
18956 generate_exception_err(ctx
, EXCP_CpU
, 2);
18960 check_insn(ctx
, INSN_LOONGSON2F
);
18961 /* Note that these instructions use different fields. */
18962 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
18966 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18967 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
18968 check_cp1_enabled(ctx
);
18969 op1
= MASK_CP3(ctx
->opcode
);
18973 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
18979 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
18980 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
18983 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
18984 /* Treat as NOP. */
18987 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
19001 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
19002 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
19006 generate_exception (ctx
, EXCP_RI
);
19010 generate_exception_err(ctx
, EXCP_CpU
, 1);
19014 #if defined(TARGET_MIPS64)
19015 /* MIPS64 opcodes */
19016 case OPC_LDL
... OPC_LDR
:
19018 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19022 check_insn(ctx
, ISA_MIPS3
);
19023 check_mips_64(ctx
);
19024 gen_ld(ctx
, op
, rt
, rs
, imm
);
19026 case OPC_SDL
... OPC_SDR
:
19027 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19030 check_insn(ctx
, ISA_MIPS3
);
19031 check_mips_64(ctx
);
19032 gen_st(ctx
, op
, rt
, rs
, imm
);
19035 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19036 check_insn(ctx
, ISA_MIPS3
);
19037 check_mips_64(ctx
);
19038 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
19040 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19041 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19042 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19043 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19046 check_insn(ctx
, ISA_MIPS3
);
19047 check_mips_64(ctx
);
19048 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19052 check_insn(ctx
, ISA_MIPS3
);
19053 check_mips_64(ctx
);
19054 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19057 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
19058 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19059 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19061 MIPS_INVAL("major opcode");
19062 generate_exception(ctx
, EXCP_RI
);
19066 case OPC_DAUI
: /* OPC_JALX */
19067 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19068 #if defined(TARGET_MIPS64)
19070 check_mips_64(ctx
);
19072 TCGv t0
= tcg_temp_new();
19073 gen_load_gpr(t0
, rs
);
19074 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
19077 MIPS_DEBUG("daui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
19079 generate_exception(ctx
, EXCP_RI
);
19080 MIPS_INVAL("major opcode");
19084 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
19085 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
19086 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
19089 case OPC_MSA
: /* OPC_MDMX */
19090 /* MDMX: Not implemented. */
19094 check_insn(ctx
, ISA_MIPS32R6
);
19095 gen_pcrel(ctx
, rs
, imm
);
19097 default: /* Invalid */
19098 MIPS_INVAL("major opcode");
19099 generate_exception(ctx
, EXCP_RI
);
19105 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
19108 CPUState
*cs
= CPU(cpu
);
19109 CPUMIPSState
*env
= &cpu
->env
;
19111 target_ulong pc_start
;
19112 target_ulong next_page_start
;
19121 qemu_log("search pc %d\n", search_pc
);
19124 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
19127 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
19128 ctx
.insn_flags
= env
->insn_flags
;
19129 ctx
.CP0_Config1
= env
->CP0_Config1
;
19131 ctx
.bstate
= BS_NONE
;
19132 ctx
.kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
19133 ctx
.rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
19134 ctx
.ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
19135 ctx
.bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
19136 ctx
.bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
19137 /* Restore delay slot state from the tb context. */
19138 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
19139 ctx
.ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
19140 restore_cpu_state(env
, &ctx
);
19141 #ifdef CONFIG_USER_ONLY
19142 ctx
.mem_idx
= MIPS_HFLAG_UM
;
19144 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
19147 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
19148 if (max_insns
== 0)
19149 max_insns
= CF_COUNT_MASK
;
19150 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
19152 while (ctx
.bstate
== BS_NONE
) {
19153 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
19154 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
19155 if (bp
->pc
== ctx
.pc
) {
19156 save_cpu_state(&ctx
, 1);
19157 ctx
.bstate
= BS_BRANCH
;
19158 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
19159 /* Include the breakpoint location or the tb won't
19160 * be flushed when it must be. */
19162 goto done_generating
;
19168 j
= tcg_op_buf_count();
19172 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
19174 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
19175 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
19176 gen_opc_btarget
[lj
] = ctx
.btarget
;
19177 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
19178 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
19180 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
19183 is_slot
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
19184 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
19185 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
19187 decode_opc(env
, &ctx
);
19188 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
19189 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
19190 insn_bytes
= decode_micromips_opc(env
, &ctx
);
19191 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
19192 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
19193 insn_bytes
= decode_mips16_opc(env
, &ctx
);
19195 generate_exception(&ctx
, EXCP_RI
);
19196 ctx
.bstate
= BS_STOP
;
19200 if (ctx
.hflags
& MIPS_HFLAG_BMASK
) {
19201 if (!(ctx
.hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
19202 MIPS_HFLAG_FBNSLOT
))) {
19203 /* force to generate branch as there is neither delay nor
19209 gen_branch(&ctx
, insn_bytes
);
19211 ctx
.pc
+= insn_bytes
;
19215 /* Execute a branch and its delay slot as a single instruction.
19216 This is what GDB expects and is consistent with what the
19217 hardware does (e.g. if a delay slot instruction faults, the
19218 reported PC is the PC of the branch). */
19219 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
19223 if (ctx
.pc
>= next_page_start
) {
19227 if (tcg_op_buf_full()) {
19231 if (num_insns
>= max_insns
)
19237 if (tb
->cflags
& CF_LAST_IO
) {
19240 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
19241 save_cpu_state(&ctx
, ctx
.bstate
!= BS_EXCP
);
19242 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
19244 switch (ctx
.bstate
) {
19246 gen_goto_tb(&ctx
, 0, ctx
.pc
);
19249 save_cpu_state(&ctx
, 0);
19250 gen_goto_tb(&ctx
, 0, ctx
.pc
);
19253 tcg_gen_exit_tb(0);
19261 gen_tb_end(tb
, num_insns
);
19264 j
= tcg_op_buf_count();
19267 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
19269 tb
->size
= ctx
.pc
- pc_start
;
19270 tb
->icount
= num_insns
;
19274 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
19275 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
19276 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
19282 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
19284 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
19287 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
19289 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
19292 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
19296 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
19298 #define printfpr(fp) \
19301 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19302 " fd:%13g fs:%13g psu: %13g\n", \
19303 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
19304 (double)(fp)->fd, \
19305 (double)(fp)->fs[FP_ENDIAN_IDX], \
19306 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
19309 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
19310 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
19311 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
19312 " fd:%13g fs:%13g psu:%13g\n", \
19313 tmp.w[FP_ENDIAN_IDX], tmp.d, \
19315 (double)tmp.fs[FP_ENDIAN_IDX], \
19316 (double)tmp.fs[!FP_ENDIAN_IDX]); \
19321 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
19322 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
19323 get_float_exception_flags(&env
->active_fpu
.fp_status
));
19324 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
19325 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
19326 printfpr(&env
->active_fpu
.fpr
[i
]);
19332 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
19333 /* Debug help: The architecture requires 32bit code to maintain proper
19334 sign-extended values on 64bit machines. */
19336 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
19339 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
19340 fprintf_function cpu_fprintf
,
19345 if (!SIGN_EXT_P(env
->active_tc
.PC
))
19346 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
19347 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
19348 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
19349 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
19350 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
19351 if (!SIGN_EXT_P(env
->btarget
))
19352 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
19354 for (i
= 0; i
< 32; i
++) {
19355 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
19356 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
19359 if (!SIGN_EXT_P(env
->CP0_EPC
))
19360 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
19361 if (!SIGN_EXT_P(env
->lladdr
))
19362 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
19366 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
19369 MIPSCPU
*cpu
= MIPS_CPU(cs
);
19370 CPUMIPSState
*env
= &cpu
->env
;
19373 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
19374 " LO=0x" TARGET_FMT_lx
" ds %04x "
19375 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
19376 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
19377 env
->hflags
, env
->btarget
, env
->bcond
);
19378 for (i
= 0; i
< 32; i
++) {
19380 cpu_fprintf(f
, "GPR%02d:", i
);
19381 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
19383 cpu_fprintf(f
, "\n");
19386 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
19387 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
19388 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
19389 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
19390 cpu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
19391 env
->CP0_Config2
, env
->CP0_Config3
);
19392 cpu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
19393 env
->CP0_Config4
, env
->CP0_Config5
);
19394 if (env
->hflags
& MIPS_HFLAG_FPU
)
19395 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
19396 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
19397 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
19401 void mips_tcg_init(void)
19406 /* Initialize various static tables. */
19410 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
19411 TCGV_UNUSED(cpu_gpr
[0]);
19412 for (i
= 1; i
< 32; i
++)
19413 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
19414 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
19417 for (i
= 0; i
< 32; i
++) {
19418 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
19420 tcg_global_mem_new_i64(TCG_AREG0
, off
, msaregnames
[i
* 2]);
19421 /* The scalar floating-point unit (FPU) registers are mapped on
19422 * the MSA vector registers. */
19423 fpu_f64
[i
] = msa_wr_d
[i
* 2];
19424 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
19425 msa_wr_d
[i
* 2 + 1] =
19426 tcg_global_mem_new_i64(TCG_AREG0
, off
, msaregnames
[i
* 2 + 1]);
19429 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
19430 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
19431 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
19432 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
19433 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
19435 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
19436 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
19439 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
19440 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
19442 bcond
= tcg_global_mem_new(TCG_AREG0
,
19443 offsetof(CPUMIPSState
, bcond
), "bcond");
19444 btarget
= tcg_global_mem_new(TCG_AREG0
,
19445 offsetof(CPUMIPSState
, btarget
), "btarget");
19446 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
19447 offsetof(CPUMIPSState
, hflags
), "hflags");
19449 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
19450 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
19452 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
19453 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
19459 #include "translate_init.c"
19461 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
19465 const mips_def_t
*def
;
19467 def
= cpu_mips_find_by_name(cpu_model
);
19470 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
19472 env
->cpu_model
= def
;
19474 #ifndef CONFIG_USER_ONLY
19475 mmu_init(env
, def
);
19477 fpu_init(env
, def
);
19478 mvp_init(env
, def
);
19480 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
19485 void cpu_state_reset(CPUMIPSState
*env
)
19487 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
19488 CPUState
*cs
= CPU(cpu
);
19490 /* Reset registers to their default values */
19491 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
19492 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
19493 #ifdef TARGET_WORDS_BIGENDIAN
19494 env
->CP0_Config0
|= (1 << CP0C0_BE
);
19496 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
19497 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
19498 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
19499 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
19500 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
19501 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
19502 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
19503 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
19504 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
19505 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
19506 << env
->cpu_model
->CP0_LLAddr_shift
;
19507 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
19508 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
19509 env
->CCRes
= env
->cpu_model
->CCRes
;
19510 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
19511 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
19512 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
19513 env
->current_tc
= 0;
19514 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
19515 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
19516 #if defined(TARGET_MIPS64)
19517 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
19518 env
->SEGMask
|= 3ULL << 62;
19521 env
->PABITS
= env
->cpu_model
->PABITS
;
19522 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
19523 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
19524 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
19525 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
19526 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
19527 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
19528 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
19529 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
19530 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
19531 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
19532 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
19533 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
19534 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
19535 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
19536 env
->msair
= env
->cpu_model
->MSAIR
;
19537 env
->insn_flags
= env
->cpu_model
->insn_flags
;
19539 #if defined(CONFIG_USER_ONLY)
19540 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
19541 # ifdef TARGET_MIPS64
19542 /* Enable 64-bit register mode. */
19543 env
->CP0_Status
|= (1 << CP0St_PX
);
19545 # ifdef TARGET_ABI_MIPSN64
19546 /* Enable 64-bit address mode. */
19547 env
->CP0_Status
|= (1 << CP0St_UX
);
19549 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
19550 hardware registers. */
19551 env
->CP0_HWREna
|= 0x0000000F;
19552 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
19553 env
->CP0_Status
|= (1 << CP0St_CU1
);
19555 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
19556 env
->CP0_Status
|= (1 << CP0St_MX
);
19558 # if defined(TARGET_MIPS64)
19559 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
19560 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
19561 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
19562 env
->CP0_Status
|= (1 << CP0St_FR
);
19566 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
19567 /* If the exception was raised from a delay slot,
19568 come back to the jump. */
19569 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
19570 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
19572 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
19574 env
->active_tc
.PC
= (int32_t)0xBFC00000;
19575 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
19576 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
19577 env
->CP0_Wired
= 0;
19578 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
19579 if (kvm_enabled()) {
19580 env
->CP0_EBase
|= 0x40000000;
19582 env
->CP0_EBase
|= 0x80000000;
19584 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
19585 /* vectored interrupts not implemented, timer on int 7,
19586 no performance counters. */
19587 env
->CP0_IntCtl
= 0xe0000000;
19591 for (i
= 0; i
< 7; i
++) {
19592 env
->CP0_WatchLo
[i
] = 0;
19593 env
->CP0_WatchHi
[i
] = 0x80000000;
19595 env
->CP0_WatchLo
[7] = 0;
19596 env
->CP0_WatchHi
[7] = 0;
19598 /* Count register increments in debug mode, EJTAG version 1 */
19599 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
19601 cpu_mips_store_count(env
, 1);
19603 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
19606 /* Only TC0 on VPE 0 starts as active. */
19607 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
19608 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
19609 env
->tcs
[i
].CP0_TCHalt
= 1;
19611 env
->active_tc
.CP0_TCHalt
= 1;
19614 if (cs
->cpu_index
== 0) {
19615 /* VPE0 starts up enabled. */
19616 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
19617 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
19619 /* TC0 starts up unhalted. */
19621 env
->active_tc
.CP0_TCHalt
= 0;
19622 env
->tcs
[0].CP0_TCHalt
= 0;
19623 /* With thread 0 active. */
19624 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
19625 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
19629 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
19630 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
19631 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
19632 env
->CP0_Status
|= (1 << CP0St_FR
);
19636 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
19640 compute_hflags(env
);
19641 restore_rounding_mode(env
);
19642 restore_flush_mode(env
);
19643 cs
->exception_index
= EXCP_NONE
;
19646 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
19648 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
19649 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
19650 env
->hflags
|= gen_opc_hflags
[pc_pos
];
19651 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
19652 case MIPS_HFLAG_BR
:
19654 case MIPS_HFLAG_BC
:
19655 case MIPS_HFLAG_BL
:
19657 env
->btarget
= gen_opc_btarget
[pc_pos
];