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"
32 #include "exec/semihost.h"
34 #include "trace-tcg.h"
37 #define MIPS_DEBUG_DISAS 0
38 //#define MIPS_DEBUG_SIGN_EXTENSIONS
40 /* MIPS major opcodes */
41 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
44 /* indirect opcode tables */
45 OPC_SPECIAL
= (0x00 << 26),
46 OPC_REGIMM
= (0x01 << 26),
47 OPC_CP0
= (0x10 << 26),
48 OPC_CP1
= (0x11 << 26),
49 OPC_CP2
= (0x12 << 26),
50 OPC_CP3
= (0x13 << 26),
51 OPC_SPECIAL2
= (0x1C << 26),
52 OPC_SPECIAL3
= (0x1F << 26),
53 /* arithmetic with immediate */
54 OPC_ADDI
= (0x08 << 26),
55 OPC_ADDIU
= (0x09 << 26),
56 OPC_SLTI
= (0x0A << 26),
57 OPC_SLTIU
= (0x0B << 26),
58 /* logic with immediate */
59 OPC_ANDI
= (0x0C << 26),
60 OPC_ORI
= (0x0D << 26),
61 OPC_XORI
= (0x0E << 26),
62 OPC_LUI
= (0x0F << 26),
63 /* arithmetic with immediate */
64 OPC_DADDI
= (0x18 << 26),
65 OPC_DADDIU
= (0x19 << 26),
66 /* Jump and branches */
68 OPC_JAL
= (0x03 << 26),
69 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
70 OPC_BEQL
= (0x14 << 26),
71 OPC_BNE
= (0x05 << 26),
72 OPC_BNEL
= (0x15 << 26),
73 OPC_BLEZ
= (0x06 << 26),
74 OPC_BLEZL
= (0x16 << 26),
75 OPC_BGTZ
= (0x07 << 26),
76 OPC_BGTZL
= (0x17 << 26),
77 OPC_JALX
= (0x1D << 26),
78 OPC_DAUI
= (0x1D << 26),
80 OPC_LDL
= (0x1A << 26),
81 OPC_LDR
= (0x1B << 26),
82 OPC_LB
= (0x20 << 26),
83 OPC_LH
= (0x21 << 26),
84 OPC_LWL
= (0x22 << 26),
85 OPC_LW
= (0x23 << 26),
86 OPC_LWPC
= OPC_LW
| 0x5,
87 OPC_LBU
= (0x24 << 26),
88 OPC_LHU
= (0x25 << 26),
89 OPC_LWR
= (0x26 << 26),
90 OPC_LWU
= (0x27 << 26),
91 OPC_SB
= (0x28 << 26),
92 OPC_SH
= (0x29 << 26),
93 OPC_SWL
= (0x2A << 26),
94 OPC_SW
= (0x2B << 26),
95 OPC_SDL
= (0x2C << 26),
96 OPC_SDR
= (0x2D << 26),
97 OPC_SWR
= (0x2E << 26),
98 OPC_LL
= (0x30 << 26),
99 OPC_LLD
= (0x34 << 26),
100 OPC_LD
= (0x37 << 26),
101 OPC_LDPC
= OPC_LD
| 0x5,
102 OPC_SC
= (0x38 << 26),
103 OPC_SCD
= (0x3C << 26),
104 OPC_SD
= (0x3F << 26),
105 /* Floating point load/store */
106 OPC_LWC1
= (0x31 << 26),
107 OPC_LWC2
= (0x32 << 26),
108 OPC_LDC1
= (0x35 << 26),
109 OPC_LDC2
= (0x36 << 26),
110 OPC_SWC1
= (0x39 << 26),
111 OPC_SWC2
= (0x3A << 26),
112 OPC_SDC1
= (0x3D << 26),
113 OPC_SDC2
= (0x3E << 26),
114 /* Compact Branches */
115 OPC_BLEZALC
= (0x06 << 26),
116 OPC_BGEZALC
= (0x06 << 26),
117 OPC_BGEUC
= (0x06 << 26),
118 OPC_BGTZALC
= (0x07 << 26),
119 OPC_BLTZALC
= (0x07 << 26),
120 OPC_BLTUC
= (0x07 << 26),
121 OPC_BOVC
= (0x08 << 26),
122 OPC_BEQZALC
= (0x08 << 26),
123 OPC_BEQC
= (0x08 << 26),
124 OPC_BLEZC
= (0x16 << 26),
125 OPC_BGEZC
= (0x16 << 26),
126 OPC_BGEC
= (0x16 << 26),
127 OPC_BGTZC
= (0x17 << 26),
128 OPC_BLTZC
= (0x17 << 26),
129 OPC_BLTC
= (0x17 << 26),
130 OPC_BNVC
= (0x18 << 26),
131 OPC_BNEZALC
= (0x18 << 26),
132 OPC_BNEC
= (0x18 << 26),
133 OPC_BC
= (0x32 << 26),
134 OPC_BEQZC
= (0x36 << 26),
135 OPC_JIC
= (0x36 << 26),
136 OPC_BALC
= (0x3A << 26),
137 OPC_BNEZC
= (0x3E << 26),
138 OPC_JIALC
= (0x3E << 26),
139 /* MDMX ASE specific */
140 OPC_MDMX
= (0x1E << 26),
141 /* MSA ASE, same as MDMX */
143 /* Cache and prefetch */
144 OPC_CACHE
= (0x2F << 26),
145 OPC_PREF
= (0x33 << 26),
146 /* PC-relative address computation / loads */
147 OPC_PCREL
= (0x3B << 26),
150 /* PC-relative address computation / loads */
151 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
152 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
154 /* Instructions determined by bits 19 and 20 */
155 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
156 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
157 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
159 /* Instructions determined by bits 16 ... 20 */
160 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
161 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
164 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
167 /* MIPS special opcodes */
168 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
172 OPC_SLL
= 0x00 | OPC_SPECIAL
,
173 /* NOP is SLL r0, r0, 0 */
174 /* SSNOP is SLL r0, r0, 1 */
175 /* EHB is SLL r0, r0, 3 */
176 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
177 OPC_ROTR
= OPC_SRL
| (1 << 21),
178 OPC_SRA
= 0x03 | OPC_SPECIAL
,
179 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
180 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
181 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
182 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
183 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
184 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
185 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
186 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
187 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
188 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
189 OPC_DROTR
= OPC_DSRL
| (1 << 21),
190 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
191 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
192 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
193 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
194 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
195 /* Multiplication / division */
196 OPC_MULT
= 0x18 | OPC_SPECIAL
,
197 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
198 OPC_DIV
= 0x1A | OPC_SPECIAL
,
199 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
200 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
201 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
202 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
203 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
205 /* 2 registers arithmetic / logic */
206 OPC_ADD
= 0x20 | OPC_SPECIAL
,
207 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
208 OPC_SUB
= 0x22 | OPC_SPECIAL
,
209 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
210 OPC_AND
= 0x24 | OPC_SPECIAL
,
211 OPC_OR
= 0x25 | OPC_SPECIAL
,
212 OPC_XOR
= 0x26 | OPC_SPECIAL
,
213 OPC_NOR
= 0x27 | OPC_SPECIAL
,
214 OPC_SLT
= 0x2A | OPC_SPECIAL
,
215 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
216 OPC_DADD
= 0x2C | OPC_SPECIAL
,
217 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
218 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
219 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
221 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
222 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
224 OPC_TGE
= 0x30 | OPC_SPECIAL
,
225 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
226 OPC_TLT
= 0x32 | OPC_SPECIAL
,
227 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
228 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
229 OPC_TNE
= 0x36 | OPC_SPECIAL
,
230 /* HI / LO registers load & stores */
231 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
232 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
233 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
234 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
235 /* Conditional moves */
236 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
237 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
239 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
240 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
242 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
245 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
246 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
247 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
248 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
249 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
251 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
252 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
253 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
254 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
257 /* R6 Multiply and Divide instructions have the same Opcode
258 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
259 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
262 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
263 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
264 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
265 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
266 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
267 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
268 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
269 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
271 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
272 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
273 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
274 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
275 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
276 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
277 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
278 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
280 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
281 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
282 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
283 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
284 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
286 OPC_LSA
= 0x05 | OPC_SPECIAL
,
287 OPC_DLSA
= 0x15 | OPC_SPECIAL
,
290 /* Multiplication variants of the vr54xx. */
291 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
294 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
295 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
296 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
297 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
298 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
299 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
300 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
301 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
302 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
303 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
304 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
305 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
306 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
307 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
310 /* REGIMM (rt field) opcodes */
311 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
314 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
315 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
316 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
317 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
318 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
319 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
320 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
321 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
322 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
323 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
324 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
325 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
326 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
327 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
328 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
330 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
331 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
334 /* Special2 opcodes */
335 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
338 /* Multiply & xxx operations */
339 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
340 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
341 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
342 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
343 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
345 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
346 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
347 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
348 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
349 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
350 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
351 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
352 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
353 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
354 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
355 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
356 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
358 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
359 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
360 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
361 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
363 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
366 /* Special3 opcodes */
367 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
370 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
371 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
372 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
373 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
374 OPC_INS
= 0x04 | OPC_SPECIAL3
,
375 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
376 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
377 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
378 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
379 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
380 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
381 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
382 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
385 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
386 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
387 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
388 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
389 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
390 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
391 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
392 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
393 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
394 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
395 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
396 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
399 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
400 /* MIPS DSP Arithmetic */
401 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
402 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
403 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
404 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
405 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
406 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
407 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
408 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
409 /* MIPS DSP GPR-Based Shift Sub-class */
410 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
411 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
412 /* MIPS DSP Multiply Sub-class insns */
413 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
414 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
415 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
416 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
417 /* DSP Bit/Manipulation Sub-class */
418 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
419 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
420 /* MIPS DSP Append Sub-class */
421 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
422 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
423 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
424 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
425 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
428 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
429 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
430 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
431 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
432 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
433 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
437 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
440 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
441 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
442 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
443 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp */
444 OPC_ALIGN_END
= (0x0B << 6) | OPC_BSHFL
, /* 010.00 to 010.11 */
445 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
449 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
452 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
453 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
454 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp */
455 OPC_DALIGN_END
= (0x0F << 6) | OPC_DBSHFL
, /* 01.000 to 01.111 */
456 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
459 /* MIPS DSP REGIMM opcodes */
461 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
462 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
465 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
468 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
469 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
470 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
471 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
474 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
476 /* MIPS DSP Arithmetic Sub-class */
477 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
478 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
479 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
480 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
481 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
482 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
483 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
484 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
485 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
486 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
487 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
488 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
489 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
490 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
491 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
492 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
493 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
494 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
495 /* MIPS DSP Multiply Sub-class insns */
496 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
497 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
498 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
499 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
500 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
501 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
504 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
505 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
507 /* MIPS DSP Arithmetic Sub-class */
508 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
509 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
510 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
511 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
512 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
513 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
514 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
515 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
516 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
517 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
518 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
519 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
520 /* MIPS DSP Multiply Sub-class insns */
521 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
522 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
523 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
524 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
527 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529 /* MIPS DSP Arithmetic Sub-class */
530 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
531 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
532 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
533 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
534 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
535 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
536 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
537 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
538 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
539 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
540 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
541 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
542 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
543 /* DSP Bit/Manipulation Sub-class */
544 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
545 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
546 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
547 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
548 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
551 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 /* MIPS DSP Arithmetic Sub-class */
554 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
555 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
556 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
557 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
558 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
559 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
560 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
561 /* DSP Compare-Pick Sub-class */
562 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
563 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
564 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
565 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
566 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
567 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
568 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
569 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
570 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
571 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
572 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
573 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
574 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
575 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
576 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
579 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
581 /* MIPS DSP GPR-Based Shift Sub-class */
582 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
583 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
584 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
585 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
586 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
587 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
588 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
589 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
590 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
591 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
592 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
593 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
594 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
595 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
596 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
597 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
598 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
599 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
600 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
601 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
602 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
603 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
606 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
608 /* MIPS DSP Multiply Sub-class insns */
609 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
610 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
611 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
612 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
613 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
614 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
615 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
616 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
617 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
618 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
619 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
620 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
621 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
622 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
623 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
624 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
625 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
626 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
627 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
628 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
629 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
630 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
633 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
635 /* DSP Bit/Manipulation Sub-class */
636 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
639 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
641 /* MIPS DSP Append Sub-class */
642 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
643 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
644 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
647 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
649 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
650 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
651 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
652 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
653 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
654 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
655 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
656 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
657 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
658 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
659 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
660 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
661 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
662 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
663 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
664 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
665 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
666 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
669 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671 /* MIPS DSP Arithmetic Sub-class */
672 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
673 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
674 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
675 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
676 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
677 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
678 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
679 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
680 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
681 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
682 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
683 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
684 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
685 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
686 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
687 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
688 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
689 /* DSP Bit/Manipulation Sub-class */
690 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
691 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
692 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
693 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
694 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
695 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
698 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
700 /* MIPS DSP Multiply Sub-class insns */
701 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
702 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
703 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
704 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
705 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
706 /* MIPS DSP Arithmetic Sub-class */
707 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
708 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
709 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
710 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
711 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
712 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
713 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
714 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
715 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
716 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
717 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
718 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
719 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
720 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
721 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
722 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
723 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
724 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
725 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
726 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
727 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
730 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
732 /* DSP Compare-Pick Sub-class */
733 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
734 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
735 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
736 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
737 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
738 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
739 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
740 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
741 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
742 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
743 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
744 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
745 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
746 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
747 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
748 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
749 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
750 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
751 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
752 /* MIPS DSP Arithmetic Sub-class */
753 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
754 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
755 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
756 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
757 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
758 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
759 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
760 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
763 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
765 /* DSP Append Sub-class */
766 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
767 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
768 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
769 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
772 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
774 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
775 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
776 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
777 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
778 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
779 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
780 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
781 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
782 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
783 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
784 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
785 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
786 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
787 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
788 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
789 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
790 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
791 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
792 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
793 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
794 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
795 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
798 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
800 /* DSP Bit/Manipulation Sub-class */
801 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
804 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
806 /* MIPS DSP Multiply Sub-class insns */
807 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
808 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
809 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
810 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
811 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
812 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
813 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
814 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
815 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
816 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
817 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
818 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
819 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
820 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
821 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
822 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
823 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
824 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
825 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
826 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
827 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
828 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
829 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
830 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
831 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
832 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
835 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
837 /* MIPS DSP GPR-Based Shift Sub-class */
838 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
839 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
840 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
841 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
842 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
843 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
844 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
845 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
846 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
847 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
848 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
849 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
850 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
851 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
852 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
853 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
854 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
855 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
856 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
857 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
858 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
859 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
860 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
861 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
862 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
863 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
866 /* Coprocessor 0 (rs field) */
867 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
870 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
871 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
872 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
873 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
874 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
875 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
876 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
877 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
878 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
879 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
880 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
881 OPC_C0
= (0x10 << 21) | OPC_CP0
,
882 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
883 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
887 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
890 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
891 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
892 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
893 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
894 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
895 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
898 /* Coprocessor 0 (with rs == C0) */
899 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
902 OPC_TLBR
= 0x01 | OPC_C0
,
903 OPC_TLBWI
= 0x02 | OPC_C0
,
904 OPC_TLBINV
= 0x03 | OPC_C0
,
905 OPC_TLBINVF
= 0x04 | OPC_C0
,
906 OPC_TLBWR
= 0x06 | OPC_C0
,
907 OPC_TLBP
= 0x08 | OPC_C0
,
908 OPC_RFE
= 0x10 | OPC_C0
,
909 OPC_ERET
= 0x18 | OPC_C0
,
910 OPC_DERET
= 0x1F | OPC_C0
,
911 OPC_WAIT
= 0x20 | OPC_C0
,
914 /* Coprocessor 1 (rs field) */
915 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
917 /* Values for the fmt field in FP instructions */
919 /* 0 - 15 are reserved */
920 FMT_S
= 16, /* single fp */
921 FMT_D
= 17, /* double fp */
922 FMT_E
= 18, /* extended fp */
923 FMT_Q
= 19, /* quad fp */
924 FMT_W
= 20, /* 32-bit fixed */
925 FMT_L
= 21, /* 64-bit fixed */
926 FMT_PS
= 22, /* paired single fp */
927 /* 23 - 31 are reserved */
931 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
932 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
933 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
934 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
935 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
936 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
937 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
938 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
939 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
940 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
941 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
942 OPC_BZ_V
= (0x0B << 21) | OPC_CP1
,
943 OPC_BNZ_V
= (0x0F << 21) | OPC_CP1
,
944 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
945 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
946 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
947 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
948 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
949 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
950 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
951 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
952 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
953 OPC_BZ_B
= (0x18 << 21) | OPC_CP1
,
954 OPC_BZ_H
= (0x19 << 21) | OPC_CP1
,
955 OPC_BZ_W
= (0x1A << 21) | OPC_CP1
,
956 OPC_BZ_D
= (0x1B << 21) | OPC_CP1
,
957 OPC_BNZ_B
= (0x1C << 21) | OPC_CP1
,
958 OPC_BNZ_H
= (0x1D << 21) | OPC_CP1
,
959 OPC_BNZ_W
= (0x1E << 21) | OPC_CP1
,
960 OPC_BNZ_D
= (0x1F << 21) | OPC_CP1
,
963 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
964 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
967 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
968 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
969 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
970 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
974 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
975 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
979 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
980 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
983 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
986 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
987 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
988 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
989 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
990 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
991 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
992 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
993 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
994 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
995 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
996 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
999 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1002 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1003 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1004 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1005 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1006 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1007 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1008 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1009 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1011 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1012 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1013 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1014 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1015 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1016 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1017 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1018 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1020 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1021 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1022 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1023 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1024 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1025 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1026 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1027 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1029 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1030 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1031 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1032 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1033 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1034 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1035 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1036 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1038 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1039 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1040 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1041 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1042 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1043 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1045 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1046 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1047 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1048 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1049 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1050 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1052 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1053 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1054 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1055 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1056 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1057 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1059 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1060 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1061 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1062 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1063 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1064 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1066 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1067 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1068 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1069 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1070 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1071 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1073 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1074 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1075 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1076 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1077 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1078 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1080 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1081 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1082 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1083 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1084 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1085 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1087 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1088 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1089 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1090 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1091 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1092 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1096 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1099 OPC_LWXC1
= 0x00 | OPC_CP3
,
1100 OPC_LDXC1
= 0x01 | OPC_CP3
,
1101 OPC_LUXC1
= 0x05 | OPC_CP3
,
1102 OPC_SWXC1
= 0x08 | OPC_CP3
,
1103 OPC_SDXC1
= 0x09 | OPC_CP3
,
1104 OPC_SUXC1
= 0x0D | OPC_CP3
,
1105 OPC_PREFX
= 0x0F | OPC_CP3
,
1106 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1107 OPC_MADD_S
= 0x20 | OPC_CP3
,
1108 OPC_MADD_D
= 0x21 | OPC_CP3
,
1109 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1110 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1111 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1112 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1113 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1114 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1115 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1116 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1117 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1118 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1122 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1124 OPC_MSA_I8_00
= 0x00 | OPC_MSA
,
1125 OPC_MSA_I8_01
= 0x01 | OPC_MSA
,
1126 OPC_MSA_I8_02
= 0x02 | OPC_MSA
,
1127 OPC_MSA_I5_06
= 0x06 | OPC_MSA
,
1128 OPC_MSA_I5_07
= 0x07 | OPC_MSA
,
1129 OPC_MSA_BIT_09
= 0x09 | OPC_MSA
,
1130 OPC_MSA_BIT_0A
= 0x0A | OPC_MSA
,
1131 OPC_MSA_3R_0D
= 0x0D | OPC_MSA
,
1132 OPC_MSA_3R_0E
= 0x0E | OPC_MSA
,
1133 OPC_MSA_3R_0F
= 0x0F | OPC_MSA
,
1134 OPC_MSA_3R_10
= 0x10 | OPC_MSA
,
1135 OPC_MSA_3R_11
= 0x11 | OPC_MSA
,
1136 OPC_MSA_3R_12
= 0x12 | OPC_MSA
,
1137 OPC_MSA_3R_13
= 0x13 | OPC_MSA
,
1138 OPC_MSA_3R_14
= 0x14 | OPC_MSA
,
1139 OPC_MSA_3R_15
= 0x15 | OPC_MSA
,
1140 OPC_MSA_ELM
= 0x19 | OPC_MSA
,
1141 OPC_MSA_3RF_1A
= 0x1A | OPC_MSA
,
1142 OPC_MSA_3RF_1B
= 0x1B | OPC_MSA
,
1143 OPC_MSA_3RF_1C
= 0x1C | OPC_MSA
,
1144 OPC_MSA_VEC
= 0x1E | OPC_MSA
,
1146 /* MI10 instruction */
1147 OPC_LD_B
= (0x20) | OPC_MSA
,
1148 OPC_LD_H
= (0x21) | OPC_MSA
,
1149 OPC_LD_W
= (0x22) | OPC_MSA
,
1150 OPC_LD_D
= (0x23) | OPC_MSA
,
1151 OPC_ST_B
= (0x24) | OPC_MSA
,
1152 OPC_ST_H
= (0x25) | OPC_MSA
,
1153 OPC_ST_W
= (0x26) | OPC_MSA
,
1154 OPC_ST_D
= (0x27) | OPC_MSA
,
1158 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1159 OPC_ADDVI_df
= (0x0 << 23) | OPC_MSA_I5_06
,
1160 OPC_CEQI_df
= (0x0 << 23) | OPC_MSA_I5_07
,
1161 OPC_SUBVI_df
= (0x1 << 23) | OPC_MSA_I5_06
,
1162 OPC_MAXI_S_df
= (0x2 << 23) | OPC_MSA_I5_06
,
1163 OPC_CLTI_S_df
= (0x2 << 23) | OPC_MSA_I5_07
,
1164 OPC_MAXI_U_df
= (0x3 << 23) | OPC_MSA_I5_06
,
1165 OPC_CLTI_U_df
= (0x3 << 23) | OPC_MSA_I5_07
,
1166 OPC_MINI_S_df
= (0x4 << 23) | OPC_MSA_I5_06
,
1167 OPC_CLEI_S_df
= (0x4 << 23) | OPC_MSA_I5_07
,
1168 OPC_MINI_U_df
= (0x5 << 23) | OPC_MSA_I5_06
,
1169 OPC_CLEI_U_df
= (0x5 << 23) | OPC_MSA_I5_07
,
1170 OPC_LDI_df
= (0x6 << 23) | OPC_MSA_I5_07
,
1172 /* I8 instruction */
1173 OPC_ANDI_B
= (0x0 << 24) | OPC_MSA_I8_00
,
1174 OPC_BMNZI_B
= (0x0 << 24) | OPC_MSA_I8_01
,
1175 OPC_SHF_B
= (0x0 << 24) | OPC_MSA_I8_02
,
1176 OPC_ORI_B
= (0x1 << 24) | OPC_MSA_I8_00
,
1177 OPC_BMZI_B
= (0x1 << 24) | OPC_MSA_I8_01
,
1178 OPC_SHF_H
= (0x1 << 24) | OPC_MSA_I8_02
,
1179 OPC_NORI_B
= (0x2 << 24) | OPC_MSA_I8_00
,
1180 OPC_BSELI_B
= (0x2 << 24) | OPC_MSA_I8_01
,
1181 OPC_SHF_W
= (0x2 << 24) | OPC_MSA_I8_02
,
1182 OPC_XORI_B
= (0x3 << 24) | OPC_MSA_I8_00
,
1184 /* VEC/2R/2RF instruction */
1185 OPC_AND_V
= (0x00 << 21) | OPC_MSA_VEC
,
1186 OPC_OR_V
= (0x01 << 21) | OPC_MSA_VEC
,
1187 OPC_NOR_V
= (0x02 << 21) | OPC_MSA_VEC
,
1188 OPC_XOR_V
= (0x03 << 21) | OPC_MSA_VEC
,
1189 OPC_BMNZ_V
= (0x04 << 21) | OPC_MSA_VEC
,
1190 OPC_BMZ_V
= (0x05 << 21) | OPC_MSA_VEC
,
1191 OPC_BSEL_V
= (0x06 << 21) | OPC_MSA_VEC
,
1193 OPC_MSA_2R
= (0x18 << 21) | OPC_MSA_VEC
,
1194 OPC_MSA_2RF
= (0x19 << 21) | OPC_MSA_VEC
,
1196 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1197 OPC_FILL_df
= (0x00 << 18) | OPC_MSA_2R
,
1198 OPC_PCNT_df
= (0x01 << 18) | OPC_MSA_2R
,
1199 OPC_NLOC_df
= (0x02 << 18) | OPC_MSA_2R
,
1200 OPC_NLZC_df
= (0x03 << 18) | OPC_MSA_2R
,
1202 /* 2RF instruction df(bit 16) = _w, _d */
1203 OPC_FCLASS_df
= (0x00 << 17) | OPC_MSA_2RF
,
1204 OPC_FTRUNC_S_df
= (0x01 << 17) | OPC_MSA_2RF
,
1205 OPC_FTRUNC_U_df
= (0x02 << 17) | OPC_MSA_2RF
,
1206 OPC_FSQRT_df
= (0x03 << 17) | OPC_MSA_2RF
,
1207 OPC_FRSQRT_df
= (0x04 << 17) | OPC_MSA_2RF
,
1208 OPC_FRCP_df
= (0x05 << 17) | OPC_MSA_2RF
,
1209 OPC_FRINT_df
= (0x06 << 17) | OPC_MSA_2RF
,
1210 OPC_FLOG2_df
= (0x07 << 17) | OPC_MSA_2RF
,
1211 OPC_FEXUPL_df
= (0x08 << 17) | OPC_MSA_2RF
,
1212 OPC_FEXUPR_df
= (0x09 << 17) | OPC_MSA_2RF
,
1213 OPC_FFQL_df
= (0x0A << 17) | OPC_MSA_2RF
,
1214 OPC_FFQR_df
= (0x0B << 17) | OPC_MSA_2RF
,
1215 OPC_FTINT_S_df
= (0x0C << 17) | OPC_MSA_2RF
,
1216 OPC_FTINT_U_df
= (0x0D << 17) | OPC_MSA_2RF
,
1217 OPC_FFINT_S_df
= (0x0E << 17) | OPC_MSA_2RF
,
1218 OPC_FFINT_U_df
= (0x0F << 17) | OPC_MSA_2RF
,
1220 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1221 OPC_SLL_df
= (0x0 << 23) | OPC_MSA_3R_0D
,
1222 OPC_ADDV_df
= (0x0 << 23) | OPC_MSA_3R_0E
,
1223 OPC_CEQ_df
= (0x0 << 23) | OPC_MSA_3R_0F
,
1224 OPC_ADD_A_df
= (0x0 << 23) | OPC_MSA_3R_10
,
1225 OPC_SUBS_S_df
= (0x0 << 23) | OPC_MSA_3R_11
,
1226 OPC_MULV_df
= (0x0 << 23) | OPC_MSA_3R_12
,
1227 OPC_DOTP_S_df
= (0x0 << 23) | OPC_MSA_3R_13
,
1228 OPC_SLD_df
= (0x0 << 23) | OPC_MSA_3R_14
,
1229 OPC_VSHF_df
= (0x0 << 23) | OPC_MSA_3R_15
,
1230 OPC_SRA_df
= (0x1 << 23) | OPC_MSA_3R_0D
,
1231 OPC_SUBV_df
= (0x1 << 23) | OPC_MSA_3R_0E
,
1232 OPC_ADDS_A_df
= (0x1 << 23) | OPC_MSA_3R_10
,
1233 OPC_SUBS_U_df
= (0x1 << 23) | OPC_MSA_3R_11
,
1234 OPC_MADDV_df
= (0x1 << 23) | OPC_MSA_3R_12
,
1235 OPC_DOTP_U_df
= (0x1 << 23) | OPC_MSA_3R_13
,
1236 OPC_SPLAT_df
= (0x1 << 23) | OPC_MSA_3R_14
,
1237 OPC_SRAR_df
= (0x1 << 23) | OPC_MSA_3R_15
,
1238 OPC_SRL_df
= (0x2 << 23) | OPC_MSA_3R_0D
,
1239 OPC_MAX_S_df
= (0x2 << 23) | OPC_MSA_3R_0E
,
1240 OPC_CLT_S_df
= (0x2 << 23) | OPC_MSA_3R_0F
,
1241 OPC_ADDS_S_df
= (0x2 << 23) | OPC_MSA_3R_10
,
1242 OPC_SUBSUS_U_df
= (0x2 << 23) | OPC_MSA_3R_11
,
1243 OPC_MSUBV_df
= (0x2 << 23) | OPC_MSA_3R_12
,
1244 OPC_DPADD_S_df
= (0x2 << 23) | OPC_MSA_3R_13
,
1245 OPC_PCKEV_df
= (0x2 << 23) | OPC_MSA_3R_14
,
1246 OPC_SRLR_df
= (0x2 << 23) | OPC_MSA_3R_15
,
1247 OPC_BCLR_df
= (0x3 << 23) | OPC_MSA_3R_0D
,
1248 OPC_MAX_U_df
= (0x3 << 23) | OPC_MSA_3R_0E
,
1249 OPC_CLT_U_df
= (0x3 << 23) | OPC_MSA_3R_0F
,
1250 OPC_ADDS_U_df
= (0x3 << 23) | OPC_MSA_3R_10
,
1251 OPC_SUBSUU_S_df
= (0x3 << 23) | OPC_MSA_3R_11
,
1252 OPC_DPADD_U_df
= (0x3 << 23) | OPC_MSA_3R_13
,
1253 OPC_PCKOD_df
= (0x3 << 23) | OPC_MSA_3R_14
,
1254 OPC_BSET_df
= (0x4 << 23) | OPC_MSA_3R_0D
,
1255 OPC_MIN_S_df
= (0x4 << 23) | OPC_MSA_3R_0E
,
1256 OPC_CLE_S_df
= (0x4 << 23) | OPC_MSA_3R_0F
,
1257 OPC_AVE_S_df
= (0x4 << 23) | OPC_MSA_3R_10
,
1258 OPC_ASUB_S_df
= (0x4 << 23) | OPC_MSA_3R_11
,
1259 OPC_DIV_S_df
= (0x4 << 23) | OPC_MSA_3R_12
,
1260 OPC_DPSUB_S_df
= (0x4 << 23) | OPC_MSA_3R_13
,
1261 OPC_ILVL_df
= (0x4 << 23) | OPC_MSA_3R_14
,
1262 OPC_HADD_S_df
= (0x4 << 23) | OPC_MSA_3R_15
,
1263 OPC_BNEG_df
= (0x5 << 23) | OPC_MSA_3R_0D
,
1264 OPC_MIN_U_df
= (0x5 << 23) | OPC_MSA_3R_0E
,
1265 OPC_CLE_U_df
= (0x5 << 23) | OPC_MSA_3R_0F
,
1266 OPC_AVE_U_df
= (0x5 << 23) | OPC_MSA_3R_10
,
1267 OPC_ASUB_U_df
= (0x5 << 23) | OPC_MSA_3R_11
,
1268 OPC_DIV_U_df
= (0x5 << 23) | OPC_MSA_3R_12
,
1269 OPC_DPSUB_U_df
= (0x5 << 23) | OPC_MSA_3R_13
,
1270 OPC_ILVR_df
= (0x5 << 23) | OPC_MSA_3R_14
,
1271 OPC_HADD_U_df
= (0x5 << 23) | OPC_MSA_3R_15
,
1272 OPC_BINSL_df
= (0x6 << 23) | OPC_MSA_3R_0D
,
1273 OPC_MAX_A_df
= (0x6 << 23) | OPC_MSA_3R_0E
,
1274 OPC_AVER_S_df
= (0x6 << 23) | OPC_MSA_3R_10
,
1275 OPC_MOD_S_df
= (0x6 << 23) | OPC_MSA_3R_12
,
1276 OPC_ILVEV_df
= (0x6 << 23) | OPC_MSA_3R_14
,
1277 OPC_HSUB_S_df
= (0x6 << 23) | OPC_MSA_3R_15
,
1278 OPC_BINSR_df
= (0x7 << 23) | OPC_MSA_3R_0D
,
1279 OPC_MIN_A_df
= (0x7 << 23) | OPC_MSA_3R_0E
,
1280 OPC_AVER_U_df
= (0x7 << 23) | OPC_MSA_3R_10
,
1281 OPC_MOD_U_df
= (0x7 << 23) | OPC_MSA_3R_12
,
1282 OPC_ILVOD_df
= (0x7 << 23) | OPC_MSA_3R_14
,
1283 OPC_HSUB_U_df
= (0x7 << 23) | OPC_MSA_3R_15
,
1285 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1286 OPC_SLDI_df
= (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1287 OPC_CTCMSA
= (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1288 OPC_SPLATI_df
= (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1289 OPC_CFCMSA
= (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1290 OPC_COPY_S_df
= (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1291 OPC_MOVE_V
= (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1292 OPC_COPY_U_df
= (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1293 OPC_INSERT_df
= (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1294 OPC_INSVE_df
= (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1296 /* 3RF instruction _df(bit 21) = _w, _d */
1297 OPC_FCAF_df
= (0x0 << 22) | OPC_MSA_3RF_1A
,
1298 OPC_FADD_df
= (0x0 << 22) | OPC_MSA_3RF_1B
,
1299 OPC_FCUN_df
= (0x1 << 22) | OPC_MSA_3RF_1A
,
1300 OPC_FSUB_df
= (0x1 << 22) | OPC_MSA_3RF_1B
,
1301 OPC_FCOR_df
= (0x1 << 22) | OPC_MSA_3RF_1C
,
1302 OPC_FCEQ_df
= (0x2 << 22) | OPC_MSA_3RF_1A
,
1303 OPC_FMUL_df
= (0x2 << 22) | OPC_MSA_3RF_1B
,
1304 OPC_FCUNE_df
= (0x2 << 22) | OPC_MSA_3RF_1C
,
1305 OPC_FCUEQ_df
= (0x3 << 22) | OPC_MSA_3RF_1A
,
1306 OPC_FDIV_df
= (0x3 << 22) | OPC_MSA_3RF_1B
,
1307 OPC_FCNE_df
= (0x3 << 22) | OPC_MSA_3RF_1C
,
1308 OPC_FCLT_df
= (0x4 << 22) | OPC_MSA_3RF_1A
,
1309 OPC_FMADD_df
= (0x4 << 22) | OPC_MSA_3RF_1B
,
1310 OPC_MUL_Q_df
= (0x4 << 22) | OPC_MSA_3RF_1C
,
1311 OPC_FCULT_df
= (0x5 << 22) | OPC_MSA_3RF_1A
,
1312 OPC_FMSUB_df
= (0x5 << 22) | OPC_MSA_3RF_1B
,
1313 OPC_MADD_Q_df
= (0x5 << 22) | OPC_MSA_3RF_1C
,
1314 OPC_FCLE_df
= (0x6 << 22) | OPC_MSA_3RF_1A
,
1315 OPC_MSUB_Q_df
= (0x6 << 22) | OPC_MSA_3RF_1C
,
1316 OPC_FCULE_df
= (0x7 << 22) | OPC_MSA_3RF_1A
,
1317 OPC_FEXP2_df
= (0x7 << 22) | OPC_MSA_3RF_1B
,
1318 OPC_FSAF_df
= (0x8 << 22) | OPC_MSA_3RF_1A
,
1319 OPC_FEXDO_df
= (0x8 << 22) | OPC_MSA_3RF_1B
,
1320 OPC_FSUN_df
= (0x9 << 22) | OPC_MSA_3RF_1A
,
1321 OPC_FSOR_df
= (0x9 << 22) | OPC_MSA_3RF_1C
,
1322 OPC_FSEQ_df
= (0xA << 22) | OPC_MSA_3RF_1A
,
1323 OPC_FTQ_df
= (0xA << 22) | OPC_MSA_3RF_1B
,
1324 OPC_FSUNE_df
= (0xA << 22) | OPC_MSA_3RF_1C
,
1325 OPC_FSUEQ_df
= (0xB << 22) | OPC_MSA_3RF_1A
,
1326 OPC_FSNE_df
= (0xB << 22) | OPC_MSA_3RF_1C
,
1327 OPC_FSLT_df
= (0xC << 22) | OPC_MSA_3RF_1A
,
1328 OPC_FMIN_df
= (0xC << 22) | OPC_MSA_3RF_1B
,
1329 OPC_MULR_Q_df
= (0xC << 22) | OPC_MSA_3RF_1C
,
1330 OPC_FSULT_df
= (0xD << 22) | OPC_MSA_3RF_1A
,
1331 OPC_FMIN_A_df
= (0xD << 22) | OPC_MSA_3RF_1B
,
1332 OPC_MADDR_Q_df
= (0xD << 22) | OPC_MSA_3RF_1C
,
1333 OPC_FSLE_df
= (0xE << 22) | OPC_MSA_3RF_1A
,
1334 OPC_FMAX_df
= (0xE << 22) | OPC_MSA_3RF_1B
,
1335 OPC_MSUBR_Q_df
= (0xE << 22) | OPC_MSA_3RF_1C
,
1336 OPC_FSULE_df
= (0xF << 22) | OPC_MSA_3RF_1A
,
1337 OPC_FMAX_A_df
= (0xF << 22) | OPC_MSA_3RF_1B
,
1339 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1340 OPC_SLLI_df
= (0x0 << 23) | OPC_MSA_BIT_09
,
1341 OPC_SAT_S_df
= (0x0 << 23) | OPC_MSA_BIT_0A
,
1342 OPC_SRAI_df
= (0x1 << 23) | OPC_MSA_BIT_09
,
1343 OPC_SAT_U_df
= (0x1 << 23) | OPC_MSA_BIT_0A
,
1344 OPC_SRLI_df
= (0x2 << 23) | OPC_MSA_BIT_09
,
1345 OPC_SRARI_df
= (0x2 << 23) | OPC_MSA_BIT_0A
,
1346 OPC_BCLRI_df
= (0x3 << 23) | OPC_MSA_BIT_09
,
1347 OPC_SRLRI_df
= (0x3 << 23) | OPC_MSA_BIT_0A
,
1348 OPC_BSETI_df
= (0x4 << 23) | OPC_MSA_BIT_09
,
1349 OPC_BNEGI_df
= (0x5 << 23) | OPC_MSA_BIT_09
,
1350 OPC_BINSLI_df
= (0x6 << 23) | OPC_MSA_BIT_09
,
1351 OPC_BINSRI_df
= (0x7 << 23) | OPC_MSA_BIT_09
,
1354 /* global register indices */
1355 static TCGv_ptr cpu_env
;
1356 static TCGv cpu_gpr
[32], cpu_PC
;
1357 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1358 static TCGv cpu_dspctrl
, btarget
, bcond
;
1359 static TCGv_i32 hflags
;
1360 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1361 static TCGv_i64 fpu_f64
[32];
1362 static TCGv_i64 msa_wr_d
[64];
1364 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1365 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1367 #include "exec/gen-icount.h"
1369 #define gen_helper_0e0i(name, arg) do { \
1370 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1371 gen_helper_##name(cpu_env, helper_tmp); \
1372 tcg_temp_free_i32(helper_tmp); \
1375 #define gen_helper_0e1i(name, arg1, arg2) do { \
1376 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1377 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1378 tcg_temp_free_i32(helper_tmp); \
1381 #define gen_helper_1e0i(name, ret, arg1) do { \
1382 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1383 gen_helper_##name(ret, cpu_env, helper_tmp); \
1384 tcg_temp_free_i32(helper_tmp); \
1387 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1388 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1389 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1390 tcg_temp_free_i32(helper_tmp); \
1393 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1394 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1395 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1396 tcg_temp_free_i32(helper_tmp); \
1399 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1400 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1401 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1402 tcg_temp_free_i32(helper_tmp); \
1405 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1406 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1407 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1408 tcg_temp_free_i32(helper_tmp); \
1411 typedef struct DisasContext
{
1412 struct TranslationBlock
*tb
;
1413 target_ulong pc
, saved_pc
;
1415 int singlestep_enabled
;
1417 int32_t CP0_Config1
;
1418 /* Routine used to access memory */
1420 TCGMemOp default_tcg_memop_mask
;
1421 uint32_t hflags
, saved_hflags
;
1423 target_ulong btarget
;
1432 int CP0_LLAddr_shift
;
1437 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1438 * exception condition */
1439 BS_STOP
= 1, /* We want to stop translation for any reason */
1440 BS_BRANCH
= 2, /* We reached a branch condition */
1441 BS_EXCP
= 3, /* We reached an exception condition */
1444 static const char * const regnames
[] = {
1445 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1446 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1447 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1448 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1451 static const char * const regnames_HI
[] = {
1452 "HI0", "HI1", "HI2", "HI3",
1455 static const char * const regnames_LO
[] = {
1456 "LO0", "LO1", "LO2", "LO3",
1459 static const char * const fregnames
[] = {
1460 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1461 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1462 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1463 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1466 static const char * const msaregnames
[] = {
1467 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1468 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1469 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1470 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1471 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1472 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1473 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1474 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1475 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1476 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1477 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1478 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1479 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1480 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1481 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1482 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1485 #define MIPS_DEBUG(fmt, ...) \
1487 if (MIPS_DEBUG_DISAS) { \
1488 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1489 TARGET_FMT_lx ": %08x " fmt "\n", \
1490 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1494 #define LOG_DISAS(...) \
1496 if (MIPS_DEBUG_DISAS) { \
1497 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1501 #define MIPS_INVAL(op) \
1502 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1503 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1505 /* General purpose registers moves. */
1506 static inline void gen_load_gpr (TCGv t
, int reg
)
1509 tcg_gen_movi_tl(t
, 0);
1511 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1514 static inline void gen_store_gpr (TCGv t
, int reg
)
1517 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1520 /* Moves to/from shadow registers. */
1521 static inline void gen_load_srsgpr (int from
, int to
)
1523 TCGv t0
= tcg_temp_new();
1526 tcg_gen_movi_tl(t0
, 0);
1528 TCGv_i32 t2
= tcg_temp_new_i32();
1529 TCGv_ptr addr
= tcg_temp_new_ptr();
1531 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1532 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1533 tcg_gen_andi_i32(t2
, t2
, 0xf);
1534 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1535 tcg_gen_ext_i32_ptr(addr
, t2
);
1536 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1538 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1539 tcg_temp_free_ptr(addr
);
1540 tcg_temp_free_i32(t2
);
1542 gen_store_gpr(t0
, to
);
1546 static inline void gen_store_srsgpr (int from
, int to
)
1549 TCGv t0
= tcg_temp_new();
1550 TCGv_i32 t2
= tcg_temp_new_i32();
1551 TCGv_ptr addr
= tcg_temp_new_ptr();
1553 gen_load_gpr(t0
, from
);
1554 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1555 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1556 tcg_gen_andi_i32(t2
, t2
, 0xf);
1557 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1558 tcg_gen_ext_i32_ptr(addr
, t2
);
1559 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1561 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1562 tcg_temp_free_ptr(addr
);
1563 tcg_temp_free_i32(t2
);
1569 static inline void gen_save_pc(target_ulong pc
)
1571 tcg_gen_movi_tl(cpu_PC
, pc
);
1574 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
1576 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1577 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1578 gen_save_pc(ctx
->pc
);
1579 ctx
->saved_pc
= ctx
->pc
;
1581 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1582 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1583 ctx
->saved_hflags
= ctx
->hflags
;
1584 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1590 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1596 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
1598 ctx
->saved_hflags
= ctx
->hflags
;
1599 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1605 ctx
->btarget
= env
->btarget
;
1610 static inline void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
1612 TCGv_i32 texcp
= tcg_const_i32(excp
);
1613 TCGv_i32 terr
= tcg_const_i32(err
);
1614 save_cpu_state(ctx
, 1);
1615 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1616 tcg_temp_free_i32(terr
);
1617 tcg_temp_free_i32(texcp
);
1620 static inline void generate_exception(DisasContext
*ctx
, int excp
)
1622 save_cpu_state(ctx
, 1);
1623 gen_helper_0e0i(raise_exception
, excp
);
1626 /* Floating point register moves. */
1627 static void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1629 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1630 generate_exception(ctx
, EXCP_RI
);
1632 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1635 static void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1638 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1639 generate_exception(ctx
, EXCP_RI
);
1641 t64
= tcg_temp_new_i64();
1642 tcg_gen_extu_i32_i64(t64
, t
);
1643 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1644 tcg_temp_free_i64(t64
);
1647 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1649 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1650 TCGv_i64 t64
= tcg_temp_new_i64();
1651 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1652 tcg_gen_trunc_i64_i32(t
, t64
);
1653 tcg_temp_free_i64(t64
);
1655 gen_load_fpr32(ctx
, t
, reg
| 1);
1659 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1661 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1662 TCGv_i64 t64
= tcg_temp_new_i64();
1663 tcg_gen_extu_i32_i64(t64
, t
);
1664 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1665 tcg_temp_free_i64(t64
);
1667 gen_store_fpr32(ctx
, t
, reg
| 1);
1671 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1673 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1674 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1676 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1680 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1682 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1683 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1686 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1687 t0
= tcg_temp_new_i64();
1688 tcg_gen_shri_i64(t0
, t
, 32);
1689 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1690 tcg_temp_free_i64(t0
);
1694 static inline int get_fp_bit (int cc
)
1702 /* Addresses computation */
1703 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1705 tcg_gen_add_tl(ret
, arg0
, arg1
);
1707 #if defined(TARGET_MIPS64)
1708 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1709 tcg_gen_ext32s_i64(ret
, ret
);
1714 /* Addresses computation (translation time) */
1715 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1718 target_long sum
= base
+ offset
;
1720 #if defined(TARGET_MIPS64)
1721 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1728 static inline void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
1730 #if defined(TARGET_MIPS64)
1731 tcg_gen_ext32s_tl(ret
, arg
);
1733 tcg_gen_trunc_i64_tl(ret
, arg
);
1737 static inline void check_cp0_enabled(DisasContext
*ctx
)
1739 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1740 generate_exception_err(ctx
, EXCP_CpU
, 0);
1743 static inline void check_cp1_enabled(DisasContext
*ctx
)
1745 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1746 generate_exception_err(ctx
, EXCP_CpU
, 1);
1749 /* Verify that the processor is running with COP1X instructions enabled.
1750 This is associated with the nabla symbol in the MIPS32 and MIPS64
1753 static inline void check_cop1x(DisasContext
*ctx
)
1755 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1756 generate_exception(ctx
, EXCP_RI
);
1759 /* Verify that the processor is running with 64-bit floating-point
1760 operations enabled. */
1762 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1764 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1765 generate_exception(ctx
, EXCP_RI
);
1769 * Verify if floating point register is valid; an operation is not defined
1770 * if bit 0 of any register specification is set and the FR bit in the
1771 * Status register equals zero, since the register numbers specify an
1772 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1773 * in the Status register equals one, both even and odd register numbers
1774 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1776 * Multiple 64 bit wide registers can be checked by calling
1777 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1779 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1781 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1782 generate_exception(ctx
, EXCP_RI
);
1785 /* Verify that the processor is running with DSP instructions enabled.
1786 This is enabled by CP0 Status register MX(24) bit.
1789 static inline void check_dsp(DisasContext
*ctx
)
1791 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1792 if (ctx
->insn_flags
& ASE_DSP
) {
1793 generate_exception(ctx
, EXCP_DSPDIS
);
1795 generate_exception(ctx
, EXCP_RI
);
1800 static inline void check_dspr2(DisasContext
*ctx
)
1802 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1803 if (ctx
->insn_flags
& ASE_DSP
) {
1804 generate_exception(ctx
, EXCP_DSPDIS
);
1806 generate_exception(ctx
, EXCP_RI
);
1811 /* This code generates a "reserved instruction" exception if the
1812 CPU does not support the instruction set corresponding to flags. */
1813 static inline void check_insn(DisasContext
*ctx
, int flags
)
1815 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1816 generate_exception(ctx
, EXCP_RI
);
1820 /* This code generates a "reserved instruction" exception if the
1821 CPU has corresponding flag set which indicates that the instruction
1822 has been removed. */
1823 static inline void check_insn_opc_removed(DisasContext
*ctx
, int flags
)
1825 if (unlikely(ctx
->insn_flags
& flags
)) {
1826 generate_exception(ctx
, EXCP_RI
);
1830 /* This code generates a "reserved instruction" exception if the
1831 CPU does not support 64-bit paired-single (PS) floating point data type */
1832 static inline void check_ps(DisasContext
*ctx
)
1834 if (unlikely(!ctx
->ps
)) {
1835 generate_exception(ctx
, EXCP_RI
);
1837 check_cp1_64bitmode(ctx
);
1840 #ifdef TARGET_MIPS64
1841 /* This code generates a "reserved instruction" exception if 64-bit
1842 instructions are not enabled. */
1843 static inline void check_mips_64(DisasContext
*ctx
)
1845 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1846 generate_exception(ctx
, EXCP_RI
);
1850 #ifndef CONFIG_USER_ONLY
1851 static inline void check_mvh(DisasContext
*ctx
)
1853 if (unlikely(!ctx
->mvh
)) {
1854 generate_exception(ctx
, EXCP_RI
);
1859 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1860 calling interface for 32 and 64-bit FPRs. No sense in changing
1861 all callers for gen_load_fpr32 when we need the CTX parameter for
1863 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1864 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1865 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1866 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1867 int ft, int fs, int cc) \
1869 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1870 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1879 check_cp1_registers(ctx, fs | ft); \
1887 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1888 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1890 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1891 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1892 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1893 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1894 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1895 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1896 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1897 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1898 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1899 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1900 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1901 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1902 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1903 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1904 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1905 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1908 tcg_temp_free_i##bits (fp0); \
1909 tcg_temp_free_i##bits (fp1); \
1912 FOP_CONDS(, 0, d
, FMT_D
, 64)
1913 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1914 FOP_CONDS(, 0, s
, FMT_S
, 32)
1915 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1916 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1917 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1920 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1921 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1922 int ft, int fs, int fd) \
1924 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1925 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1926 if (ifmt == FMT_D) { \
1927 check_cp1_registers(ctx, fs | ft | fd); \
1929 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1930 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1933 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1936 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1939 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1942 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1945 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1948 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1951 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1954 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1957 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1960 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1963 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1966 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1969 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1972 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1975 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1978 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1981 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1984 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1987 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1990 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1993 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1996 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2002 tcg_temp_free_i ## bits (fp0); \
2003 tcg_temp_free_i ## bits (fp1); \
2006 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
2007 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
2009 #undef gen_ldcmp_fpr32
2010 #undef gen_ldcmp_fpr64
2012 /* load/store instructions. */
2013 #ifdef CONFIG_USER_ONLY
2014 #define OP_LD_ATOMIC(insn,fname) \
2015 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2017 TCGv t0 = tcg_temp_new(); \
2018 tcg_gen_mov_tl(t0, arg1); \
2019 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2020 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2021 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2022 tcg_temp_free(t0); \
2025 #define OP_LD_ATOMIC(insn,fname) \
2026 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2028 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
2031 OP_LD_ATOMIC(ll
,ld32s
);
2032 #if defined(TARGET_MIPS64)
2033 OP_LD_ATOMIC(lld
,ld64
);
2037 #ifdef CONFIG_USER_ONLY
2038 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2039 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2041 TCGv t0 = tcg_temp_new(); \
2042 TCGLabel *l1 = gen_new_label(); \
2043 TCGLabel *l2 = gen_new_label(); \
2045 tcg_gen_andi_tl(t0, arg2, almask); \
2046 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2047 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2048 generate_exception(ctx, EXCP_AdES); \
2049 gen_set_label(l1); \
2050 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2051 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2052 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2053 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2054 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2055 gen_helper_0e0i(raise_exception, EXCP_SC); \
2056 gen_set_label(l2); \
2057 tcg_gen_movi_tl(t0, 0); \
2058 gen_store_gpr(t0, rt); \
2059 tcg_temp_free(t0); \
2062 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2063 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2065 TCGv t0 = tcg_temp_new(); \
2066 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2067 gen_store_gpr(t0, rt); \
2068 tcg_temp_free(t0); \
2071 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
2072 #if defined(TARGET_MIPS64)
2073 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
2077 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
2078 int base
, int16_t offset
)
2081 tcg_gen_movi_tl(addr
, offset
);
2082 } else if (offset
== 0) {
2083 gen_load_gpr(addr
, base
);
2085 tcg_gen_movi_tl(addr
, offset
);
2086 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2090 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
2092 target_ulong pc
= ctx
->pc
;
2094 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2095 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2100 pc
&= ~(target_ulong
)3;
2105 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2106 int rt
, int base
, int16_t offset
)
2108 const char *opn
= "ld";
2111 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
2112 /* Loongson CPU uses a load to zero register for prefetch.
2113 We emulate it as a NOP. On other CPU we must perform the
2114 actual memory access. */
2119 t0
= tcg_temp_new();
2120 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2123 #if defined(TARGET_MIPS64)
2125 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2126 ctx
->default_tcg_memop_mask
);
2127 gen_store_gpr(t0
, rt
);
2131 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2132 ctx
->default_tcg_memop_mask
);
2133 gen_store_gpr(t0
, rt
);
2138 save_cpu_state(ctx
, 1);
2139 op_ld_lld(t0
, t0
, ctx
);
2140 gen_store_gpr(t0
, rt
);
2144 t1
= tcg_temp_new();
2145 /* Do a byte access to possibly trigger a page
2146 fault with the unaligned address. */
2147 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
2148 tcg_gen_andi_tl(t1
, t0
, 7);
2149 #ifndef TARGET_WORDS_BIGENDIAN
2150 tcg_gen_xori_tl(t1
, t1
, 7);
2152 tcg_gen_shli_tl(t1
, t1
, 3);
2153 tcg_gen_andi_tl(t0
, t0
, ~7);
2154 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2155 tcg_gen_shl_tl(t0
, t0
, t1
);
2156 tcg_gen_xori_tl(t1
, t1
, 63);
2157 t2
= tcg_const_tl(0x7fffffffffffffffull
);
2158 tcg_gen_shr_tl(t2
, t2
, t1
);
2159 gen_load_gpr(t1
, rt
);
2160 tcg_gen_and_tl(t1
, t1
, t2
);
2162 tcg_gen_or_tl(t0
, t0
, t1
);
2164 gen_store_gpr(t0
, rt
);
2168 t1
= tcg_temp_new();
2169 /* Do a byte access to possibly trigger a page
2170 fault with the unaligned address. */
2171 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
2172 tcg_gen_andi_tl(t1
, t0
, 7);
2173 #ifdef TARGET_WORDS_BIGENDIAN
2174 tcg_gen_xori_tl(t1
, t1
, 7);
2176 tcg_gen_shli_tl(t1
, t1
, 3);
2177 tcg_gen_andi_tl(t0
, t0
, ~7);
2178 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2179 tcg_gen_shr_tl(t0
, t0
, t1
);
2180 tcg_gen_xori_tl(t1
, t1
, 63);
2181 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2182 tcg_gen_shl_tl(t2
, t2
, t1
);
2183 gen_load_gpr(t1
, rt
);
2184 tcg_gen_and_tl(t1
, t1
, t2
);
2186 tcg_gen_or_tl(t0
, t0
, t1
);
2188 gen_store_gpr(t0
, rt
);
2192 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2193 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2195 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2196 gen_store_gpr(t0
, rt
);
2201 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2202 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2204 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
2205 gen_store_gpr(t0
, rt
);
2209 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
2210 ctx
->default_tcg_memop_mask
);
2211 gen_store_gpr(t0
, rt
);
2215 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
2216 ctx
->default_tcg_memop_mask
);
2217 gen_store_gpr(t0
, rt
);
2221 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
|
2222 ctx
->default_tcg_memop_mask
);
2223 gen_store_gpr(t0
, rt
);
2227 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
2228 gen_store_gpr(t0
, rt
);
2232 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
2233 gen_store_gpr(t0
, rt
);
2237 t1
= tcg_temp_new();
2238 /* Do a byte access to possibly trigger a page
2239 fault with the unaligned address. */
2240 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
2241 tcg_gen_andi_tl(t1
, t0
, 3);
2242 #ifndef TARGET_WORDS_BIGENDIAN
2243 tcg_gen_xori_tl(t1
, t1
, 3);
2245 tcg_gen_shli_tl(t1
, t1
, 3);
2246 tcg_gen_andi_tl(t0
, t0
, ~3);
2247 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2248 tcg_gen_shl_tl(t0
, t0
, t1
);
2249 tcg_gen_xori_tl(t1
, t1
, 31);
2250 t2
= tcg_const_tl(0x7fffffffull
);
2251 tcg_gen_shr_tl(t2
, t2
, t1
);
2252 gen_load_gpr(t1
, rt
);
2253 tcg_gen_and_tl(t1
, t1
, t2
);
2255 tcg_gen_or_tl(t0
, t0
, t1
);
2257 tcg_gen_ext32s_tl(t0
, t0
);
2258 gen_store_gpr(t0
, rt
);
2262 t1
= tcg_temp_new();
2263 /* Do a byte access to possibly trigger a page
2264 fault with the unaligned address. */
2265 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
2266 tcg_gen_andi_tl(t1
, t0
, 3);
2267 #ifdef TARGET_WORDS_BIGENDIAN
2268 tcg_gen_xori_tl(t1
, t1
, 3);
2270 tcg_gen_shli_tl(t1
, t1
, 3);
2271 tcg_gen_andi_tl(t0
, t0
, ~3);
2272 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2273 tcg_gen_shr_tl(t0
, t0
, t1
);
2274 tcg_gen_xori_tl(t1
, t1
, 31);
2275 t2
= tcg_const_tl(0xfffffffeull
);
2276 tcg_gen_shl_tl(t2
, t2
, t1
);
2277 gen_load_gpr(t1
, rt
);
2278 tcg_gen_and_tl(t1
, t1
, t2
);
2280 tcg_gen_or_tl(t0
, t0
, t1
);
2282 tcg_gen_ext32s_tl(t0
, t0
);
2283 gen_store_gpr(t0
, rt
);
2288 save_cpu_state(ctx
, 1);
2289 op_ld_ll(t0
, t0
, ctx
);
2290 gen_store_gpr(t0
, rt
);
2294 (void)opn
; /* avoid a compiler warning */
2295 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2300 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
2301 int base
, int16_t offset
)
2303 const char *opn
= "st";
2304 TCGv t0
= tcg_temp_new();
2305 TCGv t1
= tcg_temp_new();
2307 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2308 gen_load_gpr(t1
, rt
);
2310 #if defined(TARGET_MIPS64)
2312 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
2313 ctx
->default_tcg_memop_mask
);
2317 save_cpu_state(ctx
, 1);
2318 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
2322 save_cpu_state(ctx
, 1);
2323 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
2328 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
2329 ctx
->default_tcg_memop_mask
);
2333 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
2334 ctx
->default_tcg_memop_mask
);
2338 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
2342 save_cpu_state(ctx
, 1);
2343 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
2347 save_cpu_state(ctx
, 1);
2348 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
2352 (void)opn
; /* avoid a compiler warning */
2353 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2359 /* Store conditional */
2360 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
2361 int base
, int16_t offset
)
2363 const char *opn
= "st_cond";
2366 #ifdef CONFIG_USER_ONLY
2367 t0
= tcg_temp_local_new();
2368 t1
= tcg_temp_local_new();
2370 t0
= tcg_temp_new();
2371 t1
= tcg_temp_new();
2373 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2374 gen_load_gpr(t1
, rt
);
2376 #if defined(TARGET_MIPS64)
2379 save_cpu_state(ctx
, 1);
2380 op_st_scd(t1
, t0
, rt
, ctx
);
2386 save_cpu_state(ctx
, 1);
2387 op_st_sc(t1
, t0
, rt
, ctx
);
2391 (void)opn
; /* avoid a compiler warning */
2392 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2397 /* Load and store */
2398 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
2399 int base
, int16_t offset
)
2401 const char *opn
= "flt_ldst";
2402 TCGv t0
= tcg_temp_new();
2404 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2405 /* Don't do NOP if destination is zero: we must perform the actual
2410 TCGv_i32 fp0
= tcg_temp_new_i32();
2411 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
2412 ctx
->default_tcg_memop_mask
);
2413 gen_store_fpr32(ctx
, fp0
, ft
);
2414 tcg_temp_free_i32(fp0
);
2420 TCGv_i32 fp0
= tcg_temp_new_i32();
2421 gen_load_fpr32(ctx
, fp0
, ft
);
2422 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2423 ctx
->default_tcg_memop_mask
);
2424 tcg_temp_free_i32(fp0
);
2430 TCGv_i64 fp0
= tcg_temp_new_i64();
2431 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2432 ctx
->default_tcg_memop_mask
);
2433 gen_store_fpr64(ctx
, fp0
, ft
);
2434 tcg_temp_free_i64(fp0
);
2440 TCGv_i64 fp0
= tcg_temp_new_i64();
2441 gen_load_fpr64(ctx
, fp0
, ft
);
2442 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2443 ctx
->default_tcg_memop_mask
);
2444 tcg_temp_free_i64(fp0
);
2450 generate_exception(ctx
, EXCP_RI
);
2453 (void)opn
; /* avoid a compiler warning */
2454 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
2459 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2460 int rs
, int16_t imm
)
2462 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2463 check_cp1_enabled(ctx
);
2467 check_insn(ctx
, ISA_MIPS2
);
2470 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
2473 generate_exception_err(ctx
, EXCP_CpU
, 1);
2477 /* Arithmetic with immediate operand */
2478 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2479 int rt
, int rs
, int16_t imm
)
2481 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2482 const char *opn
= "imm arith";
2484 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2485 /* If no destination, treat it as a NOP.
2486 For addi, we must generate the overflow exception when needed. */
2493 TCGv t0
= tcg_temp_local_new();
2494 TCGv t1
= tcg_temp_new();
2495 TCGv t2
= tcg_temp_new();
2496 TCGLabel
*l1
= gen_new_label();
2498 gen_load_gpr(t1
, rs
);
2499 tcg_gen_addi_tl(t0
, t1
, uimm
);
2500 tcg_gen_ext32s_tl(t0
, t0
);
2502 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2503 tcg_gen_xori_tl(t2
, t0
, uimm
);
2504 tcg_gen_and_tl(t1
, t1
, t2
);
2506 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2508 /* operands of same sign, result different sign */
2509 generate_exception(ctx
, EXCP_OVERFLOW
);
2511 tcg_gen_ext32s_tl(t0
, t0
);
2512 gen_store_gpr(t0
, rt
);
2519 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2520 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2522 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2526 #if defined(TARGET_MIPS64)
2529 TCGv t0
= tcg_temp_local_new();
2530 TCGv t1
= tcg_temp_new();
2531 TCGv t2
= tcg_temp_new();
2532 TCGLabel
*l1
= gen_new_label();
2534 gen_load_gpr(t1
, rs
);
2535 tcg_gen_addi_tl(t0
, t1
, uimm
);
2537 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2538 tcg_gen_xori_tl(t2
, t0
, uimm
);
2539 tcg_gen_and_tl(t1
, t1
, t2
);
2541 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2543 /* operands of same sign, result different sign */
2544 generate_exception(ctx
, EXCP_OVERFLOW
);
2546 gen_store_gpr(t0
, rt
);
2553 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2555 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2561 (void)opn
; /* avoid a compiler warning */
2562 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2565 /* Logic with immediate operand */
2566 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2567 int rt
, int rs
, int16_t imm
)
2572 /* If no destination, treat it as a NOP. */
2576 uimm
= (uint16_t)imm
;
2579 if (likely(rs
!= 0))
2580 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2582 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2583 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2584 regnames
[rs
], uimm
);
2588 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2590 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2591 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2592 regnames
[rs
], uimm
);
2595 if (likely(rs
!= 0))
2596 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2598 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2599 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2600 regnames
[rs
], uimm
);
2603 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
2605 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2606 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2607 MIPS_DEBUG("aui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
2609 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2610 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2615 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2620 /* Set on less than with immediate operand */
2621 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2622 int rt
, int rs
, int16_t imm
)
2624 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2625 const char *opn
= "imm arith";
2629 /* If no destination, treat it as a NOP. */
2633 t0
= tcg_temp_new();
2634 gen_load_gpr(t0
, rs
);
2637 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2641 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2645 (void)opn
; /* avoid a compiler warning */
2646 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2650 /* Shifts with immediate operand */
2651 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2652 int rt
, int rs
, int16_t imm
)
2654 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2655 const char *opn
= "imm shift";
2659 /* If no destination, treat it as a NOP. */
2664 t0
= tcg_temp_new();
2665 gen_load_gpr(t0
, rs
);
2668 tcg_gen_shli_tl(t0
, t0
, uimm
);
2669 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2673 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2678 tcg_gen_ext32u_tl(t0
, t0
);
2679 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2681 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2687 TCGv_i32 t1
= tcg_temp_new_i32();
2689 tcg_gen_trunc_tl_i32(t1
, t0
);
2690 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2691 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2692 tcg_temp_free_i32(t1
);
2694 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2698 #if defined(TARGET_MIPS64)
2700 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2704 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2708 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2713 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2715 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2720 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2724 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2728 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2732 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2737 (void)opn
; /* avoid a compiler warning */
2738 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2743 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2744 int rd
, int rs
, int rt
)
2746 const char *opn
= "arith";
2748 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2749 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2750 /* If no destination, treat it as a NOP.
2751 For add & sub, we must generate the overflow exception when needed. */
2759 TCGv t0
= tcg_temp_local_new();
2760 TCGv t1
= tcg_temp_new();
2761 TCGv t2
= tcg_temp_new();
2762 TCGLabel
*l1
= gen_new_label();
2764 gen_load_gpr(t1
, rs
);
2765 gen_load_gpr(t2
, rt
);
2766 tcg_gen_add_tl(t0
, t1
, t2
);
2767 tcg_gen_ext32s_tl(t0
, t0
);
2768 tcg_gen_xor_tl(t1
, t1
, t2
);
2769 tcg_gen_xor_tl(t2
, t0
, t2
);
2770 tcg_gen_andc_tl(t1
, t2
, t1
);
2772 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2774 /* operands of same sign, result different sign */
2775 generate_exception(ctx
, EXCP_OVERFLOW
);
2777 gen_store_gpr(t0
, rd
);
2783 if (rs
!= 0 && rt
!= 0) {
2784 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2785 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2786 } else if (rs
== 0 && rt
!= 0) {
2787 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2788 } else if (rs
!= 0 && rt
== 0) {
2789 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2791 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2797 TCGv t0
= tcg_temp_local_new();
2798 TCGv t1
= tcg_temp_new();
2799 TCGv t2
= tcg_temp_new();
2800 TCGLabel
*l1
= gen_new_label();
2802 gen_load_gpr(t1
, rs
);
2803 gen_load_gpr(t2
, rt
);
2804 tcg_gen_sub_tl(t0
, t1
, t2
);
2805 tcg_gen_ext32s_tl(t0
, t0
);
2806 tcg_gen_xor_tl(t2
, t1
, t2
);
2807 tcg_gen_xor_tl(t1
, t0
, t1
);
2808 tcg_gen_and_tl(t1
, t1
, t2
);
2810 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2812 /* operands of different sign, first operand and result different sign */
2813 generate_exception(ctx
, EXCP_OVERFLOW
);
2815 gen_store_gpr(t0
, rd
);
2821 if (rs
!= 0 && rt
!= 0) {
2822 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2823 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2824 } else if (rs
== 0 && rt
!= 0) {
2825 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2826 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2827 } else if (rs
!= 0 && rt
== 0) {
2828 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2830 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2834 #if defined(TARGET_MIPS64)
2837 TCGv t0
= tcg_temp_local_new();
2838 TCGv t1
= tcg_temp_new();
2839 TCGv t2
= tcg_temp_new();
2840 TCGLabel
*l1
= gen_new_label();
2842 gen_load_gpr(t1
, rs
);
2843 gen_load_gpr(t2
, rt
);
2844 tcg_gen_add_tl(t0
, t1
, t2
);
2845 tcg_gen_xor_tl(t1
, t1
, t2
);
2846 tcg_gen_xor_tl(t2
, t0
, t2
);
2847 tcg_gen_andc_tl(t1
, t2
, t1
);
2849 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2851 /* operands of same sign, result different sign */
2852 generate_exception(ctx
, EXCP_OVERFLOW
);
2854 gen_store_gpr(t0
, rd
);
2860 if (rs
!= 0 && rt
!= 0) {
2861 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2862 } else if (rs
== 0 && rt
!= 0) {
2863 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2864 } else if (rs
!= 0 && rt
== 0) {
2865 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2867 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2873 TCGv t0
= tcg_temp_local_new();
2874 TCGv t1
= tcg_temp_new();
2875 TCGv t2
= tcg_temp_new();
2876 TCGLabel
*l1
= gen_new_label();
2878 gen_load_gpr(t1
, rs
);
2879 gen_load_gpr(t2
, rt
);
2880 tcg_gen_sub_tl(t0
, t1
, t2
);
2881 tcg_gen_xor_tl(t2
, t1
, t2
);
2882 tcg_gen_xor_tl(t1
, t0
, t1
);
2883 tcg_gen_and_tl(t1
, t1
, t2
);
2885 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2887 /* operands of different sign, first operand and result different sign */
2888 generate_exception(ctx
, EXCP_OVERFLOW
);
2890 gen_store_gpr(t0
, rd
);
2896 if (rs
!= 0 && rt
!= 0) {
2897 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2898 } else if (rs
== 0 && rt
!= 0) {
2899 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2900 } else if (rs
!= 0 && rt
== 0) {
2901 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2903 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2909 if (likely(rs
!= 0 && rt
!= 0)) {
2910 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2911 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2913 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2918 (void)opn
; /* avoid a compiler warning */
2919 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2922 /* Conditional move */
2923 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2924 int rd
, int rs
, int rt
)
2926 const char *opn
= "cond move";
2930 /* If no destination, treat it as a NOP. */
2935 t0
= tcg_temp_new();
2936 gen_load_gpr(t0
, rt
);
2937 t1
= tcg_const_tl(0);
2938 t2
= tcg_temp_new();
2939 gen_load_gpr(t2
, rs
);
2942 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2946 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2950 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2954 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2962 (void)opn
; /* avoid a compiler warning */
2963 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2967 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2968 int rd
, int rs
, int rt
)
2970 const char *opn
= "logic";
2973 /* If no destination, treat it as a NOP. */
2980 if (likely(rs
!= 0 && rt
!= 0)) {
2981 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2983 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2988 if (rs
!= 0 && rt
!= 0) {
2989 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2990 } else if (rs
== 0 && rt
!= 0) {
2991 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2992 } else if (rs
!= 0 && rt
== 0) {
2993 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2995 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
3000 if (likely(rs
!= 0 && rt
!= 0)) {
3001 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3002 } else if (rs
== 0 && rt
!= 0) {
3003 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3004 } else if (rs
!= 0 && rt
== 0) {
3005 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3007 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3012 if (likely(rs
!= 0 && rt
!= 0)) {
3013 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3014 } else if (rs
== 0 && rt
!= 0) {
3015 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3016 } else if (rs
!= 0 && rt
== 0) {
3017 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3019 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3024 (void)opn
; /* avoid a compiler warning */
3025 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3028 /* Set on lower than */
3029 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
3030 int rd
, int rs
, int rt
)
3032 const char *opn
= "slt";
3036 /* If no destination, treat it as a NOP. */
3041 t0
= tcg_temp_new();
3042 t1
= tcg_temp_new();
3043 gen_load_gpr(t0
, rs
);
3044 gen_load_gpr(t1
, rt
);
3047 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
3051 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
3055 (void)opn
; /* avoid a compiler warning */
3056 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3062 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
3063 int rd
, int rs
, int rt
)
3065 const char *opn
= "shifts";
3069 /* If no destination, treat it as a NOP.
3070 For add & sub, we must generate the overflow exception when needed. */
3075 t0
= tcg_temp_new();
3076 t1
= tcg_temp_new();
3077 gen_load_gpr(t0
, rs
);
3078 gen_load_gpr(t1
, rt
);
3081 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3082 tcg_gen_shl_tl(t0
, t1
, t0
);
3083 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3087 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3088 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3092 tcg_gen_ext32u_tl(t1
, t1
);
3093 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3094 tcg_gen_shr_tl(t0
, t1
, t0
);
3095 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3100 TCGv_i32 t2
= tcg_temp_new_i32();
3101 TCGv_i32 t3
= tcg_temp_new_i32();
3103 tcg_gen_trunc_tl_i32(t2
, t0
);
3104 tcg_gen_trunc_tl_i32(t3
, t1
);
3105 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3106 tcg_gen_rotr_i32(t2
, t3
, t2
);
3107 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3108 tcg_temp_free_i32(t2
);
3109 tcg_temp_free_i32(t3
);
3113 #if defined(TARGET_MIPS64)
3115 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3116 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3120 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3121 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3125 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3126 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3130 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3131 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3136 (void)opn
; /* avoid a compiler warning */
3137 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3142 /* Arithmetic on HI/LO registers */
3143 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3145 const char *opn
= "hilo";
3147 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3159 #if defined(TARGET_MIPS64)
3161 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3165 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3170 #if defined(TARGET_MIPS64)
3172 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3176 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3182 #if defined(TARGET_MIPS64)
3184 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3188 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3191 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3197 #if defined(TARGET_MIPS64)
3199 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3203 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3206 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3211 (void)opn
; /* avoid a compiler warning */
3212 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
3215 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3218 TCGv t0
= tcg_const_tl(addr
);
3219 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3220 gen_store_gpr(t0
, reg
);
3224 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
3230 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
3233 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3234 addr
= addr_add(ctx
, pc
, offset
);
3235 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3239 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3240 addr
= addr_add(ctx
, pc
, offset
);
3241 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3243 #if defined(TARGET_MIPS64)
3246 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3247 addr
= addr_add(ctx
, pc
, offset
);
3248 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3252 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
3255 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3256 addr
= addr_add(ctx
, pc
, offset
);
3257 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3262 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3263 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
3264 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3267 #if defined(TARGET_MIPS64)
3268 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3269 case R6_OPC_LDPC
+ (1 << 16):
3270 case R6_OPC_LDPC
+ (2 << 16):
3271 case R6_OPC_LDPC
+ (3 << 16):
3273 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3274 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
3275 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3279 MIPS_INVAL("OPC_PCREL");
3280 generate_exception(ctx
, EXCP_RI
);
3287 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3289 const char *opn
= "r6 mul/div";
3298 t0
= tcg_temp_new();
3299 t1
= tcg_temp_new();
3301 gen_load_gpr(t0
, rs
);
3302 gen_load_gpr(t1
, rt
);
3307 TCGv t2
= tcg_temp_new();
3308 TCGv t3
= tcg_temp_new();
3309 tcg_gen_ext32s_tl(t0
, t0
);
3310 tcg_gen_ext32s_tl(t1
, t1
);
3311 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3312 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3313 tcg_gen_and_tl(t2
, t2
, t3
);
3314 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3315 tcg_gen_or_tl(t2
, t2
, t3
);
3316 tcg_gen_movi_tl(t3
, 0);
3317 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3318 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3319 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3327 TCGv t2
= tcg_temp_new();
3328 TCGv t3
= tcg_temp_new();
3329 tcg_gen_ext32s_tl(t0
, t0
);
3330 tcg_gen_ext32s_tl(t1
, t1
);
3331 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3332 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3333 tcg_gen_and_tl(t2
, t2
, t3
);
3334 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3335 tcg_gen_or_tl(t2
, t2
, t3
);
3336 tcg_gen_movi_tl(t3
, 0);
3337 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3338 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3339 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3347 TCGv t2
= tcg_const_tl(0);
3348 TCGv t3
= tcg_const_tl(1);
3349 tcg_gen_ext32u_tl(t0
, t0
);
3350 tcg_gen_ext32u_tl(t1
, t1
);
3351 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3352 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3353 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3361 TCGv t2
= tcg_const_tl(0);
3362 TCGv t3
= tcg_const_tl(1);
3363 tcg_gen_ext32u_tl(t0
, t0
);
3364 tcg_gen_ext32u_tl(t1
, t1
);
3365 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3366 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3367 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3375 TCGv_i32 t2
= tcg_temp_new_i32();
3376 TCGv_i32 t3
= tcg_temp_new_i32();
3377 tcg_gen_trunc_tl_i32(t2
, t0
);
3378 tcg_gen_trunc_tl_i32(t3
, t1
);
3379 tcg_gen_mul_i32(t2
, t2
, t3
);
3380 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3381 tcg_temp_free_i32(t2
);
3382 tcg_temp_free_i32(t3
);
3388 TCGv_i32 t2
= tcg_temp_new_i32();
3389 TCGv_i32 t3
= tcg_temp_new_i32();
3390 tcg_gen_trunc_tl_i32(t2
, t0
);
3391 tcg_gen_trunc_tl_i32(t3
, t1
);
3392 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3393 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3394 tcg_temp_free_i32(t2
);
3395 tcg_temp_free_i32(t3
);
3401 TCGv_i32 t2
= tcg_temp_new_i32();
3402 TCGv_i32 t3
= tcg_temp_new_i32();
3403 tcg_gen_trunc_tl_i32(t2
, t0
);
3404 tcg_gen_trunc_tl_i32(t3
, t1
);
3405 tcg_gen_mul_i32(t2
, t2
, t3
);
3406 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3407 tcg_temp_free_i32(t2
);
3408 tcg_temp_free_i32(t3
);
3414 TCGv_i32 t2
= tcg_temp_new_i32();
3415 TCGv_i32 t3
= tcg_temp_new_i32();
3416 tcg_gen_trunc_tl_i32(t2
, t0
);
3417 tcg_gen_trunc_tl_i32(t3
, t1
);
3418 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3419 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3420 tcg_temp_free_i32(t2
);
3421 tcg_temp_free_i32(t3
);
3425 #if defined(TARGET_MIPS64)
3428 TCGv t2
= tcg_temp_new();
3429 TCGv t3
= tcg_temp_new();
3430 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3431 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3432 tcg_gen_and_tl(t2
, t2
, t3
);
3433 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3434 tcg_gen_or_tl(t2
, t2
, t3
);
3435 tcg_gen_movi_tl(t3
, 0);
3436 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3437 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3445 TCGv t2
= tcg_temp_new();
3446 TCGv t3
= tcg_temp_new();
3447 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3448 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3449 tcg_gen_and_tl(t2
, t2
, t3
);
3450 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3451 tcg_gen_or_tl(t2
, t2
, t3
);
3452 tcg_gen_movi_tl(t3
, 0);
3453 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3454 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3462 TCGv t2
= tcg_const_tl(0);
3463 TCGv t3
= tcg_const_tl(1);
3464 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3465 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3473 TCGv t2
= tcg_const_tl(0);
3474 TCGv t3
= tcg_const_tl(1);
3475 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3476 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3483 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3488 TCGv t2
= tcg_temp_new();
3489 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3495 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3500 TCGv t2
= tcg_temp_new();
3501 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3509 generate_exception(ctx
, EXCP_RI
);
3512 (void)opn
; /* avoid a compiler warning */
3513 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3519 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3520 int acc
, int rs
, int rt
)
3522 const char *opn
= "mul/div";
3525 t0
= tcg_temp_new();
3526 t1
= tcg_temp_new();
3528 gen_load_gpr(t0
, rs
);
3529 gen_load_gpr(t1
, rt
);
3538 TCGv t2
= tcg_temp_new();
3539 TCGv t3
= tcg_temp_new();
3540 tcg_gen_ext32s_tl(t0
, t0
);
3541 tcg_gen_ext32s_tl(t1
, t1
);
3542 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3543 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3544 tcg_gen_and_tl(t2
, t2
, t3
);
3545 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3546 tcg_gen_or_tl(t2
, t2
, t3
);
3547 tcg_gen_movi_tl(t3
, 0);
3548 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3549 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3550 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3551 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3552 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3560 TCGv t2
= tcg_const_tl(0);
3561 TCGv t3
= tcg_const_tl(1);
3562 tcg_gen_ext32u_tl(t0
, t0
);
3563 tcg_gen_ext32u_tl(t1
, t1
);
3564 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3565 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3566 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3567 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3568 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3576 TCGv_i32 t2
= tcg_temp_new_i32();
3577 TCGv_i32 t3
= tcg_temp_new_i32();
3578 tcg_gen_trunc_tl_i32(t2
, t0
);
3579 tcg_gen_trunc_tl_i32(t3
, t1
);
3580 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3581 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3582 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3583 tcg_temp_free_i32(t2
);
3584 tcg_temp_free_i32(t3
);
3590 TCGv_i32 t2
= tcg_temp_new_i32();
3591 TCGv_i32 t3
= tcg_temp_new_i32();
3592 tcg_gen_trunc_tl_i32(t2
, t0
);
3593 tcg_gen_trunc_tl_i32(t3
, t1
);
3594 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3595 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3596 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3597 tcg_temp_free_i32(t2
);
3598 tcg_temp_free_i32(t3
);
3602 #if defined(TARGET_MIPS64)
3605 TCGv t2
= tcg_temp_new();
3606 TCGv t3
= tcg_temp_new();
3607 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3608 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3609 tcg_gen_and_tl(t2
, t2
, t3
);
3610 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3611 tcg_gen_or_tl(t2
, t2
, t3
);
3612 tcg_gen_movi_tl(t3
, 0);
3613 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3614 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3615 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3623 TCGv t2
= tcg_const_tl(0);
3624 TCGv t3
= tcg_const_tl(1);
3625 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3626 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3627 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3634 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3638 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3644 TCGv_i64 t2
= tcg_temp_new_i64();
3645 TCGv_i64 t3
= tcg_temp_new_i64();
3647 tcg_gen_ext_tl_i64(t2
, t0
);
3648 tcg_gen_ext_tl_i64(t3
, t1
);
3649 tcg_gen_mul_i64(t2
, t2
, t3
);
3650 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3651 tcg_gen_add_i64(t2
, t2
, t3
);
3652 tcg_temp_free_i64(t3
);
3653 tcg_gen_trunc_i64_tl(t0
, t2
);
3654 tcg_gen_shri_i64(t2
, t2
, 32);
3655 tcg_gen_trunc_i64_tl(t1
, t2
);
3656 tcg_temp_free_i64(t2
);
3657 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3658 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3664 TCGv_i64 t2
= tcg_temp_new_i64();
3665 TCGv_i64 t3
= tcg_temp_new_i64();
3667 tcg_gen_ext32u_tl(t0
, t0
);
3668 tcg_gen_ext32u_tl(t1
, t1
);
3669 tcg_gen_extu_tl_i64(t2
, t0
);
3670 tcg_gen_extu_tl_i64(t3
, t1
);
3671 tcg_gen_mul_i64(t2
, t2
, t3
);
3672 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3673 tcg_gen_add_i64(t2
, t2
, t3
);
3674 tcg_temp_free_i64(t3
);
3675 tcg_gen_trunc_i64_tl(t0
, t2
);
3676 tcg_gen_shri_i64(t2
, t2
, 32);
3677 tcg_gen_trunc_i64_tl(t1
, t2
);
3678 tcg_temp_free_i64(t2
);
3679 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3680 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3686 TCGv_i64 t2
= tcg_temp_new_i64();
3687 TCGv_i64 t3
= tcg_temp_new_i64();
3689 tcg_gen_ext_tl_i64(t2
, t0
);
3690 tcg_gen_ext_tl_i64(t3
, t1
);
3691 tcg_gen_mul_i64(t2
, t2
, t3
);
3692 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3693 tcg_gen_sub_i64(t2
, t3
, t2
);
3694 tcg_temp_free_i64(t3
);
3695 tcg_gen_trunc_i64_tl(t0
, t2
);
3696 tcg_gen_shri_i64(t2
, t2
, 32);
3697 tcg_gen_trunc_i64_tl(t1
, t2
);
3698 tcg_temp_free_i64(t2
);
3699 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3700 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3706 TCGv_i64 t2
= tcg_temp_new_i64();
3707 TCGv_i64 t3
= tcg_temp_new_i64();
3709 tcg_gen_ext32u_tl(t0
, t0
);
3710 tcg_gen_ext32u_tl(t1
, t1
);
3711 tcg_gen_extu_tl_i64(t2
, t0
);
3712 tcg_gen_extu_tl_i64(t3
, t1
);
3713 tcg_gen_mul_i64(t2
, t2
, t3
);
3714 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3715 tcg_gen_sub_i64(t2
, t3
, t2
);
3716 tcg_temp_free_i64(t3
);
3717 tcg_gen_trunc_i64_tl(t0
, t2
);
3718 tcg_gen_shri_i64(t2
, t2
, 32);
3719 tcg_gen_trunc_i64_tl(t1
, t2
);
3720 tcg_temp_free_i64(t2
);
3721 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3722 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3728 generate_exception(ctx
, EXCP_RI
);
3731 (void)opn
; /* avoid a compiler warning */
3732 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3738 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
3739 int rd
, int rs
, int rt
)
3741 const char *opn
= "mul vr54xx";
3742 TCGv t0
= tcg_temp_new();
3743 TCGv t1
= tcg_temp_new();
3745 gen_load_gpr(t0
, rs
);
3746 gen_load_gpr(t1
, rt
);
3749 case OPC_VR54XX_MULS
:
3750 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3753 case OPC_VR54XX_MULSU
:
3754 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3757 case OPC_VR54XX_MACC
:
3758 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3761 case OPC_VR54XX_MACCU
:
3762 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3765 case OPC_VR54XX_MSAC
:
3766 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3769 case OPC_VR54XX_MSACU
:
3770 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3773 case OPC_VR54XX_MULHI
:
3774 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3777 case OPC_VR54XX_MULHIU
:
3778 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3781 case OPC_VR54XX_MULSHI
:
3782 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3785 case OPC_VR54XX_MULSHIU
:
3786 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3789 case OPC_VR54XX_MACCHI
:
3790 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3793 case OPC_VR54XX_MACCHIU
:
3794 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3797 case OPC_VR54XX_MSACHI
:
3798 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3801 case OPC_VR54XX_MSACHIU
:
3802 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3806 MIPS_INVAL("mul vr54xx");
3807 generate_exception(ctx
, EXCP_RI
);
3810 gen_store_gpr(t0
, rd
);
3811 (void)opn
; /* avoid a compiler warning */
3812 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3819 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
3822 const char *opn
= "CLx";
3830 t0
= tcg_temp_new();
3831 gen_load_gpr(t0
, rs
);
3835 gen_helper_clo(cpu_gpr
[rd
], t0
);
3840 gen_helper_clz(cpu_gpr
[rd
], t0
);
3843 #if defined(TARGET_MIPS64)
3846 gen_helper_dclo(cpu_gpr
[rd
], t0
);
3851 gen_helper_dclz(cpu_gpr
[rd
], t0
);
3856 (void)opn
; /* avoid a compiler warning */
3857 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3861 /* Godson integer instructions */
3862 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3863 int rd
, int rs
, int rt
)
3865 const char *opn
= "loongson";
3877 case OPC_MULTU_G_2E
:
3878 case OPC_MULTU_G_2F
:
3879 #if defined(TARGET_MIPS64)
3880 case OPC_DMULT_G_2E
:
3881 case OPC_DMULT_G_2F
:
3882 case OPC_DMULTU_G_2E
:
3883 case OPC_DMULTU_G_2F
:
3885 t0
= tcg_temp_new();
3886 t1
= tcg_temp_new();
3889 t0
= tcg_temp_local_new();
3890 t1
= tcg_temp_local_new();
3894 gen_load_gpr(t0
, rs
);
3895 gen_load_gpr(t1
, rt
);
3900 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3901 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3904 case OPC_MULTU_G_2E
:
3905 case OPC_MULTU_G_2F
:
3906 tcg_gen_ext32u_tl(t0
, t0
);
3907 tcg_gen_ext32u_tl(t1
, t1
);
3908 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3909 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3915 TCGLabel
*l1
= gen_new_label();
3916 TCGLabel
*l2
= gen_new_label();
3917 TCGLabel
*l3
= gen_new_label();
3918 tcg_gen_ext32s_tl(t0
, t0
);
3919 tcg_gen_ext32s_tl(t1
, t1
);
3920 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3921 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3924 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3925 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3926 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3929 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3930 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3938 TCGLabel
*l1
= gen_new_label();
3939 TCGLabel
*l2
= gen_new_label();
3940 tcg_gen_ext32u_tl(t0
, t0
);
3941 tcg_gen_ext32u_tl(t1
, t1
);
3942 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3943 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3946 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3947 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3955 TCGLabel
*l1
= gen_new_label();
3956 TCGLabel
*l2
= gen_new_label();
3957 TCGLabel
*l3
= gen_new_label();
3958 tcg_gen_ext32u_tl(t0
, t0
);
3959 tcg_gen_ext32u_tl(t1
, t1
);
3960 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3961 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3962 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3964 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3967 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3968 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3976 TCGLabel
*l1
= gen_new_label();
3977 TCGLabel
*l2
= gen_new_label();
3978 tcg_gen_ext32u_tl(t0
, t0
);
3979 tcg_gen_ext32u_tl(t1
, t1
);
3980 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3981 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3984 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3985 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3990 #if defined(TARGET_MIPS64)
3991 case OPC_DMULT_G_2E
:
3992 case OPC_DMULT_G_2F
:
3993 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3996 case OPC_DMULTU_G_2E
:
3997 case OPC_DMULTU_G_2F
:
3998 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4004 TCGLabel
*l1
= gen_new_label();
4005 TCGLabel
*l2
= gen_new_label();
4006 TCGLabel
*l3
= gen_new_label();
4007 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4008 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4011 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4012 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4013 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4016 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4021 case OPC_DDIVU_G_2E
:
4022 case OPC_DDIVU_G_2F
:
4024 TCGLabel
*l1
= gen_new_label();
4025 TCGLabel
*l2
= gen_new_label();
4026 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4027 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4030 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4038 TCGLabel
*l1
= gen_new_label();
4039 TCGLabel
*l2
= gen_new_label();
4040 TCGLabel
*l3
= gen_new_label();
4041 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4042 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4043 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4045 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4048 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4053 case OPC_DMODU_G_2E
:
4054 case OPC_DMODU_G_2F
:
4056 TCGLabel
*l1
= gen_new_label();
4057 TCGLabel
*l2
= gen_new_label();
4058 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4059 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4062 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4070 (void)opn
; /* avoid a compiler warning */
4071 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
4076 /* Loongson multimedia instructions */
4077 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4079 const char *opn
= "loongson_cp2";
4080 uint32_t opc
, shift_max
;
4083 opc
= MASK_LMI(ctx
->opcode
);
4089 t0
= tcg_temp_local_new_i64();
4090 t1
= tcg_temp_local_new_i64();
4093 t0
= tcg_temp_new_i64();
4094 t1
= tcg_temp_new_i64();
4098 gen_load_fpr64(ctx
, t0
, rs
);
4099 gen_load_fpr64(ctx
, t1
, rt
);
4101 #define LMI_HELPER(UP, LO) \
4102 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4103 #define LMI_HELPER_1(UP, LO) \
4104 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4105 #define LMI_DIRECT(UP, LO, OP) \
4106 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4109 LMI_HELPER(PADDSH
, paddsh
);
4110 LMI_HELPER(PADDUSH
, paddush
);
4111 LMI_HELPER(PADDH
, paddh
);
4112 LMI_HELPER(PADDW
, paddw
);
4113 LMI_HELPER(PADDSB
, paddsb
);
4114 LMI_HELPER(PADDUSB
, paddusb
);
4115 LMI_HELPER(PADDB
, paddb
);
4117 LMI_HELPER(PSUBSH
, psubsh
);
4118 LMI_HELPER(PSUBUSH
, psubush
);
4119 LMI_HELPER(PSUBH
, psubh
);
4120 LMI_HELPER(PSUBW
, psubw
);
4121 LMI_HELPER(PSUBSB
, psubsb
);
4122 LMI_HELPER(PSUBUSB
, psubusb
);
4123 LMI_HELPER(PSUBB
, psubb
);
4125 LMI_HELPER(PSHUFH
, pshufh
);
4126 LMI_HELPER(PACKSSWH
, packsswh
);
4127 LMI_HELPER(PACKSSHB
, packsshb
);
4128 LMI_HELPER(PACKUSHB
, packushb
);
4130 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
4131 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
4132 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
4133 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
4134 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
4135 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
4137 LMI_HELPER(PAVGH
, pavgh
);
4138 LMI_HELPER(PAVGB
, pavgb
);
4139 LMI_HELPER(PMAXSH
, pmaxsh
);
4140 LMI_HELPER(PMINSH
, pminsh
);
4141 LMI_HELPER(PMAXUB
, pmaxub
);
4142 LMI_HELPER(PMINUB
, pminub
);
4144 LMI_HELPER(PCMPEQW
, pcmpeqw
);
4145 LMI_HELPER(PCMPGTW
, pcmpgtw
);
4146 LMI_HELPER(PCMPEQH
, pcmpeqh
);
4147 LMI_HELPER(PCMPGTH
, pcmpgth
);
4148 LMI_HELPER(PCMPEQB
, pcmpeqb
);
4149 LMI_HELPER(PCMPGTB
, pcmpgtb
);
4151 LMI_HELPER(PSLLW
, psllw
);
4152 LMI_HELPER(PSLLH
, psllh
);
4153 LMI_HELPER(PSRLW
, psrlw
);
4154 LMI_HELPER(PSRLH
, psrlh
);
4155 LMI_HELPER(PSRAW
, psraw
);
4156 LMI_HELPER(PSRAH
, psrah
);
4158 LMI_HELPER(PMULLH
, pmullh
);
4159 LMI_HELPER(PMULHH
, pmulhh
);
4160 LMI_HELPER(PMULHUH
, pmulhuh
);
4161 LMI_HELPER(PMADDHW
, pmaddhw
);
4163 LMI_HELPER(PASUBUB
, pasubub
);
4164 LMI_HELPER_1(BIADD
, biadd
);
4165 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
4167 LMI_DIRECT(PADDD
, paddd
, add
);
4168 LMI_DIRECT(PSUBD
, psubd
, sub
);
4169 LMI_DIRECT(XOR_CP2
, xor, xor);
4170 LMI_DIRECT(NOR_CP2
, nor
, nor
);
4171 LMI_DIRECT(AND_CP2
, and, and);
4172 LMI_DIRECT(PANDN
, pandn
, andc
);
4173 LMI_DIRECT(OR
, or, or);
4176 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
4180 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
4184 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
4188 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
4193 tcg_gen_andi_i64(t1
, t1
, 3);
4194 tcg_gen_shli_i64(t1
, t1
, 4);
4195 tcg_gen_shr_i64(t0
, t0
, t1
);
4196 tcg_gen_ext16u_i64(t0
, t0
);
4201 tcg_gen_add_i64(t0
, t0
, t1
);
4202 tcg_gen_ext32s_i64(t0
, t0
);
4206 tcg_gen_sub_i64(t0
, t0
, t1
);
4207 tcg_gen_ext32s_i64(t0
, t0
);
4236 /* Make sure shift count isn't TCG undefined behaviour. */
4237 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4242 tcg_gen_shl_i64(t0
, t0
, t1
);
4246 /* Since SRA is UndefinedResult without sign-extended inputs,
4247 we can treat SRA and DSRA the same. */
4248 tcg_gen_sar_i64(t0
, t0
, t1
);
4251 /* We want to shift in zeros for SRL; zero-extend first. */
4252 tcg_gen_ext32u_i64(t0
, t0
);
4255 tcg_gen_shr_i64(t0
, t0
, t1
);
4259 if (shift_max
== 32) {
4260 tcg_gen_ext32s_i64(t0
, t0
);
4263 /* Shifts larger than MAX produce zero. */
4264 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4265 tcg_gen_neg_i64(t1
, t1
);
4266 tcg_gen_and_i64(t0
, t0
, t1
);
4272 TCGv_i64 t2
= tcg_temp_new_i64();
4273 TCGLabel
*lab
= gen_new_label();
4275 tcg_gen_mov_i64(t2
, t0
);
4276 tcg_gen_add_i64(t0
, t1
, t2
);
4277 if (opc
== OPC_ADD_CP2
) {
4278 tcg_gen_ext32s_i64(t0
, t0
);
4280 tcg_gen_xor_i64(t1
, t1
, t2
);
4281 tcg_gen_xor_i64(t2
, t2
, t0
);
4282 tcg_gen_andc_i64(t1
, t2
, t1
);
4283 tcg_temp_free_i64(t2
);
4284 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4285 generate_exception(ctx
, EXCP_OVERFLOW
);
4288 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
4295 TCGv_i64 t2
= tcg_temp_new_i64();
4296 TCGLabel
*lab
= gen_new_label();
4298 tcg_gen_mov_i64(t2
, t0
);
4299 tcg_gen_sub_i64(t0
, t1
, t2
);
4300 if (opc
== OPC_SUB_CP2
) {
4301 tcg_gen_ext32s_i64(t0
, t0
);
4303 tcg_gen_xor_i64(t1
, t1
, t2
);
4304 tcg_gen_xor_i64(t2
, t2
, t0
);
4305 tcg_gen_and_i64(t1
, t1
, t2
);
4306 tcg_temp_free_i64(t2
);
4307 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4308 generate_exception(ctx
, EXCP_OVERFLOW
);
4311 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
4316 tcg_gen_ext32u_i64(t0
, t0
);
4317 tcg_gen_ext32u_i64(t1
, t1
);
4318 tcg_gen_mul_i64(t0
, t0
, t1
);
4328 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4329 FD field is the CC field? */
4332 generate_exception(ctx
, EXCP_RI
);
4339 gen_store_fpr64(ctx
, t0
, rd
);
4341 (void)opn
; /* avoid a compiler warning */
4342 MIPS_DEBUG("%s %s, %s, %s", opn
,
4343 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
4344 tcg_temp_free_i64(t0
);
4345 tcg_temp_free_i64(t1
);
4349 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
4350 int rs
, int rt
, int16_t imm
)
4353 TCGv t0
= tcg_temp_new();
4354 TCGv t1
= tcg_temp_new();
4357 /* Load needed operands */
4365 /* Compare two registers */
4367 gen_load_gpr(t0
, rs
);
4368 gen_load_gpr(t1
, rt
);
4378 /* Compare register to immediate */
4379 if (rs
!= 0 || imm
!= 0) {
4380 gen_load_gpr(t0
, rs
);
4381 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4388 case OPC_TEQ
: /* rs == rs */
4389 case OPC_TEQI
: /* r0 == 0 */
4390 case OPC_TGE
: /* rs >= rs */
4391 case OPC_TGEI
: /* r0 >= 0 */
4392 case OPC_TGEU
: /* rs >= rs unsigned */
4393 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4395 generate_exception(ctx
, EXCP_TRAP
);
4397 case OPC_TLT
: /* rs < rs */
4398 case OPC_TLTI
: /* r0 < 0 */
4399 case OPC_TLTU
: /* rs < rs unsigned */
4400 case OPC_TLTIU
: /* r0 < 0 unsigned */
4401 case OPC_TNE
: /* rs != rs */
4402 case OPC_TNEI
: /* r0 != 0 */
4403 /* Never trap: treat as NOP. */
4407 TCGLabel
*l1
= gen_new_label();
4412 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4416 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4420 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
4424 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
4428 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
4432 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
4435 generate_exception(ctx
, EXCP_TRAP
);
4442 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
4444 TranslationBlock
*tb
;
4446 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
4447 likely(!ctx
->singlestep_enabled
)) {
4450 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
4453 if (ctx
->singlestep_enabled
) {
4454 save_cpu_state(ctx
, 0);
4455 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
4461 /* Branches (before delay slot) */
4462 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
4464 int rs
, int rt
, int32_t offset
,
4467 target_ulong btgt
= -1;
4469 int bcond_compute
= 0;
4470 TCGv t0
= tcg_temp_new();
4471 TCGv t1
= tcg_temp_new();
4473 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
4474 #ifdef MIPS_DEBUG_DISAS
4475 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4476 TARGET_FMT_lx
"\n", ctx
->pc
);
4478 generate_exception(ctx
, EXCP_RI
);
4482 /* Load needed operands */
4488 /* Compare two registers */
4490 gen_load_gpr(t0
, rs
);
4491 gen_load_gpr(t1
, rt
);
4494 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4508 /* Compare to zero */
4510 gen_load_gpr(t0
, rs
);
4513 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4516 #if defined(TARGET_MIPS64)
4518 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
4520 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
4523 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4528 /* Jump to immediate */
4529 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
4533 /* Jump to register */
4534 if (offset
!= 0 && offset
!= 16) {
4535 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4536 others are reserved. */
4537 MIPS_INVAL("jump hint");
4538 generate_exception(ctx
, EXCP_RI
);
4541 gen_load_gpr(btarget
, rs
);
4544 MIPS_INVAL("branch/jump");
4545 generate_exception(ctx
, EXCP_RI
);
4548 if (bcond_compute
== 0) {
4549 /* No condition to be computed */
4551 case OPC_BEQ
: /* rx == rx */
4552 case OPC_BEQL
: /* rx == rx likely */
4553 case OPC_BGEZ
: /* 0 >= 0 */
4554 case OPC_BGEZL
: /* 0 >= 0 likely */
4555 case OPC_BLEZ
: /* 0 <= 0 */
4556 case OPC_BLEZL
: /* 0 <= 0 likely */
4558 ctx
->hflags
|= MIPS_HFLAG_B
;
4559 MIPS_DEBUG("balways");
4561 case OPC_BGEZAL
: /* 0 >= 0 */
4562 case OPC_BGEZALL
: /* 0 >= 0 likely */
4563 /* Always take and link */
4565 ctx
->hflags
|= MIPS_HFLAG_B
;
4566 MIPS_DEBUG("balways and link");
4568 case OPC_BNE
: /* rx != rx */
4569 case OPC_BGTZ
: /* 0 > 0 */
4570 case OPC_BLTZ
: /* 0 < 0 */
4572 MIPS_DEBUG("bnever (NOP)");
4574 case OPC_BLTZAL
: /* 0 < 0 */
4575 /* Handle as an unconditional branch to get correct delay
4578 btgt
= ctx
->pc
+ insn_bytes
+ delayslot_size
;
4579 ctx
->hflags
|= MIPS_HFLAG_B
;
4580 MIPS_DEBUG("bnever and link");
4582 case OPC_BLTZALL
: /* 0 < 0 likely */
4583 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
4584 /* Skip the instruction in the delay slot */
4585 MIPS_DEBUG("bnever, link and skip");
4588 case OPC_BNEL
: /* rx != rx likely */
4589 case OPC_BGTZL
: /* 0 > 0 likely */
4590 case OPC_BLTZL
: /* 0 < 0 likely */
4591 /* Skip the instruction in the delay slot */
4592 MIPS_DEBUG("bnever and skip");
4596 ctx
->hflags
|= MIPS_HFLAG_B
;
4597 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
4600 ctx
->hflags
|= MIPS_HFLAG_BX
;
4604 ctx
->hflags
|= MIPS_HFLAG_B
;
4605 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
4608 ctx
->hflags
|= MIPS_HFLAG_BR
;
4609 MIPS_DEBUG("jr %s", regnames
[rs
]);
4613 ctx
->hflags
|= MIPS_HFLAG_BR
;
4614 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
4617 MIPS_INVAL("branch/jump");
4618 generate_exception(ctx
, EXCP_RI
);
4624 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4625 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
4626 regnames
[rs
], regnames
[rt
], btgt
);
4629 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4630 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
4631 regnames
[rs
], regnames
[rt
], btgt
);
4634 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4635 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
4636 regnames
[rs
], regnames
[rt
], btgt
);
4639 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4640 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
4641 regnames
[rs
], regnames
[rt
], btgt
);
4644 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4645 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4648 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4649 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4652 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4653 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4657 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4659 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4662 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4663 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4666 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4667 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4670 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4671 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4674 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4675 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4678 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4679 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4682 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4683 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4686 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
4687 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
4689 #if defined(TARGET_MIPS64)
4691 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
4692 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
4696 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4698 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4700 ctx
->hflags
|= MIPS_HFLAG_BC
;
4703 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4705 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4707 ctx
->hflags
|= MIPS_HFLAG_BL
;
4710 MIPS_INVAL("conditional branch/jump");
4711 generate_exception(ctx
, EXCP_RI
);
4715 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
4716 blink
, ctx
->hflags
, btgt
);
4718 ctx
->btarget
= btgt
;
4720 switch (delayslot_size
) {
4722 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
4725 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
4730 int post_delay
= insn_bytes
+ delayslot_size
;
4731 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
4733 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
4737 if (insn_bytes
== 2)
4738 ctx
->hflags
|= MIPS_HFLAG_B16
;
4743 /* special3 bitfield operations */
4744 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
4745 int rs
, int lsb
, int msb
)
4747 TCGv t0
= tcg_temp_new();
4748 TCGv t1
= tcg_temp_new();
4750 gen_load_gpr(t1
, rs
);
4755 tcg_gen_shri_tl(t0
, t1
, lsb
);
4757 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
4759 tcg_gen_ext32s_tl(t0
, t0
);
4762 #if defined(TARGET_MIPS64)
4764 tcg_gen_shri_tl(t0
, t1
, lsb
);
4766 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
4770 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
4771 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4774 tcg_gen_shri_tl(t0
, t1
, lsb
);
4775 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4781 gen_load_gpr(t0
, rt
);
4782 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4783 tcg_gen_ext32s_tl(t0
, t0
);
4785 #if defined(TARGET_MIPS64)
4787 gen_load_gpr(t0
, rt
);
4788 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
4791 gen_load_gpr(t0
, rt
);
4792 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
4795 gen_load_gpr(t0
, rt
);
4796 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4801 MIPS_INVAL("bitops");
4802 generate_exception(ctx
, EXCP_RI
);
4807 gen_store_gpr(t0
, rt
);
4812 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4817 /* If no destination, treat it as a NOP. */
4822 t0
= tcg_temp_new();
4823 gen_load_gpr(t0
, rt
);
4827 TCGv t1
= tcg_temp_new();
4829 tcg_gen_shri_tl(t1
, t0
, 8);
4830 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4831 tcg_gen_shli_tl(t0
, t0
, 8);
4832 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4833 tcg_gen_or_tl(t0
, t0
, t1
);
4835 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4839 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4842 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4844 #if defined(TARGET_MIPS64)
4847 TCGv t1
= tcg_temp_new();
4849 tcg_gen_shri_tl(t1
, t0
, 8);
4850 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4851 tcg_gen_shli_tl(t0
, t0
, 8);
4852 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4853 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4859 TCGv t1
= tcg_temp_new();
4861 tcg_gen_shri_tl(t1
, t0
, 16);
4862 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4863 tcg_gen_shli_tl(t0
, t0
, 16);
4864 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4865 tcg_gen_or_tl(t0
, t0
, t1
);
4866 tcg_gen_shri_tl(t1
, t0
, 32);
4867 tcg_gen_shli_tl(t0
, t0
, 32);
4868 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4874 MIPS_INVAL("bsfhl");
4875 generate_exception(ctx
, EXCP_RI
);
4882 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
4891 t0
= tcg_temp_new();
4892 t1
= tcg_temp_new();
4893 gen_load_gpr(t0
, rs
);
4894 gen_load_gpr(t1
, rt
);
4895 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
4896 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
4897 if (opc
== OPC_LSA
) {
4898 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4907 static void gen_align(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
4915 t0
= tcg_temp_new();
4916 gen_load_gpr(t0
, rt
);
4918 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4920 TCGv t1
= tcg_temp_new();
4921 gen_load_gpr(t1
, rs
);
4925 TCGv_i64 t2
= tcg_temp_new_i64();
4926 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
4927 tcg_gen_shri_i64(t2
, t2
, 8 * (4 - bp
));
4928 gen_move_low32(cpu_gpr
[rd
], t2
);
4929 tcg_temp_free_i64(t2
);
4932 #if defined(TARGET_MIPS64)
4934 tcg_gen_shli_tl(t0
, t0
, 8 * bp
);
4935 tcg_gen_shri_tl(t1
, t1
, 8 * (8 - bp
));
4936 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
4946 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
4953 t0
= tcg_temp_new();
4954 gen_load_gpr(t0
, rt
);
4957 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
4959 #if defined(TARGET_MIPS64)
4961 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
4968 #ifndef CONFIG_USER_ONLY
4969 /* CP0 (MMU and control) */
4970 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
4972 TCGv_i64 t0
= tcg_temp_new_i64();
4973 TCGv_i64 t1
= tcg_temp_new_i64();
4975 tcg_gen_ext_tl_i64(t0
, arg
);
4976 tcg_gen_ld_i64(t1
, cpu_env
, off
);
4977 #if defined(TARGET_MIPS64)
4978 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
4980 tcg_gen_concat32_i64(t1
, t1
, t0
);
4982 tcg_gen_st_i64(t1
, cpu_env
, off
);
4983 tcg_temp_free_i64(t1
);
4984 tcg_temp_free_i64(t0
);
4987 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
4989 TCGv_i64 t0
= tcg_temp_new_i64();
4990 TCGv_i64 t1
= tcg_temp_new_i64();
4992 tcg_gen_ext_tl_i64(t0
, arg
);
4993 tcg_gen_ld_i64(t1
, cpu_env
, off
);
4994 tcg_gen_concat32_i64(t1
, t1
, t0
);
4995 tcg_gen_st_i64(t1
, cpu_env
, off
);
4996 tcg_temp_free_i64(t1
);
4997 tcg_temp_free_i64(t0
);
5000 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
5002 TCGv_i64 t0
= tcg_temp_new_i64();
5004 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5005 #if defined(TARGET_MIPS64)
5006 tcg_gen_shri_i64(t0
, t0
, 30);
5008 tcg_gen_shri_i64(t0
, t0
, 32);
5010 gen_move_low32(arg
, t0
);
5011 tcg_temp_free_i64(t0
);
5014 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
5016 TCGv_i64 t0
= tcg_temp_new_i64();
5018 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5019 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
5020 gen_move_low32(arg
, t0
);
5021 tcg_temp_free_i64(t0
);
5024 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
5026 TCGv_i32 t0
= tcg_temp_new_i32();
5028 tcg_gen_ld_i32(t0
, cpu_env
, off
);
5029 tcg_gen_ext_i32_tl(arg
, t0
);
5030 tcg_temp_free_i32(t0
);
5033 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
5035 tcg_gen_ld_tl(arg
, cpu_env
, off
);
5036 tcg_gen_ext32s_tl(arg
, arg
);
5039 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
5041 TCGv_i32 t0
= tcg_temp_new_i32();
5043 tcg_gen_trunc_tl_i32(t0
, arg
);
5044 tcg_gen_st_i32(t0
, cpu_env
, off
);
5045 tcg_temp_free_i32(t0
);
5048 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
5050 tcg_gen_ext32s_tl(arg
, arg
);
5051 tcg_gen_st_tl(arg
, cpu_env
, off
);
5054 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5056 const char *rn
= "invalid";
5058 if (!(ctx
->hflags
& MIPS_HFLAG_ELPA
)) {
5059 goto mfhc0_read_zero
;
5066 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5070 goto mfhc0_read_zero
;
5076 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5080 goto mfhc0_read_zero
;
5086 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, lladdr
),
5087 ctx
->CP0_LLAddr_shift
);
5091 goto mfhc0_read_zero
;
5100 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
5104 goto mfhc0_read_zero
;
5108 goto mfhc0_read_zero
;
5111 (void)rn
; /* avoid a compiler warning */
5112 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5116 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5117 tcg_gen_movi_tl(arg
, 0);
5120 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5122 const char *rn
= "invalid";
5123 uint64_t mask
= ctx
->PAMask
>> 36;
5125 if (!(ctx
->hflags
& MIPS_HFLAG_ELPA
)) {
5133 tcg_gen_andi_tl(arg
, arg
, mask
);
5134 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5144 tcg_gen_andi_tl(arg
, arg
, mask
);
5145 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5155 /* LLAddr is read-only (the only exception is bit 0 if LLB is
5156 supported); the CP0_LLAddr_rw_bitmask does not seem to be
5157 relevant for modern MIPS cores supporting MTHC0, therefore
5158 treating MTHC0 to LLAddr as NOP. */
5171 tcg_gen_andi_tl(arg
, arg
, mask
);
5172 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5183 (void)rn
; /* avoid a compiler warning */
5185 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5188 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
5190 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
5191 tcg_gen_movi_tl(arg
, 0);
5193 tcg_gen_movi_tl(arg
, ~0);
5197 #define CP0_CHECK(c) \
5200 goto cp0_unimplemented; \
5204 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5206 const char *rn
= "invalid";
5209 check_insn(ctx
, ISA_MIPS32
);
5215 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5219 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5220 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5224 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5225 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5229 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5230 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5234 goto cp0_unimplemented
;
5240 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5241 gen_helper_mfc0_random(arg
, cpu_env
);
5245 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5246 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5250 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5251 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5255 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5256 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5260 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5261 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
5265 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5266 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5270 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5271 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5272 rn
= "VPEScheFBack";
5275 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5276 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5280 goto cp0_unimplemented
;
5287 TCGv_i64 tmp
= tcg_temp_new_i64();
5288 tcg_gen_ld_i64(tmp
, cpu_env
,
5289 offsetof(CPUMIPSState
, CP0_EntryLo0
));
5290 #if defined(TARGET_MIPS64)
5292 /* Move RI/XI fields to bits 31:30 */
5293 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
5294 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
5297 gen_move_low32(arg
, tmp
);
5298 tcg_temp_free_i64(tmp
);
5303 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5304 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5308 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5309 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5313 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5314 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
5318 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5319 gen_helper_mfc0_tchalt(arg
, cpu_env
);
5323 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5324 gen_helper_mfc0_tccontext(arg
, cpu_env
);
5328 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5329 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
5333 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5334 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
5338 goto cp0_unimplemented
;
5345 TCGv_i64 tmp
= tcg_temp_new_i64();
5346 tcg_gen_ld_i64(tmp
, cpu_env
,
5347 offsetof(CPUMIPSState
, CP0_EntryLo1
));
5348 #if defined(TARGET_MIPS64)
5350 /* Move RI/XI fields to bits 31:30 */
5351 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
5352 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
5355 gen_move_low32(arg
, tmp
);
5356 tcg_temp_free_i64(tmp
);
5361 goto cp0_unimplemented
;
5367 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5368 tcg_gen_ext32s_tl(arg
, arg
);
5372 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5373 rn
= "ContextConfig";
5374 goto cp0_unimplemented
;
5377 CP0_CHECK(ctx
->ulri
);
5378 tcg_gen_ld32s_tl(arg
, cpu_env
,
5379 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5383 goto cp0_unimplemented
;
5389 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5393 check_insn(ctx
, ISA_MIPS32R2
);
5394 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5398 goto cp0_unimplemented
;
5404 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5408 check_insn(ctx
, ISA_MIPS32R2
);
5409 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5413 check_insn(ctx
, ISA_MIPS32R2
);
5414 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5418 check_insn(ctx
, ISA_MIPS32R2
);
5419 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5423 check_insn(ctx
, ISA_MIPS32R2
);
5424 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5428 check_insn(ctx
, ISA_MIPS32R2
);
5429 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5433 goto cp0_unimplemented
;
5439 check_insn(ctx
, ISA_MIPS32R2
);
5440 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5444 goto cp0_unimplemented
;
5450 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5451 tcg_gen_ext32s_tl(arg
, arg
);
5456 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
5461 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
5465 goto cp0_unimplemented
;
5471 /* Mark as an IO operation because we read the time. */
5472 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5475 gen_helper_mfc0_count(arg
, cpu_env
);
5476 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5479 /* Break the TB to be able to take timer interrupts immediately
5480 after reading count. */
5481 ctx
->bstate
= BS_STOP
;
5484 /* 6,7 are implementation dependent */
5486 goto cp0_unimplemented
;
5492 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5493 tcg_gen_ext32s_tl(arg
, arg
);
5497 goto cp0_unimplemented
;
5503 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5506 /* 6,7 are implementation dependent */
5508 goto cp0_unimplemented
;
5514 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5518 check_insn(ctx
, ISA_MIPS32R2
);
5519 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5523 check_insn(ctx
, ISA_MIPS32R2
);
5524 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5528 check_insn(ctx
, ISA_MIPS32R2
);
5529 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5533 goto cp0_unimplemented
;
5539 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5543 goto cp0_unimplemented
;
5549 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5550 tcg_gen_ext32s_tl(arg
, arg
);
5554 goto cp0_unimplemented
;
5560 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5564 check_insn(ctx
, ISA_MIPS32R2
);
5565 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5569 goto cp0_unimplemented
;
5575 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5579 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5583 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5587 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5591 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
5595 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
5598 /* 6,7 are implementation dependent */
5600 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5604 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5608 goto cp0_unimplemented
;
5614 gen_helper_mfc0_lladdr(arg
, cpu_env
);
5618 goto cp0_unimplemented
;
5624 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
5628 goto cp0_unimplemented
;
5634 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5638 goto cp0_unimplemented
;
5644 #if defined(TARGET_MIPS64)
5645 check_insn(ctx
, ISA_MIPS3
);
5646 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5647 tcg_gen_ext32s_tl(arg
, arg
);
5652 goto cp0_unimplemented
;
5656 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5657 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5660 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5664 goto cp0_unimplemented
;
5668 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5669 rn
= "'Diagnostic"; /* implementation dependent */
5674 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5678 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5679 rn
= "TraceControl";
5682 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5683 rn
= "TraceControl2";
5686 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5687 rn
= "UserTraceData";
5690 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5694 goto cp0_unimplemented
;
5701 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5702 tcg_gen_ext32s_tl(arg
, arg
);
5706 goto cp0_unimplemented
;
5712 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5713 rn
= "Performance0";
5716 // gen_helper_mfc0_performance1(arg);
5717 rn
= "Performance1";
5720 // gen_helper_mfc0_performance2(arg);
5721 rn
= "Performance2";
5724 // gen_helper_mfc0_performance3(arg);
5725 rn
= "Performance3";
5728 // gen_helper_mfc0_performance4(arg);
5729 rn
= "Performance4";
5732 // gen_helper_mfc0_performance5(arg);
5733 rn
= "Performance5";
5736 // gen_helper_mfc0_performance6(arg);
5737 rn
= "Performance6";
5740 // gen_helper_mfc0_performance7(arg);
5741 rn
= "Performance7";
5744 goto cp0_unimplemented
;
5748 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5754 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5758 goto cp0_unimplemented
;
5768 TCGv_i64 tmp
= tcg_temp_new_i64();
5769 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
5770 gen_move_low32(arg
, tmp
);
5771 tcg_temp_free_i64(tmp
);
5779 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5783 goto cp0_unimplemented
;
5792 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5799 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5803 goto cp0_unimplemented
;
5809 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5810 tcg_gen_ext32s_tl(arg
, arg
);
5814 goto cp0_unimplemented
;
5821 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5825 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
5826 tcg_gen_ld_tl(arg
, cpu_env
,
5827 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
5828 tcg_gen_ext32s_tl(arg
, arg
);
5832 goto cp0_unimplemented
;
5836 goto cp0_unimplemented
;
5838 (void)rn
; /* avoid a compiler warning */
5839 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5843 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5844 gen_mfc0_unimplemented(ctx
, arg
);
5847 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5849 const char *rn
= "invalid";
5852 check_insn(ctx
, ISA_MIPS32
);
5854 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5862 gen_helper_mtc0_index(cpu_env
, arg
);
5866 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5867 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5871 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5876 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5881 goto cp0_unimplemented
;
5891 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5892 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5896 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5897 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5901 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5902 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5906 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5907 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5911 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5912 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5916 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5917 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5918 rn
= "VPEScheFBack";
5921 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5922 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5926 goto cp0_unimplemented
;
5932 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5936 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5937 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5941 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5942 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5946 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5947 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5951 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5952 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5956 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5957 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5961 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5962 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5966 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5967 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5971 goto cp0_unimplemented
;
5977 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5981 goto cp0_unimplemented
;
5987 gen_helper_mtc0_context(cpu_env
, arg
);
5991 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5992 rn
= "ContextConfig";
5993 goto cp0_unimplemented
;
5996 CP0_CHECK(ctx
->ulri
);
5997 tcg_gen_st_tl(arg
, cpu_env
,
5998 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6002 goto cp0_unimplemented
;
6008 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6012 check_insn(ctx
, ISA_MIPS32R2
);
6013 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6015 ctx
->bstate
= BS_STOP
;
6018 goto cp0_unimplemented
;
6024 gen_helper_mtc0_wired(cpu_env
, arg
);
6028 check_insn(ctx
, ISA_MIPS32R2
);
6029 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6033 check_insn(ctx
, ISA_MIPS32R2
);
6034 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6038 check_insn(ctx
, ISA_MIPS32R2
);
6039 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6043 check_insn(ctx
, ISA_MIPS32R2
);
6044 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6048 check_insn(ctx
, ISA_MIPS32R2
);
6049 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6053 goto cp0_unimplemented
;
6059 check_insn(ctx
, ISA_MIPS32R2
);
6060 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6061 ctx
->bstate
= BS_STOP
;
6065 goto cp0_unimplemented
;
6083 goto cp0_unimplemented
;
6089 gen_helper_mtc0_count(cpu_env
, arg
);
6092 /* 6,7 are implementation dependent */
6094 goto cp0_unimplemented
;
6100 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6104 goto cp0_unimplemented
;
6110 gen_helper_mtc0_compare(cpu_env
, arg
);
6113 /* 6,7 are implementation dependent */
6115 goto cp0_unimplemented
;
6121 save_cpu_state(ctx
, 1);
6122 gen_helper_mtc0_status(cpu_env
, arg
);
6123 /* BS_STOP isn't good enough here, hflags may have changed. */
6124 gen_save_pc(ctx
->pc
+ 4);
6125 ctx
->bstate
= BS_EXCP
;
6129 check_insn(ctx
, ISA_MIPS32R2
);
6130 gen_helper_mtc0_intctl(cpu_env
, arg
);
6131 /* Stop translation as we may have switched the execution mode */
6132 ctx
->bstate
= BS_STOP
;
6136 check_insn(ctx
, ISA_MIPS32R2
);
6137 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6138 /* Stop translation as we may have switched the execution mode */
6139 ctx
->bstate
= BS_STOP
;
6143 check_insn(ctx
, ISA_MIPS32R2
);
6144 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6145 /* Stop translation as we may have switched the execution mode */
6146 ctx
->bstate
= BS_STOP
;
6150 goto cp0_unimplemented
;
6156 save_cpu_state(ctx
, 1);
6157 gen_helper_mtc0_cause(cpu_env
, arg
);
6161 goto cp0_unimplemented
;
6167 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
6171 goto cp0_unimplemented
;
6181 check_insn(ctx
, ISA_MIPS32R2
);
6182 gen_helper_mtc0_ebase(cpu_env
, arg
);
6186 goto cp0_unimplemented
;
6192 gen_helper_mtc0_config0(cpu_env
, arg
);
6194 /* Stop translation as we may have switched the execution mode */
6195 ctx
->bstate
= BS_STOP
;
6198 /* ignored, read only */
6202 gen_helper_mtc0_config2(cpu_env
, arg
);
6204 /* Stop translation as we may have switched the execution mode */
6205 ctx
->bstate
= BS_STOP
;
6208 gen_helper_mtc0_config3(cpu_env
, arg
);
6210 /* Stop translation as we may have switched the execution mode */
6211 ctx
->bstate
= BS_STOP
;
6214 gen_helper_mtc0_config4(cpu_env
, arg
);
6216 ctx
->bstate
= BS_STOP
;
6219 gen_helper_mtc0_config5(cpu_env
, arg
);
6221 /* Stop translation as we may have switched the execution mode */
6222 ctx
->bstate
= BS_STOP
;
6224 /* 6,7 are implementation dependent */
6234 rn
= "Invalid config selector";
6235 goto cp0_unimplemented
;
6241 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6245 goto cp0_unimplemented
;
6251 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6255 goto cp0_unimplemented
;
6261 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6265 goto cp0_unimplemented
;
6271 #if defined(TARGET_MIPS64)
6272 check_insn(ctx
, ISA_MIPS3
);
6273 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6278 goto cp0_unimplemented
;
6282 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6283 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6286 gen_helper_mtc0_framemask(cpu_env
, arg
);
6290 goto cp0_unimplemented
;
6295 rn
= "Diagnostic"; /* implementation dependent */
6300 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6301 /* BS_STOP isn't good enough here, hflags may have changed. */
6302 gen_save_pc(ctx
->pc
+ 4);
6303 ctx
->bstate
= BS_EXCP
;
6307 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6308 rn
= "TraceControl";
6309 /* Stop translation as we may have switched the execution mode */
6310 ctx
->bstate
= BS_STOP
;
6313 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6314 rn
= "TraceControl2";
6315 /* Stop translation as we may have switched the execution mode */
6316 ctx
->bstate
= BS_STOP
;
6319 /* Stop translation as we may have switched the execution mode */
6320 ctx
->bstate
= BS_STOP
;
6321 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6322 rn
= "UserTraceData";
6323 /* Stop translation as we may have switched the execution mode */
6324 ctx
->bstate
= BS_STOP
;
6327 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6328 /* Stop translation as we may have switched the execution mode */
6329 ctx
->bstate
= BS_STOP
;
6333 goto cp0_unimplemented
;
6340 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
6344 goto cp0_unimplemented
;
6350 gen_helper_mtc0_performance0(cpu_env
, arg
);
6351 rn
= "Performance0";
6354 // gen_helper_mtc0_performance1(arg);
6355 rn
= "Performance1";
6358 // gen_helper_mtc0_performance2(arg);
6359 rn
= "Performance2";
6362 // gen_helper_mtc0_performance3(arg);
6363 rn
= "Performance3";
6366 // gen_helper_mtc0_performance4(arg);
6367 rn
= "Performance4";
6370 // gen_helper_mtc0_performance5(arg);
6371 rn
= "Performance5";
6374 // gen_helper_mtc0_performance6(arg);
6375 rn
= "Performance6";
6378 // gen_helper_mtc0_performance7(arg);
6379 rn
= "Performance7";
6382 goto cp0_unimplemented
;
6396 goto cp0_unimplemented
;
6405 gen_helper_mtc0_taglo(cpu_env
, arg
);
6412 gen_helper_mtc0_datalo(cpu_env
, arg
);
6416 goto cp0_unimplemented
;
6425 gen_helper_mtc0_taghi(cpu_env
, arg
);
6432 gen_helper_mtc0_datahi(cpu_env
, arg
);
6437 goto cp0_unimplemented
;
6443 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6447 goto cp0_unimplemented
;
6454 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6458 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6459 tcg_gen_st_tl(arg
, cpu_env
,
6460 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6464 goto cp0_unimplemented
;
6466 /* Stop translation as we may have switched the execution mode */
6467 ctx
->bstate
= BS_STOP
;
6470 goto cp0_unimplemented
;
6472 (void)rn
; /* avoid a compiler warning */
6473 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6474 /* For simplicity assume that all writes can cause interrupts. */
6475 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6477 ctx
->bstate
= BS_STOP
;
6482 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6485 #if defined(TARGET_MIPS64)
6486 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6488 const char *rn
= "invalid";
6491 check_insn(ctx
, ISA_MIPS64
);
6497 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6501 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6502 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6506 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6507 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6511 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6512 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6516 goto cp0_unimplemented
;
6522 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6523 gen_helper_mfc0_random(arg
, cpu_env
);
6527 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6528 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6532 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6533 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6537 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6538 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6542 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6543 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
6547 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6548 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6552 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6553 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6554 rn
= "VPEScheFBack";
6557 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6558 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6562 goto cp0_unimplemented
;
6568 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6572 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6573 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6577 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6578 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6582 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6583 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
6587 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6588 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
6592 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6593 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
6597 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6598 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
6602 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6603 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
6607 goto cp0_unimplemented
;
6613 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6617 goto cp0_unimplemented
;
6623 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6627 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6628 rn
= "ContextConfig";
6629 goto cp0_unimplemented
;
6632 CP0_CHECK(ctx
->ulri
);
6633 tcg_gen_ld_tl(arg
, cpu_env
,
6634 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6638 goto cp0_unimplemented
;
6644 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6648 check_insn(ctx
, ISA_MIPS32R2
);
6649 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6653 goto cp0_unimplemented
;
6659 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6663 check_insn(ctx
, ISA_MIPS32R2
);
6664 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6668 check_insn(ctx
, ISA_MIPS32R2
);
6669 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6673 check_insn(ctx
, ISA_MIPS32R2
);
6674 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6678 check_insn(ctx
, ISA_MIPS32R2
);
6679 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6683 check_insn(ctx
, ISA_MIPS32R2
);
6684 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6688 goto cp0_unimplemented
;
6694 check_insn(ctx
, ISA_MIPS32R2
);
6695 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6699 goto cp0_unimplemented
;
6705 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6710 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6715 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6719 goto cp0_unimplemented
;
6725 /* Mark as an IO operation because we read the time. */
6726 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6729 gen_helper_mfc0_count(arg
, cpu_env
);
6730 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6733 /* Break the TB to be able to take timer interrupts immediately
6734 after reading count. */
6735 ctx
->bstate
= BS_STOP
;
6738 /* 6,7 are implementation dependent */
6740 goto cp0_unimplemented
;
6746 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6750 goto cp0_unimplemented
;
6756 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6759 /* 6,7 are implementation dependent */
6761 goto cp0_unimplemented
;
6767 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6771 check_insn(ctx
, ISA_MIPS32R2
);
6772 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6776 check_insn(ctx
, ISA_MIPS32R2
);
6777 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6781 check_insn(ctx
, ISA_MIPS32R2
);
6782 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6786 goto cp0_unimplemented
;
6792 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6796 goto cp0_unimplemented
;
6802 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6806 goto cp0_unimplemented
;
6812 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6816 check_insn(ctx
, ISA_MIPS32R2
);
6817 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
6821 goto cp0_unimplemented
;
6827 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6831 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6835 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6839 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6843 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6847 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6850 /* 6,7 are implementation dependent */
6852 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6856 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6860 goto cp0_unimplemented
;
6866 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
6870 goto cp0_unimplemented
;
6876 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
6880 goto cp0_unimplemented
;
6886 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6890 goto cp0_unimplemented
;
6896 check_insn(ctx
, ISA_MIPS3
);
6897 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6901 goto cp0_unimplemented
;
6905 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6906 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6909 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6913 goto cp0_unimplemented
;
6917 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6918 rn
= "'Diagnostic"; /* implementation dependent */
6923 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6927 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6928 rn
= "TraceControl";
6931 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6932 rn
= "TraceControl2";
6935 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6936 rn
= "UserTraceData";
6939 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6943 goto cp0_unimplemented
;
6950 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6954 goto cp0_unimplemented
;
6960 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6961 rn
= "Performance0";
6964 // gen_helper_dmfc0_performance1(arg);
6965 rn
= "Performance1";
6968 // gen_helper_dmfc0_performance2(arg);
6969 rn
= "Performance2";
6972 // gen_helper_dmfc0_performance3(arg);
6973 rn
= "Performance3";
6976 // gen_helper_dmfc0_performance4(arg);
6977 rn
= "Performance4";
6980 // gen_helper_dmfc0_performance5(arg);
6981 rn
= "Performance5";
6984 // gen_helper_dmfc0_performance6(arg);
6985 rn
= "Performance6";
6988 // gen_helper_dmfc0_performance7(arg);
6989 rn
= "Performance7";
6992 goto cp0_unimplemented
;
6996 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7003 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7007 goto cp0_unimplemented
;
7016 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
7023 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7027 goto cp0_unimplemented
;
7036 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7043 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7047 goto cp0_unimplemented
;
7053 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7057 goto cp0_unimplemented
;
7064 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7068 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7069 tcg_gen_ld_tl(arg
, cpu_env
,
7070 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7074 goto cp0_unimplemented
;
7078 goto cp0_unimplemented
;
7080 (void)rn
; /* avoid a compiler warning */
7081 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7085 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7086 gen_mfc0_unimplemented(ctx
, arg
);
7089 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7091 const char *rn
= "invalid";
7094 check_insn(ctx
, ISA_MIPS64
);
7096 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7104 gen_helper_mtc0_index(cpu_env
, arg
);
7108 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7109 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7113 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7118 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7123 goto cp0_unimplemented
;
7133 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7134 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7138 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7139 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7143 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7144 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7148 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7149 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7153 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7154 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7158 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7159 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7160 rn
= "VPEScheFBack";
7163 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7164 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7168 goto cp0_unimplemented
;
7174 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
7178 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7179 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7183 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7184 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7188 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7189 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7193 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7194 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7198 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7199 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7203 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7204 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7208 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7209 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7213 goto cp0_unimplemented
;
7219 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
7223 goto cp0_unimplemented
;
7229 gen_helper_mtc0_context(cpu_env
, arg
);
7233 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7234 rn
= "ContextConfig";
7235 goto cp0_unimplemented
;
7238 CP0_CHECK(ctx
->ulri
);
7239 tcg_gen_st_tl(arg
, cpu_env
,
7240 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7244 goto cp0_unimplemented
;
7250 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7254 check_insn(ctx
, ISA_MIPS32R2
);
7255 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7259 goto cp0_unimplemented
;
7265 gen_helper_mtc0_wired(cpu_env
, arg
);
7269 check_insn(ctx
, ISA_MIPS32R2
);
7270 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7274 check_insn(ctx
, ISA_MIPS32R2
);
7275 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7279 check_insn(ctx
, ISA_MIPS32R2
);
7280 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7284 check_insn(ctx
, ISA_MIPS32R2
);
7285 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7289 check_insn(ctx
, ISA_MIPS32R2
);
7290 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7294 goto cp0_unimplemented
;
7300 check_insn(ctx
, ISA_MIPS32R2
);
7301 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7302 ctx
->bstate
= BS_STOP
;
7306 goto cp0_unimplemented
;
7324 goto cp0_unimplemented
;
7330 gen_helper_mtc0_count(cpu_env
, arg
);
7333 /* 6,7 are implementation dependent */
7335 goto cp0_unimplemented
;
7337 /* Stop translation as we may have switched the execution mode */
7338 ctx
->bstate
= BS_STOP
;
7343 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7347 goto cp0_unimplemented
;
7353 gen_helper_mtc0_compare(cpu_env
, arg
);
7356 /* 6,7 are implementation dependent */
7358 goto cp0_unimplemented
;
7360 /* Stop translation as we may have switched the execution mode */
7361 ctx
->bstate
= BS_STOP
;
7366 save_cpu_state(ctx
, 1);
7367 gen_helper_mtc0_status(cpu_env
, arg
);
7368 /* BS_STOP isn't good enough here, hflags may have changed. */
7369 gen_save_pc(ctx
->pc
+ 4);
7370 ctx
->bstate
= BS_EXCP
;
7374 check_insn(ctx
, ISA_MIPS32R2
);
7375 gen_helper_mtc0_intctl(cpu_env
, arg
);
7376 /* Stop translation as we may have switched the execution mode */
7377 ctx
->bstate
= BS_STOP
;
7381 check_insn(ctx
, ISA_MIPS32R2
);
7382 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7383 /* Stop translation as we may have switched the execution mode */
7384 ctx
->bstate
= BS_STOP
;
7388 check_insn(ctx
, ISA_MIPS32R2
);
7389 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7390 /* Stop translation as we may have switched the execution mode */
7391 ctx
->bstate
= BS_STOP
;
7395 goto cp0_unimplemented
;
7401 save_cpu_state(ctx
, 1);
7402 /* Mark as an IO operation because we may trigger a software
7404 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7407 gen_helper_mtc0_cause(cpu_env
, arg
);
7408 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7411 /* Stop translation as we may have triggered an intetrupt */
7412 ctx
->bstate
= BS_STOP
;
7416 goto cp0_unimplemented
;
7422 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7426 goto cp0_unimplemented
;
7436 check_insn(ctx
, ISA_MIPS32R2
);
7437 gen_helper_mtc0_ebase(cpu_env
, arg
);
7441 goto cp0_unimplemented
;
7447 gen_helper_mtc0_config0(cpu_env
, arg
);
7449 /* Stop translation as we may have switched the execution mode */
7450 ctx
->bstate
= BS_STOP
;
7453 /* ignored, read only */
7457 gen_helper_mtc0_config2(cpu_env
, arg
);
7459 /* Stop translation as we may have switched the execution mode */
7460 ctx
->bstate
= BS_STOP
;
7463 gen_helper_mtc0_config3(cpu_env
, arg
);
7465 /* Stop translation as we may have switched the execution mode */
7466 ctx
->bstate
= BS_STOP
;
7469 /* currently ignored */
7473 gen_helper_mtc0_config5(cpu_env
, arg
);
7475 /* Stop translation as we may have switched the execution mode */
7476 ctx
->bstate
= BS_STOP
;
7478 /* 6,7 are implementation dependent */
7480 rn
= "Invalid config selector";
7481 goto cp0_unimplemented
;
7487 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7491 goto cp0_unimplemented
;
7497 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7501 goto cp0_unimplemented
;
7507 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7511 goto cp0_unimplemented
;
7517 check_insn(ctx
, ISA_MIPS3
);
7518 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7522 goto cp0_unimplemented
;
7526 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7527 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7530 gen_helper_mtc0_framemask(cpu_env
, arg
);
7534 goto cp0_unimplemented
;
7539 rn
= "Diagnostic"; /* implementation dependent */
7544 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7545 /* BS_STOP isn't good enough here, hflags may have changed. */
7546 gen_save_pc(ctx
->pc
+ 4);
7547 ctx
->bstate
= BS_EXCP
;
7551 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7552 /* Stop translation as we may have switched the execution mode */
7553 ctx
->bstate
= BS_STOP
;
7554 rn
= "TraceControl";
7557 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7558 /* Stop translation as we may have switched the execution mode */
7559 ctx
->bstate
= BS_STOP
;
7560 rn
= "TraceControl2";
7563 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7564 /* Stop translation as we may have switched the execution mode */
7565 ctx
->bstate
= BS_STOP
;
7566 rn
= "UserTraceData";
7569 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7570 /* Stop translation as we may have switched the execution mode */
7571 ctx
->bstate
= BS_STOP
;
7575 goto cp0_unimplemented
;
7582 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7586 goto cp0_unimplemented
;
7592 gen_helper_mtc0_performance0(cpu_env
, arg
);
7593 rn
= "Performance0";
7596 // gen_helper_mtc0_performance1(cpu_env, arg);
7597 rn
= "Performance1";
7600 // gen_helper_mtc0_performance2(cpu_env, arg);
7601 rn
= "Performance2";
7604 // gen_helper_mtc0_performance3(cpu_env, arg);
7605 rn
= "Performance3";
7608 // gen_helper_mtc0_performance4(cpu_env, arg);
7609 rn
= "Performance4";
7612 // gen_helper_mtc0_performance5(cpu_env, arg);
7613 rn
= "Performance5";
7616 // gen_helper_mtc0_performance6(cpu_env, arg);
7617 rn
= "Performance6";
7620 // gen_helper_mtc0_performance7(cpu_env, arg);
7621 rn
= "Performance7";
7624 goto cp0_unimplemented
;
7638 goto cp0_unimplemented
;
7647 gen_helper_mtc0_taglo(cpu_env
, arg
);
7654 gen_helper_mtc0_datalo(cpu_env
, arg
);
7658 goto cp0_unimplemented
;
7667 gen_helper_mtc0_taghi(cpu_env
, arg
);
7674 gen_helper_mtc0_datahi(cpu_env
, arg
);
7679 goto cp0_unimplemented
;
7685 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7689 goto cp0_unimplemented
;
7696 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7700 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7701 tcg_gen_st_tl(arg
, cpu_env
,
7702 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7706 goto cp0_unimplemented
;
7708 /* Stop translation as we may have switched the execution mode */
7709 ctx
->bstate
= BS_STOP
;
7712 goto cp0_unimplemented
;
7714 (void)rn
; /* avoid a compiler warning */
7715 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7716 /* For simplicity assume that all writes can cause interrupts. */
7717 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7719 ctx
->bstate
= BS_STOP
;
7724 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7726 #endif /* TARGET_MIPS64 */
7728 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
7729 int u
, int sel
, int h
)
7731 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7732 TCGv t0
= tcg_temp_local_new();
7734 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7735 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7736 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7737 tcg_gen_movi_tl(t0
, -1);
7738 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7739 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7740 tcg_gen_movi_tl(t0
, -1);
7746 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
7749 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
7759 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
7762 gen_helper_mftc0_tcbind(t0
, cpu_env
);
7765 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
7768 gen_helper_mftc0_tchalt(t0
, cpu_env
);
7771 gen_helper_mftc0_tccontext(t0
, cpu_env
);
7774 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
7777 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
7780 gen_mfc0(ctx
, t0
, rt
, sel
);
7787 gen_helper_mftc0_entryhi(t0
, cpu_env
);
7790 gen_mfc0(ctx
, t0
, rt
, sel
);
7796 gen_helper_mftc0_status(t0
, cpu_env
);
7799 gen_mfc0(ctx
, t0
, rt
, sel
);
7805 gen_helper_mftc0_cause(t0
, cpu_env
);
7815 gen_helper_mftc0_epc(t0
, cpu_env
);
7825 gen_helper_mftc0_ebase(t0
, cpu_env
);
7835 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
7845 gen_helper_mftc0_debug(t0
, cpu_env
);
7848 gen_mfc0(ctx
, t0
, rt
, sel
);
7853 gen_mfc0(ctx
, t0
, rt
, sel
);
7855 } else switch (sel
) {
7856 /* GPR registers. */
7858 gen_helper_1e0i(mftgpr
, t0
, rt
);
7860 /* Auxiliary CPU registers */
7864 gen_helper_1e0i(mftlo
, t0
, 0);
7867 gen_helper_1e0i(mfthi
, t0
, 0);
7870 gen_helper_1e0i(mftacx
, t0
, 0);
7873 gen_helper_1e0i(mftlo
, t0
, 1);
7876 gen_helper_1e0i(mfthi
, t0
, 1);
7879 gen_helper_1e0i(mftacx
, t0
, 1);
7882 gen_helper_1e0i(mftlo
, t0
, 2);
7885 gen_helper_1e0i(mfthi
, t0
, 2);
7888 gen_helper_1e0i(mftacx
, t0
, 2);
7891 gen_helper_1e0i(mftlo
, t0
, 3);
7894 gen_helper_1e0i(mfthi
, t0
, 3);
7897 gen_helper_1e0i(mftacx
, t0
, 3);
7900 gen_helper_mftdsp(t0
, cpu_env
);
7906 /* Floating point (COP1). */
7908 /* XXX: For now we support only a single FPU context. */
7910 TCGv_i32 fp0
= tcg_temp_new_i32();
7912 gen_load_fpr32(ctx
, fp0
, rt
);
7913 tcg_gen_ext_i32_tl(t0
, fp0
);
7914 tcg_temp_free_i32(fp0
);
7916 TCGv_i32 fp0
= tcg_temp_new_i32();
7918 gen_load_fpr32h(ctx
, fp0
, rt
);
7919 tcg_gen_ext_i32_tl(t0
, fp0
);
7920 tcg_temp_free_i32(fp0
);
7924 /* XXX: For now we support only a single FPU context. */
7925 gen_helper_1e0i(cfc1
, t0
, rt
);
7927 /* COP2: Not implemented. */
7934 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7935 gen_store_gpr(t0
, rd
);
7941 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7942 generate_exception(ctx
, EXCP_RI
);
7945 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
7946 int u
, int sel
, int h
)
7948 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7949 TCGv t0
= tcg_temp_local_new();
7951 gen_load_gpr(t0
, rt
);
7952 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7953 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7954 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7956 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7957 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7964 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
7967 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
7977 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
7980 gen_helper_mttc0_tcbind(cpu_env
, t0
);
7983 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
7986 gen_helper_mttc0_tchalt(cpu_env
, t0
);
7989 gen_helper_mttc0_tccontext(cpu_env
, t0
);
7992 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
7995 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
7998 gen_mtc0(ctx
, t0
, rd
, sel
);
8005 gen_helper_mttc0_entryhi(cpu_env
, t0
);
8008 gen_mtc0(ctx
, t0
, rd
, sel
);
8014 gen_helper_mttc0_status(cpu_env
, t0
);
8017 gen_mtc0(ctx
, t0
, rd
, sel
);
8023 gen_helper_mttc0_cause(cpu_env
, t0
);
8033 gen_helper_mttc0_ebase(cpu_env
, t0
);
8043 gen_helper_mttc0_debug(cpu_env
, t0
);
8046 gen_mtc0(ctx
, t0
, rd
, sel
);
8051 gen_mtc0(ctx
, t0
, rd
, sel
);
8053 } else switch (sel
) {
8054 /* GPR registers. */
8056 gen_helper_0e1i(mttgpr
, t0
, rd
);
8058 /* Auxiliary CPU registers */
8062 gen_helper_0e1i(mttlo
, t0
, 0);
8065 gen_helper_0e1i(mtthi
, t0
, 0);
8068 gen_helper_0e1i(mttacx
, t0
, 0);
8071 gen_helper_0e1i(mttlo
, t0
, 1);
8074 gen_helper_0e1i(mtthi
, t0
, 1);
8077 gen_helper_0e1i(mttacx
, t0
, 1);
8080 gen_helper_0e1i(mttlo
, t0
, 2);
8083 gen_helper_0e1i(mtthi
, t0
, 2);
8086 gen_helper_0e1i(mttacx
, t0
, 2);
8089 gen_helper_0e1i(mttlo
, t0
, 3);
8092 gen_helper_0e1i(mtthi
, t0
, 3);
8095 gen_helper_0e1i(mttacx
, t0
, 3);
8098 gen_helper_mttdsp(cpu_env
, t0
);
8104 /* Floating point (COP1). */
8106 /* XXX: For now we support only a single FPU context. */
8108 TCGv_i32 fp0
= tcg_temp_new_i32();
8110 tcg_gen_trunc_tl_i32(fp0
, t0
);
8111 gen_store_fpr32(ctx
, fp0
, rd
);
8112 tcg_temp_free_i32(fp0
);
8114 TCGv_i32 fp0
= tcg_temp_new_i32();
8116 tcg_gen_trunc_tl_i32(fp0
, t0
);
8117 gen_store_fpr32h(ctx
, fp0
, rd
);
8118 tcg_temp_free_i32(fp0
);
8122 /* XXX: For now we support only a single FPU context. */
8123 save_cpu_state(ctx
, 1);
8125 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
8127 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8128 tcg_temp_free_i32(fs_tmp
);
8130 /* Stop translation as we may have changed hflags */
8131 ctx
->bstate
= BS_STOP
;
8133 /* COP2: Not implemented. */
8140 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
8146 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
8147 generate_exception(ctx
, EXCP_RI
);
8150 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
8152 const char *opn
= "ldst";
8154 check_cp0_enabled(ctx
);
8161 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8166 TCGv t0
= tcg_temp_new();
8168 gen_load_gpr(t0
, rt
);
8169 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8174 #if defined(TARGET_MIPS64)
8176 check_insn(ctx
, ISA_MIPS3
);
8181 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8185 check_insn(ctx
, ISA_MIPS3
);
8187 TCGv t0
= tcg_temp_new();
8189 gen_load_gpr(t0
, rt
);
8190 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8202 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8208 TCGv t0
= tcg_temp_new();
8209 gen_load_gpr(t0
, rt
);
8210 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8216 check_insn(ctx
, ASE_MT
);
8221 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
8222 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
8226 check_insn(ctx
, ASE_MT
);
8227 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
8228 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
8233 if (!env
->tlb
->helper_tlbwi
)
8235 gen_helper_tlbwi(cpu_env
);
8240 if (!env
->tlb
->helper_tlbinv
) {
8243 gen_helper_tlbinv(cpu_env
);
8244 } /* treat as nop if TLBINV not supported */
8249 if (!env
->tlb
->helper_tlbinvf
) {
8252 gen_helper_tlbinvf(cpu_env
);
8253 } /* treat as nop if TLBINV not supported */
8257 if (!env
->tlb
->helper_tlbwr
)
8259 gen_helper_tlbwr(cpu_env
);
8263 if (!env
->tlb
->helper_tlbp
)
8265 gen_helper_tlbp(cpu_env
);
8269 if (!env
->tlb
->helper_tlbr
)
8271 gen_helper_tlbr(cpu_env
);
8273 case OPC_ERET
: /* OPC_ERETNC */
8274 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8275 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8276 MIPS_DEBUG("CTI in delay / forbidden slot");
8279 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
8280 if (ctx
->opcode
& (1 << bit_shift
)) {
8283 check_insn(ctx
, ISA_MIPS32R5
);
8284 gen_helper_eretnc(cpu_env
);
8288 check_insn(ctx
, ISA_MIPS2
);
8289 gen_helper_eret(cpu_env
);
8291 ctx
->bstate
= BS_EXCP
;
8296 check_insn(ctx
, ISA_MIPS32
);
8297 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8298 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8299 MIPS_DEBUG("CTI in delay / forbidden slot");
8302 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
8304 generate_exception(ctx
, EXCP_RI
);
8306 gen_helper_deret(cpu_env
);
8307 ctx
->bstate
= BS_EXCP
;
8312 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
8313 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8314 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8315 MIPS_DEBUG("CTI in delay / forbidden slot");
8318 /* If we get an exception, we want to restart at next instruction */
8320 save_cpu_state(ctx
, 1);
8322 gen_helper_wait(cpu_env
);
8323 ctx
->bstate
= BS_EXCP
;
8328 generate_exception(ctx
, EXCP_RI
);
8331 (void)opn
; /* avoid a compiler warning */
8332 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
8334 #endif /* !CONFIG_USER_ONLY */
8336 /* CP1 Branches (before delay slot) */
8337 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
8338 int32_t cc
, int32_t offset
)
8340 target_ulong btarget
;
8341 const char *opn
= "cp1 cond branch";
8342 TCGv_i32 t0
= tcg_temp_new_i32();
8344 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8345 MIPS_DEBUG("CTI in delay / forbidden slot");
8346 generate_exception(ctx
, EXCP_RI
);
8351 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
8353 btarget
= ctx
->pc
+ 4 + offset
;
8357 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8358 tcg_gen_not_i32(t0
, t0
);
8359 tcg_gen_andi_i32(t0
, t0
, 1);
8360 tcg_gen_extu_i32_tl(bcond
, t0
);
8364 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8365 tcg_gen_not_i32(t0
, t0
);
8366 tcg_gen_andi_i32(t0
, t0
, 1);
8367 tcg_gen_extu_i32_tl(bcond
, t0
);
8371 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8372 tcg_gen_andi_i32(t0
, t0
, 1);
8373 tcg_gen_extu_i32_tl(bcond
, t0
);
8377 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8378 tcg_gen_andi_i32(t0
, t0
, 1);
8379 tcg_gen_extu_i32_tl(bcond
, t0
);
8382 ctx
->hflags
|= MIPS_HFLAG_BL
;
8386 TCGv_i32 t1
= tcg_temp_new_i32();
8387 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8388 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8389 tcg_gen_nand_i32(t0
, t0
, t1
);
8390 tcg_temp_free_i32(t1
);
8391 tcg_gen_andi_i32(t0
, t0
, 1);
8392 tcg_gen_extu_i32_tl(bcond
, t0
);
8398 TCGv_i32 t1
= tcg_temp_new_i32();
8399 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8400 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8401 tcg_gen_or_i32(t0
, t0
, t1
);
8402 tcg_temp_free_i32(t1
);
8403 tcg_gen_andi_i32(t0
, t0
, 1);
8404 tcg_gen_extu_i32_tl(bcond
, t0
);
8410 TCGv_i32 t1
= tcg_temp_new_i32();
8411 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8412 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8413 tcg_gen_and_i32(t0
, t0
, t1
);
8414 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8415 tcg_gen_and_i32(t0
, t0
, t1
);
8416 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8417 tcg_gen_nand_i32(t0
, t0
, t1
);
8418 tcg_temp_free_i32(t1
);
8419 tcg_gen_andi_i32(t0
, t0
, 1);
8420 tcg_gen_extu_i32_tl(bcond
, t0
);
8426 TCGv_i32 t1
= tcg_temp_new_i32();
8427 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8428 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8429 tcg_gen_or_i32(t0
, t0
, t1
);
8430 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8431 tcg_gen_or_i32(t0
, t0
, t1
);
8432 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8433 tcg_gen_or_i32(t0
, t0
, t1
);
8434 tcg_temp_free_i32(t1
);
8435 tcg_gen_andi_i32(t0
, t0
, 1);
8436 tcg_gen_extu_i32_tl(bcond
, t0
);
8440 ctx
->hflags
|= MIPS_HFLAG_BC
;
8444 generate_exception (ctx
, EXCP_RI
);
8447 (void)opn
; /* avoid a compiler warning */
8448 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
8449 ctx
->hflags
, btarget
);
8450 ctx
->btarget
= btarget
;
8451 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8453 tcg_temp_free_i32(t0
);
8456 /* R6 CP1 Branches */
8457 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
8458 int32_t ft
, int32_t offset
,
8461 target_ulong btarget
;
8462 const char *opn
= "cp1 cond branch";
8463 TCGv_i64 t0
= tcg_temp_new_i64();
8465 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
8466 #ifdef MIPS_DEBUG_DISAS
8467 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8470 generate_exception(ctx
, EXCP_RI
);
8474 gen_load_fpr64(ctx
, t0
, ft
);
8475 tcg_gen_andi_i64(t0
, t0
, 1);
8477 btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
8481 tcg_gen_xori_i64(t0
, t0
, 1);
8483 ctx
->hflags
|= MIPS_HFLAG_BC
;
8486 /* t0 already set */
8488 ctx
->hflags
|= MIPS_HFLAG_BC
;
8492 generate_exception(ctx
, EXCP_RI
);
8496 tcg_gen_trunc_i64_tl(bcond
, t0
);
8498 (void)opn
; /* avoid a compiler warning */
8499 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
8500 ctx
->hflags
, btarget
);
8501 ctx
->btarget
= btarget
;
8503 switch (delayslot_size
) {
8505 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
8508 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8513 tcg_temp_free_i64(t0
);
8516 /* Coprocessor 1 (FPU) */
8518 #define FOP(func, fmt) (((fmt) << 21) | (func))
8521 OPC_ADD_S
= FOP(0, FMT_S
),
8522 OPC_SUB_S
= FOP(1, FMT_S
),
8523 OPC_MUL_S
= FOP(2, FMT_S
),
8524 OPC_DIV_S
= FOP(3, FMT_S
),
8525 OPC_SQRT_S
= FOP(4, FMT_S
),
8526 OPC_ABS_S
= FOP(5, FMT_S
),
8527 OPC_MOV_S
= FOP(6, FMT_S
),
8528 OPC_NEG_S
= FOP(7, FMT_S
),
8529 OPC_ROUND_L_S
= FOP(8, FMT_S
),
8530 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
8531 OPC_CEIL_L_S
= FOP(10, FMT_S
),
8532 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
8533 OPC_ROUND_W_S
= FOP(12, FMT_S
),
8534 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
8535 OPC_CEIL_W_S
= FOP(14, FMT_S
),
8536 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
8537 OPC_SEL_S
= FOP(16, FMT_S
),
8538 OPC_MOVCF_S
= FOP(17, FMT_S
),
8539 OPC_MOVZ_S
= FOP(18, FMT_S
),
8540 OPC_MOVN_S
= FOP(19, FMT_S
),
8541 OPC_SELEQZ_S
= FOP(20, FMT_S
),
8542 OPC_RECIP_S
= FOP(21, FMT_S
),
8543 OPC_RSQRT_S
= FOP(22, FMT_S
),
8544 OPC_SELNEZ_S
= FOP(23, FMT_S
),
8545 OPC_MADDF_S
= FOP(24, FMT_S
),
8546 OPC_MSUBF_S
= FOP(25, FMT_S
),
8547 OPC_RINT_S
= FOP(26, FMT_S
),
8548 OPC_CLASS_S
= FOP(27, FMT_S
),
8549 OPC_MIN_S
= FOP(28, FMT_S
),
8550 OPC_RECIP2_S
= FOP(28, FMT_S
),
8551 OPC_MINA_S
= FOP(29, FMT_S
),
8552 OPC_RECIP1_S
= FOP(29, FMT_S
),
8553 OPC_MAX_S
= FOP(30, FMT_S
),
8554 OPC_RSQRT1_S
= FOP(30, FMT_S
),
8555 OPC_MAXA_S
= FOP(31, FMT_S
),
8556 OPC_RSQRT2_S
= FOP(31, FMT_S
),
8557 OPC_CVT_D_S
= FOP(33, FMT_S
),
8558 OPC_CVT_W_S
= FOP(36, FMT_S
),
8559 OPC_CVT_L_S
= FOP(37, FMT_S
),
8560 OPC_CVT_PS_S
= FOP(38, FMT_S
),
8561 OPC_CMP_F_S
= FOP (48, FMT_S
),
8562 OPC_CMP_UN_S
= FOP (49, FMT_S
),
8563 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
8564 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
8565 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
8566 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
8567 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
8568 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
8569 OPC_CMP_SF_S
= FOP (56, FMT_S
),
8570 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
8571 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
8572 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
8573 OPC_CMP_LT_S
= FOP (60, FMT_S
),
8574 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
8575 OPC_CMP_LE_S
= FOP (62, FMT_S
),
8576 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
8578 OPC_ADD_D
= FOP(0, FMT_D
),
8579 OPC_SUB_D
= FOP(1, FMT_D
),
8580 OPC_MUL_D
= FOP(2, FMT_D
),
8581 OPC_DIV_D
= FOP(3, FMT_D
),
8582 OPC_SQRT_D
= FOP(4, FMT_D
),
8583 OPC_ABS_D
= FOP(5, FMT_D
),
8584 OPC_MOV_D
= FOP(6, FMT_D
),
8585 OPC_NEG_D
= FOP(7, FMT_D
),
8586 OPC_ROUND_L_D
= FOP(8, FMT_D
),
8587 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
8588 OPC_CEIL_L_D
= FOP(10, FMT_D
),
8589 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
8590 OPC_ROUND_W_D
= FOP(12, FMT_D
),
8591 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
8592 OPC_CEIL_W_D
= FOP(14, FMT_D
),
8593 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
8594 OPC_SEL_D
= FOP(16, FMT_D
),
8595 OPC_MOVCF_D
= FOP(17, FMT_D
),
8596 OPC_MOVZ_D
= FOP(18, FMT_D
),
8597 OPC_MOVN_D
= FOP(19, FMT_D
),
8598 OPC_SELEQZ_D
= FOP(20, FMT_D
),
8599 OPC_RECIP_D
= FOP(21, FMT_D
),
8600 OPC_RSQRT_D
= FOP(22, FMT_D
),
8601 OPC_SELNEZ_D
= FOP(23, FMT_D
),
8602 OPC_MADDF_D
= FOP(24, FMT_D
),
8603 OPC_MSUBF_D
= FOP(25, FMT_D
),
8604 OPC_RINT_D
= FOP(26, FMT_D
),
8605 OPC_CLASS_D
= FOP(27, FMT_D
),
8606 OPC_MIN_D
= FOP(28, FMT_D
),
8607 OPC_RECIP2_D
= FOP(28, FMT_D
),
8608 OPC_MINA_D
= FOP(29, FMT_D
),
8609 OPC_RECIP1_D
= FOP(29, FMT_D
),
8610 OPC_MAX_D
= FOP(30, FMT_D
),
8611 OPC_RSQRT1_D
= FOP(30, FMT_D
),
8612 OPC_MAXA_D
= FOP(31, FMT_D
),
8613 OPC_RSQRT2_D
= FOP(31, FMT_D
),
8614 OPC_CVT_S_D
= FOP(32, FMT_D
),
8615 OPC_CVT_W_D
= FOP(36, FMT_D
),
8616 OPC_CVT_L_D
= FOP(37, FMT_D
),
8617 OPC_CMP_F_D
= FOP (48, FMT_D
),
8618 OPC_CMP_UN_D
= FOP (49, FMT_D
),
8619 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
8620 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
8621 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
8622 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
8623 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
8624 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
8625 OPC_CMP_SF_D
= FOP (56, FMT_D
),
8626 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
8627 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
8628 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
8629 OPC_CMP_LT_D
= FOP (60, FMT_D
),
8630 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
8631 OPC_CMP_LE_D
= FOP (62, FMT_D
),
8632 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
8634 OPC_CVT_S_W
= FOP(32, FMT_W
),
8635 OPC_CVT_D_W
= FOP(33, FMT_W
),
8636 OPC_CVT_S_L
= FOP(32, FMT_L
),
8637 OPC_CVT_D_L
= FOP(33, FMT_L
),
8638 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
8640 OPC_ADD_PS
= FOP(0, FMT_PS
),
8641 OPC_SUB_PS
= FOP(1, FMT_PS
),
8642 OPC_MUL_PS
= FOP(2, FMT_PS
),
8643 OPC_DIV_PS
= FOP(3, FMT_PS
),
8644 OPC_ABS_PS
= FOP(5, FMT_PS
),
8645 OPC_MOV_PS
= FOP(6, FMT_PS
),
8646 OPC_NEG_PS
= FOP(7, FMT_PS
),
8647 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
8648 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
8649 OPC_MOVN_PS
= FOP(19, FMT_PS
),
8650 OPC_ADDR_PS
= FOP(24, FMT_PS
),
8651 OPC_MULR_PS
= FOP(26, FMT_PS
),
8652 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
8653 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
8654 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
8655 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
8657 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
8658 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
8659 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
8660 OPC_PLL_PS
= FOP(44, FMT_PS
),
8661 OPC_PLU_PS
= FOP(45, FMT_PS
),
8662 OPC_PUL_PS
= FOP(46, FMT_PS
),
8663 OPC_PUU_PS
= FOP(47, FMT_PS
),
8664 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
8665 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
8666 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
8667 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
8668 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
8669 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
8670 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
8671 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
8672 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
8673 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
8674 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
8675 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
8676 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
8677 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
8678 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
8679 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
8683 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
8684 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
8685 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
8686 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
8687 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
8688 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
8689 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
8690 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
8691 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
8692 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
8693 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
8694 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
8695 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
8696 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
8697 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
8698 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
8699 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
8700 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
8701 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
8702 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
8703 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
8704 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
8706 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
8707 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
8708 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
8709 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
8710 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
8711 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
8712 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
8713 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
8714 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
8715 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
8716 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
8717 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
8718 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
8719 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
8720 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
8721 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
8722 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
8723 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
8724 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
8725 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
8726 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
8727 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
8729 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
8731 const char *opn
= "cp1 move";
8732 TCGv t0
= tcg_temp_new();
8737 TCGv_i32 fp0
= tcg_temp_new_i32();
8739 gen_load_fpr32(ctx
, fp0
, fs
);
8740 tcg_gen_ext_i32_tl(t0
, fp0
);
8741 tcg_temp_free_i32(fp0
);
8743 gen_store_gpr(t0
, rt
);
8747 gen_load_gpr(t0
, rt
);
8749 TCGv_i32 fp0
= tcg_temp_new_i32();
8751 tcg_gen_trunc_tl_i32(fp0
, t0
);
8752 gen_store_fpr32(ctx
, fp0
, fs
);
8753 tcg_temp_free_i32(fp0
);
8758 gen_helper_1e0i(cfc1
, t0
, fs
);
8759 gen_store_gpr(t0
, rt
);
8763 gen_load_gpr(t0
, rt
);
8764 save_cpu_state(ctx
, 1);
8766 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
8768 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8769 tcg_temp_free_i32(fs_tmp
);
8771 /* Stop translation as we may have changed hflags */
8772 ctx
->bstate
= BS_STOP
;
8775 #if defined(TARGET_MIPS64)
8777 gen_load_fpr64(ctx
, t0
, fs
);
8778 gen_store_gpr(t0
, rt
);
8782 gen_load_gpr(t0
, rt
);
8783 gen_store_fpr64(ctx
, t0
, fs
);
8789 TCGv_i32 fp0
= tcg_temp_new_i32();
8791 gen_load_fpr32h(ctx
, fp0
, fs
);
8792 tcg_gen_ext_i32_tl(t0
, fp0
);
8793 tcg_temp_free_i32(fp0
);
8795 gen_store_gpr(t0
, rt
);
8799 gen_load_gpr(t0
, rt
);
8801 TCGv_i32 fp0
= tcg_temp_new_i32();
8803 tcg_gen_trunc_tl_i32(fp0
, t0
);
8804 gen_store_fpr32h(ctx
, fp0
, fs
);
8805 tcg_temp_free_i32(fp0
);
8811 generate_exception (ctx
, EXCP_RI
);
8814 (void)opn
; /* avoid a compiler warning */
8815 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
8821 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
8837 l1
= gen_new_label();
8838 t0
= tcg_temp_new_i32();
8839 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8840 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8841 tcg_temp_free_i32(t0
);
8843 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
8845 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
8850 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
8854 TCGv_i32 t0
= tcg_temp_new_i32();
8855 TCGLabel
*l1
= gen_new_label();
8862 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8863 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8864 gen_load_fpr32(ctx
, t0
, fs
);
8865 gen_store_fpr32(ctx
, t0
, fd
);
8867 tcg_temp_free_i32(t0
);
8870 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
8873 TCGv_i32 t0
= tcg_temp_new_i32();
8875 TCGLabel
*l1
= gen_new_label();
8882 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8883 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8884 tcg_temp_free_i32(t0
);
8885 fp0
= tcg_temp_new_i64();
8886 gen_load_fpr64(ctx
, fp0
, fs
);
8887 gen_store_fpr64(ctx
, fp0
, fd
);
8888 tcg_temp_free_i64(fp0
);
8892 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
8896 TCGv_i32 t0
= tcg_temp_new_i32();
8897 TCGLabel
*l1
= gen_new_label();
8898 TCGLabel
*l2
= gen_new_label();
8905 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8906 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8907 gen_load_fpr32(ctx
, t0
, fs
);
8908 gen_store_fpr32(ctx
, t0
, fd
);
8911 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
8912 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
8913 gen_load_fpr32h(ctx
, t0
, fs
);
8914 gen_store_fpr32h(ctx
, t0
, fd
);
8915 tcg_temp_free_i32(t0
);
8919 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8922 TCGv_i32 t1
= tcg_const_i32(0);
8923 TCGv_i32 fp0
= tcg_temp_new_i32();
8924 TCGv_i32 fp1
= tcg_temp_new_i32();
8925 TCGv_i32 fp2
= tcg_temp_new_i32();
8926 gen_load_fpr32(ctx
, fp0
, fd
);
8927 gen_load_fpr32(ctx
, fp1
, ft
);
8928 gen_load_fpr32(ctx
, fp2
, fs
);
8932 tcg_gen_andi_i32(fp0
, fp0
, 1);
8933 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8936 tcg_gen_andi_i32(fp1
, fp1
, 1);
8937 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8940 tcg_gen_andi_i32(fp1
, fp1
, 1);
8941 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8944 MIPS_INVAL("gen_sel_s");
8945 generate_exception (ctx
, EXCP_RI
);
8949 gen_store_fpr32(ctx
, fp0
, fd
);
8950 tcg_temp_free_i32(fp2
);
8951 tcg_temp_free_i32(fp1
);
8952 tcg_temp_free_i32(fp0
);
8953 tcg_temp_free_i32(t1
);
8956 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8959 TCGv_i64 t1
= tcg_const_i64(0);
8960 TCGv_i64 fp0
= tcg_temp_new_i64();
8961 TCGv_i64 fp1
= tcg_temp_new_i64();
8962 TCGv_i64 fp2
= tcg_temp_new_i64();
8963 gen_load_fpr64(ctx
, fp0
, fd
);
8964 gen_load_fpr64(ctx
, fp1
, ft
);
8965 gen_load_fpr64(ctx
, fp2
, fs
);
8969 tcg_gen_andi_i64(fp0
, fp0
, 1);
8970 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8973 tcg_gen_andi_i64(fp1
, fp1
, 1);
8974 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8977 tcg_gen_andi_i64(fp1
, fp1
, 1);
8978 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8981 MIPS_INVAL("gen_sel_d");
8982 generate_exception (ctx
, EXCP_RI
);
8986 gen_store_fpr64(ctx
, fp0
, fd
);
8987 tcg_temp_free_i64(fp2
);
8988 tcg_temp_free_i64(fp1
);
8989 tcg_temp_free_i64(fp0
);
8990 tcg_temp_free_i64(t1
);
8993 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
8994 int ft
, int fs
, int fd
, int cc
)
8996 const char *opn
= "farith";
8997 const char *condnames
[] = {
9015 const char *condnames_abs
[] = {
9033 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
9034 uint32_t func
= ctx
->opcode
& 0x3f;
9038 TCGv_i32 fp0
= tcg_temp_new_i32();
9039 TCGv_i32 fp1
= tcg_temp_new_i32();
9041 gen_load_fpr32(ctx
, fp0
, fs
);
9042 gen_load_fpr32(ctx
, fp1
, ft
);
9043 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
9044 tcg_temp_free_i32(fp1
);
9045 gen_store_fpr32(ctx
, fp0
, fd
);
9046 tcg_temp_free_i32(fp0
);
9053 TCGv_i32 fp0
= tcg_temp_new_i32();
9054 TCGv_i32 fp1
= tcg_temp_new_i32();
9056 gen_load_fpr32(ctx
, fp0
, fs
);
9057 gen_load_fpr32(ctx
, fp1
, ft
);
9058 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
9059 tcg_temp_free_i32(fp1
);
9060 gen_store_fpr32(ctx
, fp0
, fd
);
9061 tcg_temp_free_i32(fp0
);
9068 TCGv_i32 fp0
= tcg_temp_new_i32();
9069 TCGv_i32 fp1
= tcg_temp_new_i32();
9071 gen_load_fpr32(ctx
, fp0
, fs
);
9072 gen_load_fpr32(ctx
, fp1
, ft
);
9073 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
9074 tcg_temp_free_i32(fp1
);
9075 gen_store_fpr32(ctx
, fp0
, fd
);
9076 tcg_temp_free_i32(fp0
);
9083 TCGv_i32 fp0
= tcg_temp_new_i32();
9084 TCGv_i32 fp1
= tcg_temp_new_i32();
9086 gen_load_fpr32(ctx
, fp0
, fs
);
9087 gen_load_fpr32(ctx
, fp1
, ft
);
9088 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
9089 tcg_temp_free_i32(fp1
);
9090 gen_store_fpr32(ctx
, fp0
, fd
);
9091 tcg_temp_free_i32(fp0
);
9098 TCGv_i32 fp0
= tcg_temp_new_i32();
9100 gen_load_fpr32(ctx
, fp0
, fs
);
9101 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
9102 gen_store_fpr32(ctx
, fp0
, fd
);
9103 tcg_temp_free_i32(fp0
);
9109 TCGv_i32 fp0
= tcg_temp_new_i32();
9111 gen_load_fpr32(ctx
, fp0
, fs
);
9112 gen_helper_float_abs_s(fp0
, fp0
);
9113 gen_store_fpr32(ctx
, fp0
, fd
);
9114 tcg_temp_free_i32(fp0
);
9120 TCGv_i32 fp0
= tcg_temp_new_i32();
9122 gen_load_fpr32(ctx
, fp0
, fs
);
9123 gen_store_fpr32(ctx
, fp0
, fd
);
9124 tcg_temp_free_i32(fp0
);
9130 TCGv_i32 fp0
= tcg_temp_new_i32();
9132 gen_load_fpr32(ctx
, fp0
, fs
);
9133 gen_helper_float_chs_s(fp0
, fp0
);
9134 gen_store_fpr32(ctx
, fp0
, fd
);
9135 tcg_temp_free_i32(fp0
);
9140 check_cp1_64bitmode(ctx
);
9142 TCGv_i32 fp32
= tcg_temp_new_i32();
9143 TCGv_i64 fp64
= tcg_temp_new_i64();
9145 gen_load_fpr32(ctx
, fp32
, fs
);
9146 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
9147 tcg_temp_free_i32(fp32
);
9148 gen_store_fpr64(ctx
, fp64
, fd
);
9149 tcg_temp_free_i64(fp64
);
9154 check_cp1_64bitmode(ctx
);
9156 TCGv_i32 fp32
= tcg_temp_new_i32();
9157 TCGv_i64 fp64
= tcg_temp_new_i64();
9159 gen_load_fpr32(ctx
, fp32
, fs
);
9160 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
9161 tcg_temp_free_i32(fp32
);
9162 gen_store_fpr64(ctx
, fp64
, fd
);
9163 tcg_temp_free_i64(fp64
);
9168 check_cp1_64bitmode(ctx
);
9170 TCGv_i32 fp32
= tcg_temp_new_i32();
9171 TCGv_i64 fp64
= tcg_temp_new_i64();
9173 gen_load_fpr32(ctx
, fp32
, fs
);
9174 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
9175 tcg_temp_free_i32(fp32
);
9176 gen_store_fpr64(ctx
, fp64
, fd
);
9177 tcg_temp_free_i64(fp64
);
9182 check_cp1_64bitmode(ctx
);
9184 TCGv_i32 fp32
= tcg_temp_new_i32();
9185 TCGv_i64 fp64
= tcg_temp_new_i64();
9187 gen_load_fpr32(ctx
, fp32
, fs
);
9188 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
9189 tcg_temp_free_i32(fp32
);
9190 gen_store_fpr64(ctx
, fp64
, fd
);
9191 tcg_temp_free_i64(fp64
);
9197 TCGv_i32 fp0
= tcg_temp_new_i32();
9199 gen_load_fpr32(ctx
, fp0
, fs
);
9200 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
9201 gen_store_fpr32(ctx
, fp0
, fd
);
9202 tcg_temp_free_i32(fp0
);
9208 TCGv_i32 fp0
= tcg_temp_new_i32();
9210 gen_load_fpr32(ctx
, fp0
, fs
);
9211 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
9212 gen_store_fpr32(ctx
, fp0
, fd
);
9213 tcg_temp_free_i32(fp0
);
9219 TCGv_i32 fp0
= tcg_temp_new_i32();
9221 gen_load_fpr32(ctx
, fp0
, fs
);
9222 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
9223 gen_store_fpr32(ctx
, fp0
, fd
);
9224 tcg_temp_free_i32(fp0
);
9230 TCGv_i32 fp0
= tcg_temp_new_i32();
9232 gen_load_fpr32(ctx
, fp0
, fs
);
9233 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
9234 gen_store_fpr32(ctx
, fp0
, fd
);
9235 tcg_temp_free_i32(fp0
);
9240 check_insn(ctx
, ISA_MIPS32R6
);
9241 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9245 check_insn(ctx
, ISA_MIPS32R6
);
9246 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9250 check_insn(ctx
, ISA_MIPS32R6
);
9251 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9255 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9256 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9260 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9262 TCGLabel
*l1
= gen_new_label();
9266 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9268 fp0
= tcg_temp_new_i32();
9269 gen_load_fpr32(ctx
, fp0
, fs
);
9270 gen_store_fpr32(ctx
, fp0
, fd
);
9271 tcg_temp_free_i32(fp0
);
9277 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9279 TCGLabel
*l1
= gen_new_label();
9283 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9284 fp0
= tcg_temp_new_i32();
9285 gen_load_fpr32(ctx
, fp0
, fs
);
9286 gen_store_fpr32(ctx
, fp0
, fd
);
9287 tcg_temp_free_i32(fp0
);
9296 TCGv_i32 fp0
= tcg_temp_new_i32();
9298 gen_load_fpr32(ctx
, fp0
, fs
);
9299 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
9300 gen_store_fpr32(ctx
, fp0
, fd
);
9301 tcg_temp_free_i32(fp0
);
9308 TCGv_i32 fp0
= tcg_temp_new_i32();
9310 gen_load_fpr32(ctx
, fp0
, fs
);
9311 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
9312 gen_store_fpr32(ctx
, fp0
, fd
);
9313 tcg_temp_free_i32(fp0
);
9318 check_insn(ctx
, ISA_MIPS32R6
);
9320 TCGv_i32 fp0
= tcg_temp_new_i32();
9321 TCGv_i32 fp1
= tcg_temp_new_i32();
9322 TCGv_i32 fp2
= tcg_temp_new_i32();
9323 gen_load_fpr32(ctx
, fp0
, fs
);
9324 gen_load_fpr32(ctx
, fp1
, ft
);
9325 gen_load_fpr32(ctx
, fp2
, fd
);
9326 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9327 gen_store_fpr32(ctx
, fp2
, fd
);
9328 tcg_temp_free_i32(fp2
);
9329 tcg_temp_free_i32(fp1
);
9330 tcg_temp_free_i32(fp0
);
9335 check_insn(ctx
, ISA_MIPS32R6
);
9337 TCGv_i32 fp0
= tcg_temp_new_i32();
9338 TCGv_i32 fp1
= tcg_temp_new_i32();
9339 TCGv_i32 fp2
= tcg_temp_new_i32();
9340 gen_load_fpr32(ctx
, fp0
, fs
);
9341 gen_load_fpr32(ctx
, fp1
, ft
);
9342 gen_load_fpr32(ctx
, fp2
, fd
);
9343 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9344 gen_store_fpr32(ctx
, fp2
, fd
);
9345 tcg_temp_free_i32(fp2
);
9346 tcg_temp_free_i32(fp1
);
9347 tcg_temp_free_i32(fp0
);
9352 check_insn(ctx
, ISA_MIPS32R6
);
9354 TCGv_i32 fp0
= tcg_temp_new_i32();
9355 gen_load_fpr32(ctx
, fp0
, fs
);
9356 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
9357 gen_store_fpr32(ctx
, fp0
, fd
);
9358 tcg_temp_free_i32(fp0
);
9363 check_insn(ctx
, ISA_MIPS32R6
);
9365 TCGv_i32 fp0
= tcg_temp_new_i32();
9366 gen_load_fpr32(ctx
, fp0
, fs
);
9367 gen_helper_float_class_s(fp0
, fp0
);
9368 gen_store_fpr32(ctx
, fp0
, fd
);
9369 tcg_temp_free_i32(fp0
);
9373 case OPC_MIN_S
: /* OPC_RECIP2_S */
9374 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9376 TCGv_i32 fp0
= tcg_temp_new_i32();
9377 TCGv_i32 fp1
= tcg_temp_new_i32();
9378 TCGv_i32 fp2
= tcg_temp_new_i32();
9379 gen_load_fpr32(ctx
, fp0
, fs
);
9380 gen_load_fpr32(ctx
, fp1
, ft
);
9381 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
9382 gen_store_fpr32(ctx
, fp2
, fd
);
9383 tcg_temp_free_i32(fp2
);
9384 tcg_temp_free_i32(fp1
);
9385 tcg_temp_free_i32(fp0
);
9389 check_cp1_64bitmode(ctx
);
9391 TCGv_i32 fp0
= tcg_temp_new_i32();
9392 TCGv_i32 fp1
= tcg_temp_new_i32();
9394 gen_load_fpr32(ctx
, fp0
, fs
);
9395 gen_load_fpr32(ctx
, fp1
, ft
);
9396 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
9397 tcg_temp_free_i32(fp1
);
9398 gen_store_fpr32(ctx
, fp0
, fd
);
9399 tcg_temp_free_i32(fp0
);
9404 case OPC_MINA_S
: /* OPC_RECIP1_S */
9405 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9407 TCGv_i32 fp0
= tcg_temp_new_i32();
9408 TCGv_i32 fp1
= tcg_temp_new_i32();
9409 TCGv_i32 fp2
= tcg_temp_new_i32();
9410 gen_load_fpr32(ctx
, fp0
, fs
);
9411 gen_load_fpr32(ctx
, fp1
, ft
);
9412 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
9413 gen_store_fpr32(ctx
, fp2
, fd
);
9414 tcg_temp_free_i32(fp2
);
9415 tcg_temp_free_i32(fp1
);
9416 tcg_temp_free_i32(fp0
);
9420 check_cp1_64bitmode(ctx
);
9422 TCGv_i32 fp0
= tcg_temp_new_i32();
9424 gen_load_fpr32(ctx
, fp0
, fs
);
9425 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
9426 gen_store_fpr32(ctx
, fp0
, fd
);
9427 tcg_temp_free_i32(fp0
);
9432 case OPC_MAX_S
: /* OPC_RSQRT1_S */
9433 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9435 TCGv_i32 fp0
= tcg_temp_new_i32();
9436 TCGv_i32 fp1
= tcg_temp_new_i32();
9437 gen_load_fpr32(ctx
, fp0
, fs
);
9438 gen_load_fpr32(ctx
, fp1
, ft
);
9439 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
9440 gen_store_fpr32(ctx
, fp1
, fd
);
9441 tcg_temp_free_i32(fp1
);
9442 tcg_temp_free_i32(fp0
);
9446 check_cp1_64bitmode(ctx
);
9448 TCGv_i32 fp0
= tcg_temp_new_i32();
9450 gen_load_fpr32(ctx
, fp0
, fs
);
9451 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
9452 gen_store_fpr32(ctx
, fp0
, fd
);
9453 tcg_temp_free_i32(fp0
);
9458 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
9459 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9461 TCGv_i32 fp0
= tcg_temp_new_i32();
9462 TCGv_i32 fp1
= tcg_temp_new_i32();
9463 gen_load_fpr32(ctx
, fp0
, fs
);
9464 gen_load_fpr32(ctx
, fp1
, ft
);
9465 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
9466 gen_store_fpr32(ctx
, fp1
, fd
);
9467 tcg_temp_free_i32(fp1
);
9468 tcg_temp_free_i32(fp0
);
9472 check_cp1_64bitmode(ctx
);
9474 TCGv_i32 fp0
= tcg_temp_new_i32();
9475 TCGv_i32 fp1
= tcg_temp_new_i32();
9477 gen_load_fpr32(ctx
, fp0
, fs
);
9478 gen_load_fpr32(ctx
, fp1
, ft
);
9479 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
9480 tcg_temp_free_i32(fp1
);
9481 gen_store_fpr32(ctx
, fp0
, fd
);
9482 tcg_temp_free_i32(fp0
);
9488 check_cp1_registers(ctx
, fd
);
9490 TCGv_i32 fp32
= tcg_temp_new_i32();
9491 TCGv_i64 fp64
= tcg_temp_new_i64();
9493 gen_load_fpr32(ctx
, fp32
, fs
);
9494 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
9495 tcg_temp_free_i32(fp32
);
9496 gen_store_fpr64(ctx
, fp64
, fd
);
9497 tcg_temp_free_i64(fp64
);
9503 TCGv_i32 fp0
= tcg_temp_new_i32();
9505 gen_load_fpr32(ctx
, fp0
, fs
);
9506 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
9507 gen_store_fpr32(ctx
, fp0
, fd
);
9508 tcg_temp_free_i32(fp0
);
9513 check_cp1_64bitmode(ctx
);
9515 TCGv_i32 fp32
= tcg_temp_new_i32();
9516 TCGv_i64 fp64
= tcg_temp_new_i64();
9518 gen_load_fpr32(ctx
, fp32
, fs
);
9519 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
9520 tcg_temp_free_i32(fp32
);
9521 gen_store_fpr64(ctx
, fp64
, fd
);
9522 tcg_temp_free_i64(fp64
);
9529 TCGv_i64 fp64
= tcg_temp_new_i64();
9530 TCGv_i32 fp32_0
= tcg_temp_new_i32();
9531 TCGv_i32 fp32_1
= tcg_temp_new_i32();
9533 gen_load_fpr32(ctx
, fp32_0
, fs
);
9534 gen_load_fpr32(ctx
, fp32_1
, ft
);
9535 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
9536 tcg_temp_free_i32(fp32_1
);
9537 tcg_temp_free_i32(fp32_0
);
9538 gen_store_fpr64(ctx
, fp64
, fd
);
9539 tcg_temp_free_i64(fp64
);
9552 case OPC_CMP_NGLE_S
:
9559 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9560 if (ctx
->opcode
& (1 << 6)) {
9561 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
9562 opn
= condnames_abs
[func
-48];
9564 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
9565 opn
= condnames
[func
-48];
9570 check_cp1_registers(ctx
, fs
| ft
| fd
);
9572 TCGv_i64 fp0
= tcg_temp_new_i64();
9573 TCGv_i64 fp1
= tcg_temp_new_i64();
9575 gen_load_fpr64(ctx
, fp0
, fs
);
9576 gen_load_fpr64(ctx
, fp1
, ft
);
9577 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
9578 tcg_temp_free_i64(fp1
);
9579 gen_store_fpr64(ctx
, fp0
, fd
);
9580 tcg_temp_free_i64(fp0
);
9586 check_cp1_registers(ctx
, fs
| ft
| fd
);
9588 TCGv_i64 fp0
= tcg_temp_new_i64();
9589 TCGv_i64 fp1
= tcg_temp_new_i64();
9591 gen_load_fpr64(ctx
, fp0
, fs
);
9592 gen_load_fpr64(ctx
, fp1
, ft
);
9593 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
9594 tcg_temp_free_i64(fp1
);
9595 gen_store_fpr64(ctx
, fp0
, fd
);
9596 tcg_temp_free_i64(fp0
);
9602 check_cp1_registers(ctx
, fs
| ft
| fd
);
9604 TCGv_i64 fp0
= tcg_temp_new_i64();
9605 TCGv_i64 fp1
= tcg_temp_new_i64();
9607 gen_load_fpr64(ctx
, fp0
, fs
);
9608 gen_load_fpr64(ctx
, fp1
, ft
);
9609 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
9610 tcg_temp_free_i64(fp1
);
9611 gen_store_fpr64(ctx
, fp0
, fd
);
9612 tcg_temp_free_i64(fp0
);
9618 check_cp1_registers(ctx
, fs
| ft
| fd
);
9620 TCGv_i64 fp0
= tcg_temp_new_i64();
9621 TCGv_i64 fp1
= tcg_temp_new_i64();
9623 gen_load_fpr64(ctx
, fp0
, fs
);
9624 gen_load_fpr64(ctx
, fp1
, ft
);
9625 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
9626 tcg_temp_free_i64(fp1
);
9627 gen_store_fpr64(ctx
, fp0
, fd
);
9628 tcg_temp_free_i64(fp0
);
9634 check_cp1_registers(ctx
, fs
| fd
);
9636 TCGv_i64 fp0
= tcg_temp_new_i64();
9638 gen_load_fpr64(ctx
, fp0
, fs
);
9639 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
9640 gen_store_fpr64(ctx
, fp0
, fd
);
9641 tcg_temp_free_i64(fp0
);
9646 check_cp1_registers(ctx
, fs
| fd
);
9648 TCGv_i64 fp0
= tcg_temp_new_i64();
9650 gen_load_fpr64(ctx
, fp0
, fs
);
9651 gen_helper_float_abs_d(fp0
, fp0
);
9652 gen_store_fpr64(ctx
, fp0
, fd
);
9653 tcg_temp_free_i64(fp0
);
9658 check_cp1_registers(ctx
, fs
| fd
);
9660 TCGv_i64 fp0
= tcg_temp_new_i64();
9662 gen_load_fpr64(ctx
, fp0
, fs
);
9663 gen_store_fpr64(ctx
, fp0
, fd
);
9664 tcg_temp_free_i64(fp0
);
9669 check_cp1_registers(ctx
, fs
| fd
);
9671 TCGv_i64 fp0
= tcg_temp_new_i64();
9673 gen_load_fpr64(ctx
, fp0
, fs
);
9674 gen_helper_float_chs_d(fp0
, fp0
);
9675 gen_store_fpr64(ctx
, fp0
, fd
);
9676 tcg_temp_free_i64(fp0
);
9681 check_cp1_64bitmode(ctx
);
9683 TCGv_i64 fp0
= tcg_temp_new_i64();
9685 gen_load_fpr64(ctx
, fp0
, fs
);
9686 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
9687 gen_store_fpr64(ctx
, fp0
, fd
);
9688 tcg_temp_free_i64(fp0
);
9693 check_cp1_64bitmode(ctx
);
9695 TCGv_i64 fp0
= tcg_temp_new_i64();
9697 gen_load_fpr64(ctx
, fp0
, fs
);
9698 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
9699 gen_store_fpr64(ctx
, fp0
, fd
);
9700 tcg_temp_free_i64(fp0
);
9705 check_cp1_64bitmode(ctx
);
9707 TCGv_i64 fp0
= tcg_temp_new_i64();
9709 gen_load_fpr64(ctx
, fp0
, fs
);
9710 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
9711 gen_store_fpr64(ctx
, fp0
, fd
);
9712 tcg_temp_free_i64(fp0
);
9717 check_cp1_64bitmode(ctx
);
9719 TCGv_i64 fp0
= tcg_temp_new_i64();
9721 gen_load_fpr64(ctx
, fp0
, fs
);
9722 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
9723 gen_store_fpr64(ctx
, fp0
, fd
);
9724 tcg_temp_free_i64(fp0
);
9729 check_cp1_registers(ctx
, fs
);
9731 TCGv_i32 fp32
= tcg_temp_new_i32();
9732 TCGv_i64 fp64
= tcg_temp_new_i64();
9734 gen_load_fpr64(ctx
, fp64
, fs
);
9735 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
9736 tcg_temp_free_i64(fp64
);
9737 gen_store_fpr32(ctx
, fp32
, fd
);
9738 tcg_temp_free_i32(fp32
);
9743 check_cp1_registers(ctx
, fs
);
9745 TCGv_i32 fp32
= tcg_temp_new_i32();
9746 TCGv_i64 fp64
= tcg_temp_new_i64();
9748 gen_load_fpr64(ctx
, fp64
, fs
);
9749 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
9750 tcg_temp_free_i64(fp64
);
9751 gen_store_fpr32(ctx
, fp32
, fd
);
9752 tcg_temp_free_i32(fp32
);
9757 check_cp1_registers(ctx
, fs
);
9759 TCGv_i32 fp32
= tcg_temp_new_i32();
9760 TCGv_i64 fp64
= tcg_temp_new_i64();
9762 gen_load_fpr64(ctx
, fp64
, fs
);
9763 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
9764 tcg_temp_free_i64(fp64
);
9765 gen_store_fpr32(ctx
, fp32
, fd
);
9766 tcg_temp_free_i32(fp32
);
9771 check_cp1_registers(ctx
, fs
);
9773 TCGv_i32 fp32
= tcg_temp_new_i32();
9774 TCGv_i64 fp64
= tcg_temp_new_i64();
9776 gen_load_fpr64(ctx
, fp64
, fs
);
9777 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
9778 tcg_temp_free_i64(fp64
);
9779 gen_store_fpr32(ctx
, fp32
, fd
);
9780 tcg_temp_free_i32(fp32
);
9785 check_insn(ctx
, ISA_MIPS32R6
);
9786 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9790 check_insn(ctx
, ISA_MIPS32R6
);
9791 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9795 check_insn(ctx
, ISA_MIPS32R6
);
9796 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9800 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9801 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9805 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9807 TCGLabel
*l1
= gen_new_label();
9811 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9813 fp0
= tcg_temp_new_i64();
9814 gen_load_fpr64(ctx
, fp0
, fs
);
9815 gen_store_fpr64(ctx
, fp0
, fd
);
9816 tcg_temp_free_i64(fp0
);
9822 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9824 TCGLabel
*l1
= gen_new_label();
9828 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9829 fp0
= tcg_temp_new_i64();
9830 gen_load_fpr64(ctx
, fp0
, fs
);
9831 gen_store_fpr64(ctx
, fp0
, fd
);
9832 tcg_temp_free_i64(fp0
);
9839 check_cp1_64bitmode(ctx
);
9841 TCGv_i64 fp0
= tcg_temp_new_i64();
9843 gen_load_fpr64(ctx
, fp0
, fs
);
9844 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
9845 gen_store_fpr64(ctx
, fp0
, fd
);
9846 tcg_temp_free_i64(fp0
);
9851 check_cp1_64bitmode(ctx
);
9853 TCGv_i64 fp0
= tcg_temp_new_i64();
9855 gen_load_fpr64(ctx
, fp0
, fs
);
9856 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
9857 gen_store_fpr64(ctx
, fp0
, fd
);
9858 tcg_temp_free_i64(fp0
);
9863 check_insn(ctx
, ISA_MIPS32R6
);
9865 TCGv_i64 fp0
= tcg_temp_new_i64();
9866 TCGv_i64 fp1
= tcg_temp_new_i64();
9867 TCGv_i64 fp2
= tcg_temp_new_i64();
9868 gen_load_fpr64(ctx
, fp0
, fs
);
9869 gen_load_fpr64(ctx
, fp1
, ft
);
9870 gen_load_fpr64(ctx
, fp2
, fd
);
9871 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9872 gen_store_fpr64(ctx
, fp2
, fd
);
9873 tcg_temp_free_i64(fp2
);
9874 tcg_temp_free_i64(fp1
);
9875 tcg_temp_free_i64(fp0
);
9880 check_insn(ctx
, ISA_MIPS32R6
);
9882 TCGv_i64 fp0
= tcg_temp_new_i64();
9883 TCGv_i64 fp1
= tcg_temp_new_i64();
9884 TCGv_i64 fp2
= tcg_temp_new_i64();
9885 gen_load_fpr64(ctx
, fp0
, fs
);
9886 gen_load_fpr64(ctx
, fp1
, ft
);
9887 gen_load_fpr64(ctx
, fp2
, fd
);
9888 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9889 gen_store_fpr64(ctx
, fp2
, fd
);
9890 tcg_temp_free_i64(fp2
);
9891 tcg_temp_free_i64(fp1
);
9892 tcg_temp_free_i64(fp0
);
9897 check_insn(ctx
, ISA_MIPS32R6
);
9899 TCGv_i64 fp0
= tcg_temp_new_i64();
9900 gen_load_fpr64(ctx
, fp0
, fs
);
9901 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
9902 gen_store_fpr64(ctx
, fp0
, fd
);
9903 tcg_temp_free_i64(fp0
);
9908 check_insn(ctx
, ISA_MIPS32R6
);
9910 TCGv_i64 fp0
= tcg_temp_new_i64();
9911 gen_load_fpr64(ctx
, fp0
, fs
);
9912 gen_helper_float_class_d(fp0
, fp0
);
9913 gen_store_fpr64(ctx
, fp0
, fd
);
9914 tcg_temp_free_i64(fp0
);
9918 case OPC_MIN_D
: /* OPC_RECIP2_D */
9919 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9921 TCGv_i64 fp0
= tcg_temp_new_i64();
9922 TCGv_i64 fp1
= tcg_temp_new_i64();
9923 gen_load_fpr64(ctx
, fp0
, fs
);
9924 gen_load_fpr64(ctx
, fp1
, ft
);
9925 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
9926 gen_store_fpr64(ctx
, fp1
, fd
);
9927 tcg_temp_free_i64(fp1
);
9928 tcg_temp_free_i64(fp0
);
9932 check_cp1_64bitmode(ctx
);
9934 TCGv_i64 fp0
= tcg_temp_new_i64();
9935 TCGv_i64 fp1
= tcg_temp_new_i64();
9937 gen_load_fpr64(ctx
, fp0
, fs
);
9938 gen_load_fpr64(ctx
, fp1
, ft
);
9939 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
9940 tcg_temp_free_i64(fp1
);
9941 gen_store_fpr64(ctx
, fp0
, fd
);
9942 tcg_temp_free_i64(fp0
);
9947 case OPC_MINA_D
: /* OPC_RECIP1_D */
9948 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9950 TCGv_i64 fp0
= tcg_temp_new_i64();
9951 TCGv_i64 fp1
= tcg_temp_new_i64();
9952 gen_load_fpr64(ctx
, fp0
, fs
);
9953 gen_load_fpr64(ctx
, fp1
, ft
);
9954 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
9955 gen_store_fpr64(ctx
, fp1
, fd
);
9956 tcg_temp_free_i64(fp1
);
9957 tcg_temp_free_i64(fp0
);
9961 check_cp1_64bitmode(ctx
);
9963 TCGv_i64 fp0
= tcg_temp_new_i64();
9965 gen_load_fpr64(ctx
, fp0
, fs
);
9966 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
9967 gen_store_fpr64(ctx
, fp0
, fd
);
9968 tcg_temp_free_i64(fp0
);
9973 case OPC_MAX_D
: /* OPC_RSQRT1_D */
9974 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9976 TCGv_i64 fp0
= tcg_temp_new_i64();
9977 TCGv_i64 fp1
= tcg_temp_new_i64();
9978 gen_load_fpr64(ctx
, fp0
, fs
);
9979 gen_load_fpr64(ctx
, fp1
, ft
);
9980 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
9981 gen_store_fpr64(ctx
, fp1
, fd
);
9982 tcg_temp_free_i64(fp1
);
9983 tcg_temp_free_i64(fp0
);
9987 check_cp1_64bitmode(ctx
);
9989 TCGv_i64 fp0
= tcg_temp_new_i64();
9991 gen_load_fpr64(ctx
, fp0
, fs
);
9992 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
9993 gen_store_fpr64(ctx
, fp0
, fd
);
9994 tcg_temp_free_i64(fp0
);
9999 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
10000 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
10002 TCGv_i64 fp0
= tcg_temp_new_i64();
10003 TCGv_i64 fp1
= tcg_temp_new_i64();
10004 gen_load_fpr64(ctx
, fp0
, fs
);
10005 gen_load_fpr64(ctx
, fp1
, ft
);
10006 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
10007 gen_store_fpr64(ctx
, fp1
, fd
);
10008 tcg_temp_free_i64(fp1
);
10009 tcg_temp_free_i64(fp0
);
10013 check_cp1_64bitmode(ctx
);
10015 TCGv_i64 fp0
= tcg_temp_new_i64();
10016 TCGv_i64 fp1
= tcg_temp_new_i64();
10018 gen_load_fpr64(ctx
, fp0
, fs
);
10019 gen_load_fpr64(ctx
, fp1
, ft
);
10020 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
10021 tcg_temp_free_i64(fp1
);
10022 gen_store_fpr64(ctx
, fp0
, fd
);
10023 tcg_temp_free_i64(fp0
);
10031 case OPC_CMP_UEQ_D
:
10032 case OPC_CMP_OLT_D
:
10033 case OPC_CMP_ULT_D
:
10034 case OPC_CMP_OLE_D
:
10035 case OPC_CMP_ULE_D
:
10037 case OPC_CMP_NGLE_D
:
10038 case OPC_CMP_SEQ_D
:
10039 case OPC_CMP_NGL_D
:
10041 case OPC_CMP_NGE_D
:
10043 case OPC_CMP_NGT_D
:
10044 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
10045 if (ctx
->opcode
& (1 << 6)) {
10046 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
10047 opn
= condnames_abs
[func
-48];
10049 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
10050 opn
= condnames
[func
-48];
10055 check_cp1_registers(ctx
, fs
);
10057 TCGv_i32 fp32
= tcg_temp_new_i32();
10058 TCGv_i64 fp64
= tcg_temp_new_i64();
10060 gen_load_fpr64(ctx
, fp64
, fs
);
10061 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
10062 tcg_temp_free_i64(fp64
);
10063 gen_store_fpr32(ctx
, fp32
, fd
);
10064 tcg_temp_free_i32(fp32
);
10069 check_cp1_registers(ctx
, fs
);
10071 TCGv_i32 fp32
= tcg_temp_new_i32();
10072 TCGv_i64 fp64
= tcg_temp_new_i64();
10074 gen_load_fpr64(ctx
, fp64
, fs
);
10075 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
10076 tcg_temp_free_i64(fp64
);
10077 gen_store_fpr32(ctx
, fp32
, fd
);
10078 tcg_temp_free_i32(fp32
);
10083 check_cp1_64bitmode(ctx
);
10085 TCGv_i64 fp0
= tcg_temp_new_i64();
10087 gen_load_fpr64(ctx
, fp0
, fs
);
10088 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
10089 gen_store_fpr64(ctx
, fp0
, fd
);
10090 tcg_temp_free_i64(fp0
);
10096 TCGv_i32 fp0
= tcg_temp_new_i32();
10098 gen_load_fpr32(ctx
, fp0
, fs
);
10099 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
10100 gen_store_fpr32(ctx
, fp0
, fd
);
10101 tcg_temp_free_i32(fp0
);
10106 check_cp1_registers(ctx
, fd
);
10108 TCGv_i32 fp32
= tcg_temp_new_i32();
10109 TCGv_i64 fp64
= tcg_temp_new_i64();
10111 gen_load_fpr32(ctx
, fp32
, fs
);
10112 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
10113 tcg_temp_free_i32(fp32
);
10114 gen_store_fpr64(ctx
, fp64
, fd
);
10115 tcg_temp_free_i64(fp64
);
10120 check_cp1_64bitmode(ctx
);
10122 TCGv_i32 fp32
= tcg_temp_new_i32();
10123 TCGv_i64 fp64
= tcg_temp_new_i64();
10125 gen_load_fpr64(ctx
, fp64
, fs
);
10126 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
10127 tcg_temp_free_i64(fp64
);
10128 gen_store_fpr32(ctx
, fp32
, fd
);
10129 tcg_temp_free_i32(fp32
);
10134 check_cp1_64bitmode(ctx
);
10136 TCGv_i64 fp0
= tcg_temp_new_i64();
10138 gen_load_fpr64(ctx
, fp0
, fs
);
10139 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
10140 gen_store_fpr64(ctx
, fp0
, fd
);
10141 tcg_temp_free_i64(fp0
);
10145 case OPC_CVT_PS_PW
:
10148 TCGv_i64 fp0
= tcg_temp_new_i64();
10150 gen_load_fpr64(ctx
, fp0
, fs
);
10151 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
10152 gen_store_fpr64(ctx
, fp0
, fd
);
10153 tcg_temp_free_i64(fp0
);
10160 TCGv_i64 fp0
= tcg_temp_new_i64();
10161 TCGv_i64 fp1
= tcg_temp_new_i64();
10163 gen_load_fpr64(ctx
, fp0
, fs
);
10164 gen_load_fpr64(ctx
, fp1
, ft
);
10165 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
10166 tcg_temp_free_i64(fp1
);
10167 gen_store_fpr64(ctx
, fp0
, fd
);
10168 tcg_temp_free_i64(fp0
);
10175 TCGv_i64 fp0
= tcg_temp_new_i64();
10176 TCGv_i64 fp1
= tcg_temp_new_i64();
10178 gen_load_fpr64(ctx
, fp0
, fs
);
10179 gen_load_fpr64(ctx
, fp1
, ft
);
10180 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
10181 tcg_temp_free_i64(fp1
);
10182 gen_store_fpr64(ctx
, fp0
, fd
);
10183 tcg_temp_free_i64(fp0
);
10190 TCGv_i64 fp0
= tcg_temp_new_i64();
10191 TCGv_i64 fp1
= tcg_temp_new_i64();
10193 gen_load_fpr64(ctx
, fp0
, fs
);
10194 gen_load_fpr64(ctx
, fp1
, ft
);
10195 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
10196 tcg_temp_free_i64(fp1
);
10197 gen_store_fpr64(ctx
, fp0
, fd
);
10198 tcg_temp_free_i64(fp0
);
10205 TCGv_i64 fp0
= tcg_temp_new_i64();
10207 gen_load_fpr64(ctx
, fp0
, fs
);
10208 gen_helper_float_abs_ps(fp0
, fp0
);
10209 gen_store_fpr64(ctx
, fp0
, fd
);
10210 tcg_temp_free_i64(fp0
);
10217 TCGv_i64 fp0
= tcg_temp_new_i64();
10219 gen_load_fpr64(ctx
, fp0
, fs
);
10220 gen_store_fpr64(ctx
, fp0
, fd
);
10221 tcg_temp_free_i64(fp0
);
10228 TCGv_i64 fp0
= tcg_temp_new_i64();
10230 gen_load_fpr64(ctx
, fp0
, fs
);
10231 gen_helper_float_chs_ps(fp0
, fp0
);
10232 gen_store_fpr64(ctx
, fp0
, fd
);
10233 tcg_temp_free_i64(fp0
);
10239 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10245 TCGLabel
*l1
= gen_new_label();
10249 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10250 fp0
= tcg_temp_new_i64();
10251 gen_load_fpr64(ctx
, fp0
, fs
);
10252 gen_store_fpr64(ctx
, fp0
, fd
);
10253 tcg_temp_free_i64(fp0
);
10261 TCGLabel
*l1
= gen_new_label();
10265 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10266 fp0
= tcg_temp_new_i64();
10267 gen_load_fpr64(ctx
, fp0
, fs
);
10268 gen_store_fpr64(ctx
, fp0
, fd
);
10269 tcg_temp_free_i64(fp0
);
10278 TCGv_i64 fp0
= tcg_temp_new_i64();
10279 TCGv_i64 fp1
= tcg_temp_new_i64();
10281 gen_load_fpr64(ctx
, fp0
, ft
);
10282 gen_load_fpr64(ctx
, fp1
, fs
);
10283 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
10284 tcg_temp_free_i64(fp1
);
10285 gen_store_fpr64(ctx
, fp0
, fd
);
10286 tcg_temp_free_i64(fp0
);
10293 TCGv_i64 fp0
= tcg_temp_new_i64();
10294 TCGv_i64 fp1
= tcg_temp_new_i64();
10296 gen_load_fpr64(ctx
, fp0
, ft
);
10297 gen_load_fpr64(ctx
, fp1
, fs
);
10298 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
10299 tcg_temp_free_i64(fp1
);
10300 gen_store_fpr64(ctx
, fp0
, fd
);
10301 tcg_temp_free_i64(fp0
);
10305 case OPC_RECIP2_PS
:
10308 TCGv_i64 fp0
= tcg_temp_new_i64();
10309 TCGv_i64 fp1
= tcg_temp_new_i64();
10311 gen_load_fpr64(ctx
, fp0
, fs
);
10312 gen_load_fpr64(ctx
, fp1
, ft
);
10313 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
10314 tcg_temp_free_i64(fp1
);
10315 gen_store_fpr64(ctx
, fp0
, fd
);
10316 tcg_temp_free_i64(fp0
);
10320 case OPC_RECIP1_PS
:
10323 TCGv_i64 fp0
= tcg_temp_new_i64();
10325 gen_load_fpr64(ctx
, fp0
, fs
);
10326 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
10327 gen_store_fpr64(ctx
, fp0
, fd
);
10328 tcg_temp_free_i64(fp0
);
10332 case OPC_RSQRT1_PS
:
10335 TCGv_i64 fp0
= tcg_temp_new_i64();
10337 gen_load_fpr64(ctx
, fp0
, fs
);
10338 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
10339 gen_store_fpr64(ctx
, fp0
, fd
);
10340 tcg_temp_free_i64(fp0
);
10344 case OPC_RSQRT2_PS
:
10347 TCGv_i64 fp0
= tcg_temp_new_i64();
10348 TCGv_i64 fp1
= tcg_temp_new_i64();
10350 gen_load_fpr64(ctx
, fp0
, fs
);
10351 gen_load_fpr64(ctx
, fp1
, ft
);
10352 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
10353 tcg_temp_free_i64(fp1
);
10354 gen_store_fpr64(ctx
, fp0
, fd
);
10355 tcg_temp_free_i64(fp0
);
10360 check_cp1_64bitmode(ctx
);
10362 TCGv_i32 fp0
= tcg_temp_new_i32();
10364 gen_load_fpr32h(ctx
, fp0
, fs
);
10365 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
10366 gen_store_fpr32(ctx
, fp0
, fd
);
10367 tcg_temp_free_i32(fp0
);
10371 case OPC_CVT_PW_PS
:
10374 TCGv_i64 fp0
= tcg_temp_new_i64();
10376 gen_load_fpr64(ctx
, fp0
, fs
);
10377 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
10378 gen_store_fpr64(ctx
, fp0
, fd
);
10379 tcg_temp_free_i64(fp0
);
10384 check_cp1_64bitmode(ctx
);
10386 TCGv_i32 fp0
= tcg_temp_new_i32();
10388 gen_load_fpr32(ctx
, fp0
, fs
);
10389 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
10390 gen_store_fpr32(ctx
, fp0
, fd
);
10391 tcg_temp_free_i32(fp0
);
10398 TCGv_i32 fp0
= tcg_temp_new_i32();
10399 TCGv_i32 fp1
= tcg_temp_new_i32();
10401 gen_load_fpr32(ctx
, fp0
, fs
);
10402 gen_load_fpr32(ctx
, fp1
, ft
);
10403 gen_store_fpr32h(ctx
, fp0
, fd
);
10404 gen_store_fpr32(ctx
, fp1
, fd
);
10405 tcg_temp_free_i32(fp0
);
10406 tcg_temp_free_i32(fp1
);
10413 TCGv_i32 fp0
= tcg_temp_new_i32();
10414 TCGv_i32 fp1
= tcg_temp_new_i32();
10416 gen_load_fpr32(ctx
, fp0
, fs
);
10417 gen_load_fpr32h(ctx
, fp1
, ft
);
10418 gen_store_fpr32(ctx
, fp1
, fd
);
10419 gen_store_fpr32h(ctx
, fp0
, fd
);
10420 tcg_temp_free_i32(fp0
);
10421 tcg_temp_free_i32(fp1
);
10428 TCGv_i32 fp0
= tcg_temp_new_i32();
10429 TCGv_i32 fp1
= tcg_temp_new_i32();
10431 gen_load_fpr32h(ctx
, fp0
, fs
);
10432 gen_load_fpr32(ctx
, fp1
, ft
);
10433 gen_store_fpr32(ctx
, fp1
, fd
);
10434 gen_store_fpr32h(ctx
, fp0
, fd
);
10435 tcg_temp_free_i32(fp0
);
10436 tcg_temp_free_i32(fp1
);
10443 TCGv_i32 fp0
= tcg_temp_new_i32();
10444 TCGv_i32 fp1
= tcg_temp_new_i32();
10446 gen_load_fpr32h(ctx
, fp0
, fs
);
10447 gen_load_fpr32h(ctx
, fp1
, ft
);
10448 gen_store_fpr32(ctx
, fp1
, fd
);
10449 gen_store_fpr32h(ctx
, fp0
, fd
);
10450 tcg_temp_free_i32(fp0
);
10451 tcg_temp_free_i32(fp1
);
10456 case OPC_CMP_UN_PS
:
10457 case OPC_CMP_EQ_PS
:
10458 case OPC_CMP_UEQ_PS
:
10459 case OPC_CMP_OLT_PS
:
10460 case OPC_CMP_ULT_PS
:
10461 case OPC_CMP_OLE_PS
:
10462 case OPC_CMP_ULE_PS
:
10463 case OPC_CMP_SF_PS
:
10464 case OPC_CMP_NGLE_PS
:
10465 case OPC_CMP_SEQ_PS
:
10466 case OPC_CMP_NGL_PS
:
10467 case OPC_CMP_LT_PS
:
10468 case OPC_CMP_NGE_PS
:
10469 case OPC_CMP_LE_PS
:
10470 case OPC_CMP_NGT_PS
:
10471 if (ctx
->opcode
& (1 << 6)) {
10472 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
10473 opn
= condnames_abs
[func
-48];
10475 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
10476 opn
= condnames
[func
-48];
10482 generate_exception (ctx
, EXCP_RI
);
10485 (void)opn
; /* avoid a compiler warning */
10488 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
10491 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
10494 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
10499 /* Coprocessor 3 (FPU) */
10500 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
10501 int fd
, int fs
, int base
, int index
)
10503 const char *opn
= "extended float load/store";
10505 TCGv t0
= tcg_temp_new();
10508 gen_load_gpr(t0
, index
);
10509 } else if (index
== 0) {
10510 gen_load_gpr(t0
, base
);
10512 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
10514 /* Don't do NOP if destination is zero: we must perform the actual
10520 TCGv_i32 fp0
= tcg_temp_new_i32();
10522 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
10523 tcg_gen_trunc_tl_i32(fp0
, t0
);
10524 gen_store_fpr32(ctx
, fp0
, fd
);
10525 tcg_temp_free_i32(fp0
);
10531 check_cp1_registers(ctx
, fd
);
10533 TCGv_i64 fp0
= tcg_temp_new_i64();
10534 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10535 gen_store_fpr64(ctx
, fp0
, fd
);
10536 tcg_temp_free_i64(fp0
);
10541 check_cp1_64bitmode(ctx
);
10542 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10544 TCGv_i64 fp0
= tcg_temp_new_i64();
10546 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10547 gen_store_fpr64(ctx
, fp0
, fd
);
10548 tcg_temp_free_i64(fp0
);
10555 TCGv_i32 fp0
= tcg_temp_new_i32();
10556 gen_load_fpr32(ctx
, fp0
, fs
);
10557 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
10558 tcg_temp_free_i32(fp0
);
10565 check_cp1_registers(ctx
, fs
);
10567 TCGv_i64 fp0
= tcg_temp_new_i64();
10568 gen_load_fpr64(ctx
, fp0
, fs
);
10569 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10570 tcg_temp_free_i64(fp0
);
10576 check_cp1_64bitmode(ctx
);
10577 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10579 TCGv_i64 fp0
= tcg_temp_new_i64();
10580 gen_load_fpr64(ctx
, fp0
, fs
);
10581 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10582 tcg_temp_free_i64(fp0
);
10589 (void)opn
; (void)store
; /* avoid compiler warnings */
10590 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
10591 regnames
[index
], regnames
[base
]);
10594 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
10595 int fd
, int fr
, int fs
, int ft
)
10597 const char *opn
= "flt3_arith";
10603 TCGv t0
= tcg_temp_local_new();
10604 TCGv_i32 fp
= tcg_temp_new_i32();
10605 TCGv_i32 fph
= tcg_temp_new_i32();
10606 TCGLabel
*l1
= gen_new_label();
10607 TCGLabel
*l2
= gen_new_label();
10609 gen_load_gpr(t0
, fr
);
10610 tcg_gen_andi_tl(t0
, t0
, 0x7);
10612 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
10613 gen_load_fpr32(ctx
, fp
, fs
);
10614 gen_load_fpr32h(ctx
, fph
, fs
);
10615 gen_store_fpr32(ctx
, fp
, fd
);
10616 gen_store_fpr32h(ctx
, fph
, fd
);
10619 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
10621 #ifdef TARGET_WORDS_BIGENDIAN
10622 gen_load_fpr32(ctx
, fp
, fs
);
10623 gen_load_fpr32h(ctx
, fph
, ft
);
10624 gen_store_fpr32h(ctx
, fp
, fd
);
10625 gen_store_fpr32(ctx
, fph
, fd
);
10627 gen_load_fpr32h(ctx
, fph
, fs
);
10628 gen_load_fpr32(ctx
, fp
, ft
);
10629 gen_store_fpr32(ctx
, fph
, fd
);
10630 gen_store_fpr32h(ctx
, fp
, fd
);
10633 tcg_temp_free_i32(fp
);
10634 tcg_temp_free_i32(fph
);
10641 TCGv_i32 fp0
= tcg_temp_new_i32();
10642 TCGv_i32 fp1
= tcg_temp_new_i32();
10643 TCGv_i32 fp2
= tcg_temp_new_i32();
10645 gen_load_fpr32(ctx
, fp0
, fs
);
10646 gen_load_fpr32(ctx
, fp1
, ft
);
10647 gen_load_fpr32(ctx
, fp2
, fr
);
10648 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10649 tcg_temp_free_i32(fp0
);
10650 tcg_temp_free_i32(fp1
);
10651 gen_store_fpr32(ctx
, fp2
, fd
);
10652 tcg_temp_free_i32(fp2
);
10658 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10660 TCGv_i64 fp0
= tcg_temp_new_i64();
10661 TCGv_i64 fp1
= tcg_temp_new_i64();
10662 TCGv_i64 fp2
= tcg_temp_new_i64();
10664 gen_load_fpr64(ctx
, fp0
, fs
);
10665 gen_load_fpr64(ctx
, fp1
, ft
);
10666 gen_load_fpr64(ctx
, fp2
, fr
);
10667 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10668 tcg_temp_free_i64(fp0
);
10669 tcg_temp_free_i64(fp1
);
10670 gen_store_fpr64(ctx
, fp2
, fd
);
10671 tcg_temp_free_i64(fp2
);
10678 TCGv_i64 fp0
= tcg_temp_new_i64();
10679 TCGv_i64 fp1
= tcg_temp_new_i64();
10680 TCGv_i64 fp2
= tcg_temp_new_i64();
10682 gen_load_fpr64(ctx
, fp0
, fs
);
10683 gen_load_fpr64(ctx
, fp1
, ft
);
10684 gen_load_fpr64(ctx
, fp2
, fr
);
10685 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10686 tcg_temp_free_i64(fp0
);
10687 tcg_temp_free_i64(fp1
);
10688 gen_store_fpr64(ctx
, fp2
, fd
);
10689 tcg_temp_free_i64(fp2
);
10696 TCGv_i32 fp0
= tcg_temp_new_i32();
10697 TCGv_i32 fp1
= tcg_temp_new_i32();
10698 TCGv_i32 fp2
= tcg_temp_new_i32();
10700 gen_load_fpr32(ctx
, fp0
, fs
);
10701 gen_load_fpr32(ctx
, fp1
, ft
);
10702 gen_load_fpr32(ctx
, fp2
, fr
);
10703 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10704 tcg_temp_free_i32(fp0
);
10705 tcg_temp_free_i32(fp1
);
10706 gen_store_fpr32(ctx
, fp2
, fd
);
10707 tcg_temp_free_i32(fp2
);
10713 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10715 TCGv_i64 fp0
= tcg_temp_new_i64();
10716 TCGv_i64 fp1
= tcg_temp_new_i64();
10717 TCGv_i64 fp2
= tcg_temp_new_i64();
10719 gen_load_fpr64(ctx
, fp0
, fs
);
10720 gen_load_fpr64(ctx
, fp1
, ft
);
10721 gen_load_fpr64(ctx
, fp2
, fr
);
10722 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10723 tcg_temp_free_i64(fp0
);
10724 tcg_temp_free_i64(fp1
);
10725 gen_store_fpr64(ctx
, fp2
, fd
);
10726 tcg_temp_free_i64(fp2
);
10733 TCGv_i64 fp0
= tcg_temp_new_i64();
10734 TCGv_i64 fp1
= tcg_temp_new_i64();
10735 TCGv_i64 fp2
= tcg_temp_new_i64();
10737 gen_load_fpr64(ctx
, fp0
, fs
);
10738 gen_load_fpr64(ctx
, fp1
, ft
);
10739 gen_load_fpr64(ctx
, fp2
, fr
);
10740 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10741 tcg_temp_free_i64(fp0
);
10742 tcg_temp_free_i64(fp1
);
10743 gen_store_fpr64(ctx
, fp2
, fd
);
10744 tcg_temp_free_i64(fp2
);
10751 TCGv_i32 fp0
= tcg_temp_new_i32();
10752 TCGv_i32 fp1
= tcg_temp_new_i32();
10753 TCGv_i32 fp2
= tcg_temp_new_i32();
10755 gen_load_fpr32(ctx
, fp0
, fs
);
10756 gen_load_fpr32(ctx
, fp1
, ft
);
10757 gen_load_fpr32(ctx
, fp2
, fr
);
10758 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10759 tcg_temp_free_i32(fp0
);
10760 tcg_temp_free_i32(fp1
);
10761 gen_store_fpr32(ctx
, fp2
, fd
);
10762 tcg_temp_free_i32(fp2
);
10768 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10770 TCGv_i64 fp0
= tcg_temp_new_i64();
10771 TCGv_i64 fp1
= tcg_temp_new_i64();
10772 TCGv_i64 fp2
= tcg_temp_new_i64();
10774 gen_load_fpr64(ctx
, fp0
, fs
);
10775 gen_load_fpr64(ctx
, fp1
, ft
);
10776 gen_load_fpr64(ctx
, fp2
, fr
);
10777 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10778 tcg_temp_free_i64(fp0
);
10779 tcg_temp_free_i64(fp1
);
10780 gen_store_fpr64(ctx
, fp2
, fd
);
10781 tcg_temp_free_i64(fp2
);
10788 TCGv_i64 fp0
= tcg_temp_new_i64();
10789 TCGv_i64 fp1
= tcg_temp_new_i64();
10790 TCGv_i64 fp2
= tcg_temp_new_i64();
10792 gen_load_fpr64(ctx
, fp0
, fs
);
10793 gen_load_fpr64(ctx
, fp1
, ft
);
10794 gen_load_fpr64(ctx
, fp2
, fr
);
10795 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10796 tcg_temp_free_i64(fp0
);
10797 tcg_temp_free_i64(fp1
);
10798 gen_store_fpr64(ctx
, fp2
, fd
);
10799 tcg_temp_free_i64(fp2
);
10806 TCGv_i32 fp0
= tcg_temp_new_i32();
10807 TCGv_i32 fp1
= tcg_temp_new_i32();
10808 TCGv_i32 fp2
= tcg_temp_new_i32();
10810 gen_load_fpr32(ctx
, fp0
, fs
);
10811 gen_load_fpr32(ctx
, fp1
, ft
);
10812 gen_load_fpr32(ctx
, fp2
, fr
);
10813 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10814 tcg_temp_free_i32(fp0
);
10815 tcg_temp_free_i32(fp1
);
10816 gen_store_fpr32(ctx
, fp2
, fd
);
10817 tcg_temp_free_i32(fp2
);
10823 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10825 TCGv_i64 fp0
= tcg_temp_new_i64();
10826 TCGv_i64 fp1
= tcg_temp_new_i64();
10827 TCGv_i64 fp2
= tcg_temp_new_i64();
10829 gen_load_fpr64(ctx
, fp0
, fs
);
10830 gen_load_fpr64(ctx
, fp1
, ft
);
10831 gen_load_fpr64(ctx
, fp2
, fr
);
10832 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10833 tcg_temp_free_i64(fp0
);
10834 tcg_temp_free_i64(fp1
);
10835 gen_store_fpr64(ctx
, fp2
, fd
);
10836 tcg_temp_free_i64(fp2
);
10843 TCGv_i64 fp0
= tcg_temp_new_i64();
10844 TCGv_i64 fp1
= tcg_temp_new_i64();
10845 TCGv_i64 fp2
= tcg_temp_new_i64();
10847 gen_load_fpr64(ctx
, fp0
, fs
);
10848 gen_load_fpr64(ctx
, fp1
, ft
);
10849 gen_load_fpr64(ctx
, fp2
, fr
);
10850 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10851 tcg_temp_free_i64(fp0
);
10852 tcg_temp_free_i64(fp1
);
10853 gen_store_fpr64(ctx
, fp2
, fd
);
10854 tcg_temp_free_i64(fp2
);
10860 generate_exception (ctx
, EXCP_RI
);
10863 (void)opn
; /* avoid a compiler warning */
10864 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
10865 fregnames
[fs
], fregnames
[ft
]);
10868 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
10872 #if !defined(CONFIG_USER_ONLY)
10873 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10874 Therefore only check the ISA in system mode. */
10875 check_insn(ctx
, ISA_MIPS32R2
);
10877 t0
= tcg_temp_new();
10881 save_cpu_state(ctx
, 1);
10882 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
10883 gen_store_gpr(t0
, rt
);
10886 save_cpu_state(ctx
, 1);
10887 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
10888 gen_store_gpr(t0
, rt
);
10891 save_cpu_state(ctx
, 1);
10892 gen_helper_rdhwr_cc(t0
, cpu_env
);
10893 gen_store_gpr(t0
, rt
);
10896 save_cpu_state(ctx
, 1);
10897 gen_helper_rdhwr_ccres(t0
, cpu_env
);
10898 gen_store_gpr(t0
, rt
);
10901 #if defined(CONFIG_USER_ONLY)
10902 tcg_gen_ld_tl(t0
, cpu_env
,
10903 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10904 gen_store_gpr(t0
, rt
);
10907 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
10908 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
10909 tcg_gen_ld_tl(t0
, cpu_env
,
10910 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10911 gen_store_gpr(t0
, rt
);
10913 generate_exception(ctx
, EXCP_RI
);
10917 default: /* Invalid */
10918 MIPS_INVAL("rdhwr");
10919 generate_exception(ctx
, EXCP_RI
);
10925 static inline void clear_branch_hflags(DisasContext
*ctx
)
10927 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
10928 if (ctx
->bstate
== BS_NONE
) {
10929 save_cpu_state(ctx
, 0);
10931 /* it is not safe to save ctx->hflags as hflags may be changed
10932 in execution time by the instruction in delay / forbidden slot. */
10933 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
10937 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
10939 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10940 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
10941 /* Branches completion */
10942 clear_branch_hflags(ctx
);
10943 ctx
->bstate
= BS_BRANCH
;
10944 /* FIXME: Need to clear can_do_io. */
10945 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
10946 case MIPS_HFLAG_FBNSLOT
:
10947 MIPS_DEBUG("forbidden slot");
10948 gen_goto_tb(ctx
, 0, ctx
->pc
+ insn_bytes
);
10951 /* unconditional branch */
10952 MIPS_DEBUG("unconditional branch");
10953 if (proc_hflags
& MIPS_HFLAG_BX
) {
10954 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
10956 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10958 case MIPS_HFLAG_BL
:
10959 /* blikely taken case */
10960 MIPS_DEBUG("blikely branch taken");
10961 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10963 case MIPS_HFLAG_BC
:
10964 /* Conditional branch */
10965 MIPS_DEBUG("conditional branch");
10967 TCGLabel
*l1
= gen_new_label();
10969 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
10970 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
10972 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10975 case MIPS_HFLAG_BR
:
10976 /* unconditional branch to register */
10977 MIPS_DEBUG("branch to register");
10978 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
10979 TCGv t0
= tcg_temp_new();
10980 TCGv_i32 t1
= tcg_temp_new_i32();
10982 tcg_gen_andi_tl(t0
, btarget
, 0x1);
10983 tcg_gen_trunc_tl_i32(t1
, t0
);
10985 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
10986 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
10987 tcg_gen_or_i32(hflags
, hflags
, t1
);
10988 tcg_temp_free_i32(t1
);
10990 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
10992 tcg_gen_mov_tl(cpu_PC
, btarget
);
10994 if (ctx
->singlestep_enabled
) {
10995 save_cpu_state(ctx
, 0);
10996 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
10998 tcg_gen_exit_tb(0);
11001 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
11007 /* Compact Branches */
11008 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
11009 int rs
, int rt
, int32_t offset
)
11011 int bcond_compute
= 0;
11012 TCGv t0
= tcg_temp_new();
11013 TCGv t1
= tcg_temp_new();
11014 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
11016 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11017 #ifdef MIPS_DEBUG_DISAS
11018 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11021 generate_exception(ctx
, EXCP_RI
);
11025 /* Load needed operands and calculate btarget */
11027 /* compact branch */
11028 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
11029 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
11030 gen_load_gpr(t0
, rs
);
11031 gen_load_gpr(t1
, rt
);
11033 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11034 if (rs
<= rt
&& rs
== 0) {
11035 /* OPC_BEQZALC, OPC_BNEZALC */
11036 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11039 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
11040 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
11041 gen_load_gpr(t0
, rs
);
11042 gen_load_gpr(t1
, rt
);
11044 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11046 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
11047 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
11048 if (rs
== 0 || rs
== rt
) {
11049 /* OPC_BLEZALC, OPC_BGEZALC */
11050 /* OPC_BGTZALC, OPC_BLTZALC */
11051 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11053 gen_load_gpr(t0
, rs
);
11054 gen_load_gpr(t1
, rt
);
11056 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11060 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11065 /* OPC_BEQZC, OPC_BNEZC */
11066 gen_load_gpr(t0
, rs
);
11068 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11070 /* OPC_JIC, OPC_JIALC */
11071 TCGv tbase
= tcg_temp_new();
11072 TCGv toffset
= tcg_temp_new();
11074 gen_load_gpr(tbase
, rt
);
11075 tcg_gen_movi_tl(toffset
, offset
);
11076 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
11077 tcg_temp_free(tbase
);
11078 tcg_temp_free(toffset
);
11082 MIPS_INVAL("Compact branch/jump");
11083 generate_exception(ctx
, EXCP_RI
);
11087 if (bcond_compute
== 0) {
11088 /* Uncoditional compact branch */
11091 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11094 ctx
->hflags
|= MIPS_HFLAG_BR
;
11097 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11100 ctx
->hflags
|= MIPS_HFLAG_B
;
11103 MIPS_INVAL("Compact branch/jump");
11104 generate_exception(ctx
, EXCP_RI
);
11108 /* Generating branch here as compact branches don't have delay slot */
11109 gen_branch(ctx
, 4);
11111 /* Conditional compact branch */
11112 TCGLabel
*fs
= gen_new_label();
11113 save_cpu_state(ctx
, 0);
11116 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
11117 if (rs
== 0 && rt
!= 0) {
11119 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
11120 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11122 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
11125 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
11128 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
11129 if (rs
== 0 && rt
!= 0) {
11131 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
11132 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11134 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
11137 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
11140 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
11141 if (rs
== 0 && rt
!= 0) {
11143 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
11144 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11146 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
11149 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
11152 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
11153 if (rs
== 0 && rt
!= 0) {
11155 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
11156 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11158 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
11161 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
11164 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
11165 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
11167 /* OPC_BOVC, OPC_BNVC */
11168 TCGv t2
= tcg_temp_new();
11169 TCGv t3
= tcg_temp_new();
11170 TCGv t4
= tcg_temp_new();
11171 TCGv input_overflow
= tcg_temp_new();
11173 gen_load_gpr(t0
, rs
);
11174 gen_load_gpr(t1
, rt
);
11175 tcg_gen_ext32s_tl(t2
, t0
);
11176 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
11177 tcg_gen_ext32s_tl(t3
, t1
);
11178 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
11179 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
11181 tcg_gen_add_tl(t4
, t2
, t3
);
11182 tcg_gen_ext32s_tl(t4
, t4
);
11183 tcg_gen_xor_tl(t2
, t2
, t3
);
11184 tcg_gen_xor_tl(t3
, t4
, t3
);
11185 tcg_gen_andc_tl(t2
, t3
, t2
);
11186 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
11187 tcg_gen_or_tl(t4
, t4
, input_overflow
);
11188 if (opc
== OPC_BOVC
) {
11190 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
11193 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
11195 tcg_temp_free(input_overflow
);
11199 } else if (rs
< rt
&& rs
== 0) {
11200 /* OPC_BEQZALC, OPC_BNEZALC */
11201 if (opc
== OPC_BEQZALC
) {
11203 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
11206 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
11209 /* OPC_BEQC, OPC_BNEC */
11210 if (opc
== OPC_BEQC
) {
11212 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
11215 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
11220 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
11223 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
11226 MIPS_INVAL("Compact conditional branch/jump");
11227 generate_exception(ctx
, EXCP_RI
);
11231 /* Generating branch here as compact branches don't have delay slot */
11232 gen_goto_tb(ctx
, 1, ctx
->btarget
);
11235 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
11236 MIPS_DEBUG("Compact conditional branch");
11244 /* ISA extensions (ASEs) */
11245 /* MIPS16 extension to MIPS32 */
11247 /* MIPS16 major opcodes */
11249 M16_OPC_ADDIUSP
= 0x00,
11250 M16_OPC_ADDIUPC
= 0x01,
11252 M16_OPC_JAL
= 0x03,
11253 M16_OPC_BEQZ
= 0x04,
11254 M16_OPC_BNEQZ
= 0x05,
11255 M16_OPC_SHIFT
= 0x06,
11257 M16_OPC_RRIA
= 0x08,
11258 M16_OPC_ADDIU8
= 0x09,
11259 M16_OPC_SLTI
= 0x0a,
11260 M16_OPC_SLTIU
= 0x0b,
11263 M16_OPC_CMPI
= 0x0e,
11267 M16_OPC_LWSP
= 0x12,
11269 M16_OPC_LBU
= 0x14,
11270 M16_OPC_LHU
= 0x15,
11271 M16_OPC_LWPC
= 0x16,
11272 M16_OPC_LWU
= 0x17,
11275 M16_OPC_SWSP
= 0x1a,
11277 M16_OPC_RRR
= 0x1c,
11279 M16_OPC_EXTEND
= 0x1e,
11283 /* I8 funct field */
11302 /* RR funct field */
11336 /* I64 funct field */
11344 I64_DADDIUPC
= 0x6,
11348 /* RR ry field for CNVT */
11350 RR_RY_CNVT_ZEB
= 0x0,
11351 RR_RY_CNVT_ZEH
= 0x1,
11352 RR_RY_CNVT_ZEW
= 0x2,
11353 RR_RY_CNVT_SEB
= 0x4,
11354 RR_RY_CNVT_SEH
= 0x5,
11355 RR_RY_CNVT_SEW
= 0x6,
11358 static int xlat (int r
)
11360 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11365 static void gen_mips16_save (DisasContext
*ctx
,
11366 int xsregs
, int aregs
,
11367 int do_ra
, int do_s0
, int do_s1
,
11370 TCGv t0
= tcg_temp_new();
11371 TCGv t1
= tcg_temp_new();
11372 TCGv t2
= tcg_temp_new();
11402 generate_exception(ctx
, EXCP_RI
);
11408 gen_base_offset_addr(ctx
, t0
, 29, 12);
11409 gen_load_gpr(t1
, 7);
11410 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11413 gen_base_offset_addr(ctx
, t0
, 29, 8);
11414 gen_load_gpr(t1
, 6);
11415 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11418 gen_base_offset_addr(ctx
, t0
, 29, 4);
11419 gen_load_gpr(t1
, 5);
11420 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11423 gen_base_offset_addr(ctx
, t0
, 29, 0);
11424 gen_load_gpr(t1
, 4);
11425 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11428 gen_load_gpr(t0
, 29);
11430 #define DECR_AND_STORE(reg) do { \
11431 tcg_gen_movi_tl(t2, -4); \
11432 gen_op_addr_add(ctx, t0, t0, t2); \
11433 gen_load_gpr(t1, reg); \
11434 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11438 DECR_AND_STORE(31);
11443 DECR_AND_STORE(30);
11446 DECR_AND_STORE(23);
11449 DECR_AND_STORE(22);
11452 DECR_AND_STORE(21);
11455 DECR_AND_STORE(20);
11458 DECR_AND_STORE(19);
11461 DECR_AND_STORE(18);
11465 DECR_AND_STORE(17);
11468 DECR_AND_STORE(16);
11498 generate_exception(ctx
, EXCP_RI
);
11514 #undef DECR_AND_STORE
11516 tcg_gen_movi_tl(t2
, -framesize
);
11517 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11523 static void gen_mips16_restore (DisasContext
*ctx
,
11524 int xsregs
, int aregs
,
11525 int do_ra
, int do_s0
, int do_s1
,
11529 TCGv t0
= tcg_temp_new();
11530 TCGv t1
= tcg_temp_new();
11531 TCGv t2
= tcg_temp_new();
11533 tcg_gen_movi_tl(t2
, framesize
);
11534 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
11536 #define DECR_AND_LOAD(reg) do { \
11537 tcg_gen_movi_tl(t2, -4); \
11538 gen_op_addr_add(ctx, t0, t0, t2); \
11539 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11540 gen_store_gpr(t1, reg); \
11604 generate_exception(ctx
, EXCP_RI
);
11620 #undef DECR_AND_LOAD
11622 tcg_gen_movi_tl(t2
, framesize
);
11623 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11629 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
11630 int is_64_bit
, int extended
)
11634 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11635 generate_exception(ctx
, EXCP_RI
);
11639 t0
= tcg_temp_new();
11641 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
11642 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
11644 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11650 #if defined(TARGET_MIPS64)
11651 static void decode_i64_mips16 (DisasContext
*ctx
,
11652 int ry
, int funct
, int16_t offset
,
11657 check_insn(ctx
, ISA_MIPS3
);
11658 check_mips_64(ctx
);
11659 offset
= extended
? offset
: offset
<< 3;
11660 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
11663 check_insn(ctx
, ISA_MIPS3
);
11664 check_mips_64(ctx
);
11665 offset
= extended
? offset
: offset
<< 3;
11666 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
11669 check_insn(ctx
, ISA_MIPS3
);
11670 check_mips_64(ctx
);
11671 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
11672 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
11675 check_insn(ctx
, ISA_MIPS3
);
11676 check_mips_64(ctx
);
11677 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
11678 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
11681 check_insn(ctx
, ISA_MIPS3
);
11682 check_mips_64(ctx
);
11683 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11684 generate_exception(ctx
, EXCP_RI
);
11686 offset
= extended
? offset
: offset
<< 3;
11687 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
11691 check_insn(ctx
, ISA_MIPS3
);
11692 check_mips_64(ctx
);
11693 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
11694 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
11697 check_insn(ctx
, ISA_MIPS3
);
11698 check_mips_64(ctx
);
11699 offset
= extended
? offset
: offset
<< 2;
11700 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
11703 check_insn(ctx
, ISA_MIPS3
);
11704 check_mips_64(ctx
);
11705 offset
= extended
? offset
: offset
<< 2;
11706 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
11712 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11714 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11715 int op
, rx
, ry
, funct
, sa
;
11716 int16_t imm
, offset
;
11718 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
11719 op
= (ctx
->opcode
>> 11) & 0x1f;
11720 sa
= (ctx
->opcode
>> 22) & 0x1f;
11721 funct
= (ctx
->opcode
>> 8) & 0x7;
11722 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11723 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11724 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
11725 | ((ctx
->opcode
>> 21) & 0x3f) << 5
11726 | (ctx
->opcode
& 0x1f));
11728 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11731 case M16_OPC_ADDIUSP
:
11732 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11734 case M16_OPC_ADDIUPC
:
11735 gen_addiupc(ctx
, rx
, imm
, 0, 1);
11738 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
11739 /* No delay slot, so just process as a normal instruction */
11742 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
11743 /* No delay slot, so just process as a normal instruction */
11745 case M16_OPC_BNEQZ
:
11746 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
11747 /* No delay slot, so just process as a normal instruction */
11749 case M16_OPC_SHIFT
:
11750 switch (ctx
->opcode
& 0x3) {
11752 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11755 #if defined(TARGET_MIPS64)
11756 check_mips_64(ctx
);
11757 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11759 generate_exception(ctx
, EXCP_RI
);
11763 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11766 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11770 #if defined(TARGET_MIPS64)
11772 check_insn(ctx
, ISA_MIPS3
);
11773 check_mips_64(ctx
);
11774 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
11778 imm
= ctx
->opcode
& 0xf;
11779 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
11780 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
11781 imm
= (int16_t) (imm
<< 1) >> 1;
11782 if ((ctx
->opcode
>> 4) & 0x1) {
11783 #if defined(TARGET_MIPS64)
11784 check_mips_64(ctx
);
11785 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11787 generate_exception(ctx
, EXCP_RI
);
11790 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11793 case M16_OPC_ADDIU8
:
11794 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11797 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11799 case M16_OPC_SLTIU
:
11800 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11805 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
11808 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
11811 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
11814 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
11817 check_insn(ctx
, ISA_MIPS32
);
11819 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
11820 int aregs
= (ctx
->opcode
>> 16) & 0xf;
11821 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
11822 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
11823 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
11824 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
11825 | (ctx
->opcode
& 0xf)) << 3;
11827 if (ctx
->opcode
& (1 << 7)) {
11828 gen_mips16_save(ctx
, xsregs
, aregs
,
11829 do_ra
, do_s0
, do_s1
,
11832 gen_mips16_restore(ctx
, xsregs
, aregs
,
11833 do_ra
, do_s0
, do_s1
,
11839 generate_exception(ctx
, EXCP_RI
);
11844 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
11847 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
11849 #if defined(TARGET_MIPS64)
11851 check_insn(ctx
, ISA_MIPS3
);
11852 check_mips_64(ctx
);
11853 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
11857 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11860 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
11863 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
11866 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
11869 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11872 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
11875 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
11877 #if defined(TARGET_MIPS64)
11879 check_insn(ctx
, ISA_MIPS3
);
11880 check_mips_64(ctx
);
11881 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
11885 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11888 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
11891 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
11894 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
11896 #if defined(TARGET_MIPS64)
11898 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
11902 generate_exception(ctx
, EXCP_RI
);
11909 static inline bool is_uhi(int sdbbp_code
)
11911 #ifdef CONFIG_USER_ONLY
11914 return semihosting_enabled() && sdbbp_code
== 1;
11918 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11922 int op
, cnvt_op
, op1
, offset
;
11926 op
= (ctx
->opcode
>> 11) & 0x1f;
11927 sa
= (ctx
->opcode
>> 2) & 0x7;
11928 sa
= sa
== 0 ? 8 : sa
;
11929 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11930 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
11931 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11932 op1
= offset
= ctx
->opcode
& 0x1f;
11937 case M16_OPC_ADDIUSP
:
11939 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
11941 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11944 case M16_OPC_ADDIUPC
:
11945 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
11948 offset
= (ctx
->opcode
& 0x7ff) << 1;
11949 offset
= (int16_t)(offset
<< 4) >> 4;
11950 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
11951 /* No delay slot, so just process as a normal instruction */
11954 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11955 offset
= (((ctx
->opcode
& 0x1f) << 21)
11956 | ((ctx
->opcode
>> 5) & 0x1f) << 16
11958 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
11959 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
11963 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
11964 ((int8_t)ctx
->opcode
) << 1, 0);
11965 /* No delay slot, so just process as a normal instruction */
11967 case M16_OPC_BNEQZ
:
11968 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
11969 ((int8_t)ctx
->opcode
) << 1, 0);
11970 /* No delay slot, so just process as a normal instruction */
11972 case M16_OPC_SHIFT
:
11973 switch (ctx
->opcode
& 0x3) {
11975 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11978 #if defined(TARGET_MIPS64)
11979 check_insn(ctx
, ISA_MIPS3
);
11980 check_mips_64(ctx
);
11981 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11983 generate_exception(ctx
, EXCP_RI
);
11987 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11990 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11994 #if defined(TARGET_MIPS64)
11996 check_insn(ctx
, ISA_MIPS3
);
11997 check_mips_64(ctx
);
11998 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
12003 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
12005 if ((ctx
->opcode
>> 4) & 1) {
12006 #if defined(TARGET_MIPS64)
12007 check_insn(ctx
, ISA_MIPS3
);
12008 check_mips_64(ctx
);
12009 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
12011 generate_exception(ctx
, EXCP_RI
);
12014 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
12018 case M16_OPC_ADDIU8
:
12020 int16_t imm
= (int8_t) ctx
->opcode
;
12022 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
12027 int16_t imm
= (uint8_t) ctx
->opcode
;
12028 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
12031 case M16_OPC_SLTIU
:
12033 int16_t imm
= (uint8_t) ctx
->opcode
;
12034 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
12041 funct
= (ctx
->opcode
>> 8) & 0x7;
12044 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
12045 ((int8_t)ctx
->opcode
) << 1, 0);
12048 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
12049 ((int8_t)ctx
->opcode
) << 1, 0);
12052 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
12055 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
12056 ((int8_t)ctx
->opcode
) << 3);
12059 check_insn(ctx
, ISA_MIPS32
);
12061 int do_ra
= ctx
->opcode
& (1 << 6);
12062 int do_s0
= ctx
->opcode
& (1 << 5);
12063 int do_s1
= ctx
->opcode
& (1 << 4);
12064 int framesize
= ctx
->opcode
& 0xf;
12066 if (framesize
== 0) {
12069 framesize
= framesize
<< 3;
12072 if (ctx
->opcode
& (1 << 7)) {
12073 gen_mips16_save(ctx
, 0, 0,
12074 do_ra
, do_s0
, do_s1
, framesize
);
12076 gen_mips16_restore(ctx
, 0, 0,
12077 do_ra
, do_s0
, do_s1
, framesize
);
12083 int rz
= xlat(ctx
->opcode
& 0x7);
12085 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
12086 ((ctx
->opcode
>> 5) & 0x7);
12087 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
12091 reg32
= ctx
->opcode
& 0x1f;
12092 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
12095 generate_exception(ctx
, EXCP_RI
);
12102 int16_t imm
= (uint8_t) ctx
->opcode
;
12104 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
12109 int16_t imm
= (uint8_t) ctx
->opcode
;
12110 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
12113 #if defined(TARGET_MIPS64)
12115 check_insn(ctx
, ISA_MIPS3
);
12116 check_mips_64(ctx
);
12117 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
12121 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
12124 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
12127 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
12130 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
12133 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
12136 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
12139 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
12141 #if defined (TARGET_MIPS64)
12143 check_insn(ctx
, ISA_MIPS3
);
12144 check_mips_64(ctx
);
12145 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
12149 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
12152 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
12155 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
12158 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
12162 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
12165 switch (ctx
->opcode
& 0x3) {
12167 mips32_op
= OPC_ADDU
;
12170 mips32_op
= OPC_SUBU
;
12172 #if defined(TARGET_MIPS64)
12174 mips32_op
= OPC_DADDU
;
12175 check_insn(ctx
, ISA_MIPS3
);
12176 check_mips_64(ctx
);
12179 mips32_op
= OPC_DSUBU
;
12180 check_insn(ctx
, ISA_MIPS3
);
12181 check_mips_64(ctx
);
12185 generate_exception(ctx
, EXCP_RI
);
12189 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
12198 int nd
= (ctx
->opcode
>> 7) & 0x1;
12199 int link
= (ctx
->opcode
>> 6) & 0x1;
12200 int ra
= (ctx
->opcode
>> 5) & 0x1;
12203 check_insn(ctx
, ISA_MIPS32
);
12212 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
12217 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
12218 gen_helper_do_semihosting(cpu_env
);
12220 /* XXX: not clear which exception should be raised
12221 * when in debug mode...
12223 check_insn(ctx
, ISA_MIPS32
);
12224 generate_exception(ctx
, EXCP_DBp
);
12228 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
12231 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
12234 generate_exception(ctx
, EXCP_BREAK
);
12237 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
12240 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
12243 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
12245 #if defined (TARGET_MIPS64)
12247 check_insn(ctx
, ISA_MIPS3
);
12248 check_mips_64(ctx
);
12249 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
12253 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
12256 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
12259 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
12262 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
12265 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
12268 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
12271 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
12274 check_insn(ctx
, ISA_MIPS32
);
12276 case RR_RY_CNVT_ZEB
:
12277 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12279 case RR_RY_CNVT_ZEH
:
12280 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12282 case RR_RY_CNVT_SEB
:
12283 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12285 case RR_RY_CNVT_SEH
:
12286 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12288 #if defined (TARGET_MIPS64)
12289 case RR_RY_CNVT_ZEW
:
12290 check_insn(ctx
, ISA_MIPS64
);
12291 check_mips_64(ctx
);
12292 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12294 case RR_RY_CNVT_SEW
:
12295 check_insn(ctx
, ISA_MIPS64
);
12296 check_mips_64(ctx
);
12297 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12301 generate_exception(ctx
, EXCP_RI
);
12306 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
12308 #if defined (TARGET_MIPS64)
12310 check_insn(ctx
, ISA_MIPS3
);
12311 check_mips_64(ctx
);
12312 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
12315 check_insn(ctx
, ISA_MIPS3
);
12316 check_mips_64(ctx
);
12317 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
12320 check_insn(ctx
, ISA_MIPS3
);
12321 check_mips_64(ctx
);
12322 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
12325 check_insn(ctx
, ISA_MIPS3
);
12326 check_mips_64(ctx
);
12327 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
12331 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
12334 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
12337 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
12340 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
12342 #if defined (TARGET_MIPS64)
12344 check_insn(ctx
, ISA_MIPS3
);
12345 check_mips_64(ctx
);
12346 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
12349 check_insn(ctx
, ISA_MIPS3
);
12350 check_mips_64(ctx
);
12351 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
12354 check_insn(ctx
, ISA_MIPS3
);
12355 check_mips_64(ctx
);
12356 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
12359 check_insn(ctx
, ISA_MIPS3
);
12360 check_mips_64(ctx
);
12361 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
12365 generate_exception(ctx
, EXCP_RI
);
12369 case M16_OPC_EXTEND
:
12370 decode_extended_mips16_opc(env
, ctx
);
12373 #if defined(TARGET_MIPS64)
12375 funct
= (ctx
->opcode
>> 8) & 0x7;
12376 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
12380 generate_exception(ctx
, EXCP_RI
);
12387 /* microMIPS extension to MIPS32/MIPS64 */
12390 * microMIPS32/microMIPS64 major opcodes
12392 * 1. MIPS Architecture for Programmers Volume II-B:
12393 * The microMIPS32 Instruction Set (Revision 3.05)
12395 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12397 * 2. MIPS Architecture For Programmers Volume II-A:
12398 * The MIPS64 Instruction Set (Revision 3.51)
12428 POOL32S
= 0x16, /* MIPS64 */
12429 DADDIU32
= 0x17, /* MIPS64 */
12458 /* 0x29 is reserved */
12471 /* 0x31 is reserved */
12484 SD32
= 0x36, /* MIPS64 */
12485 LD32
= 0x37, /* MIPS64 */
12487 /* 0x39 is reserved */
12503 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12513 /* POOL32A encoding of minor opcode field */
12516 /* These opcodes are distinguished only by bits 9..6; those bits are
12517 * what are recorded below. */
12553 /* The following can be distinguished by their lower 6 bits. */
12561 /* POOL32AXF encoding of minor opcode field extension */
12564 * 1. MIPS Architecture for Programmers Volume II-B:
12565 * The microMIPS32 Instruction Set (Revision 3.05)
12567 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12569 * 2. MIPS Architecture for Programmers VolumeIV-e:
12570 * The MIPS DSP Application-Specific Extension
12571 * to the microMIPS32 Architecture (Revision 2.34)
12573 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12588 /* begin of microMIPS32 DSP */
12590 /* bits 13..12 for 0x01 */
12596 /* bits 13..12 for 0x2a */
12602 /* bits 13..12 for 0x32 */
12606 /* end of microMIPS32 DSP */
12608 /* bits 15..12 for 0x2c */
12625 /* bits 15..12 for 0x34 */
12633 /* bits 15..12 for 0x3c */
12635 JR
= 0x0, /* alias */
12643 /* bits 15..12 for 0x05 */
12647 /* bits 15..12 for 0x0d */
12659 /* bits 15..12 for 0x15 */
12665 /* bits 15..12 for 0x1d */
12669 /* bits 15..12 for 0x2d */
12674 /* bits 15..12 for 0x35 */
12681 /* POOL32B encoding of minor opcode field (bits 15..12) */
12697 /* POOL32C encoding of minor opcode field (bits 15..12) */
12705 /* 0xa is reserved */
12712 /* 0x6 is reserved */
12718 /* POOL32F encoding of minor opcode field (bits 5..0) */
12721 /* These are the bit 7..6 values */
12730 /* These are the bit 8..6 values */
12755 MOVZ_FMT_05
= 0x05,
12789 CABS_COND_FMT
= 0x1c, /* MIPS3D */
12796 /* POOL32Fxf encoding of minor opcode extension field */
12834 /* POOL32I encoding of minor opcode field (bits 25..21) */
12864 /* These overlap and are distinguished by bit16 of the instruction */
12873 /* POOL16A encoding of minor opcode field */
12880 /* POOL16B encoding of minor opcode field */
12887 /* POOL16C encoding of minor opcode field */
12907 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12927 /* POOL16D encoding of minor opcode field */
12934 /* POOL16E encoding of minor opcode field */
12941 static int mmreg (int r
)
12943 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12948 /* Used for 16-bit store instructions. */
12949 static int mmreg2 (int r
)
12951 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12956 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12957 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12958 #define uMIPS_RS2(op) uMIPS_RS(op)
12959 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12960 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12961 #define uMIPS_RS5(op) (op & 0x1f)
12963 /* Signed immediate */
12964 #define SIMM(op, start, width) \
12965 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12968 /* Zero-extended immediate */
12969 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12971 static void gen_addiur1sp(DisasContext
*ctx
)
12973 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12975 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
12978 static void gen_addiur2(DisasContext
*ctx
)
12980 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12981 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12982 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12984 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
12987 static void gen_addiusp(DisasContext
*ctx
)
12989 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
12992 if (encoded
<= 1) {
12993 decoded
= 256 + encoded
;
12994 } else if (encoded
<= 255) {
12996 } else if (encoded
<= 509) {
12997 decoded
= encoded
- 512;
12999 decoded
= encoded
- 768;
13002 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
13005 static void gen_addius5(DisasContext
*ctx
)
13007 int imm
= SIMM(ctx
->opcode
, 1, 4);
13008 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13010 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
13013 static void gen_andi16(DisasContext
*ctx
)
13015 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13016 31, 32, 63, 64, 255, 32768, 65535 };
13017 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13018 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
13019 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
13021 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
13024 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
13025 int base
, int16_t offset
)
13027 const char *opn
= "ldst_multiple";
13031 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13032 generate_exception(ctx
, EXCP_RI
);
13036 t0
= tcg_temp_new();
13038 gen_base_offset_addr(ctx
, t0
, base
, offset
);
13040 t1
= tcg_const_tl(reglist
);
13041 t2
= tcg_const_i32(ctx
->mem_idx
);
13043 save_cpu_state(ctx
, 1);
13046 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
13050 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
13053 #ifdef TARGET_MIPS64
13055 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
13059 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
13065 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
13068 tcg_temp_free_i32(t2
);
13072 static void gen_pool16c_insn(DisasContext
*ctx
)
13074 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
13075 int rs
= mmreg(ctx
->opcode
& 0x7);
13077 switch (((ctx
->opcode
) >> 4) & 0x3f) {
13082 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
13088 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
13094 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
13100 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
13107 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
13108 int offset
= ZIMM(ctx
->opcode
, 0, 4);
13110 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
13119 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
13120 int offset
= ZIMM(ctx
->opcode
, 0, 4);
13122 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
13129 int reg
= ctx
->opcode
& 0x1f;
13131 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
13137 int reg
= ctx
->opcode
& 0x1f;
13138 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
13139 /* Let normal delay slot handling in our caller take us
13140 to the branch target. */
13145 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
13146 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13150 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
13151 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13155 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
13159 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
13162 generate_exception(ctx
, EXCP_BREAK
);
13165 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
13166 gen_helper_do_semihosting(cpu_env
);
13168 /* XXX: not clear which exception should be raised
13169 * when in debug mode...
13171 check_insn(ctx
, ISA_MIPS32
);
13172 generate_exception(ctx
, EXCP_DBp
);
13175 case JRADDIUSP
+ 0:
13176 case JRADDIUSP
+ 1:
13178 int imm
= ZIMM(ctx
->opcode
, 0, 5);
13179 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
13180 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
13181 /* Let normal delay slot handling in our caller take us
13182 to the branch target. */
13186 generate_exception(ctx
, EXCP_RI
);
13191 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
13194 int rd
, rs
, re
, rt
;
13195 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13196 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13197 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13198 rd
= rd_enc
[enc_dest
];
13199 re
= re_enc
[enc_dest
];
13200 rs
= rs_rt_enc
[enc_rs
];
13201 rt
= rs_rt_enc
[enc_rt
];
13203 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
13205 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
13208 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
13210 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
13214 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
13216 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
13217 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
13219 switch (ctx
->opcode
& 0xf) {
13221 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
13224 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
13228 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
13229 int offset
= extract32(ctx
->opcode
, 4, 4);
13230 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
13233 case R6_JRC16
: /* JRCADDIUSP */
13234 if ((ctx
->opcode
>> 4) & 1) {
13236 int imm
= extract32(ctx
->opcode
, 5, 5);
13237 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
13238 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
13241 int rs
= extract32(ctx
->opcode
, 5, 5);
13242 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
13245 case MOVEP
... MOVEP_07
:
13246 case MOVEP_0C
... MOVEP_0F
:
13248 int enc_dest
= uMIPS_RD(ctx
->opcode
);
13249 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
13250 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
13251 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
13255 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
13258 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
13262 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
13263 int offset
= extract32(ctx
->opcode
, 4, 4);
13264 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
13267 case JALRC16
: /* BREAK16, SDBBP16 */
13268 switch (ctx
->opcode
& 0x3f) {
13270 case JALRC16
+ 0x20:
13272 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
13277 generate_exception(ctx
, EXCP_BREAK
);
13281 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
13282 generate_exception(ctx
, EXCP_RI
);
13284 generate_exception(ctx
, EXCP_DBp
);
13290 generate_exception(ctx
, EXCP_RI
);
13295 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
13297 TCGv t0
= tcg_temp_new();
13298 TCGv t1
= tcg_temp_new();
13300 gen_load_gpr(t0
, base
);
13303 gen_load_gpr(t1
, index
);
13304 tcg_gen_shli_tl(t1
, t1
, 2);
13305 gen_op_addr_add(ctx
, t0
, t1
, t0
);
13308 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13309 gen_store_gpr(t1
, rd
);
13315 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
13316 int base
, int16_t offset
)
13318 const char *opn
= "ldst_pair";
13321 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
13322 generate_exception(ctx
, EXCP_RI
);
13326 t0
= tcg_temp_new();
13327 t1
= tcg_temp_new();
13329 gen_base_offset_addr(ctx
, t0
, base
, offset
);
13334 generate_exception(ctx
, EXCP_RI
);
13337 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13338 gen_store_gpr(t1
, rd
);
13339 tcg_gen_movi_tl(t1
, 4);
13340 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13341 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13342 gen_store_gpr(t1
, rd
+1);
13346 gen_load_gpr(t1
, rd
);
13347 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13348 tcg_gen_movi_tl(t1
, 4);
13349 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13350 gen_load_gpr(t1
, rd
+1);
13351 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13354 #ifdef TARGET_MIPS64
13357 generate_exception(ctx
, EXCP_RI
);
13360 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13361 gen_store_gpr(t1
, rd
);
13362 tcg_gen_movi_tl(t1
, 8);
13363 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13364 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13365 gen_store_gpr(t1
, rd
+1);
13369 gen_load_gpr(t1
, rd
);
13370 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13371 tcg_gen_movi_tl(t1
, 8);
13372 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13373 gen_load_gpr(t1
, rd
+1);
13374 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13379 (void)opn
; /* avoid a compiler warning */
13380 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
13385 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
13387 int extension
= (ctx
->opcode
>> 6) & 0x3f;
13388 int minor
= (ctx
->opcode
>> 12) & 0xf;
13389 uint32_t mips32_op
;
13391 switch (extension
) {
13393 mips32_op
= OPC_TEQ
;
13396 mips32_op
= OPC_TGE
;
13399 mips32_op
= OPC_TGEU
;
13402 mips32_op
= OPC_TLT
;
13405 mips32_op
= OPC_TLTU
;
13408 mips32_op
= OPC_TNE
;
13410 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
13412 #ifndef CONFIG_USER_ONLY
13415 check_cp0_enabled(ctx
);
13417 /* Treat as NOP. */
13420 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
13424 check_cp0_enabled(ctx
);
13426 TCGv t0
= tcg_temp_new();
13428 gen_load_gpr(t0
, rt
);
13429 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
13435 switch (minor
& 3) {
13437 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13440 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13443 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13446 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13449 goto pool32axf_invalid
;
13453 switch (minor
& 3) {
13455 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13458 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13461 goto pool32axf_invalid
;
13467 check_insn(ctx
, ISA_MIPS32R6
);
13468 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
13471 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
13474 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
13477 mips32_op
= OPC_CLO
;
13480 mips32_op
= OPC_CLZ
;
13482 check_insn(ctx
, ISA_MIPS32
);
13483 gen_cl(ctx
, mips32_op
, rt
, rs
);
13486 gen_rdhwr(ctx
, rt
, rs
);
13489 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
13492 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13493 mips32_op
= OPC_MULT
;
13496 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13497 mips32_op
= OPC_MULTU
;
13500 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13501 mips32_op
= OPC_DIV
;
13504 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13505 mips32_op
= OPC_DIVU
;
13508 check_insn(ctx
, ISA_MIPS32
);
13509 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
13512 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13513 mips32_op
= OPC_MADD
;
13516 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13517 mips32_op
= OPC_MADDU
;
13520 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13521 mips32_op
= OPC_MSUB
;
13524 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13525 mips32_op
= OPC_MSUBU
;
13527 check_insn(ctx
, ISA_MIPS32
);
13528 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
13531 goto pool32axf_invalid
;
13542 generate_exception_err(ctx
, EXCP_CpU
, 2);
13545 goto pool32axf_invalid
;
13550 case JALR
: /* JALRC */
13551 case JALR_HB
: /* JALRC_HB */
13552 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13553 /* JALRC, JALRC_HB */
13554 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
13556 /* JALR, JALR_HB */
13557 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
13558 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13563 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13564 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
13565 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13568 goto pool32axf_invalid
;
13574 check_cp0_enabled(ctx
);
13575 check_insn(ctx
, ISA_MIPS32R2
);
13576 gen_load_srsgpr(rs
, rt
);
13579 check_cp0_enabled(ctx
);
13580 check_insn(ctx
, ISA_MIPS32R2
);
13581 gen_store_srsgpr(rs
, rt
);
13584 goto pool32axf_invalid
;
13587 #ifndef CONFIG_USER_ONLY
13591 mips32_op
= OPC_TLBP
;
13594 mips32_op
= OPC_TLBR
;
13597 mips32_op
= OPC_TLBWI
;
13600 mips32_op
= OPC_TLBWR
;
13603 mips32_op
= OPC_TLBINV
;
13606 mips32_op
= OPC_TLBINVF
;
13609 mips32_op
= OPC_WAIT
;
13612 mips32_op
= OPC_DERET
;
13615 mips32_op
= OPC_ERET
;
13617 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
13620 goto pool32axf_invalid
;
13626 check_cp0_enabled(ctx
);
13628 TCGv t0
= tcg_temp_new();
13630 save_cpu_state(ctx
, 1);
13631 gen_helper_di(t0
, cpu_env
);
13632 gen_store_gpr(t0
, rs
);
13633 /* Stop translation as we may have switched the execution mode */
13634 ctx
->bstate
= BS_STOP
;
13639 check_cp0_enabled(ctx
);
13641 TCGv t0
= tcg_temp_new();
13643 save_cpu_state(ctx
, 1);
13644 gen_helper_ei(t0
, cpu_env
);
13645 gen_store_gpr(t0
, rs
);
13646 /* Stop translation as we may have switched the execution mode */
13647 ctx
->bstate
= BS_STOP
;
13652 goto pool32axf_invalid
;
13662 generate_exception(ctx
, EXCP_SYSCALL
);
13663 ctx
->bstate
= BS_STOP
;
13666 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
13667 gen_helper_do_semihosting(cpu_env
);
13669 check_insn(ctx
, ISA_MIPS32
);
13670 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
13671 generate_exception(ctx
, EXCP_RI
);
13673 generate_exception(ctx
, EXCP_DBp
);
13678 goto pool32axf_invalid
;
13682 switch (minor
& 3) {
13684 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
13687 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
13690 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
13693 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
13696 goto pool32axf_invalid
;
13700 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13703 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
13706 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
13709 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
13712 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
13715 goto pool32axf_invalid
;
13720 MIPS_INVAL("pool32axf");
13721 generate_exception(ctx
, EXCP_RI
);
13726 /* Values for microMIPS fmt field. Variable-width, depending on which
13727 formats the instruction supports. */
13746 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
13748 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
13749 uint32_t mips32_op
;
13751 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13752 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13753 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13755 switch (extension
) {
13756 case FLOAT_1BIT_FMT(CFC1
, 0):
13757 mips32_op
= OPC_CFC1
;
13759 case FLOAT_1BIT_FMT(CTC1
, 0):
13760 mips32_op
= OPC_CTC1
;
13762 case FLOAT_1BIT_FMT(MFC1
, 0):
13763 mips32_op
= OPC_MFC1
;
13765 case FLOAT_1BIT_FMT(MTC1
, 0):
13766 mips32_op
= OPC_MTC1
;
13768 case FLOAT_1BIT_FMT(MFHC1
, 0):
13769 mips32_op
= OPC_MFHC1
;
13771 case FLOAT_1BIT_FMT(MTHC1
, 0):
13772 mips32_op
= OPC_MTHC1
;
13774 gen_cp1(ctx
, mips32_op
, rt
, rs
);
13777 /* Reciprocal square root */
13778 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
13779 mips32_op
= OPC_RSQRT_S
;
13781 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
13782 mips32_op
= OPC_RSQRT_D
;
13786 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
13787 mips32_op
= OPC_SQRT_S
;
13789 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
13790 mips32_op
= OPC_SQRT_D
;
13794 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
13795 mips32_op
= OPC_RECIP_S
;
13797 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
13798 mips32_op
= OPC_RECIP_D
;
13802 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
13803 mips32_op
= OPC_FLOOR_L_S
;
13805 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
13806 mips32_op
= OPC_FLOOR_L_D
;
13808 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
13809 mips32_op
= OPC_FLOOR_W_S
;
13811 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
13812 mips32_op
= OPC_FLOOR_W_D
;
13816 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
13817 mips32_op
= OPC_CEIL_L_S
;
13819 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
13820 mips32_op
= OPC_CEIL_L_D
;
13822 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
13823 mips32_op
= OPC_CEIL_W_S
;
13825 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
13826 mips32_op
= OPC_CEIL_W_D
;
13830 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
13831 mips32_op
= OPC_TRUNC_L_S
;
13833 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
13834 mips32_op
= OPC_TRUNC_L_D
;
13836 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
13837 mips32_op
= OPC_TRUNC_W_S
;
13839 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
13840 mips32_op
= OPC_TRUNC_W_D
;
13844 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
13845 mips32_op
= OPC_ROUND_L_S
;
13847 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
13848 mips32_op
= OPC_ROUND_L_D
;
13850 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
13851 mips32_op
= OPC_ROUND_W_S
;
13853 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
13854 mips32_op
= OPC_ROUND_W_D
;
13857 /* Integer to floating-point conversion */
13858 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
13859 mips32_op
= OPC_CVT_L_S
;
13861 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
13862 mips32_op
= OPC_CVT_L_D
;
13864 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
13865 mips32_op
= OPC_CVT_W_S
;
13867 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
13868 mips32_op
= OPC_CVT_W_D
;
13871 /* Paired-foo conversions */
13872 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
13873 mips32_op
= OPC_CVT_S_PL
;
13875 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
13876 mips32_op
= OPC_CVT_S_PU
;
13878 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
13879 mips32_op
= OPC_CVT_PW_PS
;
13881 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
13882 mips32_op
= OPC_CVT_PS_PW
;
13885 /* Floating-point moves */
13886 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
13887 mips32_op
= OPC_MOV_S
;
13889 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
13890 mips32_op
= OPC_MOV_D
;
13892 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
13893 mips32_op
= OPC_MOV_PS
;
13896 /* Absolute value */
13897 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
13898 mips32_op
= OPC_ABS_S
;
13900 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
13901 mips32_op
= OPC_ABS_D
;
13903 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
13904 mips32_op
= OPC_ABS_PS
;
13908 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
13909 mips32_op
= OPC_NEG_S
;
13911 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
13912 mips32_op
= OPC_NEG_D
;
13914 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
13915 mips32_op
= OPC_NEG_PS
;
13918 /* Reciprocal square root step */
13919 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
13920 mips32_op
= OPC_RSQRT1_S
;
13922 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
13923 mips32_op
= OPC_RSQRT1_D
;
13925 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
13926 mips32_op
= OPC_RSQRT1_PS
;
13929 /* Reciprocal step */
13930 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
13931 mips32_op
= OPC_RECIP1_S
;
13933 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
13934 mips32_op
= OPC_RECIP1_S
;
13936 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
13937 mips32_op
= OPC_RECIP1_PS
;
13940 /* Conversions from double */
13941 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
13942 mips32_op
= OPC_CVT_D_S
;
13944 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
13945 mips32_op
= OPC_CVT_D_W
;
13947 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
13948 mips32_op
= OPC_CVT_D_L
;
13951 /* Conversions from single */
13952 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
13953 mips32_op
= OPC_CVT_S_D
;
13955 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
13956 mips32_op
= OPC_CVT_S_W
;
13958 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
13959 mips32_op
= OPC_CVT_S_L
;
13961 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
13964 /* Conditional moves on floating-point codes */
13965 case COND_FLOAT_MOV(MOVT
, 0):
13966 case COND_FLOAT_MOV(MOVT
, 1):
13967 case COND_FLOAT_MOV(MOVT
, 2):
13968 case COND_FLOAT_MOV(MOVT
, 3):
13969 case COND_FLOAT_MOV(MOVT
, 4):
13970 case COND_FLOAT_MOV(MOVT
, 5):
13971 case COND_FLOAT_MOV(MOVT
, 6):
13972 case COND_FLOAT_MOV(MOVT
, 7):
13973 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13974 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
13976 case COND_FLOAT_MOV(MOVF
, 0):
13977 case COND_FLOAT_MOV(MOVF
, 1):
13978 case COND_FLOAT_MOV(MOVF
, 2):
13979 case COND_FLOAT_MOV(MOVF
, 3):
13980 case COND_FLOAT_MOV(MOVF
, 4):
13981 case COND_FLOAT_MOV(MOVF
, 5):
13982 case COND_FLOAT_MOV(MOVF
, 6):
13983 case COND_FLOAT_MOV(MOVF
, 7):
13984 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13985 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
13988 MIPS_INVAL("pool32fxf");
13989 generate_exception(ctx
, EXCP_RI
);
13994 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13998 int rt
, rs
, rd
, rr
;
14000 uint32_t op
, minor
, mips32_op
;
14001 uint32_t cond
, fmt
, cc
;
14003 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
14004 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
14006 rt
= (ctx
->opcode
>> 21) & 0x1f;
14007 rs
= (ctx
->opcode
>> 16) & 0x1f;
14008 rd
= (ctx
->opcode
>> 11) & 0x1f;
14009 rr
= (ctx
->opcode
>> 6) & 0x1f;
14010 imm
= (int16_t) ctx
->opcode
;
14012 op
= (ctx
->opcode
>> 26) & 0x3f;
14015 minor
= ctx
->opcode
& 0x3f;
14018 minor
= (ctx
->opcode
>> 6) & 0xf;
14021 mips32_op
= OPC_SLL
;
14024 mips32_op
= OPC_SRA
;
14027 mips32_op
= OPC_SRL
;
14030 mips32_op
= OPC_ROTR
;
14032 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
14035 check_insn(ctx
, ISA_MIPS32R6
);
14036 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
14039 check_insn(ctx
, ISA_MIPS32R6
);
14040 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
14043 goto pool32a_invalid
;
14047 minor
= (ctx
->opcode
>> 6) & 0xf;
14051 mips32_op
= OPC_ADD
;
14054 mips32_op
= OPC_ADDU
;
14057 mips32_op
= OPC_SUB
;
14060 mips32_op
= OPC_SUBU
;
14063 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14064 mips32_op
= OPC_MUL
;
14066 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
14070 mips32_op
= OPC_SLLV
;
14073 mips32_op
= OPC_SRLV
;
14076 mips32_op
= OPC_SRAV
;
14079 mips32_op
= OPC_ROTRV
;
14081 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
14083 /* Logical operations */
14085 mips32_op
= OPC_AND
;
14088 mips32_op
= OPC_OR
;
14091 mips32_op
= OPC_NOR
;
14094 mips32_op
= OPC_XOR
;
14096 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
14098 /* Set less than */
14100 mips32_op
= OPC_SLT
;
14103 mips32_op
= OPC_SLTU
;
14105 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
14108 goto pool32a_invalid
;
14112 minor
= (ctx
->opcode
>> 6) & 0xf;
14114 /* Conditional moves */
14115 case MOVN
: /* MUL */
14116 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14118 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
14121 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
14124 case MOVZ
: /* MUH */
14125 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14127 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
14130 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
14134 check_insn(ctx
, ISA_MIPS32R6
);
14135 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
14138 check_insn(ctx
, ISA_MIPS32R6
);
14139 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
14141 case LWXS
: /* DIV */
14142 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14144 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
14147 gen_ldxs(ctx
, rs
, rt
, rd
);
14151 check_insn(ctx
, ISA_MIPS32R6
);
14152 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
14155 check_insn(ctx
, ISA_MIPS32R6
);
14156 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
14159 check_insn(ctx
, ISA_MIPS32R6
);
14160 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
14163 goto pool32a_invalid
;
14167 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
14170 check_insn(ctx
, ISA_MIPS32R6
);
14171 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
14172 extract32(ctx
->opcode
, 9, 2));
14175 check_insn(ctx
, ISA_MIPS32R6
);
14176 gen_align(ctx
, OPC_ALIGN
, rd
, rs
, rt
,
14177 extract32(ctx
->opcode
, 9, 2));
14180 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
14183 gen_pool32axf(env
, ctx
, rt
, rs
);
14186 generate_exception(ctx
, EXCP_BREAK
);
14190 MIPS_INVAL("pool32a");
14191 generate_exception(ctx
, EXCP_RI
);
14196 minor
= (ctx
->opcode
>> 12) & 0xf;
14199 check_cp0_enabled(ctx
);
14200 /* Treat as no-op. */
14204 /* COP2: Not implemented. */
14205 generate_exception_err(ctx
, EXCP_CpU
, 2);
14207 #ifdef TARGET_MIPS64
14210 check_insn(ctx
, ISA_MIPS3
);
14211 check_mips_64(ctx
);
14216 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14218 #ifdef TARGET_MIPS64
14221 check_insn(ctx
, ISA_MIPS3
);
14222 check_mips_64(ctx
);
14227 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14230 MIPS_INVAL("pool32b");
14231 generate_exception(ctx
, EXCP_RI
);
14236 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
14237 minor
= ctx
->opcode
& 0x3f;
14238 check_cp1_enabled(ctx
);
14241 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14242 mips32_op
= OPC_ALNV_PS
;
14245 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14246 mips32_op
= OPC_MADD_S
;
14249 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14250 mips32_op
= OPC_MADD_D
;
14253 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14254 mips32_op
= OPC_MADD_PS
;
14257 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14258 mips32_op
= OPC_MSUB_S
;
14261 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14262 mips32_op
= OPC_MSUB_D
;
14265 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14266 mips32_op
= OPC_MSUB_PS
;
14269 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14270 mips32_op
= OPC_NMADD_S
;
14273 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14274 mips32_op
= OPC_NMADD_D
;
14277 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14278 mips32_op
= OPC_NMADD_PS
;
14281 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14282 mips32_op
= OPC_NMSUB_S
;
14285 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14286 mips32_op
= OPC_NMSUB_D
;
14289 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14290 mips32_op
= OPC_NMSUB_PS
;
14292 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
14294 case CABS_COND_FMT
:
14295 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14296 cond
= (ctx
->opcode
>> 6) & 0xf;
14297 cc
= (ctx
->opcode
>> 13) & 0x7;
14298 fmt
= (ctx
->opcode
>> 10) & 0x3;
14301 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
14304 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
14307 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
14310 goto pool32f_invalid
;
14314 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14315 cond
= (ctx
->opcode
>> 6) & 0xf;
14316 cc
= (ctx
->opcode
>> 13) & 0x7;
14317 fmt
= (ctx
->opcode
>> 10) & 0x3;
14320 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
14323 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
14326 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
14329 goto pool32f_invalid
;
14333 check_insn(ctx
, ISA_MIPS32R6
);
14334 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
14337 check_insn(ctx
, ISA_MIPS32R6
);
14338 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
14341 gen_pool32fxf(ctx
, rt
, rs
);
14345 switch ((ctx
->opcode
>> 6) & 0x7) {
14347 mips32_op
= OPC_PLL_PS
;
14350 mips32_op
= OPC_PLU_PS
;
14353 mips32_op
= OPC_PUL_PS
;
14356 mips32_op
= OPC_PUU_PS
;
14359 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14360 mips32_op
= OPC_CVT_PS_S
;
14362 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14365 goto pool32f_invalid
;
14369 check_insn(ctx
, ISA_MIPS32R6
);
14370 switch ((ctx
->opcode
>> 9) & 0x3) {
14372 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
14375 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
14378 goto pool32f_invalid
;
14383 switch ((ctx
->opcode
>> 6) & 0x7) {
14385 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14386 mips32_op
= OPC_LWXC1
;
14389 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14390 mips32_op
= OPC_SWXC1
;
14393 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14394 mips32_op
= OPC_LDXC1
;
14397 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14398 mips32_op
= OPC_SDXC1
;
14401 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14402 mips32_op
= OPC_LUXC1
;
14405 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14406 mips32_op
= OPC_SUXC1
;
14408 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
14411 goto pool32f_invalid
;
14415 check_insn(ctx
, ISA_MIPS32R6
);
14416 switch ((ctx
->opcode
>> 9) & 0x3) {
14418 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
14421 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
14424 goto pool32f_invalid
;
14429 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14430 fmt
= (ctx
->opcode
>> 9) & 0x3;
14431 switch ((ctx
->opcode
>> 6) & 0x7) {
14435 mips32_op
= OPC_RSQRT2_S
;
14438 mips32_op
= OPC_RSQRT2_D
;
14441 mips32_op
= OPC_RSQRT2_PS
;
14444 goto pool32f_invalid
;
14450 mips32_op
= OPC_RECIP2_S
;
14453 mips32_op
= OPC_RECIP2_D
;
14456 mips32_op
= OPC_RECIP2_PS
;
14459 goto pool32f_invalid
;
14463 mips32_op
= OPC_ADDR_PS
;
14466 mips32_op
= OPC_MULR_PS
;
14468 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14471 goto pool32f_invalid
;
14475 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14476 cc
= (ctx
->opcode
>> 13) & 0x7;
14477 fmt
= (ctx
->opcode
>> 9) & 0x3;
14478 switch ((ctx
->opcode
>> 6) & 0x7) {
14479 case MOVF_FMT
: /* RINT_FMT */
14480 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14484 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
14487 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
14490 goto pool32f_invalid
;
14496 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
14499 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
14503 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
14506 goto pool32f_invalid
;
14510 case MOVT_FMT
: /* CLASS_FMT */
14511 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14515 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
14518 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
14521 goto pool32f_invalid
;
14527 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
14530 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
14534 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
14537 goto pool32f_invalid
;
14542 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14545 goto pool32f_invalid
;
14548 #define FINSN_3ARG_SDPS(prfx) \
14549 switch ((ctx->opcode >> 8) & 0x3) { \
14551 mips32_op = OPC_##prfx##_S; \
14554 mips32_op = OPC_##prfx##_D; \
14556 case FMT_SDPS_PS: \
14558 mips32_op = OPC_##prfx##_PS; \
14561 goto pool32f_invalid; \
14564 check_insn(ctx
, ISA_MIPS32R6
);
14565 switch ((ctx
->opcode
>> 9) & 0x3) {
14567 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
14570 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
14573 goto pool32f_invalid
;
14577 check_insn(ctx
, ISA_MIPS32R6
);
14578 switch ((ctx
->opcode
>> 9) & 0x3) {
14580 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
14583 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
14586 goto pool32f_invalid
;
14590 /* regular FP ops */
14591 switch ((ctx
->opcode
>> 6) & 0x3) {
14593 FINSN_3ARG_SDPS(ADD
);
14596 FINSN_3ARG_SDPS(SUB
);
14599 FINSN_3ARG_SDPS(MUL
);
14602 fmt
= (ctx
->opcode
>> 8) & 0x3;
14604 mips32_op
= OPC_DIV_D
;
14605 } else if (fmt
== 0) {
14606 mips32_op
= OPC_DIV_S
;
14608 goto pool32f_invalid
;
14612 goto pool32f_invalid
;
14617 switch ((ctx
->opcode
>> 6) & 0x7) {
14618 case MOVN_FMT
: /* SELNEZ_FMT */
14619 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14621 switch ((ctx
->opcode
>> 9) & 0x3) {
14623 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
14626 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
14629 goto pool32f_invalid
;
14633 FINSN_3ARG_SDPS(MOVN
);
14637 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14638 FINSN_3ARG_SDPS(MOVN
);
14640 case MOVZ_FMT
: /* SELEQZ_FMT */
14641 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14643 switch ((ctx
->opcode
>> 9) & 0x3) {
14645 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
14648 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
14651 goto pool32f_invalid
;
14655 FINSN_3ARG_SDPS(MOVZ
);
14659 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14660 FINSN_3ARG_SDPS(MOVZ
);
14663 check_insn(ctx
, ISA_MIPS32R6
);
14664 switch ((ctx
->opcode
>> 9) & 0x3) {
14666 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
14669 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
14672 goto pool32f_invalid
;
14676 check_insn(ctx
, ISA_MIPS32R6
);
14677 switch ((ctx
->opcode
>> 9) & 0x3) {
14679 mips32_op
= OPC_MADDF_S
;
14682 mips32_op
= OPC_MADDF_D
;
14685 goto pool32f_invalid
;
14689 check_insn(ctx
, ISA_MIPS32R6
);
14690 switch ((ctx
->opcode
>> 9) & 0x3) {
14692 mips32_op
= OPC_MSUBF_S
;
14695 mips32_op
= OPC_MSUBF_D
;
14698 goto pool32f_invalid
;
14702 goto pool32f_invalid
;
14706 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14710 MIPS_INVAL("pool32f");
14711 generate_exception(ctx
, EXCP_RI
);
14715 generate_exception_err(ctx
, EXCP_CpU
, 1);
14719 minor
= (ctx
->opcode
>> 21) & 0x1f;
14722 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14723 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
14726 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14727 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
14728 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14731 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14732 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
14733 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14736 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14737 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
14740 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14741 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
14742 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14745 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14746 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
14747 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14750 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14751 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
14754 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14755 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
14759 case TLTI
: /* BC1EQZC */
14760 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14762 check_cp1_enabled(ctx
);
14763 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
14766 mips32_op
= OPC_TLTI
;
14770 case TGEI
: /* BC1NEZC */
14771 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14773 check_cp1_enabled(ctx
);
14774 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
14777 mips32_op
= OPC_TGEI
;
14782 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14783 mips32_op
= OPC_TLTIU
;
14786 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14787 mips32_op
= OPC_TGEIU
;
14789 case TNEI
: /* SYNCI */
14790 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14792 /* Break the TB to be able to sync copied instructions
14794 ctx
->bstate
= BS_STOP
;
14797 mips32_op
= OPC_TNEI
;
14802 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14803 mips32_op
= OPC_TEQI
;
14805 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
14810 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14811 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
14812 4, rs
, 0, imm
<< 1, 0);
14813 /* Compact branches don't have a delay slot, so just let
14814 the normal delay slot handling take us to the branch
14818 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14819 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
14822 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14823 /* Break the TB to be able to sync copied instructions
14825 ctx
->bstate
= BS_STOP
;
14829 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14830 /* COP2: Not implemented. */
14831 generate_exception_err(ctx
, EXCP_CpU
, 2);
14834 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14835 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
14838 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14839 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
14842 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14843 mips32_op
= OPC_BC1FANY4
;
14846 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14847 mips32_op
= OPC_BC1TANY4
;
14850 check_insn(ctx
, ASE_MIPS3D
);
14853 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14854 check_cp1_enabled(ctx
);
14855 gen_compute_branch1(ctx
, mips32_op
,
14856 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
14858 generate_exception_err(ctx
, EXCP_CpU
, 1);
14863 /* MIPS DSP: not implemented */
14866 MIPS_INVAL("pool32i");
14867 generate_exception(ctx
, EXCP_RI
);
14872 minor
= (ctx
->opcode
>> 12) & 0xf;
14873 offset
= sextract32(ctx
->opcode
, 0,
14874 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
14877 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14878 mips32_op
= OPC_LWL
;
14881 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14882 mips32_op
= OPC_SWL
;
14885 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14886 mips32_op
= OPC_LWR
;
14889 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14890 mips32_op
= OPC_SWR
;
14892 #if defined(TARGET_MIPS64)
14894 check_insn(ctx
, ISA_MIPS3
);
14895 check_mips_64(ctx
);
14896 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14897 mips32_op
= OPC_LDL
;
14900 check_insn(ctx
, ISA_MIPS3
);
14901 check_mips_64(ctx
);
14902 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14903 mips32_op
= OPC_SDL
;
14906 check_insn(ctx
, ISA_MIPS3
);
14907 check_mips_64(ctx
);
14908 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14909 mips32_op
= OPC_LDR
;
14912 check_insn(ctx
, ISA_MIPS3
);
14913 check_mips_64(ctx
);
14914 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14915 mips32_op
= OPC_SDR
;
14918 check_insn(ctx
, ISA_MIPS3
);
14919 check_mips_64(ctx
);
14920 mips32_op
= OPC_LWU
;
14923 check_insn(ctx
, ISA_MIPS3
);
14924 check_mips_64(ctx
);
14925 mips32_op
= OPC_LLD
;
14929 mips32_op
= OPC_LL
;
14932 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
14935 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14938 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, offset
);
14940 #if defined(TARGET_MIPS64)
14942 check_insn(ctx
, ISA_MIPS3
);
14943 check_mips_64(ctx
);
14944 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, offset
);
14948 /* Treat as no-op */
14949 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
14950 /* hint codes 24-31 are reserved and signal RI */
14951 generate_exception(ctx
, EXCP_RI
);
14955 MIPS_INVAL("pool32c");
14956 generate_exception(ctx
, EXCP_RI
);
14960 case ADDI32
: /* AUI, LUI */
14961 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14963 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
14966 mips32_op
= OPC_ADDI
;
14971 mips32_op
= OPC_ADDIU
;
14973 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14976 /* Logical operations */
14978 mips32_op
= OPC_ORI
;
14981 mips32_op
= OPC_XORI
;
14984 mips32_op
= OPC_ANDI
;
14986 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14989 /* Set less than immediate */
14991 mips32_op
= OPC_SLTI
;
14994 mips32_op
= OPC_SLTIU
;
14996 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14999 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15000 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15001 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
15002 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15004 case JALS32
: /* BOVC, BEQC, BEQZALC */
15005 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15008 mips32_op
= OPC_BOVC
;
15009 } else if (rs
< rt
&& rs
== 0) {
15011 mips32_op
= OPC_BEQZALC
;
15014 mips32_op
= OPC_BEQC
;
15016 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15019 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
15020 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
15021 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15024 case BEQ32
: /* BC */
15025 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15027 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
15028 sextract32(ctx
->opcode
<< 1, 0, 27));
15031 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
15034 case BNE32
: /* BALC */
15035 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15037 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
15038 sextract32(ctx
->opcode
<< 1, 0, 27));
15041 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
15044 case J32
: /* BGTZC, BLTZC, BLTC */
15045 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15046 if (rs
== 0 && rt
!= 0) {
15048 mips32_op
= OPC_BGTZC
;
15049 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15051 mips32_op
= OPC_BLTZC
;
15054 mips32_op
= OPC_BLTC
;
15056 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15059 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
15060 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
15063 case JAL32
: /* BLEZC, BGEZC, BGEC */
15064 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15065 if (rs
== 0 && rt
!= 0) {
15067 mips32_op
= OPC_BLEZC
;
15068 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15070 mips32_op
= OPC_BGEZC
;
15073 mips32_op
= OPC_BGEC
;
15075 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15078 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
15079 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
15080 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15083 /* Floating point (COP1) */
15085 mips32_op
= OPC_LWC1
;
15088 mips32_op
= OPC_LDC1
;
15091 mips32_op
= OPC_SWC1
;
15094 mips32_op
= OPC_SDC1
;
15096 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
15098 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15099 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15100 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15101 switch ((ctx
->opcode
>> 16) & 0x1f) {
15102 case ADDIUPC_00
... ADDIUPC_07
:
15103 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->pc
& ~0x3, rt
);
15106 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->pc
, rt
);
15109 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->pc
, rt
);
15111 case LWPC_08
... LWPC_0F
:
15112 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->pc
& ~0x3, rt
);
15115 generate_exception(ctx
, EXCP_RI
);
15120 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
15121 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
15123 gen_addiupc(ctx
, reg
, offset
, 0, 0);
15126 case BNVC
: /* BNEC, BNEZALC */
15127 check_insn(ctx
, ISA_MIPS32R6
);
15130 mips32_op
= OPC_BNVC
;
15131 } else if (rs
< rt
&& rs
== 0) {
15133 mips32_op
= OPC_BNEZALC
;
15136 mips32_op
= OPC_BNEC
;
15138 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15140 case R6_BNEZC
: /* JIALC */
15141 check_insn(ctx
, ISA_MIPS32R6
);
15144 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
15145 sextract32(ctx
->opcode
<< 1, 0, 22));
15148 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
15151 case R6_BEQZC
: /* JIC */
15152 check_insn(ctx
, ISA_MIPS32R6
);
15155 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
15156 sextract32(ctx
->opcode
<< 1, 0, 22));
15159 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
15162 case BLEZALC
: /* BGEZALC, BGEUC */
15163 check_insn(ctx
, ISA_MIPS32R6
);
15164 if (rs
== 0 && rt
!= 0) {
15166 mips32_op
= OPC_BLEZALC
;
15167 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15169 mips32_op
= OPC_BGEZALC
;
15172 mips32_op
= OPC_BGEUC
;
15174 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15176 case BGTZALC
: /* BLTZALC, BLTUC */
15177 check_insn(ctx
, ISA_MIPS32R6
);
15178 if (rs
== 0 && rt
!= 0) {
15180 mips32_op
= OPC_BGTZALC
;
15181 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15183 mips32_op
= OPC_BLTZALC
;
15186 mips32_op
= OPC_BLTUC
;
15188 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15190 /* Loads and stores */
15192 mips32_op
= OPC_LB
;
15195 mips32_op
= OPC_LBU
;
15198 mips32_op
= OPC_LH
;
15201 mips32_op
= OPC_LHU
;
15204 mips32_op
= OPC_LW
;
15206 #ifdef TARGET_MIPS64
15208 check_insn(ctx
, ISA_MIPS3
);
15209 check_mips_64(ctx
);
15210 mips32_op
= OPC_LD
;
15213 check_insn(ctx
, ISA_MIPS3
);
15214 check_mips_64(ctx
);
15215 mips32_op
= OPC_SD
;
15219 mips32_op
= OPC_SB
;
15222 mips32_op
= OPC_SH
;
15225 mips32_op
= OPC_SW
;
15228 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
15231 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
15234 generate_exception(ctx
, EXCP_RI
);
15239 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
15243 /* make sure instructions are on a halfword boundary */
15244 if (ctx
->pc
& 0x1) {
15245 env
->CP0_BadVAddr
= ctx
->pc
;
15246 generate_exception(ctx
, EXCP_AdEL
);
15247 ctx
->bstate
= BS_STOP
;
15251 op
= (ctx
->opcode
>> 10) & 0x3f;
15252 /* Enforce properly-sized instructions in a delay slot */
15253 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
15254 switch (op
& 0x7) { /* MSB-3..MSB-5 */
15256 /* POOL32A, POOL32B, POOL32I, POOL32C */
15258 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15260 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15262 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15264 /* LB32, LH32, LWC132, LDC132, LW32 */
15265 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
15266 generate_exception(ctx
, EXCP_RI
);
15267 /* Just stop translation; the user is confused. */
15268 ctx
->bstate
= BS_STOP
;
15273 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15275 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15277 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15278 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
15279 generate_exception(ctx
, EXCP_RI
);
15280 /* Just stop translation; the user is confused. */
15281 ctx
->bstate
= BS_STOP
;
15291 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15292 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
15293 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
15296 switch (ctx
->opcode
& 0x1) {
15304 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15305 /* In the Release 6 the register number location in
15306 * the instruction encoding has changed.
15308 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
15310 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
15316 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15317 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15318 int amount
= (ctx
->opcode
>> 1) & 0x7;
15320 amount
= amount
== 0 ? 8 : amount
;
15322 switch (ctx
->opcode
& 0x1) {
15331 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
15335 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15336 gen_pool16c_r6_insn(ctx
);
15338 gen_pool16c_insn(ctx
);
15343 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15344 int rb
= 28; /* GP */
15345 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
15347 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15351 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15352 if (ctx
->opcode
& 1) {
15353 generate_exception(ctx
, EXCP_RI
);
15356 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15357 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15358 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
15359 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15364 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15365 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15366 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
15367 offset
= (offset
== 0xf ? -1 : offset
);
15369 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
15374 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15375 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15376 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
15378 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
15383 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15384 int rb
= 29; /* SP */
15385 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
15387 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15392 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15393 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15394 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
15396 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15401 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15402 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15403 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
15405 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
15410 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15411 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15412 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
15414 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
15419 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15420 int rb
= 29; /* SP */
15421 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
15423 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
15428 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15429 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15430 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
15432 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
15437 int rd
= uMIPS_RD5(ctx
->opcode
);
15438 int rs
= uMIPS_RS5(ctx
->opcode
);
15440 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
15447 switch (ctx
->opcode
& 0x1) {
15457 switch (ctx
->opcode
& 0x1) {
15462 gen_addiur1sp(ctx
);
15466 case B16
: /* BC16 */
15467 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
15468 sextract32(ctx
->opcode
, 0, 10) << 1,
15469 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
15471 case BNEZ16
: /* BNEZC16 */
15472 case BEQZ16
: /* BEQZC16 */
15473 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
15474 mmreg(uMIPS_RD(ctx
->opcode
)),
15475 0, sextract32(ctx
->opcode
, 0, 7) << 1,
15476 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
15481 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
15482 int imm
= ZIMM(ctx
->opcode
, 0, 7);
15484 imm
= (imm
== 0x7f ? -1 : imm
);
15485 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
15491 generate_exception(ctx
, EXCP_RI
);
15494 decode_micromips32_opc(env
, ctx
);
15501 /* SmartMIPS extension to MIPS32 */
15503 #if defined(TARGET_MIPS64)
15505 /* MDMX extension to MIPS64 */
15509 /* MIPSDSP functions. */
15510 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
15511 int rd
, int base
, int offset
)
15513 const char *opn
= "ldx";
15517 t0
= tcg_temp_new();
15520 gen_load_gpr(t0
, offset
);
15521 } else if (offset
== 0) {
15522 gen_load_gpr(t0
, base
);
15524 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
15529 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
15530 gen_store_gpr(t0
, rd
);
15534 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
15535 gen_store_gpr(t0
, rd
);
15539 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
15540 gen_store_gpr(t0
, rd
);
15543 #if defined(TARGET_MIPS64)
15545 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
15546 gen_store_gpr(t0
, rd
);
15551 (void)opn
; /* avoid a compiler warning */
15552 MIPS_DEBUG("%s %s, %s(%s)", opn
,
15553 regnames
[rd
], regnames
[offset
], regnames
[base
]);
15557 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15558 int ret
, int v1
, int v2
)
15560 const char *opn
= "mipsdsp arith";
15565 /* Treat as NOP. */
15570 v1_t
= tcg_temp_new();
15571 v2_t
= tcg_temp_new();
15573 gen_load_gpr(v1_t
, v1
);
15574 gen_load_gpr(v2_t
, v2
);
15577 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15578 case OPC_MULT_G_2E
:
15582 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15584 case OPC_ADDUH_R_QB
:
15585 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15588 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15590 case OPC_ADDQH_R_PH
:
15591 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15594 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15596 case OPC_ADDQH_R_W
:
15597 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15600 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15602 case OPC_SUBUH_R_QB
:
15603 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15606 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15608 case OPC_SUBQH_R_PH
:
15609 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15612 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15614 case OPC_SUBQH_R_W
:
15615 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15619 case OPC_ABSQ_S_PH_DSP
:
15621 case OPC_ABSQ_S_QB
:
15623 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
15625 case OPC_ABSQ_S_PH
:
15627 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
15631 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
15633 case OPC_PRECEQ_W_PHL
:
15635 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
15636 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15638 case OPC_PRECEQ_W_PHR
:
15640 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
15641 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
15642 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15644 case OPC_PRECEQU_PH_QBL
:
15646 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
15648 case OPC_PRECEQU_PH_QBR
:
15650 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
15652 case OPC_PRECEQU_PH_QBLA
:
15654 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
15656 case OPC_PRECEQU_PH_QBRA
:
15658 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
15660 case OPC_PRECEU_PH_QBL
:
15662 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
15664 case OPC_PRECEU_PH_QBR
:
15666 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
15668 case OPC_PRECEU_PH_QBLA
:
15670 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
15672 case OPC_PRECEU_PH_QBRA
:
15674 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
15678 case OPC_ADDU_QB_DSP
:
15682 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15684 case OPC_ADDQ_S_PH
:
15686 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15690 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15694 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15696 case OPC_ADDU_S_QB
:
15698 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15702 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15704 case OPC_ADDU_S_PH
:
15706 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15710 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15712 case OPC_SUBQ_S_PH
:
15714 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15718 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15722 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15724 case OPC_SUBU_S_QB
:
15726 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15730 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15732 case OPC_SUBU_S_PH
:
15734 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15738 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15742 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15746 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
15748 case OPC_RADDU_W_QB
:
15750 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
15754 case OPC_CMPU_EQ_QB_DSP
:
15756 case OPC_PRECR_QB_PH
:
15758 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15760 case OPC_PRECRQ_QB_PH
:
15762 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15764 case OPC_PRECR_SRA_PH_W
:
15767 TCGv_i32 sa_t
= tcg_const_i32(v2
);
15768 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
15770 tcg_temp_free_i32(sa_t
);
15773 case OPC_PRECR_SRA_R_PH_W
:
15776 TCGv_i32 sa_t
= tcg_const_i32(v2
);
15777 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
15779 tcg_temp_free_i32(sa_t
);
15782 case OPC_PRECRQ_PH_W
:
15784 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15786 case OPC_PRECRQ_RS_PH_W
:
15788 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15790 case OPC_PRECRQU_S_QB_PH
:
15792 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15796 #ifdef TARGET_MIPS64
15797 case OPC_ABSQ_S_QH_DSP
:
15799 case OPC_PRECEQ_L_PWL
:
15801 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
15803 case OPC_PRECEQ_L_PWR
:
15805 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
15807 case OPC_PRECEQ_PW_QHL
:
15809 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
15811 case OPC_PRECEQ_PW_QHR
:
15813 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
15815 case OPC_PRECEQ_PW_QHLA
:
15817 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
15819 case OPC_PRECEQ_PW_QHRA
:
15821 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
15823 case OPC_PRECEQU_QH_OBL
:
15825 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
15827 case OPC_PRECEQU_QH_OBR
:
15829 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
15831 case OPC_PRECEQU_QH_OBLA
:
15833 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
15835 case OPC_PRECEQU_QH_OBRA
:
15837 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
15839 case OPC_PRECEU_QH_OBL
:
15841 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
15843 case OPC_PRECEU_QH_OBR
:
15845 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
15847 case OPC_PRECEU_QH_OBLA
:
15849 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
15851 case OPC_PRECEU_QH_OBRA
:
15853 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
15855 case OPC_ABSQ_S_OB
:
15857 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
15859 case OPC_ABSQ_S_PW
:
15861 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
15863 case OPC_ABSQ_S_QH
:
15865 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
15869 case OPC_ADDU_OB_DSP
:
15871 case OPC_RADDU_L_OB
:
15873 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
15877 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15879 case OPC_SUBQ_S_PW
:
15881 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15885 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15887 case OPC_SUBQ_S_QH
:
15889 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15893 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15895 case OPC_SUBU_S_OB
:
15897 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15901 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15903 case OPC_SUBU_S_QH
:
15905 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15909 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15911 case OPC_SUBUH_R_OB
:
15913 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15917 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15919 case OPC_ADDQ_S_PW
:
15921 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15925 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15927 case OPC_ADDQ_S_QH
:
15929 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15933 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15935 case OPC_ADDU_S_OB
:
15937 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15941 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15943 case OPC_ADDU_S_QH
:
15945 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15949 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15951 case OPC_ADDUH_R_OB
:
15953 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15957 case OPC_CMPU_EQ_OB_DSP
:
15959 case OPC_PRECR_OB_QH
:
15961 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
15963 case OPC_PRECR_SRA_QH_PW
:
15966 TCGv_i32 ret_t
= tcg_const_i32(ret
);
15967 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
15968 tcg_temp_free_i32(ret_t
);
15971 case OPC_PRECR_SRA_R_QH_PW
:
15974 TCGv_i32 sa_v
= tcg_const_i32(ret
);
15975 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
15976 tcg_temp_free_i32(sa_v
);
15979 case OPC_PRECRQ_OB_QH
:
15981 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
15983 case OPC_PRECRQ_PW_L
:
15985 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
15987 case OPC_PRECRQ_QH_PW
:
15989 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
15991 case OPC_PRECRQ_RS_QH_PW
:
15993 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15995 case OPC_PRECRQU_S_OB_QH
:
15997 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16004 tcg_temp_free(v1_t
);
16005 tcg_temp_free(v2_t
);
16007 (void)opn
; /* avoid a compiler warning */
16008 MIPS_DEBUG("%s", opn
);
16011 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
16012 int ret
, int v1
, int v2
)
16015 const char *opn
= "mipsdsp shift";
16021 /* Treat as NOP. */
16026 t0
= tcg_temp_new();
16027 v1_t
= tcg_temp_new();
16028 v2_t
= tcg_temp_new();
16030 tcg_gen_movi_tl(t0
, v1
);
16031 gen_load_gpr(v1_t
, v1
);
16032 gen_load_gpr(v2_t
, v2
);
16035 case OPC_SHLL_QB_DSP
:
16037 op2
= MASK_SHLL_QB(ctx
->opcode
);
16041 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16045 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16049 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16053 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16055 case OPC_SHLL_S_PH
:
16057 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16059 case OPC_SHLLV_S_PH
:
16061 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16065 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16067 case OPC_SHLLV_S_W
:
16069 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16073 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
16077 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16081 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
16085 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16089 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
16091 case OPC_SHRA_R_QB
:
16093 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
16097 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16099 case OPC_SHRAV_R_QB
:
16101 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16105 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
16107 case OPC_SHRA_R_PH
:
16109 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
16113 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16115 case OPC_SHRAV_R_PH
:
16117 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16121 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
16123 case OPC_SHRAV_R_W
:
16125 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
16127 default: /* Invalid */
16128 MIPS_INVAL("MASK SHLL.QB");
16129 generate_exception(ctx
, EXCP_RI
);
16134 #ifdef TARGET_MIPS64
16135 case OPC_SHLL_OB_DSP
:
16136 op2
= MASK_SHLL_OB(ctx
->opcode
);
16140 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16144 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16146 case OPC_SHLL_S_PW
:
16148 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16150 case OPC_SHLLV_S_PW
:
16152 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16156 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16160 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16164 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16168 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16170 case OPC_SHLL_S_QH
:
16172 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16174 case OPC_SHLLV_S_QH
:
16176 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16180 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
16184 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
16186 case OPC_SHRA_R_OB
:
16188 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
16190 case OPC_SHRAV_R_OB
:
16192 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
16196 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
16200 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
16202 case OPC_SHRA_R_PW
:
16204 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
16206 case OPC_SHRAV_R_PW
:
16208 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
16212 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
16216 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
16218 case OPC_SHRA_R_QH
:
16220 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
16222 case OPC_SHRAV_R_QH
:
16224 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
16228 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
16232 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
16236 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
16240 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
16242 default: /* Invalid */
16243 MIPS_INVAL("MASK SHLL.OB");
16244 generate_exception(ctx
, EXCP_RI
);
16252 tcg_temp_free(v1_t
);
16253 tcg_temp_free(v2_t
);
16254 (void)opn
; /* avoid a compiler warning */
16255 MIPS_DEBUG("%s", opn
);
16258 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16259 int ret
, int v1
, int v2
, int check_ret
)
16261 const char *opn
= "mipsdsp multiply";
16266 if ((ret
== 0) && (check_ret
== 1)) {
16267 /* Treat as NOP. */
16272 t0
= tcg_temp_new_i32();
16273 v1_t
= tcg_temp_new();
16274 v2_t
= tcg_temp_new();
16276 tcg_gen_movi_i32(t0
, ret
);
16277 gen_load_gpr(v1_t
, v1
);
16278 gen_load_gpr(v2_t
, v2
);
16281 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16282 * the same mask and op1. */
16283 case OPC_MULT_G_2E
:
16287 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16290 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16293 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16295 case OPC_MULQ_RS_W
:
16296 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16300 case OPC_DPA_W_PH_DSP
:
16302 case OPC_DPAU_H_QBL
:
16304 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
16306 case OPC_DPAU_H_QBR
:
16308 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
16310 case OPC_DPSU_H_QBL
:
16312 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
16314 case OPC_DPSU_H_QBR
:
16316 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
16320 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16322 case OPC_DPAX_W_PH
:
16324 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16326 case OPC_DPAQ_S_W_PH
:
16328 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16330 case OPC_DPAQX_S_W_PH
:
16332 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16334 case OPC_DPAQX_SA_W_PH
:
16336 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16340 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16342 case OPC_DPSX_W_PH
:
16344 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16346 case OPC_DPSQ_S_W_PH
:
16348 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16350 case OPC_DPSQX_S_W_PH
:
16352 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16354 case OPC_DPSQX_SA_W_PH
:
16356 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16358 case OPC_MULSAQ_S_W_PH
:
16360 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16362 case OPC_DPAQ_SA_L_W
:
16364 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
16366 case OPC_DPSQ_SA_L_W
:
16368 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
16370 case OPC_MAQ_S_W_PHL
:
16372 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
16374 case OPC_MAQ_S_W_PHR
:
16376 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
16378 case OPC_MAQ_SA_W_PHL
:
16380 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
16382 case OPC_MAQ_SA_W_PHR
:
16384 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
16386 case OPC_MULSA_W_PH
:
16388 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16392 #ifdef TARGET_MIPS64
16393 case OPC_DPAQ_W_QH_DSP
:
16395 int ac
= ret
& 0x03;
16396 tcg_gen_movi_i32(t0
, ac
);
16401 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
16405 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
16409 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
16413 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
16417 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16419 case OPC_DPAQ_S_W_QH
:
16421 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16423 case OPC_DPAQ_SA_L_PW
:
16425 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16427 case OPC_DPAU_H_OBL
:
16429 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
16431 case OPC_DPAU_H_OBR
:
16433 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
16437 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16439 case OPC_DPSQ_S_W_QH
:
16441 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16443 case OPC_DPSQ_SA_L_PW
:
16445 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16447 case OPC_DPSU_H_OBL
:
16449 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
16451 case OPC_DPSU_H_OBR
:
16453 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
16455 case OPC_MAQ_S_L_PWL
:
16457 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
16459 case OPC_MAQ_S_L_PWR
:
16461 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
16463 case OPC_MAQ_S_W_QHLL
:
16465 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
16467 case OPC_MAQ_SA_W_QHLL
:
16469 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
16471 case OPC_MAQ_S_W_QHLR
:
16473 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
16475 case OPC_MAQ_SA_W_QHLR
:
16477 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
16479 case OPC_MAQ_S_W_QHRL
:
16481 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
16483 case OPC_MAQ_SA_W_QHRL
:
16485 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
16487 case OPC_MAQ_S_W_QHRR
:
16489 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
16491 case OPC_MAQ_SA_W_QHRR
:
16493 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
16495 case OPC_MULSAQ_S_L_PW
:
16497 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16499 case OPC_MULSAQ_S_W_QH
:
16501 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16507 case OPC_ADDU_QB_DSP
:
16509 case OPC_MULEU_S_PH_QBL
:
16511 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16513 case OPC_MULEU_S_PH_QBR
:
16515 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16517 case OPC_MULQ_RS_PH
:
16519 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16521 case OPC_MULEQ_S_W_PHL
:
16523 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16525 case OPC_MULEQ_S_W_PHR
:
16527 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16529 case OPC_MULQ_S_PH
:
16531 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16535 #ifdef TARGET_MIPS64
16536 case OPC_ADDU_OB_DSP
:
16538 case OPC_MULEQ_S_PW_QHL
:
16540 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16542 case OPC_MULEQ_S_PW_QHR
:
16544 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16546 case OPC_MULEU_S_QH_OBL
:
16548 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16550 case OPC_MULEU_S_QH_OBR
:
16552 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16554 case OPC_MULQ_RS_QH
:
16556 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16563 tcg_temp_free_i32(t0
);
16564 tcg_temp_free(v1_t
);
16565 tcg_temp_free(v2_t
);
16567 (void)opn
; /* avoid a compiler warning */
16568 MIPS_DEBUG("%s", opn
);
16572 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16575 const char *opn
= "mipsdsp Bit/ Manipulation";
16581 /* Treat as NOP. */
16586 t0
= tcg_temp_new();
16587 val_t
= tcg_temp_new();
16588 gen_load_gpr(val_t
, val
);
16591 case OPC_ABSQ_S_PH_DSP
:
16595 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
16600 target_long result
;
16601 imm
= (ctx
->opcode
>> 16) & 0xFF;
16602 result
= (uint32_t)imm
<< 24 |
16603 (uint32_t)imm
<< 16 |
16604 (uint32_t)imm
<< 8 |
16606 result
= (int32_t)result
;
16607 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
16612 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
16613 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
16614 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16615 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16616 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16617 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
16622 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16623 imm
= (int16_t)(imm
<< 6) >> 6;
16624 tcg_gen_movi_tl(cpu_gpr
[ret
], \
16625 (target_long
)((int32_t)imm
<< 16 | \
16631 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
16632 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16633 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16634 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
16638 #ifdef TARGET_MIPS64
16639 case OPC_ABSQ_S_QH_DSP
:
16646 imm
= (ctx
->opcode
>> 16) & 0xFF;
16647 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
16648 temp
= (temp
<< 16) | temp
;
16649 temp
= (temp
<< 32) | temp
;
16650 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16658 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16659 imm
= (int16_t)(imm
<< 6) >> 6;
16660 temp
= ((target_long
)imm
<< 32) \
16661 | ((target_long
)imm
& 0xFFFFFFFF);
16662 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16670 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16671 imm
= (int16_t)(imm
<< 6) >> 6;
16673 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
16674 ((uint64_t)(uint16_t)imm
<< 32) |
16675 ((uint64_t)(uint16_t)imm
<< 16) |
16676 (uint64_t)(uint16_t)imm
;
16677 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16682 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
16683 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
16684 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16685 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16686 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16687 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16688 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16692 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
16693 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16694 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16698 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
16699 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16700 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16701 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16702 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16709 tcg_temp_free(val_t
);
16711 (void)opn
; /* avoid a compiler warning */
16712 MIPS_DEBUG("%s", opn
);
16715 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
16716 uint32_t op1
, uint32_t op2
,
16717 int ret
, int v1
, int v2
, int check_ret
)
16719 const char *opn
= "mipsdsp add compare pick";
16724 if ((ret
== 0) && (check_ret
== 1)) {
16725 /* Treat as NOP. */
16730 t1
= tcg_temp_new();
16731 v1_t
= tcg_temp_new();
16732 v2_t
= tcg_temp_new();
16734 gen_load_gpr(v1_t
, v1
);
16735 gen_load_gpr(v2_t
, v2
);
16738 case OPC_CMPU_EQ_QB_DSP
:
16740 case OPC_CMPU_EQ_QB
:
16742 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
16744 case OPC_CMPU_LT_QB
:
16746 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
16748 case OPC_CMPU_LE_QB
:
16750 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
16752 case OPC_CMPGU_EQ_QB
:
16754 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16756 case OPC_CMPGU_LT_QB
:
16758 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16760 case OPC_CMPGU_LE_QB
:
16762 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16764 case OPC_CMPGDU_EQ_QB
:
16766 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
16767 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16768 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16769 tcg_gen_shli_tl(t1
, t1
, 24);
16770 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16772 case OPC_CMPGDU_LT_QB
:
16774 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
16775 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16776 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16777 tcg_gen_shli_tl(t1
, t1
, 24);
16778 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16780 case OPC_CMPGDU_LE_QB
:
16782 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
16783 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16784 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16785 tcg_gen_shli_tl(t1
, t1
, 24);
16786 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16788 case OPC_CMP_EQ_PH
:
16790 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
16792 case OPC_CMP_LT_PH
:
16794 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
16796 case OPC_CMP_LE_PH
:
16798 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
16802 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16806 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16808 case OPC_PACKRL_PH
:
16810 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16814 #ifdef TARGET_MIPS64
16815 case OPC_CMPU_EQ_OB_DSP
:
16817 case OPC_CMP_EQ_PW
:
16819 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
16821 case OPC_CMP_LT_PW
:
16823 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
16825 case OPC_CMP_LE_PW
:
16827 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
16829 case OPC_CMP_EQ_QH
:
16831 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
16833 case OPC_CMP_LT_QH
:
16835 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
16837 case OPC_CMP_LE_QH
:
16839 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
16841 case OPC_CMPGDU_EQ_OB
:
16843 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16845 case OPC_CMPGDU_LT_OB
:
16847 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16849 case OPC_CMPGDU_LE_OB
:
16851 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16853 case OPC_CMPGU_EQ_OB
:
16855 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16857 case OPC_CMPGU_LT_OB
:
16859 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16861 case OPC_CMPGU_LE_OB
:
16863 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16865 case OPC_CMPU_EQ_OB
:
16867 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
16869 case OPC_CMPU_LT_OB
:
16871 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
16873 case OPC_CMPU_LE_OB
:
16875 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
16877 case OPC_PACKRL_PW
:
16879 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
16883 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16887 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16891 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16899 tcg_temp_free(v1_t
);
16900 tcg_temp_free(v2_t
);
16902 (void)opn
; /* avoid a compiler warning */
16903 MIPS_DEBUG("%s", opn
);
16906 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
16907 uint32_t op1
, int rt
, int rs
, int sa
)
16909 const char *opn
= "mipsdsp append/dappend";
16915 /* Treat as NOP. */
16920 t0
= tcg_temp_new();
16921 gen_load_gpr(t0
, rs
);
16924 case OPC_APPEND_DSP
:
16925 switch (MASK_APPEND(ctx
->opcode
)) {
16928 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
16930 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16934 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16935 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
16936 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
16937 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16939 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16943 if (sa
!= 0 && sa
!= 2) {
16944 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
16945 tcg_gen_ext32u_tl(t0
, t0
);
16946 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
16947 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16949 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16951 default: /* Invalid */
16952 MIPS_INVAL("MASK APPEND");
16953 generate_exception(ctx
, EXCP_RI
);
16957 #ifdef TARGET_MIPS64
16958 case OPC_DAPPEND_DSP
:
16959 switch (MASK_DAPPEND(ctx
->opcode
)) {
16962 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
16966 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
16967 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
16968 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
16972 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
16973 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
16974 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16979 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
16980 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
16981 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
16982 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16985 default: /* Invalid */
16986 MIPS_INVAL("MASK DAPPEND");
16987 generate_exception(ctx
, EXCP_RI
);
16994 (void)opn
; /* avoid a compiler warning */
16995 MIPS_DEBUG("%s", opn
);
16998 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16999 int ret
, int v1
, int v2
, int check_ret
)
17002 const char *opn
= "mipsdsp accumulator";
17009 if ((ret
== 0) && (check_ret
== 1)) {
17010 /* Treat as NOP. */
17015 t0
= tcg_temp_new();
17016 t1
= tcg_temp_new();
17017 v1_t
= tcg_temp_new();
17018 v2_t
= tcg_temp_new();
17020 gen_load_gpr(v1_t
, v1
);
17021 gen_load_gpr(v2_t
, v2
);
17024 case OPC_EXTR_W_DSP
:
17028 tcg_gen_movi_tl(t0
, v2
);
17029 tcg_gen_movi_tl(t1
, v1
);
17030 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17033 tcg_gen_movi_tl(t0
, v2
);
17034 tcg_gen_movi_tl(t1
, v1
);
17035 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17037 case OPC_EXTR_RS_W
:
17038 tcg_gen_movi_tl(t0
, v2
);
17039 tcg_gen_movi_tl(t1
, v1
);
17040 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17043 tcg_gen_movi_tl(t0
, v2
);
17044 tcg_gen_movi_tl(t1
, v1
);
17045 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17047 case OPC_EXTRV_S_H
:
17048 tcg_gen_movi_tl(t0
, v2
);
17049 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17052 tcg_gen_movi_tl(t0
, v2
);
17053 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17055 case OPC_EXTRV_R_W
:
17056 tcg_gen_movi_tl(t0
, v2
);
17057 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17059 case OPC_EXTRV_RS_W
:
17060 tcg_gen_movi_tl(t0
, v2
);
17061 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17064 tcg_gen_movi_tl(t0
, v2
);
17065 tcg_gen_movi_tl(t1
, v1
);
17066 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17069 tcg_gen_movi_tl(t0
, v2
);
17070 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17073 tcg_gen_movi_tl(t0
, v2
);
17074 tcg_gen_movi_tl(t1
, v1
);
17075 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17078 tcg_gen_movi_tl(t0
, v2
);
17079 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17082 imm
= (ctx
->opcode
>> 20) & 0x3F;
17083 tcg_gen_movi_tl(t0
, ret
);
17084 tcg_gen_movi_tl(t1
, imm
);
17085 gen_helper_shilo(t0
, t1
, cpu_env
);
17088 tcg_gen_movi_tl(t0
, ret
);
17089 gen_helper_shilo(t0
, v1_t
, cpu_env
);
17092 tcg_gen_movi_tl(t0
, ret
);
17093 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
17096 imm
= (ctx
->opcode
>> 11) & 0x3FF;
17097 tcg_gen_movi_tl(t0
, imm
);
17098 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
17101 imm
= (ctx
->opcode
>> 16) & 0x03FF;
17102 tcg_gen_movi_tl(t0
, imm
);
17103 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
17107 #ifdef TARGET_MIPS64
17108 case OPC_DEXTR_W_DSP
:
17112 tcg_gen_movi_tl(t0
, ret
);
17113 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
17117 int shift
= (ctx
->opcode
>> 19) & 0x7F;
17118 int ac
= (ctx
->opcode
>> 11) & 0x03;
17119 tcg_gen_movi_tl(t0
, shift
);
17120 tcg_gen_movi_tl(t1
, ac
);
17121 gen_helper_dshilo(t0
, t1
, cpu_env
);
17126 int ac
= (ctx
->opcode
>> 11) & 0x03;
17127 tcg_gen_movi_tl(t0
, ac
);
17128 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
17132 tcg_gen_movi_tl(t0
, v2
);
17133 tcg_gen_movi_tl(t1
, v1
);
17135 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17138 tcg_gen_movi_tl(t0
, v2
);
17139 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17142 tcg_gen_movi_tl(t0
, v2
);
17143 tcg_gen_movi_tl(t1
, v1
);
17144 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17147 tcg_gen_movi_tl(t0
, v2
);
17148 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17151 tcg_gen_movi_tl(t0
, v2
);
17152 tcg_gen_movi_tl(t1
, v1
);
17153 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17155 case OPC_DEXTR_R_L
:
17156 tcg_gen_movi_tl(t0
, v2
);
17157 tcg_gen_movi_tl(t1
, v1
);
17158 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17160 case OPC_DEXTR_RS_L
:
17161 tcg_gen_movi_tl(t0
, v2
);
17162 tcg_gen_movi_tl(t1
, v1
);
17163 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17166 tcg_gen_movi_tl(t0
, v2
);
17167 tcg_gen_movi_tl(t1
, v1
);
17168 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17170 case OPC_DEXTR_R_W
:
17171 tcg_gen_movi_tl(t0
, v2
);
17172 tcg_gen_movi_tl(t1
, v1
);
17173 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17175 case OPC_DEXTR_RS_W
:
17176 tcg_gen_movi_tl(t0
, v2
);
17177 tcg_gen_movi_tl(t1
, v1
);
17178 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17180 case OPC_DEXTR_S_H
:
17181 tcg_gen_movi_tl(t0
, v2
);
17182 tcg_gen_movi_tl(t1
, v1
);
17183 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17185 case OPC_DEXTRV_S_H
:
17186 tcg_gen_movi_tl(t0
, v2
);
17187 tcg_gen_movi_tl(t1
, v1
);
17188 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17191 tcg_gen_movi_tl(t0
, v2
);
17192 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17194 case OPC_DEXTRV_R_L
:
17195 tcg_gen_movi_tl(t0
, v2
);
17196 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17198 case OPC_DEXTRV_RS_L
:
17199 tcg_gen_movi_tl(t0
, v2
);
17200 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17203 tcg_gen_movi_tl(t0
, v2
);
17204 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17206 case OPC_DEXTRV_R_W
:
17207 tcg_gen_movi_tl(t0
, v2
);
17208 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17210 case OPC_DEXTRV_RS_W
:
17211 tcg_gen_movi_tl(t0
, v2
);
17212 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17221 tcg_temp_free(v1_t
);
17222 tcg_temp_free(v2_t
);
17224 (void)opn
; /* avoid a compiler warning */
17225 MIPS_DEBUG("%s", opn
);
17228 /* End MIPSDSP functions. */
17230 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
17232 int rs
, rt
, rd
, sa
;
17235 rs
= (ctx
->opcode
>> 21) & 0x1f;
17236 rt
= (ctx
->opcode
>> 16) & 0x1f;
17237 rd
= (ctx
->opcode
>> 11) & 0x1f;
17238 sa
= (ctx
->opcode
>> 6) & 0x1f;
17240 op1
= MASK_SPECIAL(ctx
->opcode
);
17243 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
17245 case OPC_MULT
... OPC_DIVU
:
17246 op2
= MASK_R6_MULDIV(ctx
->opcode
);
17256 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
17259 MIPS_INVAL("special_r6 muldiv");
17260 generate_exception(ctx
, EXCP_RI
);
17266 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
17270 if (rt
== 0 && sa
== 1) {
17271 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17272 We need additionally to check other fields */
17273 gen_cl(ctx
, op1
, rd
, rs
);
17275 generate_exception(ctx
, EXCP_RI
);
17279 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
17280 gen_helper_do_semihosting(cpu_env
);
17282 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
17283 generate_exception(ctx
, EXCP_RI
);
17285 generate_exception(ctx
, EXCP_DBp
);
17289 #if defined(TARGET_MIPS64)
17291 check_mips_64(ctx
);
17292 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
17296 if (rt
== 0 && sa
== 1) {
17297 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17298 We need additionally to check other fields */
17299 check_mips_64(ctx
);
17300 gen_cl(ctx
, op1
, rd
, rs
);
17302 generate_exception(ctx
, EXCP_RI
);
17305 case OPC_DMULT
... OPC_DDIVU
:
17306 op2
= MASK_R6_MULDIV(ctx
->opcode
);
17316 check_mips_64(ctx
);
17317 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
17320 MIPS_INVAL("special_r6 muldiv");
17321 generate_exception(ctx
, EXCP_RI
);
17326 default: /* Invalid */
17327 MIPS_INVAL("special_r6");
17328 generate_exception(ctx
, EXCP_RI
);
17333 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17335 int rs
, rt
, rd
, sa
;
17338 rs
= (ctx
->opcode
>> 21) & 0x1f;
17339 rt
= (ctx
->opcode
>> 16) & 0x1f;
17340 rd
= (ctx
->opcode
>> 11) & 0x1f;
17341 sa
= (ctx
->opcode
>> 6) & 0x1f;
17343 op1
= MASK_SPECIAL(ctx
->opcode
);
17345 case OPC_MOVN
: /* Conditional move */
17347 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
17348 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
17349 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
17351 case OPC_MFHI
: /* Move from HI/LO */
17353 gen_HILO(ctx
, op1
, rs
& 3, rd
);
17356 case OPC_MTLO
: /* Move to HI/LO */
17357 gen_HILO(ctx
, op1
, rd
& 3, rs
);
17360 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
17361 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17362 check_cp1_enabled(ctx
);
17363 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
17364 (ctx
->opcode
>> 16) & 1);
17366 generate_exception_err(ctx
, EXCP_CpU
, 1);
17372 check_insn(ctx
, INSN_VR54XX
);
17373 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
17374 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
17376 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
17381 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
17383 #if defined(TARGET_MIPS64)
17384 case OPC_DMULT
... OPC_DDIVU
:
17385 check_insn(ctx
, ISA_MIPS3
);
17386 check_mips_64(ctx
);
17387 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
17391 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
17394 #ifdef MIPS_STRICT_STANDARD
17395 MIPS_INVAL("SPIM");
17396 generate_exception(ctx
, EXCP_RI
);
17398 /* Implemented as RI exception for now. */
17399 MIPS_INVAL("spim (unofficial)");
17400 generate_exception(ctx
, EXCP_RI
);
17403 default: /* Invalid */
17404 MIPS_INVAL("special_legacy");
17405 generate_exception(ctx
, EXCP_RI
);
17410 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
17412 int rs
, rt
, rd
, sa
;
17415 rs
= (ctx
->opcode
>> 21) & 0x1f;
17416 rt
= (ctx
->opcode
>> 16) & 0x1f;
17417 rd
= (ctx
->opcode
>> 11) & 0x1f;
17418 sa
= (ctx
->opcode
>> 6) & 0x1f;
17420 op1
= MASK_SPECIAL(ctx
->opcode
);
17422 case OPC_SLL
: /* Shift with immediate */
17423 if (sa
== 5 && rd
== 0 &&
17424 rs
== 0 && rt
== 0) { /* PAUSE */
17425 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
17426 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
17427 MIPS_DEBUG("CTI in delay / forbidden slot");
17428 generate_exception(ctx
, EXCP_RI
);
17434 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17437 switch ((ctx
->opcode
>> 21) & 0x1f) {
17439 /* rotr is decoded as srl on non-R2 CPUs */
17440 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17445 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17448 generate_exception(ctx
, EXCP_RI
);
17452 case OPC_ADD
... OPC_SUBU
:
17453 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17455 case OPC_SLLV
: /* Shifts */
17457 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17460 switch ((ctx
->opcode
>> 6) & 0x1f) {
17462 /* rotrv is decoded as srlv on non-R2 CPUs */
17463 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17468 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17471 generate_exception(ctx
, EXCP_RI
);
17475 case OPC_SLT
: /* Set on less than */
17477 gen_slt(ctx
, op1
, rd
, rs
, rt
);
17479 case OPC_AND
: /* Logic*/
17483 gen_logic(ctx
, op1
, rd
, rs
, rt
);
17486 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
17488 case OPC_TGE
... OPC_TEQ
: /* Traps */
17490 check_insn(ctx
, ISA_MIPS2
);
17491 gen_trap(ctx
, op1
, rs
, rt
, -1);
17493 case OPC_LSA
: /* OPC_PMON */
17494 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
17495 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
17496 decode_opc_special_r6(env
, ctx
);
17498 /* Pmon entry point, also R4010 selsl */
17499 #ifdef MIPS_STRICT_STANDARD
17500 MIPS_INVAL("PMON / selsl");
17501 generate_exception(ctx
, EXCP_RI
);
17503 gen_helper_0e0i(pmon
, sa
);
17508 generate_exception(ctx
, EXCP_SYSCALL
);
17509 ctx
->bstate
= BS_STOP
;
17512 generate_exception(ctx
, EXCP_BREAK
);
17515 check_insn(ctx
, ISA_MIPS2
);
17516 /* Treat as NOP. */
17519 #if defined(TARGET_MIPS64)
17520 /* MIPS64 specific opcodes */
17525 check_insn(ctx
, ISA_MIPS3
);
17526 check_mips_64(ctx
);
17527 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17530 switch ((ctx
->opcode
>> 21) & 0x1f) {
17532 /* drotr is decoded as dsrl on non-R2 CPUs */
17533 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17538 check_insn(ctx
, ISA_MIPS3
);
17539 check_mips_64(ctx
);
17540 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17543 generate_exception(ctx
, EXCP_RI
);
17548 switch ((ctx
->opcode
>> 21) & 0x1f) {
17550 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17551 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17556 check_insn(ctx
, ISA_MIPS3
);
17557 check_mips_64(ctx
);
17558 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17561 generate_exception(ctx
, EXCP_RI
);
17565 case OPC_DADD
... OPC_DSUBU
:
17566 check_insn(ctx
, ISA_MIPS3
);
17567 check_mips_64(ctx
);
17568 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17572 check_insn(ctx
, ISA_MIPS3
);
17573 check_mips_64(ctx
);
17574 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17577 switch ((ctx
->opcode
>> 6) & 0x1f) {
17579 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17580 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17585 check_insn(ctx
, ISA_MIPS3
);
17586 check_mips_64(ctx
);
17587 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17590 generate_exception(ctx
, EXCP_RI
);
17595 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
17596 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
17597 decode_opc_special_r6(env
, ctx
);
17602 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17603 decode_opc_special_r6(env
, ctx
);
17605 decode_opc_special_legacy(env
, ctx
);
17610 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17615 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17617 rs
= (ctx
->opcode
>> 21) & 0x1f;
17618 rt
= (ctx
->opcode
>> 16) & 0x1f;
17619 rd
= (ctx
->opcode
>> 11) & 0x1f;
17621 op1
= MASK_SPECIAL2(ctx
->opcode
);
17623 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
17624 case OPC_MSUB
... OPC_MSUBU
:
17625 check_insn(ctx
, ISA_MIPS32
);
17626 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
17629 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17632 case OPC_DIVU_G_2F
:
17633 case OPC_MULT_G_2F
:
17634 case OPC_MULTU_G_2F
:
17636 case OPC_MODU_G_2F
:
17637 check_insn(ctx
, INSN_LOONGSON2F
);
17638 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17642 check_insn(ctx
, ISA_MIPS32
);
17643 gen_cl(ctx
, op1
, rd
, rs
);
17646 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
17647 gen_helper_do_semihosting(cpu_env
);
17649 /* XXX: not clear which exception should be raised
17650 * when in debug mode...
17652 check_insn(ctx
, ISA_MIPS32
);
17653 generate_exception(ctx
, EXCP_DBp
);
17656 #if defined(TARGET_MIPS64)
17659 check_insn(ctx
, ISA_MIPS64
);
17660 check_mips_64(ctx
);
17661 gen_cl(ctx
, op1
, rd
, rs
);
17663 case OPC_DMULT_G_2F
:
17664 case OPC_DMULTU_G_2F
:
17665 case OPC_DDIV_G_2F
:
17666 case OPC_DDIVU_G_2F
:
17667 case OPC_DMOD_G_2F
:
17668 case OPC_DMODU_G_2F
:
17669 check_insn(ctx
, INSN_LOONGSON2F
);
17670 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17673 default: /* Invalid */
17674 MIPS_INVAL("special2_legacy");
17675 generate_exception(ctx
, EXCP_RI
);
17680 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
17682 int rs
, rt
, rd
, sa
;
17686 rs
= (ctx
->opcode
>> 21) & 0x1f;
17687 rt
= (ctx
->opcode
>> 16) & 0x1f;
17688 rd
= (ctx
->opcode
>> 11) & 0x1f;
17689 sa
= (ctx
->opcode
>> 6) & 0x1f;
17690 imm
= (int16_t)ctx
->opcode
>> 7;
17692 op1
= MASK_SPECIAL3(ctx
->opcode
);
17696 /* hint codes 24-31 are reserved and signal RI */
17697 generate_exception(ctx
, EXCP_RI
);
17699 /* Treat as NOP. */
17702 /* Treat as NOP. */
17705 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
17708 gen_ld(ctx
, op1
, rt
, rs
, imm
);
17713 /* Treat as NOP. */
17716 op2
= MASK_BSHFL(ctx
->opcode
);
17718 case OPC_ALIGN
... OPC_ALIGN_END
:
17719 gen_align(ctx
, OPC_ALIGN
, rd
, rs
, rt
, sa
& 3);
17722 gen_bitswap(ctx
, op2
, rd
, rt
);
17727 #if defined(TARGET_MIPS64)
17729 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
17732 gen_ld(ctx
, op1
, rt
, rs
, imm
);
17735 check_mips_64(ctx
);
17738 /* Treat as NOP. */
17741 op2
= MASK_DBSHFL(ctx
->opcode
);
17743 case OPC_DALIGN
... OPC_DALIGN_END
:
17744 gen_align(ctx
, OPC_DALIGN
, rd
, rs
, rt
, sa
& 7);
17747 gen_bitswap(ctx
, op2
, rd
, rt
);
17754 default: /* Invalid */
17755 MIPS_INVAL("special3_r6");
17756 generate_exception(ctx
, EXCP_RI
);
17761 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17766 rs
= (ctx
->opcode
>> 21) & 0x1f;
17767 rt
= (ctx
->opcode
>> 16) & 0x1f;
17768 rd
= (ctx
->opcode
>> 11) & 0x1f;
17770 op1
= MASK_SPECIAL3(ctx
->opcode
);
17772 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
17773 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
17774 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
17775 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17776 * the same mask and op1. */
17777 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
17778 op2
= MASK_ADDUH_QB(ctx
->opcode
);
17781 case OPC_ADDUH_R_QB
:
17783 case OPC_ADDQH_R_PH
:
17785 case OPC_ADDQH_R_W
:
17787 case OPC_SUBUH_R_QB
:
17789 case OPC_SUBQH_R_PH
:
17791 case OPC_SUBQH_R_W
:
17792 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17797 case OPC_MULQ_RS_W
:
17798 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17801 MIPS_INVAL("MASK ADDUH.QB");
17802 generate_exception(ctx
, EXCP_RI
);
17805 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
17806 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17808 generate_exception(ctx
, EXCP_RI
);
17812 op2
= MASK_LX(ctx
->opcode
);
17814 #if defined(TARGET_MIPS64)
17820 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
17822 default: /* Invalid */
17823 MIPS_INVAL("MASK LX");
17824 generate_exception(ctx
, EXCP_RI
);
17828 case OPC_ABSQ_S_PH_DSP
:
17829 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
17831 case OPC_ABSQ_S_QB
:
17832 case OPC_ABSQ_S_PH
:
17834 case OPC_PRECEQ_W_PHL
:
17835 case OPC_PRECEQ_W_PHR
:
17836 case OPC_PRECEQU_PH_QBL
:
17837 case OPC_PRECEQU_PH_QBR
:
17838 case OPC_PRECEQU_PH_QBLA
:
17839 case OPC_PRECEQU_PH_QBRA
:
17840 case OPC_PRECEU_PH_QBL
:
17841 case OPC_PRECEU_PH_QBR
:
17842 case OPC_PRECEU_PH_QBLA
:
17843 case OPC_PRECEU_PH_QBRA
:
17844 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17851 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
17854 MIPS_INVAL("MASK ABSQ_S.PH");
17855 generate_exception(ctx
, EXCP_RI
);
17859 case OPC_ADDU_QB_DSP
:
17860 op2
= MASK_ADDU_QB(ctx
->opcode
);
17863 case OPC_ADDQ_S_PH
:
17866 case OPC_ADDU_S_QB
:
17868 case OPC_ADDU_S_PH
:
17870 case OPC_SUBQ_S_PH
:
17873 case OPC_SUBU_S_QB
:
17875 case OPC_SUBU_S_PH
:
17879 case OPC_RADDU_W_QB
:
17880 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17882 case OPC_MULEU_S_PH_QBL
:
17883 case OPC_MULEU_S_PH_QBR
:
17884 case OPC_MULQ_RS_PH
:
17885 case OPC_MULEQ_S_W_PHL
:
17886 case OPC_MULEQ_S_W_PHR
:
17887 case OPC_MULQ_S_PH
:
17888 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17890 default: /* Invalid */
17891 MIPS_INVAL("MASK ADDU.QB");
17892 generate_exception(ctx
, EXCP_RI
);
17897 case OPC_CMPU_EQ_QB_DSP
:
17898 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
17900 case OPC_PRECR_SRA_PH_W
:
17901 case OPC_PRECR_SRA_R_PH_W
:
17902 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
17904 case OPC_PRECR_QB_PH
:
17905 case OPC_PRECRQ_QB_PH
:
17906 case OPC_PRECRQ_PH_W
:
17907 case OPC_PRECRQ_RS_PH_W
:
17908 case OPC_PRECRQU_S_QB_PH
:
17909 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17911 case OPC_CMPU_EQ_QB
:
17912 case OPC_CMPU_LT_QB
:
17913 case OPC_CMPU_LE_QB
:
17914 case OPC_CMP_EQ_PH
:
17915 case OPC_CMP_LT_PH
:
17916 case OPC_CMP_LE_PH
:
17917 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17919 case OPC_CMPGU_EQ_QB
:
17920 case OPC_CMPGU_LT_QB
:
17921 case OPC_CMPGU_LE_QB
:
17922 case OPC_CMPGDU_EQ_QB
:
17923 case OPC_CMPGDU_LT_QB
:
17924 case OPC_CMPGDU_LE_QB
:
17927 case OPC_PACKRL_PH
:
17928 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17930 default: /* Invalid */
17931 MIPS_INVAL("MASK CMPU.EQ.QB");
17932 generate_exception(ctx
, EXCP_RI
);
17936 case OPC_SHLL_QB_DSP
:
17937 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
17939 case OPC_DPA_W_PH_DSP
:
17940 op2
= MASK_DPA_W_PH(ctx
->opcode
);
17942 case OPC_DPAU_H_QBL
:
17943 case OPC_DPAU_H_QBR
:
17944 case OPC_DPSU_H_QBL
:
17945 case OPC_DPSU_H_QBR
:
17947 case OPC_DPAX_W_PH
:
17948 case OPC_DPAQ_S_W_PH
:
17949 case OPC_DPAQX_S_W_PH
:
17950 case OPC_DPAQX_SA_W_PH
:
17952 case OPC_DPSX_W_PH
:
17953 case OPC_DPSQ_S_W_PH
:
17954 case OPC_DPSQX_S_W_PH
:
17955 case OPC_DPSQX_SA_W_PH
:
17956 case OPC_MULSAQ_S_W_PH
:
17957 case OPC_DPAQ_SA_L_W
:
17958 case OPC_DPSQ_SA_L_W
:
17959 case OPC_MAQ_S_W_PHL
:
17960 case OPC_MAQ_S_W_PHR
:
17961 case OPC_MAQ_SA_W_PHL
:
17962 case OPC_MAQ_SA_W_PHR
:
17963 case OPC_MULSA_W_PH
:
17964 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17966 default: /* Invalid */
17967 MIPS_INVAL("MASK DPAW.PH");
17968 generate_exception(ctx
, EXCP_RI
);
17973 op2
= MASK_INSV(ctx
->opcode
);
17985 t0
= tcg_temp_new();
17986 t1
= tcg_temp_new();
17988 gen_load_gpr(t0
, rt
);
17989 gen_load_gpr(t1
, rs
);
17991 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
17997 default: /* Invalid */
17998 MIPS_INVAL("MASK INSV");
17999 generate_exception(ctx
, EXCP_RI
);
18003 case OPC_APPEND_DSP
:
18004 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
18006 case OPC_EXTR_W_DSP
:
18007 op2
= MASK_EXTR_W(ctx
->opcode
);
18011 case OPC_EXTR_RS_W
:
18013 case OPC_EXTRV_S_H
:
18015 case OPC_EXTRV_R_W
:
18016 case OPC_EXTRV_RS_W
:
18021 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
18024 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
18030 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18032 default: /* Invalid */
18033 MIPS_INVAL("MASK EXTR.W");
18034 generate_exception(ctx
, EXCP_RI
);
18038 #if defined(TARGET_MIPS64)
18039 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
18040 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
18041 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
18042 check_insn(ctx
, INSN_LOONGSON2E
);
18043 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
18045 case OPC_ABSQ_S_QH_DSP
:
18046 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
18048 case OPC_PRECEQ_L_PWL
:
18049 case OPC_PRECEQ_L_PWR
:
18050 case OPC_PRECEQ_PW_QHL
:
18051 case OPC_PRECEQ_PW_QHR
:
18052 case OPC_PRECEQ_PW_QHLA
:
18053 case OPC_PRECEQ_PW_QHRA
:
18054 case OPC_PRECEQU_QH_OBL
:
18055 case OPC_PRECEQU_QH_OBR
:
18056 case OPC_PRECEQU_QH_OBLA
:
18057 case OPC_PRECEQU_QH_OBRA
:
18058 case OPC_PRECEU_QH_OBL
:
18059 case OPC_PRECEU_QH_OBR
:
18060 case OPC_PRECEU_QH_OBLA
:
18061 case OPC_PRECEU_QH_OBRA
:
18062 case OPC_ABSQ_S_OB
:
18063 case OPC_ABSQ_S_PW
:
18064 case OPC_ABSQ_S_QH
:
18065 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
18073 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
18075 default: /* Invalid */
18076 MIPS_INVAL("MASK ABSQ_S.QH");
18077 generate_exception(ctx
, EXCP_RI
);
18081 case OPC_ADDU_OB_DSP
:
18082 op2
= MASK_ADDU_OB(ctx
->opcode
);
18084 case OPC_RADDU_L_OB
:
18086 case OPC_SUBQ_S_PW
:
18088 case OPC_SUBQ_S_QH
:
18090 case OPC_SUBU_S_OB
:
18092 case OPC_SUBU_S_QH
:
18094 case OPC_SUBUH_R_OB
:
18096 case OPC_ADDQ_S_PW
:
18098 case OPC_ADDQ_S_QH
:
18100 case OPC_ADDU_S_OB
:
18102 case OPC_ADDU_S_QH
:
18104 case OPC_ADDUH_R_OB
:
18105 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
18107 case OPC_MULEQ_S_PW_QHL
:
18108 case OPC_MULEQ_S_PW_QHR
:
18109 case OPC_MULEU_S_QH_OBL
:
18110 case OPC_MULEU_S_QH_OBR
:
18111 case OPC_MULQ_RS_QH
:
18112 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
18114 default: /* Invalid */
18115 MIPS_INVAL("MASK ADDU.OB");
18116 generate_exception(ctx
, EXCP_RI
);
18120 case OPC_CMPU_EQ_OB_DSP
:
18121 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
18123 case OPC_PRECR_SRA_QH_PW
:
18124 case OPC_PRECR_SRA_R_QH_PW
:
18125 /* Return value is rt. */
18126 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
18128 case OPC_PRECR_OB_QH
:
18129 case OPC_PRECRQ_OB_QH
:
18130 case OPC_PRECRQ_PW_L
:
18131 case OPC_PRECRQ_QH_PW
:
18132 case OPC_PRECRQ_RS_QH_PW
:
18133 case OPC_PRECRQU_S_OB_QH
:
18134 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
18136 case OPC_CMPU_EQ_OB
:
18137 case OPC_CMPU_LT_OB
:
18138 case OPC_CMPU_LE_OB
:
18139 case OPC_CMP_EQ_QH
:
18140 case OPC_CMP_LT_QH
:
18141 case OPC_CMP_LE_QH
:
18142 case OPC_CMP_EQ_PW
:
18143 case OPC_CMP_LT_PW
:
18144 case OPC_CMP_LE_PW
:
18145 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18147 case OPC_CMPGDU_EQ_OB
:
18148 case OPC_CMPGDU_LT_OB
:
18149 case OPC_CMPGDU_LE_OB
:
18150 case OPC_CMPGU_EQ_OB
:
18151 case OPC_CMPGU_LT_OB
:
18152 case OPC_CMPGU_LE_OB
:
18153 case OPC_PACKRL_PW
:
18157 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
18159 default: /* Invalid */
18160 MIPS_INVAL("MASK CMPU_EQ.OB");
18161 generate_exception(ctx
, EXCP_RI
);
18165 case OPC_DAPPEND_DSP
:
18166 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
18168 case OPC_DEXTR_W_DSP
:
18169 op2
= MASK_DEXTR_W(ctx
->opcode
);
18176 case OPC_DEXTR_R_L
:
18177 case OPC_DEXTR_RS_L
:
18179 case OPC_DEXTR_R_W
:
18180 case OPC_DEXTR_RS_W
:
18181 case OPC_DEXTR_S_H
:
18183 case OPC_DEXTRV_R_L
:
18184 case OPC_DEXTRV_RS_L
:
18185 case OPC_DEXTRV_S_H
:
18187 case OPC_DEXTRV_R_W
:
18188 case OPC_DEXTRV_RS_W
:
18189 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
18194 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18196 default: /* Invalid */
18197 MIPS_INVAL("MASK EXTR.W");
18198 generate_exception(ctx
, EXCP_RI
);
18202 case OPC_DPAQ_W_QH_DSP
:
18203 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
18205 case OPC_DPAU_H_OBL
:
18206 case OPC_DPAU_H_OBR
:
18207 case OPC_DPSU_H_OBL
:
18208 case OPC_DPSU_H_OBR
:
18210 case OPC_DPAQ_S_W_QH
:
18212 case OPC_DPSQ_S_W_QH
:
18213 case OPC_MULSAQ_S_W_QH
:
18214 case OPC_DPAQ_SA_L_PW
:
18215 case OPC_DPSQ_SA_L_PW
:
18216 case OPC_MULSAQ_S_L_PW
:
18217 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18219 case OPC_MAQ_S_W_QHLL
:
18220 case OPC_MAQ_S_W_QHLR
:
18221 case OPC_MAQ_S_W_QHRL
:
18222 case OPC_MAQ_S_W_QHRR
:
18223 case OPC_MAQ_SA_W_QHLL
:
18224 case OPC_MAQ_SA_W_QHLR
:
18225 case OPC_MAQ_SA_W_QHRL
:
18226 case OPC_MAQ_SA_W_QHRR
:
18227 case OPC_MAQ_S_L_PWL
:
18228 case OPC_MAQ_S_L_PWR
:
18233 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18235 default: /* Invalid */
18236 MIPS_INVAL("MASK DPAQ.W.QH");
18237 generate_exception(ctx
, EXCP_RI
);
18241 case OPC_DINSV_DSP
:
18242 op2
= MASK_INSV(ctx
->opcode
);
18254 t0
= tcg_temp_new();
18255 t1
= tcg_temp_new();
18257 gen_load_gpr(t0
, rt
);
18258 gen_load_gpr(t1
, rs
);
18260 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
18266 default: /* Invalid */
18267 MIPS_INVAL("MASK DINSV");
18268 generate_exception(ctx
, EXCP_RI
);
18272 case OPC_SHLL_OB_DSP
:
18273 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
18276 default: /* Invalid */
18277 MIPS_INVAL("special3_legacy");
18278 generate_exception(ctx
, EXCP_RI
);
18283 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
18285 int rs
, rt
, rd
, sa
;
18288 rs
= (ctx
->opcode
>> 21) & 0x1f;
18289 rt
= (ctx
->opcode
>> 16) & 0x1f;
18290 rd
= (ctx
->opcode
>> 11) & 0x1f;
18291 sa
= (ctx
->opcode
>> 6) & 0x1f;
18293 op1
= MASK_SPECIAL3(ctx
->opcode
);
18297 check_insn(ctx
, ISA_MIPS32R2
);
18298 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
18301 op2
= MASK_BSHFL(ctx
->opcode
);
18303 case OPC_ALIGN
... OPC_ALIGN_END
:
18305 check_insn(ctx
, ISA_MIPS32R6
);
18306 decode_opc_special3_r6(env
, ctx
);
18309 check_insn(ctx
, ISA_MIPS32R2
);
18310 gen_bshfl(ctx
, op2
, rt
, rd
);
18314 #if defined(TARGET_MIPS64)
18315 case OPC_DEXTM
... OPC_DEXT
:
18316 case OPC_DINSM
... OPC_DINS
:
18317 check_insn(ctx
, ISA_MIPS64R2
);
18318 check_mips_64(ctx
);
18319 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
18322 op2
= MASK_DBSHFL(ctx
->opcode
);
18324 case OPC_DALIGN
... OPC_DALIGN_END
:
18326 check_insn(ctx
, ISA_MIPS32R6
);
18327 decode_opc_special3_r6(env
, ctx
);
18330 check_insn(ctx
, ISA_MIPS64R2
);
18331 check_mips_64(ctx
);
18332 op2
= MASK_DBSHFL(ctx
->opcode
);
18333 gen_bshfl(ctx
, op2
, rt
, rd
);
18339 gen_rdhwr(ctx
, rt
, rd
);
18342 check_insn(ctx
, ASE_MT
);
18344 TCGv t0
= tcg_temp_new();
18345 TCGv t1
= tcg_temp_new();
18347 gen_load_gpr(t0
, rt
);
18348 gen_load_gpr(t1
, rs
);
18349 gen_helper_fork(t0
, t1
);
18355 check_insn(ctx
, ASE_MT
);
18357 TCGv t0
= tcg_temp_new();
18359 save_cpu_state(ctx
, 1);
18360 gen_load_gpr(t0
, rs
);
18361 gen_helper_yield(t0
, cpu_env
, t0
);
18362 gen_store_gpr(t0
, rd
);
18367 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18368 decode_opc_special3_r6(env
, ctx
);
18370 decode_opc_special3_legacy(env
, ctx
);
18375 /* MIPS SIMD Architecture (MSA) */
18376 static inline int check_msa_access(DisasContext
*ctx
)
18378 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
18379 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
18380 generate_exception(ctx
, EXCP_RI
);
18384 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
18385 if (ctx
->insn_flags
& ASE_MSA
) {
18386 generate_exception(ctx
, EXCP_MSADIS
);
18389 generate_exception(ctx
, EXCP_RI
);
18396 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
18398 /* generates tcg ops to check if any element is 0 */
18399 /* Note this function only works with MSA_WRLEN = 128 */
18400 uint64_t eval_zero_or_big
= 0;
18401 uint64_t eval_big
= 0;
18402 TCGv_i64 t0
= tcg_temp_new_i64();
18403 TCGv_i64 t1
= tcg_temp_new_i64();
18406 eval_zero_or_big
= 0x0101010101010101ULL
;
18407 eval_big
= 0x8080808080808080ULL
;
18410 eval_zero_or_big
= 0x0001000100010001ULL
;
18411 eval_big
= 0x8000800080008000ULL
;
18414 eval_zero_or_big
= 0x0000000100000001ULL
;
18415 eval_big
= 0x8000000080000000ULL
;
18418 eval_zero_or_big
= 0x0000000000000001ULL
;
18419 eval_big
= 0x8000000000000000ULL
;
18422 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<<1], eval_zero_or_big
);
18423 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<<1]);
18424 tcg_gen_andi_i64(t0
, t0
, eval_big
);
18425 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<<1)+1], eval_zero_or_big
);
18426 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<<1)+1]);
18427 tcg_gen_andi_i64(t1
, t1
, eval_big
);
18428 tcg_gen_or_i64(t0
, t0
, t1
);
18429 /* if all bits are zero then all elements are not zero */
18430 /* if some bit is non-zero then some element is zero */
18431 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
18432 tcg_gen_trunc_i64_tl(tresult
, t0
);
18433 tcg_temp_free_i64(t0
);
18434 tcg_temp_free_i64(t1
);
18437 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
18439 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18440 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18441 int64_t s16
= (int16_t)ctx
->opcode
;
18443 check_msa_access(ctx
);
18445 if (ctx
->insn_flags
& ISA_MIPS32R6
&& ctx
->hflags
& MIPS_HFLAG_BMASK
) {
18446 MIPS_DEBUG("CTI in delay / forbidden slot");
18447 generate_exception(ctx
, EXCP_RI
);
18454 TCGv_i64 t0
= tcg_temp_new_i64();
18455 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<<1], msa_wr_d
[(wt
<<1)+1]);
18456 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
18457 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
18458 tcg_gen_trunc_i64_tl(bcond
, t0
);
18459 tcg_temp_free_i64(t0
);
18466 gen_check_zero_element(bcond
, df
, wt
);
18472 gen_check_zero_element(bcond
, df
, wt
);
18473 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
18477 ctx
->btarget
= ctx
->pc
+ (s16
<< 2) + 4;
18479 ctx
->hflags
|= MIPS_HFLAG_BC
;
18480 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
18483 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
18485 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18486 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
18487 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18488 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18490 TCGv_i32 twd
= tcg_const_i32(wd
);
18491 TCGv_i32 tws
= tcg_const_i32(ws
);
18492 TCGv_i32 ti8
= tcg_const_i32(i8
);
18494 switch (MASK_MSA_I8(ctx
->opcode
)) {
18496 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
18499 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
18502 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
18505 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
18508 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
18511 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
18514 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
18520 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
18521 if (df
== DF_DOUBLE
) {
18522 generate_exception(ctx
, EXCP_RI
);
18524 TCGv_i32 tdf
= tcg_const_i32(df
);
18525 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
18526 tcg_temp_free_i32(tdf
);
18531 MIPS_INVAL("MSA instruction");
18532 generate_exception(ctx
, EXCP_RI
);
18536 tcg_temp_free_i32(twd
);
18537 tcg_temp_free_i32(tws
);
18538 tcg_temp_free_i32(ti8
);
18541 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
18543 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18544 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18545 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
18546 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
18547 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18548 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18550 TCGv_i32 tdf
= tcg_const_i32(df
);
18551 TCGv_i32 twd
= tcg_const_i32(wd
);
18552 TCGv_i32 tws
= tcg_const_i32(ws
);
18553 TCGv_i32 timm
= tcg_temp_new_i32();
18554 tcg_gen_movi_i32(timm
, u5
);
18556 switch (MASK_MSA_I5(ctx
->opcode
)) {
18558 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18561 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18563 case OPC_MAXI_S_df
:
18564 tcg_gen_movi_i32(timm
, s5
);
18565 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18567 case OPC_MAXI_U_df
:
18568 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18570 case OPC_MINI_S_df
:
18571 tcg_gen_movi_i32(timm
, s5
);
18572 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18574 case OPC_MINI_U_df
:
18575 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18578 tcg_gen_movi_i32(timm
, s5
);
18579 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18581 case OPC_CLTI_S_df
:
18582 tcg_gen_movi_i32(timm
, s5
);
18583 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18585 case OPC_CLTI_U_df
:
18586 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18588 case OPC_CLEI_S_df
:
18589 tcg_gen_movi_i32(timm
, s5
);
18590 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18592 case OPC_CLEI_U_df
:
18593 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18597 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
18598 tcg_gen_movi_i32(timm
, s10
);
18599 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
18603 MIPS_INVAL("MSA instruction");
18604 generate_exception(ctx
, EXCP_RI
);
18608 tcg_temp_free_i32(tdf
);
18609 tcg_temp_free_i32(twd
);
18610 tcg_temp_free_i32(tws
);
18611 tcg_temp_free_i32(timm
);
18614 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
18616 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18617 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
18618 uint32_t df
= 0, m
= 0;
18619 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18620 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18627 if ((dfm
& 0x40) == 0x00) {
18630 } else if ((dfm
& 0x60) == 0x40) {
18633 } else if ((dfm
& 0x70) == 0x60) {
18636 } else if ((dfm
& 0x78) == 0x70) {
18640 generate_exception(ctx
, EXCP_RI
);
18644 tdf
= tcg_const_i32(df
);
18645 tm
= tcg_const_i32(m
);
18646 twd
= tcg_const_i32(wd
);
18647 tws
= tcg_const_i32(ws
);
18649 switch (MASK_MSA_BIT(ctx
->opcode
)) {
18651 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18654 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
18657 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18660 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18663 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
18666 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
18668 case OPC_BINSLI_df
:
18669 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18671 case OPC_BINSRI_df
:
18672 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18675 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
18678 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
18681 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
18684 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18687 MIPS_INVAL("MSA instruction");
18688 generate_exception(ctx
, EXCP_RI
);
18692 tcg_temp_free_i32(tdf
);
18693 tcg_temp_free_i32(tm
);
18694 tcg_temp_free_i32(twd
);
18695 tcg_temp_free_i32(tws
);
18698 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
18700 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18701 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18702 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18703 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18704 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18706 TCGv_i32 tdf
= tcg_const_i32(df
);
18707 TCGv_i32 twd
= tcg_const_i32(wd
);
18708 TCGv_i32 tws
= tcg_const_i32(ws
);
18709 TCGv_i32 twt
= tcg_const_i32(wt
);
18711 switch (MASK_MSA_3R(ctx
->opcode
)) {
18713 gen_helper_msa_sll_df(cpu_env
, tdf
, twd
, tws
, twt
);
18716 gen_helper_msa_addv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18719 gen_helper_msa_ceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18722 gen_helper_msa_add_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18724 case OPC_SUBS_S_df
:
18725 gen_helper_msa_subs_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18728 gen_helper_msa_mulv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18731 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
18734 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18737 gen_helper_msa_sra_df(cpu_env
, tdf
, twd
, tws
, twt
);
18740 gen_helper_msa_subv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18742 case OPC_ADDS_A_df
:
18743 gen_helper_msa_adds_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18745 case OPC_SUBS_U_df
:
18746 gen_helper_msa_subs_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18749 gen_helper_msa_maddv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18752 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
18755 gen_helper_msa_srar_df(cpu_env
, tdf
, twd
, tws
, twt
);
18758 gen_helper_msa_srl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18761 gen_helper_msa_max_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18764 gen_helper_msa_clt_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18766 case OPC_ADDS_S_df
:
18767 gen_helper_msa_adds_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18769 case OPC_SUBSUS_U_df
:
18770 gen_helper_msa_subsus_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18773 gen_helper_msa_msubv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18776 gen_helper_msa_pckev_df(cpu_env
, tdf
, twd
, tws
, twt
);
18779 gen_helper_msa_srlr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18782 gen_helper_msa_bclr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18785 gen_helper_msa_max_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18788 gen_helper_msa_clt_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18790 case OPC_ADDS_U_df
:
18791 gen_helper_msa_adds_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18793 case OPC_SUBSUU_S_df
:
18794 gen_helper_msa_subsuu_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18797 gen_helper_msa_pckod_df(cpu_env
, tdf
, twd
, tws
, twt
);
18800 gen_helper_msa_bset_df(cpu_env
, tdf
, twd
, tws
, twt
);
18803 gen_helper_msa_min_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18806 gen_helper_msa_cle_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18809 gen_helper_msa_ave_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18811 case OPC_ASUB_S_df
:
18812 gen_helper_msa_asub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18815 gen_helper_msa_div_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18818 gen_helper_msa_ilvl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18821 gen_helper_msa_bneg_df(cpu_env
, tdf
, twd
, tws
, twt
);
18824 gen_helper_msa_min_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18827 gen_helper_msa_cle_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18830 gen_helper_msa_ave_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18832 case OPC_ASUB_U_df
:
18833 gen_helper_msa_asub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18836 gen_helper_msa_div_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18839 gen_helper_msa_ilvr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18842 gen_helper_msa_binsl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18845 gen_helper_msa_max_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18847 case OPC_AVER_S_df
:
18848 gen_helper_msa_aver_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18851 gen_helper_msa_mod_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18854 gen_helper_msa_ilvev_df(cpu_env
, tdf
, twd
, tws
, twt
);
18857 gen_helper_msa_binsr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18860 gen_helper_msa_min_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18862 case OPC_AVER_U_df
:
18863 gen_helper_msa_aver_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18866 gen_helper_msa_mod_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18869 gen_helper_msa_ilvod_df(cpu_env
, tdf
, twd
, tws
, twt
);
18872 case OPC_DOTP_S_df
:
18873 case OPC_DOTP_U_df
:
18874 case OPC_DPADD_S_df
:
18875 case OPC_DPADD_U_df
:
18876 case OPC_DPSUB_S_df
:
18877 case OPC_HADD_S_df
:
18878 case OPC_DPSUB_U_df
:
18879 case OPC_HADD_U_df
:
18880 case OPC_HSUB_S_df
:
18881 case OPC_HSUB_U_df
:
18882 if (df
== DF_BYTE
) {
18883 generate_exception(ctx
, EXCP_RI
);
18885 switch (MASK_MSA_3R(ctx
->opcode
)) {
18886 case OPC_DOTP_S_df
:
18887 gen_helper_msa_dotp_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18889 case OPC_DOTP_U_df
:
18890 gen_helper_msa_dotp_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18892 case OPC_DPADD_S_df
:
18893 gen_helper_msa_dpadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18895 case OPC_DPADD_U_df
:
18896 gen_helper_msa_dpadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18898 case OPC_DPSUB_S_df
:
18899 gen_helper_msa_dpsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18901 case OPC_HADD_S_df
:
18902 gen_helper_msa_hadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18904 case OPC_DPSUB_U_df
:
18905 gen_helper_msa_dpsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18907 case OPC_HADD_U_df
:
18908 gen_helper_msa_hadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18910 case OPC_HSUB_S_df
:
18911 gen_helper_msa_hsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18913 case OPC_HSUB_U_df
:
18914 gen_helper_msa_hsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18919 MIPS_INVAL("MSA instruction");
18920 generate_exception(ctx
, EXCP_RI
);
18923 tcg_temp_free_i32(twd
);
18924 tcg_temp_free_i32(tws
);
18925 tcg_temp_free_i32(twt
);
18926 tcg_temp_free_i32(tdf
);
18929 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
18931 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18932 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
18933 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
18934 TCGv telm
= tcg_temp_new();
18935 TCGv_i32 tsr
= tcg_const_i32(source
);
18936 TCGv_i32 tdt
= tcg_const_i32(dest
);
18938 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
18940 gen_load_gpr(telm
, source
);
18941 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
18944 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
18945 gen_store_gpr(telm
, dest
);
18948 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
18951 MIPS_INVAL("MSA instruction");
18952 generate_exception(ctx
, EXCP_RI
);
18956 tcg_temp_free(telm
);
18957 tcg_temp_free_i32(tdt
);
18958 tcg_temp_free_i32(tsr
);
18961 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
18964 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18965 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18966 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18968 TCGv_i32 tws
= tcg_const_i32(ws
);
18969 TCGv_i32 twd
= tcg_const_i32(wd
);
18970 TCGv_i32 tn
= tcg_const_i32(n
);
18971 TCGv_i32 tdf
= tcg_const_i32(df
);
18973 switch (MASK_MSA_ELM(ctx
->opcode
)) {
18975 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
18977 case OPC_SPLATI_df
:
18978 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
18981 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
18983 case OPC_COPY_S_df
:
18984 case OPC_COPY_U_df
:
18985 case OPC_INSERT_df
:
18986 #if !defined(TARGET_MIPS64)
18987 /* Double format valid only for MIPS64 */
18988 if (df
== DF_DOUBLE
) {
18989 generate_exception(ctx
, EXCP_RI
);
18993 switch (MASK_MSA_ELM(ctx
->opcode
)) {
18994 case OPC_COPY_S_df
:
18995 gen_helper_msa_copy_s_df(cpu_env
, tdf
, twd
, tws
, tn
);
18997 case OPC_COPY_U_df
:
18998 gen_helper_msa_copy_u_df(cpu_env
, tdf
, twd
, tws
, tn
);
19000 case OPC_INSERT_df
:
19001 gen_helper_msa_insert_df(cpu_env
, tdf
, twd
, tws
, tn
);
19006 MIPS_INVAL("MSA instruction");
19007 generate_exception(ctx
, EXCP_RI
);
19009 tcg_temp_free_i32(twd
);
19010 tcg_temp_free_i32(tws
);
19011 tcg_temp_free_i32(tn
);
19012 tcg_temp_free_i32(tdf
);
19015 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
19017 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
19018 uint32_t df
= 0, n
= 0;
19020 if ((dfn
& 0x30) == 0x00) {
19023 } else if ((dfn
& 0x38) == 0x20) {
19026 } else if ((dfn
& 0x3c) == 0x30) {
19029 } else if ((dfn
& 0x3e) == 0x38) {
19032 } else if (dfn
== 0x3E) {
19033 /* CTCMSA, CFCMSA, MOVE.V */
19034 gen_msa_elm_3e(env
, ctx
);
19037 generate_exception(ctx
, EXCP_RI
);
19041 gen_msa_elm_df(env
, ctx
, df
, n
);
19044 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
19046 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19047 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
19048 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19049 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19050 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19052 TCGv_i32 twd
= tcg_const_i32(wd
);
19053 TCGv_i32 tws
= tcg_const_i32(ws
);
19054 TCGv_i32 twt
= tcg_const_i32(wt
);
19055 TCGv_i32 tdf
= tcg_temp_new_i32();
19057 /* adjust df value for floating-point instruction */
19058 tcg_gen_movi_i32(tdf
, df
+ 2);
19060 switch (MASK_MSA_3RF(ctx
->opcode
)) {
19062 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
19065 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
19068 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
19071 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
19074 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
19077 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19080 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
19083 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
19086 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19089 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
19092 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
19095 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
19098 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
19101 tcg_gen_movi_i32(tdf
, df
+ 1);
19102 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19105 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
19108 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
19110 case OPC_MADD_Q_df
:
19111 tcg_gen_movi_i32(tdf
, df
+ 1);
19112 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19115 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
19117 case OPC_MSUB_Q_df
:
19118 tcg_gen_movi_i32(tdf
, df
+ 1);
19119 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19122 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
19125 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
19128 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
19131 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
19134 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
19137 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
19140 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19143 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19146 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
19149 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19152 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
19155 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
19158 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
19160 case OPC_MULR_Q_df
:
19161 tcg_gen_movi_i32(tdf
, df
+ 1);
19162 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19165 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
19167 case OPC_FMIN_A_df
:
19168 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
19170 case OPC_MADDR_Q_df
:
19171 tcg_gen_movi_i32(tdf
, df
+ 1);
19172 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19175 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
19178 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
19180 case OPC_MSUBR_Q_df
:
19181 tcg_gen_movi_i32(tdf
, df
+ 1);
19182 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19185 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
19187 case OPC_FMAX_A_df
:
19188 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
19191 MIPS_INVAL("MSA instruction");
19192 generate_exception(ctx
, EXCP_RI
);
19196 tcg_temp_free_i32(twd
);
19197 tcg_temp_free_i32(tws
);
19198 tcg_temp_free_i32(twt
);
19199 tcg_temp_free_i32(tdf
);
19202 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
19204 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19205 (op & (0x7 << 18)))
19206 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19207 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19208 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19209 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
19210 TCGv_i32 twd
= tcg_const_i32(wd
);
19211 TCGv_i32 tws
= tcg_const_i32(ws
);
19212 TCGv_i32 twt
= tcg_const_i32(wt
);
19213 TCGv_i32 tdf
= tcg_const_i32(df
);
19215 switch (MASK_MSA_2R(ctx
->opcode
)) {
19217 #if !defined(TARGET_MIPS64)
19218 /* Double format valid only for MIPS64 */
19219 if (df
== DF_DOUBLE
) {
19220 generate_exception(ctx
, EXCP_RI
);
19224 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
19227 gen_helper_msa_pcnt_df(cpu_env
, tdf
, twd
, tws
);
19230 gen_helper_msa_nloc_df(cpu_env
, tdf
, twd
, tws
);
19233 gen_helper_msa_nlzc_df(cpu_env
, tdf
, twd
, tws
);
19236 MIPS_INVAL("MSA instruction");
19237 generate_exception(ctx
, EXCP_RI
);
19241 tcg_temp_free_i32(twd
);
19242 tcg_temp_free_i32(tws
);
19243 tcg_temp_free_i32(twt
);
19244 tcg_temp_free_i32(tdf
);
19247 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
19249 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19250 (op & (0xf << 17)))
19251 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19252 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19253 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19254 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
19255 TCGv_i32 twd
= tcg_const_i32(wd
);
19256 TCGv_i32 tws
= tcg_const_i32(ws
);
19257 TCGv_i32 twt
= tcg_const_i32(wt
);
19258 /* adjust df value for floating-point instruction */
19259 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
19261 switch (MASK_MSA_2RF(ctx
->opcode
)) {
19262 case OPC_FCLASS_df
:
19263 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
19265 case OPC_FTRUNC_S_df
:
19266 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
19268 case OPC_FTRUNC_U_df
:
19269 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
19272 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
19274 case OPC_FRSQRT_df
:
19275 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
19278 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
19281 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
19284 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
19286 case OPC_FEXUPL_df
:
19287 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
19289 case OPC_FEXUPR_df
:
19290 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
19293 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
19296 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
19298 case OPC_FTINT_S_df
:
19299 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
19301 case OPC_FTINT_U_df
:
19302 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
19304 case OPC_FFINT_S_df
:
19305 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
19307 case OPC_FFINT_U_df
:
19308 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
19312 tcg_temp_free_i32(twd
);
19313 tcg_temp_free_i32(tws
);
19314 tcg_temp_free_i32(twt
);
19315 tcg_temp_free_i32(tdf
);
19318 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
19320 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19321 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19322 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19323 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19324 TCGv_i32 twd
= tcg_const_i32(wd
);
19325 TCGv_i32 tws
= tcg_const_i32(ws
);
19326 TCGv_i32 twt
= tcg_const_i32(wt
);
19328 switch (MASK_MSA_VEC(ctx
->opcode
)) {
19330 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
19333 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
19336 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
19339 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
19342 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
19345 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
19348 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
19351 MIPS_INVAL("MSA instruction");
19352 generate_exception(ctx
, EXCP_RI
);
19356 tcg_temp_free_i32(twd
);
19357 tcg_temp_free_i32(tws
);
19358 tcg_temp_free_i32(twt
);
19361 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
19363 switch (MASK_MSA_VEC(ctx
->opcode
)) {
19371 gen_msa_vec_v(env
, ctx
);
19374 gen_msa_2r(env
, ctx
);
19377 gen_msa_2rf(env
, ctx
);
19380 MIPS_INVAL("MSA instruction");
19381 generate_exception(ctx
, EXCP_RI
);
19386 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
19388 uint32_t opcode
= ctx
->opcode
;
19389 check_insn(ctx
, ASE_MSA
);
19390 check_msa_access(ctx
);
19392 switch (MASK_MSA_MINOR(opcode
)) {
19393 case OPC_MSA_I8_00
:
19394 case OPC_MSA_I8_01
:
19395 case OPC_MSA_I8_02
:
19396 gen_msa_i8(env
, ctx
);
19398 case OPC_MSA_I5_06
:
19399 case OPC_MSA_I5_07
:
19400 gen_msa_i5(env
, ctx
);
19402 case OPC_MSA_BIT_09
:
19403 case OPC_MSA_BIT_0A
:
19404 gen_msa_bit(env
, ctx
);
19406 case OPC_MSA_3R_0D
:
19407 case OPC_MSA_3R_0E
:
19408 case OPC_MSA_3R_0F
:
19409 case OPC_MSA_3R_10
:
19410 case OPC_MSA_3R_11
:
19411 case OPC_MSA_3R_12
:
19412 case OPC_MSA_3R_13
:
19413 case OPC_MSA_3R_14
:
19414 case OPC_MSA_3R_15
:
19415 gen_msa_3r(env
, ctx
);
19418 gen_msa_elm(env
, ctx
);
19420 case OPC_MSA_3RF_1A
:
19421 case OPC_MSA_3RF_1B
:
19422 case OPC_MSA_3RF_1C
:
19423 gen_msa_3rf(env
, ctx
);
19426 gen_msa_vec(env
, ctx
);
19437 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
19438 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
19439 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19440 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
19442 TCGv_i32 twd
= tcg_const_i32(wd
);
19443 TCGv taddr
= tcg_temp_new();
19444 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
19446 switch (MASK_MSA_MINOR(opcode
)) {
19448 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
19451 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
19454 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
19457 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
19460 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
19463 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
19466 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
19469 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
19473 tcg_temp_free_i32(twd
);
19474 tcg_temp_free(taddr
);
19478 MIPS_INVAL("MSA instruction");
19479 generate_exception(ctx
, EXCP_RI
);
19485 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
19488 int rs
, rt
, rd
, sa
;
19492 /* make sure instructions are on a word boundary */
19493 if (ctx
->pc
& 0x3) {
19494 env
->CP0_BadVAddr
= ctx
->pc
;
19495 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
19496 ctx
->bstate
= BS_STOP
;
19500 /* Handle blikely not taken case */
19501 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
19502 TCGLabel
*l1
= gen_new_label();
19504 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
19505 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
19506 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
19507 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
19511 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
19512 tcg_gen_debug_insn_start(ctx
->pc
);
19515 op
= MASK_OP_MAJOR(ctx
->opcode
);
19516 rs
= (ctx
->opcode
>> 21) & 0x1f;
19517 rt
= (ctx
->opcode
>> 16) & 0x1f;
19518 rd
= (ctx
->opcode
>> 11) & 0x1f;
19519 sa
= (ctx
->opcode
>> 6) & 0x1f;
19520 imm
= (int16_t)ctx
->opcode
;
19523 decode_opc_special(env
, ctx
);
19526 decode_opc_special2_legacy(env
, ctx
);
19529 decode_opc_special3(env
, ctx
);
19532 op1
= MASK_REGIMM(ctx
->opcode
);
19534 case OPC_BLTZL
: /* REGIMM branches */
19538 check_insn(ctx
, ISA_MIPS2
);
19539 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19543 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
19547 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19549 /* OPC_NAL, OPC_BAL */
19550 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
19552 generate_exception(ctx
, EXCP_RI
);
19555 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
19558 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
19560 check_insn(ctx
, ISA_MIPS2
);
19561 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19562 gen_trap(ctx
, op1
, rs
, -1, imm
);
19565 check_insn(ctx
, ISA_MIPS32R2
);
19566 /* Break the TB to be able to sync copied instructions
19568 ctx
->bstate
= BS_STOP
;
19570 case OPC_BPOSGE32
: /* MIPS DSP branch */
19571 #if defined(TARGET_MIPS64)
19575 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
19577 #if defined(TARGET_MIPS64)
19579 check_insn(ctx
, ISA_MIPS32R6
);
19580 check_mips_64(ctx
);
19582 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
19584 MIPS_DEBUG("dahi %s, %04x", regnames
[rs
], imm
);
19587 check_insn(ctx
, ISA_MIPS32R6
);
19588 check_mips_64(ctx
);
19590 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
19592 MIPS_DEBUG("dati %s, %04x", regnames
[rs
], imm
);
19595 default: /* Invalid */
19596 MIPS_INVAL("regimm");
19597 generate_exception(ctx
, EXCP_RI
);
19602 check_cp0_enabled(ctx
);
19603 op1
= MASK_CP0(ctx
->opcode
);
19611 #if defined(TARGET_MIPS64)
19615 #ifndef CONFIG_USER_ONLY
19616 gen_cp0(env
, ctx
, op1
, rt
, rd
);
19617 #endif /* !CONFIG_USER_ONLY */
19619 case OPC_C0_FIRST
... OPC_C0_LAST
:
19620 #ifndef CONFIG_USER_ONLY
19621 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
19622 #endif /* !CONFIG_USER_ONLY */
19625 #ifndef CONFIG_USER_ONLY
19628 TCGv t0
= tcg_temp_new();
19630 op2
= MASK_MFMC0(ctx
->opcode
);
19633 check_insn(ctx
, ASE_MT
);
19634 gen_helper_dmt(t0
);
19635 gen_store_gpr(t0
, rt
);
19638 check_insn(ctx
, ASE_MT
);
19639 gen_helper_emt(t0
);
19640 gen_store_gpr(t0
, rt
);
19643 check_insn(ctx
, ASE_MT
);
19644 gen_helper_dvpe(t0
, cpu_env
);
19645 gen_store_gpr(t0
, rt
);
19648 check_insn(ctx
, ASE_MT
);
19649 gen_helper_evpe(t0
, cpu_env
);
19650 gen_store_gpr(t0
, rt
);
19653 check_insn(ctx
, ISA_MIPS32R2
);
19654 save_cpu_state(ctx
, 1);
19655 gen_helper_di(t0
, cpu_env
);
19656 gen_store_gpr(t0
, rt
);
19657 /* Stop translation as we may have switched
19658 the execution mode. */
19659 ctx
->bstate
= BS_STOP
;
19662 check_insn(ctx
, ISA_MIPS32R2
);
19663 save_cpu_state(ctx
, 1);
19664 gen_helper_ei(t0
, cpu_env
);
19665 gen_store_gpr(t0
, rt
);
19666 /* Stop translation as we may have switched
19667 the execution mode. */
19668 ctx
->bstate
= BS_STOP
;
19670 default: /* Invalid */
19671 MIPS_INVAL("mfmc0");
19672 generate_exception(ctx
, EXCP_RI
);
19677 #endif /* !CONFIG_USER_ONLY */
19680 check_insn(ctx
, ISA_MIPS32R2
);
19681 gen_load_srsgpr(rt
, rd
);
19684 check_insn(ctx
, ISA_MIPS32R2
);
19685 gen_store_srsgpr(rt
, rd
);
19689 generate_exception(ctx
, EXCP_RI
);
19693 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19694 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19695 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19696 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19699 /* Arithmetic with immediate opcode */
19700 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19704 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19706 case OPC_SLTI
: /* Set on less than with immediate opcode */
19708 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
19710 case OPC_ANDI
: /* Arithmetic with immediate opcode */
19711 case OPC_LUI
: /* OPC_AUI */
19714 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
19716 case OPC_J
... OPC_JAL
: /* Jump */
19717 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
19718 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
19721 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19722 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19724 generate_exception(ctx
, EXCP_RI
);
19727 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19728 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19731 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19734 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19735 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19737 generate_exception(ctx
, EXCP_RI
);
19740 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19741 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19744 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19747 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19750 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19752 check_insn(ctx
, ISA_MIPS32R6
);
19753 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19754 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19757 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19760 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19762 check_insn(ctx
, ISA_MIPS32R6
);
19763 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19764 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19769 check_insn(ctx
, ISA_MIPS2
);
19770 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19774 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19776 case OPC_LL
: /* Load and stores */
19777 check_insn(ctx
, ISA_MIPS2
);
19781 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19783 case OPC_LB
... OPC_LH
:
19784 case OPC_LW
... OPC_LHU
:
19785 gen_ld(ctx
, op
, rt
, rs
, imm
);
19789 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19791 case OPC_SB
... OPC_SH
:
19793 gen_st(ctx
, op
, rt
, rs
, imm
);
19796 check_insn(ctx
, ISA_MIPS2
);
19797 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19798 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
19801 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19802 check_cp0_enabled(ctx
);
19803 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
19804 /* Treat as NOP. */
19807 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19808 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
19809 /* Treat as NOP. */
19812 /* Floating point (COP1). */
19817 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
19821 op1
= MASK_CP1(ctx
->opcode
);
19826 check_cp1_enabled(ctx
);
19827 check_insn(ctx
, ISA_MIPS32R2
);
19832 check_cp1_enabled(ctx
);
19833 gen_cp1(ctx
, op1
, rt
, rd
);
19835 #if defined(TARGET_MIPS64)
19838 check_cp1_enabled(ctx
);
19839 check_insn(ctx
, ISA_MIPS3
);
19840 check_mips_64(ctx
);
19841 gen_cp1(ctx
, op1
, rt
, rd
);
19844 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
19845 check_cp1_enabled(ctx
);
19846 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19848 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
19853 check_insn(ctx
, ASE_MIPS3D
);
19854 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
19855 (rt
>> 2) & 0x7, imm
<< 2);
19859 check_cp1_enabled(ctx
);
19860 check_insn(ctx
, ISA_MIPS32R6
);
19861 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
19865 check_cp1_enabled(ctx
);
19866 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19868 check_insn(ctx
, ASE_MIPS3D
);
19871 check_cp1_enabled(ctx
);
19872 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19873 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
19874 (rt
>> 2) & 0x7, imm
<< 2);
19881 check_cp1_enabled(ctx
);
19882 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
19888 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
19889 check_cp1_enabled(ctx
);
19890 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19892 case R6_OPC_CMP_AF_S
:
19893 case R6_OPC_CMP_UN_S
:
19894 case R6_OPC_CMP_EQ_S
:
19895 case R6_OPC_CMP_UEQ_S
:
19896 case R6_OPC_CMP_LT_S
:
19897 case R6_OPC_CMP_ULT_S
:
19898 case R6_OPC_CMP_LE_S
:
19899 case R6_OPC_CMP_ULE_S
:
19900 case R6_OPC_CMP_SAF_S
:
19901 case R6_OPC_CMP_SUN_S
:
19902 case R6_OPC_CMP_SEQ_S
:
19903 case R6_OPC_CMP_SEUQ_S
:
19904 case R6_OPC_CMP_SLT_S
:
19905 case R6_OPC_CMP_SULT_S
:
19906 case R6_OPC_CMP_SLE_S
:
19907 case R6_OPC_CMP_SULE_S
:
19908 case R6_OPC_CMP_OR_S
:
19909 case R6_OPC_CMP_UNE_S
:
19910 case R6_OPC_CMP_NE_S
:
19911 case R6_OPC_CMP_SOR_S
:
19912 case R6_OPC_CMP_SUNE_S
:
19913 case R6_OPC_CMP_SNE_S
:
19914 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
19916 case R6_OPC_CMP_AF_D
:
19917 case R6_OPC_CMP_UN_D
:
19918 case R6_OPC_CMP_EQ_D
:
19919 case R6_OPC_CMP_UEQ_D
:
19920 case R6_OPC_CMP_LT_D
:
19921 case R6_OPC_CMP_ULT_D
:
19922 case R6_OPC_CMP_LE_D
:
19923 case R6_OPC_CMP_ULE_D
:
19924 case R6_OPC_CMP_SAF_D
:
19925 case R6_OPC_CMP_SUN_D
:
19926 case R6_OPC_CMP_SEQ_D
:
19927 case R6_OPC_CMP_SEUQ_D
:
19928 case R6_OPC_CMP_SLT_D
:
19929 case R6_OPC_CMP_SULT_D
:
19930 case R6_OPC_CMP_SLE_D
:
19931 case R6_OPC_CMP_SULE_D
:
19932 case R6_OPC_CMP_OR_D
:
19933 case R6_OPC_CMP_UNE_D
:
19934 case R6_OPC_CMP_NE_D
:
19935 case R6_OPC_CMP_SOR_D
:
19936 case R6_OPC_CMP_SUNE_D
:
19937 case R6_OPC_CMP_SNE_D
:
19938 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
19941 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
19942 rt
, rd
, sa
, (imm
>> 8) & 0x7);
19947 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
19962 check_insn(ctx
, ASE_MSA
);
19963 gen_msa_branch(env
, ctx
, op1
);
19967 generate_exception(ctx
, EXCP_RI
);
19972 /* Compact branches [R6] and COP2 [non-R6] */
19973 case OPC_BC
: /* OPC_LWC2 */
19974 case OPC_BALC
: /* OPC_SWC2 */
19975 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19976 /* OPC_BC, OPC_BALC */
19977 gen_compute_compact_branch(ctx
, op
, 0, 0,
19978 sextract32(ctx
->opcode
<< 2, 0, 28));
19980 /* OPC_LWC2, OPC_SWC2 */
19981 /* COP2: Not implemented. */
19982 generate_exception_err(ctx
, EXCP_CpU
, 2);
19985 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
19986 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
19987 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19989 /* OPC_BEQZC, OPC_BNEZC */
19990 gen_compute_compact_branch(ctx
, op
, rs
, 0,
19991 sextract32(ctx
->opcode
<< 2, 0, 23));
19993 /* OPC_JIC, OPC_JIALC */
19994 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
19997 /* OPC_LWC2, OPC_SWC2 */
19998 /* COP2: Not implemented. */
19999 generate_exception_err(ctx
, EXCP_CpU
, 2);
20003 check_insn(ctx
, INSN_LOONGSON2F
);
20004 /* Note that these instructions use different fields. */
20005 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
20009 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20010 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20011 check_cp1_enabled(ctx
);
20012 op1
= MASK_CP3(ctx
->opcode
);
20016 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
20022 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
20023 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
20026 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
20027 /* Treat as NOP. */
20030 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
20044 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
20045 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
20049 generate_exception (ctx
, EXCP_RI
);
20053 generate_exception_err(ctx
, EXCP_CpU
, 1);
20057 #if defined(TARGET_MIPS64)
20058 /* MIPS64 opcodes */
20059 case OPC_LDL
... OPC_LDR
:
20061 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20065 check_insn(ctx
, ISA_MIPS3
);
20066 check_mips_64(ctx
);
20067 gen_ld(ctx
, op
, rt
, rs
, imm
);
20069 case OPC_SDL
... OPC_SDR
:
20070 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20073 check_insn(ctx
, ISA_MIPS3
);
20074 check_mips_64(ctx
);
20075 gen_st(ctx
, op
, rt
, rs
, imm
);
20078 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20079 check_insn(ctx
, ISA_MIPS3
);
20080 check_mips_64(ctx
);
20081 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
20083 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
20084 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
20085 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
20086 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
20089 check_insn(ctx
, ISA_MIPS3
);
20090 check_mips_64(ctx
);
20091 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
20095 check_insn(ctx
, ISA_MIPS3
);
20096 check_mips_64(ctx
);
20097 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
20100 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
20101 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
20102 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
20104 MIPS_INVAL("major opcode");
20105 generate_exception(ctx
, EXCP_RI
);
20109 case OPC_DAUI
: /* OPC_JALX */
20110 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
20111 #if defined(TARGET_MIPS64)
20113 check_mips_64(ctx
);
20115 TCGv t0
= tcg_temp_new();
20116 gen_load_gpr(t0
, rs
);
20117 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
20120 MIPS_DEBUG("daui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
20122 generate_exception(ctx
, EXCP_RI
);
20123 MIPS_INVAL("major opcode");
20127 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
20128 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
20129 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
20132 case OPC_MSA
: /* OPC_MDMX */
20133 /* MDMX: Not implemented. */
20137 check_insn(ctx
, ISA_MIPS32R6
);
20138 gen_pcrel(ctx
, ctx
->opcode
, ctx
->pc
, rs
);
20140 default: /* Invalid */
20141 MIPS_INVAL("major opcode");
20142 generate_exception(ctx
, EXCP_RI
);
20148 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
20151 CPUState
*cs
= CPU(cpu
);
20152 CPUMIPSState
*env
= &cpu
->env
;
20154 target_ulong pc_start
;
20155 target_ulong next_page_start
;
20164 qemu_log("search pc %d\n", search_pc
);
20167 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
20170 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
20171 ctx
.insn_flags
= env
->insn_flags
;
20172 ctx
.CP0_Config1
= env
->CP0_Config1
;
20174 ctx
.bstate
= BS_NONE
;
20175 ctx
.kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
20176 ctx
.rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
20177 ctx
.ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
20178 ctx
.bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
20179 ctx
.bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
20180 ctx
.PAMask
= env
->PAMask
;
20181 ctx
.mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
20182 ctx
.CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
20183 /* Restore delay slot state from the tb context. */
20184 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
20185 ctx
.ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
20186 ctx
.ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
20187 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
20188 restore_cpu_state(env
, &ctx
);
20189 #ifdef CONFIG_USER_ONLY
20190 ctx
.mem_idx
= MIPS_HFLAG_UM
;
20192 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
20194 ctx
.default_tcg_memop_mask
= (ctx
.insn_flags
& ISA_MIPS32R6
) ?
20195 MO_UNALN
: MO_ALIGN
;
20197 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
20198 if (max_insns
== 0)
20199 max_insns
= CF_COUNT_MASK
;
20200 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
20202 while (ctx
.bstate
== BS_NONE
) {
20203 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
20204 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
20205 if (bp
->pc
== ctx
.pc
) {
20206 save_cpu_state(&ctx
, 1);
20207 ctx
.bstate
= BS_BRANCH
;
20208 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
20209 /* Include the breakpoint location or the tb won't
20210 * be flushed when it must be. */
20212 goto done_generating
;
20218 j
= tcg_op_buf_count();
20222 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
20224 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
20225 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
20226 gen_opc_btarget
[lj
] = ctx
.btarget
;
20227 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
20228 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
20230 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
20233 is_slot
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
20234 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
20235 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
20237 decode_opc(env
, &ctx
);
20238 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
20239 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
20240 insn_bytes
= decode_micromips_opc(env
, &ctx
);
20241 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
20242 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
20243 insn_bytes
= decode_mips16_opc(env
, &ctx
);
20245 generate_exception(&ctx
, EXCP_RI
);
20246 ctx
.bstate
= BS_STOP
;
20250 if (ctx
.hflags
& MIPS_HFLAG_BMASK
) {
20251 if (!(ctx
.hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
20252 MIPS_HFLAG_FBNSLOT
))) {
20253 /* force to generate branch as there is neither delay nor
20257 if ((ctx
.hflags
& MIPS_HFLAG_M16
) &&
20258 (ctx
.hflags
& MIPS_HFLAG_FBNSLOT
)) {
20259 /* Force to generate branch as microMIPS R6 doesn't restrict
20260 branches in the forbidden slot. */
20265 gen_branch(&ctx
, insn_bytes
);
20267 ctx
.pc
+= insn_bytes
;
20271 /* Execute a branch and its delay slot as a single instruction.
20272 This is what GDB expects and is consistent with what the
20273 hardware does (e.g. if a delay slot instruction faults, the
20274 reported PC is the PC of the branch). */
20275 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
20279 if (ctx
.pc
>= next_page_start
) {
20283 if (tcg_op_buf_full()) {
20287 if (num_insns
>= max_insns
)
20293 if (tb
->cflags
& CF_LAST_IO
) {
20296 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
20297 save_cpu_state(&ctx
, ctx
.bstate
!= BS_EXCP
);
20298 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
20300 switch (ctx
.bstate
) {
20302 gen_goto_tb(&ctx
, 0, ctx
.pc
);
20305 save_cpu_state(&ctx
, 0);
20306 gen_goto_tb(&ctx
, 0, ctx
.pc
);
20309 tcg_gen_exit_tb(0);
20317 gen_tb_end(tb
, num_insns
);
20320 j
= tcg_op_buf_count();
20323 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
20325 tb
->size
= ctx
.pc
- pc_start
;
20326 tb
->icount
= num_insns
;
20330 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
20331 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
20332 log_target_disas(cs
, pc_start
, ctx
.pc
- pc_start
, 0);
20338 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
20340 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
20343 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
20345 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
20348 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
20352 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
20354 #define printfpr(fp) \
20357 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20358 " fd:%13g fs:%13g psu: %13g\n", \
20359 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20360 (double)(fp)->fd, \
20361 (double)(fp)->fs[FP_ENDIAN_IDX], \
20362 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20365 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20366 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20367 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20368 " fd:%13g fs:%13g psu:%13g\n", \
20369 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20371 (double)tmp.fs[FP_ENDIAN_IDX], \
20372 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20377 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20378 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
20379 get_float_exception_flags(&env
->active_fpu
.fp_status
));
20380 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
20381 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
20382 printfpr(&env
->active_fpu
.fpr
[i
]);
20388 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
20389 /* Debug help: The architecture requires 32bit code to maintain proper
20390 sign-extended values on 64bit machines. */
20392 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
20395 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
20396 fprintf_function cpu_fprintf
,
20401 if (!SIGN_EXT_P(env
->active_tc
.PC
))
20402 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
20403 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
20404 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
20405 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
20406 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
20407 if (!SIGN_EXT_P(env
->btarget
))
20408 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
20410 for (i
= 0; i
< 32; i
++) {
20411 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
20412 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
20415 if (!SIGN_EXT_P(env
->CP0_EPC
))
20416 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
20417 if (!SIGN_EXT_P(env
->lladdr
))
20418 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
20422 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
20425 MIPSCPU
*cpu
= MIPS_CPU(cs
);
20426 CPUMIPSState
*env
= &cpu
->env
;
20429 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
20430 " LO=0x" TARGET_FMT_lx
" ds %04x "
20431 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
20432 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
20433 env
->hflags
, env
->btarget
, env
->bcond
);
20434 for (i
= 0; i
< 32; i
++) {
20436 cpu_fprintf(f
, "GPR%02d:", i
);
20437 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
20439 cpu_fprintf(f
, "\n");
20442 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
20443 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
20444 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20446 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
20447 cpu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
20448 env
->CP0_Config2
, env
->CP0_Config3
);
20449 cpu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
20450 env
->CP0_Config4
, env
->CP0_Config5
);
20451 if (env
->hflags
& MIPS_HFLAG_FPU
)
20452 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
20453 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
20454 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
20458 void mips_tcg_init(void)
20463 /* Initialize various static tables. */
20467 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
20468 TCGV_UNUSED(cpu_gpr
[0]);
20469 for (i
= 1; i
< 32; i
++)
20470 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
20471 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
20474 for (i
= 0; i
< 32; i
++) {
20475 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
20477 tcg_global_mem_new_i64(TCG_AREG0
, off
, msaregnames
[i
* 2]);
20478 /* The scalar floating-point unit (FPU) registers are mapped on
20479 * the MSA vector registers. */
20480 fpu_f64
[i
] = msa_wr_d
[i
* 2];
20481 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
20482 msa_wr_d
[i
* 2 + 1] =
20483 tcg_global_mem_new_i64(TCG_AREG0
, off
, msaregnames
[i
* 2 + 1]);
20486 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
20487 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
20488 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
20489 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
20490 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
20492 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
20493 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
20496 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
20497 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
20499 bcond
= tcg_global_mem_new(TCG_AREG0
,
20500 offsetof(CPUMIPSState
, bcond
), "bcond");
20501 btarget
= tcg_global_mem_new(TCG_AREG0
,
20502 offsetof(CPUMIPSState
, btarget
), "btarget");
20503 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
20504 offsetof(CPUMIPSState
, hflags
), "hflags");
20506 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
20507 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
20509 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
20510 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
20516 #include "translate_init.c"
20518 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
20522 const mips_def_t
*def
;
20524 def
= cpu_mips_find_by_name(cpu_model
);
20527 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
20529 env
->cpu_model
= def
;
20531 #ifndef CONFIG_USER_ONLY
20532 mmu_init(env
, def
);
20534 fpu_init(env
, def
);
20535 mvp_init(env
, def
);
20537 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
20542 void cpu_state_reset(CPUMIPSState
*env
)
20544 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
20545 CPUState
*cs
= CPU(cpu
);
20547 /* Reset registers to their default values */
20548 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
20549 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
20550 #ifdef TARGET_WORDS_BIGENDIAN
20551 env
->CP0_Config0
|= (1 << CP0C0_BE
);
20553 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
20554 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
20555 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
20556 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
20557 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
20558 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
20559 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
20560 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
20561 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
20562 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
20563 << env
->cpu_model
->CP0_LLAddr_shift
;
20564 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
20565 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
20566 env
->CCRes
= env
->cpu_model
->CCRes
;
20567 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
20568 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
20569 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
20570 env
->current_tc
= 0;
20571 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
20572 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
20573 #if defined(TARGET_MIPS64)
20574 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
20575 env
->SEGMask
|= 3ULL << 62;
20578 env
->PABITS
= env
->cpu_model
->PABITS
;
20579 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
20580 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
20581 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
20582 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
20583 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
20584 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
20585 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
20586 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
20587 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
20588 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
20589 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
20590 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
20591 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
20592 env
->msair
= env
->cpu_model
->MSAIR
;
20593 env
->insn_flags
= env
->cpu_model
->insn_flags
;
20595 #if defined(CONFIG_USER_ONLY)
20596 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
20597 # ifdef TARGET_MIPS64
20598 /* Enable 64-bit register mode. */
20599 env
->CP0_Status
|= (1 << CP0St_PX
);
20601 # ifdef TARGET_ABI_MIPSN64
20602 /* Enable 64-bit address mode. */
20603 env
->CP0_Status
|= (1 << CP0St_UX
);
20605 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20606 hardware registers. */
20607 env
->CP0_HWREna
|= 0x0000000F;
20608 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
20609 env
->CP0_Status
|= (1 << CP0St_CU1
);
20611 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
20612 env
->CP0_Status
|= (1 << CP0St_MX
);
20614 # if defined(TARGET_MIPS64)
20615 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20616 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
20617 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
20618 env
->CP0_Status
|= (1 << CP0St_FR
);
20622 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
20623 /* If the exception was raised from a delay slot,
20624 come back to the jump. */
20625 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
20626 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
20628 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
20630 env
->active_tc
.PC
= (int32_t)0xBFC00000;
20631 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
20632 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
20633 env
->CP0_Wired
= 0;
20634 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
20635 if (kvm_enabled()) {
20636 env
->CP0_EBase
|= 0x40000000;
20638 env
->CP0_EBase
|= 0x80000000;
20640 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
20641 /* vectored interrupts not implemented, timer on int 7,
20642 no performance counters. */
20643 env
->CP0_IntCtl
= 0xe0000000;
20647 for (i
= 0; i
< 7; i
++) {
20648 env
->CP0_WatchLo
[i
] = 0;
20649 env
->CP0_WatchHi
[i
] = 0x80000000;
20651 env
->CP0_WatchLo
[7] = 0;
20652 env
->CP0_WatchHi
[7] = 0;
20654 /* Count register increments in debug mode, EJTAG version 1 */
20655 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
20657 cpu_mips_store_count(env
, 1);
20659 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
20662 /* Only TC0 on VPE 0 starts as active. */
20663 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
20664 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
20665 env
->tcs
[i
].CP0_TCHalt
= 1;
20667 env
->active_tc
.CP0_TCHalt
= 1;
20670 if (cs
->cpu_index
== 0) {
20671 /* VPE0 starts up enabled. */
20672 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
20673 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
20675 /* TC0 starts up unhalted. */
20677 env
->active_tc
.CP0_TCHalt
= 0;
20678 env
->tcs
[0].CP0_TCHalt
= 0;
20679 /* With thread 0 active. */
20680 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
20681 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
20685 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
20686 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
20687 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20688 env
->CP0_Status
|= (1 << CP0St_FR
);
20692 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
20696 compute_hflags(env
);
20697 restore_rounding_mode(env
);
20698 restore_flush_mode(env
);
20699 restore_pamask(env
);
20700 cs
->exception_index
= EXCP_NONE
;
20702 if (semihosting_get_argc()) {
20703 /* UHI interface can be used to obtain argc and argv */
20704 env
->active_tc
.gpr
[4] = -1;
20708 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
20710 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
20711 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
20712 env
->hflags
|= gen_opc_hflags
[pc_pos
];
20713 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
20714 case MIPS_HFLAG_BR
:
20716 case MIPS_HFLAG_BC
:
20717 case MIPS_HFLAG_BL
:
20719 env
->btarget
= gen_opc_btarget
[pc_pos
];