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(); \
1887 check_cp1_registers(ctx, fs | ft | fd); \
1890 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1891 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1894 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1897 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1900 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1903 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1906 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1909 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1912 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1915 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1918 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1921 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1924 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1927 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1930 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1933 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1936 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1939 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1942 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1945 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1948 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1951 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1954 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1957 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1963 tcg_temp_free_i ## bits (fp0); \
1964 tcg_temp_free_i ## bits (fp1); \
1967 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
1968 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(fp0
, fd
))
1970 #undef gen_ldcmp_fpr32
1971 #undef gen_ldcmp_fpr64
1973 /* load/store instructions. */
1974 #ifdef CONFIG_USER_ONLY
1975 #define OP_LD_ATOMIC(insn,fname) \
1976 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1978 TCGv t0 = tcg_temp_new(); \
1979 tcg_gen_mov_tl(t0, arg1); \
1980 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1981 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1982 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1983 tcg_temp_free(t0); \
1986 #define OP_LD_ATOMIC(insn,fname) \
1987 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1989 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1992 OP_LD_ATOMIC(ll
,ld32s
);
1993 #if defined(TARGET_MIPS64)
1994 OP_LD_ATOMIC(lld
,ld64
);
1998 #ifdef CONFIG_USER_ONLY
1999 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2000 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2002 TCGv t0 = tcg_temp_new(); \
2003 int l1 = gen_new_label(); \
2004 int l2 = gen_new_label(); \
2006 tcg_gen_andi_tl(t0, arg2, almask); \
2007 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2008 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2009 generate_exception(ctx, EXCP_AdES); \
2010 gen_set_label(l1); \
2011 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2012 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2013 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2014 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2015 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2016 gen_helper_0e0i(raise_exception, EXCP_SC); \
2017 gen_set_label(l2); \
2018 tcg_gen_movi_tl(t0, 0); \
2019 gen_store_gpr(t0, rt); \
2020 tcg_temp_free(t0); \
2023 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2024 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2026 TCGv t0 = tcg_temp_new(); \
2027 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2028 gen_store_gpr(t0, rt); \
2029 tcg_temp_free(t0); \
2032 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
2033 #if defined(TARGET_MIPS64)
2034 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
2038 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
2039 int base
, int16_t offset
)
2042 tcg_gen_movi_tl(addr
, offset
);
2043 } else if (offset
== 0) {
2044 gen_load_gpr(addr
, base
);
2046 tcg_gen_movi_tl(addr
, offset
);
2047 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2051 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
2053 target_ulong pc
= ctx
->pc
;
2055 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2056 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2061 pc
&= ~(target_ulong
)3;
2066 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2067 int rt
, int base
, int16_t offset
)
2069 const char *opn
= "ld";
2072 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
2073 /* Loongson CPU uses a load to zero register for prefetch.
2074 We emulate it as a NOP. On other CPU we must perform the
2075 actual memory access. */
2080 t0
= tcg_temp_new();
2081 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2084 #if defined(TARGET_MIPS64)
2086 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2087 gen_store_gpr(t0
, rt
);
2091 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2092 gen_store_gpr(t0
, rt
);
2097 save_cpu_state(ctx
, 1);
2098 op_ld_lld(t0
, t0
, ctx
);
2099 gen_store_gpr(t0
, rt
);
2103 t1
= tcg_temp_new();
2104 tcg_gen_andi_tl(t1
, t0
, 7);
2105 #ifndef TARGET_WORDS_BIGENDIAN
2106 tcg_gen_xori_tl(t1
, t1
, 7);
2108 tcg_gen_shli_tl(t1
, t1
, 3);
2109 tcg_gen_andi_tl(t0
, t0
, ~7);
2110 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2111 tcg_gen_shl_tl(t0
, t0
, t1
);
2112 tcg_gen_xori_tl(t1
, t1
, 63);
2113 t2
= tcg_const_tl(0x7fffffffffffffffull
);
2114 tcg_gen_shr_tl(t2
, t2
, t1
);
2115 gen_load_gpr(t1
, rt
);
2116 tcg_gen_and_tl(t1
, t1
, t2
);
2118 tcg_gen_or_tl(t0
, t0
, t1
);
2120 gen_store_gpr(t0
, rt
);
2124 t1
= tcg_temp_new();
2125 tcg_gen_andi_tl(t1
, t0
, 7);
2126 #ifdef TARGET_WORDS_BIGENDIAN
2127 tcg_gen_xori_tl(t1
, t1
, 7);
2129 tcg_gen_shli_tl(t1
, t1
, 3);
2130 tcg_gen_andi_tl(t0
, t0
, ~7);
2131 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2132 tcg_gen_shr_tl(t0
, t0
, t1
);
2133 tcg_gen_xori_tl(t1
, t1
, 63);
2134 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2135 tcg_gen_shl_tl(t2
, t2
, t1
);
2136 gen_load_gpr(t1
, rt
);
2137 tcg_gen_and_tl(t1
, t1
, t2
);
2139 tcg_gen_or_tl(t0
, t0
, t1
);
2141 gen_store_gpr(t0
, rt
);
2145 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2146 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2148 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2149 gen_store_gpr(t0
, rt
);
2154 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2155 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2157 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
2158 gen_store_gpr(t0
, rt
);
2162 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
2163 gen_store_gpr(t0
, rt
);
2167 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
2168 gen_store_gpr(t0
, rt
);
2172 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
2173 gen_store_gpr(t0
, rt
);
2177 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
2178 gen_store_gpr(t0
, rt
);
2182 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
2183 gen_store_gpr(t0
, rt
);
2187 t1
= tcg_temp_new();
2188 tcg_gen_andi_tl(t1
, t0
, 3);
2189 #ifndef TARGET_WORDS_BIGENDIAN
2190 tcg_gen_xori_tl(t1
, t1
, 3);
2192 tcg_gen_shli_tl(t1
, t1
, 3);
2193 tcg_gen_andi_tl(t0
, t0
, ~3);
2194 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2195 tcg_gen_shl_tl(t0
, t0
, t1
);
2196 tcg_gen_xori_tl(t1
, t1
, 31);
2197 t2
= tcg_const_tl(0x7fffffffull
);
2198 tcg_gen_shr_tl(t2
, t2
, t1
);
2199 gen_load_gpr(t1
, rt
);
2200 tcg_gen_and_tl(t1
, t1
, t2
);
2202 tcg_gen_or_tl(t0
, t0
, t1
);
2204 tcg_gen_ext32s_tl(t0
, t0
);
2205 gen_store_gpr(t0
, rt
);
2209 t1
= tcg_temp_new();
2210 tcg_gen_andi_tl(t1
, t0
, 3);
2211 #ifdef TARGET_WORDS_BIGENDIAN
2212 tcg_gen_xori_tl(t1
, t1
, 3);
2214 tcg_gen_shli_tl(t1
, t1
, 3);
2215 tcg_gen_andi_tl(t0
, t0
, ~3);
2216 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2217 tcg_gen_shr_tl(t0
, t0
, t1
);
2218 tcg_gen_xori_tl(t1
, t1
, 31);
2219 t2
= tcg_const_tl(0xfffffffeull
);
2220 tcg_gen_shl_tl(t2
, t2
, t1
);
2221 gen_load_gpr(t1
, rt
);
2222 tcg_gen_and_tl(t1
, t1
, t2
);
2224 tcg_gen_or_tl(t0
, t0
, t1
);
2226 tcg_gen_ext32s_tl(t0
, t0
);
2227 gen_store_gpr(t0
, rt
);
2232 save_cpu_state(ctx
, 1);
2233 op_ld_ll(t0
, t0
, ctx
);
2234 gen_store_gpr(t0
, rt
);
2238 (void)opn
; /* avoid a compiler warning */
2239 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2244 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
2245 int base
, int16_t offset
)
2247 const char *opn
= "st";
2248 TCGv t0
= tcg_temp_new();
2249 TCGv t1
= tcg_temp_new();
2251 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2252 gen_load_gpr(t1
, rt
);
2254 #if defined(TARGET_MIPS64)
2256 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
2260 save_cpu_state(ctx
, 1);
2261 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
2265 save_cpu_state(ctx
, 1);
2266 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
2271 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
2275 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
2279 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
2283 save_cpu_state(ctx
, 1);
2284 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
2288 save_cpu_state(ctx
, 1);
2289 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
2293 (void)opn
; /* avoid a compiler warning */
2294 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2300 /* Store conditional */
2301 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
2302 int base
, int16_t offset
)
2304 const char *opn
= "st_cond";
2307 #ifdef CONFIG_USER_ONLY
2308 t0
= tcg_temp_local_new();
2309 t1
= tcg_temp_local_new();
2311 t0
= tcg_temp_new();
2312 t1
= tcg_temp_new();
2314 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2315 gen_load_gpr(t1
, rt
);
2317 #if defined(TARGET_MIPS64)
2320 save_cpu_state(ctx
, 1);
2321 op_st_scd(t1
, t0
, rt
, ctx
);
2327 save_cpu_state(ctx
, 1);
2328 op_st_sc(t1
, t0
, rt
, ctx
);
2332 (void)opn
; /* avoid a compiler warning */
2333 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2338 /* Load and store */
2339 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
2340 int base
, int16_t offset
)
2342 const char *opn
= "flt_ldst";
2343 TCGv t0
= tcg_temp_new();
2345 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2346 /* Don't do NOP if destination is zero: we must perform the actual
2351 TCGv_i32 fp0
= tcg_temp_new_i32();
2352 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
2353 gen_store_fpr32(fp0
, ft
);
2354 tcg_temp_free_i32(fp0
);
2360 TCGv_i32 fp0
= tcg_temp_new_i32();
2361 gen_load_fpr32(fp0
, ft
);
2362 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2363 tcg_temp_free_i32(fp0
);
2369 TCGv_i64 fp0
= tcg_temp_new_i64();
2370 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2371 gen_store_fpr64(ctx
, fp0
, ft
);
2372 tcg_temp_free_i64(fp0
);
2378 TCGv_i64 fp0
= tcg_temp_new_i64();
2379 gen_load_fpr64(ctx
, fp0
, ft
);
2380 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2381 tcg_temp_free_i64(fp0
);
2387 generate_exception(ctx
, EXCP_RI
);
2390 (void)opn
; /* avoid a compiler warning */
2391 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
2396 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2397 int rs
, int16_t imm
)
2399 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2400 check_cp1_enabled(ctx
);
2401 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
2403 generate_exception_err(ctx
, EXCP_CpU
, 1);
2407 /* Arithmetic with immediate operand */
2408 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2409 int rt
, int rs
, int16_t imm
)
2411 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2412 const char *opn
= "imm arith";
2414 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2415 /* If no destination, treat it as a NOP.
2416 For addi, we must generate the overflow exception when needed. */
2423 TCGv t0
= tcg_temp_local_new();
2424 TCGv t1
= tcg_temp_new();
2425 TCGv t2
= tcg_temp_new();
2426 int l1
= gen_new_label();
2428 gen_load_gpr(t1
, rs
);
2429 tcg_gen_addi_tl(t0
, t1
, uimm
);
2430 tcg_gen_ext32s_tl(t0
, t0
);
2432 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2433 tcg_gen_xori_tl(t2
, t0
, uimm
);
2434 tcg_gen_and_tl(t1
, t1
, t2
);
2436 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2438 /* operands of same sign, result different sign */
2439 generate_exception(ctx
, EXCP_OVERFLOW
);
2441 tcg_gen_ext32s_tl(t0
, t0
);
2442 gen_store_gpr(t0
, rt
);
2449 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2450 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2452 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2456 #if defined(TARGET_MIPS64)
2459 TCGv t0
= tcg_temp_local_new();
2460 TCGv t1
= tcg_temp_new();
2461 TCGv t2
= tcg_temp_new();
2462 int l1
= gen_new_label();
2464 gen_load_gpr(t1
, rs
);
2465 tcg_gen_addi_tl(t0
, t1
, uimm
);
2467 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2468 tcg_gen_xori_tl(t2
, t0
, uimm
);
2469 tcg_gen_and_tl(t1
, t1
, t2
);
2471 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2473 /* operands of same sign, result different sign */
2474 generate_exception(ctx
, EXCP_OVERFLOW
);
2476 gen_store_gpr(t0
, rt
);
2483 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2485 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2491 (void)opn
; /* avoid a compiler warning */
2492 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2495 /* Logic with immediate operand */
2496 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2497 int rt
, int rs
, int16_t imm
)
2502 /* If no destination, treat it as a NOP. */
2506 uimm
= (uint16_t)imm
;
2509 if (likely(rs
!= 0))
2510 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2512 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2513 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2514 regnames
[rs
], uimm
);
2518 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2520 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2521 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2522 regnames
[rs
], uimm
);
2525 if (likely(rs
!= 0))
2526 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2528 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2529 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2530 regnames
[rs
], uimm
);
2533 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
2535 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2536 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2537 MIPS_DEBUG("aui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
2539 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2540 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2545 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2550 /* Set on less than with immediate operand */
2551 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2552 int rt
, int rs
, int16_t imm
)
2554 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2555 const char *opn
= "imm arith";
2559 /* If no destination, treat it as a NOP. */
2563 t0
= tcg_temp_new();
2564 gen_load_gpr(t0
, rs
);
2567 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2571 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2575 (void)opn
; /* avoid a compiler warning */
2576 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2580 /* Shifts with immediate operand */
2581 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2582 int rt
, int rs
, int16_t imm
)
2584 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2585 const char *opn
= "imm shift";
2589 /* If no destination, treat it as a NOP. */
2594 t0
= tcg_temp_new();
2595 gen_load_gpr(t0
, rs
);
2598 tcg_gen_shli_tl(t0
, t0
, uimm
);
2599 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2603 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2608 tcg_gen_ext32u_tl(t0
, t0
);
2609 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2611 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2617 TCGv_i32 t1
= tcg_temp_new_i32();
2619 tcg_gen_trunc_tl_i32(t1
, t0
);
2620 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2621 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2622 tcg_temp_free_i32(t1
);
2624 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2628 #if defined(TARGET_MIPS64)
2630 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2634 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2638 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2643 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2645 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2650 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2654 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2658 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2662 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2667 (void)opn
; /* avoid a compiler warning */
2668 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2673 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2674 int rd
, int rs
, int rt
)
2676 const char *opn
= "arith";
2678 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2679 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2680 /* If no destination, treat it as a NOP.
2681 For add & sub, we must generate the overflow exception when needed. */
2689 TCGv t0
= tcg_temp_local_new();
2690 TCGv t1
= tcg_temp_new();
2691 TCGv t2
= tcg_temp_new();
2692 int l1
= gen_new_label();
2694 gen_load_gpr(t1
, rs
);
2695 gen_load_gpr(t2
, rt
);
2696 tcg_gen_add_tl(t0
, t1
, t2
);
2697 tcg_gen_ext32s_tl(t0
, t0
);
2698 tcg_gen_xor_tl(t1
, t1
, t2
);
2699 tcg_gen_xor_tl(t2
, t0
, t2
);
2700 tcg_gen_andc_tl(t1
, t2
, t1
);
2702 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2704 /* operands of same sign, result different sign */
2705 generate_exception(ctx
, EXCP_OVERFLOW
);
2707 gen_store_gpr(t0
, rd
);
2713 if (rs
!= 0 && rt
!= 0) {
2714 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2715 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2716 } else if (rs
== 0 && rt
!= 0) {
2717 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2718 } else if (rs
!= 0 && rt
== 0) {
2719 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2721 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2727 TCGv t0
= tcg_temp_local_new();
2728 TCGv t1
= tcg_temp_new();
2729 TCGv t2
= tcg_temp_new();
2730 int l1
= gen_new_label();
2732 gen_load_gpr(t1
, rs
);
2733 gen_load_gpr(t2
, rt
);
2734 tcg_gen_sub_tl(t0
, t1
, t2
);
2735 tcg_gen_ext32s_tl(t0
, t0
);
2736 tcg_gen_xor_tl(t2
, t1
, t2
);
2737 tcg_gen_xor_tl(t1
, t0
, t1
);
2738 tcg_gen_and_tl(t1
, t1
, t2
);
2740 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2742 /* operands of different sign, first operand and result different sign */
2743 generate_exception(ctx
, EXCP_OVERFLOW
);
2745 gen_store_gpr(t0
, rd
);
2751 if (rs
!= 0 && rt
!= 0) {
2752 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2753 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2754 } else if (rs
== 0 && rt
!= 0) {
2755 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2756 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2757 } else if (rs
!= 0 && rt
== 0) {
2758 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2760 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2764 #if defined(TARGET_MIPS64)
2767 TCGv t0
= tcg_temp_local_new();
2768 TCGv t1
= tcg_temp_new();
2769 TCGv t2
= tcg_temp_new();
2770 int l1
= gen_new_label();
2772 gen_load_gpr(t1
, rs
);
2773 gen_load_gpr(t2
, rt
);
2774 tcg_gen_add_tl(t0
, t1
, t2
);
2775 tcg_gen_xor_tl(t1
, t1
, t2
);
2776 tcg_gen_xor_tl(t2
, t0
, t2
);
2777 tcg_gen_andc_tl(t1
, t2
, t1
);
2779 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2781 /* operands of same sign, result different sign */
2782 generate_exception(ctx
, EXCP_OVERFLOW
);
2784 gen_store_gpr(t0
, rd
);
2790 if (rs
!= 0 && rt
!= 0) {
2791 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2792 } else if (rs
== 0 && rt
!= 0) {
2793 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2794 } else if (rs
!= 0 && rt
== 0) {
2795 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2797 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2803 TCGv t0
= tcg_temp_local_new();
2804 TCGv t1
= tcg_temp_new();
2805 TCGv t2
= tcg_temp_new();
2806 int l1
= gen_new_label();
2808 gen_load_gpr(t1
, rs
);
2809 gen_load_gpr(t2
, rt
);
2810 tcg_gen_sub_tl(t0
, t1
, t2
);
2811 tcg_gen_xor_tl(t2
, t1
, t2
);
2812 tcg_gen_xor_tl(t1
, t0
, t1
);
2813 tcg_gen_and_tl(t1
, t1
, t2
);
2815 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2817 /* operands of different sign, first operand and result different sign */
2818 generate_exception(ctx
, EXCP_OVERFLOW
);
2820 gen_store_gpr(t0
, rd
);
2826 if (rs
!= 0 && rt
!= 0) {
2827 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2828 } else if (rs
== 0 && rt
!= 0) {
2829 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2830 } else if (rs
!= 0 && rt
== 0) {
2831 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2833 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2839 if (likely(rs
!= 0 && rt
!= 0)) {
2840 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2841 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2843 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2848 (void)opn
; /* avoid a compiler warning */
2849 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2852 /* Conditional move */
2853 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2854 int rd
, int rs
, int rt
)
2856 const char *opn
= "cond move";
2860 /* If no destination, treat it as a NOP. */
2865 t0
= tcg_temp_new();
2866 gen_load_gpr(t0
, rt
);
2867 t1
= tcg_const_tl(0);
2868 t2
= tcg_temp_new();
2869 gen_load_gpr(t2
, rs
);
2872 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2876 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2880 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2884 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2892 (void)opn
; /* avoid a compiler warning */
2893 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2897 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2898 int rd
, int rs
, int rt
)
2900 const char *opn
= "logic";
2903 /* If no destination, treat it as a NOP. */
2910 if (likely(rs
!= 0 && rt
!= 0)) {
2911 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2913 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2918 if (rs
!= 0 && rt
!= 0) {
2919 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2920 } else if (rs
== 0 && rt
!= 0) {
2921 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2922 } else if (rs
!= 0 && rt
== 0) {
2923 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2925 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2930 if (likely(rs
!= 0 && rt
!= 0)) {
2931 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2932 } else if (rs
== 0 && rt
!= 0) {
2933 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2934 } else if (rs
!= 0 && rt
== 0) {
2935 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2937 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2942 if (likely(rs
!= 0 && rt
!= 0)) {
2943 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2944 } else if (rs
== 0 && rt
!= 0) {
2945 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2946 } else if (rs
!= 0 && rt
== 0) {
2947 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2949 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2954 (void)opn
; /* avoid a compiler warning */
2955 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2958 /* Set on lower than */
2959 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2960 int rd
, int rs
, int rt
)
2962 const char *opn
= "slt";
2966 /* If no destination, treat it as a NOP. */
2971 t0
= tcg_temp_new();
2972 t1
= tcg_temp_new();
2973 gen_load_gpr(t0
, rs
);
2974 gen_load_gpr(t1
, rt
);
2977 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2981 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2985 (void)opn
; /* avoid a compiler warning */
2986 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2992 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2993 int rd
, int rs
, int rt
)
2995 const char *opn
= "shifts";
2999 /* If no destination, treat it as a NOP.
3000 For add & sub, we must generate the overflow exception when needed. */
3005 t0
= tcg_temp_new();
3006 t1
= tcg_temp_new();
3007 gen_load_gpr(t0
, rs
);
3008 gen_load_gpr(t1
, rt
);
3011 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3012 tcg_gen_shl_tl(t0
, t1
, t0
);
3013 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3017 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3018 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3022 tcg_gen_ext32u_tl(t1
, t1
);
3023 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3024 tcg_gen_shr_tl(t0
, t1
, t0
);
3025 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3030 TCGv_i32 t2
= tcg_temp_new_i32();
3031 TCGv_i32 t3
= tcg_temp_new_i32();
3033 tcg_gen_trunc_tl_i32(t2
, t0
);
3034 tcg_gen_trunc_tl_i32(t3
, t1
);
3035 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3036 tcg_gen_rotr_i32(t2
, t3
, t2
);
3037 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3038 tcg_temp_free_i32(t2
);
3039 tcg_temp_free_i32(t3
);
3043 #if defined(TARGET_MIPS64)
3045 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3046 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3050 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3051 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3055 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3056 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3060 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3061 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3066 (void)opn
; /* avoid a compiler warning */
3067 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3072 /* Arithmetic on HI/LO registers */
3073 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3075 const char *opn
= "hilo";
3077 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3089 #if defined(TARGET_MIPS64)
3091 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3095 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3100 #if defined(TARGET_MIPS64)
3102 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3106 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3112 #if defined(TARGET_MIPS64)
3114 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3118 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3121 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3127 #if defined(TARGET_MIPS64)
3129 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3133 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3136 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3141 (void)opn
; /* avoid a compiler warning */
3142 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
3145 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3148 TCGv t0
= tcg_const_tl(addr
);
3149 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3150 gen_store_gpr(t0
, reg
);
3154 static inline void gen_pcrel(DisasContext
*ctx
, int rs
, int16_t imm
)
3159 switch (MASK_OPC_PCREL_TOP2BITS(ctx
->opcode
)) {
3162 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3163 addr
= addr_add(ctx
, ctx
->pc
, offset
);
3164 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3168 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3169 addr
= addr_add(ctx
, ctx
->pc
, offset
);
3170 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3172 #if defined(TARGET_MIPS64)
3175 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3176 addr
= addr_add(ctx
, ctx
->pc
, offset
);
3177 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3181 switch (MASK_OPC_PCREL_TOP5BITS(ctx
->opcode
)) {
3185 addr
= addr_add(ctx
, ctx
->pc
, offset
);
3186 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3192 addr
= ~0xFFFF & addr_add(ctx
, ctx
->pc
, offset
);
3193 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3196 #if defined(TARGET_MIPS64)
3197 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3198 case R6_OPC_LDPC
+ (1 << 16):
3199 case R6_OPC_LDPC
+ (2 << 16):
3200 case R6_OPC_LDPC
+ (3 << 16):
3202 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3203 addr
= addr_add(ctx
, (ctx
->pc
& ~0x7), offset
);
3204 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3208 MIPS_INVAL("OPC_PCREL");
3209 generate_exception(ctx
, EXCP_RI
);
3216 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3218 const char *opn
= "r6 mul/div";
3227 t0
= tcg_temp_new();
3228 t1
= tcg_temp_new();
3230 gen_load_gpr(t0
, rs
);
3231 gen_load_gpr(t1
, rt
);
3236 TCGv t2
= tcg_temp_new();
3237 TCGv t3
= tcg_temp_new();
3238 tcg_gen_ext32s_tl(t0
, t0
);
3239 tcg_gen_ext32s_tl(t1
, t1
);
3240 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3241 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3242 tcg_gen_and_tl(t2
, t2
, t3
);
3243 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3244 tcg_gen_or_tl(t2
, t2
, t3
);
3245 tcg_gen_movi_tl(t3
, 0);
3246 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3247 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3248 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3256 TCGv t2
= tcg_temp_new();
3257 TCGv t3
= tcg_temp_new();
3258 tcg_gen_ext32s_tl(t0
, t0
);
3259 tcg_gen_ext32s_tl(t1
, t1
);
3260 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3261 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3262 tcg_gen_and_tl(t2
, t2
, t3
);
3263 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3264 tcg_gen_or_tl(t2
, t2
, t3
);
3265 tcg_gen_movi_tl(t3
, 0);
3266 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3267 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3268 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3276 TCGv t2
= tcg_const_tl(0);
3277 TCGv t3
= tcg_const_tl(1);
3278 tcg_gen_ext32u_tl(t0
, t0
);
3279 tcg_gen_ext32u_tl(t1
, t1
);
3280 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3281 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3282 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3290 TCGv t2
= tcg_const_tl(0);
3291 TCGv t3
= tcg_const_tl(1);
3292 tcg_gen_ext32u_tl(t0
, t0
);
3293 tcg_gen_ext32u_tl(t1
, t1
);
3294 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3295 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3296 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3304 TCGv_i32 t2
= tcg_temp_new_i32();
3305 TCGv_i32 t3
= tcg_temp_new_i32();
3306 tcg_gen_trunc_tl_i32(t2
, t0
);
3307 tcg_gen_trunc_tl_i32(t3
, t1
);
3308 tcg_gen_mul_i32(t2
, t2
, t3
);
3309 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3310 tcg_temp_free_i32(t2
);
3311 tcg_temp_free_i32(t3
);
3317 TCGv_i32 t2
= tcg_temp_new_i32();
3318 TCGv_i32 t3
= tcg_temp_new_i32();
3319 tcg_gen_trunc_tl_i32(t2
, t0
);
3320 tcg_gen_trunc_tl_i32(t3
, t1
);
3321 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3322 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3323 tcg_temp_free_i32(t2
);
3324 tcg_temp_free_i32(t3
);
3330 TCGv_i32 t2
= tcg_temp_new_i32();
3331 TCGv_i32 t3
= tcg_temp_new_i32();
3332 tcg_gen_trunc_tl_i32(t2
, t0
);
3333 tcg_gen_trunc_tl_i32(t3
, t1
);
3334 tcg_gen_mul_i32(t2
, t2
, t3
);
3335 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3336 tcg_temp_free_i32(t2
);
3337 tcg_temp_free_i32(t3
);
3343 TCGv_i32 t2
= tcg_temp_new_i32();
3344 TCGv_i32 t3
= tcg_temp_new_i32();
3345 tcg_gen_trunc_tl_i32(t2
, t0
);
3346 tcg_gen_trunc_tl_i32(t3
, t1
);
3347 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3348 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3349 tcg_temp_free_i32(t2
);
3350 tcg_temp_free_i32(t3
);
3354 #if defined(TARGET_MIPS64)
3357 TCGv t2
= tcg_temp_new();
3358 TCGv t3
= tcg_temp_new();
3359 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3360 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3361 tcg_gen_and_tl(t2
, t2
, t3
);
3362 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3363 tcg_gen_or_tl(t2
, t2
, t3
);
3364 tcg_gen_movi_tl(t3
, 0);
3365 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3366 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3374 TCGv t2
= tcg_temp_new();
3375 TCGv t3
= tcg_temp_new();
3376 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3377 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3378 tcg_gen_and_tl(t2
, t2
, t3
);
3379 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3380 tcg_gen_or_tl(t2
, t2
, t3
);
3381 tcg_gen_movi_tl(t3
, 0);
3382 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3383 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3391 TCGv t2
= tcg_const_tl(0);
3392 TCGv t3
= tcg_const_tl(1);
3393 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3394 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3402 TCGv t2
= tcg_const_tl(0);
3403 TCGv t3
= tcg_const_tl(1);
3404 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3405 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3412 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3417 TCGv t2
= tcg_temp_new();
3418 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3424 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3429 TCGv t2
= tcg_temp_new();
3430 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3438 generate_exception(ctx
, EXCP_RI
);
3441 (void)opn
; /* avoid a compiler warning */
3442 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3448 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3449 int acc
, int rs
, int rt
)
3451 const char *opn
= "mul/div";
3454 t0
= tcg_temp_new();
3455 t1
= tcg_temp_new();
3457 gen_load_gpr(t0
, rs
);
3458 gen_load_gpr(t1
, rt
);
3467 TCGv t2
= tcg_temp_new();
3468 TCGv t3
= tcg_temp_new();
3469 tcg_gen_ext32s_tl(t0
, t0
);
3470 tcg_gen_ext32s_tl(t1
, t1
);
3471 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3472 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3473 tcg_gen_and_tl(t2
, t2
, t3
);
3474 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3475 tcg_gen_or_tl(t2
, t2
, t3
);
3476 tcg_gen_movi_tl(t3
, 0);
3477 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3478 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3479 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3480 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3481 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3489 TCGv t2
= tcg_const_tl(0);
3490 TCGv t3
= tcg_const_tl(1);
3491 tcg_gen_ext32u_tl(t0
, t0
);
3492 tcg_gen_ext32u_tl(t1
, t1
);
3493 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3494 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3495 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3496 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3497 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3505 TCGv_i32 t2
= tcg_temp_new_i32();
3506 TCGv_i32 t3
= tcg_temp_new_i32();
3507 tcg_gen_trunc_tl_i32(t2
, t0
);
3508 tcg_gen_trunc_tl_i32(t3
, t1
);
3509 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3510 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3511 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3512 tcg_temp_free_i32(t2
);
3513 tcg_temp_free_i32(t3
);
3519 TCGv_i32 t2
= tcg_temp_new_i32();
3520 TCGv_i32 t3
= tcg_temp_new_i32();
3521 tcg_gen_trunc_tl_i32(t2
, t0
);
3522 tcg_gen_trunc_tl_i32(t3
, t1
);
3523 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3524 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3525 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3526 tcg_temp_free_i32(t2
);
3527 tcg_temp_free_i32(t3
);
3531 #if defined(TARGET_MIPS64)
3534 TCGv t2
= tcg_temp_new();
3535 TCGv t3
= tcg_temp_new();
3536 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3537 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3538 tcg_gen_and_tl(t2
, t2
, t3
);
3539 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3540 tcg_gen_or_tl(t2
, t2
, t3
);
3541 tcg_gen_movi_tl(t3
, 0);
3542 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3543 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3544 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3552 TCGv t2
= tcg_const_tl(0);
3553 TCGv t3
= tcg_const_tl(1);
3554 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3555 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3556 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3563 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3567 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3573 TCGv_i64 t2
= tcg_temp_new_i64();
3574 TCGv_i64 t3
= tcg_temp_new_i64();
3576 tcg_gen_ext_tl_i64(t2
, t0
);
3577 tcg_gen_ext_tl_i64(t3
, t1
);
3578 tcg_gen_mul_i64(t2
, t2
, t3
);
3579 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3580 tcg_gen_add_i64(t2
, t2
, t3
);
3581 tcg_temp_free_i64(t3
);
3582 tcg_gen_trunc_i64_tl(t0
, t2
);
3583 tcg_gen_shri_i64(t2
, t2
, 32);
3584 tcg_gen_trunc_i64_tl(t1
, t2
);
3585 tcg_temp_free_i64(t2
);
3586 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3587 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3593 TCGv_i64 t2
= tcg_temp_new_i64();
3594 TCGv_i64 t3
= tcg_temp_new_i64();
3596 tcg_gen_ext32u_tl(t0
, t0
);
3597 tcg_gen_ext32u_tl(t1
, t1
);
3598 tcg_gen_extu_tl_i64(t2
, t0
);
3599 tcg_gen_extu_tl_i64(t3
, t1
);
3600 tcg_gen_mul_i64(t2
, t2
, t3
);
3601 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3602 tcg_gen_add_i64(t2
, t2
, t3
);
3603 tcg_temp_free_i64(t3
);
3604 tcg_gen_trunc_i64_tl(t0
, t2
);
3605 tcg_gen_shri_i64(t2
, t2
, 32);
3606 tcg_gen_trunc_i64_tl(t1
, t2
);
3607 tcg_temp_free_i64(t2
);
3608 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3609 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3615 TCGv_i64 t2
= tcg_temp_new_i64();
3616 TCGv_i64 t3
= tcg_temp_new_i64();
3618 tcg_gen_ext_tl_i64(t2
, t0
);
3619 tcg_gen_ext_tl_i64(t3
, t1
);
3620 tcg_gen_mul_i64(t2
, t2
, t3
);
3621 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3622 tcg_gen_sub_i64(t2
, t3
, t2
);
3623 tcg_temp_free_i64(t3
);
3624 tcg_gen_trunc_i64_tl(t0
, t2
);
3625 tcg_gen_shri_i64(t2
, t2
, 32);
3626 tcg_gen_trunc_i64_tl(t1
, t2
);
3627 tcg_temp_free_i64(t2
);
3628 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3629 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3635 TCGv_i64 t2
= tcg_temp_new_i64();
3636 TCGv_i64 t3
= tcg_temp_new_i64();
3638 tcg_gen_ext32u_tl(t0
, t0
);
3639 tcg_gen_ext32u_tl(t1
, t1
);
3640 tcg_gen_extu_tl_i64(t2
, t0
);
3641 tcg_gen_extu_tl_i64(t3
, t1
);
3642 tcg_gen_mul_i64(t2
, t2
, t3
);
3643 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3644 tcg_gen_sub_i64(t2
, t3
, t2
);
3645 tcg_temp_free_i64(t3
);
3646 tcg_gen_trunc_i64_tl(t0
, t2
);
3647 tcg_gen_shri_i64(t2
, t2
, 32);
3648 tcg_gen_trunc_i64_tl(t1
, t2
);
3649 tcg_temp_free_i64(t2
);
3650 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3651 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3657 generate_exception(ctx
, EXCP_RI
);
3660 (void)opn
; /* avoid a compiler warning */
3661 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3667 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
3668 int rd
, int rs
, int rt
)
3670 const char *opn
= "mul vr54xx";
3671 TCGv t0
= tcg_temp_new();
3672 TCGv t1
= tcg_temp_new();
3674 gen_load_gpr(t0
, rs
);
3675 gen_load_gpr(t1
, rt
);
3678 case OPC_VR54XX_MULS
:
3679 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3682 case OPC_VR54XX_MULSU
:
3683 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3686 case OPC_VR54XX_MACC
:
3687 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3690 case OPC_VR54XX_MACCU
:
3691 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3694 case OPC_VR54XX_MSAC
:
3695 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3698 case OPC_VR54XX_MSACU
:
3699 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3702 case OPC_VR54XX_MULHI
:
3703 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3706 case OPC_VR54XX_MULHIU
:
3707 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3710 case OPC_VR54XX_MULSHI
:
3711 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3714 case OPC_VR54XX_MULSHIU
:
3715 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3718 case OPC_VR54XX_MACCHI
:
3719 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3722 case OPC_VR54XX_MACCHIU
:
3723 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3726 case OPC_VR54XX_MSACHI
:
3727 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3730 case OPC_VR54XX_MSACHIU
:
3731 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3735 MIPS_INVAL("mul vr54xx");
3736 generate_exception(ctx
, EXCP_RI
);
3739 gen_store_gpr(t0
, rd
);
3740 (void)opn
; /* avoid a compiler warning */
3741 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3748 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
3751 const char *opn
= "CLx";
3759 t0
= tcg_temp_new();
3760 gen_load_gpr(t0
, rs
);
3764 gen_helper_clo(cpu_gpr
[rd
], t0
);
3769 gen_helper_clz(cpu_gpr
[rd
], t0
);
3772 #if defined(TARGET_MIPS64)
3775 gen_helper_dclo(cpu_gpr
[rd
], t0
);
3780 gen_helper_dclz(cpu_gpr
[rd
], t0
);
3785 (void)opn
; /* avoid a compiler warning */
3786 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3790 /* Godson integer instructions */
3791 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3792 int rd
, int rs
, int rt
)
3794 const char *opn
= "loongson";
3806 case OPC_MULTU_G_2E
:
3807 case OPC_MULTU_G_2F
:
3808 #if defined(TARGET_MIPS64)
3809 case OPC_DMULT_G_2E
:
3810 case OPC_DMULT_G_2F
:
3811 case OPC_DMULTU_G_2E
:
3812 case OPC_DMULTU_G_2F
:
3814 t0
= tcg_temp_new();
3815 t1
= tcg_temp_new();
3818 t0
= tcg_temp_local_new();
3819 t1
= tcg_temp_local_new();
3823 gen_load_gpr(t0
, rs
);
3824 gen_load_gpr(t1
, rt
);
3829 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3830 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3833 case OPC_MULTU_G_2E
:
3834 case OPC_MULTU_G_2F
:
3835 tcg_gen_ext32u_tl(t0
, t0
);
3836 tcg_gen_ext32u_tl(t1
, t1
);
3837 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3838 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3844 int l1
= gen_new_label();
3845 int l2
= gen_new_label();
3846 int l3
= gen_new_label();
3847 tcg_gen_ext32s_tl(t0
, t0
);
3848 tcg_gen_ext32s_tl(t1
, t1
);
3849 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3850 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3853 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3854 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3855 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3858 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3859 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3867 int l1
= gen_new_label();
3868 int l2
= gen_new_label();
3869 tcg_gen_ext32u_tl(t0
, t0
);
3870 tcg_gen_ext32u_tl(t1
, t1
);
3871 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3872 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3875 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3876 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3884 int l1
= gen_new_label();
3885 int l2
= gen_new_label();
3886 int l3
= gen_new_label();
3887 tcg_gen_ext32u_tl(t0
, t0
);
3888 tcg_gen_ext32u_tl(t1
, t1
);
3889 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3890 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3891 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3893 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3896 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3897 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3905 int l1
= gen_new_label();
3906 int l2
= gen_new_label();
3907 tcg_gen_ext32u_tl(t0
, t0
);
3908 tcg_gen_ext32u_tl(t1
, t1
);
3909 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3910 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3913 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3914 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3919 #if defined(TARGET_MIPS64)
3920 case OPC_DMULT_G_2E
:
3921 case OPC_DMULT_G_2F
:
3922 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3925 case OPC_DMULTU_G_2E
:
3926 case OPC_DMULTU_G_2F
:
3927 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3933 int l1
= gen_new_label();
3934 int l2
= gen_new_label();
3935 int l3
= gen_new_label();
3936 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3937 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3940 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3941 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3942 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3945 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3950 case OPC_DDIVU_G_2E
:
3951 case OPC_DDIVU_G_2F
:
3953 int l1
= gen_new_label();
3954 int l2
= gen_new_label();
3955 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3956 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3959 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3967 int l1
= gen_new_label();
3968 int l2
= gen_new_label();
3969 int l3
= gen_new_label();
3970 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3971 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3972 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3974 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3977 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3982 case OPC_DMODU_G_2E
:
3983 case OPC_DMODU_G_2F
:
3985 int l1
= gen_new_label();
3986 int l2
= gen_new_label();
3987 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3988 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3991 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3999 (void)opn
; /* avoid a compiler warning */
4000 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
4005 /* Loongson multimedia instructions */
4006 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4008 const char *opn
= "loongson_cp2";
4009 uint32_t opc
, shift_max
;
4012 opc
= MASK_LMI(ctx
->opcode
);
4018 t0
= tcg_temp_local_new_i64();
4019 t1
= tcg_temp_local_new_i64();
4022 t0
= tcg_temp_new_i64();
4023 t1
= tcg_temp_new_i64();
4027 gen_load_fpr64(ctx
, t0
, rs
);
4028 gen_load_fpr64(ctx
, t1
, rt
);
4030 #define LMI_HELPER(UP, LO) \
4031 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4032 #define LMI_HELPER_1(UP, LO) \
4033 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4034 #define LMI_DIRECT(UP, LO, OP) \
4035 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4038 LMI_HELPER(PADDSH
, paddsh
);
4039 LMI_HELPER(PADDUSH
, paddush
);
4040 LMI_HELPER(PADDH
, paddh
);
4041 LMI_HELPER(PADDW
, paddw
);
4042 LMI_HELPER(PADDSB
, paddsb
);
4043 LMI_HELPER(PADDUSB
, paddusb
);
4044 LMI_HELPER(PADDB
, paddb
);
4046 LMI_HELPER(PSUBSH
, psubsh
);
4047 LMI_HELPER(PSUBUSH
, psubush
);
4048 LMI_HELPER(PSUBH
, psubh
);
4049 LMI_HELPER(PSUBW
, psubw
);
4050 LMI_HELPER(PSUBSB
, psubsb
);
4051 LMI_HELPER(PSUBUSB
, psubusb
);
4052 LMI_HELPER(PSUBB
, psubb
);
4054 LMI_HELPER(PSHUFH
, pshufh
);
4055 LMI_HELPER(PACKSSWH
, packsswh
);
4056 LMI_HELPER(PACKSSHB
, packsshb
);
4057 LMI_HELPER(PACKUSHB
, packushb
);
4059 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
4060 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
4061 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
4062 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
4063 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
4064 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
4066 LMI_HELPER(PAVGH
, pavgh
);
4067 LMI_HELPER(PAVGB
, pavgb
);
4068 LMI_HELPER(PMAXSH
, pmaxsh
);
4069 LMI_HELPER(PMINSH
, pminsh
);
4070 LMI_HELPER(PMAXUB
, pmaxub
);
4071 LMI_HELPER(PMINUB
, pminub
);
4073 LMI_HELPER(PCMPEQW
, pcmpeqw
);
4074 LMI_HELPER(PCMPGTW
, pcmpgtw
);
4075 LMI_HELPER(PCMPEQH
, pcmpeqh
);
4076 LMI_HELPER(PCMPGTH
, pcmpgth
);
4077 LMI_HELPER(PCMPEQB
, pcmpeqb
);
4078 LMI_HELPER(PCMPGTB
, pcmpgtb
);
4080 LMI_HELPER(PSLLW
, psllw
);
4081 LMI_HELPER(PSLLH
, psllh
);
4082 LMI_HELPER(PSRLW
, psrlw
);
4083 LMI_HELPER(PSRLH
, psrlh
);
4084 LMI_HELPER(PSRAW
, psraw
);
4085 LMI_HELPER(PSRAH
, psrah
);
4087 LMI_HELPER(PMULLH
, pmullh
);
4088 LMI_HELPER(PMULHH
, pmulhh
);
4089 LMI_HELPER(PMULHUH
, pmulhuh
);
4090 LMI_HELPER(PMADDHW
, pmaddhw
);
4092 LMI_HELPER(PASUBUB
, pasubub
);
4093 LMI_HELPER_1(BIADD
, biadd
);
4094 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
4096 LMI_DIRECT(PADDD
, paddd
, add
);
4097 LMI_DIRECT(PSUBD
, psubd
, sub
);
4098 LMI_DIRECT(XOR_CP2
, xor, xor);
4099 LMI_DIRECT(NOR_CP2
, nor
, nor
);
4100 LMI_DIRECT(AND_CP2
, and, and);
4101 LMI_DIRECT(PANDN
, pandn
, andc
);
4102 LMI_DIRECT(OR
, or, or);
4105 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
4109 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
4113 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
4117 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
4122 tcg_gen_andi_i64(t1
, t1
, 3);
4123 tcg_gen_shli_i64(t1
, t1
, 4);
4124 tcg_gen_shr_i64(t0
, t0
, t1
);
4125 tcg_gen_ext16u_i64(t0
, t0
);
4130 tcg_gen_add_i64(t0
, t0
, t1
);
4131 tcg_gen_ext32s_i64(t0
, t0
);
4135 tcg_gen_sub_i64(t0
, t0
, t1
);
4136 tcg_gen_ext32s_i64(t0
, t0
);
4165 /* Make sure shift count isn't TCG undefined behaviour. */
4166 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4171 tcg_gen_shl_i64(t0
, t0
, t1
);
4175 /* Since SRA is UndefinedResult without sign-extended inputs,
4176 we can treat SRA and DSRA the same. */
4177 tcg_gen_sar_i64(t0
, t0
, t1
);
4180 /* We want to shift in zeros for SRL; zero-extend first. */
4181 tcg_gen_ext32u_i64(t0
, t0
);
4184 tcg_gen_shr_i64(t0
, t0
, t1
);
4188 if (shift_max
== 32) {
4189 tcg_gen_ext32s_i64(t0
, t0
);
4192 /* Shifts larger than MAX produce zero. */
4193 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4194 tcg_gen_neg_i64(t1
, t1
);
4195 tcg_gen_and_i64(t0
, t0
, t1
);
4201 TCGv_i64 t2
= tcg_temp_new_i64();
4202 int lab
= gen_new_label();
4204 tcg_gen_mov_i64(t2
, t0
);
4205 tcg_gen_add_i64(t0
, t1
, t2
);
4206 if (opc
== OPC_ADD_CP2
) {
4207 tcg_gen_ext32s_i64(t0
, t0
);
4209 tcg_gen_xor_i64(t1
, t1
, t2
);
4210 tcg_gen_xor_i64(t2
, t2
, t0
);
4211 tcg_gen_andc_i64(t1
, t2
, t1
);
4212 tcg_temp_free_i64(t2
);
4213 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4214 generate_exception(ctx
, EXCP_OVERFLOW
);
4217 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
4224 TCGv_i64 t2
= tcg_temp_new_i64();
4225 int lab
= gen_new_label();
4227 tcg_gen_mov_i64(t2
, t0
);
4228 tcg_gen_sub_i64(t0
, t1
, t2
);
4229 if (opc
== OPC_SUB_CP2
) {
4230 tcg_gen_ext32s_i64(t0
, t0
);
4232 tcg_gen_xor_i64(t1
, t1
, t2
);
4233 tcg_gen_xor_i64(t2
, t2
, t0
);
4234 tcg_gen_and_i64(t1
, t1
, t2
);
4235 tcg_temp_free_i64(t2
);
4236 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4237 generate_exception(ctx
, EXCP_OVERFLOW
);
4240 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
4245 tcg_gen_ext32u_i64(t0
, t0
);
4246 tcg_gen_ext32u_i64(t1
, t1
);
4247 tcg_gen_mul_i64(t0
, t0
, t1
);
4257 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4258 FD field is the CC field? */
4261 generate_exception(ctx
, EXCP_RI
);
4268 gen_store_fpr64(ctx
, t0
, rd
);
4270 (void)opn
; /* avoid a compiler warning */
4271 MIPS_DEBUG("%s %s, %s, %s", opn
,
4272 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
4273 tcg_temp_free_i64(t0
);
4274 tcg_temp_free_i64(t1
);
4278 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
4279 int rs
, int rt
, int16_t imm
)
4282 TCGv t0
= tcg_temp_new();
4283 TCGv t1
= tcg_temp_new();
4286 /* Load needed operands */
4294 /* Compare two registers */
4296 gen_load_gpr(t0
, rs
);
4297 gen_load_gpr(t1
, rt
);
4307 /* Compare register to immediate */
4308 if (rs
!= 0 || imm
!= 0) {
4309 gen_load_gpr(t0
, rs
);
4310 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4317 case OPC_TEQ
: /* rs == rs */
4318 case OPC_TEQI
: /* r0 == 0 */
4319 case OPC_TGE
: /* rs >= rs */
4320 case OPC_TGEI
: /* r0 >= 0 */
4321 case OPC_TGEU
: /* rs >= rs unsigned */
4322 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4324 generate_exception(ctx
, EXCP_TRAP
);
4326 case OPC_TLT
: /* rs < rs */
4327 case OPC_TLTI
: /* r0 < 0 */
4328 case OPC_TLTU
: /* rs < rs unsigned */
4329 case OPC_TLTIU
: /* r0 < 0 unsigned */
4330 case OPC_TNE
: /* rs != rs */
4331 case OPC_TNEI
: /* r0 != 0 */
4332 /* Never trap: treat as NOP. */
4336 int l1
= gen_new_label();
4341 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4345 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4349 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
4353 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
4357 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
4361 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
4364 generate_exception(ctx
, EXCP_TRAP
);
4371 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
4373 TranslationBlock
*tb
;
4375 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
4376 likely(!ctx
->singlestep_enabled
)) {
4379 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
4382 if (ctx
->singlestep_enabled
) {
4383 save_cpu_state(ctx
, 0);
4384 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
4390 /* Branches (before delay slot) */
4391 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
4393 int rs
, int rt
, int32_t offset
,
4396 target_ulong btgt
= -1;
4398 int bcond_compute
= 0;
4399 TCGv t0
= tcg_temp_new();
4400 TCGv t1
= tcg_temp_new();
4402 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
4403 #ifdef MIPS_DEBUG_DISAS
4404 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4405 TARGET_FMT_lx
"\n", ctx
->pc
);
4407 generate_exception(ctx
, EXCP_RI
);
4411 /* Load needed operands */
4417 /* Compare two registers */
4419 gen_load_gpr(t0
, rs
);
4420 gen_load_gpr(t1
, rt
);
4423 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4437 /* Compare to zero */
4439 gen_load_gpr(t0
, rs
);
4442 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4445 #if defined(TARGET_MIPS64)
4447 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
4449 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
4452 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4457 /* Jump to immediate */
4458 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
4462 /* Jump to register */
4463 if (offset
!= 0 && offset
!= 16) {
4464 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4465 others are reserved. */
4466 MIPS_INVAL("jump hint");
4467 generate_exception(ctx
, EXCP_RI
);
4470 gen_load_gpr(btarget
, rs
);
4473 MIPS_INVAL("branch/jump");
4474 generate_exception(ctx
, EXCP_RI
);
4477 if (bcond_compute
== 0) {
4478 /* No condition to be computed */
4480 case OPC_BEQ
: /* rx == rx */
4481 case OPC_BEQL
: /* rx == rx likely */
4482 case OPC_BGEZ
: /* 0 >= 0 */
4483 case OPC_BGEZL
: /* 0 >= 0 likely */
4484 case OPC_BLEZ
: /* 0 <= 0 */
4485 case OPC_BLEZL
: /* 0 <= 0 likely */
4487 ctx
->hflags
|= MIPS_HFLAG_B
;
4488 MIPS_DEBUG("balways");
4490 case OPC_BGEZAL
: /* 0 >= 0 */
4491 case OPC_BGEZALL
: /* 0 >= 0 likely */
4492 /* Always take and link */
4494 ctx
->hflags
|= MIPS_HFLAG_B
;
4495 MIPS_DEBUG("balways and link");
4497 case OPC_BNE
: /* rx != rx */
4498 case OPC_BGTZ
: /* 0 > 0 */
4499 case OPC_BLTZ
: /* 0 < 0 */
4501 MIPS_DEBUG("bnever (NOP)");
4503 case OPC_BLTZAL
: /* 0 < 0 */
4504 /* Handle as an unconditional branch to get correct delay
4507 btgt
= ctx
->pc
+ insn_bytes
+ delayslot_size
;
4508 ctx
->hflags
|= MIPS_HFLAG_B
;
4509 MIPS_DEBUG("bnever and link");
4511 case OPC_BLTZALL
: /* 0 < 0 likely */
4512 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
4513 /* Skip the instruction in the delay slot */
4514 MIPS_DEBUG("bnever, link and skip");
4517 case OPC_BNEL
: /* rx != rx likely */
4518 case OPC_BGTZL
: /* 0 > 0 likely */
4519 case OPC_BLTZL
: /* 0 < 0 likely */
4520 /* Skip the instruction in the delay slot */
4521 MIPS_DEBUG("bnever and skip");
4525 ctx
->hflags
|= MIPS_HFLAG_B
;
4526 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
4529 ctx
->hflags
|= MIPS_HFLAG_BX
;
4533 ctx
->hflags
|= MIPS_HFLAG_B
;
4534 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
4537 ctx
->hflags
|= MIPS_HFLAG_BR
;
4538 MIPS_DEBUG("jr %s", regnames
[rs
]);
4542 ctx
->hflags
|= MIPS_HFLAG_BR
;
4543 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
4546 MIPS_INVAL("branch/jump");
4547 generate_exception(ctx
, EXCP_RI
);
4553 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4554 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
4555 regnames
[rs
], regnames
[rt
], btgt
);
4558 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4559 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
4560 regnames
[rs
], regnames
[rt
], btgt
);
4563 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4564 MIPS_DEBUG("bne %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("bnel %s, %s, " TARGET_FMT_lx
,
4570 regnames
[rs
], regnames
[rt
], btgt
);
4573 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4574 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4577 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4578 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4581 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4582 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4586 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4588 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4591 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4592 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4595 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4596 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4599 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4600 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4603 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4604 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4607 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4608 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4611 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4612 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4615 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
4616 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
4618 #if defined(TARGET_MIPS64)
4620 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
4621 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
4625 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4627 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4629 ctx
->hflags
|= MIPS_HFLAG_BC
;
4632 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4634 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4636 ctx
->hflags
|= MIPS_HFLAG_BL
;
4639 MIPS_INVAL("conditional branch/jump");
4640 generate_exception(ctx
, EXCP_RI
);
4644 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
4645 blink
, ctx
->hflags
, btgt
);
4647 ctx
->btarget
= btgt
;
4649 switch (delayslot_size
) {
4651 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
4654 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
4659 int post_delay
= insn_bytes
+ delayslot_size
;
4660 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
4662 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
4666 if (insn_bytes
== 2)
4667 ctx
->hflags
|= MIPS_HFLAG_B16
;
4672 /* special3 bitfield operations */
4673 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
4674 int rs
, int lsb
, int msb
)
4676 TCGv t0
= tcg_temp_new();
4677 TCGv t1
= tcg_temp_new();
4679 gen_load_gpr(t1
, rs
);
4684 tcg_gen_shri_tl(t0
, t1
, lsb
);
4686 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
4688 tcg_gen_ext32s_tl(t0
, t0
);
4691 #if defined(TARGET_MIPS64)
4693 tcg_gen_shri_tl(t0
, t1
, lsb
);
4695 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
4699 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
4700 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4703 tcg_gen_shri_tl(t0
, t1
, lsb
);
4704 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4710 gen_load_gpr(t0
, rt
);
4711 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4712 tcg_gen_ext32s_tl(t0
, t0
);
4714 #if defined(TARGET_MIPS64)
4716 gen_load_gpr(t0
, rt
);
4717 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
4720 gen_load_gpr(t0
, rt
);
4721 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
4724 gen_load_gpr(t0
, rt
);
4725 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4730 MIPS_INVAL("bitops");
4731 generate_exception(ctx
, EXCP_RI
);
4736 gen_store_gpr(t0
, rt
);
4741 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4746 /* If no destination, treat it as a NOP. */
4751 t0
= tcg_temp_new();
4752 gen_load_gpr(t0
, rt
);
4756 TCGv t1
= tcg_temp_new();
4758 tcg_gen_shri_tl(t1
, t0
, 8);
4759 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4760 tcg_gen_shli_tl(t0
, t0
, 8);
4761 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4762 tcg_gen_or_tl(t0
, t0
, t1
);
4764 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4768 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4771 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4773 #if defined(TARGET_MIPS64)
4776 TCGv t1
= tcg_temp_new();
4778 tcg_gen_shri_tl(t1
, t0
, 8);
4779 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4780 tcg_gen_shli_tl(t0
, t0
, 8);
4781 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4782 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4788 TCGv t1
= tcg_temp_new();
4790 tcg_gen_shri_tl(t1
, t0
, 16);
4791 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4792 tcg_gen_shli_tl(t0
, t0
, 16);
4793 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4794 tcg_gen_or_tl(t0
, t0
, t1
);
4795 tcg_gen_shri_tl(t1
, t0
, 32);
4796 tcg_gen_shli_tl(t0
, t0
, 32);
4797 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4803 MIPS_INVAL("bsfhl");
4804 generate_exception(ctx
, EXCP_RI
);
4811 #ifndef CONFIG_USER_ONLY
4812 /* CP0 (MMU and control) */
4813 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4815 TCGv_i32 t0
= tcg_temp_new_i32();
4817 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4818 tcg_gen_ext_i32_tl(arg
, t0
);
4819 tcg_temp_free_i32(t0
);
4822 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4824 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4825 tcg_gen_ext32s_tl(arg
, arg
);
4828 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4830 TCGv_i32 t0
= tcg_temp_new_i32();
4832 tcg_gen_trunc_tl_i32(t0
, arg
);
4833 tcg_gen_st_i32(t0
, cpu_env
, off
);
4834 tcg_temp_free_i32(t0
);
4837 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4839 tcg_gen_ext32s_tl(arg
, arg
);
4840 tcg_gen_st_tl(arg
, cpu_env
, off
);
4843 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
4845 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
4846 tcg_gen_movi_tl(arg
, 0);
4848 tcg_gen_movi_tl(arg
, ~0);
4852 #define CP0_CHECK(c) \
4855 goto cp0_unimplemented; \
4859 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4861 const char *rn
= "invalid";
4864 check_insn(ctx
, ISA_MIPS32
);
4870 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4874 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4875 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4879 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4880 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4884 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4885 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4889 goto cp0_unimplemented
;
4895 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
4896 gen_helper_mfc0_random(arg
, cpu_env
);
4900 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4901 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4905 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4906 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4910 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4911 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4915 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4916 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4920 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4921 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4925 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4926 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4927 rn
= "VPEScheFBack";
4930 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4931 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4935 goto cp0_unimplemented
;
4941 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4942 #if defined(TARGET_MIPS64)
4944 TCGv tmp
= tcg_temp_new();
4945 tcg_gen_andi_tl(tmp
, arg
, (3ull << 62));
4946 tcg_gen_shri_tl(tmp
, tmp
, 32);
4947 tcg_gen_or_tl(arg
, arg
, tmp
);
4951 tcg_gen_ext32s_tl(arg
, arg
);
4955 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4956 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4960 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4961 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4965 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4966 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4970 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4971 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4975 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4976 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4980 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4981 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4985 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4986 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4990 goto cp0_unimplemented
;
4996 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4997 #if defined(TARGET_MIPS64)
4999 TCGv tmp
= tcg_temp_new();
5000 tcg_gen_andi_tl(tmp
, arg
, (3ull << 62));
5001 tcg_gen_shri_tl(tmp
, tmp
, 32);
5002 tcg_gen_or_tl(arg
, arg
, tmp
);
5006 tcg_gen_ext32s_tl(arg
, arg
);
5010 goto cp0_unimplemented
;
5016 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5017 tcg_gen_ext32s_tl(arg
, arg
);
5021 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5022 rn
= "ContextConfig";
5023 goto cp0_unimplemented
;
5026 CP0_CHECK(ctx
->ulri
);
5027 tcg_gen_ld32s_tl(arg
, cpu_env
,
5028 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5032 goto cp0_unimplemented
;
5038 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5042 check_insn(ctx
, ISA_MIPS32R2
);
5043 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5047 goto cp0_unimplemented
;
5053 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5057 check_insn(ctx
, ISA_MIPS32R2
);
5058 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5062 check_insn(ctx
, ISA_MIPS32R2
);
5063 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5067 check_insn(ctx
, ISA_MIPS32R2
);
5068 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5072 check_insn(ctx
, ISA_MIPS32R2
);
5073 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5077 check_insn(ctx
, ISA_MIPS32R2
);
5078 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5082 goto cp0_unimplemented
;
5088 check_insn(ctx
, ISA_MIPS32R2
);
5089 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5093 goto cp0_unimplemented
;
5099 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5100 tcg_gen_ext32s_tl(arg
, arg
);
5105 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
5110 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
5114 goto cp0_unimplemented
;
5120 /* Mark as an IO operation because we read the time. */
5123 gen_helper_mfc0_count(arg
, cpu_env
);
5127 /* Break the TB to be able to take timer interrupts immediately
5128 after reading count. */
5129 ctx
->bstate
= BS_STOP
;
5132 /* 6,7 are implementation dependent */
5134 goto cp0_unimplemented
;
5140 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5141 tcg_gen_ext32s_tl(arg
, arg
);
5145 goto cp0_unimplemented
;
5151 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5154 /* 6,7 are implementation dependent */
5156 goto cp0_unimplemented
;
5162 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5166 check_insn(ctx
, ISA_MIPS32R2
);
5167 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5171 check_insn(ctx
, ISA_MIPS32R2
);
5172 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5176 check_insn(ctx
, ISA_MIPS32R2
);
5177 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5181 goto cp0_unimplemented
;
5187 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5191 goto cp0_unimplemented
;
5197 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5198 tcg_gen_ext32s_tl(arg
, arg
);
5202 goto cp0_unimplemented
;
5208 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5212 check_insn(ctx
, ISA_MIPS32R2
);
5213 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5217 goto cp0_unimplemented
;
5223 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5227 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5231 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5235 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5239 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
5243 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
5246 /* 6,7 are implementation dependent */
5248 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5252 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5256 goto cp0_unimplemented
;
5262 gen_helper_mfc0_lladdr(arg
, cpu_env
);
5266 goto cp0_unimplemented
;
5272 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
5276 goto cp0_unimplemented
;
5282 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5286 goto cp0_unimplemented
;
5292 #if defined(TARGET_MIPS64)
5293 check_insn(ctx
, ISA_MIPS3
);
5294 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5295 tcg_gen_ext32s_tl(arg
, arg
);
5300 goto cp0_unimplemented
;
5304 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5305 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5308 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5312 goto cp0_unimplemented
;
5316 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5317 rn
= "'Diagnostic"; /* implementation dependent */
5322 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5326 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5327 rn
= "TraceControl";
5330 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5331 rn
= "TraceControl2";
5334 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5335 rn
= "UserTraceData";
5338 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5342 goto cp0_unimplemented
;
5349 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5350 tcg_gen_ext32s_tl(arg
, arg
);
5354 goto cp0_unimplemented
;
5360 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5361 rn
= "Performance0";
5364 // gen_helper_mfc0_performance1(arg);
5365 rn
= "Performance1";
5368 // gen_helper_mfc0_performance2(arg);
5369 rn
= "Performance2";
5372 // gen_helper_mfc0_performance3(arg);
5373 rn
= "Performance3";
5376 // gen_helper_mfc0_performance4(arg);
5377 rn
= "Performance4";
5380 // gen_helper_mfc0_performance5(arg);
5381 rn
= "Performance5";
5384 // gen_helper_mfc0_performance6(arg);
5385 rn
= "Performance6";
5388 // gen_helper_mfc0_performance7(arg);
5389 rn
= "Performance7";
5392 goto cp0_unimplemented
;
5396 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5402 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5406 goto cp0_unimplemented
;
5415 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5422 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5426 goto cp0_unimplemented
;
5435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5442 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5446 goto cp0_unimplemented
;
5452 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5453 tcg_gen_ext32s_tl(arg
, arg
);
5457 goto cp0_unimplemented
;
5464 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5468 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
5469 tcg_gen_ld_tl(arg
, cpu_env
,
5470 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
5471 tcg_gen_ext32s_tl(arg
, arg
);
5475 goto cp0_unimplemented
;
5479 goto cp0_unimplemented
;
5481 (void)rn
; /* avoid a compiler warning */
5482 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5486 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5487 gen_mfc0_unimplemented(ctx
, arg
);
5490 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5492 const char *rn
= "invalid";
5495 check_insn(ctx
, ISA_MIPS32
);
5504 gen_helper_mtc0_index(cpu_env
, arg
);
5508 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5509 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5513 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5518 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5523 goto cp0_unimplemented
;
5533 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5534 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5538 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5539 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5543 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5544 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5548 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5549 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5553 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5554 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5558 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5559 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5560 rn
= "VPEScheFBack";
5563 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5564 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5568 goto cp0_unimplemented
;
5574 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5578 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5579 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5583 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5584 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5588 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5589 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5593 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5594 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5598 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5599 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5603 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5604 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5608 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5609 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5613 goto cp0_unimplemented
;
5619 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5623 goto cp0_unimplemented
;
5629 gen_helper_mtc0_context(cpu_env
, arg
);
5633 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5634 rn
= "ContextConfig";
5635 goto cp0_unimplemented
;
5638 CP0_CHECK(ctx
->ulri
);
5639 tcg_gen_st_tl(arg
, cpu_env
,
5640 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5644 goto cp0_unimplemented
;
5650 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5654 check_insn(ctx
, ISA_MIPS32R2
);
5655 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5659 goto cp0_unimplemented
;
5665 gen_helper_mtc0_wired(cpu_env
, arg
);
5669 check_insn(ctx
, ISA_MIPS32R2
);
5670 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5674 check_insn(ctx
, ISA_MIPS32R2
);
5675 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
5679 check_insn(ctx
, ISA_MIPS32R2
);
5680 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
5684 check_insn(ctx
, ISA_MIPS32R2
);
5685 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
5689 check_insn(ctx
, ISA_MIPS32R2
);
5690 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
5694 goto cp0_unimplemented
;
5700 check_insn(ctx
, ISA_MIPS32R2
);
5701 gen_helper_mtc0_hwrena(cpu_env
, arg
);
5702 ctx
->bstate
= BS_STOP
;
5706 goto cp0_unimplemented
;
5724 goto cp0_unimplemented
;
5730 gen_helper_mtc0_count(cpu_env
, arg
);
5733 /* 6,7 are implementation dependent */
5735 goto cp0_unimplemented
;
5741 gen_helper_mtc0_entryhi(cpu_env
, arg
);
5745 goto cp0_unimplemented
;
5751 gen_helper_mtc0_compare(cpu_env
, arg
);
5754 /* 6,7 are implementation dependent */
5756 goto cp0_unimplemented
;
5762 save_cpu_state(ctx
, 1);
5763 gen_helper_mtc0_status(cpu_env
, arg
);
5764 /* BS_STOP isn't good enough here, hflags may have changed. */
5765 gen_save_pc(ctx
->pc
+ 4);
5766 ctx
->bstate
= BS_EXCP
;
5770 check_insn(ctx
, ISA_MIPS32R2
);
5771 gen_helper_mtc0_intctl(cpu_env
, arg
);
5772 /* Stop translation as we may have switched the execution mode */
5773 ctx
->bstate
= BS_STOP
;
5777 check_insn(ctx
, ISA_MIPS32R2
);
5778 gen_helper_mtc0_srsctl(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_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5786 /* Stop translation as we may have switched the execution mode */
5787 ctx
->bstate
= BS_STOP
;
5791 goto cp0_unimplemented
;
5797 save_cpu_state(ctx
, 1);
5798 gen_helper_mtc0_cause(cpu_env
, arg
);
5802 goto cp0_unimplemented
;
5808 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
5812 goto cp0_unimplemented
;
5822 check_insn(ctx
, ISA_MIPS32R2
);
5823 gen_helper_mtc0_ebase(cpu_env
, arg
);
5827 goto cp0_unimplemented
;
5833 gen_helper_mtc0_config0(cpu_env
, arg
);
5835 /* Stop translation as we may have switched the execution mode */
5836 ctx
->bstate
= BS_STOP
;
5839 /* ignored, read only */
5843 gen_helper_mtc0_config2(cpu_env
, arg
);
5845 /* Stop translation as we may have switched the execution mode */
5846 ctx
->bstate
= BS_STOP
;
5849 /* ignored, read only */
5853 gen_helper_mtc0_config4(cpu_env
, arg
);
5855 ctx
->bstate
= BS_STOP
;
5858 gen_helper_mtc0_config5(cpu_env
, arg
);
5860 /* Stop translation as we may have switched the execution mode */
5861 ctx
->bstate
= BS_STOP
;
5863 /* 6,7 are implementation dependent */
5873 rn
= "Invalid config selector";
5874 goto cp0_unimplemented
;
5880 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5884 goto cp0_unimplemented
;
5890 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5894 goto cp0_unimplemented
;
5900 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5904 goto cp0_unimplemented
;
5910 #if defined(TARGET_MIPS64)
5911 check_insn(ctx
, ISA_MIPS3
);
5912 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5917 goto cp0_unimplemented
;
5921 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5922 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5925 gen_helper_mtc0_framemask(cpu_env
, arg
);
5929 goto cp0_unimplemented
;
5934 rn
= "Diagnostic"; /* implementation dependent */
5939 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5940 /* BS_STOP isn't good enough here, hflags may have changed. */
5941 gen_save_pc(ctx
->pc
+ 4);
5942 ctx
->bstate
= BS_EXCP
;
5946 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5947 rn
= "TraceControl";
5948 /* Stop translation as we may have switched the execution mode */
5949 ctx
->bstate
= BS_STOP
;
5952 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5953 rn
= "TraceControl2";
5954 /* Stop translation as we may have switched the execution mode */
5955 ctx
->bstate
= BS_STOP
;
5958 /* Stop translation as we may have switched the execution mode */
5959 ctx
->bstate
= BS_STOP
;
5960 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5961 rn
= "UserTraceData";
5962 /* Stop translation as we may have switched the execution mode */
5963 ctx
->bstate
= BS_STOP
;
5966 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5967 /* Stop translation as we may have switched the execution mode */
5968 ctx
->bstate
= BS_STOP
;
5972 goto cp0_unimplemented
;
5979 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5983 goto cp0_unimplemented
;
5989 gen_helper_mtc0_performance0(cpu_env
, arg
);
5990 rn
= "Performance0";
5993 // gen_helper_mtc0_performance1(arg);
5994 rn
= "Performance1";
5997 // gen_helper_mtc0_performance2(arg);
5998 rn
= "Performance2";
6001 // gen_helper_mtc0_performance3(arg);
6002 rn
= "Performance3";
6005 // gen_helper_mtc0_performance4(arg);
6006 rn
= "Performance4";
6009 // gen_helper_mtc0_performance5(arg);
6010 rn
= "Performance5";
6013 // gen_helper_mtc0_performance6(arg);
6014 rn
= "Performance6";
6017 // gen_helper_mtc0_performance7(arg);
6018 rn
= "Performance7";
6021 goto cp0_unimplemented
;
6035 goto cp0_unimplemented
;
6044 gen_helper_mtc0_taglo(cpu_env
, arg
);
6051 gen_helper_mtc0_datalo(cpu_env
, arg
);
6055 goto cp0_unimplemented
;
6064 gen_helper_mtc0_taghi(cpu_env
, arg
);
6071 gen_helper_mtc0_datahi(cpu_env
, arg
);
6076 goto cp0_unimplemented
;
6082 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6086 goto cp0_unimplemented
;
6093 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6097 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6098 tcg_gen_st_tl(arg
, cpu_env
,
6099 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6103 goto cp0_unimplemented
;
6105 /* Stop translation as we may have switched the execution mode */
6106 ctx
->bstate
= BS_STOP
;
6109 goto cp0_unimplemented
;
6111 (void)rn
; /* avoid a compiler warning */
6112 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6113 /* For simplicity assume that all writes can cause interrupts. */
6116 ctx
->bstate
= BS_STOP
;
6121 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6124 #if defined(TARGET_MIPS64)
6125 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6127 const char *rn
= "invalid";
6130 check_insn(ctx
, ISA_MIPS64
);
6136 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6140 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6141 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6145 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6146 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6150 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6151 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6155 goto cp0_unimplemented
;
6161 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6162 gen_helper_mfc0_random(arg
, cpu_env
);
6166 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6167 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6171 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6172 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6176 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6177 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6181 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6182 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
6186 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6187 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6191 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6192 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6193 rn
= "VPEScheFBack";
6196 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6197 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6201 goto cp0_unimplemented
;
6207 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6211 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6212 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6216 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6217 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6221 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6222 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
6226 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6227 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
6231 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6232 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
6236 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6237 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
6241 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6242 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
6246 goto cp0_unimplemented
;
6252 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6256 goto cp0_unimplemented
;
6262 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6266 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6267 rn
= "ContextConfig";
6268 goto cp0_unimplemented
;
6271 CP0_CHECK(ctx
->ulri
);
6272 tcg_gen_ld_tl(arg
, cpu_env
,
6273 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6277 goto cp0_unimplemented
;
6283 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6287 check_insn(ctx
, ISA_MIPS32R2
);
6288 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6292 goto cp0_unimplemented
;
6298 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6302 check_insn(ctx
, ISA_MIPS32R2
);
6303 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6307 check_insn(ctx
, ISA_MIPS32R2
);
6308 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6312 check_insn(ctx
, ISA_MIPS32R2
);
6313 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6317 check_insn(ctx
, ISA_MIPS32R2
);
6318 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6322 check_insn(ctx
, ISA_MIPS32R2
);
6323 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6327 goto cp0_unimplemented
;
6333 check_insn(ctx
, ISA_MIPS32R2
);
6334 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6338 goto cp0_unimplemented
;
6344 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6349 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6354 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6358 goto cp0_unimplemented
;
6364 /* Mark as an IO operation because we read the time. */
6367 gen_helper_mfc0_count(arg
, cpu_env
);
6371 /* Break the TB to be able to take timer interrupts immediately
6372 after reading count. */
6373 ctx
->bstate
= BS_STOP
;
6376 /* 6,7 are implementation dependent */
6378 goto cp0_unimplemented
;
6384 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6388 goto cp0_unimplemented
;
6394 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6397 /* 6,7 are implementation dependent */
6399 goto cp0_unimplemented
;
6405 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6409 check_insn(ctx
, ISA_MIPS32R2
);
6410 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6414 check_insn(ctx
, ISA_MIPS32R2
);
6415 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6419 check_insn(ctx
, ISA_MIPS32R2
);
6420 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6424 goto cp0_unimplemented
;
6430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6434 goto cp0_unimplemented
;
6440 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6444 goto cp0_unimplemented
;
6450 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6454 check_insn(ctx
, ISA_MIPS32R2
);
6455 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
6459 goto cp0_unimplemented
;
6465 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6469 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6473 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6477 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6481 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6485 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6488 /* 6,7 are implementation dependent */
6490 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6494 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6498 goto cp0_unimplemented
;
6504 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
6508 goto cp0_unimplemented
;
6514 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
6518 goto cp0_unimplemented
;
6524 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6528 goto cp0_unimplemented
;
6534 check_insn(ctx
, ISA_MIPS3
);
6535 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6539 goto cp0_unimplemented
;
6543 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6544 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6547 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6551 goto cp0_unimplemented
;
6555 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6556 rn
= "'Diagnostic"; /* implementation dependent */
6561 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6565 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6566 rn
= "TraceControl";
6569 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6570 rn
= "TraceControl2";
6573 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6574 rn
= "UserTraceData";
6577 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6581 goto cp0_unimplemented
;
6588 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6592 goto cp0_unimplemented
;
6598 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6599 rn
= "Performance0";
6602 // gen_helper_dmfc0_performance1(arg);
6603 rn
= "Performance1";
6606 // gen_helper_dmfc0_performance2(arg);
6607 rn
= "Performance2";
6610 // gen_helper_dmfc0_performance3(arg);
6611 rn
= "Performance3";
6614 // gen_helper_dmfc0_performance4(arg);
6615 rn
= "Performance4";
6618 // gen_helper_dmfc0_performance5(arg);
6619 rn
= "Performance5";
6622 // gen_helper_dmfc0_performance6(arg);
6623 rn
= "Performance6";
6626 // gen_helper_dmfc0_performance7(arg);
6627 rn
= "Performance7";
6630 goto cp0_unimplemented
;
6634 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6641 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6645 goto cp0_unimplemented
;
6654 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6661 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6665 goto cp0_unimplemented
;
6674 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6681 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6685 goto cp0_unimplemented
;
6691 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6695 goto cp0_unimplemented
;
6702 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6706 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6707 tcg_gen_ld_tl(arg
, cpu_env
,
6708 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6712 goto cp0_unimplemented
;
6716 goto cp0_unimplemented
;
6718 (void)rn
; /* avoid a compiler warning */
6719 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6723 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6724 gen_mfc0_unimplemented(ctx
, arg
);
6727 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6729 const char *rn
= "invalid";
6732 check_insn(ctx
, ISA_MIPS64
);
6741 gen_helper_mtc0_index(cpu_env
, arg
);
6745 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6746 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6750 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6755 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6760 goto cp0_unimplemented
;
6770 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6771 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6775 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6776 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6780 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6781 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6785 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6786 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6790 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6791 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6795 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6796 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6797 rn
= "VPEScheFBack";
6800 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6801 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6805 goto cp0_unimplemented
;
6811 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
6815 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6816 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6820 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6821 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6825 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6826 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
6830 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6831 gen_helper_mtc0_tchalt(cpu_env
, arg
);
6835 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6836 gen_helper_mtc0_tccontext(cpu_env
, arg
);
6840 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6841 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
6845 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6846 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6850 goto cp0_unimplemented
;
6856 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
6860 goto cp0_unimplemented
;
6866 gen_helper_mtc0_context(cpu_env
, arg
);
6870 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6871 rn
= "ContextConfig";
6872 goto cp0_unimplemented
;
6875 CP0_CHECK(ctx
->ulri
);
6876 tcg_gen_st_tl(arg
, cpu_env
,
6877 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6881 goto cp0_unimplemented
;
6887 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6891 check_insn(ctx
, ISA_MIPS32R2
);
6892 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6896 goto cp0_unimplemented
;
6902 gen_helper_mtc0_wired(cpu_env
, arg
);
6906 check_insn(ctx
, ISA_MIPS32R2
);
6907 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6911 check_insn(ctx
, ISA_MIPS32R2
);
6912 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6916 check_insn(ctx
, ISA_MIPS32R2
);
6917 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6921 check_insn(ctx
, ISA_MIPS32R2
);
6922 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6926 check_insn(ctx
, ISA_MIPS32R2
);
6927 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6931 goto cp0_unimplemented
;
6937 check_insn(ctx
, ISA_MIPS32R2
);
6938 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6939 ctx
->bstate
= BS_STOP
;
6943 goto cp0_unimplemented
;
6961 goto cp0_unimplemented
;
6967 gen_helper_mtc0_count(cpu_env
, arg
);
6970 /* 6,7 are implementation dependent */
6972 goto cp0_unimplemented
;
6974 /* Stop translation as we may have switched the execution mode */
6975 ctx
->bstate
= BS_STOP
;
6980 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6984 goto cp0_unimplemented
;
6990 gen_helper_mtc0_compare(cpu_env
, arg
);
6993 /* 6,7 are implementation dependent */
6995 goto cp0_unimplemented
;
6997 /* Stop translation as we may have switched the execution mode */
6998 ctx
->bstate
= BS_STOP
;
7003 save_cpu_state(ctx
, 1);
7004 gen_helper_mtc0_status(cpu_env
, arg
);
7005 /* BS_STOP isn't good enough here, hflags may have changed. */
7006 gen_save_pc(ctx
->pc
+ 4);
7007 ctx
->bstate
= BS_EXCP
;
7011 check_insn(ctx
, ISA_MIPS32R2
);
7012 gen_helper_mtc0_intctl(cpu_env
, arg
);
7013 /* Stop translation as we may have switched the execution mode */
7014 ctx
->bstate
= BS_STOP
;
7018 check_insn(ctx
, ISA_MIPS32R2
);
7019 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7020 /* Stop translation as we may have switched the execution mode */
7021 ctx
->bstate
= BS_STOP
;
7025 check_insn(ctx
, ISA_MIPS32R2
);
7026 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7027 /* Stop translation as we may have switched the execution mode */
7028 ctx
->bstate
= BS_STOP
;
7032 goto cp0_unimplemented
;
7038 save_cpu_state(ctx
, 1);
7039 /* Mark as an IO operation because we may trigger a software
7044 gen_helper_mtc0_cause(cpu_env
, arg
);
7048 /* Stop translation as we may have triggered an intetrupt */
7049 ctx
->bstate
= BS_STOP
;
7053 goto cp0_unimplemented
;
7059 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7063 goto cp0_unimplemented
;
7073 check_insn(ctx
, ISA_MIPS32R2
);
7074 gen_helper_mtc0_ebase(cpu_env
, arg
);
7078 goto cp0_unimplemented
;
7084 gen_helper_mtc0_config0(cpu_env
, arg
);
7086 /* Stop translation as we may have switched the execution mode */
7087 ctx
->bstate
= BS_STOP
;
7090 /* ignored, read only */
7094 gen_helper_mtc0_config2(cpu_env
, arg
);
7096 /* Stop translation as we may have switched the execution mode */
7097 ctx
->bstate
= BS_STOP
;
7104 /* currently ignored */
7108 gen_helper_mtc0_config5(cpu_env
, arg
);
7110 /* Stop translation as we may have switched the execution mode */
7111 ctx
->bstate
= BS_STOP
;
7113 /* 6,7 are implementation dependent */
7115 rn
= "Invalid config selector";
7116 goto cp0_unimplemented
;
7122 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7126 goto cp0_unimplemented
;
7132 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7136 goto cp0_unimplemented
;
7142 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7146 goto cp0_unimplemented
;
7152 check_insn(ctx
, ISA_MIPS3
);
7153 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7157 goto cp0_unimplemented
;
7161 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7162 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7165 gen_helper_mtc0_framemask(cpu_env
, arg
);
7169 goto cp0_unimplemented
;
7174 rn
= "Diagnostic"; /* implementation dependent */
7179 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7180 /* BS_STOP isn't good enough here, hflags may have changed. */
7181 gen_save_pc(ctx
->pc
+ 4);
7182 ctx
->bstate
= BS_EXCP
;
7186 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7187 /* Stop translation as we may have switched the execution mode */
7188 ctx
->bstate
= BS_STOP
;
7189 rn
= "TraceControl";
7192 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7193 /* Stop translation as we may have switched the execution mode */
7194 ctx
->bstate
= BS_STOP
;
7195 rn
= "TraceControl2";
7198 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7199 /* Stop translation as we may have switched the execution mode */
7200 ctx
->bstate
= BS_STOP
;
7201 rn
= "UserTraceData";
7204 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7205 /* Stop translation as we may have switched the execution mode */
7206 ctx
->bstate
= BS_STOP
;
7210 goto cp0_unimplemented
;
7217 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7221 goto cp0_unimplemented
;
7227 gen_helper_mtc0_performance0(cpu_env
, arg
);
7228 rn
= "Performance0";
7231 // gen_helper_mtc0_performance1(cpu_env, arg);
7232 rn
= "Performance1";
7235 // gen_helper_mtc0_performance2(cpu_env, arg);
7236 rn
= "Performance2";
7239 // gen_helper_mtc0_performance3(cpu_env, arg);
7240 rn
= "Performance3";
7243 // gen_helper_mtc0_performance4(cpu_env, arg);
7244 rn
= "Performance4";
7247 // gen_helper_mtc0_performance5(cpu_env, arg);
7248 rn
= "Performance5";
7251 // gen_helper_mtc0_performance6(cpu_env, arg);
7252 rn
= "Performance6";
7255 // gen_helper_mtc0_performance7(cpu_env, arg);
7256 rn
= "Performance7";
7259 goto cp0_unimplemented
;
7273 goto cp0_unimplemented
;
7282 gen_helper_mtc0_taglo(cpu_env
, arg
);
7289 gen_helper_mtc0_datalo(cpu_env
, arg
);
7293 goto cp0_unimplemented
;
7302 gen_helper_mtc0_taghi(cpu_env
, arg
);
7309 gen_helper_mtc0_datahi(cpu_env
, arg
);
7314 goto cp0_unimplemented
;
7320 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7324 goto cp0_unimplemented
;
7331 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7335 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7336 tcg_gen_st_tl(arg
, cpu_env
,
7337 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7341 goto cp0_unimplemented
;
7343 /* Stop translation as we may have switched the execution mode */
7344 ctx
->bstate
= BS_STOP
;
7347 goto cp0_unimplemented
;
7349 (void)rn
; /* avoid a compiler warning */
7350 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7351 /* For simplicity assume that all writes can cause interrupts. */
7354 ctx
->bstate
= BS_STOP
;
7359 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7361 #endif /* TARGET_MIPS64 */
7363 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
7364 int u
, int sel
, int h
)
7366 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7367 TCGv t0
= tcg_temp_local_new();
7369 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7370 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7371 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7372 tcg_gen_movi_tl(t0
, -1);
7373 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7374 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7375 tcg_gen_movi_tl(t0
, -1);
7381 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
7384 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
7394 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
7397 gen_helper_mftc0_tcbind(t0
, cpu_env
);
7400 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
7403 gen_helper_mftc0_tchalt(t0
, cpu_env
);
7406 gen_helper_mftc0_tccontext(t0
, cpu_env
);
7409 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
7412 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
7415 gen_mfc0(ctx
, t0
, rt
, sel
);
7422 gen_helper_mftc0_entryhi(t0
, cpu_env
);
7425 gen_mfc0(ctx
, t0
, rt
, sel
);
7431 gen_helper_mftc0_status(t0
, cpu_env
);
7434 gen_mfc0(ctx
, t0
, rt
, sel
);
7440 gen_helper_mftc0_cause(t0
, cpu_env
);
7450 gen_helper_mftc0_epc(t0
, cpu_env
);
7460 gen_helper_mftc0_ebase(t0
, cpu_env
);
7470 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
7480 gen_helper_mftc0_debug(t0
, cpu_env
);
7483 gen_mfc0(ctx
, t0
, rt
, sel
);
7488 gen_mfc0(ctx
, t0
, rt
, sel
);
7490 } else switch (sel
) {
7491 /* GPR registers. */
7493 gen_helper_1e0i(mftgpr
, t0
, rt
);
7495 /* Auxiliary CPU registers */
7499 gen_helper_1e0i(mftlo
, t0
, 0);
7502 gen_helper_1e0i(mfthi
, t0
, 0);
7505 gen_helper_1e0i(mftacx
, t0
, 0);
7508 gen_helper_1e0i(mftlo
, t0
, 1);
7511 gen_helper_1e0i(mfthi
, t0
, 1);
7514 gen_helper_1e0i(mftacx
, t0
, 1);
7517 gen_helper_1e0i(mftlo
, t0
, 2);
7520 gen_helper_1e0i(mfthi
, t0
, 2);
7523 gen_helper_1e0i(mftacx
, t0
, 2);
7526 gen_helper_1e0i(mftlo
, t0
, 3);
7529 gen_helper_1e0i(mfthi
, t0
, 3);
7532 gen_helper_1e0i(mftacx
, t0
, 3);
7535 gen_helper_mftdsp(t0
, cpu_env
);
7541 /* Floating point (COP1). */
7543 /* XXX: For now we support only a single FPU context. */
7545 TCGv_i32 fp0
= tcg_temp_new_i32();
7547 gen_load_fpr32(fp0
, rt
);
7548 tcg_gen_ext_i32_tl(t0
, fp0
);
7549 tcg_temp_free_i32(fp0
);
7551 TCGv_i32 fp0
= tcg_temp_new_i32();
7553 gen_load_fpr32h(ctx
, fp0
, rt
);
7554 tcg_gen_ext_i32_tl(t0
, fp0
);
7555 tcg_temp_free_i32(fp0
);
7559 /* XXX: For now we support only a single FPU context. */
7560 gen_helper_1e0i(cfc1
, t0
, rt
);
7562 /* COP2: Not implemented. */
7569 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7570 gen_store_gpr(t0
, rd
);
7576 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7577 generate_exception(ctx
, EXCP_RI
);
7580 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
7581 int u
, int sel
, int h
)
7583 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7584 TCGv t0
= tcg_temp_local_new();
7586 gen_load_gpr(t0
, rt
);
7587 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7588 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7589 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7591 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7592 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7599 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
7602 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
7612 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
7615 gen_helper_mttc0_tcbind(cpu_env
, t0
);
7618 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
7621 gen_helper_mttc0_tchalt(cpu_env
, t0
);
7624 gen_helper_mttc0_tccontext(cpu_env
, t0
);
7627 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
7630 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
7633 gen_mtc0(ctx
, t0
, rd
, sel
);
7640 gen_helper_mttc0_entryhi(cpu_env
, t0
);
7643 gen_mtc0(ctx
, t0
, rd
, sel
);
7649 gen_helper_mttc0_status(cpu_env
, t0
);
7652 gen_mtc0(ctx
, t0
, rd
, sel
);
7658 gen_helper_mttc0_cause(cpu_env
, t0
);
7668 gen_helper_mttc0_ebase(cpu_env
, t0
);
7678 gen_helper_mttc0_debug(cpu_env
, t0
);
7681 gen_mtc0(ctx
, t0
, rd
, sel
);
7686 gen_mtc0(ctx
, t0
, rd
, sel
);
7688 } else switch (sel
) {
7689 /* GPR registers. */
7691 gen_helper_0e1i(mttgpr
, t0
, rd
);
7693 /* Auxiliary CPU registers */
7697 gen_helper_0e1i(mttlo
, t0
, 0);
7700 gen_helper_0e1i(mtthi
, t0
, 0);
7703 gen_helper_0e1i(mttacx
, t0
, 0);
7706 gen_helper_0e1i(mttlo
, t0
, 1);
7709 gen_helper_0e1i(mtthi
, t0
, 1);
7712 gen_helper_0e1i(mttacx
, t0
, 1);
7715 gen_helper_0e1i(mttlo
, t0
, 2);
7718 gen_helper_0e1i(mtthi
, t0
, 2);
7721 gen_helper_0e1i(mttacx
, t0
, 2);
7724 gen_helper_0e1i(mttlo
, t0
, 3);
7727 gen_helper_0e1i(mtthi
, t0
, 3);
7730 gen_helper_0e1i(mttacx
, t0
, 3);
7733 gen_helper_mttdsp(cpu_env
, t0
);
7739 /* Floating point (COP1). */
7741 /* XXX: For now we support only a single FPU context. */
7743 TCGv_i32 fp0
= tcg_temp_new_i32();
7745 tcg_gen_trunc_tl_i32(fp0
, t0
);
7746 gen_store_fpr32(fp0
, rd
);
7747 tcg_temp_free_i32(fp0
);
7749 TCGv_i32 fp0
= tcg_temp_new_i32();
7751 tcg_gen_trunc_tl_i32(fp0
, t0
);
7752 gen_store_fpr32h(ctx
, fp0
, rd
);
7753 tcg_temp_free_i32(fp0
);
7757 /* XXX: For now we support only a single FPU context. */
7758 save_cpu_state(ctx
, 1);
7760 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
7762 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7763 tcg_temp_free_i32(fs_tmp
);
7765 /* Stop translation as we may have changed hflags */
7766 ctx
->bstate
= BS_STOP
;
7768 /* COP2: Not implemented. */
7775 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
7781 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
7782 generate_exception(ctx
, EXCP_RI
);
7785 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
7787 const char *opn
= "ldst";
7789 check_cp0_enabled(ctx
);
7796 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
7801 TCGv t0
= tcg_temp_new();
7803 gen_load_gpr(t0
, rt
);
7804 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
7809 #if defined(TARGET_MIPS64)
7811 check_insn(ctx
, ISA_MIPS3
);
7816 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
7820 check_insn(ctx
, ISA_MIPS3
);
7822 TCGv t0
= tcg_temp_new();
7824 gen_load_gpr(t0
, rt
);
7825 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
7832 check_insn(ctx
, ASE_MT
);
7837 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
7838 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
7842 check_insn(ctx
, ASE_MT
);
7843 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
7844 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
7849 if (!env
->tlb
->helper_tlbwi
)
7851 gen_helper_tlbwi(cpu_env
);
7856 if (!env
->tlb
->helper_tlbinv
) {
7859 gen_helper_tlbinv(cpu_env
);
7860 } /* treat as nop if TLBINV not supported */
7865 if (!env
->tlb
->helper_tlbinvf
) {
7868 gen_helper_tlbinvf(cpu_env
);
7869 } /* treat as nop if TLBINV not supported */
7873 if (!env
->tlb
->helper_tlbwr
)
7875 gen_helper_tlbwr(cpu_env
);
7879 if (!env
->tlb
->helper_tlbp
)
7881 gen_helper_tlbp(cpu_env
);
7885 if (!env
->tlb
->helper_tlbr
)
7887 gen_helper_tlbr(cpu_env
);
7891 check_insn(ctx
, ISA_MIPS2
);
7892 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
7893 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
7894 MIPS_DEBUG("CTI in delay / forbidden slot");
7897 gen_helper_eret(cpu_env
);
7898 ctx
->bstate
= BS_EXCP
;
7902 check_insn(ctx
, ISA_MIPS32
);
7903 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
7904 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
7905 MIPS_DEBUG("CTI in delay / forbidden slot");
7908 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
7910 generate_exception(ctx
, EXCP_RI
);
7912 gen_helper_deret(cpu_env
);
7913 ctx
->bstate
= BS_EXCP
;
7918 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
7919 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
7920 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
7921 MIPS_DEBUG("CTI in delay / forbidden slot");
7924 /* If we get an exception, we want to restart at next instruction */
7926 save_cpu_state(ctx
, 1);
7928 gen_helper_wait(cpu_env
);
7929 ctx
->bstate
= BS_EXCP
;
7934 generate_exception(ctx
, EXCP_RI
);
7937 (void)opn
; /* avoid a compiler warning */
7938 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
7940 #endif /* !CONFIG_USER_ONLY */
7942 /* CP1 Branches (before delay slot) */
7943 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
7944 int32_t cc
, int32_t offset
)
7946 target_ulong btarget
;
7947 const char *opn
= "cp1 cond branch";
7948 TCGv_i32 t0
= tcg_temp_new_i32();
7950 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
7951 MIPS_DEBUG("CTI in delay / forbidden slot");
7952 generate_exception(ctx
, EXCP_RI
);
7957 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
7959 btarget
= ctx
->pc
+ 4 + offset
;
7963 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7964 tcg_gen_not_i32(t0
, t0
);
7965 tcg_gen_andi_i32(t0
, t0
, 1);
7966 tcg_gen_extu_i32_tl(bcond
, t0
);
7970 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7971 tcg_gen_not_i32(t0
, t0
);
7972 tcg_gen_andi_i32(t0
, t0
, 1);
7973 tcg_gen_extu_i32_tl(bcond
, t0
);
7977 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
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_andi_i32(t0
, t0
, 1);
7985 tcg_gen_extu_i32_tl(bcond
, t0
);
7988 ctx
->hflags
|= MIPS_HFLAG_BL
;
7992 TCGv_i32 t1
= tcg_temp_new_i32();
7993 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7994 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7995 tcg_gen_nand_i32(t0
, t0
, t1
);
7996 tcg_temp_free_i32(t1
);
7997 tcg_gen_andi_i32(t0
, t0
, 1);
7998 tcg_gen_extu_i32_tl(bcond
, t0
);
8004 TCGv_i32 t1
= tcg_temp_new_i32();
8005 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8006 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8007 tcg_gen_or_i32(t0
, t0
, t1
);
8008 tcg_temp_free_i32(t1
);
8009 tcg_gen_andi_i32(t0
, t0
, 1);
8010 tcg_gen_extu_i32_tl(bcond
, t0
);
8016 TCGv_i32 t1
= tcg_temp_new_i32();
8017 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8018 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8019 tcg_gen_and_i32(t0
, t0
, t1
);
8020 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8021 tcg_gen_and_i32(t0
, t0
, t1
);
8022 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8023 tcg_gen_nand_i32(t0
, t0
, t1
);
8024 tcg_temp_free_i32(t1
);
8025 tcg_gen_andi_i32(t0
, t0
, 1);
8026 tcg_gen_extu_i32_tl(bcond
, t0
);
8032 TCGv_i32 t1
= tcg_temp_new_i32();
8033 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8034 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8035 tcg_gen_or_i32(t0
, t0
, t1
);
8036 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8037 tcg_gen_or_i32(t0
, t0
, t1
);
8038 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8039 tcg_gen_or_i32(t0
, t0
, t1
);
8040 tcg_temp_free_i32(t1
);
8041 tcg_gen_andi_i32(t0
, t0
, 1);
8042 tcg_gen_extu_i32_tl(bcond
, t0
);
8046 ctx
->hflags
|= MIPS_HFLAG_BC
;
8050 generate_exception (ctx
, EXCP_RI
);
8053 (void)opn
; /* avoid a compiler warning */
8054 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
8055 ctx
->hflags
, btarget
);
8056 ctx
->btarget
= btarget
;
8057 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8059 tcg_temp_free_i32(t0
);
8062 /* R6 CP1 Branches */
8063 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
8064 int32_t ft
, int32_t offset
)
8066 target_ulong btarget
;
8067 const char *opn
= "cp1 cond branch";
8068 TCGv_i64 t0
= tcg_temp_new_i64();
8070 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
8071 #ifdef MIPS_DEBUG_DISAS
8072 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8075 generate_exception(ctx
, EXCP_RI
);
8079 gen_load_fpr64(ctx
, t0
, ft
);
8080 tcg_gen_andi_i64(t0
, t0
, 1);
8082 btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
8086 tcg_gen_xori_i64(t0
, t0
, 1);
8088 ctx
->hflags
|= MIPS_HFLAG_BC
;
8091 /* t0 already set */
8093 ctx
->hflags
|= MIPS_HFLAG_BC
;
8097 generate_exception(ctx
, EXCP_RI
);
8101 tcg_gen_trunc_i64_tl(bcond
, t0
);
8103 (void)opn
; /* avoid a compiler warning */
8104 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
8105 ctx
->hflags
, btarget
);
8106 ctx
->btarget
= btarget
;
8109 tcg_temp_free_i64(t0
);
8112 /* Coprocessor 1 (FPU) */
8114 #define FOP(func, fmt) (((fmt) << 21) | (func))
8117 OPC_ADD_S
= FOP(0, FMT_S
),
8118 OPC_SUB_S
= FOP(1, FMT_S
),
8119 OPC_MUL_S
= FOP(2, FMT_S
),
8120 OPC_DIV_S
= FOP(3, FMT_S
),
8121 OPC_SQRT_S
= FOP(4, FMT_S
),
8122 OPC_ABS_S
= FOP(5, FMT_S
),
8123 OPC_MOV_S
= FOP(6, FMT_S
),
8124 OPC_NEG_S
= FOP(7, FMT_S
),
8125 OPC_ROUND_L_S
= FOP(8, FMT_S
),
8126 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
8127 OPC_CEIL_L_S
= FOP(10, FMT_S
),
8128 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
8129 OPC_ROUND_W_S
= FOP(12, FMT_S
),
8130 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
8131 OPC_CEIL_W_S
= FOP(14, FMT_S
),
8132 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
8133 OPC_SEL_S
= FOP(16, FMT_S
),
8134 OPC_MOVCF_S
= FOP(17, FMT_S
),
8135 OPC_MOVZ_S
= FOP(18, FMT_S
),
8136 OPC_MOVN_S
= FOP(19, FMT_S
),
8137 OPC_SELEQZ_S
= FOP(20, FMT_S
),
8138 OPC_RECIP_S
= FOP(21, FMT_S
),
8139 OPC_RSQRT_S
= FOP(22, FMT_S
),
8140 OPC_SELNEZ_S
= FOP(23, FMT_S
),
8141 OPC_MADDF_S
= FOP(24, FMT_S
),
8142 OPC_MSUBF_S
= FOP(25, FMT_S
),
8143 OPC_RINT_S
= FOP(26, FMT_S
),
8144 OPC_CLASS_S
= FOP(27, FMT_S
),
8145 OPC_MIN_S
= FOP(28, FMT_S
),
8146 OPC_RECIP2_S
= FOP(28, FMT_S
),
8147 OPC_MINA_S
= FOP(29, FMT_S
),
8148 OPC_RECIP1_S
= FOP(29, FMT_S
),
8149 OPC_MAX_S
= FOP(30, FMT_S
),
8150 OPC_RSQRT1_S
= FOP(30, FMT_S
),
8151 OPC_MAXA_S
= FOP(31, FMT_S
),
8152 OPC_RSQRT2_S
= FOP(31, FMT_S
),
8153 OPC_CVT_D_S
= FOP(33, FMT_S
),
8154 OPC_CVT_W_S
= FOP(36, FMT_S
),
8155 OPC_CVT_L_S
= FOP(37, FMT_S
),
8156 OPC_CVT_PS_S
= FOP(38, FMT_S
),
8157 OPC_CMP_F_S
= FOP (48, FMT_S
),
8158 OPC_CMP_UN_S
= FOP (49, FMT_S
),
8159 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
8160 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
8161 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
8162 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
8163 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
8164 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
8165 OPC_CMP_SF_S
= FOP (56, FMT_S
),
8166 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
8167 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
8168 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
8169 OPC_CMP_LT_S
= FOP (60, FMT_S
),
8170 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
8171 OPC_CMP_LE_S
= FOP (62, FMT_S
),
8172 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
8174 OPC_ADD_D
= FOP(0, FMT_D
),
8175 OPC_SUB_D
= FOP(1, FMT_D
),
8176 OPC_MUL_D
= FOP(2, FMT_D
),
8177 OPC_DIV_D
= FOP(3, FMT_D
),
8178 OPC_SQRT_D
= FOP(4, FMT_D
),
8179 OPC_ABS_D
= FOP(5, FMT_D
),
8180 OPC_MOV_D
= FOP(6, FMT_D
),
8181 OPC_NEG_D
= FOP(7, FMT_D
),
8182 OPC_ROUND_L_D
= FOP(8, FMT_D
),
8183 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
8184 OPC_CEIL_L_D
= FOP(10, FMT_D
),
8185 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
8186 OPC_ROUND_W_D
= FOP(12, FMT_D
),
8187 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
8188 OPC_CEIL_W_D
= FOP(14, FMT_D
),
8189 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
8190 OPC_SEL_D
= FOP(16, FMT_D
),
8191 OPC_MOVCF_D
= FOP(17, FMT_D
),
8192 OPC_MOVZ_D
= FOP(18, FMT_D
),
8193 OPC_MOVN_D
= FOP(19, FMT_D
),
8194 OPC_SELEQZ_D
= FOP(20, FMT_D
),
8195 OPC_RECIP_D
= FOP(21, FMT_D
),
8196 OPC_RSQRT_D
= FOP(22, FMT_D
),
8197 OPC_SELNEZ_D
= FOP(23, FMT_D
),
8198 OPC_MADDF_D
= FOP(24, FMT_D
),
8199 OPC_MSUBF_D
= FOP(25, FMT_D
),
8200 OPC_RINT_D
= FOP(26, FMT_D
),
8201 OPC_CLASS_D
= FOP(27, FMT_D
),
8202 OPC_MIN_D
= FOP(28, FMT_D
),
8203 OPC_RECIP2_D
= FOP(28, FMT_D
),
8204 OPC_MINA_D
= FOP(29, FMT_D
),
8205 OPC_RECIP1_D
= FOP(29, FMT_D
),
8206 OPC_MAX_D
= FOP(30, FMT_D
),
8207 OPC_RSQRT1_D
= FOP(30, FMT_D
),
8208 OPC_MAXA_D
= FOP(31, FMT_D
),
8209 OPC_RSQRT2_D
= FOP(31, FMT_D
),
8210 OPC_CVT_S_D
= FOP(32, FMT_D
),
8211 OPC_CVT_W_D
= FOP(36, FMT_D
),
8212 OPC_CVT_L_D
= FOP(37, FMT_D
),
8213 OPC_CMP_F_D
= FOP (48, FMT_D
),
8214 OPC_CMP_UN_D
= FOP (49, FMT_D
),
8215 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
8216 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
8217 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
8218 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
8219 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
8220 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
8221 OPC_CMP_SF_D
= FOP (56, FMT_D
),
8222 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
8223 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
8224 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
8225 OPC_CMP_LT_D
= FOP (60, FMT_D
),
8226 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
8227 OPC_CMP_LE_D
= FOP (62, FMT_D
),
8228 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
8230 OPC_CVT_S_W
= FOP(32, FMT_W
),
8231 OPC_CVT_D_W
= FOP(33, FMT_W
),
8232 OPC_CVT_S_L
= FOP(32, FMT_L
),
8233 OPC_CVT_D_L
= FOP(33, FMT_L
),
8234 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
8236 OPC_ADD_PS
= FOP(0, FMT_PS
),
8237 OPC_SUB_PS
= FOP(1, FMT_PS
),
8238 OPC_MUL_PS
= FOP(2, FMT_PS
),
8239 OPC_DIV_PS
= FOP(3, FMT_PS
),
8240 OPC_ABS_PS
= FOP(5, FMT_PS
),
8241 OPC_MOV_PS
= FOP(6, FMT_PS
),
8242 OPC_NEG_PS
= FOP(7, FMT_PS
),
8243 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
8244 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
8245 OPC_MOVN_PS
= FOP(19, FMT_PS
),
8246 OPC_ADDR_PS
= FOP(24, FMT_PS
),
8247 OPC_MULR_PS
= FOP(26, FMT_PS
),
8248 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
8249 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
8250 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
8251 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
8253 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
8254 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
8255 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
8256 OPC_PLL_PS
= FOP(44, FMT_PS
),
8257 OPC_PLU_PS
= FOP(45, FMT_PS
),
8258 OPC_PUL_PS
= FOP(46, FMT_PS
),
8259 OPC_PUU_PS
= FOP(47, FMT_PS
),
8260 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
8261 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
8262 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
8263 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
8264 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
8265 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
8266 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
8267 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
8268 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
8269 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
8270 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
8271 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
8272 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
8273 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
8274 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
8275 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
8279 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
8280 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
8281 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
8282 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
8283 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
8284 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
8285 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
8286 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
8287 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
8288 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
8289 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
8290 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
8291 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
8292 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
8293 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
8294 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
8295 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
8296 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
8297 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
8298 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
8299 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
8300 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
8302 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
8303 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
8304 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
8305 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
8306 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
8307 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
8308 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
8309 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
8310 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
8311 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
8312 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
8313 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
8314 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
8315 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
8316 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
8317 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
8318 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
8319 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
8320 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
8321 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
8322 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
8323 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
8325 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
8327 const char *opn
= "cp1 move";
8328 TCGv t0
= tcg_temp_new();
8333 TCGv_i32 fp0
= tcg_temp_new_i32();
8335 gen_load_fpr32(fp0
, fs
);
8336 tcg_gen_ext_i32_tl(t0
, fp0
);
8337 tcg_temp_free_i32(fp0
);
8339 gen_store_gpr(t0
, rt
);
8343 gen_load_gpr(t0
, rt
);
8345 TCGv_i32 fp0
= tcg_temp_new_i32();
8347 tcg_gen_trunc_tl_i32(fp0
, t0
);
8348 gen_store_fpr32(fp0
, fs
);
8349 tcg_temp_free_i32(fp0
);
8354 gen_helper_1e0i(cfc1
, t0
, fs
);
8355 gen_store_gpr(t0
, rt
);
8359 gen_load_gpr(t0
, rt
);
8360 save_cpu_state(ctx
, 1);
8362 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
8364 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8365 tcg_temp_free_i32(fs_tmp
);
8367 /* Stop translation as we may have changed hflags */
8368 ctx
->bstate
= BS_STOP
;
8371 #if defined(TARGET_MIPS64)
8373 gen_load_fpr64(ctx
, t0
, fs
);
8374 gen_store_gpr(t0
, rt
);
8378 gen_load_gpr(t0
, rt
);
8379 gen_store_fpr64(ctx
, t0
, fs
);
8385 TCGv_i32 fp0
= tcg_temp_new_i32();
8387 gen_load_fpr32h(ctx
, fp0
, fs
);
8388 tcg_gen_ext_i32_tl(t0
, fp0
);
8389 tcg_temp_free_i32(fp0
);
8391 gen_store_gpr(t0
, rt
);
8395 gen_load_gpr(t0
, rt
);
8397 TCGv_i32 fp0
= tcg_temp_new_i32();
8399 tcg_gen_trunc_tl_i32(fp0
, t0
);
8400 gen_store_fpr32h(ctx
, fp0
, fs
);
8401 tcg_temp_free_i32(fp0
);
8407 generate_exception (ctx
, EXCP_RI
);
8410 (void)opn
; /* avoid a compiler warning */
8411 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
8417 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
8433 l1
= gen_new_label();
8434 t0
= tcg_temp_new_i32();
8435 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8436 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8437 tcg_temp_free_i32(t0
);
8439 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
8441 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
8446 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
8449 TCGv_i32 t0
= tcg_temp_new_i32();
8450 int l1
= gen_new_label();
8457 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8458 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8459 gen_load_fpr32(t0
, fs
);
8460 gen_store_fpr32(t0
, fd
);
8462 tcg_temp_free_i32(t0
);
8465 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
8468 TCGv_i32 t0
= tcg_temp_new_i32();
8470 int l1
= gen_new_label();
8477 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8478 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8479 tcg_temp_free_i32(t0
);
8480 fp0
= tcg_temp_new_i64();
8481 gen_load_fpr64(ctx
, fp0
, fs
);
8482 gen_store_fpr64(ctx
, fp0
, fd
);
8483 tcg_temp_free_i64(fp0
);
8487 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
8491 TCGv_i32 t0
= tcg_temp_new_i32();
8492 int l1
= gen_new_label();
8493 int l2
= gen_new_label();
8500 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8501 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8502 gen_load_fpr32(t0
, fs
);
8503 gen_store_fpr32(t0
, fd
);
8506 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
8507 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
8508 gen_load_fpr32h(ctx
, t0
, fs
);
8509 gen_store_fpr32h(ctx
, t0
, fd
);
8510 tcg_temp_free_i32(t0
);
8514 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8517 TCGv_i32 t1
= tcg_const_i32(0);
8518 TCGv_i32 fp0
= tcg_temp_new_i32();
8519 TCGv_i32 fp1
= tcg_temp_new_i32();
8520 TCGv_i32 fp2
= tcg_temp_new_i32();
8521 gen_load_fpr32(fp0
, fd
);
8522 gen_load_fpr32(fp1
, ft
);
8523 gen_load_fpr32(fp2
, fs
);
8527 tcg_gen_andi_i32(fp0
, fp0
, 1);
8528 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8531 tcg_gen_andi_i32(fp1
, fp1
, 1);
8532 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8535 tcg_gen_andi_i32(fp1
, fp1
, 1);
8536 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8539 MIPS_INVAL("gen_sel_s");
8540 generate_exception (ctx
, EXCP_RI
);
8544 gen_store_fpr32(fp0
, fd
);
8545 tcg_temp_free_i32(fp2
);
8546 tcg_temp_free_i32(fp1
);
8547 tcg_temp_free_i32(fp0
);
8548 tcg_temp_free_i32(t1
);
8551 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8554 TCGv_i64 t1
= tcg_const_i64(0);
8555 TCGv_i64 fp0
= tcg_temp_new_i64();
8556 TCGv_i64 fp1
= tcg_temp_new_i64();
8557 TCGv_i64 fp2
= tcg_temp_new_i64();
8558 gen_load_fpr64(ctx
, fp0
, fd
);
8559 gen_load_fpr64(ctx
, fp1
, ft
);
8560 gen_load_fpr64(ctx
, fp2
, fs
);
8564 tcg_gen_andi_i64(fp0
, fp0
, 1);
8565 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8568 tcg_gen_andi_i64(fp1
, fp1
, 1);
8569 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8572 tcg_gen_andi_i64(fp1
, fp1
, 1);
8573 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8576 MIPS_INVAL("gen_sel_d");
8577 generate_exception (ctx
, EXCP_RI
);
8581 gen_store_fpr64(ctx
, fp0
, fd
);
8582 tcg_temp_free_i64(fp2
);
8583 tcg_temp_free_i64(fp1
);
8584 tcg_temp_free_i64(fp0
);
8585 tcg_temp_free_i64(t1
);
8588 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
8589 int ft
, int fs
, int fd
, int cc
)
8591 const char *opn
= "farith";
8592 const char *condnames
[] = {
8610 const char *condnames_abs
[] = {
8628 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
8629 uint32_t func
= ctx
->opcode
& 0x3f;
8634 TCGv_i32 fp0
= tcg_temp_new_i32();
8635 TCGv_i32 fp1
= tcg_temp_new_i32();
8637 gen_load_fpr32(fp0
, fs
);
8638 gen_load_fpr32(fp1
, ft
);
8639 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
8640 tcg_temp_free_i32(fp1
);
8641 gen_store_fpr32(fp0
, fd
);
8642 tcg_temp_free_i32(fp0
);
8649 TCGv_i32 fp0
= tcg_temp_new_i32();
8650 TCGv_i32 fp1
= tcg_temp_new_i32();
8652 gen_load_fpr32(fp0
, fs
);
8653 gen_load_fpr32(fp1
, ft
);
8654 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
8655 tcg_temp_free_i32(fp1
);
8656 gen_store_fpr32(fp0
, fd
);
8657 tcg_temp_free_i32(fp0
);
8664 TCGv_i32 fp0
= tcg_temp_new_i32();
8665 TCGv_i32 fp1
= tcg_temp_new_i32();
8667 gen_load_fpr32(fp0
, fs
);
8668 gen_load_fpr32(fp1
, ft
);
8669 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
8670 tcg_temp_free_i32(fp1
);
8671 gen_store_fpr32(fp0
, fd
);
8672 tcg_temp_free_i32(fp0
);
8679 TCGv_i32 fp0
= tcg_temp_new_i32();
8680 TCGv_i32 fp1
= tcg_temp_new_i32();
8682 gen_load_fpr32(fp0
, fs
);
8683 gen_load_fpr32(fp1
, ft
);
8684 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
8685 tcg_temp_free_i32(fp1
);
8686 gen_store_fpr32(fp0
, fd
);
8687 tcg_temp_free_i32(fp0
);
8694 TCGv_i32 fp0
= tcg_temp_new_i32();
8696 gen_load_fpr32(fp0
, fs
);
8697 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
8698 gen_store_fpr32(fp0
, fd
);
8699 tcg_temp_free_i32(fp0
);
8705 TCGv_i32 fp0
= tcg_temp_new_i32();
8707 gen_load_fpr32(fp0
, fs
);
8708 gen_helper_float_abs_s(fp0
, fp0
);
8709 gen_store_fpr32(fp0
, fd
);
8710 tcg_temp_free_i32(fp0
);
8716 TCGv_i32 fp0
= tcg_temp_new_i32();
8718 gen_load_fpr32(fp0
, fs
);
8719 gen_store_fpr32(fp0
, fd
);
8720 tcg_temp_free_i32(fp0
);
8726 TCGv_i32 fp0
= tcg_temp_new_i32();
8728 gen_load_fpr32(fp0
, fs
);
8729 gen_helper_float_chs_s(fp0
, fp0
);
8730 gen_store_fpr32(fp0
, fd
);
8731 tcg_temp_free_i32(fp0
);
8736 check_cp1_64bitmode(ctx
);
8738 TCGv_i32 fp32
= tcg_temp_new_i32();
8739 TCGv_i64 fp64
= tcg_temp_new_i64();
8741 gen_load_fpr32(fp32
, fs
);
8742 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
8743 tcg_temp_free_i32(fp32
);
8744 gen_store_fpr64(ctx
, fp64
, fd
);
8745 tcg_temp_free_i64(fp64
);
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_truncl_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_ceill_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_floorl_s(fp64
, cpu_env
, fp32
);
8785 tcg_temp_free_i32(fp32
);
8786 gen_store_fpr64(ctx
, fp64
, fd
);
8787 tcg_temp_free_i64(fp64
);
8793 TCGv_i32 fp0
= tcg_temp_new_i32();
8795 gen_load_fpr32(fp0
, fs
);
8796 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
8797 gen_store_fpr32(fp0
, fd
);
8798 tcg_temp_free_i32(fp0
);
8804 TCGv_i32 fp0
= tcg_temp_new_i32();
8806 gen_load_fpr32(fp0
, fs
);
8807 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
8808 gen_store_fpr32(fp0
, fd
);
8809 tcg_temp_free_i32(fp0
);
8815 TCGv_i32 fp0
= tcg_temp_new_i32();
8817 gen_load_fpr32(fp0
, fs
);
8818 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
8819 gen_store_fpr32(fp0
, fd
);
8820 tcg_temp_free_i32(fp0
);
8826 TCGv_i32 fp0
= tcg_temp_new_i32();
8828 gen_load_fpr32(fp0
, fs
);
8829 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
8830 gen_store_fpr32(fp0
, fd
);
8831 tcg_temp_free_i32(fp0
);
8836 check_insn(ctx
, ISA_MIPS32R6
);
8837 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8841 check_insn(ctx
, ISA_MIPS32R6
);
8842 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8846 check_insn(ctx
, ISA_MIPS32R6
);
8847 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8851 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8852 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8856 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8858 int l1
= gen_new_label();
8862 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8864 fp0
= tcg_temp_new_i32();
8865 gen_load_fpr32(fp0
, fs
);
8866 gen_store_fpr32(fp0
, fd
);
8867 tcg_temp_free_i32(fp0
);
8873 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8875 int l1
= gen_new_label();
8879 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8880 fp0
= tcg_temp_new_i32();
8881 gen_load_fpr32(fp0
, fs
);
8882 gen_store_fpr32(fp0
, fd
);
8883 tcg_temp_free_i32(fp0
);
8892 TCGv_i32 fp0
= tcg_temp_new_i32();
8894 gen_load_fpr32(fp0
, fs
);
8895 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
8896 gen_store_fpr32(fp0
, fd
);
8897 tcg_temp_free_i32(fp0
);
8904 TCGv_i32 fp0
= tcg_temp_new_i32();
8906 gen_load_fpr32(fp0
, fs
);
8907 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
8908 gen_store_fpr32(fp0
, fd
);
8909 tcg_temp_free_i32(fp0
);
8914 check_insn(ctx
, ISA_MIPS32R6
);
8916 TCGv_i32 fp0
= tcg_temp_new_i32();
8917 TCGv_i32 fp1
= tcg_temp_new_i32();
8918 TCGv_i32 fp2
= tcg_temp_new_i32();
8919 gen_load_fpr32(fp0
, fs
);
8920 gen_load_fpr32(fp1
, ft
);
8921 gen_load_fpr32(fp2
, fd
);
8922 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8923 gen_store_fpr32(fp2
, fd
);
8924 tcg_temp_free_i32(fp2
);
8925 tcg_temp_free_i32(fp1
);
8926 tcg_temp_free_i32(fp0
);
8931 check_insn(ctx
, ISA_MIPS32R6
);
8933 TCGv_i32 fp0
= tcg_temp_new_i32();
8934 TCGv_i32 fp1
= tcg_temp_new_i32();
8935 TCGv_i32 fp2
= tcg_temp_new_i32();
8936 gen_load_fpr32(fp0
, fs
);
8937 gen_load_fpr32(fp1
, ft
);
8938 gen_load_fpr32(fp2
, fd
);
8939 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8940 gen_store_fpr32(fp2
, fd
);
8941 tcg_temp_free_i32(fp2
);
8942 tcg_temp_free_i32(fp1
);
8943 tcg_temp_free_i32(fp0
);
8948 check_insn(ctx
, ISA_MIPS32R6
);
8950 TCGv_i32 fp0
= tcg_temp_new_i32();
8951 gen_load_fpr32(fp0
, fs
);
8952 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
8953 gen_store_fpr32(fp0
, fd
);
8954 tcg_temp_free_i32(fp0
);
8959 check_insn(ctx
, ISA_MIPS32R6
);
8961 TCGv_i32 fp0
= tcg_temp_new_i32();
8962 gen_load_fpr32(fp0
, fs
);
8963 gen_helper_float_class_s(fp0
, fp0
);
8964 gen_store_fpr32(fp0
, fd
);
8965 tcg_temp_free_i32(fp0
);
8969 case OPC_MIN_S
: /* OPC_RECIP2_S */
8970 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8972 TCGv_i32 fp0
= tcg_temp_new_i32();
8973 TCGv_i32 fp1
= tcg_temp_new_i32();
8974 TCGv_i32 fp2
= tcg_temp_new_i32();
8975 gen_load_fpr32(fp0
, fs
);
8976 gen_load_fpr32(fp1
, ft
);
8977 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
8978 gen_store_fpr32(fp2
, fd
);
8979 tcg_temp_free_i32(fp2
);
8980 tcg_temp_free_i32(fp1
);
8981 tcg_temp_free_i32(fp0
);
8985 check_cp1_64bitmode(ctx
);
8987 TCGv_i32 fp0
= tcg_temp_new_i32();
8988 TCGv_i32 fp1
= tcg_temp_new_i32();
8990 gen_load_fpr32(fp0
, fs
);
8991 gen_load_fpr32(fp1
, ft
);
8992 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
8993 tcg_temp_free_i32(fp1
);
8994 gen_store_fpr32(fp0
, fd
);
8995 tcg_temp_free_i32(fp0
);
9000 case OPC_MINA_S
: /* OPC_RECIP1_S */
9001 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9003 TCGv_i32 fp0
= tcg_temp_new_i32();
9004 TCGv_i32 fp1
= tcg_temp_new_i32();
9005 TCGv_i32 fp2
= tcg_temp_new_i32();
9006 gen_load_fpr32(fp0
, fs
);
9007 gen_load_fpr32(fp1
, ft
);
9008 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
9009 gen_store_fpr32(fp2
, fd
);
9010 tcg_temp_free_i32(fp2
);
9011 tcg_temp_free_i32(fp1
);
9012 tcg_temp_free_i32(fp0
);
9016 check_cp1_64bitmode(ctx
);
9018 TCGv_i32 fp0
= tcg_temp_new_i32();
9020 gen_load_fpr32(fp0
, fs
);
9021 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
9022 gen_store_fpr32(fp0
, fd
);
9023 tcg_temp_free_i32(fp0
);
9028 case OPC_MAX_S
: /* OPC_RSQRT1_S */
9029 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9031 TCGv_i32 fp0
= tcg_temp_new_i32();
9032 TCGv_i32 fp1
= tcg_temp_new_i32();
9033 gen_load_fpr32(fp0
, fs
);
9034 gen_load_fpr32(fp1
, ft
);
9035 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
9036 gen_store_fpr32(fp1
, fd
);
9037 tcg_temp_free_i32(fp1
);
9038 tcg_temp_free_i32(fp0
);
9042 check_cp1_64bitmode(ctx
);
9044 TCGv_i32 fp0
= tcg_temp_new_i32();
9046 gen_load_fpr32(fp0
, fs
);
9047 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
9048 gen_store_fpr32(fp0
, fd
);
9049 tcg_temp_free_i32(fp0
);
9054 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
9055 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9057 TCGv_i32 fp0
= tcg_temp_new_i32();
9058 TCGv_i32 fp1
= tcg_temp_new_i32();
9059 gen_load_fpr32(fp0
, fs
);
9060 gen_load_fpr32(fp1
, ft
);
9061 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
9062 gen_store_fpr32(fp1
, fd
);
9063 tcg_temp_free_i32(fp1
);
9064 tcg_temp_free_i32(fp0
);
9068 check_cp1_64bitmode(ctx
);
9070 TCGv_i32 fp0
= tcg_temp_new_i32();
9071 TCGv_i32 fp1
= tcg_temp_new_i32();
9073 gen_load_fpr32(fp0
, fs
);
9074 gen_load_fpr32(fp1
, ft
);
9075 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
9076 tcg_temp_free_i32(fp1
);
9077 gen_store_fpr32(fp0
, fd
);
9078 tcg_temp_free_i32(fp0
);
9084 check_cp1_registers(ctx
, fd
);
9086 TCGv_i32 fp32
= tcg_temp_new_i32();
9087 TCGv_i64 fp64
= tcg_temp_new_i64();
9089 gen_load_fpr32(fp32
, fs
);
9090 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
9091 tcg_temp_free_i32(fp32
);
9092 gen_store_fpr64(ctx
, fp64
, fd
);
9093 tcg_temp_free_i64(fp64
);
9099 TCGv_i32 fp0
= tcg_temp_new_i32();
9101 gen_load_fpr32(fp0
, fs
);
9102 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
9103 gen_store_fpr32(fp0
, fd
);
9104 tcg_temp_free_i32(fp0
);
9109 check_cp1_64bitmode(ctx
);
9111 TCGv_i32 fp32
= tcg_temp_new_i32();
9112 TCGv_i64 fp64
= tcg_temp_new_i64();
9114 gen_load_fpr32(fp32
, fs
);
9115 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
9116 tcg_temp_free_i32(fp32
);
9117 gen_store_fpr64(ctx
, fp64
, fd
);
9118 tcg_temp_free_i64(fp64
);
9123 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9124 check_cp1_64bitmode(ctx
);
9126 TCGv_i64 fp64
= tcg_temp_new_i64();
9127 TCGv_i32 fp32_0
= tcg_temp_new_i32();
9128 TCGv_i32 fp32_1
= tcg_temp_new_i32();
9130 gen_load_fpr32(fp32_0
, fs
);
9131 gen_load_fpr32(fp32_1
, ft
);
9132 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
9133 tcg_temp_free_i32(fp32_1
);
9134 tcg_temp_free_i32(fp32_0
);
9135 gen_store_fpr64(ctx
, fp64
, fd
);
9136 tcg_temp_free_i64(fp64
);
9149 case OPC_CMP_NGLE_S
:
9156 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9157 if (ctx
->opcode
& (1 << 6)) {
9158 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
9159 opn
= condnames_abs
[func
-48];
9161 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
9162 opn
= condnames
[func
-48];
9166 check_cp1_registers(ctx
, fs
| ft
| fd
);
9168 TCGv_i64 fp0
= tcg_temp_new_i64();
9169 TCGv_i64 fp1
= tcg_temp_new_i64();
9171 gen_load_fpr64(ctx
, fp0
, fs
);
9172 gen_load_fpr64(ctx
, fp1
, ft
);
9173 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
9174 tcg_temp_free_i64(fp1
);
9175 gen_store_fpr64(ctx
, fp0
, fd
);
9176 tcg_temp_free_i64(fp0
);
9182 check_cp1_registers(ctx
, fs
| ft
| fd
);
9184 TCGv_i64 fp0
= tcg_temp_new_i64();
9185 TCGv_i64 fp1
= tcg_temp_new_i64();
9187 gen_load_fpr64(ctx
, fp0
, fs
);
9188 gen_load_fpr64(ctx
, fp1
, ft
);
9189 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
9190 tcg_temp_free_i64(fp1
);
9191 gen_store_fpr64(ctx
, fp0
, fd
);
9192 tcg_temp_free_i64(fp0
);
9198 check_cp1_registers(ctx
, fs
| ft
| fd
);
9200 TCGv_i64 fp0
= tcg_temp_new_i64();
9201 TCGv_i64 fp1
= tcg_temp_new_i64();
9203 gen_load_fpr64(ctx
, fp0
, fs
);
9204 gen_load_fpr64(ctx
, fp1
, ft
);
9205 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
9206 tcg_temp_free_i64(fp1
);
9207 gen_store_fpr64(ctx
, fp0
, fd
);
9208 tcg_temp_free_i64(fp0
);
9214 check_cp1_registers(ctx
, fs
| ft
| fd
);
9216 TCGv_i64 fp0
= tcg_temp_new_i64();
9217 TCGv_i64 fp1
= tcg_temp_new_i64();
9219 gen_load_fpr64(ctx
, fp0
, fs
);
9220 gen_load_fpr64(ctx
, fp1
, ft
);
9221 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
9222 tcg_temp_free_i64(fp1
);
9223 gen_store_fpr64(ctx
, fp0
, fd
);
9224 tcg_temp_free_i64(fp0
);
9230 check_cp1_registers(ctx
, fs
| fd
);
9232 TCGv_i64 fp0
= tcg_temp_new_i64();
9234 gen_load_fpr64(ctx
, fp0
, fs
);
9235 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
9236 gen_store_fpr64(ctx
, fp0
, fd
);
9237 tcg_temp_free_i64(fp0
);
9242 check_cp1_registers(ctx
, fs
| fd
);
9244 TCGv_i64 fp0
= tcg_temp_new_i64();
9246 gen_load_fpr64(ctx
, fp0
, fs
);
9247 gen_helper_float_abs_d(fp0
, fp0
);
9248 gen_store_fpr64(ctx
, fp0
, fd
);
9249 tcg_temp_free_i64(fp0
);
9254 check_cp1_registers(ctx
, fs
| fd
);
9256 TCGv_i64 fp0
= tcg_temp_new_i64();
9258 gen_load_fpr64(ctx
, fp0
, fs
);
9259 gen_store_fpr64(ctx
, fp0
, fd
);
9260 tcg_temp_free_i64(fp0
);
9265 check_cp1_registers(ctx
, fs
| fd
);
9267 TCGv_i64 fp0
= tcg_temp_new_i64();
9269 gen_load_fpr64(ctx
, fp0
, fs
);
9270 gen_helper_float_chs_d(fp0
, fp0
);
9271 gen_store_fpr64(ctx
, fp0
, fd
);
9272 tcg_temp_free_i64(fp0
);
9277 check_cp1_64bitmode(ctx
);
9279 TCGv_i64 fp0
= tcg_temp_new_i64();
9281 gen_load_fpr64(ctx
, fp0
, fs
);
9282 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
9283 gen_store_fpr64(ctx
, fp0
, fd
);
9284 tcg_temp_free_i64(fp0
);
9289 check_cp1_64bitmode(ctx
);
9291 TCGv_i64 fp0
= tcg_temp_new_i64();
9293 gen_load_fpr64(ctx
, fp0
, fs
);
9294 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
9295 gen_store_fpr64(ctx
, fp0
, fd
);
9296 tcg_temp_free_i64(fp0
);
9301 check_cp1_64bitmode(ctx
);
9303 TCGv_i64 fp0
= tcg_temp_new_i64();
9305 gen_load_fpr64(ctx
, fp0
, fs
);
9306 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
9307 gen_store_fpr64(ctx
, fp0
, fd
);
9308 tcg_temp_free_i64(fp0
);
9313 check_cp1_64bitmode(ctx
);
9315 TCGv_i64 fp0
= tcg_temp_new_i64();
9317 gen_load_fpr64(ctx
, fp0
, fs
);
9318 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
9319 gen_store_fpr64(ctx
, fp0
, fd
);
9320 tcg_temp_free_i64(fp0
);
9325 check_cp1_registers(ctx
, fs
);
9327 TCGv_i32 fp32
= tcg_temp_new_i32();
9328 TCGv_i64 fp64
= tcg_temp_new_i64();
9330 gen_load_fpr64(ctx
, fp64
, fs
);
9331 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
9332 tcg_temp_free_i64(fp64
);
9333 gen_store_fpr32(fp32
, fd
);
9334 tcg_temp_free_i32(fp32
);
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_truncw_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_ceilw_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_floorw_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_insn(ctx
, ISA_MIPS32R6
);
9382 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9386 check_insn(ctx
, ISA_MIPS32R6
);
9387 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9391 check_insn(ctx
, ISA_MIPS32R6
);
9392 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9396 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9397 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9401 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9403 int l1
= gen_new_label();
9407 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9409 fp0
= tcg_temp_new_i64();
9410 gen_load_fpr64(ctx
, fp0
, fs
);
9411 gen_store_fpr64(ctx
, fp0
, fd
);
9412 tcg_temp_free_i64(fp0
);
9418 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9420 int l1
= gen_new_label();
9424 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9425 fp0
= tcg_temp_new_i64();
9426 gen_load_fpr64(ctx
, fp0
, fs
);
9427 gen_store_fpr64(ctx
, fp0
, fd
);
9428 tcg_temp_free_i64(fp0
);
9435 check_cp1_64bitmode(ctx
);
9437 TCGv_i64 fp0
= tcg_temp_new_i64();
9439 gen_load_fpr64(ctx
, fp0
, fs
);
9440 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
9441 gen_store_fpr64(ctx
, fp0
, fd
);
9442 tcg_temp_free_i64(fp0
);
9447 check_cp1_64bitmode(ctx
);
9449 TCGv_i64 fp0
= tcg_temp_new_i64();
9451 gen_load_fpr64(ctx
, fp0
, fs
);
9452 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
9453 gen_store_fpr64(ctx
, fp0
, fd
);
9454 tcg_temp_free_i64(fp0
);
9459 check_insn(ctx
, ISA_MIPS32R6
);
9461 TCGv_i64 fp0
= tcg_temp_new_i64();
9462 TCGv_i64 fp1
= tcg_temp_new_i64();
9463 TCGv_i64 fp2
= tcg_temp_new_i64();
9464 gen_load_fpr64(ctx
, fp0
, fs
);
9465 gen_load_fpr64(ctx
, fp1
, ft
);
9466 gen_load_fpr64(ctx
, fp2
, fd
);
9467 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9468 gen_store_fpr64(ctx
, fp2
, fd
);
9469 tcg_temp_free_i64(fp2
);
9470 tcg_temp_free_i64(fp1
);
9471 tcg_temp_free_i64(fp0
);
9476 check_insn(ctx
, ISA_MIPS32R6
);
9478 TCGv_i64 fp0
= tcg_temp_new_i64();
9479 TCGv_i64 fp1
= tcg_temp_new_i64();
9480 TCGv_i64 fp2
= tcg_temp_new_i64();
9481 gen_load_fpr64(ctx
, fp0
, fs
);
9482 gen_load_fpr64(ctx
, fp1
, ft
);
9483 gen_load_fpr64(ctx
, fp2
, fd
);
9484 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9485 gen_store_fpr64(ctx
, fp2
, fd
);
9486 tcg_temp_free_i64(fp2
);
9487 tcg_temp_free_i64(fp1
);
9488 tcg_temp_free_i64(fp0
);
9493 check_insn(ctx
, ISA_MIPS32R6
);
9495 TCGv_i64 fp0
= tcg_temp_new_i64();
9496 gen_load_fpr64(ctx
, fp0
, fs
);
9497 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
9498 gen_store_fpr64(ctx
, fp0
, fd
);
9499 tcg_temp_free_i64(fp0
);
9504 check_insn(ctx
, ISA_MIPS32R6
);
9506 TCGv_i64 fp0
= tcg_temp_new_i64();
9507 gen_load_fpr64(ctx
, fp0
, fs
);
9508 gen_helper_float_class_d(fp0
, fp0
);
9509 gen_store_fpr64(ctx
, fp0
, fd
);
9510 tcg_temp_free_i64(fp0
);
9514 case OPC_MIN_D
: /* OPC_RECIP2_D */
9515 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9517 TCGv_i64 fp0
= tcg_temp_new_i64();
9518 TCGv_i64 fp1
= tcg_temp_new_i64();
9519 gen_load_fpr64(ctx
, fp0
, fs
);
9520 gen_load_fpr64(ctx
, fp1
, ft
);
9521 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
9522 gen_store_fpr64(ctx
, fp1
, fd
);
9523 tcg_temp_free_i64(fp1
);
9524 tcg_temp_free_i64(fp0
);
9528 check_cp1_64bitmode(ctx
);
9530 TCGv_i64 fp0
= tcg_temp_new_i64();
9531 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_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
9536 tcg_temp_free_i64(fp1
);
9537 gen_store_fpr64(ctx
, fp0
, fd
);
9538 tcg_temp_free_i64(fp0
);
9543 case OPC_MINA_D
: /* OPC_RECIP1_D */
9544 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9546 TCGv_i64 fp0
= tcg_temp_new_i64();
9547 TCGv_i64 fp1
= tcg_temp_new_i64();
9548 gen_load_fpr64(ctx
, fp0
, fs
);
9549 gen_load_fpr64(ctx
, fp1
, ft
);
9550 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
9551 gen_store_fpr64(ctx
, fp1
, fd
);
9552 tcg_temp_free_i64(fp1
);
9553 tcg_temp_free_i64(fp0
);
9557 check_cp1_64bitmode(ctx
);
9559 TCGv_i64 fp0
= tcg_temp_new_i64();
9561 gen_load_fpr64(ctx
, fp0
, fs
);
9562 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
9563 gen_store_fpr64(ctx
, fp0
, fd
);
9564 tcg_temp_free_i64(fp0
);
9569 case OPC_MAX_D
: /* OPC_RSQRT1_D */
9570 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9572 TCGv_i64 fp0
= tcg_temp_new_i64();
9573 TCGv_i64 fp1
= tcg_temp_new_i64();
9574 gen_load_fpr64(ctx
, fp0
, fs
);
9575 gen_load_fpr64(ctx
, fp1
, ft
);
9576 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
9577 gen_store_fpr64(ctx
, fp1
, fd
);
9578 tcg_temp_free_i64(fp1
);
9579 tcg_temp_free_i64(fp0
);
9583 check_cp1_64bitmode(ctx
);
9585 TCGv_i64 fp0
= tcg_temp_new_i64();
9587 gen_load_fpr64(ctx
, fp0
, fs
);
9588 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
9589 gen_store_fpr64(ctx
, fp0
, fd
);
9590 tcg_temp_free_i64(fp0
);
9595 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
9596 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9598 TCGv_i64 fp0
= tcg_temp_new_i64();
9599 TCGv_i64 fp1
= tcg_temp_new_i64();
9600 gen_load_fpr64(ctx
, fp0
, fs
);
9601 gen_load_fpr64(ctx
, fp1
, ft
);
9602 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
9603 gen_store_fpr64(ctx
, fp1
, fd
);
9604 tcg_temp_free_i64(fp1
);
9605 tcg_temp_free_i64(fp0
);
9609 check_cp1_64bitmode(ctx
);
9611 TCGv_i64 fp0
= tcg_temp_new_i64();
9612 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_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
9617 tcg_temp_free_i64(fp1
);
9618 gen_store_fpr64(ctx
, fp0
, fd
);
9619 tcg_temp_free_i64(fp0
);
9633 case OPC_CMP_NGLE_D
:
9640 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9641 if (ctx
->opcode
& (1 << 6)) {
9642 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
9643 opn
= condnames_abs
[func
-48];
9645 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
9646 opn
= condnames
[func
-48];
9650 check_cp1_registers(ctx
, fs
);
9652 TCGv_i32 fp32
= tcg_temp_new_i32();
9653 TCGv_i64 fp64
= tcg_temp_new_i64();
9655 gen_load_fpr64(ctx
, fp64
, fs
);
9656 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
9657 tcg_temp_free_i64(fp64
);
9658 gen_store_fpr32(fp32
, fd
);
9659 tcg_temp_free_i32(fp32
);
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_cvtw_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_64bitmode(ctx
);
9680 TCGv_i64 fp0
= tcg_temp_new_i64();
9682 gen_load_fpr64(ctx
, fp0
, fs
);
9683 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
9684 gen_store_fpr64(ctx
, fp0
, fd
);
9685 tcg_temp_free_i64(fp0
);
9691 TCGv_i32 fp0
= tcg_temp_new_i32();
9693 gen_load_fpr32(fp0
, fs
);
9694 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
9695 gen_store_fpr32(fp0
, fd
);
9696 tcg_temp_free_i32(fp0
);
9701 check_cp1_registers(ctx
, fd
);
9703 TCGv_i32 fp32
= tcg_temp_new_i32();
9704 TCGv_i64 fp64
= tcg_temp_new_i64();
9706 gen_load_fpr32(fp32
, fs
);
9707 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
9708 tcg_temp_free_i32(fp32
);
9709 gen_store_fpr64(ctx
, fp64
, fd
);
9710 tcg_temp_free_i64(fp64
);
9715 check_cp1_64bitmode(ctx
);
9717 TCGv_i32 fp32
= tcg_temp_new_i32();
9718 TCGv_i64 fp64
= tcg_temp_new_i64();
9720 gen_load_fpr64(ctx
, fp64
, fs
);
9721 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
9722 tcg_temp_free_i64(fp64
);
9723 gen_store_fpr32(fp32
, fd
);
9724 tcg_temp_free_i32(fp32
);
9729 check_cp1_64bitmode(ctx
);
9731 TCGv_i64 fp0
= tcg_temp_new_i64();
9733 gen_load_fpr64(ctx
, fp0
, fs
);
9734 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
9735 gen_store_fpr64(ctx
, fp0
, fd
);
9736 tcg_temp_free_i64(fp0
);
9741 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9742 check_cp1_64bitmode(ctx
);
9744 TCGv_i64 fp0
= tcg_temp_new_i64();
9746 gen_load_fpr64(ctx
, fp0
, fs
);
9747 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
9748 gen_store_fpr64(ctx
, fp0
, fd
);
9749 tcg_temp_free_i64(fp0
);
9754 check_cp1_64bitmode(ctx
);
9756 TCGv_i64 fp0
= tcg_temp_new_i64();
9757 TCGv_i64 fp1
= tcg_temp_new_i64();
9759 gen_load_fpr64(ctx
, fp0
, fs
);
9760 gen_load_fpr64(ctx
, fp1
, ft
);
9761 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
9762 tcg_temp_free_i64(fp1
);
9763 gen_store_fpr64(ctx
, fp0
, fd
);
9764 tcg_temp_free_i64(fp0
);
9769 check_cp1_64bitmode(ctx
);
9771 TCGv_i64 fp0
= tcg_temp_new_i64();
9772 TCGv_i64 fp1
= tcg_temp_new_i64();
9774 gen_load_fpr64(ctx
, fp0
, fs
);
9775 gen_load_fpr64(ctx
, fp1
, ft
);
9776 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
9777 tcg_temp_free_i64(fp1
);
9778 gen_store_fpr64(ctx
, fp0
, fd
);
9779 tcg_temp_free_i64(fp0
);
9784 check_cp1_64bitmode(ctx
);
9786 TCGv_i64 fp0
= tcg_temp_new_i64();
9787 TCGv_i64 fp1
= tcg_temp_new_i64();
9789 gen_load_fpr64(ctx
, fp0
, fs
);
9790 gen_load_fpr64(ctx
, fp1
, ft
);
9791 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
9792 tcg_temp_free_i64(fp1
);
9793 gen_store_fpr64(ctx
, fp0
, fd
);
9794 tcg_temp_free_i64(fp0
);
9799 check_cp1_64bitmode(ctx
);
9801 TCGv_i64 fp0
= tcg_temp_new_i64();
9803 gen_load_fpr64(ctx
, fp0
, fs
);
9804 gen_helper_float_abs_ps(fp0
, fp0
);
9805 gen_store_fpr64(ctx
, fp0
, fd
);
9806 tcg_temp_free_i64(fp0
);
9811 check_cp1_64bitmode(ctx
);
9813 TCGv_i64 fp0
= tcg_temp_new_i64();
9815 gen_load_fpr64(ctx
, fp0
, fs
);
9816 gen_store_fpr64(ctx
, fp0
, fd
);
9817 tcg_temp_free_i64(fp0
);
9822 check_cp1_64bitmode(ctx
);
9824 TCGv_i64 fp0
= tcg_temp_new_i64();
9826 gen_load_fpr64(ctx
, fp0
, fs
);
9827 gen_helper_float_chs_ps(fp0
, fp0
);
9828 gen_store_fpr64(ctx
, fp0
, fd
);
9829 tcg_temp_free_i64(fp0
);
9834 check_cp1_64bitmode(ctx
);
9835 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9839 check_cp1_64bitmode(ctx
);
9841 int l1
= gen_new_label();
9845 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9846 fp0
= tcg_temp_new_i64();
9847 gen_load_fpr64(ctx
, fp0
, fs
);
9848 gen_store_fpr64(ctx
, fp0
, fd
);
9849 tcg_temp_free_i64(fp0
);
9855 check_cp1_64bitmode(ctx
);
9857 int l1
= gen_new_label();
9861 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9862 fp0
= tcg_temp_new_i64();
9863 gen_load_fpr64(ctx
, fp0
, fs
);
9864 gen_store_fpr64(ctx
, fp0
, fd
);
9865 tcg_temp_free_i64(fp0
);
9872 check_cp1_64bitmode(ctx
);
9874 TCGv_i64 fp0
= tcg_temp_new_i64();
9875 TCGv_i64 fp1
= tcg_temp_new_i64();
9877 gen_load_fpr64(ctx
, fp0
, ft
);
9878 gen_load_fpr64(ctx
, fp1
, fs
);
9879 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
9880 tcg_temp_free_i64(fp1
);
9881 gen_store_fpr64(ctx
, fp0
, fd
);
9882 tcg_temp_free_i64(fp0
);
9887 check_cp1_64bitmode(ctx
);
9889 TCGv_i64 fp0
= tcg_temp_new_i64();
9890 TCGv_i64 fp1
= tcg_temp_new_i64();
9892 gen_load_fpr64(ctx
, fp0
, ft
);
9893 gen_load_fpr64(ctx
, fp1
, fs
);
9894 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
9895 tcg_temp_free_i64(fp1
);
9896 gen_store_fpr64(ctx
, fp0
, fd
);
9897 tcg_temp_free_i64(fp0
);
9902 check_cp1_64bitmode(ctx
);
9904 TCGv_i64 fp0
= tcg_temp_new_i64();
9905 TCGv_i64 fp1
= tcg_temp_new_i64();
9907 gen_load_fpr64(ctx
, fp0
, fs
);
9908 gen_load_fpr64(ctx
, fp1
, ft
);
9909 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
9910 tcg_temp_free_i64(fp1
);
9911 gen_store_fpr64(ctx
, fp0
, fd
);
9912 tcg_temp_free_i64(fp0
);
9917 check_cp1_64bitmode(ctx
);
9919 TCGv_i64 fp0
= tcg_temp_new_i64();
9921 gen_load_fpr64(ctx
, fp0
, fs
);
9922 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
9923 gen_store_fpr64(ctx
, fp0
, fd
);
9924 tcg_temp_free_i64(fp0
);
9929 check_cp1_64bitmode(ctx
);
9931 TCGv_i64 fp0
= tcg_temp_new_i64();
9933 gen_load_fpr64(ctx
, fp0
, fs
);
9934 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
9935 gen_store_fpr64(ctx
, fp0
, fd
);
9936 tcg_temp_free_i64(fp0
);
9941 check_cp1_64bitmode(ctx
);
9943 TCGv_i64 fp0
= tcg_temp_new_i64();
9944 TCGv_i64 fp1
= tcg_temp_new_i64();
9946 gen_load_fpr64(ctx
, fp0
, fs
);
9947 gen_load_fpr64(ctx
, fp1
, ft
);
9948 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
9949 tcg_temp_free_i64(fp1
);
9950 gen_store_fpr64(ctx
, fp0
, fd
);
9951 tcg_temp_free_i64(fp0
);
9956 check_cp1_64bitmode(ctx
);
9958 TCGv_i32 fp0
= tcg_temp_new_i32();
9960 gen_load_fpr32h(ctx
, fp0
, fs
);
9961 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
9962 gen_store_fpr32(fp0
, fd
);
9963 tcg_temp_free_i32(fp0
);
9968 check_cp1_64bitmode(ctx
);
9970 TCGv_i64 fp0
= tcg_temp_new_i64();
9972 gen_load_fpr64(ctx
, fp0
, fs
);
9973 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
9974 gen_store_fpr64(ctx
, fp0
, fd
);
9975 tcg_temp_free_i64(fp0
);
9980 check_cp1_64bitmode(ctx
);
9982 TCGv_i32 fp0
= tcg_temp_new_i32();
9984 gen_load_fpr32(fp0
, fs
);
9985 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
9986 gen_store_fpr32(fp0
, fd
);
9987 tcg_temp_free_i32(fp0
);
9992 check_cp1_64bitmode(ctx
);
9994 TCGv_i32 fp0
= tcg_temp_new_i32();
9995 TCGv_i32 fp1
= tcg_temp_new_i32();
9997 gen_load_fpr32(fp0
, fs
);
9998 gen_load_fpr32(fp1
, ft
);
9999 gen_store_fpr32h(ctx
, fp0
, fd
);
10000 gen_store_fpr32(fp1
, fd
);
10001 tcg_temp_free_i32(fp0
);
10002 tcg_temp_free_i32(fp1
);
10007 check_cp1_64bitmode(ctx
);
10009 TCGv_i32 fp0
= tcg_temp_new_i32();
10010 TCGv_i32 fp1
= tcg_temp_new_i32();
10012 gen_load_fpr32(fp0
, fs
);
10013 gen_load_fpr32h(ctx
, fp1
, ft
);
10014 gen_store_fpr32(fp1
, fd
);
10015 gen_store_fpr32h(ctx
, fp0
, fd
);
10016 tcg_temp_free_i32(fp0
);
10017 tcg_temp_free_i32(fp1
);
10022 check_cp1_64bitmode(ctx
);
10024 TCGv_i32 fp0
= tcg_temp_new_i32();
10025 TCGv_i32 fp1
= tcg_temp_new_i32();
10027 gen_load_fpr32h(ctx
, fp0
, fs
);
10028 gen_load_fpr32(fp1
, ft
);
10029 gen_store_fpr32(fp1
, fd
);
10030 gen_store_fpr32h(ctx
, fp0
, fd
);
10031 tcg_temp_free_i32(fp0
);
10032 tcg_temp_free_i32(fp1
);
10037 check_cp1_64bitmode(ctx
);
10039 TCGv_i32 fp0
= tcg_temp_new_i32();
10040 TCGv_i32 fp1
= tcg_temp_new_i32();
10042 gen_load_fpr32h(ctx
, fp0
, fs
);
10043 gen_load_fpr32h(ctx
, fp1
, ft
);
10044 gen_store_fpr32(fp1
, fd
);
10045 gen_store_fpr32h(ctx
, fp0
, fd
);
10046 tcg_temp_free_i32(fp0
);
10047 tcg_temp_free_i32(fp1
);
10052 case OPC_CMP_UN_PS
:
10053 case OPC_CMP_EQ_PS
:
10054 case OPC_CMP_UEQ_PS
:
10055 case OPC_CMP_OLT_PS
:
10056 case OPC_CMP_ULT_PS
:
10057 case OPC_CMP_OLE_PS
:
10058 case OPC_CMP_ULE_PS
:
10059 case OPC_CMP_SF_PS
:
10060 case OPC_CMP_NGLE_PS
:
10061 case OPC_CMP_SEQ_PS
:
10062 case OPC_CMP_NGL_PS
:
10063 case OPC_CMP_LT_PS
:
10064 case OPC_CMP_NGE_PS
:
10065 case OPC_CMP_LE_PS
:
10066 case OPC_CMP_NGT_PS
:
10067 if (ctx
->opcode
& (1 << 6)) {
10068 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
10069 opn
= condnames_abs
[func
-48];
10071 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
10072 opn
= condnames
[func
-48];
10077 generate_exception (ctx
, EXCP_RI
);
10080 (void)opn
; /* avoid a compiler warning */
10083 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
10086 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
10089 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
10094 /* Coprocessor 3 (FPU) */
10095 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
10096 int fd
, int fs
, int base
, int index
)
10098 const char *opn
= "extended float load/store";
10100 TCGv t0
= tcg_temp_new();
10103 gen_load_gpr(t0
, index
);
10104 } else if (index
== 0) {
10105 gen_load_gpr(t0
, base
);
10107 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
10109 /* Don't do NOP if destination is zero: we must perform the actual
10115 TCGv_i32 fp0
= tcg_temp_new_i32();
10117 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
10118 tcg_gen_trunc_tl_i32(fp0
, t0
);
10119 gen_store_fpr32(fp0
, fd
);
10120 tcg_temp_free_i32(fp0
);
10126 check_cp1_registers(ctx
, fd
);
10128 TCGv_i64 fp0
= tcg_temp_new_i64();
10129 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10130 gen_store_fpr64(ctx
, fp0
, fd
);
10131 tcg_temp_free_i64(fp0
);
10136 check_cp1_64bitmode(ctx
);
10137 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10139 TCGv_i64 fp0
= tcg_temp_new_i64();
10141 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10142 gen_store_fpr64(ctx
, fp0
, fd
);
10143 tcg_temp_free_i64(fp0
);
10150 TCGv_i32 fp0
= tcg_temp_new_i32();
10151 gen_load_fpr32(fp0
, fs
);
10152 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
10153 tcg_temp_free_i32(fp0
);
10160 check_cp1_registers(ctx
, fs
);
10162 TCGv_i64 fp0
= tcg_temp_new_i64();
10163 gen_load_fpr64(ctx
, fp0
, fs
);
10164 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10165 tcg_temp_free_i64(fp0
);
10171 check_cp1_64bitmode(ctx
);
10172 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10174 TCGv_i64 fp0
= tcg_temp_new_i64();
10175 gen_load_fpr64(ctx
, fp0
, fs
);
10176 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10177 tcg_temp_free_i64(fp0
);
10184 (void)opn
; (void)store
; /* avoid compiler warnings */
10185 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
10186 regnames
[index
], regnames
[base
]);
10189 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
10190 int fd
, int fr
, int fs
, int ft
)
10192 const char *opn
= "flt3_arith";
10196 check_cp1_64bitmode(ctx
);
10198 TCGv t0
= tcg_temp_local_new();
10199 TCGv_i32 fp
= tcg_temp_new_i32();
10200 TCGv_i32 fph
= tcg_temp_new_i32();
10201 int l1
= gen_new_label();
10202 int l2
= gen_new_label();
10204 gen_load_gpr(t0
, fr
);
10205 tcg_gen_andi_tl(t0
, t0
, 0x7);
10207 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
10208 gen_load_fpr32(fp
, fs
);
10209 gen_load_fpr32h(ctx
, fph
, fs
);
10210 gen_store_fpr32(fp
, fd
);
10211 gen_store_fpr32h(ctx
, fph
, fd
);
10214 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
10216 #ifdef TARGET_WORDS_BIGENDIAN
10217 gen_load_fpr32(fp
, fs
);
10218 gen_load_fpr32h(ctx
, fph
, ft
);
10219 gen_store_fpr32h(ctx
, fp
, fd
);
10220 gen_store_fpr32(fph
, fd
);
10222 gen_load_fpr32h(ctx
, fph
, fs
);
10223 gen_load_fpr32(fp
, ft
);
10224 gen_store_fpr32(fph
, fd
);
10225 gen_store_fpr32h(ctx
, fp
, fd
);
10228 tcg_temp_free_i32(fp
);
10229 tcg_temp_free_i32(fph
);
10236 TCGv_i32 fp0
= tcg_temp_new_i32();
10237 TCGv_i32 fp1
= tcg_temp_new_i32();
10238 TCGv_i32 fp2
= tcg_temp_new_i32();
10240 gen_load_fpr32(fp0
, fs
);
10241 gen_load_fpr32(fp1
, ft
);
10242 gen_load_fpr32(fp2
, fr
);
10243 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10244 tcg_temp_free_i32(fp0
);
10245 tcg_temp_free_i32(fp1
);
10246 gen_store_fpr32(fp2
, fd
);
10247 tcg_temp_free_i32(fp2
);
10253 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10255 TCGv_i64 fp0
= tcg_temp_new_i64();
10256 TCGv_i64 fp1
= tcg_temp_new_i64();
10257 TCGv_i64 fp2
= tcg_temp_new_i64();
10259 gen_load_fpr64(ctx
, fp0
, fs
);
10260 gen_load_fpr64(ctx
, fp1
, ft
);
10261 gen_load_fpr64(ctx
, fp2
, fr
);
10262 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10263 tcg_temp_free_i64(fp0
);
10264 tcg_temp_free_i64(fp1
);
10265 gen_store_fpr64(ctx
, fp2
, fd
);
10266 tcg_temp_free_i64(fp2
);
10271 check_cp1_64bitmode(ctx
);
10273 TCGv_i64 fp0
= tcg_temp_new_i64();
10274 TCGv_i64 fp1
= tcg_temp_new_i64();
10275 TCGv_i64 fp2
= tcg_temp_new_i64();
10277 gen_load_fpr64(ctx
, fp0
, fs
);
10278 gen_load_fpr64(ctx
, fp1
, ft
);
10279 gen_load_fpr64(ctx
, fp2
, fr
);
10280 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10281 tcg_temp_free_i64(fp0
);
10282 tcg_temp_free_i64(fp1
);
10283 gen_store_fpr64(ctx
, fp2
, fd
);
10284 tcg_temp_free_i64(fp2
);
10291 TCGv_i32 fp0
= tcg_temp_new_i32();
10292 TCGv_i32 fp1
= tcg_temp_new_i32();
10293 TCGv_i32 fp2
= tcg_temp_new_i32();
10295 gen_load_fpr32(fp0
, fs
);
10296 gen_load_fpr32(fp1
, ft
);
10297 gen_load_fpr32(fp2
, fr
);
10298 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10299 tcg_temp_free_i32(fp0
);
10300 tcg_temp_free_i32(fp1
);
10301 gen_store_fpr32(fp2
, fd
);
10302 tcg_temp_free_i32(fp2
);
10308 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10310 TCGv_i64 fp0
= tcg_temp_new_i64();
10311 TCGv_i64 fp1
= tcg_temp_new_i64();
10312 TCGv_i64 fp2
= tcg_temp_new_i64();
10314 gen_load_fpr64(ctx
, fp0
, fs
);
10315 gen_load_fpr64(ctx
, fp1
, ft
);
10316 gen_load_fpr64(ctx
, fp2
, fr
);
10317 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10318 tcg_temp_free_i64(fp0
);
10319 tcg_temp_free_i64(fp1
);
10320 gen_store_fpr64(ctx
, fp2
, fd
);
10321 tcg_temp_free_i64(fp2
);
10326 check_cp1_64bitmode(ctx
);
10328 TCGv_i64 fp0
= tcg_temp_new_i64();
10329 TCGv_i64 fp1
= tcg_temp_new_i64();
10330 TCGv_i64 fp2
= tcg_temp_new_i64();
10332 gen_load_fpr64(ctx
, fp0
, fs
);
10333 gen_load_fpr64(ctx
, fp1
, ft
);
10334 gen_load_fpr64(ctx
, fp2
, fr
);
10335 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10336 tcg_temp_free_i64(fp0
);
10337 tcg_temp_free_i64(fp1
);
10338 gen_store_fpr64(ctx
, fp2
, fd
);
10339 tcg_temp_free_i64(fp2
);
10346 TCGv_i32 fp0
= tcg_temp_new_i32();
10347 TCGv_i32 fp1
= tcg_temp_new_i32();
10348 TCGv_i32 fp2
= tcg_temp_new_i32();
10350 gen_load_fpr32(fp0
, fs
);
10351 gen_load_fpr32(fp1
, ft
);
10352 gen_load_fpr32(fp2
, fr
);
10353 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10354 tcg_temp_free_i32(fp0
);
10355 tcg_temp_free_i32(fp1
);
10356 gen_store_fpr32(fp2
, fd
);
10357 tcg_temp_free_i32(fp2
);
10363 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10365 TCGv_i64 fp0
= tcg_temp_new_i64();
10366 TCGv_i64 fp1
= tcg_temp_new_i64();
10367 TCGv_i64 fp2
= tcg_temp_new_i64();
10369 gen_load_fpr64(ctx
, fp0
, fs
);
10370 gen_load_fpr64(ctx
, fp1
, ft
);
10371 gen_load_fpr64(ctx
, fp2
, fr
);
10372 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10373 tcg_temp_free_i64(fp0
);
10374 tcg_temp_free_i64(fp1
);
10375 gen_store_fpr64(ctx
, fp2
, fd
);
10376 tcg_temp_free_i64(fp2
);
10381 check_cp1_64bitmode(ctx
);
10383 TCGv_i64 fp0
= tcg_temp_new_i64();
10384 TCGv_i64 fp1
= tcg_temp_new_i64();
10385 TCGv_i64 fp2
= tcg_temp_new_i64();
10387 gen_load_fpr64(ctx
, fp0
, fs
);
10388 gen_load_fpr64(ctx
, fp1
, ft
);
10389 gen_load_fpr64(ctx
, fp2
, fr
);
10390 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10391 tcg_temp_free_i64(fp0
);
10392 tcg_temp_free_i64(fp1
);
10393 gen_store_fpr64(ctx
, fp2
, fd
);
10394 tcg_temp_free_i64(fp2
);
10401 TCGv_i32 fp0
= tcg_temp_new_i32();
10402 TCGv_i32 fp1
= tcg_temp_new_i32();
10403 TCGv_i32 fp2
= tcg_temp_new_i32();
10405 gen_load_fpr32(fp0
, fs
);
10406 gen_load_fpr32(fp1
, ft
);
10407 gen_load_fpr32(fp2
, fr
);
10408 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10409 tcg_temp_free_i32(fp0
);
10410 tcg_temp_free_i32(fp1
);
10411 gen_store_fpr32(fp2
, fd
);
10412 tcg_temp_free_i32(fp2
);
10418 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10420 TCGv_i64 fp0
= tcg_temp_new_i64();
10421 TCGv_i64 fp1
= tcg_temp_new_i64();
10422 TCGv_i64 fp2
= tcg_temp_new_i64();
10424 gen_load_fpr64(ctx
, fp0
, fs
);
10425 gen_load_fpr64(ctx
, fp1
, ft
);
10426 gen_load_fpr64(ctx
, fp2
, fr
);
10427 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10428 tcg_temp_free_i64(fp0
);
10429 tcg_temp_free_i64(fp1
);
10430 gen_store_fpr64(ctx
, fp2
, fd
);
10431 tcg_temp_free_i64(fp2
);
10436 check_cp1_64bitmode(ctx
);
10438 TCGv_i64 fp0
= tcg_temp_new_i64();
10439 TCGv_i64 fp1
= tcg_temp_new_i64();
10440 TCGv_i64 fp2
= tcg_temp_new_i64();
10442 gen_load_fpr64(ctx
, fp0
, fs
);
10443 gen_load_fpr64(ctx
, fp1
, ft
);
10444 gen_load_fpr64(ctx
, fp2
, fr
);
10445 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10446 tcg_temp_free_i64(fp0
);
10447 tcg_temp_free_i64(fp1
);
10448 gen_store_fpr64(ctx
, fp2
, fd
);
10449 tcg_temp_free_i64(fp2
);
10455 generate_exception (ctx
, EXCP_RI
);
10458 (void)opn
; /* avoid a compiler warning */
10459 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
10460 fregnames
[fs
], fregnames
[ft
]);
10463 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
10467 #if !defined(CONFIG_USER_ONLY)
10468 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10469 Therefore only check the ISA in system mode. */
10470 check_insn(ctx
, ISA_MIPS32R2
);
10472 t0
= tcg_temp_new();
10476 save_cpu_state(ctx
, 1);
10477 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
10478 gen_store_gpr(t0
, rt
);
10481 save_cpu_state(ctx
, 1);
10482 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
10483 gen_store_gpr(t0
, rt
);
10486 save_cpu_state(ctx
, 1);
10487 gen_helper_rdhwr_cc(t0
, cpu_env
);
10488 gen_store_gpr(t0
, rt
);
10491 save_cpu_state(ctx
, 1);
10492 gen_helper_rdhwr_ccres(t0
, cpu_env
);
10493 gen_store_gpr(t0
, rt
);
10496 #if defined(CONFIG_USER_ONLY)
10497 tcg_gen_ld_tl(t0
, cpu_env
,
10498 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10499 gen_store_gpr(t0
, rt
);
10502 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
10503 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
10504 tcg_gen_ld_tl(t0
, cpu_env
,
10505 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10506 gen_store_gpr(t0
, rt
);
10508 generate_exception(ctx
, EXCP_RI
);
10512 default: /* Invalid */
10513 MIPS_INVAL("rdhwr");
10514 generate_exception(ctx
, EXCP_RI
);
10520 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
10522 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10523 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
10524 /* Branches completion */
10525 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
10526 ctx
->bstate
= BS_BRANCH
;
10527 save_cpu_state(ctx
, 0);
10528 /* FIXME: Need to clear can_do_io. */
10529 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
10530 case MIPS_HFLAG_FBNSLOT
:
10531 MIPS_DEBUG("forbidden slot");
10532 gen_goto_tb(ctx
, 0, ctx
->pc
+ insn_bytes
);
10535 /* unconditional branch */
10536 MIPS_DEBUG("unconditional branch");
10537 if (proc_hflags
& MIPS_HFLAG_BX
) {
10538 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
10540 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10542 case MIPS_HFLAG_BL
:
10543 /* blikely taken case */
10544 MIPS_DEBUG("blikely branch taken");
10545 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10547 case MIPS_HFLAG_BC
:
10548 /* Conditional branch */
10549 MIPS_DEBUG("conditional branch");
10551 int l1
= gen_new_label();
10553 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
10554 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
10556 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10559 case MIPS_HFLAG_BR
:
10560 /* unconditional branch to register */
10561 MIPS_DEBUG("branch to register");
10562 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
10563 TCGv t0
= tcg_temp_new();
10564 TCGv_i32 t1
= tcg_temp_new_i32();
10566 tcg_gen_andi_tl(t0
, btarget
, 0x1);
10567 tcg_gen_trunc_tl_i32(t1
, t0
);
10569 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
10570 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
10571 tcg_gen_or_i32(hflags
, hflags
, t1
);
10572 tcg_temp_free_i32(t1
);
10574 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
10576 tcg_gen_mov_tl(cpu_PC
, btarget
);
10578 if (ctx
->singlestep_enabled
) {
10579 save_cpu_state(ctx
, 0);
10580 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
10582 tcg_gen_exit_tb(0);
10585 MIPS_DEBUG("unknown branch");
10591 /* ISA extensions (ASEs) */
10592 /* MIPS16 extension to MIPS32 */
10594 /* MIPS16 major opcodes */
10596 M16_OPC_ADDIUSP
= 0x00,
10597 M16_OPC_ADDIUPC
= 0x01,
10599 M16_OPC_JAL
= 0x03,
10600 M16_OPC_BEQZ
= 0x04,
10601 M16_OPC_BNEQZ
= 0x05,
10602 M16_OPC_SHIFT
= 0x06,
10604 M16_OPC_RRIA
= 0x08,
10605 M16_OPC_ADDIU8
= 0x09,
10606 M16_OPC_SLTI
= 0x0a,
10607 M16_OPC_SLTIU
= 0x0b,
10610 M16_OPC_CMPI
= 0x0e,
10614 M16_OPC_LWSP
= 0x12,
10616 M16_OPC_LBU
= 0x14,
10617 M16_OPC_LHU
= 0x15,
10618 M16_OPC_LWPC
= 0x16,
10619 M16_OPC_LWU
= 0x17,
10622 M16_OPC_SWSP
= 0x1a,
10624 M16_OPC_RRR
= 0x1c,
10626 M16_OPC_EXTEND
= 0x1e,
10630 /* I8 funct field */
10649 /* RR funct field */
10683 /* I64 funct field */
10691 I64_DADDIUPC
= 0x6,
10695 /* RR ry field for CNVT */
10697 RR_RY_CNVT_ZEB
= 0x0,
10698 RR_RY_CNVT_ZEH
= 0x1,
10699 RR_RY_CNVT_ZEW
= 0x2,
10700 RR_RY_CNVT_SEB
= 0x4,
10701 RR_RY_CNVT_SEH
= 0x5,
10702 RR_RY_CNVT_SEW
= 0x6,
10705 static int xlat (int r
)
10707 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10712 static void gen_mips16_save (DisasContext
*ctx
,
10713 int xsregs
, int aregs
,
10714 int do_ra
, int do_s0
, int do_s1
,
10717 TCGv t0
= tcg_temp_new();
10718 TCGv t1
= tcg_temp_new();
10748 generate_exception(ctx
, EXCP_RI
);
10754 gen_base_offset_addr(ctx
, t0
, 29, 12);
10755 gen_load_gpr(t1
, 7);
10756 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10759 gen_base_offset_addr(ctx
, t0
, 29, 8);
10760 gen_load_gpr(t1
, 6);
10761 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10764 gen_base_offset_addr(ctx
, t0
, 29, 4);
10765 gen_load_gpr(t1
, 5);
10766 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10769 gen_base_offset_addr(ctx
, t0
, 29, 0);
10770 gen_load_gpr(t1
, 4);
10771 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10774 gen_load_gpr(t0
, 29);
10776 #define DECR_AND_STORE(reg) do { \
10777 tcg_gen_subi_tl(t0, t0, 4); \
10778 gen_load_gpr(t1, reg); \
10779 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
10783 DECR_AND_STORE(31);
10788 DECR_AND_STORE(30);
10791 DECR_AND_STORE(23);
10794 DECR_AND_STORE(22);
10797 DECR_AND_STORE(21);
10800 DECR_AND_STORE(20);
10803 DECR_AND_STORE(19);
10806 DECR_AND_STORE(18);
10810 DECR_AND_STORE(17);
10813 DECR_AND_STORE(16);
10843 generate_exception(ctx
, EXCP_RI
);
10859 #undef DECR_AND_STORE
10861 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
10866 static void gen_mips16_restore (DisasContext
*ctx
,
10867 int xsregs
, int aregs
,
10868 int do_ra
, int do_s0
, int do_s1
,
10872 TCGv t0
= tcg_temp_new();
10873 TCGv t1
= tcg_temp_new();
10875 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
10877 #define DECR_AND_LOAD(reg) do { \
10878 tcg_gen_subi_tl(t0, t0, 4); \
10879 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10880 gen_store_gpr(t1, reg); \
10944 generate_exception(ctx
, EXCP_RI
);
10960 #undef DECR_AND_LOAD
10962 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
10967 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
10968 int is_64_bit
, int extended
)
10972 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10973 generate_exception(ctx
, EXCP_RI
);
10977 t0
= tcg_temp_new();
10979 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
10980 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
10982 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10988 #if defined(TARGET_MIPS64)
10989 static void decode_i64_mips16 (DisasContext
*ctx
,
10990 int ry
, int funct
, int16_t offset
,
10995 check_mips_64(ctx
);
10996 offset
= extended
? offset
: offset
<< 3;
10997 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
11000 check_mips_64(ctx
);
11001 offset
= extended
? offset
: offset
<< 3;
11002 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
11005 check_mips_64(ctx
);
11006 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
11007 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
11010 check_mips_64(ctx
);
11011 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
11012 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
11015 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11016 generate_exception(ctx
, EXCP_RI
);
11018 offset
= extended
? offset
: offset
<< 3;
11019 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
11023 check_mips_64(ctx
);
11024 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
11025 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
11028 check_mips_64(ctx
);
11029 offset
= extended
? offset
: offset
<< 2;
11030 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
11033 check_mips_64(ctx
);
11034 offset
= extended
? offset
: offset
<< 2;
11035 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
11041 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11043 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11044 int op
, rx
, ry
, funct
, sa
;
11045 int16_t imm
, offset
;
11047 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
11048 op
= (ctx
->opcode
>> 11) & 0x1f;
11049 sa
= (ctx
->opcode
>> 22) & 0x1f;
11050 funct
= (ctx
->opcode
>> 8) & 0x7;
11051 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11052 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11053 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
11054 | ((ctx
->opcode
>> 21) & 0x3f) << 5
11055 | (ctx
->opcode
& 0x1f));
11057 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11060 case M16_OPC_ADDIUSP
:
11061 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11063 case M16_OPC_ADDIUPC
:
11064 gen_addiupc(ctx
, rx
, imm
, 0, 1);
11067 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
11068 /* No delay slot, so just process as a normal instruction */
11071 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
11072 /* No delay slot, so just process as a normal instruction */
11074 case M16_OPC_BNEQZ
:
11075 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
11076 /* No delay slot, so just process as a normal instruction */
11078 case M16_OPC_SHIFT
:
11079 switch (ctx
->opcode
& 0x3) {
11081 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11084 #if defined(TARGET_MIPS64)
11085 check_mips_64(ctx
);
11086 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11088 generate_exception(ctx
, EXCP_RI
);
11092 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11095 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11099 #if defined(TARGET_MIPS64)
11101 check_mips_64(ctx
);
11102 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
11106 imm
= ctx
->opcode
& 0xf;
11107 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
11108 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
11109 imm
= (int16_t) (imm
<< 1) >> 1;
11110 if ((ctx
->opcode
>> 4) & 0x1) {
11111 #if defined(TARGET_MIPS64)
11112 check_mips_64(ctx
);
11113 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11115 generate_exception(ctx
, EXCP_RI
);
11118 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11121 case M16_OPC_ADDIU8
:
11122 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11125 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11127 case M16_OPC_SLTIU
:
11128 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11133 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
11136 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
11139 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
11142 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
11146 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
11147 int aregs
= (ctx
->opcode
>> 16) & 0xf;
11148 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
11149 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
11150 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
11151 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
11152 | (ctx
->opcode
& 0xf)) << 3;
11154 if (ctx
->opcode
& (1 << 7)) {
11155 gen_mips16_save(ctx
, xsregs
, aregs
,
11156 do_ra
, do_s0
, do_s1
,
11159 gen_mips16_restore(ctx
, xsregs
, aregs
,
11160 do_ra
, do_s0
, do_s1
,
11166 generate_exception(ctx
, EXCP_RI
);
11171 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
11174 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
11176 #if defined(TARGET_MIPS64)
11178 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
11182 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11185 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
11188 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
11191 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
11194 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11197 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
11200 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
11202 #if defined(TARGET_MIPS64)
11204 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
11208 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11211 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
11214 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
11217 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
11219 #if defined(TARGET_MIPS64)
11221 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
11225 generate_exception(ctx
, EXCP_RI
);
11232 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11236 int op
, cnvt_op
, op1
, offset
;
11240 op
= (ctx
->opcode
>> 11) & 0x1f;
11241 sa
= (ctx
->opcode
>> 2) & 0x7;
11242 sa
= sa
== 0 ? 8 : sa
;
11243 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11244 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
11245 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11246 op1
= offset
= ctx
->opcode
& 0x1f;
11251 case M16_OPC_ADDIUSP
:
11253 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
11255 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11258 case M16_OPC_ADDIUPC
:
11259 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
11262 offset
= (ctx
->opcode
& 0x7ff) << 1;
11263 offset
= (int16_t)(offset
<< 4) >> 4;
11264 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
11265 /* No delay slot, so just process as a normal instruction */
11268 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11269 offset
= (((ctx
->opcode
& 0x1f) << 21)
11270 | ((ctx
->opcode
>> 5) & 0x1f) << 16
11272 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
11273 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
11277 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
11278 ((int8_t)ctx
->opcode
) << 1, 0);
11279 /* No delay slot, so just process as a normal instruction */
11281 case M16_OPC_BNEQZ
:
11282 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
11283 ((int8_t)ctx
->opcode
) << 1, 0);
11284 /* No delay slot, so just process as a normal instruction */
11286 case M16_OPC_SHIFT
:
11287 switch (ctx
->opcode
& 0x3) {
11289 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11292 #if defined(TARGET_MIPS64)
11293 check_mips_64(ctx
);
11294 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11296 generate_exception(ctx
, EXCP_RI
);
11300 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11303 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11307 #if defined(TARGET_MIPS64)
11309 check_mips_64(ctx
);
11310 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
11315 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
11317 if ((ctx
->opcode
>> 4) & 1) {
11318 #if defined(TARGET_MIPS64)
11319 check_mips_64(ctx
);
11320 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11322 generate_exception(ctx
, EXCP_RI
);
11325 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11329 case M16_OPC_ADDIU8
:
11331 int16_t imm
= (int8_t) ctx
->opcode
;
11333 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11338 int16_t imm
= (uint8_t) ctx
->opcode
;
11339 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11342 case M16_OPC_SLTIU
:
11344 int16_t imm
= (uint8_t) ctx
->opcode
;
11345 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11352 funct
= (ctx
->opcode
>> 8) & 0x7;
11355 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
11356 ((int8_t)ctx
->opcode
) << 1, 0);
11359 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
11360 ((int8_t)ctx
->opcode
) << 1, 0);
11363 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
11366 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
11367 ((int8_t)ctx
->opcode
) << 3);
11371 int do_ra
= ctx
->opcode
& (1 << 6);
11372 int do_s0
= ctx
->opcode
& (1 << 5);
11373 int do_s1
= ctx
->opcode
& (1 << 4);
11374 int framesize
= ctx
->opcode
& 0xf;
11376 if (framesize
== 0) {
11379 framesize
= framesize
<< 3;
11382 if (ctx
->opcode
& (1 << 7)) {
11383 gen_mips16_save(ctx
, 0, 0,
11384 do_ra
, do_s0
, do_s1
, framesize
);
11386 gen_mips16_restore(ctx
, 0, 0,
11387 do_ra
, do_s0
, do_s1
, framesize
);
11393 int rz
= xlat(ctx
->opcode
& 0x7);
11395 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
11396 ((ctx
->opcode
>> 5) & 0x7);
11397 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
11401 reg32
= ctx
->opcode
& 0x1f;
11402 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
11405 generate_exception(ctx
, EXCP_RI
);
11412 int16_t imm
= (uint8_t) ctx
->opcode
;
11414 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
11419 int16_t imm
= (uint8_t) ctx
->opcode
;
11420 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
11423 #if defined(TARGET_MIPS64)
11425 check_mips_64(ctx
);
11426 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
11430 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11433 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
11436 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11439 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
11442 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11445 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
11448 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
11450 #if defined (TARGET_MIPS64)
11452 check_mips_64(ctx
);
11453 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
11457 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11460 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
11463 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11466 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
11470 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
11473 switch (ctx
->opcode
& 0x3) {
11475 mips32_op
= OPC_ADDU
;
11478 mips32_op
= OPC_SUBU
;
11480 #if defined(TARGET_MIPS64)
11482 mips32_op
= OPC_DADDU
;
11483 check_mips_64(ctx
);
11486 mips32_op
= OPC_DSUBU
;
11487 check_mips_64(ctx
);
11491 generate_exception(ctx
, EXCP_RI
);
11495 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
11504 int nd
= (ctx
->opcode
>> 7) & 0x1;
11505 int link
= (ctx
->opcode
>> 6) & 0x1;
11506 int ra
= (ctx
->opcode
>> 5) & 0x1;
11514 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
11519 /* XXX: not clear which exception should be raised
11520 * when in debug mode...
11522 check_insn(ctx
, ISA_MIPS32
);
11523 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11524 generate_exception(ctx
, EXCP_DBp
);
11526 generate_exception(ctx
, EXCP_DBp
);
11530 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
11533 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
11536 generate_exception(ctx
, EXCP_BREAK
);
11539 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
11542 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
11545 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
11547 #if defined (TARGET_MIPS64)
11549 check_mips_64(ctx
);
11550 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
11554 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
11557 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
11560 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
11563 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
11566 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
11569 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
11572 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
11576 case RR_RY_CNVT_ZEB
:
11577 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11579 case RR_RY_CNVT_ZEH
:
11580 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11582 case RR_RY_CNVT_SEB
:
11583 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11585 case RR_RY_CNVT_SEH
:
11586 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11588 #if defined (TARGET_MIPS64)
11589 case RR_RY_CNVT_ZEW
:
11590 check_mips_64(ctx
);
11591 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11593 case RR_RY_CNVT_SEW
:
11594 check_mips_64(ctx
);
11595 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11599 generate_exception(ctx
, EXCP_RI
);
11604 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
11606 #if defined (TARGET_MIPS64)
11608 check_mips_64(ctx
);
11609 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
11612 check_mips_64(ctx
);
11613 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
11616 check_mips_64(ctx
);
11617 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
11620 check_mips_64(ctx
);
11621 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
11625 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
11628 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
11631 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
11634 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
11636 #if defined (TARGET_MIPS64)
11638 check_mips_64(ctx
);
11639 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
11642 check_mips_64(ctx
);
11643 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
11646 check_mips_64(ctx
);
11647 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
11650 check_mips_64(ctx
);
11651 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
11655 generate_exception(ctx
, EXCP_RI
);
11659 case M16_OPC_EXTEND
:
11660 decode_extended_mips16_opc(env
, ctx
);
11663 #if defined(TARGET_MIPS64)
11665 funct
= (ctx
->opcode
>> 8) & 0x7;
11666 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
11670 generate_exception(ctx
, EXCP_RI
);
11677 /* microMIPS extension to MIPS32/MIPS64 */
11680 * microMIPS32/microMIPS64 major opcodes
11682 * 1. MIPS Architecture for Programmers Volume II-B:
11683 * The microMIPS32 Instruction Set (Revision 3.05)
11685 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11687 * 2. MIPS Architecture For Programmers Volume II-A:
11688 * The MIPS64 Instruction Set (Revision 3.51)
11716 POOL32S
= 0x16, /* MIPS64 */
11717 DADDIU32
= 0x17, /* MIPS64 */
11719 /* 0x1f is reserved */
11728 /* 0x20 is reserved */
11738 /* 0x28 and 0x29 are reserved */
11748 /* 0x30 and 0x31 are reserved */
11755 SD32
= 0x36, /* MIPS64 */
11756 LD32
= 0x37, /* MIPS64 */
11758 /* 0x38 and 0x39 are reserved */
11769 /* POOL32A encoding of minor opcode field */
11772 /* These opcodes are distinguished only by bits 9..6; those bits are
11773 * what are recorded below. */
11799 /* The following can be distinguished by their lower 6 bits. */
11805 /* POOL32AXF encoding of minor opcode field extension */
11808 * 1. MIPS Architecture for Programmers Volume II-B:
11809 * The microMIPS32 Instruction Set (Revision 3.05)
11811 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11813 * 2. MIPS Architecture for Programmers VolumeIV-e:
11814 * The MIPS DSP Application-Specific Extension
11815 * to the microMIPS32 Architecture (Revision 2.34)
11817 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11832 /* begin of microMIPS32 DSP */
11834 /* bits 13..12 for 0x01 */
11840 /* bits 13..12 for 0x2a */
11846 /* bits 13..12 for 0x32 */
11850 /* end of microMIPS32 DSP */
11852 /* bits 15..12 for 0x2c */
11868 /* bits 15..12 for 0x34 */
11876 /* bits 15..12 for 0x3c */
11878 JR
= 0x0, /* alias */
11883 /* bits 15..12 for 0x05 */
11887 /* bits 15..12 for 0x0d */
11897 /* bits 15..12 for 0x15 */
11903 /* bits 15..12 for 0x1d */
11907 /* bits 15..12 for 0x2d */
11912 /* bits 15..12 for 0x35 */
11919 /* POOL32B encoding of minor opcode field (bits 15..12) */
11935 /* POOL32C encoding of minor opcode field (bits 15..12) */
11943 /* 0xa is reserved */
11950 /* 0x6 is reserved */
11956 /* POOL32F encoding of minor opcode field (bits 5..0) */
11959 /* These are the bit 7..6 values */
11970 /* These are the bit 8..6 values */
12014 CABS_COND_FMT
= 0x1c, /* MIPS3D */
12018 /* POOL32Fxf encoding of minor opcode extension field */
12056 /* POOL32I encoding of minor opcode field (bits 25..21) */
12081 /* These overlap and are distinguished by bit16 of the instruction */
12090 /* POOL16A encoding of minor opcode field */
12097 /* POOL16B encoding of minor opcode field */
12104 /* POOL16C encoding of minor opcode field */
12124 /* POOL16D encoding of minor opcode field */
12131 /* POOL16E encoding of minor opcode field */
12138 static int mmreg (int r
)
12140 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12145 /* Used for 16-bit store instructions. */
12146 static int mmreg2 (int r
)
12148 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12153 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12154 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12155 #define uMIPS_RS2(op) uMIPS_RS(op)
12156 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12157 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12158 #define uMIPS_RS5(op) (op & 0x1f)
12160 /* Signed immediate */
12161 #define SIMM(op, start, width) \
12162 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12165 /* Zero-extended immediate */
12166 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12168 static void gen_addiur1sp(DisasContext
*ctx
)
12170 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12172 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
12175 static void gen_addiur2(DisasContext
*ctx
)
12177 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12178 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12179 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12181 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
12184 static void gen_addiusp(DisasContext
*ctx
)
12186 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
12189 if (encoded
<= 1) {
12190 decoded
= 256 + encoded
;
12191 } else if (encoded
<= 255) {
12193 } else if (encoded
<= 509) {
12194 decoded
= encoded
- 512;
12196 decoded
= encoded
- 768;
12199 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
12202 static void gen_addius5(DisasContext
*ctx
)
12204 int imm
= SIMM(ctx
->opcode
, 1, 4);
12205 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12207 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
12210 static void gen_andi16(DisasContext
*ctx
)
12212 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12213 31, 32, 63, 64, 255, 32768, 65535 };
12214 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12215 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12216 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
12218 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
12221 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
12222 int base
, int16_t offset
)
12224 const char *opn
= "ldst_multiple";
12228 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12229 generate_exception(ctx
, EXCP_RI
);
12233 t0
= tcg_temp_new();
12235 gen_base_offset_addr(ctx
, t0
, base
, offset
);
12237 t1
= tcg_const_tl(reglist
);
12238 t2
= tcg_const_i32(ctx
->mem_idx
);
12240 save_cpu_state(ctx
, 1);
12243 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
12247 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
12250 #ifdef TARGET_MIPS64
12252 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
12256 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
12262 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
12265 tcg_temp_free_i32(t2
);
12269 static void gen_pool16c_insn(DisasContext
*ctx
)
12271 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
12272 int rs
= mmreg(ctx
->opcode
& 0x7);
12274 switch (((ctx
->opcode
) >> 4) & 0x3f) {
12279 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
12285 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
12291 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
12297 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
12304 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
12305 int offset
= ZIMM(ctx
->opcode
, 0, 4);
12307 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
12316 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
12317 int offset
= ZIMM(ctx
->opcode
, 0, 4);
12319 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
12326 int reg
= ctx
->opcode
& 0x1f;
12328 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
12334 int reg
= ctx
->opcode
& 0x1f;
12335 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
12336 /* Let normal delay slot handling in our caller take us
12337 to the branch target. */
12342 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
12343 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12347 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
12348 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12352 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
12356 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
12359 generate_exception(ctx
, EXCP_BREAK
);
12362 /* XXX: not clear which exception should be raised
12363 * when in debug mode...
12365 check_insn(ctx
, ISA_MIPS32
);
12366 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
12367 generate_exception(ctx
, EXCP_DBp
);
12369 generate_exception(ctx
, EXCP_DBp
);
12372 case JRADDIUSP
+ 0:
12373 case JRADDIUSP
+ 1:
12375 int imm
= ZIMM(ctx
->opcode
, 0, 5);
12376 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
12377 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
12378 /* Let normal delay slot handling in our caller take us
12379 to the branch target. */
12383 generate_exception(ctx
, EXCP_RI
);
12388 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
12390 TCGv t0
= tcg_temp_new();
12391 TCGv t1
= tcg_temp_new();
12393 gen_load_gpr(t0
, base
);
12396 gen_load_gpr(t1
, index
);
12397 tcg_gen_shli_tl(t1
, t1
, 2);
12398 gen_op_addr_add(ctx
, t0
, t1
, t0
);
12401 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12402 gen_store_gpr(t1
, rd
);
12408 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
12409 int base
, int16_t offset
)
12411 const char *opn
= "ldst_pair";
12414 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
12415 generate_exception(ctx
, EXCP_RI
);
12419 t0
= tcg_temp_new();
12420 t1
= tcg_temp_new();
12422 gen_base_offset_addr(ctx
, t0
, base
, offset
);
12427 generate_exception(ctx
, EXCP_RI
);
12430 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12431 gen_store_gpr(t1
, rd
);
12432 tcg_gen_movi_tl(t1
, 4);
12433 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12434 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12435 gen_store_gpr(t1
, rd
+1);
12439 gen_load_gpr(t1
, rd
);
12440 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12441 tcg_gen_movi_tl(t1
, 4);
12442 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12443 gen_load_gpr(t1
, rd
+1);
12444 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12447 #ifdef TARGET_MIPS64
12450 generate_exception(ctx
, EXCP_RI
);
12453 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12454 gen_store_gpr(t1
, rd
);
12455 tcg_gen_movi_tl(t1
, 8);
12456 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12457 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12458 gen_store_gpr(t1
, rd
+1);
12462 gen_load_gpr(t1
, rd
);
12463 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12464 tcg_gen_movi_tl(t1
, 8);
12465 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12466 gen_load_gpr(t1
, rd
+1);
12467 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12472 (void)opn
; /* avoid a compiler warning */
12473 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
12478 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
12480 int extension
= (ctx
->opcode
>> 6) & 0x3f;
12481 int minor
= (ctx
->opcode
>> 12) & 0xf;
12482 uint32_t mips32_op
;
12484 switch (extension
) {
12486 mips32_op
= OPC_TEQ
;
12489 mips32_op
= OPC_TGE
;
12492 mips32_op
= OPC_TGEU
;
12495 mips32_op
= OPC_TLT
;
12498 mips32_op
= OPC_TLTU
;
12501 mips32_op
= OPC_TNE
;
12503 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
12505 #ifndef CONFIG_USER_ONLY
12508 check_cp0_enabled(ctx
);
12510 /* Treat as NOP. */
12513 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
12517 check_cp0_enabled(ctx
);
12519 TCGv t0
= tcg_temp_new();
12521 gen_load_gpr(t0
, rt
);
12522 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
12528 switch (minor
& 3) {
12530 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12533 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12536 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12539 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12542 goto pool32axf_invalid
;
12546 switch (minor
& 3) {
12548 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12551 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12554 goto pool32axf_invalid
;
12560 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
12563 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
12566 mips32_op
= OPC_CLO
;
12569 mips32_op
= OPC_CLZ
;
12571 check_insn(ctx
, ISA_MIPS32
);
12572 gen_cl(ctx
, mips32_op
, rt
, rs
);
12575 gen_rdhwr(ctx
, rt
, rs
);
12578 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
12581 mips32_op
= OPC_MULT
;
12584 mips32_op
= OPC_MULTU
;
12587 mips32_op
= OPC_DIV
;
12590 mips32_op
= OPC_DIVU
;
12593 check_insn(ctx
, ISA_MIPS32
);
12594 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
12597 mips32_op
= OPC_MADD
;
12600 mips32_op
= OPC_MADDU
;
12603 mips32_op
= OPC_MSUB
;
12606 mips32_op
= OPC_MSUBU
;
12608 check_insn(ctx
, ISA_MIPS32
);
12609 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
12612 goto pool32axf_invalid
;
12623 generate_exception_err(ctx
, EXCP_CpU
, 2);
12626 goto pool32axf_invalid
;
12633 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
12634 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12638 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
12639 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12642 goto pool32axf_invalid
;
12648 check_cp0_enabled(ctx
);
12649 check_insn(ctx
, ISA_MIPS32R2
);
12650 gen_load_srsgpr(rt
, rs
);
12653 check_cp0_enabled(ctx
);
12654 check_insn(ctx
, ISA_MIPS32R2
);
12655 gen_store_srsgpr(rt
, rs
);
12658 goto pool32axf_invalid
;
12661 #ifndef CONFIG_USER_ONLY
12665 mips32_op
= OPC_TLBP
;
12668 mips32_op
= OPC_TLBR
;
12671 mips32_op
= OPC_TLBWI
;
12674 mips32_op
= OPC_TLBWR
;
12677 mips32_op
= OPC_WAIT
;
12680 mips32_op
= OPC_DERET
;
12683 mips32_op
= OPC_ERET
;
12685 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
12688 goto pool32axf_invalid
;
12694 check_cp0_enabled(ctx
);
12696 TCGv t0
= tcg_temp_new();
12698 save_cpu_state(ctx
, 1);
12699 gen_helper_di(t0
, cpu_env
);
12700 gen_store_gpr(t0
, rs
);
12701 /* Stop translation as we may have switched the execution mode */
12702 ctx
->bstate
= BS_STOP
;
12707 check_cp0_enabled(ctx
);
12709 TCGv t0
= tcg_temp_new();
12711 save_cpu_state(ctx
, 1);
12712 gen_helper_ei(t0
, cpu_env
);
12713 gen_store_gpr(t0
, rs
);
12714 /* Stop translation as we may have switched the execution mode */
12715 ctx
->bstate
= BS_STOP
;
12720 goto pool32axf_invalid
;
12730 generate_exception(ctx
, EXCP_SYSCALL
);
12731 ctx
->bstate
= BS_STOP
;
12734 check_insn(ctx
, ISA_MIPS32
);
12735 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
12736 generate_exception(ctx
, EXCP_DBp
);
12738 generate_exception(ctx
, EXCP_DBp
);
12742 goto pool32axf_invalid
;
12746 switch (minor
& 3) {
12748 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
12751 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
12754 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
12757 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
12760 goto pool32axf_invalid
;
12766 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
12769 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
12772 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
12775 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
12778 goto pool32axf_invalid
;
12783 MIPS_INVAL("pool32axf");
12784 generate_exception(ctx
, EXCP_RI
);
12789 /* Values for microMIPS fmt field. Variable-width, depending on which
12790 formats the instruction supports. */
12809 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
12811 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
12812 uint32_t mips32_op
;
12814 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12815 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12816 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12818 switch (extension
) {
12819 case FLOAT_1BIT_FMT(CFC1
, 0):
12820 mips32_op
= OPC_CFC1
;
12822 case FLOAT_1BIT_FMT(CTC1
, 0):
12823 mips32_op
= OPC_CTC1
;
12825 case FLOAT_1BIT_FMT(MFC1
, 0):
12826 mips32_op
= OPC_MFC1
;
12828 case FLOAT_1BIT_FMT(MTC1
, 0):
12829 mips32_op
= OPC_MTC1
;
12831 case FLOAT_1BIT_FMT(MFHC1
, 0):
12832 mips32_op
= OPC_MFHC1
;
12834 case FLOAT_1BIT_FMT(MTHC1
, 0):
12835 mips32_op
= OPC_MTHC1
;
12837 gen_cp1(ctx
, mips32_op
, rt
, rs
);
12840 /* Reciprocal square root */
12841 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
12842 mips32_op
= OPC_RSQRT_S
;
12844 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
12845 mips32_op
= OPC_RSQRT_D
;
12849 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
12850 mips32_op
= OPC_SQRT_S
;
12852 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
12853 mips32_op
= OPC_SQRT_D
;
12857 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
12858 mips32_op
= OPC_RECIP_S
;
12860 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
12861 mips32_op
= OPC_RECIP_D
;
12865 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
12866 mips32_op
= OPC_FLOOR_L_S
;
12868 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
12869 mips32_op
= OPC_FLOOR_L_D
;
12871 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
12872 mips32_op
= OPC_FLOOR_W_S
;
12874 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
12875 mips32_op
= OPC_FLOOR_W_D
;
12879 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
12880 mips32_op
= OPC_CEIL_L_S
;
12882 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
12883 mips32_op
= OPC_CEIL_L_D
;
12885 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
12886 mips32_op
= OPC_CEIL_W_S
;
12888 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
12889 mips32_op
= OPC_CEIL_W_D
;
12893 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
12894 mips32_op
= OPC_TRUNC_L_S
;
12896 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
12897 mips32_op
= OPC_TRUNC_L_D
;
12899 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
12900 mips32_op
= OPC_TRUNC_W_S
;
12902 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
12903 mips32_op
= OPC_TRUNC_W_D
;
12907 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
12908 mips32_op
= OPC_ROUND_L_S
;
12910 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
12911 mips32_op
= OPC_ROUND_L_D
;
12913 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
12914 mips32_op
= OPC_ROUND_W_S
;
12916 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
12917 mips32_op
= OPC_ROUND_W_D
;
12920 /* Integer to floating-point conversion */
12921 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
12922 mips32_op
= OPC_CVT_L_S
;
12924 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
12925 mips32_op
= OPC_CVT_L_D
;
12927 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
12928 mips32_op
= OPC_CVT_W_S
;
12930 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
12931 mips32_op
= OPC_CVT_W_D
;
12934 /* Paired-foo conversions */
12935 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
12936 mips32_op
= OPC_CVT_S_PL
;
12938 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
12939 mips32_op
= OPC_CVT_S_PU
;
12941 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
12942 mips32_op
= OPC_CVT_PW_PS
;
12944 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
12945 mips32_op
= OPC_CVT_PS_PW
;
12948 /* Floating-point moves */
12949 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
12950 mips32_op
= OPC_MOV_S
;
12952 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
12953 mips32_op
= OPC_MOV_D
;
12955 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
12956 mips32_op
= OPC_MOV_PS
;
12959 /* Absolute value */
12960 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
12961 mips32_op
= OPC_ABS_S
;
12963 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
12964 mips32_op
= OPC_ABS_D
;
12966 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
12967 mips32_op
= OPC_ABS_PS
;
12971 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
12972 mips32_op
= OPC_NEG_S
;
12974 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
12975 mips32_op
= OPC_NEG_D
;
12977 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
12978 mips32_op
= OPC_NEG_PS
;
12981 /* Reciprocal square root step */
12982 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
12983 mips32_op
= OPC_RSQRT1_S
;
12985 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
12986 mips32_op
= OPC_RSQRT1_D
;
12988 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
12989 mips32_op
= OPC_RSQRT1_PS
;
12992 /* Reciprocal step */
12993 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
12994 mips32_op
= OPC_RECIP1_S
;
12996 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
12997 mips32_op
= OPC_RECIP1_S
;
12999 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
13000 mips32_op
= OPC_RECIP1_PS
;
13003 /* Conversions from double */
13004 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
13005 mips32_op
= OPC_CVT_D_S
;
13007 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
13008 mips32_op
= OPC_CVT_D_W
;
13010 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
13011 mips32_op
= OPC_CVT_D_L
;
13014 /* Conversions from single */
13015 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
13016 mips32_op
= OPC_CVT_S_D
;
13018 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
13019 mips32_op
= OPC_CVT_S_W
;
13021 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
13022 mips32_op
= OPC_CVT_S_L
;
13024 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
13027 /* Conditional moves on floating-point codes */
13028 case COND_FLOAT_MOV(MOVT
, 0):
13029 case COND_FLOAT_MOV(MOVT
, 1):
13030 case COND_FLOAT_MOV(MOVT
, 2):
13031 case COND_FLOAT_MOV(MOVT
, 3):
13032 case COND_FLOAT_MOV(MOVT
, 4):
13033 case COND_FLOAT_MOV(MOVT
, 5):
13034 case COND_FLOAT_MOV(MOVT
, 6):
13035 case COND_FLOAT_MOV(MOVT
, 7):
13036 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
13038 case COND_FLOAT_MOV(MOVF
, 0):
13039 case COND_FLOAT_MOV(MOVF
, 1):
13040 case COND_FLOAT_MOV(MOVF
, 2):
13041 case COND_FLOAT_MOV(MOVF
, 3):
13042 case COND_FLOAT_MOV(MOVF
, 4):
13043 case COND_FLOAT_MOV(MOVF
, 5):
13044 case COND_FLOAT_MOV(MOVF
, 6):
13045 case COND_FLOAT_MOV(MOVF
, 7):
13046 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
13049 MIPS_INVAL("pool32fxf");
13050 generate_exception(ctx
, EXCP_RI
);
13055 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
13060 int rt
, rs
, rd
, rr
;
13062 uint32_t op
, minor
, mips32_op
;
13063 uint32_t cond
, fmt
, cc
;
13065 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
13066 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
13068 rt
= (ctx
->opcode
>> 21) & 0x1f;
13069 rs
= (ctx
->opcode
>> 16) & 0x1f;
13070 rd
= (ctx
->opcode
>> 11) & 0x1f;
13071 rr
= (ctx
->opcode
>> 6) & 0x1f;
13072 imm
= (int16_t) ctx
->opcode
;
13074 op
= (ctx
->opcode
>> 26) & 0x3f;
13077 minor
= ctx
->opcode
& 0x3f;
13080 minor
= (ctx
->opcode
>> 6) & 0xf;
13083 mips32_op
= OPC_SLL
;
13086 mips32_op
= OPC_SRA
;
13089 mips32_op
= OPC_SRL
;
13092 mips32_op
= OPC_ROTR
;
13094 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
13097 goto pool32a_invalid
;
13101 minor
= (ctx
->opcode
>> 6) & 0xf;
13105 mips32_op
= OPC_ADD
;
13108 mips32_op
= OPC_ADDU
;
13111 mips32_op
= OPC_SUB
;
13114 mips32_op
= OPC_SUBU
;
13117 mips32_op
= OPC_MUL
;
13119 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
13123 mips32_op
= OPC_SLLV
;
13126 mips32_op
= OPC_SRLV
;
13129 mips32_op
= OPC_SRAV
;
13132 mips32_op
= OPC_ROTRV
;
13134 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
13136 /* Logical operations */
13138 mips32_op
= OPC_AND
;
13141 mips32_op
= OPC_OR
;
13144 mips32_op
= OPC_NOR
;
13147 mips32_op
= OPC_XOR
;
13149 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
13151 /* Set less than */
13153 mips32_op
= OPC_SLT
;
13156 mips32_op
= OPC_SLTU
;
13158 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
13161 goto pool32a_invalid
;
13165 minor
= (ctx
->opcode
>> 6) & 0xf;
13167 /* Conditional moves */
13169 mips32_op
= OPC_MOVN
;
13172 mips32_op
= OPC_MOVZ
;
13174 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
13177 gen_ldxs(ctx
, rs
, rt
, rd
);
13180 goto pool32a_invalid
;
13184 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
13187 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
13190 gen_pool32axf(env
, ctx
, rt
, rs
);
13193 generate_exception(ctx
, EXCP_BREAK
);
13197 MIPS_INVAL("pool32a");
13198 generate_exception(ctx
, EXCP_RI
);
13203 minor
= (ctx
->opcode
>> 12) & 0xf;
13206 check_cp0_enabled(ctx
);
13207 /* Treat as no-op. */
13211 /* COP2: Not implemented. */
13212 generate_exception_err(ctx
, EXCP_CpU
, 2);
13216 #ifdef TARGET_MIPS64
13220 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13224 #ifdef TARGET_MIPS64
13228 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13231 MIPS_INVAL("pool32b");
13232 generate_exception(ctx
, EXCP_RI
);
13237 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
13238 minor
= ctx
->opcode
& 0x3f;
13239 check_cp1_enabled(ctx
);
13242 mips32_op
= OPC_ALNV_PS
;
13245 mips32_op
= OPC_MADD_S
;
13248 mips32_op
= OPC_MADD_D
;
13251 mips32_op
= OPC_MADD_PS
;
13254 mips32_op
= OPC_MSUB_S
;
13257 mips32_op
= OPC_MSUB_D
;
13260 mips32_op
= OPC_MSUB_PS
;
13263 mips32_op
= OPC_NMADD_S
;
13266 mips32_op
= OPC_NMADD_D
;
13269 mips32_op
= OPC_NMADD_PS
;
13272 mips32_op
= OPC_NMSUB_S
;
13275 mips32_op
= OPC_NMSUB_D
;
13278 mips32_op
= OPC_NMSUB_PS
;
13280 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
13282 case CABS_COND_FMT
:
13283 cond
= (ctx
->opcode
>> 6) & 0xf;
13284 cc
= (ctx
->opcode
>> 13) & 0x7;
13285 fmt
= (ctx
->opcode
>> 10) & 0x3;
13288 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
13291 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
13294 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
13297 goto pool32f_invalid
;
13301 cond
= (ctx
->opcode
>> 6) & 0xf;
13302 cc
= (ctx
->opcode
>> 13) & 0x7;
13303 fmt
= (ctx
->opcode
>> 10) & 0x3;
13306 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
13309 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
13312 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
13315 goto pool32f_invalid
;
13319 gen_pool32fxf(ctx
, rt
, rs
);
13323 switch ((ctx
->opcode
>> 6) & 0x7) {
13325 mips32_op
= OPC_PLL_PS
;
13328 mips32_op
= OPC_PLU_PS
;
13331 mips32_op
= OPC_PUL_PS
;
13334 mips32_op
= OPC_PUU_PS
;
13337 mips32_op
= OPC_CVT_PS_S
;
13339 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13342 goto pool32f_invalid
;
13347 switch ((ctx
->opcode
>> 6) & 0x7) {
13349 mips32_op
= OPC_LWXC1
;
13352 mips32_op
= OPC_SWXC1
;
13355 mips32_op
= OPC_LDXC1
;
13358 mips32_op
= OPC_SDXC1
;
13361 mips32_op
= OPC_LUXC1
;
13364 mips32_op
= OPC_SUXC1
;
13366 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
13369 goto pool32f_invalid
;
13374 fmt
= (ctx
->opcode
>> 9) & 0x3;
13375 switch ((ctx
->opcode
>> 6) & 0x7) {
13379 mips32_op
= OPC_RSQRT2_S
;
13382 mips32_op
= OPC_RSQRT2_D
;
13385 mips32_op
= OPC_RSQRT2_PS
;
13388 goto pool32f_invalid
;
13394 mips32_op
= OPC_RECIP2_S
;
13397 mips32_op
= OPC_RECIP2_D
;
13400 mips32_op
= OPC_RECIP2_PS
;
13403 goto pool32f_invalid
;
13407 mips32_op
= OPC_ADDR_PS
;
13410 mips32_op
= OPC_MULR_PS
;
13412 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13415 goto pool32f_invalid
;
13419 /* MOV[FT].fmt and PREFX */
13420 cc
= (ctx
->opcode
>> 13) & 0x7;
13421 fmt
= (ctx
->opcode
>> 9) & 0x3;
13422 switch ((ctx
->opcode
>> 6) & 0x7) {
13426 gen_movcf_s(rs
, rt
, cc
, 0);
13429 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
13432 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
13435 goto pool32f_invalid
;
13441 gen_movcf_s(rs
, rt
, cc
, 1);
13444 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
13447 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
13450 goto pool32f_invalid
;
13456 goto pool32f_invalid
;
13459 #define FINSN_3ARG_SDPS(prfx) \
13460 switch ((ctx->opcode >> 8) & 0x3) { \
13462 mips32_op = OPC_##prfx##_S; \
13465 mips32_op = OPC_##prfx##_D; \
13467 case FMT_SDPS_PS: \
13468 mips32_op = OPC_##prfx##_PS; \
13471 goto pool32f_invalid; \
13474 /* regular FP ops */
13475 switch ((ctx
->opcode
>> 6) & 0x3) {
13477 FINSN_3ARG_SDPS(ADD
);
13480 FINSN_3ARG_SDPS(SUB
);
13483 FINSN_3ARG_SDPS(MUL
);
13486 fmt
= (ctx
->opcode
>> 8) & 0x3;
13488 mips32_op
= OPC_DIV_D
;
13489 } else if (fmt
== 0) {
13490 mips32_op
= OPC_DIV_S
;
13492 goto pool32f_invalid
;
13496 goto pool32f_invalid
;
13501 switch ((ctx
->opcode
>> 6) & 0x3) {
13503 FINSN_3ARG_SDPS(MOVN
);
13506 FINSN_3ARG_SDPS(MOVZ
);
13509 goto pool32f_invalid
;
13513 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13517 MIPS_INVAL("pool32f");
13518 generate_exception(ctx
, EXCP_RI
);
13522 generate_exception_err(ctx
, EXCP_CpU
, 1);
13526 minor
= (ctx
->opcode
>> 21) & 0x1f;
13529 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
13532 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
13533 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13536 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
13537 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13540 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
13543 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
13544 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13547 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
13548 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13551 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
13554 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
13559 mips32_op
= OPC_TLTI
;
13562 mips32_op
= OPC_TGEI
;
13565 mips32_op
= OPC_TLTIU
;
13568 mips32_op
= OPC_TGEIU
;
13571 mips32_op
= OPC_TNEI
;
13574 mips32_op
= OPC_TEQI
;
13576 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
13581 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
13582 4, rs
, 0, imm
<< 1, 0);
13583 /* Compact branches don't have a delay slot, so just let
13584 the normal delay slot handling take us to the branch
13588 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
13591 /* Break the TB to be able to sync copied instructions
13593 ctx
->bstate
= BS_STOP
;
13597 /* COP2: Not implemented. */
13598 generate_exception_err(ctx
, EXCP_CpU
, 2);
13601 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
13604 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
13607 mips32_op
= OPC_BC1FANY4
;
13610 mips32_op
= OPC_BC1TANY4
;
13613 check_insn(ctx
, ASE_MIPS3D
);
13616 gen_compute_branch1(ctx
, mips32_op
,
13617 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
13621 /* MIPS DSP: not implemented */
13624 MIPS_INVAL("pool32i");
13625 generate_exception(ctx
, EXCP_RI
);
13630 minor
= (ctx
->opcode
>> 12) & 0xf;
13633 mips32_op
= OPC_LWL
;
13636 mips32_op
= OPC_SWL
;
13639 mips32_op
= OPC_LWR
;
13642 mips32_op
= OPC_SWR
;
13644 #if defined(TARGET_MIPS64)
13646 mips32_op
= OPC_LDL
;
13649 mips32_op
= OPC_SDL
;
13652 mips32_op
= OPC_LDR
;
13655 mips32_op
= OPC_SDR
;
13658 mips32_op
= OPC_LWU
;
13661 mips32_op
= OPC_LLD
;
13665 mips32_op
= OPC_LL
;
13668 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13671 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13674 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13676 #if defined(TARGET_MIPS64)
13678 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13682 /* Treat as no-op */
13685 MIPS_INVAL("pool32c");
13686 generate_exception(ctx
, EXCP_RI
);
13691 mips32_op
= OPC_ADDI
;
13694 mips32_op
= OPC_ADDIU
;
13696 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13699 /* Logical operations */
13701 mips32_op
= OPC_ORI
;
13704 mips32_op
= OPC_XORI
;
13707 mips32_op
= OPC_ANDI
;
13709 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13712 /* Set less than immediate */
13714 mips32_op
= OPC_SLTI
;
13717 mips32_op
= OPC_SLTIU
;
13719 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13722 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
13723 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
13724 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13727 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
13728 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
13729 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13732 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
13735 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
13738 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
13739 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
13742 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
13743 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
13744 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13746 /* Floating point (COP1) */
13748 mips32_op
= OPC_LWC1
;
13751 mips32_op
= OPC_LDC1
;
13754 mips32_op
= OPC_SWC1
;
13757 mips32_op
= OPC_SDC1
;
13759 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
13763 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
13764 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
13766 gen_addiupc(ctx
, reg
, offset
, 0, 0);
13769 /* Loads and stores */
13771 mips32_op
= OPC_LB
;
13774 mips32_op
= OPC_LBU
;
13777 mips32_op
= OPC_LH
;
13780 mips32_op
= OPC_LHU
;
13783 mips32_op
= OPC_LW
;
13785 #ifdef TARGET_MIPS64
13787 mips32_op
= OPC_LD
;
13790 mips32_op
= OPC_SD
;
13794 mips32_op
= OPC_SB
;
13797 mips32_op
= OPC_SH
;
13800 mips32_op
= OPC_SW
;
13803 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
13806 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
13809 generate_exception(ctx
, EXCP_RI
);
13814 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
13818 /* make sure instructions are on a halfword boundary */
13819 if (ctx
->pc
& 0x1) {
13820 env
->CP0_BadVAddr
= ctx
->pc
;
13821 generate_exception(ctx
, EXCP_AdEL
);
13822 ctx
->bstate
= BS_STOP
;
13826 op
= (ctx
->opcode
>> 10) & 0x3f;
13827 /* Enforce properly-sized instructions in a delay slot */
13828 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
13829 switch (op
& 0x7) { /* MSB-3..MSB-5 */
13831 /* POOL32A, POOL32B, POOL32I, POOL32C */
13833 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13835 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13837 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13839 /* LB32, LH32, LWC132, LDC132, LW32 */
13840 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
13841 generate_exception(ctx
, EXCP_RI
);
13842 /* Just stop translation; the user is confused. */
13843 ctx
->bstate
= BS_STOP
;
13848 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13850 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13852 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13853 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
13854 generate_exception(ctx
, EXCP_RI
);
13855 /* Just stop translation; the user is confused. */
13856 ctx
->bstate
= BS_STOP
;
13866 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13867 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
13868 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
13871 switch (ctx
->opcode
& 0x1) {
13880 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
13885 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13886 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
13887 int amount
= (ctx
->opcode
>> 1) & 0x7;
13889 amount
= amount
== 0 ? 8 : amount
;
13891 switch (ctx
->opcode
& 0x1) {
13900 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
13904 gen_pool16c_insn(ctx
);
13908 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13909 int rb
= 28; /* GP */
13910 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
13912 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13916 if (ctx
->opcode
& 1) {
13917 generate_exception(ctx
, EXCP_RI
);
13920 int enc_dest
= uMIPS_RD(ctx
->opcode
);
13921 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
13922 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
13923 int rd
, rs
, re
, rt
;
13924 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13925 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13926 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13928 rd
= rd_enc
[enc_dest
];
13929 re
= re_enc
[enc_dest
];
13930 rs
= rs_rt_enc
[enc_rs
];
13931 rt
= rs_rt_enc
[enc_rt
];
13933 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
13934 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
13939 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13940 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13941 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
13942 offset
= (offset
== 0xf ? -1 : offset
);
13944 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
13949 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13950 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13951 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
13953 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
13958 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13959 int rb
= 29; /* SP */
13960 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
13962 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13967 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13968 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13969 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
13971 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13976 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13977 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13978 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
13980 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
13985 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13986 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13987 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
13989 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
13994 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13995 int rb
= 29; /* SP */
13996 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
13998 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
14003 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
14004 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
14005 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
14007 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
14012 int rd
= uMIPS_RD5(ctx
->opcode
);
14013 int rs
= uMIPS_RS5(ctx
->opcode
);
14015 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
14022 switch (ctx
->opcode
& 0x1) {
14032 switch (ctx
->opcode
& 0x1) {
14037 gen_addiur1sp(ctx
);
14042 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
14043 SIMM(ctx
->opcode
, 0, 10) << 1, 4);
14047 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
14048 mmreg(uMIPS_RD(ctx
->opcode
)),
14049 0, SIMM(ctx
->opcode
, 0, 7) << 1, 4);
14053 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
14054 int imm
= ZIMM(ctx
->opcode
, 0, 7);
14056 imm
= (imm
== 0x7f ? -1 : imm
);
14057 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
14067 generate_exception(ctx
, EXCP_RI
);
14070 decode_micromips32_opc (env
, ctx
, op
);
14077 /* SmartMIPS extension to MIPS32 */
14079 #if defined(TARGET_MIPS64)
14081 /* MDMX extension to MIPS64 */
14085 /* MIPSDSP functions. */
14086 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
14087 int rd
, int base
, int offset
)
14089 const char *opn
= "ldx";
14093 t0
= tcg_temp_new();
14096 gen_load_gpr(t0
, offset
);
14097 } else if (offset
== 0) {
14098 gen_load_gpr(t0
, base
);
14100 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
14105 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
14106 gen_store_gpr(t0
, rd
);
14110 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
14111 gen_store_gpr(t0
, rd
);
14115 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
14116 gen_store_gpr(t0
, rd
);
14119 #if defined(TARGET_MIPS64)
14121 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
14122 gen_store_gpr(t0
, rd
);
14127 (void)opn
; /* avoid a compiler warning */
14128 MIPS_DEBUG("%s %s, %s(%s)", opn
,
14129 regnames
[rd
], regnames
[offset
], regnames
[base
]);
14133 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14134 int ret
, int v1
, int v2
)
14136 const char *opn
= "mipsdsp arith";
14141 /* Treat as NOP. */
14146 v1_t
= tcg_temp_new();
14147 v2_t
= tcg_temp_new();
14149 gen_load_gpr(v1_t
, v1
);
14150 gen_load_gpr(v2_t
, v2
);
14153 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
14154 case OPC_MULT_G_2E
:
14158 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14160 case OPC_ADDUH_R_QB
:
14161 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14164 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14166 case OPC_ADDQH_R_PH
:
14167 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14170 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14172 case OPC_ADDQH_R_W
:
14173 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14176 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14178 case OPC_SUBUH_R_QB
:
14179 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14182 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14184 case OPC_SUBQH_R_PH
:
14185 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14188 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14190 case OPC_SUBQH_R_W
:
14191 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14195 case OPC_ABSQ_S_PH_DSP
:
14197 case OPC_ABSQ_S_QB
:
14199 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
14201 case OPC_ABSQ_S_PH
:
14203 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
14207 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
14209 case OPC_PRECEQ_W_PHL
:
14211 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
14212 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
14214 case OPC_PRECEQ_W_PHR
:
14216 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
14217 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
14218 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
14220 case OPC_PRECEQU_PH_QBL
:
14222 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
14224 case OPC_PRECEQU_PH_QBR
:
14226 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
14228 case OPC_PRECEQU_PH_QBLA
:
14230 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
14232 case OPC_PRECEQU_PH_QBRA
:
14234 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
14236 case OPC_PRECEU_PH_QBL
:
14238 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
14240 case OPC_PRECEU_PH_QBR
:
14242 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
14244 case OPC_PRECEU_PH_QBLA
:
14246 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
14248 case OPC_PRECEU_PH_QBRA
:
14250 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
14254 case OPC_ADDU_QB_DSP
:
14258 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14260 case OPC_ADDQ_S_PH
:
14262 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14266 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14270 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14272 case OPC_ADDU_S_QB
:
14274 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14278 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14280 case OPC_ADDU_S_PH
:
14282 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14286 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14288 case OPC_SUBQ_S_PH
:
14290 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14294 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14298 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14300 case OPC_SUBU_S_QB
:
14302 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14306 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14308 case OPC_SUBU_S_PH
:
14310 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14314 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14318 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14322 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
14324 case OPC_RADDU_W_QB
:
14326 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
14330 case OPC_CMPU_EQ_QB_DSP
:
14332 case OPC_PRECR_QB_PH
:
14334 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14336 case OPC_PRECRQ_QB_PH
:
14338 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14340 case OPC_PRECR_SRA_PH_W
:
14343 TCGv_i32 sa_t
= tcg_const_i32(v2
);
14344 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
14346 tcg_temp_free_i32(sa_t
);
14349 case OPC_PRECR_SRA_R_PH_W
:
14352 TCGv_i32 sa_t
= tcg_const_i32(v2
);
14353 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
14355 tcg_temp_free_i32(sa_t
);
14358 case OPC_PRECRQ_PH_W
:
14360 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14362 case OPC_PRECRQ_RS_PH_W
:
14364 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14366 case OPC_PRECRQU_S_QB_PH
:
14368 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14372 #ifdef TARGET_MIPS64
14373 case OPC_ABSQ_S_QH_DSP
:
14375 case OPC_PRECEQ_L_PWL
:
14377 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
14379 case OPC_PRECEQ_L_PWR
:
14381 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
14383 case OPC_PRECEQ_PW_QHL
:
14385 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
14387 case OPC_PRECEQ_PW_QHR
:
14389 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
14391 case OPC_PRECEQ_PW_QHLA
:
14393 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
14395 case OPC_PRECEQ_PW_QHRA
:
14397 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
14399 case OPC_PRECEQU_QH_OBL
:
14401 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
14403 case OPC_PRECEQU_QH_OBR
:
14405 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
14407 case OPC_PRECEQU_QH_OBLA
:
14409 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
14411 case OPC_PRECEQU_QH_OBRA
:
14413 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
14415 case OPC_PRECEU_QH_OBL
:
14417 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
14419 case OPC_PRECEU_QH_OBR
:
14421 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
14423 case OPC_PRECEU_QH_OBLA
:
14425 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
14427 case OPC_PRECEU_QH_OBRA
:
14429 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
14431 case OPC_ABSQ_S_OB
:
14433 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
14435 case OPC_ABSQ_S_PW
:
14437 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
14439 case OPC_ABSQ_S_QH
:
14441 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
14445 case OPC_ADDU_OB_DSP
:
14447 case OPC_RADDU_L_OB
:
14449 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
14453 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14455 case OPC_SUBQ_S_PW
:
14457 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14461 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14463 case OPC_SUBQ_S_QH
:
14465 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14469 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14471 case OPC_SUBU_S_OB
:
14473 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14477 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14479 case OPC_SUBU_S_QH
:
14481 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14485 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14487 case OPC_SUBUH_R_OB
:
14489 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14493 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14495 case OPC_ADDQ_S_PW
:
14497 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14501 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14503 case OPC_ADDQ_S_QH
:
14505 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14509 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14511 case OPC_ADDU_S_OB
:
14513 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14517 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14519 case OPC_ADDU_S_QH
:
14521 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14525 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14527 case OPC_ADDUH_R_OB
:
14529 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14533 case OPC_CMPU_EQ_OB_DSP
:
14535 case OPC_PRECR_OB_QH
:
14537 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
14539 case OPC_PRECR_SRA_QH_PW
:
14542 TCGv_i32 ret_t
= tcg_const_i32(ret
);
14543 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
14544 tcg_temp_free_i32(ret_t
);
14547 case OPC_PRECR_SRA_R_QH_PW
:
14550 TCGv_i32 sa_v
= tcg_const_i32(ret
);
14551 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
14552 tcg_temp_free_i32(sa_v
);
14555 case OPC_PRECRQ_OB_QH
:
14557 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
14559 case OPC_PRECRQ_PW_L
:
14561 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
14563 case OPC_PRECRQ_QH_PW
:
14565 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14567 case OPC_PRECRQ_RS_QH_PW
:
14569 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14571 case OPC_PRECRQU_S_OB_QH
:
14573 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14580 tcg_temp_free(v1_t
);
14581 tcg_temp_free(v2_t
);
14583 (void)opn
; /* avoid a compiler warning */
14584 MIPS_DEBUG("%s", opn
);
14587 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
14588 int ret
, int v1
, int v2
)
14591 const char *opn
= "mipsdsp shift";
14597 /* Treat as NOP. */
14602 t0
= tcg_temp_new();
14603 v1_t
= tcg_temp_new();
14604 v2_t
= tcg_temp_new();
14606 tcg_gen_movi_tl(t0
, v1
);
14607 gen_load_gpr(v1_t
, v1
);
14608 gen_load_gpr(v2_t
, v2
);
14611 case OPC_SHLL_QB_DSP
:
14613 op2
= MASK_SHLL_QB(ctx
->opcode
);
14617 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14621 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14625 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14629 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14631 case OPC_SHLL_S_PH
:
14633 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14635 case OPC_SHLLV_S_PH
:
14637 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14641 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14643 case OPC_SHLLV_S_W
:
14645 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14649 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
14653 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14657 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
14661 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14665 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
14667 case OPC_SHRA_R_QB
:
14669 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
14673 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14675 case OPC_SHRAV_R_QB
:
14677 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14681 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
14683 case OPC_SHRA_R_PH
:
14685 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
14689 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14691 case OPC_SHRAV_R_PH
:
14693 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14697 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
14699 case OPC_SHRAV_R_W
:
14701 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14703 default: /* Invalid */
14704 MIPS_INVAL("MASK SHLL.QB");
14705 generate_exception(ctx
, EXCP_RI
);
14710 #ifdef TARGET_MIPS64
14711 case OPC_SHLL_OB_DSP
:
14712 op2
= MASK_SHLL_OB(ctx
->opcode
);
14716 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14720 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14722 case OPC_SHLL_S_PW
:
14724 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14726 case OPC_SHLLV_S_PW
:
14728 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14732 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14736 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14740 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14744 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14746 case OPC_SHLL_S_QH
:
14748 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14750 case OPC_SHLLV_S_QH
:
14752 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14756 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
14760 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14762 case OPC_SHRA_R_OB
:
14764 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
14766 case OPC_SHRAV_R_OB
:
14768 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14772 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
14776 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
14778 case OPC_SHRA_R_PW
:
14780 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
14782 case OPC_SHRAV_R_PW
:
14784 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
14788 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
14792 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14794 case OPC_SHRA_R_QH
:
14796 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
14798 case OPC_SHRAV_R_QH
:
14800 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14804 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
14808 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14812 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
14816 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14818 default: /* Invalid */
14819 MIPS_INVAL("MASK SHLL.OB");
14820 generate_exception(ctx
, EXCP_RI
);
14828 tcg_temp_free(v1_t
);
14829 tcg_temp_free(v2_t
);
14830 (void)opn
; /* avoid a compiler warning */
14831 MIPS_DEBUG("%s", opn
);
14834 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14835 int ret
, int v1
, int v2
, int check_ret
)
14837 const char *opn
= "mipsdsp multiply";
14842 if ((ret
== 0) && (check_ret
== 1)) {
14843 /* Treat as NOP. */
14848 t0
= tcg_temp_new_i32();
14849 v1_t
= tcg_temp_new();
14850 v2_t
= tcg_temp_new();
14852 tcg_gen_movi_i32(t0
, ret
);
14853 gen_load_gpr(v1_t
, v1
);
14854 gen_load_gpr(v2_t
, v2
);
14857 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14858 * the same mask and op1. */
14859 case OPC_MULT_G_2E
:
14863 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14866 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14869 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14871 case OPC_MULQ_RS_W
:
14872 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14876 case OPC_DPA_W_PH_DSP
:
14878 case OPC_DPAU_H_QBL
:
14880 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
14882 case OPC_DPAU_H_QBR
:
14884 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
14886 case OPC_DPSU_H_QBL
:
14888 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
14890 case OPC_DPSU_H_QBR
:
14892 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
14896 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14898 case OPC_DPAX_W_PH
:
14900 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14902 case OPC_DPAQ_S_W_PH
:
14904 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14906 case OPC_DPAQX_S_W_PH
:
14908 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14910 case OPC_DPAQX_SA_W_PH
:
14912 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14916 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14918 case OPC_DPSX_W_PH
:
14920 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14922 case OPC_DPSQ_S_W_PH
:
14924 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14926 case OPC_DPSQX_S_W_PH
:
14928 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14930 case OPC_DPSQX_SA_W_PH
:
14932 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14934 case OPC_MULSAQ_S_W_PH
:
14936 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14938 case OPC_DPAQ_SA_L_W
:
14940 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
14942 case OPC_DPSQ_SA_L_W
:
14944 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
14946 case OPC_MAQ_S_W_PHL
:
14948 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
14950 case OPC_MAQ_S_W_PHR
:
14952 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
14954 case OPC_MAQ_SA_W_PHL
:
14956 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
14958 case OPC_MAQ_SA_W_PHR
:
14960 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
14962 case OPC_MULSA_W_PH
:
14964 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14968 #ifdef TARGET_MIPS64
14969 case OPC_DPAQ_W_QH_DSP
:
14971 int ac
= ret
& 0x03;
14972 tcg_gen_movi_i32(t0
, ac
);
14977 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
14981 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
14985 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
14989 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
14993 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14995 case OPC_DPAQ_S_W_QH
:
14997 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14999 case OPC_DPAQ_SA_L_PW
:
15001 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
15003 case OPC_DPAU_H_OBL
:
15005 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
15007 case OPC_DPAU_H_OBR
:
15009 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
15013 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
15015 case OPC_DPSQ_S_W_QH
:
15017 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
15019 case OPC_DPSQ_SA_L_PW
:
15021 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
15023 case OPC_DPSU_H_OBL
:
15025 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
15027 case OPC_DPSU_H_OBR
:
15029 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
15031 case OPC_MAQ_S_L_PWL
:
15033 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
15035 case OPC_MAQ_S_L_PWR
:
15037 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
15039 case OPC_MAQ_S_W_QHLL
:
15041 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
15043 case OPC_MAQ_SA_W_QHLL
:
15045 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
15047 case OPC_MAQ_S_W_QHLR
:
15049 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
15051 case OPC_MAQ_SA_W_QHLR
:
15053 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
15055 case OPC_MAQ_S_W_QHRL
:
15057 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
15059 case OPC_MAQ_SA_W_QHRL
:
15061 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
15063 case OPC_MAQ_S_W_QHRR
:
15065 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
15067 case OPC_MAQ_SA_W_QHRR
:
15069 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
15071 case OPC_MULSAQ_S_L_PW
:
15073 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
15075 case OPC_MULSAQ_S_W_QH
:
15077 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
15083 case OPC_ADDU_QB_DSP
:
15085 case OPC_MULEU_S_PH_QBL
:
15087 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15089 case OPC_MULEU_S_PH_QBR
:
15091 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15093 case OPC_MULQ_RS_PH
:
15095 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15097 case OPC_MULEQ_S_W_PHL
:
15099 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15101 case OPC_MULEQ_S_W_PHR
:
15103 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15105 case OPC_MULQ_S_PH
:
15107 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15111 #ifdef TARGET_MIPS64
15112 case OPC_ADDU_OB_DSP
:
15114 case OPC_MULEQ_S_PW_QHL
:
15116 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15118 case OPC_MULEQ_S_PW_QHR
:
15120 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15122 case OPC_MULEU_S_QH_OBL
:
15124 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15126 case OPC_MULEU_S_QH_OBR
:
15128 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15130 case OPC_MULQ_RS_QH
:
15132 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15139 tcg_temp_free_i32(t0
);
15140 tcg_temp_free(v1_t
);
15141 tcg_temp_free(v2_t
);
15143 (void)opn
; /* avoid a compiler warning */
15144 MIPS_DEBUG("%s", opn
);
15148 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15151 const char *opn
= "mipsdsp Bit/ Manipulation";
15157 /* Treat as NOP. */
15162 t0
= tcg_temp_new();
15163 val_t
= tcg_temp_new();
15164 gen_load_gpr(val_t
, val
);
15167 case OPC_ABSQ_S_PH_DSP
:
15171 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
15176 target_long result
;
15177 imm
= (ctx
->opcode
>> 16) & 0xFF;
15178 result
= (uint32_t)imm
<< 24 |
15179 (uint32_t)imm
<< 16 |
15180 (uint32_t)imm
<< 8 |
15182 result
= (int32_t)result
;
15183 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
15188 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
15189 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
15190 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15191 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
15192 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15193 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15198 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15199 imm
= (int16_t)(imm
<< 6) >> 6;
15200 tcg_gen_movi_tl(cpu_gpr
[ret
], \
15201 (target_long
)((int32_t)imm
<< 16 | \
15207 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
15208 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
15209 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15210 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15214 #ifdef TARGET_MIPS64
15215 case OPC_ABSQ_S_QH_DSP
:
15222 imm
= (ctx
->opcode
>> 16) & 0xFF;
15223 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
15224 temp
= (temp
<< 16) | temp
;
15225 temp
= (temp
<< 32) | temp
;
15226 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
15234 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15235 imm
= (int16_t)(imm
<< 6) >> 6;
15236 temp
= ((target_long
)imm
<< 32) \
15237 | ((target_long
)imm
& 0xFFFFFFFF);
15238 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
15246 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15247 imm
= (int16_t)(imm
<< 6) >> 6;
15249 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
15250 ((uint64_t)(uint16_t)imm
<< 32) |
15251 ((uint64_t)(uint16_t)imm
<< 16) |
15252 (uint64_t)(uint16_t)imm
;
15253 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
15258 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
15259 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
15260 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15261 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
15262 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15263 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
15264 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15268 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
15269 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
15270 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15274 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
15275 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
15276 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15277 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
15278 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
15285 tcg_temp_free(val_t
);
15287 (void)opn
; /* avoid a compiler warning */
15288 MIPS_DEBUG("%s", opn
);
15291 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
15292 uint32_t op1
, uint32_t op2
,
15293 int ret
, int v1
, int v2
, int check_ret
)
15295 const char *opn
= "mipsdsp add compare pick";
15300 if ((ret
== 0) && (check_ret
== 1)) {
15301 /* Treat as NOP. */
15306 t1
= tcg_temp_new();
15307 v1_t
= tcg_temp_new();
15308 v2_t
= tcg_temp_new();
15310 gen_load_gpr(v1_t
, v1
);
15311 gen_load_gpr(v2_t
, v2
);
15314 case OPC_CMPU_EQ_QB_DSP
:
15316 case OPC_CMPU_EQ_QB
:
15318 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
15320 case OPC_CMPU_LT_QB
:
15322 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
15324 case OPC_CMPU_LE_QB
:
15326 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
15328 case OPC_CMPGU_EQ_QB
:
15330 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15332 case OPC_CMPGU_LT_QB
:
15334 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15336 case OPC_CMPGU_LE_QB
:
15338 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15340 case OPC_CMPGDU_EQ_QB
:
15342 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
15343 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
15344 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
15345 tcg_gen_shli_tl(t1
, t1
, 24);
15346 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
15348 case OPC_CMPGDU_LT_QB
:
15350 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
15351 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
15352 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
15353 tcg_gen_shli_tl(t1
, t1
, 24);
15354 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
15356 case OPC_CMPGDU_LE_QB
:
15358 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
15359 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
15360 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
15361 tcg_gen_shli_tl(t1
, t1
, 24);
15362 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
15364 case OPC_CMP_EQ_PH
:
15366 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
15368 case OPC_CMP_LT_PH
:
15370 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
15372 case OPC_CMP_LE_PH
:
15374 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
15378 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15382 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15384 case OPC_PACKRL_PH
:
15386 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15390 #ifdef TARGET_MIPS64
15391 case OPC_CMPU_EQ_OB_DSP
:
15393 case OPC_CMP_EQ_PW
:
15395 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
15397 case OPC_CMP_LT_PW
:
15399 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
15401 case OPC_CMP_LE_PW
:
15403 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
15405 case OPC_CMP_EQ_QH
:
15407 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
15409 case OPC_CMP_LT_QH
:
15411 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
15413 case OPC_CMP_LE_QH
:
15415 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
15417 case OPC_CMPGDU_EQ_OB
:
15419 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15421 case OPC_CMPGDU_LT_OB
:
15423 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15425 case OPC_CMPGDU_LE_OB
:
15427 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15429 case OPC_CMPGU_EQ_OB
:
15431 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15433 case OPC_CMPGU_LT_OB
:
15435 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15437 case OPC_CMPGU_LE_OB
:
15439 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15441 case OPC_CMPU_EQ_OB
:
15443 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
15445 case OPC_CMPU_LT_OB
:
15447 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
15449 case OPC_CMPU_LE_OB
:
15451 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
15453 case OPC_PACKRL_PW
:
15455 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
15459 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15463 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15467 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15475 tcg_temp_free(v1_t
);
15476 tcg_temp_free(v2_t
);
15478 (void)opn
; /* avoid a compiler warning */
15479 MIPS_DEBUG("%s", opn
);
15482 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
15483 uint32_t op1
, int rt
, int rs
, int sa
)
15485 const char *opn
= "mipsdsp append/dappend";
15491 /* Treat as NOP. */
15496 t0
= tcg_temp_new();
15497 gen_load_gpr(t0
, rs
);
15500 case OPC_APPEND_DSP
:
15501 switch (MASK_APPEND(ctx
->opcode
)) {
15504 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
15506 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15510 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15511 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
15512 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
15513 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15515 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15519 if (sa
!= 0 && sa
!= 2) {
15520 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
15521 tcg_gen_ext32u_tl(t0
, t0
);
15522 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
15523 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15525 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15527 default: /* Invalid */
15528 MIPS_INVAL("MASK APPEND");
15529 generate_exception(ctx
, EXCP_RI
);
15533 #ifdef TARGET_MIPS64
15534 case OPC_DAPPEND_DSP
:
15535 switch (MASK_DAPPEND(ctx
->opcode
)) {
15538 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
15542 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
15543 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
15544 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
15548 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
15549 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
15550 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15555 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
15556 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
15557 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
15558 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15561 default: /* Invalid */
15562 MIPS_INVAL("MASK DAPPEND");
15563 generate_exception(ctx
, EXCP_RI
);
15570 (void)opn
; /* avoid a compiler warning */
15571 MIPS_DEBUG("%s", opn
);
15574 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15575 int ret
, int v1
, int v2
, int check_ret
)
15578 const char *opn
= "mipsdsp accumulator";
15585 if ((ret
== 0) && (check_ret
== 1)) {
15586 /* Treat as NOP. */
15591 t0
= tcg_temp_new();
15592 t1
= tcg_temp_new();
15593 v1_t
= tcg_temp_new();
15594 v2_t
= tcg_temp_new();
15596 gen_load_gpr(v1_t
, v1
);
15597 gen_load_gpr(v2_t
, v2
);
15600 case OPC_EXTR_W_DSP
:
15604 tcg_gen_movi_tl(t0
, v2
);
15605 tcg_gen_movi_tl(t1
, v1
);
15606 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15609 tcg_gen_movi_tl(t0
, v2
);
15610 tcg_gen_movi_tl(t1
, v1
);
15611 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15613 case OPC_EXTR_RS_W
:
15614 tcg_gen_movi_tl(t0
, v2
);
15615 tcg_gen_movi_tl(t1
, v1
);
15616 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15619 tcg_gen_movi_tl(t0
, v2
);
15620 tcg_gen_movi_tl(t1
, v1
);
15621 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15623 case OPC_EXTRV_S_H
:
15624 tcg_gen_movi_tl(t0
, v2
);
15625 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15628 tcg_gen_movi_tl(t0
, v2
);
15629 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15631 case OPC_EXTRV_R_W
:
15632 tcg_gen_movi_tl(t0
, v2
);
15633 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15635 case OPC_EXTRV_RS_W
:
15636 tcg_gen_movi_tl(t0
, v2
);
15637 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15640 tcg_gen_movi_tl(t0
, v2
);
15641 tcg_gen_movi_tl(t1
, v1
);
15642 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15645 tcg_gen_movi_tl(t0
, v2
);
15646 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15649 tcg_gen_movi_tl(t0
, v2
);
15650 tcg_gen_movi_tl(t1
, v1
);
15651 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15654 tcg_gen_movi_tl(t0
, v2
);
15655 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15658 imm
= (ctx
->opcode
>> 20) & 0x3F;
15659 tcg_gen_movi_tl(t0
, ret
);
15660 tcg_gen_movi_tl(t1
, imm
);
15661 gen_helper_shilo(t0
, t1
, cpu_env
);
15664 tcg_gen_movi_tl(t0
, ret
);
15665 gen_helper_shilo(t0
, v1_t
, cpu_env
);
15668 tcg_gen_movi_tl(t0
, ret
);
15669 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
15672 imm
= (ctx
->opcode
>> 11) & 0x3FF;
15673 tcg_gen_movi_tl(t0
, imm
);
15674 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
15677 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15678 tcg_gen_movi_tl(t0
, imm
);
15679 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
15683 #ifdef TARGET_MIPS64
15684 case OPC_DEXTR_W_DSP
:
15688 tcg_gen_movi_tl(t0
, ret
);
15689 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
15693 int shift
= (ctx
->opcode
>> 19) & 0x7F;
15694 int ac
= (ctx
->opcode
>> 11) & 0x03;
15695 tcg_gen_movi_tl(t0
, shift
);
15696 tcg_gen_movi_tl(t1
, ac
);
15697 gen_helper_dshilo(t0
, t1
, cpu_env
);
15702 int ac
= (ctx
->opcode
>> 11) & 0x03;
15703 tcg_gen_movi_tl(t0
, ac
);
15704 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
15708 tcg_gen_movi_tl(t0
, v2
);
15709 tcg_gen_movi_tl(t1
, v1
);
15711 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15714 tcg_gen_movi_tl(t0
, v2
);
15715 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15718 tcg_gen_movi_tl(t0
, v2
);
15719 tcg_gen_movi_tl(t1
, v1
);
15720 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15723 tcg_gen_movi_tl(t0
, v2
);
15724 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15727 tcg_gen_movi_tl(t0
, v2
);
15728 tcg_gen_movi_tl(t1
, v1
);
15729 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15731 case OPC_DEXTR_R_L
:
15732 tcg_gen_movi_tl(t0
, v2
);
15733 tcg_gen_movi_tl(t1
, v1
);
15734 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15736 case OPC_DEXTR_RS_L
:
15737 tcg_gen_movi_tl(t0
, v2
);
15738 tcg_gen_movi_tl(t1
, v1
);
15739 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15742 tcg_gen_movi_tl(t0
, v2
);
15743 tcg_gen_movi_tl(t1
, v1
);
15744 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15746 case OPC_DEXTR_R_W
:
15747 tcg_gen_movi_tl(t0
, v2
);
15748 tcg_gen_movi_tl(t1
, v1
);
15749 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15751 case OPC_DEXTR_RS_W
:
15752 tcg_gen_movi_tl(t0
, v2
);
15753 tcg_gen_movi_tl(t1
, v1
);
15754 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15756 case OPC_DEXTR_S_H
:
15757 tcg_gen_movi_tl(t0
, v2
);
15758 tcg_gen_movi_tl(t1
, v1
);
15759 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15761 case OPC_DEXTRV_S_H
:
15762 tcg_gen_movi_tl(t0
, v2
);
15763 tcg_gen_movi_tl(t1
, v1
);
15764 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15767 tcg_gen_movi_tl(t0
, v2
);
15768 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15770 case OPC_DEXTRV_R_L
:
15771 tcg_gen_movi_tl(t0
, v2
);
15772 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15774 case OPC_DEXTRV_RS_L
:
15775 tcg_gen_movi_tl(t0
, v2
);
15776 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15779 tcg_gen_movi_tl(t0
, v2
);
15780 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15782 case OPC_DEXTRV_R_W
:
15783 tcg_gen_movi_tl(t0
, v2
);
15784 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15786 case OPC_DEXTRV_RS_W
:
15787 tcg_gen_movi_tl(t0
, v2
);
15788 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15797 tcg_temp_free(v1_t
);
15798 tcg_temp_free(v2_t
);
15800 (void)opn
; /* avoid a compiler warning */
15801 MIPS_DEBUG("%s", opn
);
15804 /* End MIPSDSP functions. */
15806 /* Compact Branches */
15807 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
15808 int rs
, int rt
, int32_t offset
)
15810 int bcond_compute
= 0;
15811 TCGv t0
= tcg_temp_new();
15812 TCGv t1
= tcg_temp_new();
15814 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15815 #ifdef MIPS_DEBUG_DISAS
15816 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
15819 generate_exception(ctx
, EXCP_RI
);
15823 /* Load needed operands and calculate btarget */
15825 /* compact branch */
15826 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
15827 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
15828 gen_load_gpr(t0
, rs
);
15829 gen_load_gpr(t1
, rt
);
15831 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15832 if (rs
<= rt
&& rs
== 0) {
15833 /* OPC_BEQZALC, OPC_BNEZALC */
15834 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15837 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
15838 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
15839 gen_load_gpr(t0
, rs
);
15840 gen_load_gpr(t1
, rt
);
15842 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15844 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
15845 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
15846 if (rs
== 0 || rs
== rt
) {
15847 /* OPC_BLEZALC, OPC_BGEZALC */
15848 /* OPC_BGTZALC, OPC_BLTZALC */
15849 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15851 gen_load_gpr(t0
, rs
);
15852 gen_load_gpr(t1
, rt
);
15854 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15858 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15863 /* OPC_BEQZC, OPC_BNEZC */
15864 gen_load_gpr(t0
, rs
);
15866 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15868 /* OPC_JIC, OPC_JIALC */
15869 TCGv tbase
= tcg_temp_new();
15870 TCGv toffset
= tcg_temp_new();
15872 gen_load_gpr(tbase
, rt
);
15873 tcg_gen_movi_tl(toffset
, offset
);
15874 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
15875 tcg_temp_free(tbase
);
15876 tcg_temp_free(toffset
);
15880 MIPS_INVAL("Compact branch/jump");
15881 generate_exception(ctx
, EXCP_RI
);
15885 if (bcond_compute
== 0) {
15886 /* Uncoditional compact branch */
15889 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15892 ctx
->hflags
|= MIPS_HFLAG_BR
;
15895 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15898 ctx
->hflags
|= MIPS_HFLAG_B
;
15901 MIPS_INVAL("Compact branch/jump");
15902 generate_exception(ctx
, EXCP_RI
);
15906 /* Generating branch here as compact branches don't have delay slot */
15907 gen_branch(ctx
, 4);
15909 /* Conditional compact branch */
15910 int fs
= gen_new_label();
15911 save_cpu_state(ctx
, 0);
15914 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
15915 if (rs
== 0 && rt
!= 0) {
15917 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
15918 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15920 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
15923 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
15926 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
15927 if (rs
== 0 && rt
!= 0) {
15929 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
15930 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15932 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
15935 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
15938 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
15939 if (rs
== 0 && rt
!= 0) {
15941 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
15942 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15944 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
15947 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
15950 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
15951 if (rs
== 0 && rt
!= 0) {
15953 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
15954 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15956 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
15959 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
15962 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
15963 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
15965 /* OPC_BOVC, OPC_BNVC */
15966 TCGv t2
= tcg_temp_new();
15967 TCGv t3
= tcg_temp_new();
15968 TCGv t4
= tcg_temp_new();
15969 TCGv input_overflow
= tcg_temp_new();
15971 gen_load_gpr(t0
, rs
);
15972 gen_load_gpr(t1
, rt
);
15973 tcg_gen_ext32s_tl(t2
, t0
);
15974 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
15975 tcg_gen_ext32s_tl(t3
, t1
);
15976 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
15977 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
15979 tcg_gen_add_tl(t4
, t2
, t3
);
15980 tcg_gen_ext32s_tl(t4
, t4
);
15981 tcg_gen_xor_tl(t2
, t2
, t3
);
15982 tcg_gen_xor_tl(t3
, t4
, t3
);
15983 tcg_gen_andc_tl(t2
, t3
, t2
);
15984 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
15985 tcg_gen_or_tl(t4
, t4
, input_overflow
);
15986 if (opc
== OPC_BOVC
) {
15988 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
15991 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
15993 tcg_temp_free(input_overflow
);
15997 } else if (rs
< rt
&& rs
== 0) {
15998 /* OPC_BEQZALC, OPC_BNEZALC */
15999 if (opc
== OPC_BEQZALC
) {
16001 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
16004 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
16007 /* OPC_BEQC, OPC_BNEC */
16008 if (opc
== OPC_BEQC
) {
16010 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
16013 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
16018 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
16021 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
16024 MIPS_INVAL("Compact conditional branch/jump");
16025 generate_exception(ctx
, EXCP_RI
);
16029 /* Generating branch here as compact branches don't have delay slot */
16030 gen_goto_tb(ctx
, 1, ctx
->btarget
);
16033 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
16034 MIPS_DEBUG("Compact conditional branch");
16042 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
16044 int rs
, rt
, rd
, sa
;
16047 rs
= (ctx
->opcode
>> 21) & 0x1f;
16048 rt
= (ctx
->opcode
>> 16) & 0x1f;
16049 rd
= (ctx
->opcode
>> 11) & 0x1f;
16050 sa
= (ctx
->opcode
>> 6) & 0x1f;
16052 op1
= MASK_SPECIAL(ctx
->opcode
);
16056 int imm2
= extract32(ctx
->opcode
, 6, 3);
16057 TCGv t0
= tcg_temp_new();
16058 TCGv t1
= tcg_temp_new();
16059 gen_load_gpr(t0
, rs
);
16060 gen_load_gpr(t1
, rt
);
16061 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
16062 tcg_gen_add_tl(t0
, t0
, t1
);
16063 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
16068 case OPC_MULT
... OPC_DIVU
:
16069 op2
= MASK_R6_MULDIV(ctx
->opcode
);
16079 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
16082 MIPS_INVAL("special_r6 muldiv");
16083 generate_exception(ctx
, EXCP_RI
);
16089 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
16093 if (rt
== 0 && sa
== 1) {
16094 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16095 We need additionally to check other fields */
16096 gen_cl(ctx
, op1
, rd
, rs
);
16098 generate_exception(ctx
, EXCP_RI
);
16102 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
16103 generate_exception(ctx
, EXCP_RI
);
16105 generate_exception(ctx
, EXCP_DBp
);
16108 #if defined(TARGET_MIPS64)
16110 check_mips_64(ctx
);
16112 int imm2
= extract32(ctx
->opcode
, 6, 3);
16113 TCGv t0
= tcg_temp_new();
16114 TCGv t1
= tcg_temp_new();
16115 gen_load_gpr(t0
, rs
);
16116 gen_load_gpr(t1
, rt
);
16117 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
16118 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
16125 if (rt
== 0 && sa
== 1) {
16126 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16127 We need additionally to check other fields */
16128 check_mips_64(ctx
);
16129 gen_cl(ctx
, op1
, rd
, rs
);
16131 generate_exception(ctx
, EXCP_RI
);
16134 case OPC_DMULT
... OPC_DDIVU
:
16135 op2
= MASK_R6_MULDIV(ctx
->opcode
);
16145 check_mips_64(ctx
);
16146 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
16149 MIPS_INVAL("special_r6 muldiv");
16150 generate_exception(ctx
, EXCP_RI
);
16155 default: /* Invalid */
16156 MIPS_INVAL("special_r6");
16157 generate_exception(ctx
, EXCP_RI
);
16162 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16164 int rs
, rt
, rd
, sa
;
16167 rs
= (ctx
->opcode
>> 21) & 0x1f;
16168 rt
= (ctx
->opcode
>> 16) & 0x1f;
16169 rd
= (ctx
->opcode
>> 11) & 0x1f;
16170 sa
= (ctx
->opcode
>> 6) & 0x1f;
16172 op1
= MASK_SPECIAL(ctx
->opcode
);
16174 case OPC_MOVN
: /* Conditional move */
16176 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
16177 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
16178 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
16180 case OPC_MFHI
: /* Move from HI/LO */
16182 gen_HILO(ctx
, op1
, rs
& 3, rd
);
16185 case OPC_MTLO
: /* Move to HI/LO */
16186 gen_HILO(ctx
, op1
, rd
& 3, rs
);
16189 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
16190 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16191 check_cp1_enabled(ctx
);
16192 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
16193 (ctx
->opcode
>> 16) & 1);
16195 generate_exception_err(ctx
, EXCP_CpU
, 1);
16201 check_insn(ctx
, INSN_VR54XX
);
16202 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
16203 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
16205 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
16210 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
16212 #if defined(TARGET_MIPS64)
16213 case OPC_DMULT
... OPC_DDIVU
:
16214 check_insn(ctx
, ISA_MIPS3
);
16215 check_mips_64(ctx
);
16216 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
16220 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
16223 #ifdef MIPS_STRICT_STANDARD
16224 MIPS_INVAL("SPIM");
16225 generate_exception(ctx
, EXCP_RI
);
16227 /* Implemented as RI exception for now. */
16228 MIPS_INVAL("spim (unofficial)");
16229 generate_exception(ctx
, EXCP_RI
);
16232 default: /* Invalid */
16233 MIPS_INVAL("special_legacy");
16234 generate_exception(ctx
, EXCP_RI
);
16239 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
16241 int rs
, rt
, rd
, sa
;
16244 rs
= (ctx
->opcode
>> 21) & 0x1f;
16245 rt
= (ctx
->opcode
>> 16) & 0x1f;
16246 rd
= (ctx
->opcode
>> 11) & 0x1f;
16247 sa
= (ctx
->opcode
>> 6) & 0x1f;
16249 op1
= MASK_SPECIAL(ctx
->opcode
);
16251 case OPC_SLL
: /* Shift with immediate */
16252 if (sa
== 5 && rd
== 0 &&
16253 rs
== 0 && rt
== 0) { /* PAUSE */
16254 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
16255 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
16256 MIPS_DEBUG("CTI in delay / forbidden slot");
16257 generate_exception(ctx
, EXCP_RI
);
16263 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16266 switch ((ctx
->opcode
>> 21) & 0x1f) {
16268 /* rotr is decoded as srl on non-R2 CPUs */
16269 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16274 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16277 generate_exception(ctx
, EXCP_RI
);
16281 case OPC_ADD
... OPC_SUBU
:
16282 gen_arith(ctx
, op1
, rd
, rs
, rt
);
16284 case OPC_SLLV
: /* Shifts */
16286 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16289 switch ((ctx
->opcode
>> 6) & 0x1f) {
16291 /* rotrv is decoded as srlv on non-R2 CPUs */
16292 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16297 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16300 generate_exception(ctx
, EXCP_RI
);
16304 case OPC_SLT
: /* Set on less than */
16306 gen_slt(ctx
, op1
, rd
, rs
, rt
);
16308 case OPC_AND
: /* Logic*/
16312 gen_logic(ctx
, op1
, rd
, rs
, rt
);
16315 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
16317 case OPC_TGE
... OPC_TEQ
: /* Traps */
16319 gen_trap(ctx
, op1
, rs
, rt
, -1);
16321 case OPC_LSA
: /* OPC_PMON */
16322 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16323 decode_opc_special_r6(env
, ctx
);
16325 /* Pmon entry point, also R4010 selsl */
16326 #ifdef MIPS_STRICT_STANDARD
16327 MIPS_INVAL("PMON / selsl");
16328 generate_exception(ctx
, EXCP_RI
);
16330 gen_helper_0e0i(pmon
, sa
);
16335 generate_exception(ctx
, EXCP_SYSCALL
);
16336 ctx
->bstate
= BS_STOP
;
16339 generate_exception(ctx
, EXCP_BREAK
);
16342 /* Treat as NOP. */
16345 #if defined(TARGET_MIPS64)
16346 /* MIPS64 specific opcodes */
16351 check_insn(ctx
, ISA_MIPS3
);
16352 check_mips_64(ctx
);
16353 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16356 switch ((ctx
->opcode
>> 21) & 0x1f) {
16358 /* drotr is decoded as dsrl on non-R2 CPUs */
16359 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16364 check_insn(ctx
, ISA_MIPS3
);
16365 check_mips_64(ctx
);
16366 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16369 generate_exception(ctx
, EXCP_RI
);
16374 switch ((ctx
->opcode
>> 21) & 0x1f) {
16376 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16377 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16382 check_insn(ctx
, ISA_MIPS3
);
16383 check_mips_64(ctx
);
16384 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16387 generate_exception(ctx
, EXCP_RI
);
16391 case OPC_DADD
... OPC_DSUBU
:
16392 check_insn(ctx
, ISA_MIPS3
);
16393 check_mips_64(ctx
);
16394 gen_arith(ctx
, op1
, rd
, rs
, rt
);
16398 check_insn(ctx
, ISA_MIPS3
);
16399 check_mips_64(ctx
);
16400 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16403 switch ((ctx
->opcode
>> 6) & 0x1f) {
16405 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16406 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16411 check_insn(ctx
, ISA_MIPS3
);
16412 check_mips_64(ctx
);
16413 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16416 generate_exception(ctx
, EXCP_RI
);
16422 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16423 decode_opc_special_r6(env
, ctx
);
16425 decode_opc_special_legacy(env
, ctx
);
16430 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16435 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16437 rs
= (ctx
->opcode
>> 21) & 0x1f;
16438 rt
= (ctx
->opcode
>> 16) & 0x1f;
16439 rd
= (ctx
->opcode
>> 11) & 0x1f;
16441 op1
= MASK_SPECIAL2(ctx
->opcode
);
16443 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
16444 case OPC_MSUB
... OPC_MSUBU
:
16445 check_insn(ctx
, ISA_MIPS32
);
16446 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
16449 gen_arith(ctx
, op1
, rd
, rs
, rt
);
16452 case OPC_DIVU_G_2F
:
16453 case OPC_MULT_G_2F
:
16454 case OPC_MULTU_G_2F
:
16456 case OPC_MODU_G_2F
:
16457 check_insn(ctx
, INSN_LOONGSON2F
);
16458 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16462 check_insn(ctx
, ISA_MIPS32
);
16463 gen_cl(ctx
, op1
, rd
, rs
);
16466 /* XXX: not clear which exception should be raised
16467 * when in debug mode...
16469 check_insn(ctx
, ISA_MIPS32
);
16470 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
16471 generate_exception(ctx
, EXCP_DBp
);
16473 generate_exception(ctx
, EXCP_DBp
);
16475 /* Treat as NOP. */
16477 #if defined(TARGET_MIPS64)
16480 check_insn(ctx
, ISA_MIPS64
);
16481 check_mips_64(ctx
);
16482 gen_cl(ctx
, op1
, rd
, rs
);
16484 case OPC_DMULT_G_2F
:
16485 case OPC_DMULTU_G_2F
:
16486 case OPC_DDIV_G_2F
:
16487 case OPC_DDIVU_G_2F
:
16488 case OPC_DMOD_G_2F
:
16489 case OPC_DMODU_G_2F
:
16490 check_insn(ctx
, INSN_LOONGSON2F
);
16491 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16494 default: /* Invalid */
16495 MIPS_INVAL("special2_legacy");
16496 generate_exception(ctx
, EXCP_RI
);
16501 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
16503 int rs
, rt
, rd
, sa
;
16507 rs
= (ctx
->opcode
>> 21) & 0x1f;
16508 rt
= (ctx
->opcode
>> 16) & 0x1f;
16509 rd
= (ctx
->opcode
>> 11) & 0x1f;
16510 sa
= (ctx
->opcode
>> 6) & 0x1f;
16511 imm
= (int16_t)ctx
->opcode
>> 7;
16513 op1
= MASK_SPECIAL3(ctx
->opcode
);
16517 /* hint codes 24-31 are reserved and signal RI */
16518 generate_exception(ctx
, EXCP_RI
);
16520 /* Treat as NOP. */
16523 /* Treat as NOP. */
16526 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
16529 gen_ld(ctx
, op1
, rt
, rs
, imm
);
16534 /* Treat as NOP. */
16537 TCGv t0
= tcg_temp_new();
16538 gen_load_gpr(t0
, rt
);
16540 op2
= MASK_BSHFL(ctx
->opcode
);
16542 case OPC_ALIGN
... OPC_ALIGN_END
:
16545 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
16547 TCGv t1
= tcg_temp_new();
16548 TCGv_i64 t2
= tcg_temp_new_i64();
16549 gen_load_gpr(t1
, rs
);
16550 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
16551 tcg_gen_shri_i64(t2
, t2
, 8 * (4 - sa
));
16552 #if defined(TARGET_MIPS64)
16553 tcg_gen_ext32s_i64(cpu_gpr
[rd
], t2
);
16555 tcg_gen_trunc_i64_i32(cpu_gpr
[rd
], t2
);
16557 tcg_temp_free_i64(t2
);
16562 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
16568 #if defined(TARGET_MIPS64)
16570 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
16573 gen_ld(ctx
, op1
, rt
, rs
, imm
);
16576 check_mips_64(ctx
);
16579 /* Treat as NOP. */
16582 TCGv t0
= tcg_temp_new();
16583 gen_load_gpr(t0
, rt
);
16585 op2
= MASK_DBSHFL(ctx
->opcode
);
16587 case OPC_DALIGN
... OPC_DALIGN_END
:
16590 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
16592 TCGv t1
= tcg_temp_new();
16593 gen_load_gpr(t1
, rs
);
16594 tcg_gen_shli_tl(t0
, t0
, 8 * sa
);
16595 tcg_gen_shri_tl(t1
, t1
, 8 * (8 - sa
));
16596 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
16601 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
16608 default: /* Invalid */
16609 MIPS_INVAL("special3_r6");
16610 generate_exception(ctx
, EXCP_RI
);
16615 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16620 rs
= (ctx
->opcode
>> 21) & 0x1f;
16621 rt
= (ctx
->opcode
>> 16) & 0x1f;
16622 rd
= (ctx
->opcode
>> 11) & 0x1f;
16624 op1
= MASK_SPECIAL3(ctx
->opcode
);
16626 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
16627 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
16628 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
16629 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16630 * the same mask and op1. */
16631 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
16632 op2
= MASK_ADDUH_QB(ctx
->opcode
);
16635 case OPC_ADDUH_R_QB
:
16637 case OPC_ADDQH_R_PH
:
16639 case OPC_ADDQH_R_W
:
16641 case OPC_SUBUH_R_QB
:
16643 case OPC_SUBQH_R_PH
:
16645 case OPC_SUBQH_R_W
:
16646 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16651 case OPC_MULQ_RS_W
:
16652 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16655 MIPS_INVAL("MASK ADDUH.QB");
16656 generate_exception(ctx
, EXCP_RI
);
16659 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
16660 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16662 generate_exception(ctx
, EXCP_RI
);
16666 op2
= MASK_LX(ctx
->opcode
);
16668 #if defined(TARGET_MIPS64)
16674 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
16676 default: /* Invalid */
16677 MIPS_INVAL("MASK LX");
16678 generate_exception(ctx
, EXCP_RI
);
16682 case OPC_ABSQ_S_PH_DSP
:
16683 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
16685 case OPC_ABSQ_S_QB
:
16686 case OPC_ABSQ_S_PH
:
16688 case OPC_PRECEQ_W_PHL
:
16689 case OPC_PRECEQ_W_PHR
:
16690 case OPC_PRECEQU_PH_QBL
:
16691 case OPC_PRECEQU_PH_QBR
:
16692 case OPC_PRECEQU_PH_QBLA
:
16693 case OPC_PRECEQU_PH_QBRA
:
16694 case OPC_PRECEU_PH_QBL
:
16695 case OPC_PRECEU_PH_QBR
:
16696 case OPC_PRECEU_PH_QBLA
:
16697 case OPC_PRECEU_PH_QBRA
:
16698 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16705 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
16708 MIPS_INVAL("MASK ABSQ_S.PH");
16709 generate_exception(ctx
, EXCP_RI
);
16713 case OPC_ADDU_QB_DSP
:
16714 op2
= MASK_ADDU_QB(ctx
->opcode
);
16717 case OPC_ADDQ_S_PH
:
16720 case OPC_ADDU_S_QB
:
16722 case OPC_ADDU_S_PH
:
16724 case OPC_SUBQ_S_PH
:
16727 case OPC_SUBU_S_QB
:
16729 case OPC_SUBU_S_PH
:
16733 case OPC_RADDU_W_QB
:
16734 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16736 case OPC_MULEU_S_PH_QBL
:
16737 case OPC_MULEU_S_PH_QBR
:
16738 case OPC_MULQ_RS_PH
:
16739 case OPC_MULEQ_S_W_PHL
:
16740 case OPC_MULEQ_S_W_PHR
:
16741 case OPC_MULQ_S_PH
:
16742 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16744 default: /* Invalid */
16745 MIPS_INVAL("MASK ADDU.QB");
16746 generate_exception(ctx
, EXCP_RI
);
16751 case OPC_CMPU_EQ_QB_DSP
:
16752 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
16754 case OPC_PRECR_SRA_PH_W
:
16755 case OPC_PRECR_SRA_R_PH_W
:
16756 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
16758 case OPC_PRECR_QB_PH
:
16759 case OPC_PRECRQ_QB_PH
:
16760 case OPC_PRECRQ_PH_W
:
16761 case OPC_PRECRQ_RS_PH_W
:
16762 case OPC_PRECRQU_S_QB_PH
:
16763 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16765 case OPC_CMPU_EQ_QB
:
16766 case OPC_CMPU_LT_QB
:
16767 case OPC_CMPU_LE_QB
:
16768 case OPC_CMP_EQ_PH
:
16769 case OPC_CMP_LT_PH
:
16770 case OPC_CMP_LE_PH
:
16771 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16773 case OPC_CMPGU_EQ_QB
:
16774 case OPC_CMPGU_LT_QB
:
16775 case OPC_CMPGU_LE_QB
:
16776 case OPC_CMPGDU_EQ_QB
:
16777 case OPC_CMPGDU_LT_QB
:
16778 case OPC_CMPGDU_LE_QB
:
16781 case OPC_PACKRL_PH
:
16782 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16784 default: /* Invalid */
16785 MIPS_INVAL("MASK CMPU.EQ.QB");
16786 generate_exception(ctx
, EXCP_RI
);
16790 case OPC_SHLL_QB_DSP
:
16791 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
16793 case OPC_DPA_W_PH_DSP
:
16794 op2
= MASK_DPA_W_PH(ctx
->opcode
);
16796 case OPC_DPAU_H_QBL
:
16797 case OPC_DPAU_H_QBR
:
16798 case OPC_DPSU_H_QBL
:
16799 case OPC_DPSU_H_QBR
:
16801 case OPC_DPAX_W_PH
:
16802 case OPC_DPAQ_S_W_PH
:
16803 case OPC_DPAQX_S_W_PH
:
16804 case OPC_DPAQX_SA_W_PH
:
16806 case OPC_DPSX_W_PH
:
16807 case OPC_DPSQ_S_W_PH
:
16808 case OPC_DPSQX_S_W_PH
:
16809 case OPC_DPSQX_SA_W_PH
:
16810 case OPC_MULSAQ_S_W_PH
:
16811 case OPC_DPAQ_SA_L_W
:
16812 case OPC_DPSQ_SA_L_W
:
16813 case OPC_MAQ_S_W_PHL
:
16814 case OPC_MAQ_S_W_PHR
:
16815 case OPC_MAQ_SA_W_PHL
:
16816 case OPC_MAQ_SA_W_PHR
:
16817 case OPC_MULSA_W_PH
:
16818 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16820 default: /* Invalid */
16821 MIPS_INVAL("MASK DPAW.PH");
16822 generate_exception(ctx
, EXCP_RI
);
16827 op2
= MASK_INSV(ctx
->opcode
);
16839 t0
= tcg_temp_new();
16840 t1
= tcg_temp_new();
16842 gen_load_gpr(t0
, rt
);
16843 gen_load_gpr(t1
, rs
);
16845 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
16851 default: /* Invalid */
16852 MIPS_INVAL("MASK INSV");
16853 generate_exception(ctx
, EXCP_RI
);
16857 case OPC_APPEND_DSP
:
16858 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
16860 case OPC_EXTR_W_DSP
:
16861 op2
= MASK_EXTR_W(ctx
->opcode
);
16865 case OPC_EXTR_RS_W
:
16867 case OPC_EXTRV_S_H
:
16869 case OPC_EXTRV_R_W
:
16870 case OPC_EXTRV_RS_W
:
16875 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
16878 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16884 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16886 default: /* Invalid */
16887 MIPS_INVAL("MASK EXTR.W");
16888 generate_exception(ctx
, EXCP_RI
);
16892 #if defined(TARGET_MIPS64)
16893 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
16894 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
16895 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
16896 check_insn(ctx
, INSN_LOONGSON2E
);
16897 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16899 case OPC_ABSQ_S_QH_DSP
:
16900 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
16902 case OPC_PRECEQ_L_PWL
:
16903 case OPC_PRECEQ_L_PWR
:
16904 case OPC_PRECEQ_PW_QHL
:
16905 case OPC_PRECEQ_PW_QHR
:
16906 case OPC_PRECEQ_PW_QHLA
:
16907 case OPC_PRECEQ_PW_QHRA
:
16908 case OPC_PRECEQU_QH_OBL
:
16909 case OPC_PRECEQU_QH_OBR
:
16910 case OPC_PRECEQU_QH_OBLA
:
16911 case OPC_PRECEQU_QH_OBRA
:
16912 case OPC_PRECEU_QH_OBL
:
16913 case OPC_PRECEU_QH_OBR
:
16914 case OPC_PRECEU_QH_OBLA
:
16915 case OPC_PRECEU_QH_OBRA
:
16916 case OPC_ABSQ_S_OB
:
16917 case OPC_ABSQ_S_PW
:
16918 case OPC_ABSQ_S_QH
:
16919 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16927 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
16929 default: /* Invalid */
16930 MIPS_INVAL("MASK ABSQ_S.QH");
16931 generate_exception(ctx
, EXCP_RI
);
16935 case OPC_ADDU_OB_DSP
:
16936 op2
= MASK_ADDU_OB(ctx
->opcode
);
16938 case OPC_RADDU_L_OB
:
16940 case OPC_SUBQ_S_PW
:
16942 case OPC_SUBQ_S_QH
:
16944 case OPC_SUBU_S_OB
:
16946 case OPC_SUBU_S_QH
:
16948 case OPC_SUBUH_R_OB
:
16950 case OPC_ADDQ_S_PW
:
16952 case OPC_ADDQ_S_QH
:
16954 case OPC_ADDU_S_OB
:
16956 case OPC_ADDU_S_QH
:
16958 case OPC_ADDUH_R_OB
:
16959 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16961 case OPC_MULEQ_S_PW_QHL
:
16962 case OPC_MULEQ_S_PW_QHR
:
16963 case OPC_MULEU_S_QH_OBL
:
16964 case OPC_MULEU_S_QH_OBR
:
16965 case OPC_MULQ_RS_QH
:
16966 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16968 default: /* Invalid */
16969 MIPS_INVAL("MASK ADDU.OB");
16970 generate_exception(ctx
, EXCP_RI
);
16974 case OPC_CMPU_EQ_OB_DSP
:
16975 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
16977 case OPC_PRECR_SRA_QH_PW
:
16978 case OPC_PRECR_SRA_R_QH_PW
:
16979 /* Return value is rt. */
16980 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
16982 case OPC_PRECR_OB_QH
:
16983 case OPC_PRECRQ_OB_QH
:
16984 case OPC_PRECRQ_PW_L
:
16985 case OPC_PRECRQ_QH_PW
:
16986 case OPC_PRECRQ_RS_QH_PW
:
16987 case OPC_PRECRQU_S_OB_QH
:
16988 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16990 case OPC_CMPU_EQ_OB
:
16991 case OPC_CMPU_LT_OB
:
16992 case OPC_CMPU_LE_OB
:
16993 case OPC_CMP_EQ_QH
:
16994 case OPC_CMP_LT_QH
:
16995 case OPC_CMP_LE_QH
:
16996 case OPC_CMP_EQ_PW
:
16997 case OPC_CMP_LT_PW
:
16998 case OPC_CMP_LE_PW
:
16999 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17001 case OPC_CMPGDU_EQ_OB
:
17002 case OPC_CMPGDU_LT_OB
:
17003 case OPC_CMPGDU_LE_OB
:
17004 case OPC_CMPGU_EQ_OB
:
17005 case OPC_CMPGU_LT_OB
:
17006 case OPC_CMPGU_LE_OB
:
17007 case OPC_PACKRL_PW
:
17011 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17013 default: /* Invalid */
17014 MIPS_INVAL("MASK CMPU_EQ.OB");
17015 generate_exception(ctx
, EXCP_RI
);
17019 case OPC_DAPPEND_DSP
:
17020 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
17022 case OPC_DEXTR_W_DSP
:
17023 op2
= MASK_DEXTR_W(ctx
->opcode
);
17030 case OPC_DEXTR_R_L
:
17031 case OPC_DEXTR_RS_L
:
17033 case OPC_DEXTR_R_W
:
17034 case OPC_DEXTR_RS_W
:
17035 case OPC_DEXTR_S_H
:
17037 case OPC_DEXTRV_R_L
:
17038 case OPC_DEXTRV_RS_L
:
17039 case OPC_DEXTRV_S_H
:
17041 case OPC_DEXTRV_R_W
:
17042 case OPC_DEXTRV_RS_W
:
17043 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
17048 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17050 default: /* Invalid */
17051 MIPS_INVAL("MASK EXTR.W");
17052 generate_exception(ctx
, EXCP_RI
);
17056 case OPC_DPAQ_W_QH_DSP
:
17057 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
17059 case OPC_DPAU_H_OBL
:
17060 case OPC_DPAU_H_OBR
:
17061 case OPC_DPSU_H_OBL
:
17062 case OPC_DPSU_H_OBR
:
17064 case OPC_DPAQ_S_W_QH
:
17066 case OPC_DPSQ_S_W_QH
:
17067 case OPC_MULSAQ_S_W_QH
:
17068 case OPC_DPAQ_SA_L_PW
:
17069 case OPC_DPSQ_SA_L_PW
:
17070 case OPC_MULSAQ_S_L_PW
:
17071 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17073 case OPC_MAQ_S_W_QHLL
:
17074 case OPC_MAQ_S_W_QHLR
:
17075 case OPC_MAQ_S_W_QHRL
:
17076 case OPC_MAQ_S_W_QHRR
:
17077 case OPC_MAQ_SA_W_QHLL
:
17078 case OPC_MAQ_SA_W_QHLR
:
17079 case OPC_MAQ_SA_W_QHRL
:
17080 case OPC_MAQ_SA_W_QHRR
:
17081 case OPC_MAQ_S_L_PWL
:
17082 case OPC_MAQ_S_L_PWR
:
17087 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17089 default: /* Invalid */
17090 MIPS_INVAL("MASK DPAQ.W.QH");
17091 generate_exception(ctx
, EXCP_RI
);
17095 case OPC_DINSV_DSP
:
17096 op2
= MASK_INSV(ctx
->opcode
);
17108 t0
= tcg_temp_new();
17109 t1
= tcg_temp_new();
17111 gen_load_gpr(t0
, rt
);
17112 gen_load_gpr(t1
, rs
);
17114 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
17120 default: /* Invalid */
17121 MIPS_INVAL("MASK DINSV");
17122 generate_exception(ctx
, EXCP_RI
);
17126 case OPC_SHLL_OB_DSP
:
17127 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
17130 default: /* Invalid */
17131 MIPS_INVAL("special3_legacy");
17132 generate_exception(ctx
, EXCP_RI
);
17137 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
17139 int rs
, rt
, rd
, sa
;
17142 rs
= (ctx
->opcode
>> 21) & 0x1f;
17143 rt
= (ctx
->opcode
>> 16) & 0x1f;
17144 rd
= (ctx
->opcode
>> 11) & 0x1f;
17145 sa
= (ctx
->opcode
>> 6) & 0x1f;
17147 op1
= MASK_SPECIAL3(ctx
->opcode
);
17151 check_insn(ctx
, ISA_MIPS32R2
);
17152 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
17155 op2
= MASK_BSHFL(ctx
->opcode
);
17157 case OPC_ALIGN
... OPC_ALIGN_END
:
17159 check_insn(ctx
, ISA_MIPS32R6
);
17160 decode_opc_special3_r6(env
, ctx
);
17163 check_insn(ctx
, ISA_MIPS32R2
);
17164 gen_bshfl(ctx
, op2
, rt
, rd
);
17168 #if defined(TARGET_MIPS64)
17169 case OPC_DEXTM
... OPC_DEXT
:
17170 case OPC_DINSM
... OPC_DINS
:
17171 check_insn(ctx
, ISA_MIPS64R2
);
17172 check_mips_64(ctx
);
17173 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
17176 op2
= MASK_DBSHFL(ctx
->opcode
);
17178 case OPC_DALIGN
... OPC_DALIGN_END
:
17180 check_insn(ctx
, ISA_MIPS32R6
);
17181 decode_opc_special3_r6(env
, ctx
);
17184 check_insn(ctx
, ISA_MIPS64R2
);
17185 check_mips_64(ctx
);
17186 op2
= MASK_DBSHFL(ctx
->opcode
);
17187 gen_bshfl(ctx
, op2
, rt
, rd
);
17193 gen_rdhwr(ctx
, rt
, rd
);
17196 check_insn(ctx
, ASE_MT
);
17198 TCGv t0
= tcg_temp_new();
17199 TCGv t1
= tcg_temp_new();
17201 gen_load_gpr(t0
, rt
);
17202 gen_load_gpr(t1
, rs
);
17203 gen_helper_fork(t0
, t1
);
17209 check_insn(ctx
, ASE_MT
);
17211 TCGv t0
= tcg_temp_new();
17213 save_cpu_state(ctx
, 1);
17214 gen_load_gpr(t0
, rs
);
17215 gen_helper_yield(t0
, cpu_env
, t0
);
17216 gen_store_gpr(t0
, rd
);
17221 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17222 decode_opc_special3_r6(env
, ctx
);
17224 decode_opc_special3_legacy(env
, ctx
);
17229 /* MIPS SIMD Architecture (MSA) */
17230 static inline int check_msa_access(DisasContext
*ctx
)
17232 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
17233 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
17234 generate_exception(ctx
, EXCP_RI
);
17238 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
17239 if (ctx
->insn_flags
& ASE_MSA
) {
17240 generate_exception(ctx
, EXCP_MSADIS
);
17243 generate_exception(ctx
, EXCP_RI
);
17250 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
17252 /* generates tcg ops to check if any element is 0 */
17253 /* Note this function only works with MSA_WRLEN = 128 */
17254 uint64_t eval_zero_or_big
= 0;
17255 uint64_t eval_big
= 0;
17256 TCGv_i64 t0
= tcg_temp_new_i64();
17257 TCGv_i64 t1
= tcg_temp_new_i64();
17260 eval_zero_or_big
= 0x0101010101010101ULL
;
17261 eval_big
= 0x8080808080808080ULL
;
17264 eval_zero_or_big
= 0x0001000100010001ULL
;
17265 eval_big
= 0x8000800080008000ULL
;
17268 eval_zero_or_big
= 0x0000000100000001ULL
;
17269 eval_big
= 0x8000000080000000ULL
;
17272 eval_zero_or_big
= 0x0000000000000001ULL
;
17273 eval_big
= 0x8000000000000000ULL
;
17276 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<<1], eval_zero_or_big
);
17277 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<<1]);
17278 tcg_gen_andi_i64(t0
, t0
, eval_big
);
17279 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<<1)+1], eval_zero_or_big
);
17280 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<<1)+1]);
17281 tcg_gen_andi_i64(t1
, t1
, eval_big
);
17282 tcg_gen_or_i64(t0
, t0
, t1
);
17283 /* if all bits are zero then all elements are not zero */
17284 /* if some bit is non-zero then some element is zero */
17285 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
17286 tcg_gen_trunc_i64_tl(tresult
, t0
);
17287 tcg_temp_free_i64(t0
);
17288 tcg_temp_free_i64(t1
);
17291 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
17293 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
17294 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
17295 int64_t s16
= (int16_t)ctx
->opcode
;
17297 check_msa_access(ctx
);
17299 if (ctx
->insn_flags
& ISA_MIPS32R6
&& ctx
->hflags
& MIPS_HFLAG_BMASK
) {
17300 MIPS_DEBUG("CTI in delay / forbidden slot");
17301 generate_exception(ctx
, EXCP_RI
);
17308 TCGv_i64 t0
= tcg_temp_new_i64();
17309 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<<1], msa_wr_d
[(wt
<<1)+1]);
17310 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
17311 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
17312 tcg_gen_trunc_i64_tl(bcond
, t0
);
17313 tcg_temp_free_i64(t0
);
17320 gen_check_zero_element(bcond
, df
, wt
);
17326 gen_check_zero_element(bcond
, df
, wt
);
17327 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
17331 ctx
->btarget
= ctx
->pc
+ (s16
<< 2) + 4;
17333 ctx
->hflags
|= MIPS_HFLAG_BC
;
17334 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
17337 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
17339 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
17340 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
17341 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
17342 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
17344 TCGv_i32 twd
= tcg_const_i32(wd
);
17345 TCGv_i32 tws
= tcg_const_i32(ws
);
17346 TCGv_i32 ti8
= tcg_const_i32(i8
);
17348 switch (MASK_MSA_I8(ctx
->opcode
)) {
17350 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
17353 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
17356 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
17359 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
17362 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
17365 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
17368 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
17374 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
17375 if (df
== DF_DOUBLE
) {
17376 generate_exception(ctx
, EXCP_RI
);
17378 TCGv_i32 tdf
= tcg_const_i32(df
);
17379 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
17380 tcg_temp_free_i32(tdf
);
17385 MIPS_INVAL("MSA instruction");
17386 generate_exception(ctx
, EXCP_RI
);
17390 tcg_temp_free_i32(twd
);
17391 tcg_temp_free_i32(tws
);
17392 tcg_temp_free_i32(ti8
);
17395 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
17397 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17398 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
17399 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
17400 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
17401 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
17402 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
17404 TCGv_i32 tdf
= tcg_const_i32(df
);
17405 TCGv_i32 twd
= tcg_const_i32(wd
);
17406 TCGv_i32 tws
= tcg_const_i32(ws
);
17407 TCGv_i32 timm
= tcg_temp_new_i32();
17408 tcg_gen_movi_i32(timm
, u5
);
17410 switch (MASK_MSA_I5(ctx
->opcode
)) {
17412 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
17415 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
17417 case OPC_MAXI_S_df
:
17418 tcg_gen_movi_i32(timm
, s5
);
17419 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
17421 case OPC_MAXI_U_df
:
17422 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
17424 case OPC_MINI_S_df
:
17425 tcg_gen_movi_i32(timm
, s5
);
17426 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
17428 case OPC_MINI_U_df
:
17429 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
17432 tcg_gen_movi_i32(timm
, s5
);
17433 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
17435 case OPC_CLTI_S_df
:
17436 tcg_gen_movi_i32(timm
, s5
);
17437 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
17439 case OPC_CLTI_U_df
:
17440 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
17442 case OPC_CLEI_S_df
:
17443 tcg_gen_movi_i32(timm
, s5
);
17444 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
17446 case OPC_CLEI_U_df
:
17447 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
17451 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
17452 tcg_gen_movi_i32(timm
, s10
);
17453 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
17457 MIPS_INVAL("MSA instruction");
17458 generate_exception(ctx
, EXCP_RI
);
17462 tcg_temp_free_i32(tdf
);
17463 tcg_temp_free_i32(twd
);
17464 tcg_temp_free_i32(tws
);
17465 tcg_temp_free_i32(timm
);
17468 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
17470 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
17471 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
17472 uint32_t df
= 0, m
= 0;
17473 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
17474 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
17481 if ((dfm
& 0x40) == 0x00) {
17484 } else if ((dfm
& 0x60) == 0x40) {
17487 } else if ((dfm
& 0x70) == 0x60) {
17490 } else if ((dfm
& 0x78) == 0x70) {
17494 generate_exception(ctx
, EXCP_RI
);
17498 tdf
= tcg_const_i32(df
);
17499 tm
= tcg_const_i32(m
);
17500 twd
= tcg_const_i32(wd
);
17501 tws
= tcg_const_i32(ws
);
17503 switch (MASK_MSA_BIT(ctx
->opcode
)) {
17505 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
17508 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
17511 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
17514 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
17517 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
17520 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
17522 case OPC_BINSLI_df
:
17523 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
17525 case OPC_BINSRI_df
:
17526 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
17529 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
17532 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
17535 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
17538 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
17541 MIPS_INVAL("MSA instruction");
17542 generate_exception(ctx
, EXCP_RI
);
17546 tcg_temp_free_i32(tdf
);
17547 tcg_temp_free_i32(tm
);
17548 tcg_temp_free_i32(twd
);
17549 tcg_temp_free_i32(tws
);
17552 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
17554 uint32_t opcode
= ctx
->opcode
;
17555 check_insn(ctx
, ASE_MSA
);
17556 check_msa_access(ctx
);
17558 switch (MASK_MSA_MINOR(opcode
)) {
17559 case OPC_MSA_I8_00
:
17560 case OPC_MSA_I8_01
:
17561 case OPC_MSA_I8_02
:
17562 gen_msa_i8(env
, ctx
);
17564 case OPC_MSA_I5_06
:
17565 case OPC_MSA_I5_07
:
17566 gen_msa_i5(env
, ctx
);
17568 case OPC_MSA_BIT_09
:
17569 case OPC_MSA_BIT_0A
:
17570 gen_msa_bit(env
, ctx
);
17573 MIPS_INVAL("MSA instruction");
17574 generate_exception(ctx
, EXCP_RI
);
17580 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
17583 int rs
, rt
, rd
, sa
;
17587 /* make sure instructions are on a word boundary */
17588 if (ctx
->pc
& 0x3) {
17589 env
->CP0_BadVAddr
= ctx
->pc
;
17590 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
17594 /* Handle blikely not taken case */
17595 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
17596 int l1
= gen_new_label();
17598 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
17599 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
17600 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
17601 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
17605 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
17606 tcg_gen_debug_insn_start(ctx
->pc
);
17609 op
= MASK_OP_MAJOR(ctx
->opcode
);
17610 rs
= (ctx
->opcode
>> 21) & 0x1f;
17611 rt
= (ctx
->opcode
>> 16) & 0x1f;
17612 rd
= (ctx
->opcode
>> 11) & 0x1f;
17613 sa
= (ctx
->opcode
>> 6) & 0x1f;
17614 imm
= (int16_t)ctx
->opcode
;
17617 decode_opc_special(env
, ctx
);
17620 decode_opc_special2_legacy(env
, ctx
);
17623 decode_opc_special3(env
, ctx
);
17626 op1
= MASK_REGIMM(ctx
->opcode
);
17628 case OPC_BLTZL
: /* REGIMM branches */
17632 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17635 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
17639 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17641 /* OPC_NAL, OPC_BAL */
17642 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
17644 generate_exception(ctx
, EXCP_RI
);
17647 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
17650 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
17652 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17653 gen_trap(ctx
, op1
, rs
, -1, imm
);
17656 check_insn(ctx
, ISA_MIPS32R2
);
17657 /* Break the TB to be able to sync copied instructions
17659 ctx
->bstate
= BS_STOP
;
17661 case OPC_BPOSGE32
: /* MIPS DSP branch */
17662 #if defined(TARGET_MIPS64)
17666 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
17668 #if defined(TARGET_MIPS64)
17670 check_insn(ctx
, ISA_MIPS32R6
);
17671 check_mips_64(ctx
);
17673 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
17675 MIPS_DEBUG("dahi %s, %04x", regnames
[rs
], imm
);
17678 check_insn(ctx
, ISA_MIPS32R6
);
17679 check_mips_64(ctx
);
17681 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
17683 MIPS_DEBUG("dati %s, %04x", regnames
[rs
], imm
);
17686 default: /* Invalid */
17687 MIPS_INVAL("regimm");
17688 generate_exception(ctx
, EXCP_RI
);
17693 check_cp0_enabled(ctx
);
17694 op1
= MASK_CP0(ctx
->opcode
);
17700 #if defined(TARGET_MIPS64)
17704 #ifndef CONFIG_USER_ONLY
17705 gen_cp0(env
, ctx
, op1
, rt
, rd
);
17706 #endif /* !CONFIG_USER_ONLY */
17708 case OPC_C0_FIRST
... OPC_C0_LAST
:
17709 #ifndef CONFIG_USER_ONLY
17710 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
17711 #endif /* !CONFIG_USER_ONLY */
17714 #ifndef CONFIG_USER_ONLY
17717 TCGv t0
= tcg_temp_new();
17719 op2
= MASK_MFMC0(ctx
->opcode
);
17722 check_insn(ctx
, ASE_MT
);
17723 gen_helper_dmt(t0
);
17724 gen_store_gpr(t0
, rt
);
17727 check_insn(ctx
, ASE_MT
);
17728 gen_helper_emt(t0
);
17729 gen_store_gpr(t0
, rt
);
17732 check_insn(ctx
, ASE_MT
);
17733 gen_helper_dvpe(t0
, cpu_env
);
17734 gen_store_gpr(t0
, rt
);
17737 check_insn(ctx
, ASE_MT
);
17738 gen_helper_evpe(t0
, cpu_env
);
17739 gen_store_gpr(t0
, rt
);
17742 check_insn(ctx
, ISA_MIPS32R2
);
17743 save_cpu_state(ctx
, 1);
17744 gen_helper_di(t0
, cpu_env
);
17745 gen_store_gpr(t0
, rt
);
17746 /* Stop translation as we may have switched the execution mode */
17747 ctx
->bstate
= BS_STOP
;
17750 check_insn(ctx
, ISA_MIPS32R2
);
17751 save_cpu_state(ctx
, 1);
17752 gen_helper_ei(t0
, cpu_env
);
17753 gen_store_gpr(t0
, rt
);
17754 /* Stop translation as we may have switched the execution mode */
17755 ctx
->bstate
= BS_STOP
;
17757 default: /* Invalid */
17758 MIPS_INVAL("mfmc0");
17759 generate_exception(ctx
, EXCP_RI
);
17764 #endif /* !CONFIG_USER_ONLY */
17767 check_insn(ctx
, ISA_MIPS32R2
);
17768 gen_load_srsgpr(rt
, rd
);
17771 check_insn(ctx
, ISA_MIPS32R2
);
17772 gen_store_srsgpr(rt
, rd
);
17776 generate_exception(ctx
, EXCP_RI
);
17780 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
17781 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17782 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
17783 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17786 /* Arithmetic with immediate opcode */
17787 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17791 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17793 case OPC_SLTI
: /* Set on less than with immediate opcode */
17795 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
17797 case OPC_ANDI
: /* Arithmetic with immediate opcode */
17798 case OPC_LUI
: /* OPC_AUI */
17801 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
17803 case OPC_J
... OPC_JAL
: /* Jump */
17804 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17805 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
17808 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
17809 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17811 generate_exception(ctx
, EXCP_RI
);
17814 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
17815 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17818 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17821 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
17822 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17824 generate_exception(ctx
, EXCP_RI
);
17827 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
17828 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17831 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17834 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
17837 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17839 check_insn(ctx
, ISA_MIPS32R6
);
17840 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
17841 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17844 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
17847 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17849 check_insn(ctx
, ISA_MIPS32R6
);
17850 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
17851 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17856 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17859 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17861 case OPC_LWL
: /* Load and stores */
17864 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17865 case OPC_LB
... OPC_LH
:
17866 case OPC_LW
... OPC_LHU
:
17867 gen_ld(ctx
, op
, rt
, rs
, imm
);
17871 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17872 case OPC_SB
... OPC_SH
:
17874 gen_st(ctx
, op
, rt
, rs
, imm
);
17877 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17878 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
17881 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17882 check_cp0_enabled(ctx
);
17883 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
17884 /* Treat as NOP. */
17887 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17888 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
17889 /* Treat as NOP. */
17892 /* Floating point (COP1). */
17897 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
17901 op1
= MASK_CP1(ctx
->opcode
);
17906 check_cp1_enabled(ctx
);
17907 check_insn(ctx
, ISA_MIPS32R2
);
17912 check_cp1_enabled(ctx
);
17913 gen_cp1(ctx
, op1
, rt
, rd
);
17915 #if defined(TARGET_MIPS64)
17918 check_cp1_enabled(ctx
);
17919 check_insn(ctx
, ISA_MIPS3
);
17920 gen_cp1(ctx
, op1
, rt
, rd
);
17923 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
17924 check_cp1_enabled(ctx
);
17925 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17927 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
17932 check_insn(ctx
, ASE_MIPS3D
);
17933 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
17934 (rt
>> 2) & 0x7, imm
<< 2);
17938 check_cp1_enabled(ctx
);
17939 check_insn(ctx
, ISA_MIPS32R6
);
17940 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
17944 check_cp1_enabled(ctx
);
17945 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17947 check_insn(ctx
, ASE_MIPS3D
);
17950 check_cp1_enabled(ctx
);
17951 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17952 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
17953 (rt
>> 2) & 0x7, imm
<< 2);
17956 check_cp1_enabled(ctx
);
17957 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17960 check_cp1_enabled(ctx
);
17961 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
17967 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
17968 check_cp1_enabled(ctx
);
17969 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17971 case R6_OPC_CMP_AF_S
:
17972 case R6_OPC_CMP_UN_S
:
17973 case R6_OPC_CMP_EQ_S
:
17974 case R6_OPC_CMP_UEQ_S
:
17975 case R6_OPC_CMP_LT_S
:
17976 case R6_OPC_CMP_ULT_S
:
17977 case R6_OPC_CMP_LE_S
:
17978 case R6_OPC_CMP_ULE_S
:
17979 case R6_OPC_CMP_SAF_S
:
17980 case R6_OPC_CMP_SUN_S
:
17981 case R6_OPC_CMP_SEQ_S
:
17982 case R6_OPC_CMP_SEUQ_S
:
17983 case R6_OPC_CMP_SLT_S
:
17984 case R6_OPC_CMP_SULT_S
:
17985 case R6_OPC_CMP_SLE_S
:
17986 case R6_OPC_CMP_SULE_S
:
17987 case R6_OPC_CMP_OR_S
:
17988 case R6_OPC_CMP_UNE_S
:
17989 case R6_OPC_CMP_NE_S
:
17990 case R6_OPC_CMP_SOR_S
:
17991 case R6_OPC_CMP_SUNE_S
:
17992 case R6_OPC_CMP_SNE_S
:
17993 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
17995 case R6_OPC_CMP_AF_D
:
17996 case R6_OPC_CMP_UN_D
:
17997 case R6_OPC_CMP_EQ_D
:
17998 case R6_OPC_CMP_UEQ_D
:
17999 case R6_OPC_CMP_LT_D
:
18000 case R6_OPC_CMP_ULT_D
:
18001 case R6_OPC_CMP_LE_D
:
18002 case R6_OPC_CMP_ULE_D
:
18003 case R6_OPC_CMP_SAF_D
:
18004 case R6_OPC_CMP_SUN_D
:
18005 case R6_OPC_CMP_SEQ_D
:
18006 case R6_OPC_CMP_SEUQ_D
:
18007 case R6_OPC_CMP_SLT_D
:
18008 case R6_OPC_CMP_SULT_D
:
18009 case R6_OPC_CMP_SLE_D
:
18010 case R6_OPC_CMP_SULE_D
:
18011 case R6_OPC_CMP_OR_D
:
18012 case R6_OPC_CMP_UNE_D
:
18013 case R6_OPC_CMP_NE_D
:
18014 case R6_OPC_CMP_SOR_D
:
18015 case R6_OPC_CMP_SUNE_D
:
18016 case R6_OPC_CMP_SNE_D
:
18017 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
18020 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
18025 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
18040 check_insn(ctx
, ASE_MSA
);
18041 gen_msa_branch(env
, ctx
, op1
);
18045 generate_exception(ctx
, EXCP_RI
);
18050 /* Compact branches [R6] and COP2 [non-R6] */
18051 case OPC_BC
: /* OPC_LWC2 */
18052 case OPC_BALC
: /* OPC_SWC2 */
18053 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18054 /* OPC_BC, OPC_BALC */
18055 gen_compute_compact_branch(ctx
, op
, 0, 0,
18056 sextract32(ctx
->opcode
<< 2, 0, 28));
18058 /* OPC_LWC2, OPC_SWC2 */
18059 /* COP2: Not implemented. */
18060 generate_exception_err(ctx
, EXCP_CpU
, 2);
18063 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
18064 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
18065 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18067 /* OPC_BEQZC, OPC_BNEZC */
18068 gen_compute_compact_branch(ctx
, op
, rs
, 0,
18069 sextract32(ctx
->opcode
<< 2, 0, 23));
18071 /* OPC_JIC, OPC_JIALC */
18072 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
18075 /* OPC_LWC2, OPC_SWC2 */
18076 /* COP2: Not implemented. */
18077 generate_exception_err(ctx
, EXCP_CpU
, 2);
18081 check_insn(ctx
, INSN_LOONGSON2F
);
18082 /* Note that these instructions use different fields. */
18083 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
18087 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18088 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
18089 check_cp1_enabled(ctx
);
18090 op1
= MASK_CP3(ctx
->opcode
);
18098 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
18101 /* Treat as NOP. */
18116 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
18120 generate_exception (ctx
, EXCP_RI
);
18124 generate_exception_err(ctx
, EXCP_CpU
, 1);
18128 #if defined(TARGET_MIPS64)
18129 /* MIPS64 opcodes */
18130 case OPC_LDL
... OPC_LDR
:
18132 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18135 check_insn(ctx
, ISA_MIPS3
);
18136 check_mips_64(ctx
);
18137 gen_ld(ctx
, op
, rt
, rs
, imm
);
18139 case OPC_SDL
... OPC_SDR
:
18140 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18142 check_insn(ctx
, ISA_MIPS3
);
18143 check_mips_64(ctx
);
18144 gen_st(ctx
, op
, rt
, rs
, imm
);
18147 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
18148 check_insn(ctx
, ISA_MIPS3
);
18149 check_mips_64(ctx
);
18150 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
18152 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
18153 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18154 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
18155 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
18158 check_insn(ctx
, ISA_MIPS3
);
18159 check_mips_64(ctx
);
18160 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
18164 check_insn(ctx
, ISA_MIPS3
);
18165 check_mips_64(ctx
);
18166 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
18169 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
18170 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18171 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
18173 MIPS_INVAL("major opcode");
18174 generate_exception(ctx
, EXCP_RI
);
18178 case OPC_DAUI
: /* OPC_JALX */
18179 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18180 #if defined(TARGET_MIPS64)
18182 check_mips_64(ctx
);
18184 TCGv t0
= tcg_temp_new();
18185 gen_load_gpr(t0
, rs
);
18186 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
18189 MIPS_DEBUG("daui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
18191 generate_exception(ctx
, EXCP_RI
);
18192 MIPS_INVAL("major opcode");
18196 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
18197 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
18198 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
18201 case OPC_MSA
: /* OPC_MDMX */
18202 /* MDMX: Not implemented. */
18206 check_insn(ctx
, ISA_MIPS32R6
);
18207 gen_pcrel(ctx
, rs
, imm
);
18209 default: /* Invalid */
18210 MIPS_INVAL("major opcode");
18211 generate_exception(ctx
, EXCP_RI
);
18217 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
18220 CPUState
*cs
= CPU(cpu
);
18221 CPUMIPSState
*env
= &cpu
->env
;
18223 target_ulong pc_start
;
18224 uint16_t *gen_opc_end
;
18233 qemu_log("search pc %d\n", search_pc
);
18236 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
18239 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
18240 ctx
.insn_flags
= env
->insn_flags
;
18241 ctx
.CP0_Config1
= env
->CP0_Config1
;
18243 ctx
.bstate
= BS_NONE
;
18244 ctx
.kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
18245 ctx
.rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
18246 ctx
.ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
18247 ctx
.bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
18248 ctx
.bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
18249 /* Restore delay slot state from the tb context. */
18250 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
18251 ctx
.ulri
= env
->CP0_Config3
& (1 << CP0C3_ULRI
);
18252 restore_cpu_state(env
, &ctx
);
18253 #ifdef CONFIG_USER_ONLY
18254 ctx
.mem_idx
= MIPS_HFLAG_UM
;
18256 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
18259 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
18260 if (max_insns
== 0)
18261 max_insns
= CF_COUNT_MASK
;
18262 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
18264 while (ctx
.bstate
== BS_NONE
) {
18265 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
18266 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
18267 if (bp
->pc
== ctx
.pc
) {
18268 save_cpu_state(&ctx
, 1);
18269 ctx
.bstate
= BS_BRANCH
;
18270 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
18271 /* Include the breakpoint location or the tb won't
18272 * be flushed when it must be. */
18274 goto done_generating
;
18280 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
18284 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
18286 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
18287 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
18288 gen_opc_btarget
[lj
] = ctx
.btarget
;
18289 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
18290 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
18292 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
18295 is_slot
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
18296 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
18297 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
18299 decode_opc(env
, &ctx
);
18300 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
18301 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
18302 insn_bytes
= decode_micromips_opc(env
, &ctx
);
18303 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
18304 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
18305 insn_bytes
= decode_mips16_opc(env
, &ctx
);
18307 generate_exception(&ctx
, EXCP_RI
);
18308 ctx
.bstate
= BS_STOP
;
18312 if (ctx
.hflags
& MIPS_HFLAG_BMASK
) {
18313 if (!(ctx
.hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
18314 MIPS_HFLAG_FBNSLOT
))) {
18315 /* force to generate branch as there is neither delay nor
18321 gen_branch(&ctx
, insn_bytes
);
18323 ctx
.pc
+= insn_bytes
;
18327 /* Execute a branch and its delay slot as a single instruction.
18328 This is what GDB expects and is consistent with what the
18329 hardware does (e.g. if a delay slot instruction faults, the
18330 reported PC is the PC of the branch). */
18331 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
18335 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
18338 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
18342 if (num_insns
>= max_insns
)
18348 if (tb
->cflags
& CF_LAST_IO
) {
18351 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
18352 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
18353 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
18355 switch (ctx
.bstate
) {
18357 gen_goto_tb(&ctx
, 0, ctx
.pc
);
18360 save_cpu_state(&ctx
, 0);
18361 gen_goto_tb(&ctx
, 0, ctx
.pc
);
18364 tcg_gen_exit_tb(0);
18372 gen_tb_end(tb
, num_insns
);
18373 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
18375 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
18378 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
18380 tb
->size
= ctx
.pc
- pc_start
;
18381 tb
->icount
= num_insns
;
18385 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
18386 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
18387 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
18393 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
18395 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
18398 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
18400 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
18403 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
18407 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
18409 #define printfpr(fp) \
18412 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
18413 " fd:%13g fs:%13g psu: %13g\n", \
18414 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
18415 (double)(fp)->fd, \
18416 (double)(fp)->fs[FP_ENDIAN_IDX], \
18417 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
18420 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
18421 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
18422 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
18423 " fd:%13g fs:%13g psu:%13g\n", \
18424 tmp.w[FP_ENDIAN_IDX], tmp.d, \
18426 (double)tmp.fs[FP_ENDIAN_IDX], \
18427 (double)tmp.fs[!FP_ENDIAN_IDX]); \
18432 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
18433 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
18434 get_float_exception_flags(&env
->active_fpu
.fp_status
));
18435 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
18436 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
18437 printfpr(&env
->active_fpu
.fpr
[i
]);
18443 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
18444 /* Debug help: The architecture requires 32bit code to maintain proper
18445 sign-extended values on 64bit machines. */
18447 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
18450 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
18451 fprintf_function cpu_fprintf
,
18456 if (!SIGN_EXT_P(env
->active_tc
.PC
))
18457 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
18458 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
18459 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
18460 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
18461 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
18462 if (!SIGN_EXT_P(env
->btarget
))
18463 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
18465 for (i
= 0; i
< 32; i
++) {
18466 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
18467 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
18470 if (!SIGN_EXT_P(env
->CP0_EPC
))
18471 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
18472 if (!SIGN_EXT_P(env
->lladdr
))
18473 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
18477 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
18480 MIPSCPU
*cpu
= MIPS_CPU(cs
);
18481 CPUMIPSState
*env
= &cpu
->env
;
18484 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
18485 " LO=0x" TARGET_FMT_lx
" ds %04x "
18486 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
18487 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
18488 env
->hflags
, env
->btarget
, env
->bcond
);
18489 for (i
= 0; i
< 32; i
++) {
18491 cpu_fprintf(f
, "GPR%02d:", i
);
18492 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
18494 cpu_fprintf(f
, "\n");
18497 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
18498 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
18499 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
18500 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
18501 if (env
->hflags
& MIPS_HFLAG_FPU
)
18502 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
18503 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
18504 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
18508 void mips_tcg_init(void)
18513 /* Initialize various static tables. */
18517 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
18518 TCGV_UNUSED(cpu_gpr
[0]);
18519 for (i
= 1; i
< 32; i
++)
18520 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
18521 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
18524 for (i
= 0; i
< 32; i
++) {
18525 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
18526 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
18529 for (i
= 0; i
< 32; i
++) {
18530 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
18532 tcg_global_mem_new_i64(TCG_AREG0
, off
, msaregnames
[i
* 2]);
18533 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
18534 msa_wr_d
[i
* 2 + 1] =
18535 tcg_global_mem_new_i64(TCG_AREG0
, off
, msaregnames
[i
* 2 + 1]);
18538 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
18539 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
18540 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
18541 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
18542 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
18544 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
18545 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
18548 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
18549 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
18551 bcond
= tcg_global_mem_new(TCG_AREG0
,
18552 offsetof(CPUMIPSState
, bcond
), "bcond");
18553 btarget
= tcg_global_mem_new(TCG_AREG0
,
18554 offsetof(CPUMIPSState
, btarget
), "btarget");
18555 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
18556 offsetof(CPUMIPSState
, hflags
), "hflags");
18558 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
18559 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
18561 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
18562 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
18568 #include "translate_init.c"
18570 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
18574 const mips_def_t
*def
;
18576 def
= cpu_mips_find_by_name(cpu_model
);
18579 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
18581 env
->cpu_model
= def
;
18583 #ifndef CONFIG_USER_ONLY
18584 mmu_init(env
, def
);
18586 fpu_init(env
, def
);
18587 mvp_init(env
, def
);
18589 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
18594 void cpu_state_reset(CPUMIPSState
*env
)
18596 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
18597 CPUState
*cs
= CPU(cpu
);
18599 /* Reset registers to their default values */
18600 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
18601 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
18602 #ifdef TARGET_WORDS_BIGENDIAN
18603 env
->CP0_Config0
|= (1 << CP0C0_BE
);
18605 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
18606 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
18607 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
18608 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
18609 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
18610 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
18611 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
18612 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
18613 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
18614 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
18615 << env
->cpu_model
->CP0_LLAddr_shift
;
18616 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
18617 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
18618 env
->CCRes
= env
->cpu_model
->CCRes
;
18619 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
18620 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
18621 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
18622 env
->current_tc
= 0;
18623 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
18624 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
18625 #if defined(TARGET_MIPS64)
18626 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
18627 env
->SEGMask
|= 3ULL << 62;
18630 env
->PABITS
= env
->cpu_model
->PABITS
;
18631 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
18632 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
18633 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
18634 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
18635 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
18636 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
18637 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
18638 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
18639 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
18640 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
18641 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
18642 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
18643 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
18644 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
18645 env
->msair
= env
->cpu_model
->MSAIR
;
18646 env
->insn_flags
= env
->cpu_model
->insn_flags
;
18648 #if defined(CONFIG_USER_ONLY)
18649 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
18650 # ifdef TARGET_MIPS64
18651 /* Enable 64-bit register mode. */
18652 env
->CP0_Status
|= (1 << CP0St_PX
);
18654 # ifdef TARGET_ABI_MIPSN64
18655 /* Enable 64-bit address mode. */
18656 env
->CP0_Status
|= (1 << CP0St_UX
);
18658 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
18659 hardware registers. */
18660 env
->CP0_HWREna
|= 0x0000000F;
18661 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
18662 env
->CP0_Status
|= (1 << CP0St_CU1
);
18664 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
18665 env
->CP0_Status
|= (1 << CP0St_MX
);
18667 # if defined(TARGET_MIPS64)
18668 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
18669 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
18670 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
18671 env
->CP0_Status
|= (1 << CP0St_FR
);
18675 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
18676 /* If the exception was raised from a delay slot,
18677 come back to the jump. */
18678 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
18680 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
18682 env
->active_tc
.PC
= (int32_t)0xBFC00000;
18683 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
18684 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
18685 env
->CP0_Wired
= 0;
18686 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
18687 if (kvm_enabled()) {
18688 env
->CP0_EBase
|= 0x40000000;
18690 env
->CP0_EBase
|= 0x80000000;
18692 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
18693 /* vectored interrupts not implemented, timer on int 7,
18694 no performance counters. */
18695 env
->CP0_IntCtl
= 0xe0000000;
18699 for (i
= 0; i
< 7; i
++) {
18700 env
->CP0_WatchLo
[i
] = 0;
18701 env
->CP0_WatchHi
[i
] = 0x80000000;
18703 env
->CP0_WatchLo
[7] = 0;
18704 env
->CP0_WatchHi
[7] = 0;
18706 /* Count register increments in debug mode, EJTAG version 1 */
18707 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
18709 cpu_mips_store_count(env
, 1);
18711 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
18714 /* Only TC0 on VPE 0 starts as active. */
18715 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
18716 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
18717 env
->tcs
[i
].CP0_TCHalt
= 1;
18719 env
->active_tc
.CP0_TCHalt
= 1;
18722 if (cs
->cpu_index
== 0) {
18723 /* VPE0 starts up enabled. */
18724 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
18725 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
18727 /* TC0 starts up unhalted. */
18729 env
->active_tc
.CP0_TCHalt
= 0;
18730 env
->tcs
[0].CP0_TCHalt
= 0;
18731 /* With thread 0 active. */
18732 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
18733 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
18737 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
18738 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
18739 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
18740 env
->CP0_Status
|= (1 << CP0St_FR
);
18744 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
18748 compute_hflags(env
);
18749 cs
->exception_index
= EXCP_NONE
;
18752 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
18754 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
18755 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
18756 env
->hflags
|= gen_opc_hflags
[pc_pos
];
18757 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
18758 case MIPS_HFLAG_BR
:
18760 case MIPS_HFLAG_BC
:
18761 case MIPS_HFLAG_BL
:
18763 env
->btarget
= gen_opc_btarget
[pc_pos
];