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
);
4753 if (lsb
+ msb
> 31) {
4756 tcg_gen_shri_tl(t0
, t1
, lsb
);
4758 tcg_gen_andi_tl(t0
, t0
, (1U << (msb
+ 1)) - 1);
4760 tcg_gen_ext32s_tl(t0
, t0
);
4763 #if defined(TARGET_MIPS64)
4772 if (lsb
+ msb
> 63) {
4775 tcg_gen_shri_tl(t0
, t1
, lsb
);
4777 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4785 gen_load_gpr(t0
, rt
);
4786 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4787 tcg_gen_ext32s_tl(t0
, t0
);
4789 #if defined(TARGET_MIPS64)
4800 gen_load_gpr(t0
, rt
);
4801 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4806 MIPS_INVAL("bitops");
4807 generate_exception(ctx
, EXCP_RI
);
4812 gen_store_gpr(t0
, rt
);
4817 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4822 /* If no destination, treat it as a NOP. */
4827 t0
= tcg_temp_new();
4828 gen_load_gpr(t0
, rt
);
4832 TCGv t1
= tcg_temp_new();
4834 tcg_gen_shri_tl(t1
, t0
, 8);
4835 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4836 tcg_gen_shli_tl(t0
, t0
, 8);
4837 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4838 tcg_gen_or_tl(t0
, t0
, t1
);
4840 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4844 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4847 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4849 #if defined(TARGET_MIPS64)
4852 TCGv t1
= tcg_temp_new();
4854 tcg_gen_shri_tl(t1
, t0
, 8);
4855 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4856 tcg_gen_shli_tl(t0
, t0
, 8);
4857 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4858 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4864 TCGv t1
= tcg_temp_new();
4866 tcg_gen_shri_tl(t1
, t0
, 16);
4867 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4868 tcg_gen_shli_tl(t0
, t0
, 16);
4869 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4870 tcg_gen_or_tl(t0
, t0
, t1
);
4871 tcg_gen_shri_tl(t1
, t0
, 32);
4872 tcg_gen_shli_tl(t0
, t0
, 32);
4873 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4879 MIPS_INVAL("bsfhl");
4880 generate_exception(ctx
, EXCP_RI
);
4887 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
4896 t0
= tcg_temp_new();
4897 t1
= tcg_temp_new();
4898 gen_load_gpr(t0
, rs
);
4899 gen_load_gpr(t1
, rt
);
4900 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
4901 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
4902 if (opc
== OPC_LSA
) {
4903 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4912 static void gen_align(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
4920 t0
= tcg_temp_new();
4921 gen_load_gpr(t0
, rt
);
4923 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4925 TCGv t1
= tcg_temp_new();
4926 gen_load_gpr(t1
, rs
);
4930 TCGv_i64 t2
= tcg_temp_new_i64();
4931 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
4932 tcg_gen_shri_i64(t2
, t2
, 8 * (4 - bp
));
4933 gen_move_low32(cpu_gpr
[rd
], t2
);
4934 tcg_temp_free_i64(t2
);
4937 #if defined(TARGET_MIPS64)
4939 tcg_gen_shli_tl(t0
, t0
, 8 * bp
);
4940 tcg_gen_shri_tl(t1
, t1
, 8 * (8 - bp
));
4941 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
4951 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
4958 t0
= tcg_temp_new();
4959 gen_load_gpr(t0
, rt
);
4962 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
4964 #if defined(TARGET_MIPS64)
4966 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
4973 #ifndef CONFIG_USER_ONLY
4974 /* CP0 (MMU and control) */
4975 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
4977 TCGv_i64 t0
= tcg_temp_new_i64();
4978 TCGv_i64 t1
= tcg_temp_new_i64();
4980 tcg_gen_ext_tl_i64(t0
, arg
);
4981 tcg_gen_ld_i64(t1
, cpu_env
, off
);
4982 #if defined(TARGET_MIPS64)
4983 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
4985 tcg_gen_concat32_i64(t1
, t1
, t0
);
4987 tcg_gen_st_i64(t1
, cpu_env
, off
);
4988 tcg_temp_free_i64(t1
);
4989 tcg_temp_free_i64(t0
);
4992 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
4994 TCGv_i64 t0
= tcg_temp_new_i64();
4995 TCGv_i64 t1
= tcg_temp_new_i64();
4997 tcg_gen_ext_tl_i64(t0
, arg
);
4998 tcg_gen_ld_i64(t1
, cpu_env
, off
);
4999 tcg_gen_concat32_i64(t1
, t1
, t0
);
5000 tcg_gen_st_i64(t1
, cpu_env
, off
);
5001 tcg_temp_free_i64(t1
);
5002 tcg_temp_free_i64(t0
);
5005 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
5007 TCGv_i64 t0
= tcg_temp_new_i64();
5009 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5010 #if defined(TARGET_MIPS64)
5011 tcg_gen_shri_i64(t0
, t0
, 30);
5013 tcg_gen_shri_i64(t0
, t0
, 32);
5015 gen_move_low32(arg
, t0
);
5016 tcg_temp_free_i64(t0
);
5019 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
5021 TCGv_i64 t0
= tcg_temp_new_i64();
5023 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5024 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
5025 gen_move_low32(arg
, t0
);
5026 tcg_temp_free_i64(t0
);
5029 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
5031 TCGv_i32 t0
= tcg_temp_new_i32();
5033 tcg_gen_ld_i32(t0
, cpu_env
, off
);
5034 tcg_gen_ext_i32_tl(arg
, t0
);
5035 tcg_temp_free_i32(t0
);
5038 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
5040 tcg_gen_ld_tl(arg
, cpu_env
, off
);
5041 tcg_gen_ext32s_tl(arg
, arg
);
5044 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
5046 TCGv_i32 t0
= tcg_temp_new_i32();
5048 tcg_gen_trunc_tl_i32(t0
, arg
);
5049 tcg_gen_st_i32(t0
, cpu_env
, off
);
5050 tcg_temp_free_i32(t0
);
5053 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
5055 tcg_gen_ext32s_tl(arg
, arg
);
5056 tcg_gen_st_tl(arg
, cpu_env
, off
);
5059 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5061 const char *rn
= "invalid";
5063 if (!(ctx
->hflags
& MIPS_HFLAG_ELPA
)) {
5064 goto mfhc0_read_zero
;
5071 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5075 goto mfhc0_read_zero
;
5081 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5085 goto mfhc0_read_zero
;
5091 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, lladdr
),
5092 ctx
->CP0_LLAddr_shift
);
5096 goto mfhc0_read_zero
;
5105 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
5109 goto mfhc0_read_zero
;
5113 goto mfhc0_read_zero
;
5116 (void)rn
; /* avoid a compiler warning */
5117 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5121 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5122 tcg_gen_movi_tl(arg
, 0);
5125 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5127 const char *rn
= "invalid";
5128 uint64_t mask
= ctx
->PAMask
>> 36;
5130 if (!(ctx
->hflags
& MIPS_HFLAG_ELPA
)) {
5138 tcg_gen_andi_tl(arg
, arg
, mask
);
5139 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5149 tcg_gen_andi_tl(arg
, arg
, mask
);
5150 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5160 /* LLAddr is read-only (the only exception is bit 0 if LLB is
5161 supported); the CP0_LLAddr_rw_bitmask does not seem to be
5162 relevant for modern MIPS cores supporting MTHC0, therefore
5163 treating MTHC0 to LLAddr as NOP. */
5176 tcg_gen_andi_tl(arg
, arg
, mask
);
5177 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5188 (void)rn
; /* avoid a compiler warning */
5190 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5193 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
5195 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
5196 tcg_gen_movi_tl(arg
, 0);
5198 tcg_gen_movi_tl(arg
, ~0);
5202 #define CP0_CHECK(c) \
5205 goto cp0_unimplemented; \
5209 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5211 const char *rn
= "invalid";
5214 check_insn(ctx
, ISA_MIPS32
);
5220 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5224 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5225 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5229 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5230 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5234 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5235 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5239 goto cp0_unimplemented
;
5245 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5246 gen_helper_mfc0_random(arg
, cpu_env
);
5250 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5251 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5255 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5256 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5260 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5265 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5266 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
5270 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5271 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5275 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5276 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5277 rn
= "VPEScheFBack";
5280 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5281 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5285 goto cp0_unimplemented
;
5292 TCGv_i64 tmp
= tcg_temp_new_i64();
5293 tcg_gen_ld_i64(tmp
, cpu_env
,
5294 offsetof(CPUMIPSState
, CP0_EntryLo0
));
5295 #if defined(TARGET_MIPS64)
5297 /* Move RI/XI fields to bits 31:30 */
5298 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
5299 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
5302 gen_move_low32(arg
, tmp
);
5303 tcg_temp_free_i64(tmp
);
5308 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5309 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5313 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5314 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5318 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5319 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
5323 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5324 gen_helper_mfc0_tchalt(arg
, cpu_env
);
5328 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5329 gen_helper_mfc0_tccontext(arg
, cpu_env
);
5333 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5334 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
5338 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5339 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
5343 goto cp0_unimplemented
;
5350 TCGv_i64 tmp
= tcg_temp_new_i64();
5351 tcg_gen_ld_i64(tmp
, cpu_env
,
5352 offsetof(CPUMIPSState
, CP0_EntryLo1
));
5353 #if defined(TARGET_MIPS64)
5355 /* Move RI/XI fields to bits 31:30 */
5356 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
5357 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
5360 gen_move_low32(arg
, tmp
);
5361 tcg_temp_free_i64(tmp
);
5366 goto cp0_unimplemented
;
5372 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5373 tcg_gen_ext32s_tl(arg
, arg
);
5377 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5378 rn
= "ContextConfig";
5379 goto cp0_unimplemented
;
5382 CP0_CHECK(ctx
->ulri
);
5383 tcg_gen_ld32s_tl(arg
, cpu_env
,
5384 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5388 goto cp0_unimplemented
;
5394 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5398 check_insn(ctx
, ISA_MIPS32R2
);
5399 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5403 goto cp0_unimplemented
;
5409 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5413 check_insn(ctx
, ISA_MIPS32R2
);
5414 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5418 check_insn(ctx
, ISA_MIPS32R2
);
5419 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5423 check_insn(ctx
, ISA_MIPS32R2
);
5424 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5428 check_insn(ctx
, ISA_MIPS32R2
);
5429 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5433 check_insn(ctx
, ISA_MIPS32R2
);
5434 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5438 goto cp0_unimplemented
;
5444 check_insn(ctx
, ISA_MIPS32R2
);
5445 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5449 goto cp0_unimplemented
;
5455 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5456 tcg_gen_ext32s_tl(arg
, arg
);
5461 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
5466 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
5470 goto cp0_unimplemented
;
5476 /* Mark as an IO operation because we read the time. */
5477 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5480 gen_helper_mfc0_count(arg
, cpu_env
);
5481 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5484 /* Break the TB to be able to take timer interrupts immediately
5485 after reading count. */
5486 ctx
->bstate
= BS_STOP
;
5489 /* 6,7 are implementation dependent */
5491 goto cp0_unimplemented
;
5497 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5498 tcg_gen_ext32s_tl(arg
, arg
);
5502 goto cp0_unimplemented
;
5508 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5511 /* 6,7 are implementation dependent */
5513 goto cp0_unimplemented
;
5519 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5523 check_insn(ctx
, ISA_MIPS32R2
);
5524 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5528 check_insn(ctx
, ISA_MIPS32R2
);
5529 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5533 check_insn(ctx
, ISA_MIPS32R2
);
5534 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5538 goto cp0_unimplemented
;
5544 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5548 goto cp0_unimplemented
;
5554 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5555 tcg_gen_ext32s_tl(arg
, arg
);
5559 goto cp0_unimplemented
;
5565 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5569 check_insn(ctx
, ISA_MIPS32R2
);
5570 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5574 goto cp0_unimplemented
;
5580 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5584 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5588 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5592 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5596 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
5600 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
5603 /* 6,7 are implementation dependent */
5605 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5609 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5613 goto cp0_unimplemented
;
5619 gen_helper_mfc0_lladdr(arg
, cpu_env
);
5623 goto cp0_unimplemented
;
5629 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
5633 goto cp0_unimplemented
;
5639 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5643 goto cp0_unimplemented
;
5649 #if defined(TARGET_MIPS64)
5650 check_insn(ctx
, ISA_MIPS3
);
5651 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5652 tcg_gen_ext32s_tl(arg
, arg
);
5657 goto cp0_unimplemented
;
5661 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5662 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5665 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5669 goto cp0_unimplemented
;
5673 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5674 rn
= "'Diagnostic"; /* implementation dependent */
5679 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5683 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5684 rn
= "TraceControl";
5687 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5688 rn
= "TraceControl2";
5691 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5692 rn
= "UserTraceData";
5695 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5699 goto cp0_unimplemented
;
5706 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5707 tcg_gen_ext32s_tl(arg
, arg
);
5711 goto cp0_unimplemented
;
5717 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5718 rn
= "Performance0";
5721 // gen_helper_mfc0_performance1(arg);
5722 rn
= "Performance1";
5725 // gen_helper_mfc0_performance2(arg);
5726 rn
= "Performance2";
5729 // gen_helper_mfc0_performance3(arg);
5730 rn
= "Performance3";
5733 // gen_helper_mfc0_performance4(arg);
5734 rn
= "Performance4";
5737 // gen_helper_mfc0_performance5(arg);
5738 rn
= "Performance5";
5741 // gen_helper_mfc0_performance6(arg);
5742 rn
= "Performance6";
5745 // gen_helper_mfc0_performance7(arg);
5746 rn
= "Performance7";
5749 goto cp0_unimplemented
;
5753 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5759 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5763 goto cp0_unimplemented
;
5773 TCGv_i64 tmp
= tcg_temp_new_i64();
5774 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
5775 gen_move_low32(arg
, tmp
);
5776 tcg_temp_free_i64(tmp
);
5784 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5788 goto cp0_unimplemented
;
5797 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5804 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5808 goto cp0_unimplemented
;
5814 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5815 tcg_gen_ext32s_tl(arg
, arg
);
5819 goto cp0_unimplemented
;
5826 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5830 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
5831 tcg_gen_ld_tl(arg
, cpu_env
,
5832 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
5833 tcg_gen_ext32s_tl(arg
, arg
);
5837 goto cp0_unimplemented
;
5841 goto cp0_unimplemented
;
5843 (void)rn
; /* avoid a compiler warning */
5844 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5848 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5849 gen_mfc0_unimplemented(ctx
, arg
);
5852 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5854 const char *rn
= "invalid";
5857 check_insn(ctx
, ISA_MIPS32
);
5859 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5867 gen_helper_mtc0_index(cpu_env
, arg
);
5871 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5872 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5876 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5881 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5886 goto cp0_unimplemented
;
5896 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5897 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5901 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5902 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5906 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5907 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5911 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5912 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5916 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5917 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5921 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5922 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5923 rn
= "VPEScheFBack";
5926 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5927 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5931 goto cp0_unimplemented
;
5937 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5941 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5942 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5946 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5947 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5951 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5952 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5956 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5957 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5961 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5962 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5966 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5967 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5971 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5972 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5976 goto cp0_unimplemented
;
5982 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5986 goto cp0_unimplemented
;
5992 gen_helper_mtc0_context(cpu_env
, arg
);
5996 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5997 rn
= "ContextConfig";
5998 goto cp0_unimplemented
;
6001 CP0_CHECK(ctx
->ulri
);
6002 tcg_gen_st_tl(arg
, cpu_env
,
6003 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6007 goto cp0_unimplemented
;
6013 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6017 check_insn(ctx
, ISA_MIPS32R2
);
6018 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6020 ctx
->bstate
= BS_STOP
;
6023 goto cp0_unimplemented
;
6029 gen_helper_mtc0_wired(cpu_env
, arg
);
6033 check_insn(ctx
, ISA_MIPS32R2
);
6034 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6038 check_insn(ctx
, ISA_MIPS32R2
);
6039 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6043 check_insn(ctx
, ISA_MIPS32R2
);
6044 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6048 check_insn(ctx
, ISA_MIPS32R2
);
6049 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6053 check_insn(ctx
, ISA_MIPS32R2
);
6054 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6058 goto cp0_unimplemented
;
6064 check_insn(ctx
, ISA_MIPS32R2
);
6065 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6066 ctx
->bstate
= BS_STOP
;
6070 goto cp0_unimplemented
;
6088 goto cp0_unimplemented
;
6094 gen_helper_mtc0_count(cpu_env
, arg
);
6097 /* 6,7 are implementation dependent */
6099 goto cp0_unimplemented
;
6105 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6109 goto cp0_unimplemented
;
6115 gen_helper_mtc0_compare(cpu_env
, arg
);
6118 /* 6,7 are implementation dependent */
6120 goto cp0_unimplemented
;
6126 save_cpu_state(ctx
, 1);
6127 gen_helper_mtc0_status(cpu_env
, arg
);
6128 /* BS_STOP isn't good enough here, hflags may have changed. */
6129 gen_save_pc(ctx
->pc
+ 4);
6130 ctx
->bstate
= BS_EXCP
;
6134 check_insn(ctx
, ISA_MIPS32R2
);
6135 gen_helper_mtc0_intctl(cpu_env
, arg
);
6136 /* Stop translation as we may have switched the execution mode */
6137 ctx
->bstate
= BS_STOP
;
6141 check_insn(ctx
, ISA_MIPS32R2
);
6142 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6143 /* Stop translation as we may have switched the execution mode */
6144 ctx
->bstate
= BS_STOP
;
6148 check_insn(ctx
, ISA_MIPS32R2
);
6149 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6150 /* Stop translation as we may have switched the execution mode */
6151 ctx
->bstate
= BS_STOP
;
6155 goto cp0_unimplemented
;
6161 save_cpu_state(ctx
, 1);
6162 gen_helper_mtc0_cause(cpu_env
, arg
);
6166 goto cp0_unimplemented
;
6172 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
6176 goto cp0_unimplemented
;
6186 check_insn(ctx
, ISA_MIPS32R2
);
6187 gen_helper_mtc0_ebase(cpu_env
, arg
);
6191 goto cp0_unimplemented
;
6197 gen_helper_mtc0_config0(cpu_env
, arg
);
6199 /* Stop translation as we may have switched the execution mode */
6200 ctx
->bstate
= BS_STOP
;
6203 /* ignored, read only */
6207 gen_helper_mtc0_config2(cpu_env
, arg
);
6209 /* Stop translation as we may have switched the execution mode */
6210 ctx
->bstate
= BS_STOP
;
6213 gen_helper_mtc0_config3(cpu_env
, arg
);
6215 /* Stop translation as we may have switched the execution mode */
6216 ctx
->bstate
= BS_STOP
;
6219 gen_helper_mtc0_config4(cpu_env
, arg
);
6221 ctx
->bstate
= BS_STOP
;
6224 gen_helper_mtc0_config5(cpu_env
, arg
);
6226 /* Stop translation as we may have switched the execution mode */
6227 ctx
->bstate
= BS_STOP
;
6229 /* 6,7 are implementation dependent */
6239 rn
= "Invalid config selector";
6240 goto cp0_unimplemented
;
6246 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6250 goto cp0_unimplemented
;
6256 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6260 goto cp0_unimplemented
;
6266 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6270 goto cp0_unimplemented
;
6276 #if defined(TARGET_MIPS64)
6277 check_insn(ctx
, ISA_MIPS3
);
6278 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6283 goto cp0_unimplemented
;
6287 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6288 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6291 gen_helper_mtc0_framemask(cpu_env
, arg
);
6295 goto cp0_unimplemented
;
6300 rn
= "Diagnostic"; /* implementation dependent */
6305 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6306 /* BS_STOP isn't good enough here, hflags may have changed. */
6307 gen_save_pc(ctx
->pc
+ 4);
6308 ctx
->bstate
= BS_EXCP
;
6312 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6313 rn
= "TraceControl";
6314 /* Stop translation as we may have switched the execution mode */
6315 ctx
->bstate
= BS_STOP
;
6318 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6319 rn
= "TraceControl2";
6320 /* Stop translation as we may have switched the execution mode */
6321 ctx
->bstate
= BS_STOP
;
6324 /* Stop translation as we may have switched the execution mode */
6325 ctx
->bstate
= BS_STOP
;
6326 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6327 rn
= "UserTraceData";
6328 /* Stop translation as we may have switched the execution mode */
6329 ctx
->bstate
= BS_STOP
;
6332 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6333 /* Stop translation as we may have switched the execution mode */
6334 ctx
->bstate
= BS_STOP
;
6338 goto cp0_unimplemented
;
6345 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
6349 goto cp0_unimplemented
;
6355 gen_helper_mtc0_performance0(cpu_env
, arg
);
6356 rn
= "Performance0";
6359 // gen_helper_mtc0_performance1(arg);
6360 rn
= "Performance1";
6363 // gen_helper_mtc0_performance2(arg);
6364 rn
= "Performance2";
6367 // gen_helper_mtc0_performance3(arg);
6368 rn
= "Performance3";
6371 // gen_helper_mtc0_performance4(arg);
6372 rn
= "Performance4";
6375 // gen_helper_mtc0_performance5(arg);
6376 rn
= "Performance5";
6379 // gen_helper_mtc0_performance6(arg);
6380 rn
= "Performance6";
6383 // gen_helper_mtc0_performance7(arg);
6384 rn
= "Performance7";
6387 goto cp0_unimplemented
;
6401 goto cp0_unimplemented
;
6410 gen_helper_mtc0_taglo(cpu_env
, arg
);
6417 gen_helper_mtc0_datalo(cpu_env
, arg
);
6421 goto cp0_unimplemented
;
6430 gen_helper_mtc0_taghi(cpu_env
, arg
);
6437 gen_helper_mtc0_datahi(cpu_env
, arg
);
6442 goto cp0_unimplemented
;
6448 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6452 goto cp0_unimplemented
;
6459 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6463 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6464 tcg_gen_st_tl(arg
, cpu_env
,
6465 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6469 goto cp0_unimplemented
;
6471 /* Stop translation as we may have switched the execution mode */
6472 ctx
->bstate
= BS_STOP
;
6475 goto cp0_unimplemented
;
6477 (void)rn
; /* avoid a compiler warning */
6478 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6479 /* For simplicity assume that all writes can cause interrupts. */
6480 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6482 ctx
->bstate
= BS_STOP
;
6487 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6490 #if defined(TARGET_MIPS64)
6491 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6493 const char *rn
= "invalid";
6496 check_insn(ctx
, ISA_MIPS64
);
6502 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6506 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6507 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6511 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6512 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6516 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6517 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6521 goto cp0_unimplemented
;
6527 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6528 gen_helper_mfc0_random(arg
, cpu_env
);
6532 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6533 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6537 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6538 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6542 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6543 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6547 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6548 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
6552 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6553 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6557 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6558 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6559 rn
= "VPEScheFBack";
6562 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6563 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6567 goto cp0_unimplemented
;
6573 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6577 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6578 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6582 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6583 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6587 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6588 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
6592 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6593 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
6597 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6598 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
6602 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6603 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
6607 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6608 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
6612 goto cp0_unimplemented
;
6618 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6622 goto cp0_unimplemented
;
6628 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6632 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6633 rn
= "ContextConfig";
6634 goto cp0_unimplemented
;
6637 CP0_CHECK(ctx
->ulri
);
6638 tcg_gen_ld_tl(arg
, cpu_env
,
6639 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6643 goto cp0_unimplemented
;
6649 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6653 check_insn(ctx
, ISA_MIPS32R2
);
6654 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6658 goto cp0_unimplemented
;
6664 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6668 check_insn(ctx
, ISA_MIPS32R2
);
6669 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6673 check_insn(ctx
, ISA_MIPS32R2
);
6674 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6678 check_insn(ctx
, ISA_MIPS32R2
);
6679 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6683 check_insn(ctx
, ISA_MIPS32R2
);
6684 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6688 check_insn(ctx
, ISA_MIPS32R2
);
6689 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6693 goto cp0_unimplemented
;
6699 check_insn(ctx
, ISA_MIPS32R2
);
6700 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6704 goto cp0_unimplemented
;
6710 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6715 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6720 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6724 goto cp0_unimplemented
;
6730 /* Mark as an IO operation because we read the time. */
6731 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6734 gen_helper_mfc0_count(arg
, cpu_env
);
6735 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6738 /* Break the TB to be able to take timer interrupts immediately
6739 after reading count. */
6740 ctx
->bstate
= BS_STOP
;
6743 /* 6,7 are implementation dependent */
6745 goto cp0_unimplemented
;
6751 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6755 goto cp0_unimplemented
;
6761 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6764 /* 6,7 are implementation dependent */
6766 goto cp0_unimplemented
;
6772 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6776 check_insn(ctx
, ISA_MIPS32R2
);
6777 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6781 check_insn(ctx
, ISA_MIPS32R2
);
6782 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6786 check_insn(ctx
, ISA_MIPS32R2
);
6787 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6791 goto cp0_unimplemented
;
6797 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6801 goto cp0_unimplemented
;
6807 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6811 goto cp0_unimplemented
;
6817 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6821 check_insn(ctx
, ISA_MIPS32R2
);
6822 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
6826 goto cp0_unimplemented
;
6832 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6836 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6840 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6844 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6848 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6852 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6855 /* 6,7 are implementation dependent */
6857 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6861 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6865 goto cp0_unimplemented
;
6871 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
6875 goto cp0_unimplemented
;
6881 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
6885 goto cp0_unimplemented
;
6891 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6895 goto cp0_unimplemented
;
6901 check_insn(ctx
, ISA_MIPS3
);
6902 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6906 goto cp0_unimplemented
;
6910 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6911 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6914 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6918 goto cp0_unimplemented
;
6922 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6923 rn
= "'Diagnostic"; /* implementation dependent */
6928 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6932 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6933 rn
= "TraceControl";
6936 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6937 rn
= "TraceControl2";
6940 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6941 rn
= "UserTraceData";
6944 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6948 goto cp0_unimplemented
;
6955 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6959 goto cp0_unimplemented
;
6965 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6966 rn
= "Performance0";
6969 // gen_helper_dmfc0_performance1(arg);
6970 rn
= "Performance1";
6973 // gen_helper_dmfc0_performance2(arg);
6974 rn
= "Performance2";
6977 // gen_helper_dmfc0_performance3(arg);
6978 rn
= "Performance3";
6981 // gen_helper_dmfc0_performance4(arg);
6982 rn
= "Performance4";
6985 // gen_helper_dmfc0_performance5(arg);
6986 rn
= "Performance5";
6989 // gen_helper_dmfc0_performance6(arg);
6990 rn
= "Performance6";
6993 // gen_helper_dmfc0_performance7(arg);
6994 rn
= "Performance7";
6997 goto cp0_unimplemented
;
7001 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7008 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7012 goto cp0_unimplemented
;
7021 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
7028 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7032 goto cp0_unimplemented
;
7041 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7048 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7052 goto cp0_unimplemented
;
7058 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7062 goto cp0_unimplemented
;
7069 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7073 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7074 tcg_gen_ld_tl(arg
, cpu_env
,
7075 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7079 goto cp0_unimplemented
;
7083 goto cp0_unimplemented
;
7085 (void)rn
; /* avoid a compiler warning */
7086 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7090 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7091 gen_mfc0_unimplemented(ctx
, arg
);
7094 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7096 const char *rn
= "invalid";
7099 check_insn(ctx
, ISA_MIPS64
);
7101 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7109 gen_helper_mtc0_index(cpu_env
, arg
);
7113 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7114 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7118 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7123 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7128 goto cp0_unimplemented
;
7138 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7139 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7143 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7144 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7148 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7149 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7153 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7154 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7158 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7159 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7163 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7164 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7165 rn
= "VPEScheFBack";
7168 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7169 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7173 goto cp0_unimplemented
;
7179 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
7183 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7184 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7188 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7189 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7193 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7194 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7198 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7199 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7203 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7204 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7208 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7209 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7213 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7214 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7218 goto cp0_unimplemented
;
7224 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
7228 goto cp0_unimplemented
;
7234 gen_helper_mtc0_context(cpu_env
, arg
);
7238 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7239 rn
= "ContextConfig";
7240 goto cp0_unimplemented
;
7243 CP0_CHECK(ctx
->ulri
);
7244 tcg_gen_st_tl(arg
, cpu_env
,
7245 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7249 goto cp0_unimplemented
;
7255 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7259 check_insn(ctx
, ISA_MIPS32R2
);
7260 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7264 goto cp0_unimplemented
;
7270 gen_helper_mtc0_wired(cpu_env
, arg
);
7274 check_insn(ctx
, ISA_MIPS32R2
);
7275 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7279 check_insn(ctx
, ISA_MIPS32R2
);
7280 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7284 check_insn(ctx
, ISA_MIPS32R2
);
7285 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7289 check_insn(ctx
, ISA_MIPS32R2
);
7290 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7294 check_insn(ctx
, ISA_MIPS32R2
);
7295 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7299 goto cp0_unimplemented
;
7305 check_insn(ctx
, ISA_MIPS32R2
);
7306 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7307 ctx
->bstate
= BS_STOP
;
7311 goto cp0_unimplemented
;
7329 goto cp0_unimplemented
;
7335 gen_helper_mtc0_count(cpu_env
, arg
);
7338 /* 6,7 are implementation dependent */
7340 goto cp0_unimplemented
;
7342 /* Stop translation as we may have switched the execution mode */
7343 ctx
->bstate
= BS_STOP
;
7348 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7352 goto cp0_unimplemented
;
7358 gen_helper_mtc0_compare(cpu_env
, arg
);
7361 /* 6,7 are implementation dependent */
7363 goto cp0_unimplemented
;
7365 /* Stop translation as we may have switched the execution mode */
7366 ctx
->bstate
= BS_STOP
;
7371 save_cpu_state(ctx
, 1);
7372 gen_helper_mtc0_status(cpu_env
, arg
);
7373 /* BS_STOP isn't good enough here, hflags may have changed. */
7374 gen_save_pc(ctx
->pc
+ 4);
7375 ctx
->bstate
= BS_EXCP
;
7379 check_insn(ctx
, ISA_MIPS32R2
);
7380 gen_helper_mtc0_intctl(cpu_env
, arg
);
7381 /* Stop translation as we may have switched the execution mode */
7382 ctx
->bstate
= BS_STOP
;
7386 check_insn(ctx
, ISA_MIPS32R2
);
7387 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7388 /* Stop translation as we may have switched the execution mode */
7389 ctx
->bstate
= BS_STOP
;
7393 check_insn(ctx
, ISA_MIPS32R2
);
7394 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7395 /* Stop translation as we may have switched the execution mode */
7396 ctx
->bstate
= BS_STOP
;
7400 goto cp0_unimplemented
;
7406 save_cpu_state(ctx
, 1);
7407 /* Mark as an IO operation because we may trigger a software
7409 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7412 gen_helper_mtc0_cause(cpu_env
, arg
);
7413 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7416 /* Stop translation as we may have triggered an intetrupt */
7417 ctx
->bstate
= BS_STOP
;
7421 goto cp0_unimplemented
;
7427 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7431 goto cp0_unimplemented
;
7441 check_insn(ctx
, ISA_MIPS32R2
);
7442 gen_helper_mtc0_ebase(cpu_env
, arg
);
7446 goto cp0_unimplemented
;
7452 gen_helper_mtc0_config0(cpu_env
, arg
);
7454 /* Stop translation as we may have switched the execution mode */
7455 ctx
->bstate
= BS_STOP
;
7458 /* ignored, read only */
7462 gen_helper_mtc0_config2(cpu_env
, arg
);
7464 /* Stop translation as we may have switched the execution mode */
7465 ctx
->bstate
= BS_STOP
;
7468 gen_helper_mtc0_config3(cpu_env
, arg
);
7470 /* Stop translation as we may have switched the execution mode */
7471 ctx
->bstate
= BS_STOP
;
7474 /* currently ignored */
7478 gen_helper_mtc0_config5(cpu_env
, arg
);
7480 /* Stop translation as we may have switched the execution mode */
7481 ctx
->bstate
= BS_STOP
;
7483 /* 6,7 are implementation dependent */
7485 rn
= "Invalid config selector";
7486 goto cp0_unimplemented
;
7492 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7496 goto cp0_unimplemented
;
7502 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7506 goto cp0_unimplemented
;
7512 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7516 goto cp0_unimplemented
;
7522 check_insn(ctx
, ISA_MIPS3
);
7523 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7527 goto cp0_unimplemented
;
7531 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7532 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7535 gen_helper_mtc0_framemask(cpu_env
, arg
);
7539 goto cp0_unimplemented
;
7544 rn
= "Diagnostic"; /* implementation dependent */
7549 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7550 /* BS_STOP isn't good enough here, hflags may have changed. */
7551 gen_save_pc(ctx
->pc
+ 4);
7552 ctx
->bstate
= BS_EXCP
;
7556 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7557 /* Stop translation as we may have switched the execution mode */
7558 ctx
->bstate
= BS_STOP
;
7559 rn
= "TraceControl";
7562 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7563 /* Stop translation as we may have switched the execution mode */
7564 ctx
->bstate
= BS_STOP
;
7565 rn
= "TraceControl2";
7568 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7569 /* Stop translation as we may have switched the execution mode */
7570 ctx
->bstate
= BS_STOP
;
7571 rn
= "UserTraceData";
7574 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7575 /* Stop translation as we may have switched the execution mode */
7576 ctx
->bstate
= BS_STOP
;
7580 goto cp0_unimplemented
;
7587 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7591 goto cp0_unimplemented
;
7597 gen_helper_mtc0_performance0(cpu_env
, arg
);
7598 rn
= "Performance0";
7601 // gen_helper_mtc0_performance1(cpu_env, arg);
7602 rn
= "Performance1";
7605 // gen_helper_mtc0_performance2(cpu_env, arg);
7606 rn
= "Performance2";
7609 // gen_helper_mtc0_performance3(cpu_env, arg);
7610 rn
= "Performance3";
7613 // gen_helper_mtc0_performance4(cpu_env, arg);
7614 rn
= "Performance4";
7617 // gen_helper_mtc0_performance5(cpu_env, arg);
7618 rn
= "Performance5";
7621 // gen_helper_mtc0_performance6(cpu_env, arg);
7622 rn
= "Performance6";
7625 // gen_helper_mtc0_performance7(cpu_env, arg);
7626 rn
= "Performance7";
7629 goto cp0_unimplemented
;
7643 goto cp0_unimplemented
;
7652 gen_helper_mtc0_taglo(cpu_env
, arg
);
7659 gen_helper_mtc0_datalo(cpu_env
, arg
);
7663 goto cp0_unimplemented
;
7672 gen_helper_mtc0_taghi(cpu_env
, arg
);
7679 gen_helper_mtc0_datahi(cpu_env
, arg
);
7684 goto cp0_unimplemented
;
7690 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7694 goto cp0_unimplemented
;
7701 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7705 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7706 tcg_gen_st_tl(arg
, cpu_env
,
7707 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7711 goto cp0_unimplemented
;
7713 /* Stop translation as we may have switched the execution mode */
7714 ctx
->bstate
= BS_STOP
;
7717 goto cp0_unimplemented
;
7719 (void)rn
; /* avoid a compiler warning */
7720 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7721 /* For simplicity assume that all writes can cause interrupts. */
7722 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7724 ctx
->bstate
= BS_STOP
;
7729 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7731 #endif /* TARGET_MIPS64 */
7733 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
7734 int u
, int sel
, int h
)
7736 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7737 TCGv t0
= tcg_temp_local_new();
7739 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7740 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7741 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7742 tcg_gen_movi_tl(t0
, -1);
7743 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7744 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7745 tcg_gen_movi_tl(t0
, -1);
7751 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
7754 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
7764 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
7767 gen_helper_mftc0_tcbind(t0
, cpu_env
);
7770 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
7773 gen_helper_mftc0_tchalt(t0
, cpu_env
);
7776 gen_helper_mftc0_tccontext(t0
, cpu_env
);
7779 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
7782 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
7785 gen_mfc0(ctx
, t0
, rt
, sel
);
7792 gen_helper_mftc0_entryhi(t0
, cpu_env
);
7795 gen_mfc0(ctx
, t0
, rt
, sel
);
7801 gen_helper_mftc0_status(t0
, cpu_env
);
7804 gen_mfc0(ctx
, t0
, rt
, sel
);
7810 gen_helper_mftc0_cause(t0
, cpu_env
);
7820 gen_helper_mftc0_epc(t0
, cpu_env
);
7830 gen_helper_mftc0_ebase(t0
, cpu_env
);
7840 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
7850 gen_helper_mftc0_debug(t0
, cpu_env
);
7853 gen_mfc0(ctx
, t0
, rt
, sel
);
7858 gen_mfc0(ctx
, t0
, rt
, sel
);
7860 } else switch (sel
) {
7861 /* GPR registers. */
7863 gen_helper_1e0i(mftgpr
, t0
, rt
);
7865 /* Auxiliary CPU registers */
7869 gen_helper_1e0i(mftlo
, t0
, 0);
7872 gen_helper_1e0i(mfthi
, t0
, 0);
7875 gen_helper_1e0i(mftacx
, t0
, 0);
7878 gen_helper_1e0i(mftlo
, t0
, 1);
7881 gen_helper_1e0i(mfthi
, t0
, 1);
7884 gen_helper_1e0i(mftacx
, t0
, 1);
7887 gen_helper_1e0i(mftlo
, t0
, 2);
7890 gen_helper_1e0i(mfthi
, t0
, 2);
7893 gen_helper_1e0i(mftacx
, t0
, 2);
7896 gen_helper_1e0i(mftlo
, t0
, 3);
7899 gen_helper_1e0i(mfthi
, t0
, 3);
7902 gen_helper_1e0i(mftacx
, t0
, 3);
7905 gen_helper_mftdsp(t0
, cpu_env
);
7911 /* Floating point (COP1). */
7913 /* XXX: For now we support only a single FPU context. */
7915 TCGv_i32 fp0
= tcg_temp_new_i32();
7917 gen_load_fpr32(ctx
, fp0
, rt
);
7918 tcg_gen_ext_i32_tl(t0
, fp0
);
7919 tcg_temp_free_i32(fp0
);
7921 TCGv_i32 fp0
= tcg_temp_new_i32();
7923 gen_load_fpr32h(ctx
, fp0
, rt
);
7924 tcg_gen_ext_i32_tl(t0
, fp0
);
7925 tcg_temp_free_i32(fp0
);
7929 /* XXX: For now we support only a single FPU context. */
7930 gen_helper_1e0i(cfc1
, t0
, rt
);
7932 /* COP2: Not implemented. */
7939 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7940 gen_store_gpr(t0
, rd
);
7946 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7947 generate_exception(ctx
, EXCP_RI
);
7950 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
7951 int u
, int sel
, int h
)
7953 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7954 TCGv t0
= tcg_temp_local_new();
7956 gen_load_gpr(t0
, rt
);
7957 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7958 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7959 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7961 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7962 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7969 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
7972 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
7982 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
7985 gen_helper_mttc0_tcbind(cpu_env
, t0
);
7988 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
7991 gen_helper_mttc0_tchalt(cpu_env
, t0
);
7994 gen_helper_mttc0_tccontext(cpu_env
, t0
);
7997 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
8000 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
8003 gen_mtc0(ctx
, t0
, rd
, sel
);
8010 gen_helper_mttc0_entryhi(cpu_env
, t0
);
8013 gen_mtc0(ctx
, t0
, rd
, sel
);
8019 gen_helper_mttc0_status(cpu_env
, t0
);
8022 gen_mtc0(ctx
, t0
, rd
, sel
);
8028 gen_helper_mttc0_cause(cpu_env
, t0
);
8038 gen_helper_mttc0_ebase(cpu_env
, t0
);
8048 gen_helper_mttc0_debug(cpu_env
, t0
);
8051 gen_mtc0(ctx
, t0
, rd
, sel
);
8056 gen_mtc0(ctx
, t0
, rd
, sel
);
8058 } else switch (sel
) {
8059 /* GPR registers. */
8061 gen_helper_0e1i(mttgpr
, t0
, rd
);
8063 /* Auxiliary CPU registers */
8067 gen_helper_0e1i(mttlo
, t0
, 0);
8070 gen_helper_0e1i(mtthi
, t0
, 0);
8073 gen_helper_0e1i(mttacx
, t0
, 0);
8076 gen_helper_0e1i(mttlo
, t0
, 1);
8079 gen_helper_0e1i(mtthi
, t0
, 1);
8082 gen_helper_0e1i(mttacx
, t0
, 1);
8085 gen_helper_0e1i(mttlo
, t0
, 2);
8088 gen_helper_0e1i(mtthi
, t0
, 2);
8091 gen_helper_0e1i(mttacx
, t0
, 2);
8094 gen_helper_0e1i(mttlo
, t0
, 3);
8097 gen_helper_0e1i(mtthi
, t0
, 3);
8100 gen_helper_0e1i(mttacx
, t0
, 3);
8103 gen_helper_mttdsp(cpu_env
, t0
);
8109 /* Floating point (COP1). */
8111 /* XXX: For now we support only a single FPU context. */
8113 TCGv_i32 fp0
= tcg_temp_new_i32();
8115 tcg_gen_trunc_tl_i32(fp0
, t0
);
8116 gen_store_fpr32(ctx
, fp0
, rd
);
8117 tcg_temp_free_i32(fp0
);
8119 TCGv_i32 fp0
= tcg_temp_new_i32();
8121 tcg_gen_trunc_tl_i32(fp0
, t0
);
8122 gen_store_fpr32h(ctx
, fp0
, rd
);
8123 tcg_temp_free_i32(fp0
);
8127 /* XXX: For now we support only a single FPU context. */
8128 save_cpu_state(ctx
, 1);
8130 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
8132 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8133 tcg_temp_free_i32(fs_tmp
);
8135 /* Stop translation as we may have changed hflags */
8136 ctx
->bstate
= BS_STOP
;
8138 /* COP2: Not implemented. */
8145 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
8151 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
8152 generate_exception(ctx
, EXCP_RI
);
8155 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
8157 const char *opn
= "ldst";
8159 check_cp0_enabled(ctx
);
8166 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8171 TCGv t0
= tcg_temp_new();
8173 gen_load_gpr(t0
, rt
);
8174 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8179 #if defined(TARGET_MIPS64)
8181 check_insn(ctx
, ISA_MIPS3
);
8186 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8190 check_insn(ctx
, ISA_MIPS3
);
8192 TCGv t0
= tcg_temp_new();
8194 gen_load_gpr(t0
, rt
);
8195 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8207 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8213 TCGv t0
= tcg_temp_new();
8214 gen_load_gpr(t0
, rt
);
8215 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8221 check_insn(ctx
, ASE_MT
);
8226 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
8227 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
8231 check_insn(ctx
, ASE_MT
);
8232 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
8233 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
8238 if (!env
->tlb
->helper_tlbwi
)
8240 gen_helper_tlbwi(cpu_env
);
8245 if (!env
->tlb
->helper_tlbinv
) {
8248 gen_helper_tlbinv(cpu_env
);
8249 } /* treat as nop if TLBINV not supported */
8254 if (!env
->tlb
->helper_tlbinvf
) {
8257 gen_helper_tlbinvf(cpu_env
);
8258 } /* treat as nop if TLBINV not supported */
8262 if (!env
->tlb
->helper_tlbwr
)
8264 gen_helper_tlbwr(cpu_env
);
8268 if (!env
->tlb
->helper_tlbp
)
8270 gen_helper_tlbp(cpu_env
);
8274 if (!env
->tlb
->helper_tlbr
)
8276 gen_helper_tlbr(cpu_env
);
8278 case OPC_ERET
: /* OPC_ERETNC */
8279 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8280 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8281 MIPS_DEBUG("CTI in delay / forbidden slot");
8284 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
8285 if (ctx
->opcode
& (1 << bit_shift
)) {
8288 check_insn(ctx
, ISA_MIPS32R5
);
8289 gen_helper_eretnc(cpu_env
);
8293 check_insn(ctx
, ISA_MIPS2
);
8294 gen_helper_eret(cpu_env
);
8296 ctx
->bstate
= BS_EXCP
;
8301 check_insn(ctx
, ISA_MIPS32
);
8302 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8303 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8304 MIPS_DEBUG("CTI in delay / forbidden slot");
8307 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
8309 generate_exception(ctx
, EXCP_RI
);
8311 gen_helper_deret(cpu_env
);
8312 ctx
->bstate
= BS_EXCP
;
8317 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
8318 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8319 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8320 MIPS_DEBUG("CTI in delay / forbidden slot");
8323 /* If we get an exception, we want to restart at next instruction */
8325 save_cpu_state(ctx
, 1);
8327 gen_helper_wait(cpu_env
);
8328 ctx
->bstate
= BS_EXCP
;
8333 generate_exception(ctx
, EXCP_RI
);
8336 (void)opn
; /* avoid a compiler warning */
8337 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
8339 #endif /* !CONFIG_USER_ONLY */
8341 /* CP1 Branches (before delay slot) */
8342 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
8343 int32_t cc
, int32_t offset
)
8345 target_ulong btarget
;
8346 const char *opn
= "cp1 cond branch";
8347 TCGv_i32 t0
= tcg_temp_new_i32();
8349 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8350 MIPS_DEBUG("CTI in delay / forbidden slot");
8351 generate_exception(ctx
, EXCP_RI
);
8356 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
8358 btarget
= ctx
->pc
+ 4 + offset
;
8362 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8363 tcg_gen_not_i32(t0
, t0
);
8364 tcg_gen_andi_i32(t0
, t0
, 1);
8365 tcg_gen_extu_i32_tl(bcond
, t0
);
8369 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8370 tcg_gen_not_i32(t0
, t0
);
8371 tcg_gen_andi_i32(t0
, t0
, 1);
8372 tcg_gen_extu_i32_tl(bcond
, t0
);
8376 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8377 tcg_gen_andi_i32(t0
, t0
, 1);
8378 tcg_gen_extu_i32_tl(bcond
, t0
);
8382 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8383 tcg_gen_andi_i32(t0
, t0
, 1);
8384 tcg_gen_extu_i32_tl(bcond
, t0
);
8387 ctx
->hflags
|= MIPS_HFLAG_BL
;
8391 TCGv_i32 t1
= tcg_temp_new_i32();
8392 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8393 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8394 tcg_gen_nand_i32(t0
, t0
, t1
);
8395 tcg_temp_free_i32(t1
);
8396 tcg_gen_andi_i32(t0
, t0
, 1);
8397 tcg_gen_extu_i32_tl(bcond
, t0
);
8403 TCGv_i32 t1
= tcg_temp_new_i32();
8404 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8405 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8406 tcg_gen_or_i32(t0
, t0
, t1
);
8407 tcg_temp_free_i32(t1
);
8408 tcg_gen_andi_i32(t0
, t0
, 1);
8409 tcg_gen_extu_i32_tl(bcond
, t0
);
8415 TCGv_i32 t1
= tcg_temp_new_i32();
8416 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8417 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8418 tcg_gen_and_i32(t0
, t0
, t1
);
8419 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8420 tcg_gen_and_i32(t0
, t0
, t1
);
8421 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8422 tcg_gen_nand_i32(t0
, t0
, t1
);
8423 tcg_temp_free_i32(t1
);
8424 tcg_gen_andi_i32(t0
, t0
, 1);
8425 tcg_gen_extu_i32_tl(bcond
, t0
);
8431 TCGv_i32 t1
= tcg_temp_new_i32();
8432 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8433 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8434 tcg_gen_or_i32(t0
, t0
, t1
);
8435 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8436 tcg_gen_or_i32(t0
, t0
, t1
);
8437 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8438 tcg_gen_or_i32(t0
, t0
, t1
);
8439 tcg_temp_free_i32(t1
);
8440 tcg_gen_andi_i32(t0
, t0
, 1);
8441 tcg_gen_extu_i32_tl(bcond
, t0
);
8445 ctx
->hflags
|= MIPS_HFLAG_BC
;
8449 generate_exception (ctx
, EXCP_RI
);
8452 (void)opn
; /* avoid a compiler warning */
8453 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
8454 ctx
->hflags
, btarget
);
8455 ctx
->btarget
= btarget
;
8456 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8458 tcg_temp_free_i32(t0
);
8461 /* R6 CP1 Branches */
8462 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
8463 int32_t ft
, int32_t offset
,
8466 target_ulong btarget
;
8467 const char *opn
= "cp1 cond branch";
8468 TCGv_i64 t0
= tcg_temp_new_i64();
8470 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
8471 #ifdef MIPS_DEBUG_DISAS
8472 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8475 generate_exception(ctx
, EXCP_RI
);
8479 gen_load_fpr64(ctx
, t0
, ft
);
8480 tcg_gen_andi_i64(t0
, t0
, 1);
8482 btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
8486 tcg_gen_xori_i64(t0
, t0
, 1);
8488 ctx
->hflags
|= MIPS_HFLAG_BC
;
8491 /* t0 already set */
8493 ctx
->hflags
|= MIPS_HFLAG_BC
;
8497 generate_exception(ctx
, EXCP_RI
);
8501 tcg_gen_trunc_i64_tl(bcond
, t0
);
8503 (void)opn
; /* avoid a compiler warning */
8504 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
8505 ctx
->hflags
, btarget
);
8506 ctx
->btarget
= btarget
;
8508 switch (delayslot_size
) {
8510 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
8513 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8518 tcg_temp_free_i64(t0
);
8521 /* Coprocessor 1 (FPU) */
8523 #define FOP(func, fmt) (((fmt) << 21) | (func))
8526 OPC_ADD_S
= FOP(0, FMT_S
),
8527 OPC_SUB_S
= FOP(1, FMT_S
),
8528 OPC_MUL_S
= FOP(2, FMT_S
),
8529 OPC_DIV_S
= FOP(3, FMT_S
),
8530 OPC_SQRT_S
= FOP(4, FMT_S
),
8531 OPC_ABS_S
= FOP(5, FMT_S
),
8532 OPC_MOV_S
= FOP(6, FMT_S
),
8533 OPC_NEG_S
= FOP(7, FMT_S
),
8534 OPC_ROUND_L_S
= FOP(8, FMT_S
),
8535 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
8536 OPC_CEIL_L_S
= FOP(10, FMT_S
),
8537 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
8538 OPC_ROUND_W_S
= FOP(12, FMT_S
),
8539 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
8540 OPC_CEIL_W_S
= FOP(14, FMT_S
),
8541 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
8542 OPC_SEL_S
= FOP(16, FMT_S
),
8543 OPC_MOVCF_S
= FOP(17, FMT_S
),
8544 OPC_MOVZ_S
= FOP(18, FMT_S
),
8545 OPC_MOVN_S
= FOP(19, FMT_S
),
8546 OPC_SELEQZ_S
= FOP(20, FMT_S
),
8547 OPC_RECIP_S
= FOP(21, FMT_S
),
8548 OPC_RSQRT_S
= FOP(22, FMT_S
),
8549 OPC_SELNEZ_S
= FOP(23, FMT_S
),
8550 OPC_MADDF_S
= FOP(24, FMT_S
),
8551 OPC_MSUBF_S
= FOP(25, FMT_S
),
8552 OPC_RINT_S
= FOP(26, FMT_S
),
8553 OPC_CLASS_S
= FOP(27, FMT_S
),
8554 OPC_MIN_S
= FOP(28, FMT_S
),
8555 OPC_RECIP2_S
= FOP(28, FMT_S
),
8556 OPC_MINA_S
= FOP(29, FMT_S
),
8557 OPC_RECIP1_S
= FOP(29, FMT_S
),
8558 OPC_MAX_S
= FOP(30, FMT_S
),
8559 OPC_RSQRT1_S
= FOP(30, FMT_S
),
8560 OPC_MAXA_S
= FOP(31, FMT_S
),
8561 OPC_RSQRT2_S
= FOP(31, FMT_S
),
8562 OPC_CVT_D_S
= FOP(33, FMT_S
),
8563 OPC_CVT_W_S
= FOP(36, FMT_S
),
8564 OPC_CVT_L_S
= FOP(37, FMT_S
),
8565 OPC_CVT_PS_S
= FOP(38, FMT_S
),
8566 OPC_CMP_F_S
= FOP (48, FMT_S
),
8567 OPC_CMP_UN_S
= FOP (49, FMT_S
),
8568 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
8569 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
8570 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
8571 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
8572 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
8573 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
8574 OPC_CMP_SF_S
= FOP (56, FMT_S
),
8575 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
8576 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
8577 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
8578 OPC_CMP_LT_S
= FOP (60, FMT_S
),
8579 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
8580 OPC_CMP_LE_S
= FOP (62, FMT_S
),
8581 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
8583 OPC_ADD_D
= FOP(0, FMT_D
),
8584 OPC_SUB_D
= FOP(1, FMT_D
),
8585 OPC_MUL_D
= FOP(2, FMT_D
),
8586 OPC_DIV_D
= FOP(3, FMT_D
),
8587 OPC_SQRT_D
= FOP(4, FMT_D
),
8588 OPC_ABS_D
= FOP(5, FMT_D
),
8589 OPC_MOV_D
= FOP(6, FMT_D
),
8590 OPC_NEG_D
= FOP(7, FMT_D
),
8591 OPC_ROUND_L_D
= FOP(8, FMT_D
),
8592 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
8593 OPC_CEIL_L_D
= FOP(10, FMT_D
),
8594 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
8595 OPC_ROUND_W_D
= FOP(12, FMT_D
),
8596 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
8597 OPC_CEIL_W_D
= FOP(14, FMT_D
),
8598 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
8599 OPC_SEL_D
= FOP(16, FMT_D
),
8600 OPC_MOVCF_D
= FOP(17, FMT_D
),
8601 OPC_MOVZ_D
= FOP(18, FMT_D
),
8602 OPC_MOVN_D
= FOP(19, FMT_D
),
8603 OPC_SELEQZ_D
= FOP(20, FMT_D
),
8604 OPC_RECIP_D
= FOP(21, FMT_D
),
8605 OPC_RSQRT_D
= FOP(22, FMT_D
),
8606 OPC_SELNEZ_D
= FOP(23, FMT_D
),
8607 OPC_MADDF_D
= FOP(24, FMT_D
),
8608 OPC_MSUBF_D
= FOP(25, FMT_D
),
8609 OPC_RINT_D
= FOP(26, FMT_D
),
8610 OPC_CLASS_D
= FOP(27, FMT_D
),
8611 OPC_MIN_D
= FOP(28, FMT_D
),
8612 OPC_RECIP2_D
= FOP(28, FMT_D
),
8613 OPC_MINA_D
= FOP(29, FMT_D
),
8614 OPC_RECIP1_D
= FOP(29, FMT_D
),
8615 OPC_MAX_D
= FOP(30, FMT_D
),
8616 OPC_RSQRT1_D
= FOP(30, FMT_D
),
8617 OPC_MAXA_D
= FOP(31, FMT_D
),
8618 OPC_RSQRT2_D
= FOP(31, FMT_D
),
8619 OPC_CVT_S_D
= FOP(32, FMT_D
),
8620 OPC_CVT_W_D
= FOP(36, FMT_D
),
8621 OPC_CVT_L_D
= FOP(37, FMT_D
),
8622 OPC_CMP_F_D
= FOP (48, FMT_D
),
8623 OPC_CMP_UN_D
= FOP (49, FMT_D
),
8624 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
8625 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
8626 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
8627 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
8628 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
8629 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
8630 OPC_CMP_SF_D
= FOP (56, FMT_D
),
8631 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
8632 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
8633 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
8634 OPC_CMP_LT_D
= FOP (60, FMT_D
),
8635 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
8636 OPC_CMP_LE_D
= FOP (62, FMT_D
),
8637 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
8639 OPC_CVT_S_W
= FOP(32, FMT_W
),
8640 OPC_CVT_D_W
= FOP(33, FMT_W
),
8641 OPC_CVT_S_L
= FOP(32, FMT_L
),
8642 OPC_CVT_D_L
= FOP(33, FMT_L
),
8643 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
8645 OPC_ADD_PS
= FOP(0, FMT_PS
),
8646 OPC_SUB_PS
= FOP(1, FMT_PS
),
8647 OPC_MUL_PS
= FOP(2, FMT_PS
),
8648 OPC_DIV_PS
= FOP(3, FMT_PS
),
8649 OPC_ABS_PS
= FOP(5, FMT_PS
),
8650 OPC_MOV_PS
= FOP(6, FMT_PS
),
8651 OPC_NEG_PS
= FOP(7, FMT_PS
),
8652 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
8653 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
8654 OPC_MOVN_PS
= FOP(19, FMT_PS
),
8655 OPC_ADDR_PS
= FOP(24, FMT_PS
),
8656 OPC_MULR_PS
= FOP(26, FMT_PS
),
8657 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
8658 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
8659 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
8660 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
8662 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
8663 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
8664 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
8665 OPC_PLL_PS
= FOP(44, FMT_PS
),
8666 OPC_PLU_PS
= FOP(45, FMT_PS
),
8667 OPC_PUL_PS
= FOP(46, FMT_PS
),
8668 OPC_PUU_PS
= FOP(47, FMT_PS
),
8669 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
8670 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
8671 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
8672 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
8673 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
8674 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
8675 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
8676 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
8677 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
8678 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
8679 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
8680 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
8681 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
8682 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
8683 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
8684 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
8688 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
8689 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
8690 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
8691 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
8692 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
8693 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
8694 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
8695 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
8696 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
8697 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
8698 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
8699 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
8700 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
8701 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
8702 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
8703 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
8704 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
8705 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
8706 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
8707 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
8708 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
8709 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
8711 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
8712 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
8713 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
8714 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
8715 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
8716 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
8717 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
8718 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
8719 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
8720 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
8721 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
8722 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
8723 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
8724 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
8725 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
8726 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
8727 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
8728 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
8729 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
8730 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
8731 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
8732 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
8734 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
8736 const char *opn
= "cp1 move";
8737 TCGv t0
= tcg_temp_new();
8742 TCGv_i32 fp0
= tcg_temp_new_i32();
8744 gen_load_fpr32(ctx
, fp0
, fs
);
8745 tcg_gen_ext_i32_tl(t0
, fp0
);
8746 tcg_temp_free_i32(fp0
);
8748 gen_store_gpr(t0
, rt
);
8752 gen_load_gpr(t0
, rt
);
8754 TCGv_i32 fp0
= tcg_temp_new_i32();
8756 tcg_gen_trunc_tl_i32(fp0
, t0
);
8757 gen_store_fpr32(ctx
, fp0
, fs
);
8758 tcg_temp_free_i32(fp0
);
8763 gen_helper_1e0i(cfc1
, t0
, fs
);
8764 gen_store_gpr(t0
, rt
);
8768 gen_load_gpr(t0
, rt
);
8769 save_cpu_state(ctx
, 1);
8771 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
8773 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8774 tcg_temp_free_i32(fs_tmp
);
8776 /* Stop translation as we may have changed hflags */
8777 ctx
->bstate
= BS_STOP
;
8780 #if defined(TARGET_MIPS64)
8782 gen_load_fpr64(ctx
, t0
, fs
);
8783 gen_store_gpr(t0
, rt
);
8787 gen_load_gpr(t0
, rt
);
8788 gen_store_fpr64(ctx
, t0
, fs
);
8794 TCGv_i32 fp0
= tcg_temp_new_i32();
8796 gen_load_fpr32h(ctx
, fp0
, fs
);
8797 tcg_gen_ext_i32_tl(t0
, fp0
);
8798 tcg_temp_free_i32(fp0
);
8800 gen_store_gpr(t0
, rt
);
8804 gen_load_gpr(t0
, rt
);
8806 TCGv_i32 fp0
= tcg_temp_new_i32();
8808 tcg_gen_trunc_tl_i32(fp0
, t0
);
8809 gen_store_fpr32h(ctx
, fp0
, fs
);
8810 tcg_temp_free_i32(fp0
);
8816 generate_exception (ctx
, EXCP_RI
);
8819 (void)opn
; /* avoid a compiler warning */
8820 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
8826 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
8842 l1
= gen_new_label();
8843 t0
= tcg_temp_new_i32();
8844 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8845 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8846 tcg_temp_free_i32(t0
);
8848 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
8850 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
8855 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
8859 TCGv_i32 t0
= tcg_temp_new_i32();
8860 TCGLabel
*l1
= gen_new_label();
8867 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8868 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8869 gen_load_fpr32(ctx
, t0
, fs
);
8870 gen_store_fpr32(ctx
, t0
, fd
);
8872 tcg_temp_free_i32(t0
);
8875 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
8878 TCGv_i32 t0
= tcg_temp_new_i32();
8880 TCGLabel
*l1
= gen_new_label();
8887 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8888 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8889 tcg_temp_free_i32(t0
);
8890 fp0
= tcg_temp_new_i64();
8891 gen_load_fpr64(ctx
, fp0
, fs
);
8892 gen_store_fpr64(ctx
, fp0
, fd
);
8893 tcg_temp_free_i64(fp0
);
8897 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
8901 TCGv_i32 t0
= tcg_temp_new_i32();
8902 TCGLabel
*l1
= gen_new_label();
8903 TCGLabel
*l2
= gen_new_label();
8910 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8911 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8912 gen_load_fpr32(ctx
, t0
, fs
);
8913 gen_store_fpr32(ctx
, t0
, fd
);
8916 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
8917 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
8918 gen_load_fpr32h(ctx
, t0
, fs
);
8919 gen_store_fpr32h(ctx
, t0
, fd
);
8920 tcg_temp_free_i32(t0
);
8924 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8927 TCGv_i32 t1
= tcg_const_i32(0);
8928 TCGv_i32 fp0
= tcg_temp_new_i32();
8929 TCGv_i32 fp1
= tcg_temp_new_i32();
8930 TCGv_i32 fp2
= tcg_temp_new_i32();
8931 gen_load_fpr32(ctx
, fp0
, fd
);
8932 gen_load_fpr32(ctx
, fp1
, ft
);
8933 gen_load_fpr32(ctx
, fp2
, fs
);
8937 tcg_gen_andi_i32(fp0
, fp0
, 1);
8938 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8941 tcg_gen_andi_i32(fp1
, fp1
, 1);
8942 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8945 tcg_gen_andi_i32(fp1
, fp1
, 1);
8946 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8949 MIPS_INVAL("gen_sel_s");
8950 generate_exception (ctx
, EXCP_RI
);
8954 gen_store_fpr32(ctx
, fp0
, fd
);
8955 tcg_temp_free_i32(fp2
);
8956 tcg_temp_free_i32(fp1
);
8957 tcg_temp_free_i32(fp0
);
8958 tcg_temp_free_i32(t1
);
8961 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8964 TCGv_i64 t1
= tcg_const_i64(0);
8965 TCGv_i64 fp0
= tcg_temp_new_i64();
8966 TCGv_i64 fp1
= tcg_temp_new_i64();
8967 TCGv_i64 fp2
= tcg_temp_new_i64();
8968 gen_load_fpr64(ctx
, fp0
, fd
);
8969 gen_load_fpr64(ctx
, fp1
, ft
);
8970 gen_load_fpr64(ctx
, fp2
, fs
);
8974 tcg_gen_andi_i64(fp0
, fp0
, 1);
8975 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8978 tcg_gen_andi_i64(fp1
, fp1
, 1);
8979 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8982 tcg_gen_andi_i64(fp1
, fp1
, 1);
8983 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8986 MIPS_INVAL("gen_sel_d");
8987 generate_exception (ctx
, EXCP_RI
);
8991 gen_store_fpr64(ctx
, fp0
, fd
);
8992 tcg_temp_free_i64(fp2
);
8993 tcg_temp_free_i64(fp1
);
8994 tcg_temp_free_i64(fp0
);
8995 tcg_temp_free_i64(t1
);
8998 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
8999 int ft
, int fs
, int fd
, int cc
)
9001 const char *opn
= "farith";
9002 const char *condnames
[] = {
9020 const char *condnames_abs
[] = {
9038 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
9039 uint32_t func
= ctx
->opcode
& 0x3f;
9043 TCGv_i32 fp0
= tcg_temp_new_i32();
9044 TCGv_i32 fp1
= tcg_temp_new_i32();
9046 gen_load_fpr32(ctx
, fp0
, fs
);
9047 gen_load_fpr32(ctx
, fp1
, ft
);
9048 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
9049 tcg_temp_free_i32(fp1
);
9050 gen_store_fpr32(ctx
, fp0
, fd
);
9051 tcg_temp_free_i32(fp0
);
9058 TCGv_i32 fp0
= tcg_temp_new_i32();
9059 TCGv_i32 fp1
= tcg_temp_new_i32();
9061 gen_load_fpr32(ctx
, fp0
, fs
);
9062 gen_load_fpr32(ctx
, fp1
, ft
);
9063 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
9064 tcg_temp_free_i32(fp1
);
9065 gen_store_fpr32(ctx
, fp0
, fd
);
9066 tcg_temp_free_i32(fp0
);
9073 TCGv_i32 fp0
= tcg_temp_new_i32();
9074 TCGv_i32 fp1
= tcg_temp_new_i32();
9076 gen_load_fpr32(ctx
, fp0
, fs
);
9077 gen_load_fpr32(ctx
, fp1
, ft
);
9078 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
9079 tcg_temp_free_i32(fp1
);
9080 gen_store_fpr32(ctx
, fp0
, fd
);
9081 tcg_temp_free_i32(fp0
);
9088 TCGv_i32 fp0
= tcg_temp_new_i32();
9089 TCGv_i32 fp1
= tcg_temp_new_i32();
9091 gen_load_fpr32(ctx
, fp0
, fs
);
9092 gen_load_fpr32(ctx
, fp1
, ft
);
9093 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
9094 tcg_temp_free_i32(fp1
);
9095 gen_store_fpr32(ctx
, fp0
, fd
);
9096 tcg_temp_free_i32(fp0
);
9103 TCGv_i32 fp0
= tcg_temp_new_i32();
9105 gen_load_fpr32(ctx
, fp0
, fs
);
9106 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
9107 gen_store_fpr32(ctx
, fp0
, fd
);
9108 tcg_temp_free_i32(fp0
);
9114 TCGv_i32 fp0
= tcg_temp_new_i32();
9116 gen_load_fpr32(ctx
, fp0
, fs
);
9117 gen_helper_float_abs_s(fp0
, fp0
);
9118 gen_store_fpr32(ctx
, fp0
, fd
);
9119 tcg_temp_free_i32(fp0
);
9125 TCGv_i32 fp0
= tcg_temp_new_i32();
9127 gen_load_fpr32(ctx
, fp0
, fs
);
9128 gen_store_fpr32(ctx
, fp0
, fd
);
9129 tcg_temp_free_i32(fp0
);
9135 TCGv_i32 fp0
= tcg_temp_new_i32();
9137 gen_load_fpr32(ctx
, fp0
, fs
);
9138 gen_helper_float_chs_s(fp0
, fp0
);
9139 gen_store_fpr32(ctx
, fp0
, fd
);
9140 tcg_temp_free_i32(fp0
);
9145 check_cp1_64bitmode(ctx
);
9147 TCGv_i32 fp32
= tcg_temp_new_i32();
9148 TCGv_i64 fp64
= tcg_temp_new_i64();
9150 gen_load_fpr32(ctx
, fp32
, fs
);
9151 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
9152 tcg_temp_free_i32(fp32
);
9153 gen_store_fpr64(ctx
, fp64
, fd
);
9154 tcg_temp_free_i64(fp64
);
9159 check_cp1_64bitmode(ctx
);
9161 TCGv_i32 fp32
= tcg_temp_new_i32();
9162 TCGv_i64 fp64
= tcg_temp_new_i64();
9164 gen_load_fpr32(ctx
, fp32
, fs
);
9165 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
9166 tcg_temp_free_i32(fp32
);
9167 gen_store_fpr64(ctx
, fp64
, fd
);
9168 tcg_temp_free_i64(fp64
);
9173 check_cp1_64bitmode(ctx
);
9175 TCGv_i32 fp32
= tcg_temp_new_i32();
9176 TCGv_i64 fp64
= tcg_temp_new_i64();
9178 gen_load_fpr32(ctx
, fp32
, fs
);
9179 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
9180 tcg_temp_free_i32(fp32
);
9181 gen_store_fpr64(ctx
, fp64
, fd
);
9182 tcg_temp_free_i64(fp64
);
9187 check_cp1_64bitmode(ctx
);
9189 TCGv_i32 fp32
= tcg_temp_new_i32();
9190 TCGv_i64 fp64
= tcg_temp_new_i64();
9192 gen_load_fpr32(ctx
, fp32
, fs
);
9193 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
9194 tcg_temp_free_i32(fp32
);
9195 gen_store_fpr64(ctx
, fp64
, fd
);
9196 tcg_temp_free_i64(fp64
);
9202 TCGv_i32 fp0
= tcg_temp_new_i32();
9204 gen_load_fpr32(ctx
, fp0
, fs
);
9205 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
9206 gen_store_fpr32(ctx
, fp0
, fd
);
9207 tcg_temp_free_i32(fp0
);
9213 TCGv_i32 fp0
= tcg_temp_new_i32();
9215 gen_load_fpr32(ctx
, fp0
, fs
);
9216 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
9217 gen_store_fpr32(ctx
, fp0
, fd
);
9218 tcg_temp_free_i32(fp0
);
9224 TCGv_i32 fp0
= tcg_temp_new_i32();
9226 gen_load_fpr32(ctx
, fp0
, fs
);
9227 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
9228 gen_store_fpr32(ctx
, fp0
, fd
);
9229 tcg_temp_free_i32(fp0
);
9235 TCGv_i32 fp0
= tcg_temp_new_i32();
9237 gen_load_fpr32(ctx
, fp0
, fs
);
9238 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
9239 gen_store_fpr32(ctx
, fp0
, fd
);
9240 tcg_temp_free_i32(fp0
);
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(ctx
, ISA_MIPS32R6
);
9256 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9260 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9261 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9265 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9267 TCGLabel
*l1
= gen_new_label();
9271 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9273 fp0
= tcg_temp_new_i32();
9274 gen_load_fpr32(ctx
, fp0
, fs
);
9275 gen_store_fpr32(ctx
, fp0
, fd
);
9276 tcg_temp_free_i32(fp0
);
9282 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9284 TCGLabel
*l1
= gen_new_label();
9288 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9289 fp0
= tcg_temp_new_i32();
9290 gen_load_fpr32(ctx
, fp0
, fs
);
9291 gen_store_fpr32(ctx
, fp0
, fd
);
9292 tcg_temp_free_i32(fp0
);
9301 TCGv_i32 fp0
= tcg_temp_new_i32();
9303 gen_load_fpr32(ctx
, fp0
, fs
);
9304 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
9305 gen_store_fpr32(ctx
, fp0
, fd
);
9306 tcg_temp_free_i32(fp0
);
9313 TCGv_i32 fp0
= tcg_temp_new_i32();
9315 gen_load_fpr32(ctx
, fp0
, fs
);
9316 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
9317 gen_store_fpr32(ctx
, fp0
, fd
);
9318 tcg_temp_free_i32(fp0
);
9323 check_insn(ctx
, ISA_MIPS32R6
);
9325 TCGv_i32 fp0
= tcg_temp_new_i32();
9326 TCGv_i32 fp1
= tcg_temp_new_i32();
9327 TCGv_i32 fp2
= tcg_temp_new_i32();
9328 gen_load_fpr32(ctx
, fp0
, fs
);
9329 gen_load_fpr32(ctx
, fp1
, ft
);
9330 gen_load_fpr32(ctx
, fp2
, fd
);
9331 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9332 gen_store_fpr32(ctx
, fp2
, fd
);
9333 tcg_temp_free_i32(fp2
);
9334 tcg_temp_free_i32(fp1
);
9335 tcg_temp_free_i32(fp0
);
9340 check_insn(ctx
, ISA_MIPS32R6
);
9342 TCGv_i32 fp0
= tcg_temp_new_i32();
9343 TCGv_i32 fp1
= tcg_temp_new_i32();
9344 TCGv_i32 fp2
= tcg_temp_new_i32();
9345 gen_load_fpr32(ctx
, fp0
, fs
);
9346 gen_load_fpr32(ctx
, fp1
, ft
);
9347 gen_load_fpr32(ctx
, fp2
, fd
);
9348 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9349 gen_store_fpr32(ctx
, fp2
, fd
);
9350 tcg_temp_free_i32(fp2
);
9351 tcg_temp_free_i32(fp1
);
9352 tcg_temp_free_i32(fp0
);
9357 check_insn(ctx
, ISA_MIPS32R6
);
9359 TCGv_i32 fp0
= tcg_temp_new_i32();
9360 gen_load_fpr32(ctx
, fp0
, fs
);
9361 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
9362 gen_store_fpr32(ctx
, fp0
, fd
);
9363 tcg_temp_free_i32(fp0
);
9368 check_insn(ctx
, ISA_MIPS32R6
);
9370 TCGv_i32 fp0
= tcg_temp_new_i32();
9371 gen_load_fpr32(ctx
, fp0
, fs
);
9372 gen_helper_float_class_s(fp0
, fp0
);
9373 gen_store_fpr32(ctx
, fp0
, fd
);
9374 tcg_temp_free_i32(fp0
);
9378 case OPC_MIN_S
: /* OPC_RECIP2_S */
9379 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9381 TCGv_i32 fp0
= tcg_temp_new_i32();
9382 TCGv_i32 fp1
= tcg_temp_new_i32();
9383 TCGv_i32 fp2
= tcg_temp_new_i32();
9384 gen_load_fpr32(ctx
, fp0
, fs
);
9385 gen_load_fpr32(ctx
, fp1
, ft
);
9386 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
9387 gen_store_fpr32(ctx
, fp2
, fd
);
9388 tcg_temp_free_i32(fp2
);
9389 tcg_temp_free_i32(fp1
);
9390 tcg_temp_free_i32(fp0
);
9394 check_cp1_64bitmode(ctx
);
9396 TCGv_i32 fp0
= tcg_temp_new_i32();
9397 TCGv_i32 fp1
= tcg_temp_new_i32();
9399 gen_load_fpr32(ctx
, fp0
, fs
);
9400 gen_load_fpr32(ctx
, fp1
, ft
);
9401 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
9402 tcg_temp_free_i32(fp1
);
9403 gen_store_fpr32(ctx
, fp0
, fd
);
9404 tcg_temp_free_i32(fp0
);
9409 case OPC_MINA_S
: /* OPC_RECIP1_S */
9410 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9412 TCGv_i32 fp0
= tcg_temp_new_i32();
9413 TCGv_i32 fp1
= tcg_temp_new_i32();
9414 TCGv_i32 fp2
= tcg_temp_new_i32();
9415 gen_load_fpr32(ctx
, fp0
, fs
);
9416 gen_load_fpr32(ctx
, fp1
, ft
);
9417 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
9418 gen_store_fpr32(ctx
, fp2
, fd
);
9419 tcg_temp_free_i32(fp2
);
9420 tcg_temp_free_i32(fp1
);
9421 tcg_temp_free_i32(fp0
);
9425 check_cp1_64bitmode(ctx
);
9427 TCGv_i32 fp0
= tcg_temp_new_i32();
9429 gen_load_fpr32(ctx
, fp0
, fs
);
9430 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
9431 gen_store_fpr32(ctx
, fp0
, fd
);
9432 tcg_temp_free_i32(fp0
);
9437 case OPC_MAX_S
: /* OPC_RSQRT1_S */
9438 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9440 TCGv_i32 fp0
= tcg_temp_new_i32();
9441 TCGv_i32 fp1
= tcg_temp_new_i32();
9442 gen_load_fpr32(ctx
, fp0
, fs
);
9443 gen_load_fpr32(ctx
, fp1
, ft
);
9444 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
9445 gen_store_fpr32(ctx
, fp1
, fd
);
9446 tcg_temp_free_i32(fp1
);
9447 tcg_temp_free_i32(fp0
);
9451 check_cp1_64bitmode(ctx
);
9453 TCGv_i32 fp0
= tcg_temp_new_i32();
9455 gen_load_fpr32(ctx
, fp0
, fs
);
9456 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
9457 gen_store_fpr32(ctx
, fp0
, fd
);
9458 tcg_temp_free_i32(fp0
);
9463 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
9464 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9466 TCGv_i32 fp0
= tcg_temp_new_i32();
9467 TCGv_i32 fp1
= tcg_temp_new_i32();
9468 gen_load_fpr32(ctx
, fp0
, fs
);
9469 gen_load_fpr32(ctx
, fp1
, ft
);
9470 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
9471 gen_store_fpr32(ctx
, fp1
, fd
);
9472 tcg_temp_free_i32(fp1
);
9473 tcg_temp_free_i32(fp0
);
9477 check_cp1_64bitmode(ctx
);
9479 TCGv_i32 fp0
= tcg_temp_new_i32();
9480 TCGv_i32 fp1
= tcg_temp_new_i32();
9482 gen_load_fpr32(ctx
, fp0
, fs
);
9483 gen_load_fpr32(ctx
, fp1
, ft
);
9484 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
9485 tcg_temp_free_i32(fp1
);
9486 gen_store_fpr32(ctx
, fp0
, fd
);
9487 tcg_temp_free_i32(fp0
);
9493 check_cp1_registers(ctx
, fd
);
9495 TCGv_i32 fp32
= tcg_temp_new_i32();
9496 TCGv_i64 fp64
= tcg_temp_new_i64();
9498 gen_load_fpr32(ctx
, fp32
, fs
);
9499 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
9500 tcg_temp_free_i32(fp32
);
9501 gen_store_fpr64(ctx
, fp64
, fd
);
9502 tcg_temp_free_i64(fp64
);
9508 TCGv_i32 fp0
= tcg_temp_new_i32();
9510 gen_load_fpr32(ctx
, fp0
, fs
);
9511 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
9512 gen_store_fpr32(ctx
, fp0
, fd
);
9513 tcg_temp_free_i32(fp0
);
9518 check_cp1_64bitmode(ctx
);
9520 TCGv_i32 fp32
= tcg_temp_new_i32();
9521 TCGv_i64 fp64
= tcg_temp_new_i64();
9523 gen_load_fpr32(ctx
, fp32
, fs
);
9524 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
9525 tcg_temp_free_i32(fp32
);
9526 gen_store_fpr64(ctx
, fp64
, fd
);
9527 tcg_temp_free_i64(fp64
);
9534 TCGv_i64 fp64
= tcg_temp_new_i64();
9535 TCGv_i32 fp32_0
= tcg_temp_new_i32();
9536 TCGv_i32 fp32_1
= tcg_temp_new_i32();
9538 gen_load_fpr32(ctx
, fp32_0
, fs
);
9539 gen_load_fpr32(ctx
, fp32_1
, ft
);
9540 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
9541 tcg_temp_free_i32(fp32_1
);
9542 tcg_temp_free_i32(fp32_0
);
9543 gen_store_fpr64(ctx
, fp64
, fd
);
9544 tcg_temp_free_i64(fp64
);
9557 case OPC_CMP_NGLE_S
:
9564 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9565 if (ctx
->opcode
& (1 << 6)) {
9566 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
9567 opn
= condnames_abs
[func
-48];
9569 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
9570 opn
= condnames
[func
-48];
9575 check_cp1_registers(ctx
, fs
| ft
| fd
);
9577 TCGv_i64 fp0
= tcg_temp_new_i64();
9578 TCGv_i64 fp1
= tcg_temp_new_i64();
9580 gen_load_fpr64(ctx
, fp0
, fs
);
9581 gen_load_fpr64(ctx
, fp1
, ft
);
9582 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
9583 tcg_temp_free_i64(fp1
);
9584 gen_store_fpr64(ctx
, fp0
, fd
);
9585 tcg_temp_free_i64(fp0
);
9591 check_cp1_registers(ctx
, fs
| ft
| fd
);
9593 TCGv_i64 fp0
= tcg_temp_new_i64();
9594 TCGv_i64 fp1
= tcg_temp_new_i64();
9596 gen_load_fpr64(ctx
, fp0
, fs
);
9597 gen_load_fpr64(ctx
, fp1
, ft
);
9598 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
9599 tcg_temp_free_i64(fp1
);
9600 gen_store_fpr64(ctx
, fp0
, fd
);
9601 tcg_temp_free_i64(fp0
);
9607 check_cp1_registers(ctx
, fs
| ft
| fd
);
9609 TCGv_i64 fp0
= tcg_temp_new_i64();
9610 TCGv_i64 fp1
= tcg_temp_new_i64();
9612 gen_load_fpr64(ctx
, fp0
, fs
);
9613 gen_load_fpr64(ctx
, fp1
, ft
);
9614 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
9615 tcg_temp_free_i64(fp1
);
9616 gen_store_fpr64(ctx
, fp0
, fd
);
9617 tcg_temp_free_i64(fp0
);
9623 check_cp1_registers(ctx
, fs
| ft
| fd
);
9625 TCGv_i64 fp0
= tcg_temp_new_i64();
9626 TCGv_i64 fp1
= tcg_temp_new_i64();
9628 gen_load_fpr64(ctx
, fp0
, fs
);
9629 gen_load_fpr64(ctx
, fp1
, ft
);
9630 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
9631 tcg_temp_free_i64(fp1
);
9632 gen_store_fpr64(ctx
, fp0
, fd
);
9633 tcg_temp_free_i64(fp0
);
9639 check_cp1_registers(ctx
, fs
| fd
);
9641 TCGv_i64 fp0
= tcg_temp_new_i64();
9643 gen_load_fpr64(ctx
, fp0
, fs
);
9644 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
9645 gen_store_fpr64(ctx
, fp0
, fd
);
9646 tcg_temp_free_i64(fp0
);
9651 check_cp1_registers(ctx
, fs
| fd
);
9653 TCGv_i64 fp0
= tcg_temp_new_i64();
9655 gen_load_fpr64(ctx
, fp0
, fs
);
9656 gen_helper_float_abs_d(fp0
, fp0
);
9657 gen_store_fpr64(ctx
, fp0
, fd
);
9658 tcg_temp_free_i64(fp0
);
9663 check_cp1_registers(ctx
, fs
| fd
);
9665 TCGv_i64 fp0
= tcg_temp_new_i64();
9667 gen_load_fpr64(ctx
, fp0
, fs
);
9668 gen_store_fpr64(ctx
, fp0
, fd
);
9669 tcg_temp_free_i64(fp0
);
9674 check_cp1_registers(ctx
, fs
| fd
);
9676 TCGv_i64 fp0
= tcg_temp_new_i64();
9678 gen_load_fpr64(ctx
, fp0
, fs
);
9679 gen_helper_float_chs_d(fp0
, fp0
);
9680 gen_store_fpr64(ctx
, fp0
, fd
);
9681 tcg_temp_free_i64(fp0
);
9686 check_cp1_64bitmode(ctx
);
9688 TCGv_i64 fp0
= tcg_temp_new_i64();
9690 gen_load_fpr64(ctx
, fp0
, fs
);
9691 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
9692 gen_store_fpr64(ctx
, fp0
, fd
);
9693 tcg_temp_free_i64(fp0
);
9698 check_cp1_64bitmode(ctx
);
9700 TCGv_i64 fp0
= tcg_temp_new_i64();
9702 gen_load_fpr64(ctx
, fp0
, fs
);
9703 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
9704 gen_store_fpr64(ctx
, fp0
, fd
);
9705 tcg_temp_free_i64(fp0
);
9710 check_cp1_64bitmode(ctx
);
9712 TCGv_i64 fp0
= tcg_temp_new_i64();
9714 gen_load_fpr64(ctx
, fp0
, fs
);
9715 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
9716 gen_store_fpr64(ctx
, fp0
, fd
);
9717 tcg_temp_free_i64(fp0
);
9722 check_cp1_64bitmode(ctx
);
9724 TCGv_i64 fp0
= tcg_temp_new_i64();
9726 gen_load_fpr64(ctx
, fp0
, fs
);
9727 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
9728 gen_store_fpr64(ctx
, fp0
, fd
);
9729 tcg_temp_free_i64(fp0
);
9734 check_cp1_registers(ctx
, fs
);
9736 TCGv_i32 fp32
= tcg_temp_new_i32();
9737 TCGv_i64 fp64
= tcg_temp_new_i64();
9739 gen_load_fpr64(ctx
, fp64
, fs
);
9740 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
9741 tcg_temp_free_i64(fp64
);
9742 gen_store_fpr32(ctx
, fp32
, fd
);
9743 tcg_temp_free_i32(fp32
);
9748 check_cp1_registers(ctx
, fs
);
9750 TCGv_i32 fp32
= tcg_temp_new_i32();
9751 TCGv_i64 fp64
= tcg_temp_new_i64();
9753 gen_load_fpr64(ctx
, fp64
, fs
);
9754 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
9755 tcg_temp_free_i64(fp64
);
9756 gen_store_fpr32(ctx
, fp32
, fd
);
9757 tcg_temp_free_i32(fp32
);
9762 check_cp1_registers(ctx
, fs
);
9764 TCGv_i32 fp32
= tcg_temp_new_i32();
9765 TCGv_i64 fp64
= tcg_temp_new_i64();
9767 gen_load_fpr64(ctx
, fp64
, fs
);
9768 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
9769 tcg_temp_free_i64(fp64
);
9770 gen_store_fpr32(ctx
, fp32
, fd
);
9771 tcg_temp_free_i32(fp32
);
9776 check_cp1_registers(ctx
, fs
);
9778 TCGv_i32 fp32
= tcg_temp_new_i32();
9779 TCGv_i64 fp64
= tcg_temp_new_i64();
9781 gen_load_fpr64(ctx
, fp64
, fs
);
9782 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
9783 tcg_temp_free_i64(fp64
);
9784 gen_store_fpr32(ctx
, fp32
, fd
);
9785 tcg_temp_free_i32(fp32
);
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(ctx
, ISA_MIPS32R6
);
9801 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9805 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9806 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9810 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9812 TCGLabel
*l1
= gen_new_label();
9816 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9818 fp0
= tcg_temp_new_i64();
9819 gen_load_fpr64(ctx
, fp0
, fs
);
9820 gen_store_fpr64(ctx
, fp0
, fd
);
9821 tcg_temp_free_i64(fp0
);
9827 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9829 TCGLabel
*l1
= gen_new_label();
9833 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9834 fp0
= tcg_temp_new_i64();
9835 gen_load_fpr64(ctx
, fp0
, fs
);
9836 gen_store_fpr64(ctx
, fp0
, fd
);
9837 tcg_temp_free_i64(fp0
);
9844 check_cp1_64bitmode(ctx
);
9846 TCGv_i64 fp0
= tcg_temp_new_i64();
9848 gen_load_fpr64(ctx
, fp0
, fs
);
9849 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
9850 gen_store_fpr64(ctx
, fp0
, fd
);
9851 tcg_temp_free_i64(fp0
);
9856 check_cp1_64bitmode(ctx
);
9858 TCGv_i64 fp0
= tcg_temp_new_i64();
9860 gen_load_fpr64(ctx
, fp0
, fs
);
9861 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
9862 gen_store_fpr64(ctx
, fp0
, fd
);
9863 tcg_temp_free_i64(fp0
);
9868 check_insn(ctx
, ISA_MIPS32R6
);
9870 TCGv_i64 fp0
= tcg_temp_new_i64();
9871 TCGv_i64 fp1
= tcg_temp_new_i64();
9872 TCGv_i64 fp2
= tcg_temp_new_i64();
9873 gen_load_fpr64(ctx
, fp0
, fs
);
9874 gen_load_fpr64(ctx
, fp1
, ft
);
9875 gen_load_fpr64(ctx
, fp2
, fd
);
9876 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9877 gen_store_fpr64(ctx
, fp2
, fd
);
9878 tcg_temp_free_i64(fp2
);
9879 tcg_temp_free_i64(fp1
);
9880 tcg_temp_free_i64(fp0
);
9885 check_insn(ctx
, ISA_MIPS32R6
);
9887 TCGv_i64 fp0
= tcg_temp_new_i64();
9888 TCGv_i64 fp1
= tcg_temp_new_i64();
9889 TCGv_i64 fp2
= tcg_temp_new_i64();
9890 gen_load_fpr64(ctx
, fp0
, fs
);
9891 gen_load_fpr64(ctx
, fp1
, ft
);
9892 gen_load_fpr64(ctx
, fp2
, fd
);
9893 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9894 gen_store_fpr64(ctx
, fp2
, fd
);
9895 tcg_temp_free_i64(fp2
);
9896 tcg_temp_free_i64(fp1
);
9897 tcg_temp_free_i64(fp0
);
9902 check_insn(ctx
, ISA_MIPS32R6
);
9904 TCGv_i64 fp0
= tcg_temp_new_i64();
9905 gen_load_fpr64(ctx
, fp0
, fs
);
9906 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
9907 gen_store_fpr64(ctx
, fp0
, fd
);
9908 tcg_temp_free_i64(fp0
);
9913 check_insn(ctx
, ISA_MIPS32R6
);
9915 TCGv_i64 fp0
= tcg_temp_new_i64();
9916 gen_load_fpr64(ctx
, fp0
, fs
);
9917 gen_helper_float_class_d(fp0
, fp0
);
9918 gen_store_fpr64(ctx
, fp0
, fd
);
9919 tcg_temp_free_i64(fp0
);
9923 case OPC_MIN_D
: /* OPC_RECIP2_D */
9924 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9926 TCGv_i64 fp0
= tcg_temp_new_i64();
9927 TCGv_i64 fp1
= tcg_temp_new_i64();
9928 gen_load_fpr64(ctx
, fp0
, fs
);
9929 gen_load_fpr64(ctx
, fp1
, ft
);
9930 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
9931 gen_store_fpr64(ctx
, fp1
, fd
);
9932 tcg_temp_free_i64(fp1
);
9933 tcg_temp_free_i64(fp0
);
9937 check_cp1_64bitmode(ctx
);
9939 TCGv_i64 fp0
= tcg_temp_new_i64();
9940 TCGv_i64 fp1
= tcg_temp_new_i64();
9942 gen_load_fpr64(ctx
, fp0
, fs
);
9943 gen_load_fpr64(ctx
, fp1
, ft
);
9944 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
9945 tcg_temp_free_i64(fp1
);
9946 gen_store_fpr64(ctx
, fp0
, fd
);
9947 tcg_temp_free_i64(fp0
);
9952 case OPC_MINA_D
: /* OPC_RECIP1_D */
9953 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9955 TCGv_i64 fp0
= tcg_temp_new_i64();
9956 TCGv_i64 fp1
= tcg_temp_new_i64();
9957 gen_load_fpr64(ctx
, fp0
, fs
);
9958 gen_load_fpr64(ctx
, fp1
, ft
);
9959 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
9960 gen_store_fpr64(ctx
, fp1
, fd
);
9961 tcg_temp_free_i64(fp1
);
9962 tcg_temp_free_i64(fp0
);
9966 check_cp1_64bitmode(ctx
);
9968 TCGv_i64 fp0
= tcg_temp_new_i64();
9970 gen_load_fpr64(ctx
, fp0
, fs
);
9971 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
9972 gen_store_fpr64(ctx
, fp0
, fd
);
9973 tcg_temp_free_i64(fp0
);
9978 case OPC_MAX_D
: /* OPC_RSQRT1_D */
9979 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9981 TCGv_i64 fp0
= tcg_temp_new_i64();
9982 TCGv_i64 fp1
= tcg_temp_new_i64();
9983 gen_load_fpr64(ctx
, fp0
, fs
);
9984 gen_load_fpr64(ctx
, fp1
, ft
);
9985 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
9986 gen_store_fpr64(ctx
, fp1
, fd
);
9987 tcg_temp_free_i64(fp1
);
9988 tcg_temp_free_i64(fp0
);
9992 check_cp1_64bitmode(ctx
);
9994 TCGv_i64 fp0
= tcg_temp_new_i64();
9996 gen_load_fpr64(ctx
, fp0
, fs
);
9997 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
9998 gen_store_fpr64(ctx
, fp0
, fd
);
9999 tcg_temp_free_i64(fp0
);
10004 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
10005 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
10007 TCGv_i64 fp0
= tcg_temp_new_i64();
10008 TCGv_i64 fp1
= tcg_temp_new_i64();
10009 gen_load_fpr64(ctx
, fp0
, fs
);
10010 gen_load_fpr64(ctx
, fp1
, ft
);
10011 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
10012 gen_store_fpr64(ctx
, fp1
, fd
);
10013 tcg_temp_free_i64(fp1
);
10014 tcg_temp_free_i64(fp0
);
10018 check_cp1_64bitmode(ctx
);
10020 TCGv_i64 fp0
= tcg_temp_new_i64();
10021 TCGv_i64 fp1
= tcg_temp_new_i64();
10023 gen_load_fpr64(ctx
, fp0
, fs
);
10024 gen_load_fpr64(ctx
, fp1
, ft
);
10025 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
10026 tcg_temp_free_i64(fp1
);
10027 gen_store_fpr64(ctx
, fp0
, fd
);
10028 tcg_temp_free_i64(fp0
);
10036 case OPC_CMP_UEQ_D
:
10037 case OPC_CMP_OLT_D
:
10038 case OPC_CMP_ULT_D
:
10039 case OPC_CMP_OLE_D
:
10040 case OPC_CMP_ULE_D
:
10042 case OPC_CMP_NGLE_D
:
10043 case OPC_CMP_SEQ_D
:
10044 case OPC_CMP_NGL_D
:
10046 case OPC_CMP_NGE_D
:
10048 case OPC_CMP_NGT_D
:
10049 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
10050 if (ctx
->opcode
& (1 << 6)) {
10051 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
10052 opn
= condnames_abs
[func
-48];
10054 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
10055 opn
= condnames
[func
-48];
10060 check_cp1_registers(ctx
, fs
);
10062 TCGv_i32 fp32
= tcg_temp_new_i32();
10063 TCGv_i64 fp64
= tcg_temp_new_i64();
10065 gen_load_fpr64(ctx
, fp64
, fs
);
10066 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
10067 tcg_temp_free_i64(fp64
);
10068 gen_store_fpr32(ctx
, fp32
, fd
);
10069 tcg_temp_free_i32(fp32
);
10074 check_cp1_registers(ctx
, fs
);
10076 TCGv_i32 fp32
= tcg_temp_new_i32();
10077 TCGv_i64 fp64
= tcg_temp_new_i64();
10079 gen_load_fpr64(ctx
, fp64
, fs
);
10080 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
10081 tcg_temp_free_i64(fp64
);
10082 gen_store_fpr32(ctx
, fp32
, fd
);
10083 tcg_temp_free_i32(fp32
);
10088 check_cp1_64bitmode(ctx
);
10090 TCGv_i64 fp0
= tcg_temp_new_i64();
10092 gen_load_fpr64(ctx
, fp0
, fs
);
10093 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
10094 gen_store_fpr64(ctx
, fp0
, fd
);
10095 tcg_temp_free_i64(fp0
);
10101 TCGv_i32 fp0
= tcg_temp_new_i32();
10103 gen_load_fpr32(ctx
, fp0
, fs
);
10104 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
10105 gen_store_fpr32(ctx
, fp0
, fd
);
10106 tcg_temp_free_i32(fp0
);
10111 check_cp1_registers(ctx
, fd
);
10113 TCGv_i32 fp32
= tcg_temp_new_i32();
10114 TCGv_i64 fp64
= tcg_temp_new_i64();
10116 gen_load_fpr32(ctx
, fp32
, fs
);
10117 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
10118 tcg_temp_free_i32(fp32
);
10119 gen_store_fpr64(ctx
, fp64
, fd
);
10120 tcg_temp_free_i64(fp64
);
10125 check_cp1_64bitmode(ctx
);
10127 TCGv_i32 fp32
= tcg_temp_new_i32();
10128 TCGv_i64 fp64
= tcg_temp_new_i64();
10130 gen_load_fpr64(ctx
, fp64
, fs
);
10131 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
10132 tcg_temp_free_i64(fp64
);
10133 gen_store_fpr32(ctx
, fp32
, fd
);
10134 tcg_temp_free_i32(fp32
);
10139 check_cp1_64bitmode(ctx
);
10141 TCGv_i64 fp0
= tcg_temp_new_i64();
10143 gen_load_fpr64(ctx
, fp0
, fs
);
10144 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
10145 gen_store_fpr64(ctx
, fp0
, fd
);
10146 tcg_temp_free_i64(fp0
);
10150 case OPC_CVT_PS_PW
:
10153 TCGv_i64 fp0
= tcg_temp_new_i64();
10155 gen_load_fpr64(ctx
, fp0
, fs
);
10156 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
10157 gen_store_fpr64(ctx
, fp0
, fd
);
10158 tcg_temp_free_i64(fp0
);
10165 TCGv_i64 fp0
= tcg_temp_new_i64();
10166 TCGv_i64 fp1
= tcg_temp_new_i64();
10168 gen_load_fpr64(ctx
, fp0
, fs
);
10169 gen_load_fpr64(ctx
, fp1
, ft
);
10170 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
10171 tcg_temp_free_i64(fp1
);
10172 gen_store_fpr64(ctx
, fp0
, fd
);
10173 tcg_temp_free_i64(fp0
);
10180 TCGv_i64 fp0
= tcg_temp_new_i64();
10181 TCGv_i64 fp1
= tcg_temp_new_i64();
10183 gen_load_fpr64(ctx
, fp0
, fs
);
10184 gen_load_fpr64(ctx
, fp1
, ft
);
10185 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
10186 tcg_temp_free_i64(fp1
);
10187 gen_store_fpr64(ctx
, fp0
, fd
);
10188 tcg_temp_free_i64(fp0
);
10195 TCGv_i64 fp0
= tcg_temp_new_i64();
10196 TCGv_i64 fp1
= tcg_temp_new_i64();
10198 gen_load_fpr64(ctx
, fp0
, fs
);
10199 gen_load_fpr64(ctx
, fp1
, ft
);
10200 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
10201 tcg_temp_free_i64(fp1
);
10202 gen_store_fpr64(ctx
, fp0
, fd
);
10203 tcg_temp_free_i64(fp0
);
10210 TCGv_i64 fp0
= tcg_temp_new_i64();
10212 gen_load_fpr64(ctx
, fp0
, fs
);
10213 gen_helper_float_abs_ps(fp0
, fp0
);
10214 gen_store_fpr64(ctx
, fp0
, fd
);
10215 tcg_temp_free_i64(fp0
);
10222 TCGv_i64 fp0
= tcg_temp_new_i64();
10224 gen_load_fpr64(ctx
, fp0
, fs
);
10225 gen_store_fpr64(ctx
, fp0
, fd
);
10226 tcg_temp_free_i64(fp0
);
10233 TCGv_i64 fp0
= tcg_temp_new_i64();
10235 gen_load_fpr64(ctx
, fp0
, fs
);
10236 gen_helper_float_chs_ps(fp0
, fp0
);
10237 gen_store_fpr64(ctx
, fp0
, fd
);
10238 tcg_temp_free_i64(fp0
);
10244 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10250 TCGLabel
*l1
= gen_new_label();
10254 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10255 fp0
= tcg_temp_new_i64();
10256 gen_load_fpr64(ctx
, fp0
, fs
);
10257 gen_store_fpr64(ctx
, fp0
, fd
);
10258 tcg_temp_free_i64(fp0
);
10266 TCGLabel
*l1
= gen_new_label();
10270 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10271 fp0
= tcg_temp_new_i64();
10272 gen_load_fpr64(ctx
, fp0
, fs
);
10273 gen_store_fpr64(ctx
, fp0
, fd
);
10274 tcg_temp_free_i64(fp0
);
10283 TCGv_i64 fp0
= tcg_temp_new_i64();
10284 TCGv_i64 fp1
= tcg_temp_new_i64();
10286 gen_load_fpr64(ctx
, fp0
, ft
);
10287 gen_load_fpr64(ctx
, fp1
, fs
);
10288 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
10289 tcg_temp_free_i64(fp1
);
10290 gen_store_fpr64(ctx
, fp0
, fd
);
10291 tcg_temp_free_i64(fp0
);
10298 TCGv_i64 fp0
= tcg_temp_new_i64();
10299 TCGv_i64 fp1
= tcg_temp_new_i64();
10301 gen_load_fpr64(ctx
, fp0
, ft
);
10302 gen_load_fpr64(ctx
, fp1
, fs
);
10303 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
10304 tcg_temp_free_i64(fp1
);
10305 gen_store_fpr64(ctx
, fp0
, fd
);
10306 tcg_temp_free_i64(fp0
);
10310 case OPC_RECIP2_PS
:
10313 TCGv_i64 fp0
= tcg_temp_new_i64();
10314 TCGv_i64 fp1
= tcg_temp_new_i64();
10316 gen_load_fpr64(ctx
, fp0
, fs
);
10317 gen_load_fpr64(ctx
, fp1
, ft
);
10318 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
10319 tcg_temp_free_i64(fp1
);
10320 gen_store_fpr64(ctx
, fp0
, fd
);
10321 tcg_temp_free_i64(fp0
);
10325 case OPC_RECIP1_PS
:
10328 TCGv_i64 fp0
= tcg_temp_new_i64();
10330 gen_load_fpr64(ctx
, fp0
, fs
);
10331 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
10332 gen_store_fpr64(ctx
, fp0
, fd
);
10333 tcg_temp_free_i64(fp0
);
10337 case OPC_RSQRT1_PS
:
10340 TCGv_i64 fp0
= tcg_temp_new_i64();
10342 gen_load_fpr64(ctx
, fp0
, fs
);
10343 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
10344 gen_store_fpr64(ctx
, fp0
, fd
);
10345 tcg_temp_free_i64(fp0
);
10349 case OPC_RSQRT2_PS
:
10352 TCGv_i64 fp0
= tcg_temp_new_i64();
10353 TCGv_i64 fp1
= tcg_temp_new_i64();
10355 gen_load_fpr64(ctx
, fp0
, fs
);
10356 gen_load_fpr64(ctx
, fp1
, ft
);
10357 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
10358 tcg_temp_free_i64(fp1
);
10359 gen_store_fpr64(ctx
, fp0
, fd
);
10360 tcg_temp_free_i64(fp0
);
10365 check_cp1_64bitmode(ctx
);
10367 TCGv_i32 fp0
= tcg_temp_new_i32();
10369 gen_load_fpr32h(ctx
, fp0
, fs
);
10370 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
10371 gen_store_fpr32(ctx
, fp0
, fd
);
10372 tcg_temp_free_i32(fp0
);
10376 case OPC_CVT_PW_PS
:
10379 TCGv_i64 fp0
= tcg_temp_new_i64();
10381 gen_load_fpr64(ctx
, fp0
, fs
);
10382 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
10383 gen_store_fpr64(ctx
, fp0
, fd
);
10384 tcg_temp_free_i64(fp0
);
10389 check_cp1_64bitmode(ctx
);
10391 TCGv_i32 fp0
= tcg_temp_new_i32();
10393 gen_load_fpr32(ctx
, fp0
, fs
);
10394 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
10395 gen_store_fpr32(ctx
, fp0
, fd
);
10396 tcg_temp_free_i32(fp0
);
10403 TCGv_i32 fp0
= tcg_temp_new_i32();
10404 TCGv_i32 fp1
= tcg_temp_new_i32();
10406 gen_load_fpr32(ctx
, fp0
, fs
);
10407 gen_load_fpr32(ctx
, fp1
, ft
);
10408 gen_store_fpr32h(ctx
, fp0
, fd
);
10409 gen_store_fpr32(ctx
, fp1
, fd
);
10410 tcg_temp_free_i32(fp0
);
10411 tcg_temp_free_i32(fp1
);
10418 TCGv_i32 fp0
= tcg_temp_new_i32();
10419 TCGv_i32 fp1
= tcg_temp_new_i32();
10421 gen_load_fpr32(ctx
, fp0
, fs
);
10422 gen_load_fpr32h(ctx
, fp1
, ft
);
10423 gen_store_fpr32(ctx
, fp1
, fd
);
10424 gen_store_fpr32h(ctx
, fp0
, fd
);
10425 tcg_temp_free_i32(fp0
);
10426 tcg_temp_free_i32(fp1
);
10433 TCGv_i32 fp0
= tcg_temp_new_i32();
10434 TCGv_i32 fp1
= tcg_temp_new_i32();
10436 gen_load_fpr32h(ctx
, fp0
, fs
);
10437 gen_load_fpr32(ctx
, fp1
, ft
);
10438 gen_store_fpr32(ctx
, fp1
, fd
);
10439 gen_store_fpr32h(ctx
, fp0
, fd
);
10440 tcg_temp_free_i32(fp0
);
10441 tcg_temp_free_i32(fp1
);
10448 TCGv_i32 fp0
= tcg_temp_new_i32();
10449 TCGv_i32 fp1
= tcg_temp_new_i32();
10451 gen_load_fpr32h(ctx
, fp0
, fs
);
10452 gen_load_fpr32h(ctx
, fp1
, ft
);
10453 gen_store_fpr32(ctx
, fp1
, fd
);
10454 gen_store_fpr32h(ctx
, fp0
, fd
);
10455 tcg_temp_free_i32(fp0
);
10456 tcg_temp_free_i32(fp1
);
10461 case OPC_CMP_UN_PS
:
10462 case OPC_CMP_EQ_PS
:
10463 case OPC_CMP_UEQ_PS
:
10464 case OPC_CMP_OLT_PS
:
10465 case OPC_CMP_ULT_PS
:
10466 case OPC_CMP_OLE_PS
:
10467 case OPC_CMP_ULE_PS
:
10468 case OPC_CMP_SF_PS
:
10469 case OPC_CMP_NGLE_PS
:
10470 case OPC_CMP_SEQ_PS
:
10471 case OPC_CMP_NGL_PS
:
10472 case OPC_CMP_LT_PS
:
10473 case OPC_CMP_NGE_PS
:
10474 case OPC_CMP_LE_PS
:
10475 case OPC_CMP_NGT_PS
:
10476 if (ctx
->opcode
& (1 << 6)) {
10477 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
10478 opn
= condnames_abs
[func
-48];
10480 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
10481 opn
= condnames
[func
-48];
10487 generate_exception (ctx
, EXCP_RI
);
10490 (void)opn
; /* avoid a compiler warning */
10493 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
10496 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
10499 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
10504 /* Coprocessor 3 (FPU) */
10505 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
10506 int fd
, int fs
, int base
, int index
)
10508 const char *opn
= "extended float load/store";
10510 TCGv t0
= tcg_temp_new();
10513 gen_load_gpr(t0
, index
);
10514 } else if (index
== 0) {
10515 gen_load_gpr(t0
, base
);
10517 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
10519 /* Don't do NOP if destination is zero: we must perform the actual
10525 TCGv_i32 fp0
= tcg_temp_new_i32();
10527 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
10528 tcg_gen_trunc_tl_i32(fp0
, t0
);
10529 gen_store_fpr32(ctx
, fp0
, fd
);
10530 tcg_temp_free_i32(fp0
);
10536 check_cp1_registers(ctx
, fd
);
10538 TCGv_i64 fp0
= tcg_temp_new_i64();
10539 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10540 gen_store_fpr64(ctx
, fp0
, fd
);
10541 tcg_temp_free_i64(fp0
);
10546 check_cp1_64bitmode(ctx
);
10547 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10549 TCGv_i64 fp0
= tcg_temp_new_i64();
10551 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10552 gen_store_fpr64(ctx
, fp0
, fd
);
10553 tcg_temp_free_i64(fp0
);
10560 TCGv_i32 fp0
= tcg_temp_new_i32();
10561 gen_load_fpr32(ctx
, fp0
, fs
);
10562 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
10563 tcg_temp_free_i32(fp0
);
10570 check_cp1_registers(ctx
, fs
);
10572 TCGv_i64 fp0
= tcg_temp_new_i64();
10573 gen_load_fpr64(ctx
, fp0
, fs
);
10574 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10575 tcg_temp_free_i64(fp0
);
10581 check_cp1_64bitmode(ctx
);
10582 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10584 TCGv_i64 fp0
= tcg_temp_new_i64();
10585 gen_load_fpr64(ctx
, fp0
, fs
);
10586 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10587 tcg_temp_free_i64(fp0
);
10594 (void)opn
; (void)store
; /* avoid compiler warnings */
10595 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
10596 regnames
[index
], regnames
[base
]);
10599 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
10600 int fd
, int fr
, int fs
, int ft
)
10602 const char *opn
= "flt3_arith";
10608 TCGv t0
= tcg_temp_local_new();
10609 TCGv_i32 fp
= tcg_temp_new_i32();
10610 TCGv_i32 fph
= tcg_temp_new_i32();
10611 TCGLabel
*l1
= gen_new_label();
10612 TCGLabel
*l2
= gen_new_label();
10614 gen_load_gpr(t0
, fr
);
10615 tcg_gen_andi_tl(t0
, t0
, 0x7);
10617 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
10618 gen_load_fpr32(ctx
, fp
, fs
);
10619 gen_load_fpr32h(ctx
, fph
, fs
);
10620 gen_store_fpr32(ctx
, fp
, fd
);
10621 gen_store_fpr32h(ctx
, fph
, fd
);
10624 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
10626 #ifdef TARGET_WORDS_BIGENDIAN
10627 gen_load_fpr32(ctx
, fp
, fs
);
10628 gen_load_fpr32h(ctx
, fph
, ft
);
10629 gen_store_fpr32h(ctx
, fp
, fd
);
10630 gen_store_fpr32(ctx
, fph
, fd
);
10632 gen_load_fpr32h(ctx
, fph
, fs
);
10633 gen_load_fpr32(ctx
, fp
, ft
);
10634 gen_store_fpr32(ctx
, fph
, fd
);
10635 gen_store_fpr32h(ctx
, fp
, fd
);
10638 tcg_temp_free_i32(fp
);
10639 tcg_temp_free_i32(fph
);
10646 TCGv_i32 fp0
= tcg_temp_new_i32();
10647 TCGv_i32 fp1
= tcg_temp_new_i32();
10648 TCGv_i32 fp2
= tcg_temp_new_i32();
10650 gen_load_fpr32(ctx
, fp0
, fs
);
10651 gen_load_fpr32(ctx
, fp1
, ft
);
10652 gen_load_fpr32(ctx
, fp2
, fr
);
10653 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10654 tcg_temp_free_i32(fp0
);
10655 tcg_temp_free_i32(fp1
);
10656 gen_store_fpr32(ctx
, fp2
, fd
);
10657 tcg_temp_free_i32(fp2
);
10663 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10665 TCGv_i64 fp0
= tcg_temp_new_i64();
10666 TCGv_i64 fp1
= tcg_temp_new_i64();
10667 TCGv_i64 fp2
= tcg_temp_new_i64();
10669 gen_load_fpr64(ctx
, fp0
, fs
);
10670 gen_load_fpr64(ctx
, fp1
, ft
);
10671 gen_load_fpr64(ctx
, fp2
, fr
);
10672 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10673 tcg_temp_free_i64(fp0
);
10674 tcg_temp_free_i64(fp1
);
10675 gen_store_fpr64(ctx
, fp2
, fd
);
10676 tcg_temp_free_i64(fp2
);
10683 TCGv_i64 fp0
= tcg_temp_new_i64();
10684 TCGv_i64 fp1
= tcg_temp_new_i64();
10685 TCGv_i64 fp2
= tcg_temp_new_i64();
10687 gen_load_fpr64(ctx
, fp0
, fs
);
10688 gen_load_fpr64(ctx
, fp1
, ft
);
10689 gen_load_fpr64(ctx
, fp2
, fr
);
10690 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10691 tcg_temp_free_i64(fp0
);
10692 tcg_temp_free_i64(fp1
);
10693 gen_store_fpr64(ctx
, fp2
, fd
);
10694 tcg_temp_free_i64(fp2
);
10701 TCGv_i32 fp0
= tcg_temp_new_i32();
10702 TCGv_i32 fp1
= tcg_temp_new_i32();
10703 TCGv_i32 fp2
= tcg_temp_new_i32();
10705 gen_load_fpr32(ctx
, fp0
, fs
);
10706 gen_load_fpr32(ctx
, fp1
, ft
);
10707 gen_load_fpr32(ctx
, fp2
, fr
);
10708 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10709 tcg_temp_free_i32(fp0
);
10710 tcg_temp_free_i32(fp1
);
10711 gen_store_fpr32(ctx
, fp2
, fd
);
10712 tcg_temp_free_i32(fp2
);
10718 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10720 TCGv_i64 fp0
= tcg_temp_new_i64();
10721 TCGv_i64 fp1
= tcg_temp_new_i64();
10722 TCGv_i64 fp2
= tcg_temp_new_i64();
10724 gen_load_fpr64(ctx
, fp0
, fs
);
10725 gen_load_fpr64(ctx
, fp1
, ft
);
10726 gen_load_fpr64(ctx
, fp2
, fr
);
10727 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10728 tcg_temp_free_i64(fp0
);
10729 tcg_temp_free_i64(fp1
);
10730 gen_store_fpr64(ctx
, fp2
, fd
);
10731 tcg_temp_free_i64(fp2
);
10738 TCGv_i64 fp0
= tcg_temp_new_i64();
10739 TCGv_i64 fp1
= tcg_temp_new_i64();
10740 TCGv_i64 fp2
= tcg_temp_new_i64();
10742 gen_load_fpr64(ctx
, fp0
, fs
);
10743 gen_load_fpr64(ctx
, fp1
, ft
);
10744 gen_load_fpr64(ctx
, fp2
, fr
);
10745 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10746 tcg_temp_free_i64(fp0
);
10747 tcg_temp_free_i64(fp1
);
10748 gen_store_fpr64(ctx
, fp2
, fd
);
10749 tcg_temp_free_i64(fp2
);
10756 TCGv_i32 fp0
= tcg_temp_new_i32();
10757 TCGv_i32 fp1
= tcg_temp_new_i32();
10758 TCGv_i32 fp2
= tcg_temp_new_i32();
10760 gen_load_fpr32(ctx
, fp0
, fs
);
10761 gen_load_fpr32(ctx
, fp1
, ft
);
10762 gen_load_fpr32(ctx
, fp2
, fr
);
10763 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10764 tcg_temp_free_i32(fp0
);
10765 tcg_temp_free_i32(fp1
);
10766 gen_store_fpr32(ctx
, fp2
, fd
);
10767 tcg_temp_free_i32(fp2
);
10773 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10775 TCGv_i64 fp0
= tcg_temp_new_i64();
10776 TCGv_i64 fp1
= tcg_temp_new_i64();
10777 TCGv_i64 fp2
= tcg_temp_new_i64();
10779 gen_load_fpr64(ctx
, fp0
, fs
);
10780 gen_load_fpr64(ctx
, fp1
, ft
);
10781 gen_load_fpr64(ctx
, fp2
, fr
);
10782 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10783 tcg_temp_free_i64(fp0
);
10784 tcg_temp_free_i64(fp1
);
10785 gen_store_fpr64(ctx
, fp2
, fd
);
10786 tcg_temp_free_i64(fp2
);
10793 TCGv_i64 fp0
= tcg_temp_new_i64();
10794 TCGv_i64 fp1
= tcg_temp_new_i64();
10795 TCGv_i64 fp2
= tcg_temp_new_i64();
10797 gen_load_fpr64(ctx
, fp0
, fs
);
10798 gen_load_fpr64(ctx
, fp1
, ft
);
10799 gen_load_fpr64(ctx
, fp2
, fr
);
10800 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10801 tcg_temp_free_i64(fp0
);
10802 tcg_temp_free_i64(fp1
);
10803 gen_store_fpr64(ctx
, fp2
, fd
);
10804 tcg_temp_free_i64(fp2
);
10811 TCGv_i32 fp0
= tcg_temp_new_i32();
10812 TCGv_i32 fp1
= tcg_temp_new_i32();
10813 TCGv_i32 fp2
= tcg_temp_new_i32();
10815 gen_load_fpr32(ctx
, fp0
, fs
);
10816 gen_load_fpr32(ctx
, fp1
, ft
);
10817 gen_load_fpr32(ctx
, fp2
, fr
);
10818 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10819 tcg_temp_free_i32(fp0
);
10820 tcg_temp_free_i32(fp1
);
10821 gen_store_fpr32(ctx
, fp2
, fd
);
10822 tcg_temp_free_i32(fp2
);
10828 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10830 TCGv_i64 fp0
= tcg_temp_new_i64();
10831 TCGv_i64 fp1
= tcg_temp_new_i64();
10832 TCGv_i64 fp2
= tcg_temp_new_i64();
10834 gen_load_fpr64(ctx
, fp0
, fs
);
10835 gen_load_fpr64(ctx
, fp1
, ft
);
10836 gen_load_fpr64(ctx
, fp2
, fr
);
10837 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10838 tcg_temp_free_i64(fp0
);
10839 tcg_temp_free_i64(fp1
);
10840 gen_store_fpr64(ctx
, fp2
, fd
);
10841 tcg_temp_free_i64(fp2
);
10848 TCGv_i64 fp0
= tcg_temp_new_i64();
10849 TCGv_i64 fp1
= tcg_temp_new_i64();
10850 TCGv_i64 fp2
= tcg_temp_new_i64();
10852 gen_load_fpr64(ctx
, fp0
, fs
);
10853 gen_load_fpr64(ctx
, fp1
, ft
);
10854 gen_load_fpr64(ctx
, fp2
, fr
);
10855 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10856 tcg_temp_free_i64(fp0
);
10857 tcg_temp_free_i64(fp1
);
10858 gen_store_fpr64(ctx
, fp2
, fd
);
10859 tcg_temp_free_i64(fp2
);
10865 generate_exception (ctx
, EXCP_RI
);
10868 (void)opn
; /* avoid a compiler warning */
10869 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
10870 fregnames
[fs
], fregnames
[ft
]);
10873 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
10877 #if !defined(CONFIG_USER_ONLY)
10878 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10879 Therefore only check the ISA in system mode. */
10880 check_insn(ctx
, ISA_MIPS32R2
);
10882 t0
= tcg_temp_new();
10886 save_cpu_state(ctx
, 1);
10887 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
10888 gen_store_gpr(t0
, rt
);
10891 save_cpu_state(ctx
, 1);
10892 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
10893 gen_store_gpr(t0
, rt
);
10896 save_cpu_state(ctx
, 1);
10897 gen_helper_rdhwr_cc(t0
, cpu_env
);
10898 gen_store_gpr(t0
, rt
);
10901 save_cpu_state(ctx
, 1);
10902 gen_helper_rdhwr_ccres(t0
, cpu_env
);
10903 gen_store_gpr(t0
, rt
);
10906 #if defined(CONFIG_USER_ONLY)
10907 tcg_gen_ld_tl(t0
, cpu_env
,
10908 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10909 gen_store_gpr(t0
, rt
);
10912 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
10913 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
10914 tcg_gen_ld_tl(t0
, cpu_env
,
10915 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10916 gen_store_gpr(t0
, rt
);
10918 generate_exception(ctx
, EXCP_RI
);
10922 default: /* Invalid */
10923 MIPS_INVAL("rdhwr");
10924 generate_exception(ctx
, EXCP_RI
);
10930 static inline void clear_branch_hflags(DisasContext
*ctx
)
10932 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
10933 if (ctx
->bstate
== BS_NONE
) {
10934 save_cpu_state(ctx
, 0);
10936 /* it is not safe to save ctx->hflags as hflags may be changed
10937 in execution time by the instruction in delay / forbidden slot. */
10938 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
10942 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
10944 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10945 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
10946 /* Branches completion */
10947 clear_branch_hflags(ctx
);
10948 ctx
->bstate
= BS_BRANCH
;
10949 /* FIXME: Need to clear can_do_io. */
10950 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
10951 case MIPS_HFLAG_FBNSLOT
:
10952 MIPS_DEBUG("forbidden slot");
10953 gen_goto_tb(ctx
, 0, ctx
->pc
+ insn_bytes
);
10956 /* unconditional branch */
10957 MIPS_DEBUG("unconditional branch");
10958 if (proc_hflags
& MIPS_HFLAG_BX
) {
10959 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
10961 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10963 case MIPS_HFLAG_BL
:
10964 /* blikely taken case */
10965 MIPS_DEBUG("blikely branch taken");
10966 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10968 case MIPS_HFLAG_BC
:
10969 /* Conditional branch */
10970 MIPS_DEBUG("conditional branch");
10972 TCGLabel
*l1
= gen_new_label();
10974 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
10975 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
10977 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10980 case MIPS_HFLAG_BR
:
10981 /* unconditional branch to register */
10982 MIPS_DEBUG("branch to register");
10983 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
10984 TCGv t0
= tcg_temp_new();
10985 TCGv_i32 t1
= tcg_temp_new_i32();
10987 tcg_gen_andi_tl(t0
, btarget
, 0x1);
10988 tcg_gen_trunc_tl_i32(t1
, t0
);
10990 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
10991 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
10992 tcg_gen_or_i32(hflags
, hflags
, t1
);
10993 tcg_temp_free_i32(t1
);
10995 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
10997 tcg_gen_mov_tl(cpu_PC
, btarget
);
10999 if (ctx
->singlestep_enabled
) {
11000 save_cpu_state(ctx
, 0);
11001 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
11003 tcg_gen_exit_tb(0);
11006 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
11012 /* Compact Branches */
11013 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
11014 int rs
, int rt
, int32_t offset
)
11016 int bcond_compute
= 0;
11017 TCGv t0
= tcg_temp_new();
11018 TCGv t1
= tcg_temp_new();
11019 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
11021 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11022 #ifdef MIPS_DEBUG_DISAS
11023 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11026 generate_exception(ctx
, EXCP_RI
);
11030 /* Load needed operands and calculate btarget */
11032 /* compact branch */
11033 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
11034 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
11035 gen_load_gpr(t0
, rs
);
11036 gen_load_gpr(t1
, rt
);
11038 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11039 if (rs
<= rt
&& rs
== 0) {
11040 /* OPC_BEQZALC, OPC_BNEZALC */
11041 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11044 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
11045 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
11046 gen_load_gpr(t0
, rs
);
11047 gen_load_gpr(t1
, rt
);
11049 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11051 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
11052 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
11053 if (rs
== 0 || rs
== rt
) {
11054 /* OPC_BLEZALC, OPC_BGEZALC */
11055 /* OPC_BGTZALC, OPC_BLTZALC */
11056 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11058 gen_load_gpr(t0
, rs
);
11059 gen_load_gpr(t1
, rt
);
11061 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11065 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11070 /* OPC_BEQZC, OPC_BNEZC */
11071 gen_load_gpr(t0
, rs
);
11073 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11075 /* OPC_JIC, OPC_JIALC */
11076 TCGv tbase
= tcg_temp_new();
11077 TCGv toffset
= tcg_temp_new();
11079 gen_load_gpr(tbase
, rt
);
11080 tcg_gen_movi_tl(toffset
, offset
);
11081 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
11082 tcg_temp_free(tbase
);
11083 tcg_temp_free(toffset
);
11087 MIPS_INVAL("Compact branch/jump");
11088 generate_exception(ctx
, EXCP_RI
);
11092 if (bcond_compute
== 0) {
11093 /* Uncoditional compact branch */
11096 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11099 ctx
->hflags
|= MIPS_HFLAG_BR
;
11102 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11105 ctx
->hflags
|= MIPS_HFLAG_B
;
11108 MIPS_INVAL("Compact branch/jump");
11109 generate_exception(ctx
, EXCP_RI
);
11113 /* Generating branch here as compact branches don't have delay slot */
11114 gen_branch(ctx
, 4);
11116 /* Conditional compact branch */
11117 TCGLabel
*fs
= gen_new_label();
11118 save_cpu_state(ctx
, 0);
11121 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
11122 if (rs
== 0 && rt
!= 0) {
11124 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
11125 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11127 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
11130 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
11133 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
11134 if (rs
== 0 && rt
!= 0) {
11136 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
11137 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11139 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
11142 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
11145 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
11146 if (rs
== 0 && rt
!= 0) {
11148 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
11149 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11151 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
11154 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
11157 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
11158 if (rs
== 0 && rt
!= 0) {
11160 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
11161 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11163 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
11166 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
11169 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
11170 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
11172 /* OPC_BOVC, OPC_BNVC */
11173 TCGv t2
= tcg_temp_new();
11174 TCGv t3
= tcg_temp_new();
11175 TCGv t4
= tcg_temp_new();
11176 TCGv input_overflow
= tcg_temp_new();
11178 gen_load_gpr(t0
, rs
);
11179 gen_load_gpr(t1
, rt
);
11180 tcg_gen_ext32s_tl(t2
, t0
);
11181 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
11182 tcg_gen_ext32s_tl(t3
, t1
);
11183 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
11184 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
11186 tcg_gen_add_tl(t4
, t2
, t3
);
11187 tcg_gen_ext32s_tl(t4
, t4
);
11188 tcg_gen_xor_tl(t2
, t2
, t3
);
11189 tcg_gen_xor_tl(t3
, t4
, t3
);
11190 tcg_gen_andc_tl(t2
, t3
, t2
);
11191 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
11192 tcg_gen_or_tl(t4
, t4
, input_overflow
);
11193 if (opc
== OPC_BOVC
) {
11195 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
11198 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
11200 tcg_temp_free(input_overflow
);
11204 } else if (rs
< rt
&& rs
== 0) {
11205 /* OPC_BEQZALC, OPC_BNEZALC */
11206 if (opc
== OPC_BEQZALC
) {
11208 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
11211 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
11214 /* OPC_BEQC, OPC_BNEC */
11215 if (opc
== OPC_BEQC
) {
11217 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
11220 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
11225 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
11228 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
11231 MIPS_INVAL("Compact conditional branch/jump");
11232 generate_exception(ctx
, EXCP_RI
);
11236 /* Generating branch here as compact branches don't have delay slot */
11237 gen_goto_tb(ctx
, 1, ctx
->btarget
);
11240 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
11241 MIPS_DEBUG("Compact conditional branch");
11249 /* ISA extensions (ASEs) */
11250 /* MIPS16 extension to MIPS32 */
11252 /* MIPS16 major opcodes */
11254 M16_OPC_ADDIUSP
= 0x00,
11255 M16_OPC_ADDIUPC
= 0x01,
11257 M16_OPC_JAL
= 0x03,
11258 M16_OPC_BEQZ
= 0x04,
11259 M16_OPC_BNEQZ
= 0x05,
11260 M16_OPC_SHIFT
= 0x06,
11262 M16_OPC_RRIA
= 0x08,
11263 M16_OPC_ADDIU8
= 0x09,
11264 M16_OPC_SLTI
= 0x0a,
11265 M16_OPC_SLTIU
= 0x0b,
11268 M16_OPC_CMPI
= 0x0e,
11272 M16_OPC_LWSP
= 0x12,
11274 M16_OPC_LBU
= 0x14,
11275 M16_OPC_LHU
= 0x15,
11276 M16_OPC_LWPC
= 0x16,
11277 M16_OPC_LWU
= 0x17,
11280 M16_OPC_SWSP
= 0x1a,
11282 M16_OPC_RRR
= 0x1c,
11284 M16_OPC_EXTEND
= 0x1e,
11288 /* I8 funct field */
11307 /* RR funct field */
11341 /* I64 funct field */
11349 I64_DADDIUPC
= 0x6,
11353 /* RR ry field for CNVT */
11355 RR_RY_CNVT_ZEB
= 0x0,
11356 RR_RY_CNVT_ZEH
= 0x1,
11357 RR_RY_CNVT_ZEW
= 0x2,
11358 RR_RY_CNVT_SEB
= 0x4,
11359 RR_RY_CNVT_SEH
= 0x5,
11360 RR_RY_CNVT_SEW
= 0x6,
11363 static int xlat (int r
)
11365 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11370 static void gen_mips16_save (DisasContext
*ctx
,
11371 int xsregs
, int aregs
,
11372 int do_ra
, int do_s0
, int do_s1
,
11375 TCGv t0
= tcg_temp_new();
11376 TCGv t1
= tcg_temp_new();
11377 TCGv t2
= tcg_temp_new();
11407 generate_exception(ctx
, EXCP_RI
);
11413 gen_base_offset_addr(ctx
, t0
, 29, 12);
11414 gen_load_gpr(t1
, 7);
11415 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11418 gen_base_offset_addr(ctx
, t0
, 29, 8);
11419 gen_load_gpr(t1
, 6);
11420 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11423 gen_base_offset_addr(ctx
, t0
, 29, 4);
11424 gen_load_gpr(t1
, 5);
11425 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11428 gen_base_offset_addr(ctx
, t0
, 29, 0);
11429 gen_load_gpr(t1
, 4);
11430 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11433 gen_load_gpr(t0
, 29);
11435 #define DECR_AND_STORE(reg) do { \
11436 tcg_gen_movi_tl(t2, -4); \
11437 gen_op_addr_add(ctx, t0, t0, t2); \
11438 gen_load_gpr(t1, reg); \
11439 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11443 DECR_AND_STORE(31);
11448 DECR_AND_STORE(30);
11451 DECR_AND_STORE(23);
11454 DECR_AND_STORE(22);
11457 DECR_AND_STORE(21);
11460 DECR_AND_STORE(20);
11463 DECR_AND_STORE(19);
11466 DECR_AND_STORE(18);
11470 DECR_AND_STORE(17);
11473 DECR_AND_STORE(16);
11503 generate_exception(ctx
, EXCP_RI
);
11519 #undef DECR_AND_STORE
11521 tcg_gen_movi_tl(t2
, -framesize
);
11522 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11528 static void gen_mips16_restore (DisasContext
*ctx
,
11529 int xsregs
, int aregs
,
11530 int do_ra
, int do_s0
, int do_s1
,
11534 TCGv t0
= tcg_temp_new();
11535 TCGv t1
= tcg_temp_new();
11536 TCGv t2
= tcg_temp_new();
11538 tcg_gen_movi_tl(t2
, framesize
);
11539 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
11541 #define DECR_AND_LOAD(reg) do { \
11542 tcg_gen_movi_tl(t2, -4); \
11543 gen_op_addr_add(ctx, t0, t0, t2); \
11544 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11545 gen_store_gpr(t1, reg); \
11609 generate_exception(ctx
, EXCP_RI
);
11625 #undef DECR_AND_LOAD
11627 tcg_gen_movi_tl(t2
, framesize
);
11628 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11634 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
11635 int is_64_bit
, int extended
)
11639 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11640 generate_exception(ctx
, EXCP_RI
);
11644 t0
= tcg_temp_new();
11646 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
11647 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
11649 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11655 #if defined(TARGET_MIPS64)
11656 static void decode_i64_mips16 (DisasContext
*ctx
,
11657 int ry
, int funct
, int16_t offset
,
11662 check_insn(ctx
, ISA_MIPS3
);
11663 check_mips_64(ctx
);
11664 offset
= extended
? offset
: offset
<< 3;
11665 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
11668 check_insn(ctx
, ISA_MIPS3
);
11669 check_mips_64(ctx
);
11670 offset
= extended
? offset
: offset
<< 3;
11671 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
11674 check_insn(ctx
, ISA_MIPS3
);
11675 check_mips_64(ctx
);
11676 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
11677 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
11680 check_insn(ctx
, ISA_MIPS3
);
11681 check_mips_64(ctx
);
11682 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
11683 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
11686 check_insn(ctx
, ISA_MIPS3
);
11687 check_mips_64(ctx
);
11688 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11689 generate_exception(ctx
, EXCP_RI
);
11691 offset
= extended
? offset
: offset
<< 3;
11692 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
11696 check_insn(ctx
, ISA_MIPS3
);
11697 check_mips_64(ctx
);
11698 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
11699 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
11702 check_insn(ctx
, ISA_MIPS3
);
11703 check_mips_64(ctx
);
11704 offset
= extended
? offset
: offset
<< 2;
11705 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
11708 check_insn(ctx
, ISA_MIPS3
);
11709 check_mips_64(ctx
);
11710 offset
= extended
? offset
: offset
<< 2;
11711 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
11717 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11719 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11720 int op
, rx
, ry
, funct
, sa
;
11721 int16_t imm
, offset
;
11723 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
11724 op
= (ctx
->opcode
>> 11) & 0x1f;
11725 sa
= (ctx
->opcode
>> 22) & 0x1f;
11726 funct
= (ctx
->opcode
>> 8) & 0x7;
11727 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11728 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11729 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
11730 | ((ctx
->opcode
>> 21) & 0x3f) << 5
11731 | (ctx
->opcode
& 0x1f));
11733 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11736 case M16_OPC_ADDIUSP
:
11737 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11739 case M16_OPC_ADDIUPC
:
11740 gen_addiupc(ctx
, rx
, imm
, 0, 1);
11743 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
11744 /* No delay slot, so just process as a normal instruction */
11747 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
11748 /* No delay slot, so just process as a normal instruction */
11750 case M16_OPC_BNEQZ
:
11751 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
11752 /* No delay slot, so just process as a normal instruction */
11754 case M16_OPC_SHIFT
:
11755 switch (ctx
->opcode
& 0x3) {
11757 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11760 #if defined(TARGET_MIPS64)
11761 check_mips_64(ctx
);
11762 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11764 generate_exception(ctx
, EXCP_RI
);
11768 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11771 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11775 #if defined(TARGET_MIPS64)
11777 check_insn(ctx
, ISA_MIPS3
);
11778 check_mips_64(ctx
);
11779 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
11783 imm
= ctx
->opcode
& 0xf;
11784 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
11785 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
11786 imm
= (int16_t) (imm
<< 1) >> 1;
11787 if ((ctx
->opcode
>> 4) & 0x1) {
11788 #if defined(TARGET_MIPS64)
11789 check_mips_64(ctx
);
11790 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11792 generate_exception(ctx
, EXCP_RI
);
11795 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11798 case M16_OPC_ADDIU8
:
11799 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11802 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11804 case M16_OPC_SLTIU
:
11805 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11810 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
11813 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
11816 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
11819 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
11822 check_insn(ctx
, ISA_MIPS32
);
11824 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
11825 int aregs
= (ctx
->opcode
>> 16) & 0xf;
11826 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
11827 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
11828 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
11829 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
11830 | (ctx
->opcode
& 0xf)) << 3;
11832 if (ctx
->opcode
& (1 << 7)) {
11833 gen_mips16_save(ctx
, xsregs
, aregs
,
11834 do_ra
, do_s0
, do_s1
,
11837 gen_mips16_restore(ctx
, xsregs
, aregs
,
11838 do_ra
, do_s0
, do_s1
,
11844 generate_exception(ctx
, EXCP_RI
);
11849 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
11852 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
11854 #if defined(TARGET_MIPS64)
11856 check_insn(ctx
, ISA_MIPS3
);
11857 check_mips_64(ctx
);
11858 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
11862 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11865 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
11868 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
11871 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
11874 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11877 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
11880 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
11882 #if defined(TARGET_MIPS64)
11884 check_insn(ctx
, ISA_MIPS3
);
11885 check_mips_64(ctx
);
11886 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
11890 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11893 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
11896 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
11899 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
11901 #if defined(TARGET_MIPS64)
11903 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
11907 generate_exception(ctx
, EXCP_RI
);
11914 static inline bool is_uhi(int sdbbp_code
)
11916 #ifdef CONFIG_USER_ONLY
11919 return semihosting_enabled() && sdbbp_code
== 1;
11923 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11927 int op
, cnvt_op
, op1
, offset
;
11931 op
= (ctx
->opcode
>> 11) & 0x1f;
11932 sa
= (ctx
->opcode
>> 2) & 0x7;
11933 sa
= sa
== 0 ? 8 : sa
;
11934 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11935 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
11936 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11937 op1
= offset
= ctx
->opcode
& 0x1f;
11942 case M16_OPC_ADDIUSP
:
11944 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
11946 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11949 case M16_OPC_ADDIUPC
:
11950 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
11953 offset
= (ctx
->opcode
& 0x7ff) << 1;
11954 offset
= (int16_t)(offset
<< 4) >> 4;
11955 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
11956 /* No delay slot, so just process as a normal instruction */
11959 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11960 offset
= (((ctx
->opcode
& 0x1f) << 21)
11961 | ((ctx
->opcode
>> 5) & 0x1f) << 16
11963 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
11964 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
11968 gen_compute_branch(ctx
, OPC_BEQ
, 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_BNEQZ
:
11973 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
11974 ((int8_t)ctx
->opcode
) << 1, 0);
11975 /* No delay slot, so just process as a normal instruction */
11977 case M16_OPC_SHIFT
:
11978 switch (ctx
->opcode
& 0x3) {
11980 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11983 #if defined(TARGET_MIPS64)
11984 check_insn(ctx
, ISA_MIPS3
);
11985 check_mips_64(ctx
);
11986 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11988 generate_exception(ctx
, EXCP_RI
);
11992 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11995 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11999 #if defined(TARGET_MIPS64)
12001 check_insn(ctx
, ISA_MIPS3
);
12002 check_mips_64(ctx
);
12003 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
12008 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
12010 if ((ctx
->opcode
>> 4) & 1) {
12011 #if defined(TARGET_MIPS64)
12012 check_insn(ctx
, ISA_MIPS3
);
12013 check_mips_64(ctx
);
12014 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
12016 generate_exception(ctx
, EXCP_RI
);
12019 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
12023 case M16_OPC_ADDIU8
:
12025 int16_t imm
= (int8_t) ctx
->opcode
;
12027 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
12032 int16_t imm
= (uint8_t) ctx
->opcode
;
12033 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
12036 case M16_OPC_SLTIU
:
12038 int16_t imm
= (uint8_t) ctx
->opcode
;
12039 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
12046 funct
= (ctx
->opcode
>> 8) & 0x7;
12049 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
12050 ((int8_t)ctx
->opcode
) << 1, 0);
12053 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
12054 ((int8_t)ctx
->opcode
) << 1, 0);
12057 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
12060 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
12061 ((int8_t)ctx
->opcode
) << 3);
12064 check_insn(ctx
, ISA_MIPS32
);
12066 int do_ra
= ctx
->opcode
& (1 << 6);
12067 int do_s0
= ctx
->opcode
& (1 << 5);
12068 int do_s1
= ctx
->opcode
& (1 << 4);
12069 int framesize
= ctx
->opcode
& 0xf;
12071 if (framesize
== 0) {
12074 framesize
= framesize
<< 3;
12077 if (ctx
->opcode
& (1 << 7)) {
12078 gen_mips16_save(ctx
, 0, 0,
12079 do_ra
, do_s0
, do_s1
, framesize
);
12081 gen_mips16_restore(ctx
, 0, 0,
12082 do_ra
, do_s0
, do_s1
, framesize
);
12088 int rz
= xlat(ctx
->opcode
& 0x7);
12090 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
12091 ((ctx
->opcode
>> 5) & 0x7);
12092 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
12096 reg32
= ctx
->opcode
& 0x1f;
12097 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
12100 generate_exception(ctx
, EXCP_RI
);
12107 int16_t imm
= (uint8_t) ctx
->opcode
;
12109 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
12114 int16_t imm
= (uint8_t) ctx
->opcode
;
12115 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
12118 #if defined(TARGET_MIPS64)
12120 check_insn(ctx
, ISA_MIPS3
);
12121 check_mips_64(ctx
);
12122 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
12126 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
12129 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
12132 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
12135 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
12138 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
12141 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
12144 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
12146 #if defined (TARGET_MIPS64)
12148 check_insn(ctx
, ISA_MIPS3
);
12149 check_mips_64(ctx
);
12150 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
12154 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
12157 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
12160 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
12163 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
12167 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
12170 switch (ctx
->opcode
& 0x3) {
12172 mips32_op
= OPC_ADDU
;
12175 mips32_op
= OPC_SUBU
;
12177 #if defined(TARGET_MIPS64)
12179 mips32_op
= OPC_DADDU
;
12180 check_insn(ctx
, ISA_MIPS3
);
12181 check_mips_64(ctx
);
12184 mips32_op
= OPC_DSUBU
;
12185 check_insn(ctx
, ISA_MIPS3
);
12186 check_mips_64(ctx
);
12190 generate_exception(ctx
, EXCP_RI
);
12194 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
12203 int nd
= (ctx
->opcode
>> 7) & 0x1;
12204 int link
= (ctx
->opcode
>> 6) & 0x1;
12205 int ra
= (ctx
->opcode
>> 5) & 0x1;
12208 check_insn(ctx
, ISA_MIPS32
);
12217 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
12222 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
12223 gen_helper_do_semihosting(cpu_env
);
12225 /* XXX: not clear which exception should be raised
12226 * when in debug mode...
12228 check_insn(ctx
, ISA_MIPS32
);
12229 generate_exception(ctx
, EXCP_DBp
);
12233 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
12236 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
12239 generate_exception(ctx
, EXCP_BREAK
);
12242 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
12245 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
12248 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
12250 #if defined (TARGET_MIPS64)
12252 check_insn(ctx
, ISA_MIPS3
);
12253 check_mips_64(ctx
);
12254 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
12258 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
12261 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
12264 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
12267 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
12270 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
12273 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
12276 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
12279 check_insn(ctx
, ISA_MIPS32
);
12281 case RR_RY_CNVT_ZEB
:
12282 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12284 case RR_RY_CNVT_ZEH
:
12285 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12287 case RR_RY_CNVT_SEB
:
12288 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12290 case RR_RY_CNVT_SEH
:
12291 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12293 #if defined (TARGET_MIPS64)
12294 case RR_RY_CNVT_ZEW
:
12295 check_insn(ctx
, ISA_MIPS64
);
12296 check_mips_64(ctx
);
12297 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12299 case RR_RY_CNVT_SEW
:
12300 check_insn(ctx
, ISA_MIPS64
);
12301 check_mips_64(ctx
);
12302 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12306 generate_exception(ctx
, EXCP_RI
);
12311 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
12313 #if defined (TARGET_MIPS64)
12315 check_insn(ctx
, ISA_MIPS3
);
12316 check_mips_64(ctx
);
12317 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
12320 check_insn(ctx
, ISA_MIPS3
);
12321 check_mips_64(ctx
);
12322 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
12325 check_insn(ctx
, ISA_MIPS3
);
12326 check_mips_64(ctx
);
12327 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
12330 check_insn(ctx
, ISA_MIPS3
);
12331 check_mips_64(ctx
);
12332 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
12336 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
12339 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
12342 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
12345 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
12347 #if defined (TARGET_MIPS64)
12349 check_insn(ctx
, ISA_MIPS3
);
12350 check_mips_64(ctx
);
12351 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
12354 check_insn(ctx
, ISA_MIPS3
);
12355 check_mips_64(ctx
);
12356 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
12359 check_insn(ctx
, ISA_MIPS3
);
12360 check_mips_64(ctx
);
12361 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
12364 check_insn(ctx
, ISA_MIPS3
);
12365 check_mips_64(ctx
);
12366 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
12370 generate_exception(ctx
, EXCP_RI
);
12374 case M16_OPC_EXTEND
:
12375 decode_extended_mips16_opc(env
, ctx
);
12378 #if defined(TARGET_MIPS64)
12380 funct
= (ctx
->opcode
>> 8) & 0x7;
12381 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
12385 generate_exception(ctx
, EXCP_RI
);
12392 /* microMIPS extension to MIPS32/MIPS64 */
12395 * microMIPS32/microMIPS64 major opcodes
12397 * 1. MIPS Architecture for Programmers Volume II-B:
12398 * The microMIPS32 Instruction Set (Revision 3.05)
12400 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12402 * 2. MIPS Architecture For Programmers Volume II-A:
12403 * The MIPS64 Instruction Set (Revision 3.51)
12433 POOL32S
= 0x16, /* MIPS64 */
12434 DADDIU32
= 0x17, /* MIPS64 */
12463 /* 0x29 is reserved */
12476 /* 0x31 is reserved */
12489 SD32
= 0x36, /* MIPS64 */
12490 LD32
= 0x37, /* MIPS64 */
12492 /* 0x39 is reserved */
12508 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12518 /* POOL32A encoding of minor opcode field */
12521 /* These opcodes are distinguished only by bits 9..6; those bits are
12522 * what are recorded below. */
12558 /* The following can be distinguished by their lower 6 bits. */
12566 /* POOL32AXF encoding of minor opcode field extension */
12569 * 1. MIPS Architecture for Programmers Volume II-B:
12570 * The microMIPS32 Instruction Set (Revision 3.05)
12572 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12574 * 2. MIPS Architecture for Programmers VolumeIV-e:
12575 * The MIPS DSP Application-Specific Extension
12576 * to the microMIPS32 Architecture (Revision 2.34)
12578 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12593 /* begin of microMIPS32 DSP */
12595 /* bits 13..12 for 0x01 */
12601 /* bits 13..12 for 0x2a */
12607 /* bits 13..12 for 0x32 */
12611 /* end of microMIPS32 DSP */
12613 /* bits 15..12 for 0x2c */
12630 /* bits 15..12 for 0x34 */
12638 /* bits 15..12 for 0x3c */
12640 JR
= 0x0, /* alias */
12648 /* bits 15..12 for 0x05 */
12652 /* bits 15..12 for 0x0d */
12664 /* bits 15..12 for 0x15 */
12670 /* bits 15..12 for 0x1d */
12674 /* bits 15..12 for 0x2d */
12679 /* bits 15..12 for 0x35 */
12686 /* POOL32B encoding of minor opcode field (bits 15..12) */
12702 /* POOL32C encoding of minor opcode field (bits 15..12) */
12710 /* 0xa is reserved */
12717 /* 0x6 is reserved */
12723 /* POOL32F encoding of minor opcode field (bits 5..0) */
12726 /* These are the bit 7..6 values */
12735 /* These are the bit 8..6 values */
12760 MOVZ_FMT_05
= 0x05,
12794 CABS_COND_FMT
= 0x1c, /* MIPS3D */
12801 /* POOL32Fxf encoding of minor opcode extension field */
12839 /* POOL32I encoding of minor opcode field (bits 25..21) */
12869 /* These overlap and are distinguished by bit16 of the instruction */
12878 /* POOL16A encoding of minor opcode field */
12885 /* POOL16B encoding of minor opcode field */
12892 /* POOL16C encoding of minor opcode field */
12912 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12932 /* POOL16D encoding of minor opcode field */
12939 /* POOL16E encoding of minor opcode field */
12946 static int mmreg (int r
)
12948 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12953 /* Used for 16-bit store instructions. */
12954 static int mmreg2 (int r
)
12956 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12961 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12962 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12963 #define uMIPS_RS2(op) uMIPS_RS(op)
12964 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12965 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12966 #define uMIPS_RS5(op) (op & 0x1f)
12968 /* Signed immediate */
12969 #define SIMM(op, start, width) \
12970 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12973 /* Zero-extended immediate */
12974 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12976 static void gen_addiur1sp(DisasContext
*ctx
)
12978 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12980 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
12983 static void gen_addiur2(DisasContext
*ctx
)
12985 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12986 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12987 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12989 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
12992 static void gen_addiusp(DisasContext
*ctx
)
12994 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
12997 if (encoded
<= 1) {
12998 decoded
= 256 + encoded
;
12999 } else if (encoded
<= 255) {
13001 } else if (encoded
<= 509) {
13002 decoded
= encoded
- 512;
13004 decoded
= encoded
- 768;
13007 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
13010 static void gen_addius5(DisasContext
*ctx
)
13012 int imm
= SIMM(ctx
->opcode
, 1, 4);
13013 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13015 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
13018 static void gen_andi16(DisasContext
*ctx
)
13020 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13021 31, 32, 63, 64, 255, 32768, 65535 };
13022 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13023 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
13024 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
13026 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
13029 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
13030 int base
, int16_t offset
)
13032 const char *opn
= "ldst_multiple";
13036 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13037 generate_exception(ctx
, EXCP_RI
);
13041 t0
= tcg_temp_new();
13043 gen_base_offset_addr(ctx
, t0
, base
, offset
);
13045 t1
= tcg_const_tl(reglist
);
13046 t2
= tcg_const_i32(ctx
->mem_idx
);
13048 save_cpu_state(ctx
, 1);
13051 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
13055 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
13058 #ifdef TARGET_MIPS64
13060 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
13064 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
13070 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
13073 tcg_temp_free_i32(t2
);
13077 static void gen_pool16c_insn(DisasContext
*ctx
)
13079 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
13080 int rs
= mmreg(ctx
->opcode
& 0x7);
13082 switch (((ctx
->opcode
) >> 4) & 0x3f) {
13087 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
13093 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
13099 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
13105 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
13112 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
13113 int offset
= ZIMM(ctx
->opcode
, 0, 4);
13115 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
13124 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
13125 int offset
= ZIMM(ctx
->opcode
, 0, 4);
13127 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
13134 int reg
= ctx
->opcode
& 0x1f;
13136 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
13142 int reg
= ctx
->opcode
& 0x1f;
13143 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
13144 /* Let normal delay slot handling in our caller take us
13145 to the branch target. */
13150 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
13151 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13155 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
13156 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13160 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
13164 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
13167 generate_exception(ctx
, EXCP_BREAK
);
13170 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
13171 gen_helper_do_semihosting(cpu_env
);
13173 /* XXX: not clear which exception should be raised
13174 * when in debug mode...
13176 check_insn(ctx
, ISA_MIPS32
);
13177 generate_exception(ctx
, EXCP_DBp
);
13180 case JRADDIUSP
+ 0:
13181 case JRADDIUSP
+ 1:
13183 int imm
= ZIMM(ctx
->opcode
, 0, 5);
13184 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
13185 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
13186 /* Let normal delay slot handling in our caller take us
13187 to the branch target. */
13191 generate_exception(ctx
, EXCP_RI
);
13196 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
13199 int rd
, rs
, re
, rt
;
13200 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13201 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13202 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13203 rd
= rd_enc
[enc_dest
];
13204 re
= re_enc
[enc_dest
];
13205 rs
= rs_rt_enc
[enc_rs
];
13206 rt
= rs_rt_enc
[enc_rt
];
13208 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
13210 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
13213 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
13215 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
13219 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
13221 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
13222 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
13224 switch (ctx
->opcode
& 0xf) {
13226 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
13229 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
13233 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
13234 int offset
= extract32(ctx
->opcode
, 4, 4);
13235 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
13238 case R6_JRC16
: /* JRCADDIUSP */
13239 if ((ctx
->opcode
>> 4) & 1) {
13241 int imm
= extract32(ctx
->opcode
, 5, 5);
13242 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
13243 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
13246 int rs
= extract32(ctx
->opcode
, 5, 5);
13247 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
13250 case MOVEP
... MOVEP_07
:
13251 case MOVEP_0C
... MOVEP_0F
:
13253 int enc_dest
= uMIPS_RD(ctx
->opcode
);
13254 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
13255 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
13256 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
13260 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
13263 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
13267 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
13268 int offset
= extract32(ctx
->opcode
, 4, 4);
13269 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
13272 case JALRC16
: /* BREAK16, SDBBP16 */
13273 switch (ctx
->opcode
& 0x3f) {
13275 case JALRC16
+ 0x20:
13277 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
13282 generate_exception(ctx
, EXCP_BREAK
);
13286 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
13287 gen_helper_do_semihosting(cpu_env
);
13289 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
13290 generate_exception(ctx
, EXCP_RI
);
13292 generate_exception(ctx
, EXCP_DBp
);
13299 generate_exception(ctx
, EXCP_RI
);
13304 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
13306 TCGv t0
= tcg_temp_new();
13307 TCGv t1
= tcg_temp_new();
13309 gen_load_gpr(t0
, base
);
13312 gen_load_gpr(t1
, index
);
13313 tcg_gen_shli_tl(t1
, t1
, 2);
13314 gen_op_addr_add(ctx
, t0
, t1
, t0
);
13317 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13318 gen_store_gpr(t1
, rd
);
13324 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
13325 int base
, int16_t offset
)
13327 const char *opn
= "ldst_pair";
13330 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
13331 generate_exception(ctx
, EXCP_RI
);
13335 t0
= tcg_temp_new();
13336 t1
= tcg_temp_new();
13338 gen_base_offset_addr(ctx
, t0
, base
, offset
);
13343 generate_exception(ctx
, EXCP_RI
);
13346 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13347 gen_store_gpr(t1
, rd
);
13348 tcg_gen_movi_tl(t1
, 4);
13349 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13350 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13351 gen_store_gpr(t1
, rd
+1);
13355 gen_load_gpr(t1
, rd
);
13356 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13357 tcg_gen_movi_tl(t1
, 4);
13358 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13359 gen_load_gpr(t1
, rd
+1);
13360 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13363 #ifdef TARGET_MIPS64
13366 generate_exception(ctx
, EXCP_RI
);
13369 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13370 gen_store_gpr(t1
, rd
);
13371 tcg_gen_movi_tl(t1
, 8);
13372 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13373 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13374 gen_store_gpr(t1
, rd
+1);
13378 gen_load_gpr(t1
, rd
);
13379 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13380 tcg_gen_movi_tl(t1
, 8);
13381 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13382 gen_load_gpr(t1
, rd
+1);
13383 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13388 (void)opn
; /* avoid a compiler warning */
13389 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
13394 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
13396 int extension
= (ctx
->opcode
>> 6) & 0x3f;
13397 int minor
= (ctx
->opcode
>> 12) & 0xf;
13398 uint32_t mips32_op
;
13400 switch (extension
) {
13402 mips32_op
= OPC_TEQ
;
13405 mips32_op
= OPC_TGE
;
13408 mips32_op
= OPC_TGEU
;
13411 mips32_op
= OPC_TLT
;
13414 mips32_op
= OPC_TLTU
;
13417 mips32_op
= OPC_TNE
;
13419 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
13421 #ifndef CONFIG_USER_ONLY
13424 check_cp0_enabled(ctx
);
13426 /* Treat as NOP. */
13429 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
13433 check_cp0_enabled(ctx
);
13435 TCGv t0
= tcg_temp_new();
13437 gen_load_gpr(t0
, rt
);
13438 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
13444 switch (minor
& 3) {
13446 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13449 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13452 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13455 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13458 goto pool32axf_invalid
;
13462 switch (minor
& 3) {
13464 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13467 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13470 goto pool32axf_invalid
;
13476 check_insn(ctx
, ISA_MIPS32R6
);
13477 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
13480 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
13483 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
13486 mips32_op
= OPC_CLO
;
13489 mips32_op
= OPC_CLZ
;
13491 check_insn(ctx
, ISA_MIPS32
);
13492 gen_cl(ctx
, mips32_op
, rt
, rs
);
13495 gen_rdhwr(ctx
, rt
, rs
);
13498 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
13501 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13502 mips32_op
= OPC_MULT
;
13505 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13506 mips32_op
= OPC_MULTU
;
13509 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13510 mips32_op
= OPC_DIV
;
13513 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13514 mips32_op
= OPC_DIVU
;
13517 check_insn(ctx
, ISA_MIPS32
);
13518 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
13521 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13522 mips32_op
= OPC_MADD
;
13525 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13526 mips32_op
= OPC_MADDU
;
13529 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13530 mips32_op
= OPC_MSUB
;
13533 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13534 mips32_op
= OPC_MSUBU
;
13536 check_insn(ctx
, ISA_MIPS32
);
13537 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
13540 goto pool32axf_invalid
;
13551 generate_exception_err(ctx
, EXCP_CpU
, 2);
13554 goto pool32axf_invalid
;
13559 case JALR
: /* JALRC */
13560 case JALR_HB
: /* JALRC_HB */
13561 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13562 /* JALRC, JALRC_HB */
13563 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
13565 /* JALR, JALR_HB */
13566 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
13567 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13572 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13573 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
13574 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13577 goto pool32axf_invalid
;
13583 check_cp0_enabled(ctx
);
13584 check_insn(ctx
, ISA_MIPS32R2
);
13585 gen_load_srsgpr(rs
, rt
);
13588 check_cp0_enabled(ctx
);
13589 check_insn(ctx
, ISA_MIPS32R2
);
13590 gen_store_srsgpr(rs
, rt
);
13593 goto pool32axf_invalid
;
13596 #ifndef CONFIG_USER_ONLY
13600 mips32_op
= OPC_TLBP
;
13603 mips32_op
= OPC_TLBR
;
13606 mips32_op
= OPC_TLBWI
;
13609 mips32_op
= OPC_TLBWR
;
13612 mips32_op
= OPC_TLBINV
;
13615 mips32_op
= OPC_TLBINVF
;
13618 mips32_op
= OPC_WAIT
;
13621 mips32_op
= OPC_DERET
;
13624 mips32_op
= OPC_ERET
;
13626 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
13629 goto pool32axf_invalid
;
13635 check_cp0_enabled(ctx
);
13637 TCGv t0
= tcg_temp_new();
13639 save_cpu_state(ctx
, 1);
13640 gen_helper_di(t0
, cpu_env
);
13641 gen_store_gpr(t0
, rs
);
13642 /* Stop translation as we may have switched the execution mode */
13643 ctx
->bstate
= BS_STOP
;
13648 check_cp0_enabled(ctx
);
13650 TCGv t0
= tcg_temp_new();
13652 save_cpu_state(ctx
, 1);
13653 gen_helper_ei(t0
, cpu_env
);
13654 gen_store_gpr(t0
, rs
);
13655 /* Stop translation as we may have switched the execution mode */
13656 ctx
->bstate
= BS_STOP
;
13661 goto pool32axf_invalid
;
13671 generate_exception(ctx
, EXCP_SYSCALL
);
13672 ctx
->bstate
= BS_STOP
;
13675 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
13676 gen_helper_do_semihosting(cpu_env
);
13678 check_insn(ctx
, ISA_MIPS32
);
13679 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
13680 generate_exception(ctx
, EXCP_RI
);
13682 generate_exception(ctx
, EXCP_DBp
);
13687 goto pool32axf_invalid
;
13691 switch (minor
& 3) {
13693 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
13696 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
13699 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
13702 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
13705 goto pool32axf_invalid
;
13709 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13712 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
13715 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
13718 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
13721 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
13724 goto pool32axf_invalid
;
13729 MIPS_INVAL("pool32axf");
13730 generate_exception(ctx
, EXCP_RI
);
13735 /* Values for microMIPS fmt field. Variable-width, depending on which
13736 formats the instruction supports. */
13755 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
13757 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
13758 uint32_t mips32_op
;
13760 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13761 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13762 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13764 switch (extension
) {
13765 case FLOAT_1BIT_FMT(CFC1
, 0):
13766 mips32_op
= OPC_CFC1
;
13768 case FLOAT_1BIT_FMT(CTC1
, 0):
13769 mips32_op
= OPC_CTC1
;
13771 case FLOAT_1BIT_FMT(MFC1
, 0):
13772 mips32_op
= OPC_MFC1
;
13774 case FLOAT_1BIT_FMT(MTC1
, 0):
13775 mips32_op
= OPC_MTC1
;
13777 case FLOAT_1BIT_FMT(MFHC1
, 0):
13778 mips32_op
= OPC_MFHC1
;
13780 case FLOAT_1BIT_FMT(MTHC1
, 0):
13781 mips32_op
= OPC_MTHC1
;
13783 gen_cp1(ctx
, mips32_op
, rt
, rs
);
13786 /* Reciprocal square root */
13787 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
13788 mips32_op
= OPC_RSQRT_S
;
13790 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
13791 mips32_op
= OPC_RSQRT_D
;
13795 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
13796 mips32_op
= OPC_SQRT_S
;
13798 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
13799 mips32_op
= OPC_SQRT_D
;
13803 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
13804 mips32_op
= OPC_RECIP_S
;
13806 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
13807 mips32_op
= OPC_RECIP_D
;
13811 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
13812 mips32_op
= OPC_FLOOR_L_S
;
13814 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
13815 mips32_op
= OPC_FLOOR_L_D
;
13817 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
13818 mips32_op
= OPC_FLOOR_W_S
;
13820 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
13821 mips32_op
= OPC_FLOOR_W_D
;
13825 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
13826 mips32_op
= OPC_CEIL_L_S
;
13828 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
13829 mips32_op
= OPC_CEIL_L_D
;
13831 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
13832 mips32_op
= OPC_CEIL_W_S
;
13834 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
13835 mips32_op
= OPC_CEIL_W_D
;
13839 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
13840 mips32_op
= OPC_TRUNC_L_S
;
13842 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
13843 mips32_op
= OPC_TRUNC_L_D
;
13845 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
13846 mips32_op
= OPC_TRUNC_W_S
;
13848 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
13849 mips32_op
= OPC_TRUNC_W_D
;
13853 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
13854 mips32_op
= OPC_ROUND_L_S
;
13856 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
13857 mips32_op
= OPC_ROUND_L_D
;
13859 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
13860 mips32_op
= OPC_ROUND_W_S
;
13862 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
13863 mips32_op
= OPC_ROUND_W_D
;
13866 /* Integer to floating-point conversion */
13867 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
13868 mips32_op
= OPC_CVT_L_S
;
13870 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
13871 mips32_op
= OPC_CVT_L_D
;
13873 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
13874 mips32_op
= OPC_CVT_W_S
;
13876 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
13877 mips32_op
= OPC_CVT_W_D
;
13880 /* Paired-foo conversions */
13881 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
13882 mips32_op
= OPC_CVT_S_PL
;
13884 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
13885 mips32_op
= OPC_CVT_S_PU
;
13887 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
13888 mips32_op
= OPC_CVT_PW_PS
;
13890 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
13891 mips32_op
= OPC_CVT_PS_PW
;
13894 /* Floating-point moves */
13895 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
13896 mips32_op
= OPC_MOV_S
;
13898 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
13899 mips32_op
= OPC_MOV_D
;
13901 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
13902 mips32_op
= OPC_MOV_PS
;
13905 /* Absolute value */
13906 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
13907 mips32_op
= OPC_ABS_S
;
13909 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
13910 mips32_op
= OPC_ABS_D
;
13912 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
13913 mips32_op
= OPC_ABS_PS
;
13917 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
13918 mips32_op
= OPC_NEG_S
;
13920 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
13921 mips32_op
= OPC_NEG_D
;
13923 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
13924 mips32_op
= OPC_NEG_PS
;
13927 /* Reciprocal square root step */
13928 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
13929 mips32_op
= OPC_RSQRT1_S
;
13931 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
13932 mips32_op
= OPC_RSQRT1_D
;
13934 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
13935 mips32_op
= OPC_RSQRT1_PS
;
13938 /* Reciprocal step */
13939 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
13940 mips32_op
= OPC_RECIP1_S
;
13942 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
13943 mips32_op
= OPC_RECIP1_S
;
13945 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
13946 mips32_op
= OPC_RECIP1_PS
;
13949 /* Conversions from double */
13950 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
13951 mips32_op
= OPC_CVT_D_S
;
13953 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
13954 mips32_op
= OPC_CVT_D_W
;
13956 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
13957 mips32_op
= OPC_CVT_D_L
;
13960 /* Conversions from single */
13961 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
13962 mips32_op
= OPC_CVT_S_D
;
13964 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
13965 mips32_op
= OPC_CVT_S_W
;
13967 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
13968 mips32_op
= OPC_CVT_S_L
;
13970 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
13973 /* Conditional moves on floating-point codes */
13974 case COND_FLOAT_MOV(MOVT
, 0):
13975 case COND_FLOAT_MOV(MOVT
, 1):
13976 case COND_FLOAT_MOV(MOVT
, 2):
13977 case COND_FLOAT_MOV(MOVT
, 3):
13978 case COND_FLOAT_MOV(MOVT
, 4):
13979 case COND_FLOAT_MOV(MOVT
, 5):
13980 case COND_FLOAT_MOV(MOVT
, 6):
13981 case COND_FLOAT_MOV(MOVT
, 7):
13982 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13983 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
13985 case COND_FLOAT_MOV(MOVF
, 0):
13986 case COND_FLOAT_MOV(MOVF
, 1):
13987 case COND_FLOAT_MOV(MOVF
, 2):
13988 case COND_FLOAT_MOV(MOVF
, 3):
13989 case COND_FLOAT_MOV(MOVF
, 4):
13990 case COND_FLOAT_MOV(MOVF
, 5):
13991 case COND_FLOAT_MOV(MOVF
, 6):
13992 case COND_FLOAT_MOV(MOVF
, 7):
13993 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13994 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
13997 MIPS_INVAL("pool32fxf");
13998 generate_exception(ctx
, EXCP_RI
);
14003 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14007 int rt
, rs
, rd
, rr
;
14009 uint32_t op
, minor
, mips32_op
;
14010 uint32_t cond
, fmt
, cc
;
14012 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
14013 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
14015 rt
= (ctx
->opcode
>> 21) & 0x1f;
14016 rs
= (ctx
->opcode
>> 16) & 0x1f;
14017 rd
= (ctx
->opcode
>> 11) & 0x1f;
14018 rr
= (ctx
->opcode
>> 6) & 0x1f;
14019 imm
= (int16_t) ctx
->opcode
;
14021 op
= (ctx
->opcode
>> 26) & 0x3f;
14024 minor
= ctx
->opcode
& 0x3f;
14027 minor
= (ctx
->opcode
>> 6) & 0xf;
14030 mips32_op
= OPC_SLL
;
14033 mips32_op
= OPC_SRA
;
14036 mips32_op
= OPC_SRL
;
14039 mips32_op
= OPC_ROTR
;
14041 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
14044 check_insn(ctx
, ISA_MIPS32R6
);
14045 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
14048 check_insn(ctx
, ISA_MIPS32R6
);
14049 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
14052 goto pool32a_invalid
;
14056 minor
= (ctx
->opcode
>> 6) & 0xf;
14060 mips32_op
= OPC_ADD
;
14063 mips32_op
= OPC_ADDU
;
14066 mips32_op
= OPC_SUB
;
14069 mips32_op
= OPC_SUBU
;
14072 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14073 mips32_op
= OPC_MUL
;
14075 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
14079 mips32_op
= OPC_SLLV
;
14082 mips32_op
= OPC_SRLV
;
14085 mips32_op
= OPC_SRAV
;
14088 mips32_op
= OPC_ROTRV
;
14090 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
14092 /* Logical operations */
14094 mips32_op
= OPC_AND
;
14097 mips32_op
= OPC_OR
;
14100 mips32_op
= OPC_NOR
;
14103 mips32_op
= OPC_XOR
;
14105 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
14107 /* Set less than */
14109 mips32_op
= OPC_SLT
;
14112 mips32_op
= OPC_SLTU
;
14114 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
14117 goto pool32a_invalid
;
14121 minor
= (ctx
->opcode
>> 6) & 0xf;
14123 /* Conditional moves */
14124 case MOVN
: /* MUL */
14125 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14127 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
14130 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
14133 case MOVZ
: /* MUH */
14134 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14136 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
14139 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
14143 check_insn(ctx
, ISA_MIPS32R6
);
14144 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
14147 check_insn(ctx
, ISA_MIPS32R6
);
14148 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
14150 case LWXS
: /* DIV */
14151 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14153 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
14156 gen_ldxs(ctx
, rs
, rt
, rd
);
14160 check_insn(ctx
, ISA_MIPS32R6
);
14161 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
14164 check_insn(ctx
, ISA_MIPS32R6
);
14165 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
14168 check_insn(ctx
, ISA_MIPS32R6
);
14169 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
14172 goto pool32a_invalid
;
14176 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
14179 check_insn(ctx
, ISA_MIPS32R6
);
14180 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
14181 extract32(ctx
->opcode
, 9, 2));
14184 check_insn(ctx
, ISA_MIPS32R6
);
14185 gen_align(ctx
, OPC_ALIGN
, rd
, rs
, rt
,
14186 extract32(ctx
->opcode
, 9, 2));
14189 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
14192 gen_pool32axf(env
, ctx
, rt
, rs
);
14195 generate_exception(ctx
, EXCP_BREAK
);
14199 MIPS_INVAL("pool32a");
14200 generate_exception(ctx
, EXCP_RI
);
14205 minor
= (ctx
->opcode
>> 12) & 0xf;
14208 check_cp0_enabled(ctx
);
14209 /* Treat as no-op. */
14213 /* COP2: Not implemented. */
14214 generate_exception_err(ctx
, EXCP_CpU
, 2);
14216 #ifdef TARGET_MIPS64
14219 check_insn(ctx
, ISA_MIPS3
);
14220 check_mips_64(ctx
);
14225 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14227 #ifdef TARGET_MIPS64
14230 check_insn(ctx
, ISA_MIPS3
);
14231 check_mips_64(ctx
);
14236 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14239 MIPS_INVAL("pool32b");
14240 generate_exception(ctx
, EXCP_RI
);
14245 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
14246 minor
= ctx
->opcode
& 0x3f;
14247 check_cp1_enabled(ctx
);
14250 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14251 mips32_op
= OPC_ALNV_PS
;
14254 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14255 mips32_op
= OPC_MADD_S
;
14258 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14259 mips32_op
= OPC_MADD_D
;
14262 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14263 mips32_op
= OPC_MADD_PS
;
14266 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14267 mips32_op
= OPC_MSUB_S
;
14270 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14271 mips32_op
= OPC_MSUB_D
;
14274 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14275 mips32_op
= OPC_MSUB_PS
;
14278 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14279 mips32_op
= OPC_NMADD_S
;
14282 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14283 mips32_op
= OPC_NMADD_D
;
14286 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14287 mips32_op
= OPC_NMADD_PS
;
14290 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14291 mips32_op
= OPC_NMSUB_S
;
14294 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14295 mips32_op
= OPC_NMSUB_D
;
14298 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14299 mips32_op
= OPC_NMSUB_PS
;
14301 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
14303 case CABS_COND_FMT
:
14304 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14305 cond
= (ctx
->opcode
>> 6) & 0xf;
14306 cc
= (ctx
->opcode
>> 13) & 0x7;
14307 fmt
= (ctx
->opcode
>> 10) & 0x3;
14310 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
14313 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
14316 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
14319 goto pool32f_invalid
;
14323 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14324 cond
= (ctx
->opcode
>> 6) & 0xf;
14325 cc
= (ctx
->opcode
>> 13) & 0x7;
14326 fmt
= (ctx
->opcode
>> 10) & 0x3;
14329 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
14332 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
14335 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
14338 goto pool32f_invalid
;
14342 check_insn(ctx
, ISA_MIPS32R6
);
14343 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
14346 check_insn(ctx
, ISA_MIPS32R6
);
14347 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
14350 gen_pool32fxf(ctx
, rt
, rs
);
14354 switch ((ctx
->opcode
>> 6) & 0x7) {
14356 mips32_op
= OPC_PLL_PS
;
14359 mips32_op
= OPC_PLU_PS
;
14362 mips32_op
= OPC_PUL_PS
;
14365 mips32_op
= OPC_PUU_PS
;
14368 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14369 mips32_op
= OPC_CVT_PS_S
;
14371 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14374 goto pool32f_invalid
;
14378 check_insn(ctx
, ISA_MIPS32R6
);
14379 switch ((ctx
->opcode
>> 9) & 0x3) {
14381 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
14384 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
14387 goto pool32f_invalid
;
14392 switch ((ctx
->opcode
>> 6) & 0x7) {
14394 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14395 mips32_op
= OPC_LWXC1
;
14398 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14399 mips32_op
= OPC_SWXC1
;
14402 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14403 mips32_op
= OPC_LDXC1
;
14406 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14407 mips32_op
= OPC_SDXC1
;
14410 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14411 mips32_op
= OPC_LUXC1
;
14414 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14415 mips32_op
= OPC_SUXC1
;
14417 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
14420 goto pool32f_invalid
;
14424 check_insn(ctx
, ISA_MIPS32R6
);
14425 switch ((ctx
->opcode
>> 9) & 0x3) {
14427 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
14430 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
14433 goto pool32f_invalid
;
14438 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14439 fmt
= (ctx
->opcode
>> 9) & 0x3;
14440 switch ((ctx
->opcode
>> 6) & 0x7) {
14444 mips32_op
= OPC_RSQRT2_S
;
14447 mips32_op
= OPC_RSQRT2_D
;
14450 mips32_op
= OPC_RSQRT2_PS
;
14453 goto pool32f_invalid
;
14459 mips32_op
= OPC_RECIP2_S
;
14462 mips32_op
= OPC_RECIP2_D
;
14465 mips32_op
= OPC_RECIP2_PS
;
14468 goto pool32f_invalid
;
14472 mips32_op
= OPC_ADDR_PS
;
14475 mips32_op
= OPC_MULR_PS
;
14477 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14480 goto pool32f_invalid
;
14484 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14485 cc
= (ctx
->opcode
>> 13) & 0x7;
14486 fmt
= (ctx
->opcode
>> 9) & 0x3;
14487 switch ((ctx
->opcode
>> 6) & 0x7) {
14488 case MOVF_FMT
: /* RINT_FMT */
14489 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14493 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
14496 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
14499 goto pool32f_invalid
;
14505 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
14508 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
14512 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
14515 goto pool32f_invalid
;
14519 case MOVT_FMT
: /* CLASS_FMT */
14520 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14524 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
14527 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
14530 goto pool32f_invalid
;
14536 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
14539 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
14543 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
14546 goto pool32f_invalid
;
14551 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14554 goto pool32f_invalid
;
14557 #define FINSN_3ARG_SDPS(prfx) \
14558 switch ((ctx->opcode >> 8) & 0x3) { \
14560 mips32_op = OPC_##prfx##_S; \
14563 mips32_op = OPC_##prfx##_D; \
14565 case FMT_SDPS_PS: \
14567 mips32_op = OPC_##prfx##_PS; \
14570 goto pool32f_invalid; \
14573 check_insn(ctx
, ISA_MIPS32R6
);
14574 switch ((ctx
->opcode
>> 9) & 0x3) {
14576 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
14579 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
14582 goto pool32f_invalid
;
14586 check_insn(ctx
, ISA_MIPS32R6
);
14587 switch ((ctx
->opcode
>> 9) & 0x3) {
14589 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
14592 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
14595 goto pool32f_invalid
;
14599 /* regular FP ops */
14600 switch ((ctx
->opcode
>> 6) & 0x3) {
14602 FINSN_3ARG_SDPS(ADD
);
14605 FINSN_3ARG_SDPS(SUB
);
14608 FINSN_3ARG_SDPS(MUL
);
14611 fmt
= (ctx
->opcode
>> 8) & 0x3;
14613 mips32_op
= OPC_DIV_D
;
14614 } else if (fmt
== 0) {
14615 mips32_op
= OPC_DIV_S
;
14617 goto pool32f_invalid
;
14621 goto pool32f_invalid
;
14626 switch ((ctx
->opcode
>> 6) & 0x7) {
14627 case MOVN_FMT
: /* SELNEZ_FMT */
14628 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14630 switch ((ctx
->opcode
>> 9) & 0x3) {
14632 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
14635 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
14638 goto pool32f_invalid
;
14642 FINSN_3ARG_SDPS(MOVN
);
14646 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14647 FINSN_3ARG_SDPS(MOVN
);
14649 case MOVZ_FMT
: /* SELEQZ_FMT */
14650 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14652 switch ((ctx
->opcode
>> 9) & 0x3) {
14654 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
14657 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
14660 goto pool32f_invalid
;
14664 FINSN_3ARG_SDPS(MOVZ
);
14668 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14669 FINSN_3ARG_SDPS(MOVZ
);
14672 check_insn(ctx
, ISA_MIPS32R6
);
14673 switch ((ctx
->opcode
>> 9) & 0x3) {
14675 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
14678 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
14681 goto pool32f_invalid
;
14685 check_insn(ctx
, ISA_MIPS32R6
);
14686 switch ((ctx
->opcode
>> 9) & 0x3) {
14688 mips32_op
= OPC_MADDF_S
;
14691 mips32_op
= OPC_MADDF_D
;
14694 goto pool32f_invalid
;
14698 check_insn(ctx
, ISA_MIPS32R6
);
14699 switch ((ctx
->opcode
>> 9) & 0x3) {
14701 mips32_op
= OPC_MSUBF_S
;
14704 mips32_op
= OPC_MSUBF_D
;
14707 goto pool32f_invalid
;
14711 goto pool32f_invalid
;
14715 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14719 MIPS_INVAL("pool32f");
14720 generate_exception(ctx
, EXCP_RI
);
14724 generate_exception_err(ctx
, EXCP_CpU
, 1);
14728 minor
= (ctx
->opcode
>> 21) & 0x1f;
14731 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14732 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
14735 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14736 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
14737 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14740 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14741 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
14742 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14745 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14746 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
14749 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14750 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
14751 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14754 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14755 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
14756 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14759 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14760 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
14763 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14764 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
14768 case TLTI
: /* BC1EQZC */
14769 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14771 check_cp1_enabled(ctx
);
14772 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
14775 mips32_op
= OPC_TLTI
;
14779 case TGEI
: /* BC1NEZC */
14780 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14782 check_cp1_enabled(ctx
);
14783 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
14786 mips32_op
= OPC_TGEI
;
14791 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14792 mips32_op
= OPC_TLTIU
;
14795 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14796 mips32_op
= OPC_TGEIU
;
14798 case TNEI
: /* SYNCI */
14799 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14801 /* Break the TB to be able to sync copied instructions
14803 ctx
->bstate
= BS_STOP
;
14806 mips32_op
= OPC_TNEI
;
14811 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14812 mips32_op
= OPC_TEQI
;
14814 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
14819 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14820 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
14821 4, rs
, 0, imm
<< 1, 0);
14822 /* Compact branches don't have a delay slot, so just let
14823 the normal delay slot handling take us to the branch
14827 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14828 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
14831 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14832 /* Break the TB to be able to sync copied instructions
14834 ctx
->bstate
= BS_STOP
;
14838 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14839 /* COP2: Not implemented. */
14840 generate_exception_err(ctx
, EXCP_CpU
, 2);
14843 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14844 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
14847 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14848 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
14851 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14852 mips32_op
= OPC_BC1FANY4
;
14855 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14856 mips32_op
= OPC_BC1TANY4
;
14859 check_insn(ctx
, ASE_MIPS3D
);
14862 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14863 check_cp1_enabled(ctx
);
14864 gen_compute_branch1(ctx
, mips32_op
,
14865 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
14867 generate_exception_err(ctx
, EXCP_CpU
, 1);
14872 /* MIPS DSP: not implemented */
14875 MIPS_INVAL("pool32i");
14876 generate_exception(ctx
, EXCP_RI
);
14881 minor
= (ctx
->opcode
>> 12) & 0xf;
14882 offset
= sextract32(ctx
->opcode
, 0,
14883 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
14886 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14887 mips32_op
= OPC_LWL
;
14890 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14891 mips32_op
= OPC_SWL
;
14894 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14895 mips32_op
= OPC_LWR
;
14898 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14899 mips32_op
= OPC_SWR
;
14901 #if defined(TARGET_MIPS64)
14903 check_insn(ctx
, ISA_MIPS3
);
14904 check_mips_64(ctx
);
14905 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14906 mips32_op
= OPC_LDL
;
14909 check_insn(ctx
, ISA_MIPS3
);
14910 check_mips_64(ctx
);
14911 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14912 mips32_op
= OPC_SDL
;
14915 check_insn(ctx
, ISA_MIPS3
);
14916 check_mips_64(ctx
);
14917 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14918 mips32_op
= OPC_LDR
;
14921 check_insn(ctx
, ISA_MIPS3
);
14922 check_mips_64(ctx
);
14923 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14924 mips32_op
= OPC_SDR
;
14927 check_insn(ctx
, ISA_MIPS3
);
14928 check_mips_64(ctx
);
14929 mips32_op
= OPC_LWU
;
14932 check_insn(ctx
, ISA_MIPS3
);
14933 check_mips_64(ctx
);
14934 mips32_op
= OPC_LLD
;
14938 mips32_op
= OPC_LL
;
14941 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
14944 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14947 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, offset
);
14949 #if defined(TARGET_MIPS64)
14951 check_insn(ctx
, ISA_MIPS3
);
14952 check_mips_64(ctx
);
14953 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, offset
);
14957 /* Treat as no-op */
14958 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
14959 /* hint codes 24-31 are reserved and signal RI */
14960 generate_exception(ctx
, EXCP_RI
);
14964 MIPS_INVAL("pool32c");
14965 generate_exception(ctx
, EXCP_RI
);
14969 case ADDI32
: /* AUI, LUI */
14970 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14972 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
14975 mips32_op
= OPC_ADDI
;
14980 mips32_op
= OPC_ADDIU
;
14982 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14985 /* Logical operations */
14987 mips32_op
= OPC_ORI
;
14990 mips32_op
= OPC_XORI
;
14993 mips32_op
= OPC_ANDI
;
14995 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14998 /* Set less than immediate */
15000 mips32_op
= OPC_SLTI
;
15003 mips32_op
= OPC_SLTIU
;
15005 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
15008 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15009 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15010 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
15011 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15013 case JALS32
: /* BOVC, BEQC, BEQZALC */
15014 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15017 mips32_op
= OPC_BOVC
;
15018 } else if (rs
< rt
&& rs
== 0) {
15020 mips32_op
= OPC_BEQZALC
;
15023 mips32_op
= OPC_BEQC
;
15025 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15028 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
15029 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
15030 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15033 case BEQ32
: /* BC */
15034 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15036 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
15037 sextract32(ctx
->opcode
<< 1, 0, 27));
15040 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
15043 case BNE32
: /* BALC */
15044 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15046 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
15047 sextract32(ctx
->opcode
<< 1, 0, 27));
15050 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
15053 case J32
: /* BGTZC, BLTZC, BLTC */
15054 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15055 if (rs
== 0 && rt
!= 0) {
15057 mips32_op
= OPC_BGTZC
;
15058 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15060 mips32_op
= OPC_BLTZC
;
15063 mips32_op
= OPC_BLTC
;
15065 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15068 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
15069 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
15072 case JAL32
: /* BLEZC, BGEZC, BGEC */
15073 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15074 if (rs
== 0 && rt
!= 0) {
15076 mips32_op
= OPC_BLEZC
;
15077 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15079 mips32_op
= OPC_BGEZC
;
15082 mips32_op
= OPC_BGEC
;
15084 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15087 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
15088 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
15089 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15092 /* Floating point (COP1) */
15094 mips32_op
= OPC_LWC1
;
15097 mips32_op
= OPC_LDC1
;
15100 mips32_op
= OPC_SWC1
;
15103 mips32_op
= OPC_SDC1
;
15105 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
15107 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15108 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15109 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15110 switch ((ctx
->opcode
>> 16) & 0x1f) {
15111 case ADDIUPC_00
... ADDIUPC_07
:
15112 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->pc
& ~0x3, rt
);
15115 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->pc
, rt
);
15118 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->pc
, rt
);
15120 case LWPC_08
... LWPC_0F
:
15121 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->pc
& ~0x3, rt
);
15124 generate_exception(ctx
, EXCP_RI
);
15129 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
15130 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
15132 gen_addiupc(ctx
, reg
, offset
, 0, 0);
15135 case BNVC
: /* BNEC, BNEZALC */
15136 check_insn(ctx
, ISA_MIPS32R6
);
15139 mips32_op
= OPC_BNVC
;
15140 } else if (rs
< rt
&& rs
== 0) {
15142 mips32_op
= OPC_BNEZALC
;
15145 mips32_op
= OPC_BNEC
;
15147 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15149 case R6_BNEZC
: /* JIALC */
15150 check_insn(ctx
, ISA_MIPS32R6
);
15153 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
15154 sextract32(ctx
->opcode
<< 1, 0, 22));
15157 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
15160 case R6_BEQZC
: /* JIC */
15161 check_insn(ctx
, ISA_MIPS32R6
);
15164 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
15165 sextract32(ctx
->opcode
<< 1, 0, 22));
15168 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
15171 case BLEZALC
: /* BGEZALC, BGEUC */
15172 check_insn(ctx
, ISA_MIPS32R6
);
15173 if (rs
== 0 && rt
!= 0) {
15175 mips32_op
= OPC_BLEZALC
;
15176 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15178 mips32_op
= OPC_BGEZALC
;
15181 mips32_op
= OPC_BGEUC
;
15183 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15185 case BGTZALC
: /* BLTZALC, BLTUC */
15186 check_insn(ctx
, ISA_MIPS32R6
);
15187 if (rs
== 0 && rt
!= 0) {
15189 mips32_op
= OPC_BGTZALC
;
15190 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15192 mips32_op
= OPC_BLTZALC
;
15195 mips32_op
= OPC_BLTUC
;
15197 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15199 /* Loads and stores */
15201 mips32_op
= OPC_LB
;
15204 mips32_op
= OPC_LBU
;
15207 mips32_op
= OPC_LH
;
15210 mips32_op
= OPC_LHU
;
15213 mips32_op
= OPC_LW
;
15215 #ifdef TARGET_MIPS64
15217 check_insn(ctx
, ISA_MIPS3
);
15218 check_mips_64(ctx
);
15219 mips32_op
= OPC_LD
;
15222 check_insn(ctx
, ISA_MIPS3
);
15223 check_mips_64(ctx
);
15224 mips32_op
= OPC_SD
;
15228 mips32_op
= OPC_SB
;
15231 mips32_op
= OPC_SH
;
15234 mips32_op
= OPC_SW
;
15237 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
15240 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
15243 generate_exception(ctx
, EXCP_RI
);
15248 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
15252 /* make sure instructions are on a halfword boundary */
15253 if (ctx
->pc
& 0x1) {
15254 env
->CP0_BadVAddr
= ctx
->pc
;
15255 generate_exception(ctx
, EXCP_AdEL
);
15256 ctx
->bstate
= BS_STOP
;
15260 op
= (ctx
->opcode
>> 10) & 0x3f;
15261 /* Enforce properly-sized instructions in a delay slot */
15262 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
15263 switch (op
& 0x7) { /* MSB-3..MSB-5 */
15265 /* POOL32A, POOL32B, POOL32I, POOL32C */
15267 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15269 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15271 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15273 /* LB32, LH32, LWC132, LDC132, LW32 */
15274 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
15275 generate_exception(ctx
, EXCP_RI
);
15276 /* Just stop translation; the user is confused. */
15277 ctx
->bstate
= BS_STOP
;
15282 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15284 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15286 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15287 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
15288 generate_exception(ctx
, EXCP_RI
);
15289 /* Just stop translation; the user is confused. */
15290 ctx
->bstate
= BS_STOP
;
15300 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15301 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
15302 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
15305 switch (ctx
->opcode
& 0x1) {
15313 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15314 /* In the Release 6 the register number location in
15315 * the instruction encoding has changed.
15317 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
15319 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
15325 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15326 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15327 int amount
= (ctx
->opcode
>> 1) & 0x7;
15329 amount
= amount
== 0 ? 8 : amount
;
15331 switch (ctx
->opcode
& 0x1) {
15340 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
15344 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15345 gen_pool16c_r6_insn(ctx
);
15347 gen_pool16c_insn(ctx
);
15352 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15353 int rb
= 28; /* GP */
15354 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
15356 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15360 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15361 if (ctx
->opcode
& 1) {
15362 generate_exception(ctx
, EXCP_RI
);
15365 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15366 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15367 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
15368 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15373 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15374 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15375 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
15376 offset
= (offset
== 0xf ? -1 : offset
);
15378 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
15383 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15384 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15385 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
15387 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
15392 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15393 int rb
= 29; /* SP */
15394 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
15396 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15401 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15402 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15403 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
15405 gen_ld(ctx
, OPC_LW
, 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);
15414 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
15419 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15420 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15421 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
15423 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
15428 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15429 int rb
= 29; /* SP */
15430 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
15432 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
15437 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15438 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15439 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
15441 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
15446 int rd
= uMIPS_RD5(ctx
->opcode
);
15447 int rs
= uMIPS_RS5(ctx
->opcode
);
15449 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
15456 switch (ctx
->opcode
& 0x1) {
15466 switch (ctx
->opcode
& 0x1) {
15471 gen_addiur1sp(ctx
);
15475 case B16
: /* BC16 */
15476 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
15477 sextract32(ctx
->opcode
, 0, 10) << 1,
15478 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
15480 case BNEZ16
: /* BNEZC16 */
15481 case BEQZ16
: /* BEQZC16 */
15482 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
15483 mmreg(uMIPS_RD(ctx
->opcode
)),
15484 0, sextract32(ctx
->opcode
, 0, 7) << 1,
15485 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
15490 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
15491 int imm
= ZIMM(ctx
->opcode
, 0, 7);
15493 imm
= (imm
== 0x7f ? -1 : imm
);
15494 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
15500 generate_exception(ctx
, EXCP_RI
);
15503 decode_micromips32_opc(env
, ctx
);
15510 /* SmartMIPS extension to MIPS32 */
15512 #if defined(TARGET_MIPS64)
15514 /* MDMX extension to MIPS64 */
15518 /* MIPSDSP functions. */
15519 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
15520 int rd
, int base
, int offset
)
15522 const char *opn
= "ldx";
15526 t0
= tcg_temp_new();
15529 gen_load_gpr(t0
, offset
);
15530 } else if (offset
== 0) {
15531 gen_load_gpr(t0
, base
);
15533 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
15538 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
15539 gen_store_gpr(t0
, rd
);
15543 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
15544 gen_store_gpr(t0
, rd
);
15548 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
15549 gen_store_gpr(t0
, rd
);
15552 #if defined(TARGET_MIPS64)
15554 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
15555 gen_store_gpr(t0
, rd
);
15560 (void)opn
; /* avoid a compiler warning */
15561 MIPS_DEBUG("%s %s, %s(%s)", opn
,
15562 regnames
[rd
], regnames
[offset
], regnames
[base
]);
15566 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15567 int ret
, int v1
, int v2
)
15569 const char *opn
= "mipsdsp arith";
15574 /* Treat as NOP. */
15579 v1_t
= tcg_temp_new();
15580 v2_t
= tcg_temp_new();
15582 gen_load_gpr(v1_t
, v1
);
15583 gen_load_gpr(v2_t
, v2
);
15586 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15587 case OPC_MULT_G_2E
:
15591 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15593 case OPC_ADDUH_R_QB
:
15594 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15597 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15599 case OPC_ADDQH_R_PH
:
15600 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15603 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15605 case OPC_ADDQH_R_W
:
15606 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15609 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15611 case OPC_SUBUH_R_QB
:
15612 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15615 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15617 case OPC_SUBQH_R_PH
:
15618 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15621 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15623 case OPC_SUBQH_R_W
:
15624 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15628 case OPC_ABSQ_S_PH_DSP
:
15630 case OPC_ABSQ_S_QB
:
15632 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
15634 case OPC_ABSQ_S_PH
:
15636 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
15640 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
15642 case OPC_PRECEQ_W_PHL
:
15644 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
15645 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15647 case OPC_PRECEQ_W_PHR
:
15649 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
15650 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
15651 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15653 case OPC_PRECEQU_PH_QBL
:
15655 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
15657 case OPC_PRECEQU_PH_QBR
:
15659 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
15661 case OPC_PRECEQU_PH_QBLA
:
15663 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
15665 case OPC_PRECEQU_PH_QBRA
:
15667 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
15669 case OPC_PRECEU_PH_QBL
:
15671 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
15673 case OPC_PRECEU_PH_QBR
:
15675 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
15677 case OPC_PRECEU_PH_QBLA
:
15679 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
15681 case OPC_PRECEU_PH_QBRA
:
15683 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
15687 case OPC_ADDU_QB_DSP
:
15691 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15693 case OPC_ADDQ_S_PH
:
15695 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15699 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15703 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15705 case OPC_ADDU_S_QB
:
15707 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15711 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15713 case OPC_ADDU_S_PH
:
15715 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15719 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15721 case OPC_SUBQ_S_PH
:
15723 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15727 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15731 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15733 case OPC_SUBU_S_QB
:
15735 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15739 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15741 case OPC_SUBU_S_PH
:
15743 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15747 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15751 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15755 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
15757 case OPC_RADDU_W_QB
:
15759 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
15763 case OPC_CMPU_EQ_QB_DSP
:
15765 case OPC_PRECR_QB_PH
:
15767 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15769 case OPC_PRECRQ_QB_PH
:
15771 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15773 case OPC_PRECR_SRA_PH_W
:
15776 TCGv_i32 sa_t
= tcg_const_i32(v2
);
15777 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
15779 tcg_temp_free_i32(sa_t
);
15782 case OPC_PRECR_SRA_R_PH_W
:
15785 TCGv_i32 sa_t
= tcg_const_i32(v2
);
15786 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
15788 tcg_temp_free_i32(sa_t
);
15791 case OPC_PRECRQ_PH_W
:
15793 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15795 case OPC_PRECRQ_RS_PH_W
:
15797 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15799 case OPC_PRECRQU_S_QB_PH
:
15801 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15805 #ifdef TARGET_MIPS64
15806 case OPC_ABSQ_S_QH_DSP
:
15808 case OPC_PRECEQ_L_PWL
:
15810 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
15812 case OPC_PRECEQ_L_PWR
:
15814 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
15816 case OPC_PRECEQ_PW_QHL
:
15818 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
15820 case OPC_PRECEQ_PW_QHR
:
15822 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
15824 case OPC_PRECEQ_PW_QHLA
:
15826 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
15828 case OPC_PRECEQ_PW_QHRA
:
15830 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
15832 case OPC_PRECEQU_QH_OBL
:
15834 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
15836 case OPC_PRECEQU_QH_OBR
:
15838 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
15840 case OPC_PRECEQU_QH_OBLA
:
15842 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
15844 case OPC_PRECEQU_QH_OBRA
:
15846 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
15848 case OPC_PRECEU_QH_OBL
:
15850 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
15852 case OPC_PRECEU_QH_OBR
:
15854 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
15856 case OPC_PRECEU_QH_OBLA
:
15858 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
15860 case OPC_PRECEU_QH_OBRA
:
15862 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
15864 case OPC_ABSQ_S_OB
:
15866 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
15868 case OPC_ABSQ_S_PW
:
15870 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
15872 case OPC_ABSQ_S_QH
:
15874 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
15878 case OPC_ADDU_OB_DSP
:
15880 case OPC_RADDU_L_OB
:
15882 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
15886 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15888 case OPC_SUBQ_S_PW
:
15890 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15894 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15896 case OPC_SUBQ_S_QH
:
15898 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15902 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15904 case OPC_SUBU_S_OB
:
15906 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15910 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15912 case OPC_SUBU_S_QH
:
15914 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15918 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15920 case OPC_SUBUH_R_OB
:
15922 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15926 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15928 case OPC_ADDQ_S_PW
:
15930 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15934 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15936 case OPC_ADDQ_S_QH
:
15938 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15942 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15944 case OPC_ADDU_S_OB
:
15946 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15950 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15952 case OPC_ADDU_S_QH
:
15954 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15958 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15960 case OPC_ADDUH_R_OB
:
15962 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15966 case OPC_CMPU_EQ_OB_DSP
:
15968 case OPC_PRECR_OB_QH
:
15970 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
15972 case OPC_PRECR_SRA_QH_PW
:
15975 TCGv_i32 ret_t
= tcg_const_i32(ret
);
15976 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
15977 tcg_temp_free_i32(ret_t
);
15980 case OPC_PRECR_SRA_R_QH_PW
:
15983 TCGv_i32 sa_v
= tcg_const_i32(ret
);
15984 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
15985 tcg_temp_free_i32(sa_v
);
15988 case OPC_PRECRQ_OB_QH
:
15990 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
15992 case OPC_PRECRQ_PW_L
:
15994 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
15996 case OPC_PRECRQ_QH_PW
:
15998 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
16000 case OPC_PRECRQ_RS_QH_PW
:
16002 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16004 case OPC_PRECRQU_S_OB_QH
:
16006 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16013 tcg_temp_free(v1_t
);
16014 tcg_temp_free(v2_t
);
16016 (void)opn
; /* avoid a compiler warning */
16017 MIPS_DEBUG("%s", opn
);
16020 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
16021 int ret
, int v1
, int v2
)
16024 const char *opn
= "mipsdsp shift";
16030 /* Treat as NOP. */
16035 t0
= tcg_temp_new();
16036 v1_t
= tcg_temp_new();
16037 v2_t
= tcg_temp_new();
16039 tcg_gen_movi_tl(t0
, v1
);
16040 gen_load_gpr(v1_t
, v1
);
16041 gen_load_gpr(v2_t
, v2
);
16044 case OPC_SHLL_QB_DSP
:
16046 op2
= MASK_SHLL_QB(ctx
->opcode
);
16050 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16054 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16058 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16062 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16064 case OPC_SHLL_S_PH
:
16066 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16068 case OPC_SHLLV_S_PH
:
16070 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16074 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16076 case OPC_SHLLV_S_W
:
16078 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16082 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
16086 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16090 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
16094 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16098 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
16100 case OPC_SHRA_R_QB
:
16102 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
16106 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16108 case OPC_SHRAV_R_QB
:
16110 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16114 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
16116 case OPC_SHRA_R_PH
:
16118 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
16122 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16124 case OPC_SHRAV_R_PH
:
16126 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16130 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
16132 case OPC_SHRAV_R_W
:
16134 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
16136 default: /* Invalid */
16137 MIPS_INVAL("MASK SHLL.QB");
16138 generate_exception(ctx
, EXCP_RI
);
16143 #ifdef TARGET_MIPS64
16144 case OPC_SHLL_OB_DSP
:
16145 op2
= MASK_SHLL_OB(ctx
->opcode
);
16149 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16153 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16155 case OPC_SHLL_S_PW
:
16157 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16159 case OPC_SHLLV_S_PW
:
16161 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16165 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16169 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16173 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16177 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16179 case OPC_SHLL_S_QH
:
16181 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16183 case OPC_SHLLV_S_QH
:
16185 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16189 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
16193 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
16195 case OPC_SHRA_R_OB
:
16197 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
16199 case OPC_SHRAV_R_OB
:
16201 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
16205 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
16209 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
16211 case OPC_SHRA_R_PW
:
16213 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
16215 case OPC_SHRAV_R_PW
:
16217 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
16221 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
16225 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
16227 case OPC_SHRA_R_QH
:
16229 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
16231 case OPC_SHRAV_R_QH
:
16233 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
16237 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
16241 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
16245 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
16249 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
16251 default: /* Invalid */
16252 MIPS_INVAL("MASK SHLL.OB");
16253 generate_exception(ctx
, EXCP_RI
);
16261 tcg_temp_free(v1_t
);
16262 tcg_temp_free(v2_t
);
16263 (void)opn
; /* avoid a compiler warning */
16264 MIPS_DEBUG("%s", opn
);
16267 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16268 int ret
, int v1
, int v2
, int check_ret
)
16270 const char *opn
= "mipsdsp multiply";
16275 if ((ret
== 0) && (check_ret
== 1)) {
16276 /* Treat as NOP. */
16281 t0
= tcg_temp_new_i32();
16282 v1_t
= tcg_temp_new();
16283 v2_t
= tcg_temp_new();
16285 tcg_gen_movi_i32(t0
, ret
);
16286 gen_load_gpr(v1_t
, v1
);
16287 gen_load_gpr(v2_t
, v2
);
16290 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16291 * the same mask and op1. */
16292 case OPC_MULT_G_2E
:
16296 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16299 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16302 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16304 case OPC_MULQ_RS_W
:
16305 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16309 case OPC_DPA_W_PH_DSP
:
16311 case OPC_DPAU_H_QBL
:
16313 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
16315 case OPC_DPAU_H_QBR
:
16317 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
16319 case OPC_DPSU_H_QBL
:
16321 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
16323 case OPC_DPSU_H_QBR
:
16325 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
16329 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16331 case OPC_DPAX_W_PH
:
16333 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16335 case OPC_DPAQ_S_W_PH
:
16337 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16339 case OPC_DPAQX_S_W_PH
:
16341 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16343 case OPC_DPAQX_SA_W_PH
:
16345 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16349 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16351 case OPC_DPSX_W_PH
:
16353 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16355 case OPC_DPSQ_S_W_PH
:
16357 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16359 case OPC_DPSQX_S_W_PH
:
16361 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16363 case OPC_DPSQX_SA_W_PH
:
16365 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16367 case OPC_MULSAQ_S_W_PH
:
16369 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16371 case OPC_DPAQ_SA_L_W
:
16373 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
16375 case OPC_DPSQ_SA_L_W
:
16377 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
16379 case OPC_MAQ_S_W_PHL
:
16381 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
16383 case OPC_MAQ_S_W_PHR
:
16385 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
16387 case OPC_MAQ_SA_W_PHL
:
16389 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
16391 case OPC_MAQ_SA_W_PHR
:
16393 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
16395 case OPC_MULSA_W_PH
:
16397 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16401 #ifdef TARGET_MIPS64
16402 case OPC_DPAQ_W_QH_DSP
:
16404 int ac
= ret
& 0x03;
16405 tcg_gen_movi_i32(t0
, ac
);
16410 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
16414 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
16418 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
16422 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
16426 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16428 case OPC_DPAQ_S_W_QH
:
16430 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16432 case OPC_DPAQ_SA_L_PW
:
16434 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16436 case OPC_DPAU_H_OBL
:
16438 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
16440 case OPC_DPAU_H_OBR
:
16442 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
16446 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16448 case OPC_DPSQ_S_W_QH
:
16450 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16452 case OPC_DPSQ_SA_L_PW
:
16454 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16456 case OPC_DPSU_H_OBL
:
16458 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
16460 case OPC_DPSU_H_OBR
:
16462 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
16464 case OPC_MAQ_S_L_PWL
:
16466 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
16468 case OPC_MAQ_S_L_PWR
:
16470 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
16472 case OPC_MAQ_S_W_QHLL
:
16474 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
16476 case OPC_MAQ_SA_W_QHLL
:
16478 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
16480 case OPC_MAQ_S_W_QHLR
:
16482 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
16484 case OPC_MAQ_SA_W_QHLR
:
16486 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
16488 case OPC_MAQ_S_W_QHRL
:
16490 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
16492 case OPC_MAQ_SA_W_QHRL
:
16494 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
16496 case OPC_MAQ_S_W_QHRR
:
16498 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
16500 case OPC_MAQ_SA_W_QHRR
:
16502 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
16504 case OPC_MULSAQ_S_L_PW
:
16506 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16508 case OPC_MULSAQ_S_W_QH
:
16510 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16516 case OPC_ADDU_QB_DSP
:
16518 case OPC_MULEU_S_PH_QBL
:
16520 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16522 case OPC_MULEU_S_PH_QBR
:
16524 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16526 case OPC_MULQ_RS_PH
:
16528 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16530 case OPC_MULEQ_S_W_PHL
:
16532 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16534 case OPC_MULEQ_S_W_PHR
:
16536 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16538 case OPC_MULQ_S_PH
:
16540 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16544 #ifdef TARGET_MIPS64
16545 case OPC_ADDU_OB_DSP
:
16547 case OPC_MULEQ_S_PW_QHL
:
16549 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16551 case OPC_MULEQ_S_PW_QHR
:
16553 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16555 case OPC_MULEU_S_QH_OBL
:
16557 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16559 case OPC_MULEU_S_QH_OBR
:
16561 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16563 case OPC_MULQ_RS_QH
:
16565 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16572 tcg_temp_free_i32(t0
);
16573 tcg_temp_free(v1_t
);
16574 tcg_temp_free(v2_t
);
16576 (void)opn
; /* avoid a compiler warning */
16577 MIPS_DEBUG("%s", opn
);
16581 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16584 const char *opn
= "mipsdsp Bit/ Manipulation";
16590 /* Treat as NOP. */
16595 t0
= tcg_temp_new();
16596 val_t
= tcg_temp_new();
16597 gen_load_gpr(val_t
, val
);
16600 case OPC_ABSQ_S_PH_DSP
:
16604 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
16609 target_long result
;
16610 imm
= (ctx
->opcode
>> 16) & 0xFF;
16611 result
= (uint32_t)imm
<< 24 |
16612 (uint32_t)imm
<< 16 |
16613 (uint32_t)imm
<< 8 |
16615 result
= (int32_t)result
;
16616 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
16621 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
16622 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
16623 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16624 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16625 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16626 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
16631 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16632 imm
= (int16_t)(imm
<< 6) >> 6;
16633 tcg_gen_movi_tl(cpu_gpr
[ret
], \
16634 (target_long
)((int32_t)imm
<< 16 | \
16640 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
16641 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16642 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16643 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
16647 #ifdef TARGET_MIPS64
16648 case OPC_ABSQ_S_QH_DSP
:
16655 imm
= (ctx
->opcode
>> 16) & 0xFF;
16656 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
16657 temp
= (temp
<< 16) | temp
;
16658 temp
= (temp
<< 32) | temp
;
16659 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16667 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16668 imm
= (int16_t)(imm
<< 6) >> 6;
16669 temp
= ((target_long
)imm
<< 32) \
16670 | ((target_long
)imm
& 0xFFFFFFFF);
16671 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16679 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16680 imm
= (int16_t)(imm
<< 6) >> 6;
16682 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
16683 ((uint64_t)(uint16_t)imm
<< 32) |
16684 ((uint64_t)(uint16_t)imm
<< 16) |
16685 (uint64_t)(uint16_t)imm
;
16686 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16691 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
16692 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
16693 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16694 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16695 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16696 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16697 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16701 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
16702 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16703 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16707 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
16708 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16709 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16710 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16711 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16718 tcg_temp_free(val_t
);
16720 (void)opn
; /* avoid a compiler warning */
16721 MIPS_DEBUG("%s", opn
);
16724 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
16725 uint32_t op1
, uint32_t op2
,
16726 int ret
, int v1
, int v2
, int check_ret
)
16728 const char *opn
= "mipsdsp add compare pick";
16733 if ((ret
== 0) && (check_ret
== 1)) {
16734 /* Treat as NOP. */
16739 t1
= tcg_temp_new();
16740 v1_t
= tcg_temp_new();
16741 v2_t
= tcg_temp_new();
16743 gen_load_gpr(v1_t
, v1
);
16744 gen_load_gpr(v2_t
, v2
);
16747 case OPC_CMPU_EQ_QB_DSP
:
16749 case OPC_CMPU_EQ_QB
:
16751 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
16753 case OPC_CMPU_LT_QB
:
16755 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
16757 case OPC_CMPU_LE_QB
:
16759 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
16761 case OPC_CMPGU_EQ_QB
:
16763 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16765 case OPC_CMPGU_LT_QB
:
16767 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16769 case OPC_CMPGU_LE_QB
:
16771 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16773 case OPC_CMPGDU_EQ_QB
:
16775 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
16776 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16777 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16778 tcg_gen_shli_tl(t1
, t1
, 24);
16779 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16781 case OPC_CMPGDU_LT_QB
:
16783 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
16784 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16785 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16786 tcg_gen_shli_tl(t1
, t1
, 24);
16787 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16789 case OPC_CMPGDU_LE_QB
:
16791 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
16792 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16793 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16794 tcg_gen_shli_tl(t1
, t1
, 24);
16795 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16797 case OPC_CMP_EQ_PH
:
16799 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
16801 case OPC_CMP_LT_PH
:
16803 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
16805 case OPC_CMP_LE_PH
:
16807 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
16811 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16815 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16817 case OPC_PACKRL_PH
:
16819 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16823 #ifdef TARGET_MIPS64
16824 case OPC_CMPU_EQ_OB_DSP
:
16826 case OPC_CMP_EQ_PW
:
16828 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
16830 case OPC_CMP_LT_PW
:
16832 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
16834 case OPC_CMP_LE_PW
:
16836 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
16838 case OPC_CMP_EQ_QH
:
16840 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
16842 case OPC_CMP_LT_QH
:
16844 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
16846 case OPC_CMP_LE_QH
:
16848 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
16850 case OPC_CMPGDU_EQ_OB
:
16852 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16854 case OPC_CMPGDU_LT_OB
:
16856 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16858 case OPC_CMPGDU_LE_OB
:
16860 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16862 case OPC_CMPGU_EQ_OB
:
16864 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16866 case OPC_CMPGU_LT_OB
:
16868 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16870 case OPC_CMPGU_LE_OB
:
16872 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16874 case OPC_CMPU_EQ_OB
:
16876 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
16878 case OPC_CMPU_LT_OB
:
16880 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
16882 case OPC_CMPU_LE_OB
:
16884 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
16886 case OPC_PACKRL_PW
:
16888 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
16892 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16896 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16900 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16908 tcg_temp_free(v1_t
);
16909 tcg_temp_free(v2_t
);
16911 (void)opn
; /* avoid a compiler warning */
16912 MIPS_DEBUG("%s", opn
);
16915 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
16916 uint32_t op1
, int rt
, int rs
, int sa
)
16918 const char *opn
= "mipsdsp append/dappend";
16924 /* Treat as NOP. */
16929 t0
= tcg_temp_new();
16930 gen_load_gpr(t0
, rs
);
16933 case OPC_APPEND_DSP
:
16934 switch (MASK_APPEND(ctx
->opcode
)) {
16937 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
16939 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16943 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16944 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
16945 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
16946 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16948 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16952 if (sa
!= 0 && sa
!= 2) {
16953 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
16954 tcg_gen_ext32u_tl(t0
, t0
);
16955 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
16956 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16958 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16960 default: /* Invalid */
16961 MIPS_INVAL("MASK APPEND");
16962 generate_exception(ctx
, EXCP_RI
);
16966 #ifdef TARGET_MIPS64
16967 case OPC_DAPPEND_DSP
:
16968 switch (MASK_DAPPEND(ctx
->opcode
)) {
16971 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
16975 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
16976 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
16977 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
16981 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
16982 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
16983 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16988 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
16989 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
16990 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
16991 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16994 default: /* Invalid */
16995 MIPS_INVAL("MASK DAPPEND");
16996 generate_exception(ctx
, EXCP_RI
);
17003 (void)opn
; /* avoid a compiler warning */
17004 MIPS_DEBUG("%s", opn
);
17007 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
17008 int ret
, int v1
, int v2
, int check_ret
)
17011 const char *opn
= "mipsdsp accumulator";
17018 if ((ret
== 0) && (check_ret
== 1)) {
17019 /* Treat as NOP. */
17024 t0
= tcg_temp_new();
17025 t1
= tcg_temp_new();
17026 v1_t
= tcg_temp_new();
17027 v2_t
= tcg_temp_new();
17029 gen_load_gpr(v1_t
, v1
);
17030 gen_load_gpr(v2_t
, v2
);
17033 case OPC_EXTR_W_DSP
:
17037 tcg_gen_movi_tl(t0
, v2
);
17038 tcg_gen_movi_tl(t1
, v1
);
17039 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17042 tcg_gen_movi_tl(t0
, v2
);
17043 tcg_gen_movi_tl(t1
, v1
);
17044 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17046 case OPC_EXTR_RS_W
:
17047 tcg_gen_movi_tl(t0
, v2
);
17048 tcg_gen_movi_tl(t1
, v1
);
17049 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17052 tcg_gen_movi_tl(t0
, v2
);
17053 tcg_gen_movi_tl(t1
, v1
);
17054 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17056 case OPC_EXTRV_S_H
:
17057 tcg_gen_movi_tl(t0
, v2
);
17058 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17061 tcg_gen_movi_tl(t0
, v2
);
17062 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17064 case OPC_EXTRV_R_W
:
17065 tcg_gen_movi_tl(t0
, v2
);
17066 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17068 case OPC_EXTRV_RS_W
:
17069 tcg_gen_movi_tl(t0
, v2
);
17070 gen_helper_extr_rs_w(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_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17078 tcg_gen_movi_tl(t0
, v2
);
17079 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17082 tcg_gen_movi_tl(t0
, v2
);
17083 tcg_gen_movi_tl(t1
, v1
);
17084 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17087 tcg_gen_movi_tl(t0
, v2
);
17088 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17091 imm
= (ctx
->opcode
>> 20) & 0x3F;
17092 tcg_gen_movi_tl(t0
, ret
);
17093 tcg_gen_movi_tl(t1
, imm
);
17094 gen_helper_shilo(t0
, t1
, cpu_env
);
17097 tcg_gen_movi_tl(t0
, ret
);
17098 gen_helper_shilo(t0
, v1_t
, cpu_env
);
17101 tcg_gen_movi_tl(t0
, ret
);
17102 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
17105 imm
= (ctx
->opcode
>> 11) & 0x3FF;
17106 tcg_gen_movi_tl(t0
, imm
);
17107 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
17110 imm
= (ctx
->opcode
>> 16) & 0x03FF;
17111 tcg_gen_movi_tl(t0
, imm
);
17112 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
17116 #ifdef TARGET_MIPS64
17117 case OPC_DEXTR_W_DSP
:
17121 tcg_gen_movi_tl(t0
, ret
);
17122 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
17126 int shift
= (ctx
->opcode
>> 19) & 0x7F;
17127 int ac
= (ctx
->opcode
>> 11) & 0x03;
17128 tcg_gen_movi_tl(t0
, shift
);
17129 tcg_gen_movi_tl(t1
, ac
);
17130 gen_helper_dshilo(t0
, t1
, cpu_env
);
17135 int ac
= (ctx
->opcode
>> 11) & 0x03;
17136 tcg_gen_movi_tl(t0
, ac
);
17137 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
17141 tcg_gen_movi_tl(t0
, v2
);
17142 tcg_gen_movi_tl(t1
, v1
);
17144 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17147 tcg_gen_movi_tl(t0
, v2
);
17148 gen_helper_dextp(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_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17156 tcg_gen_movi_tl(t0
, v2
);
17157 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17160 tcg_gen_movi_tl(t0
, v2
);
17161 tcg_gen_movi_tl(t1
, v1
);
17162 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17164 case OPC_DEXTR_R_L
:
17165 tcg_gen_movi_tl(t0
, v2
);
17166 tcg_gen_movi_tl(t1
, v1
);
17167 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17169 case OPC_DEXTR_RS_L
:
17170 tcg_gen_movi_tl(t0
, v2
);
17171 tcg_gen_movi_tl(t1
, v1
);
17172 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17175 tcg_gen_movi_tl(t0
, v2
);
17176 tcg_gen_movi_tl(t1
, v1
);
17177 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17179 case OPC_DEXTR_R_W
:
17180 tcg_gen_movi_tl(t0
, v2
);
17181 tcg_gen_movi_tl(t1
, v1
);
17182 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17184 case OPC_DEXTR_RS_W
:
17185 tcg_gen_movi_tl(t0
, v2
);
17186 tcg_gen_movi_tl(t1
, v1
);
17187 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17189 case OPC_DEXTR_S_H
:
17190 tcg_gen_movi_tl(t0
, v2
);
17191 tcg_gen_movi_tl(t1
, v1
);
17192 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17194 case OPC_DEXTRV_S_H
:
17195 tcg_gen_movi_tl(t0
, v2
);
17196 tcg_gen_movi_tl(t1
, v1
);
17197 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17200 tcg_gen_movi_tl(t0
, v2
);
17201 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17203 case OPC_DEXTRV_R_L
:
17204 tcg_gen_movi_tl(t0
, v2
);
17205 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17207 case OPC_DEXTRV_RS_L
:
17208 tcg_gen_movi_tl(t0
, v2
);
17209 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17212 tcg_gen_movi_tl(t0
, v2
);
17213 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17215 case OPC_DEXTRV_R_W
:
17216 tcg_gen_movi_tl(t0
, v2
);
17217 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17219 case OPC_DEXTRV_RS_W
:
17220 tcg_gen_movi_tl(t0
, v2
);
17221 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17230 tcg_temp_free(v1_t
);
17231 tcg_temp_free(v2_t
);
17233 (void)opn
; /* avoid a compiler warning */
17234 MIPS_DEBUG("%s", opn
);
17237 /* End MIPSDSP functions. */
17239 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
17241 int rs
, rt
, rd
, sa
;
17244 rs
= (ctx
->opcode
>> 21) & 0x1f;
17245 rt
= (ctx
->opcode
>> 16) & 0x1f;
17246 rd
= (ctx
->opcode
>> 11) & 0x1f;
17247 sa
= (ctx
->opcode
>> 6) & 0x1f;
17249 op1
= MASK_SPECIAL(ctx
->opcode
);
17252 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
17254 case OPC_MULT
... OPC_DIVU
:
17255 op2
= MASK_R6_MULDIV(ctx
->opcode
);
17265 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
17268 MIPS_INVAL("special_r6 muldiv");
17269 generate_exception(ctx
, EXCP_RI
);
17275 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
17279 if (rt
== 0 && sa
== 1) {
17280 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17281 We need additionally to check other fields */
17282 gen_cl(ctx
, op1
, rd
, rs
);
17284 generate_exception(ctx
, EXCP_RI
);
17288 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
17289 gen_helper_do_semihosting(cpu_env
);
17291 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
17292 generate_exception(ctx
, EXCP_RI
);
17294 generate_exception(ctx
, EXCP_DBp
);
17298 #if defined(TARGET_MIPS64)
17300 check_mips_64(ctx
);
17301 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
17305 if (rt
== 0 && sa
== 1) {
17306 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17307 We need additionally to check other fields */
17308 check_mips_64(ctx
);
17309 gen_cl(ctx
, op1
, rd
, rs
);
17311 generate_exception(ctx
, EXCP_RI
);
17314 case OPC_DMULT
... OPC_DDIVU
:
17315 op2
= MASK_R6_MULDIV(ctx
->opcode
);
17325 check_mips_64(ctx
);
17326 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
17329 MIPS_INVAL("special_r6 muldiv");
17330 generate_exception(ctx
, EXCP_RI
);
17335 default: /* Invalid */
17336 MIPS_INVAL("special_r6");
17337 generate_exception(ctx
, EXCP_RI
);
17342 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17344 int rs
, rt
, rd
, sa
;
17347 rs
= (ctx
->opcode
>> 21) & 0x1f;
17348 rt
= (ctx
->opcode
>> 16) & 0x1f;
17349 rd
= (ctx
->opcode
>> 11) & 0x1f;
17350 sa
= (ctx
->opcode
>> 6) & 0x1f;
17352 op1
= MASK_SPECIAL(ctx
->opcode
);
17354 case OPC_MOVN
: /* Conditional move */
17356 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
17357 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
17358 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
17360 case OPC_MFHI
: /* Move from HI/LO */
17362 gen_HILO(ctx
, op1
, rs
& 3, rd
);
17365 case OPC_MTLO
: /* Move to HI/LO */
17366 gen_HILO(ctx
, op1
, rd
& 3, rs
);
17369 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
17370 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17371 check_cp1_enabled(ctx
);
17372 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
17373 (ctx
->opcode
>> 16) & 1);
17375 generate_exception_err(ctx
, EXCP_CpU
, 1);
17381 check_insn(ctx
, INSN_VR54XX
);
17382 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
17383 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
17385 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
17390 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
17392 #if defined(TARGET_MIPS64)
17393 case OPC_DMULT
... OPC_DDIVU
:
17394 check_insn(ctx
, ISA_MIPS3
);
17395 check_mips_64(ctx
);
17396 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
17400 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
17403 #ifdef MIPS_STRICT_STANDARD
17404 MIPS_INVAL("SPIM");
17405 generate_exception(ctx
, EXCP_RI
);
17407 /* Implemented as RI exception for now. */
17408 MIPS_INVAL("spim (unofficial)");
17409 generate_exception(ctx
, EXCP_RI
);
17412 default: /* Invalid */
17413 MIPS_INVAL("special_legacy");
17414 generate_exception(ctx
, EXCP_RI
);
17419 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
17421 int rs
, rt
, rd
, sa
;
17424 rs
= (ctx
->opcode
>> 21) & 0x1f;
17425 rt
= (ctx
->opcode
>> 16) & 0x1f;
17426 rd
= (ctx
->opcode
>> 11) & 0x1f;
17427 sa
= (ctx
->opcode
>> 6) & 0x1f;
17429 op1
= MASK_SPECIAL(ctx
->opcode
);
17431 case OPC_SLL
: /* Shift with immediate */
17432 if (sa
== 5 && rd
== 0 &&
17433 rs
== 0 && rt
== 0) { /* PAUSE */
17434 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
17435 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
17436 MIPS_DEBUG("CTI in delay / forbidden slot");
17437 generate_exception(ctx
, EXCP_RI
);
17443 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17446 switch ((ctx
->opcode
>> 21) & 0x1f) {
17448 /* rotr is decoded as srl on non-R2 CPUs */
17449 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17454 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17457 generate_exception(ctx
, EXCP_RI
);
17461 case OPC_ADD
... OPC_SUBU
:
17462 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17464 case OPC_SLLV
: /* Shifts */
17466 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17469 switch ((ctx
->opcode
>> 6) & 0x1f) {
17471 /* rotrv is decoded as srlv on non-R2 CPUs */
17472 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17477 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17480 generate_exception(ctx
, EXCP_RI
);
17484 case OPC_SLT
: /* Set on less than */
17486 gen_slt(ctx
, op1
, rd
, rs
, rt
);
17488 case OPC_AND
: /* Logic*/
17492 gen_logic(ctx
, op1
, rd
, rs
, rt
);
17495 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
17497 case OPC_TGE
... OPC_TEQ
: /* Traps */
17499 check_insn(ctx
, ISA_MIPS2
);
17500 gen_trap(ctx
, op1
, rs
, rt
, -1);
17502 case OPC_LSA
: /* OPC_PMON */
17503 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
17504 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
17505 decode_opc_special_r6(env
, ctx
);
17507 /* Pmon entry point, also R4010 selsl */
17508 #ifdef MIPS_STRICT_STANDARD
17509 MIPS_INVAL("PMON / selsl");
17510 generate_exception(ctx
, EXCP_RI
);
17512 gen_helper_0e0i(pmon
, sa
);
17517 generate_exception(ctx
, EXCP_SYSCALL
);
17518 ctx
->bstate
= BS_STOP
;
17521 generate_exception(ctx
, EXCP_BREAK
);
17524 check_insn(ctx
, ISA_MIPS2
);
17525 /* Treat as NOP. */
17528 #if defined(TARGET_MIPS64)
17529 /* MIPS64 specific opcodes */
17534 check_insn(ctx
, ISA_MIPS3
);
17535 check_mips_64(ctx
);
17536 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17539 switch ((ctx
->opcode
>> 21) & 0x1f) {
17541 /* drotr is decoded as dsrl on non-R2 CPUs */
17542 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17547 check_insn(ctx
, ISA_MIPS3
);
17548 check_mips_64(ctx
);
17549 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17552 generate_exception(ctx
, EXCP_RI
);
17557 switch ((ctx
->opcode
>> 21) & 0x1f) {
17559 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17560 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17565 check_insn(ctx
, ISA_MIPS3
);
17566 check_mips_64(ctx
);
17567 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17570 generate_exception(ctx
, EXCP_RI
);
17574 case OPC_DADD
... OPC_DSUBU
:
17575 check_insn(ctx
, ISA_MIPS3
);
17576 check_mips_64(ctx
);
17577 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17581 check_insn(ctx
, ISA_MIPS3
);
17582 check_mips_64(ctx
);
17583 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17586 switch ((ctx
->opcode
>> 6) & 0x1f) {
17588 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17589 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17594 check_insn(ctx
, ISA_MIPS3
);
17595 check_mips_64(ctx
);
17596 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17599 generate_exception(ctx
, EXCP_RI
);
17604 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
17605 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
17606 decode_opc_special_r6(env
, ctx
);
17611 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17612 decode_opc_special_r6(env
, ctx
);
17614 decode_opc_special_legacy(env
, ctx
);
17619 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17624 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17626 rs
= (ctx
->opcode
>> 21) & 0x1f;
17627 rt
= (ctx
->opcode
>> 16) & 0x1f;
17628 rd
= (ctx
->opcode
>> 11) & 0x1f;
17630 op1
= MASK_SPECIAL2(ctx
->opcode
);
17632 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
17633 case OPC_MSUB
... OPC_MSUBU
:
17634 check_insn(ctx
, ISA_MIPS32
);
17635 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
17638 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17641 case OPC_DIVU_G_2F
:
17642 case OPC_MULT_G_2F
:
17643 case OPC_MULTU_G_2F
:
17645 case OPC_MODU_G_2F
:
17646 check_insn(ctx
, INSN_LOONGSON2F
);
17647 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17651 check_insn(ctx
, ISA_MIPS32
);
17652 gen_cl(ctx
, op1
, rd
, rs
);
17655 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
17656 gen_helper_do_semihosting(cpu_env
);
17658 /* XXX: not clear which exception should be raised
17659 * when in debug mode...
17661 check_insn(ctx
, ISA_MIPS32
);
17662 generate_exception(ctx
, EXCP_DBp
);
17665 #if defined(TARGET_MIPS64)
17668 check_insn(ctx
, ISA_MIPS64
);
17669 check_mips_64(ctx
);
17670 gen_cl(ctx
, op1
, rd
, rs
);
17672 case OPC_DMULT_G_2F
:
17673 case OPC_DMULTU_G_2F
:
17674 case OPC_DDIV_G_2F
:
17675 case OPC_DDIVU_G_2F
:
17676 case OPC_DMOD_G_2F
:
17677 case OPC_DMODU_G_2F
:
17678 check_insn(ctx
, INSN_LOONGSON2F
);
17679 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17682 default: /* Invalid */
17683 MIPS_INVAL("special2_legacy");
17684 generate_exception(ctx
, EXCP_RI
);
17689 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
17691 int rs
, rt
, rd
, sa
;
17695 rs
= (ctx
->opcode
>> 21) & 0x1f;
17696 rt
= (ctx
->opcode
>> 16) & 0x1f;
17697 rd
= (ctx
->opcode
>> 11) & 0x1f;
17698 sa
= (ctx
->opcode
>> 6) & 0x1f;
17699 imm
= (int16_t)ctx
->opcode
>> 7;
17701 op1
= MASK_SPECIAL3(ctx
->opcode
);
17705 /* hint codes 24-31 are reserved and signal RI */
17706 generate_exception(ctx
, EXCP_RI
);
17708 /* Treat as NOP. */
17711 /* Treat as NOP. */
17714 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
17717 gen_ld(ctx
, op1
, rt
, rs
, imm
);
17722 /* Treat as NOP. */
17725 op2
= MASK_BSHFL(ctx
->opcode
);
17727 case OPC_ALIGN
... OPC_ALIGN_END
:
17728 gen_align(ctx
, OPC_ALIGN
, rd
, rs
, rt
, sa
& 3);
17731 gen_bitswap(ctx
, op2
, rd
, rt
);
17736 #if defined(TARGET_MIPS64)
17738 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
17741 gen_ld(ctx
, op1
, rt
, rs
, imm
);
17744 check_mips_64(ctx
);
17747 /* Treat as NOP. */
17750 op2
= MASK_DBSHFL(ctx
->opcode
);
17752 case OPC_DALIGN
... OPC_DALIGN_END
:
17753 gen_align(ctx
, OPC_DALIGN
, rd
, rs
, rt
, sa
& 7);
17756 gen_bitswap(ctx
, op2
, rd
, rt
);
17763 default: /* Invalid */
17764 MIPS_INVAL("special3_r6");
17765 generate_exception(ctx
, EXCP_RI
);
17770 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17775 rs
= (ctx
->opcode
>> 21) & 0x1f;
17776 rt
= (ctx
->opcode
>> 16) & 0x1f;
17777 rd
= (ctx
->opcode
>> 11) & 0x1f;
17779 op1
= MASK_SPECIAL3(ctx
->opcode
);
17781 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
17782 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
17783 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
17784 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17785 * the same mask and op1. */
17786 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
17787 op2
= MASK_ADDUH_QB(ctx
->opcode
);
17790 case OPC_ADDUH_R_QB
:
17792 case OPC_ADDQH_R_PH
:
17794 case OPC_ADDQH_R_W
:
17796 case OPC_SUBUH_R_QB
:
17798 case OPC_SUBQH_R_PH
:
17800 case OPC_SUBQH_R_W
:
17801 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17806 case OPC_MULQ_RS_W
:
17807 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17810 MIPS_INVAL("MASK ADDUH.QB");
17811 generate_exception(ctx
, EXCP_RI
);
17814 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
17815 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17817 generate_exception(ctx
, EXCP_RI
);
17821 op2
= MASK_LX(ctx
->opcode
);
17823 #if defined(TARGET_MIPS64)
17829 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
17831 default: /* Invalid */
17832 MIPS_INVAL("MASK LX");
17833 generate_exception(ctx
, EXCP_RI
);
17837 case OPC_ABSQ_S_PH_DSP
:
17838 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
17840 case OPC_ABSQ_S_QB
:
17841 case OPC_ABSQ_S_PH
:
17843 case OPC_PRECEQ_W_PHL
:
17844 case OPC_PRECEQ_W_PHR
:
17845 case OPC_PRECEQU_PH_QBL
:
17846 case OPC_PRECEQU_PH_QBR
:
17847 case OPC_PRECEQU_PH_QBLA
:
17848 case OPC_PRECEQU_PH_QBRA
:
17849 case OPC_PRECEU_PH_QBL
:
17850 case OPC_PRECEU_PH_QBR
:
17851 case OPC_PRECEU_PH_QBLA
:
17852 case OPC_PRECEU_PH_QBRA
:
17853 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17860 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
17863 MIPS_INVAL("MASK ABSQ_S.PH");
17864 generate_exception(ctx
, EXCP_RI
);
17868 case OPC_ADDU_QB_DSP
:
17869 op2
= MASK_ADDU_QB(ctx
->opcode
);
17872 case OPC_ADDQ_S_PH
:
17875 case OPC_ADDU_S_QB
:
17877 case OPC_ADDU_S_PH
:
17879 case OPC_SUBQ_S_PH
:
17882 case OPC_SUBU_S_QB
:
17884 case OPC_SUBU_S_PH
:
17888 case OPC_RADDU_W_QB
:
17889 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17891 case OPC_MULEU_S_PH_QBL
:
17892 case OPC_MULEU_S_PH_QBR
:
17893 case OPC_MULQ_RS_PH
:
17894 case OPC_MULEQ_S_W_PHL
:
17895 case OPC_MULEQ_S_W_PHR
:
17896 case OPC_MULQ_S_PH
:
17897 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17899 default: /* Invalid */
17900 MIPS_INVAL("MASK ADDU.QB");
17901 generate_exception(ctx
, EXCP_RI
);
17906 case OPC_CMPU_EQ_QB_DSP
:
17907 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
17909 case OPC_PRECR_SRA_PH_W
:
17910 case OPC_PRECR_SRA_R_PH_W
:
17911 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
17913 case OPC_PRECR_QB_PH
:
17914 case OPC_PRECRQ_QB_PH
:
17915 case OPC_PRECRQ_PH_W
:
17916 case OPC_PRECRQ_RS_PH_W
:
17917 case OPC_PRECRQU_S_QB_PH
:
17918 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17920 case OPC_CMPU_EQ_QB
:
17921 case OPC_CMPU_LT_QB
:
17922 case OPC_CMPU_LE_QB
:
17923 case OPC_CMP_EQ_PH
:
17924 case OPC_CMP_LT_PH
:
17925 case OPC_CMP_LE_PH
:
17926 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17928 case OPC_CMPGU_EQ_QB
:
17929 case OPC_CMPGU_LT_QB
:
17930 case OPC_CMPGU_LE_QB
:
17931 case OPC_CMPGDU_EQ_QB
:
17932 case OPC_CMPGDU_LT_QB
:
17933 case OPC_CMPGDU_LE_QB
:
17936 case OPC_PACKRL_PH
:
17937 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17939 default: /* Invalid */
17940 MIPS_INVAL("MASK CMPU.EQ.QB");
17941 generate_exception(ctx
, EXCP_RI
);
17945 case OPC_SHLL_QB_DSP
:
17946 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
17948 case OPC_DPA_W_PH_DSP
:
17949 op2
= MASK_DPA_W_PH(ctx
->opcode
);
17951 case OPC_DPAU_H_QBL
:
17952 case OPC_DPAU_H_QBR
:
17953 case OPC_DPSU_H_QBL
:
17954 case OPC_DPSU_H_QBR
:
17956 case OPC_DPAX_W_PH
:
17957 case OPC_DPAQ_S_W_PH
:
17958 case OPC_DPAQX_S_W_PH
:
17959 case OPC_DPAQX_SA_W_PH
:
17961 case OPC_DPSX_W_PH
:
17962 case OPC_DPSQ_S_W_PH
:
17963 case OPC_DPSQX_S_W_PH
:
17964 case OPC_DPSQX_SA_W_PH
:
17965 case OPC_MULSAQ_S_W_PH
:
17966 case OPC_DPAQ_SA_L_W
:
17967 case OPC_DPSQ_SA_L_W
:
17968 case OPC_MAQ_S_W_PHL
:
17969 case OPC_MAQ_S_W_PHR
:
17970 case OPC_MAQ_SA_W_PHL
:
17971 case OPC_MAQ_SA_W_PHR
:
17972 case OPC_MULSA_W_PH
:
17973 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17975 default: /* Invalid */
17976 MIPS_INVAL("MASK DPAW.PH");
17977 generate_exception(ctx
, EXCP_RI
);
17982 op2
= MASK_INSV(ctx
->opcode
);
17994 t0
= tcg_temp_new();
17995 t1
= tcg_temp_new();
17997 gen_load_gpr(t0
, rt
);
17998 gen_load_gpr(t1
, rs
);
18000 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
18006 default: /* Invalid */
18007 MIPS_INVAL("MASK INSV");
18008 generate_exception(ctx
, EXCP_RI
);
18012 case OPC_APPEND_DSP
:
18013 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
18015 case OPC_EXTR_W_DSP
:
18016 op2
= MASK_EXTR_W(ctx
->opcode
);
18020 case OPC_EXTR_RS_W
:
18022 case OPC_EXTRV_S_H
:
18024 case OPC_EXTRV_R_W
:
18025 case OPC_EXTRV_RS_W
:
18030 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
18033 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
18039 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18041 default: /* Invalid */
18042 MIPS_INVAL("MASK EXTR.W");
18043 generate_exception(ctx
, EXCP_RI
);
18047 #if defined(TARGET_MIPS64)
18048 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
18049 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
18050 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
18051 check_insn(ctx
, INSN_LOONGSON2E
);
18052 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
18054 case OPC_ABSQ_S_QH_DSP
:
18055 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
18057 case OPC_PRECEQ_L_PWL
:
18058 case OPC_PRECEQ_L_PWR
:
18059 case OPC_PRECEQ_PW_QHL
:
18060 case OPC_PRECEQ_PW_QHR
:
18061 case OPC_PRECEQ_PW_QHLA
:
18062 case OPC_PRECEQ_PW_QHRA
:
18063 case OPC_PRECEQU_QH_OBL
:
18064 case OPC_PRECEQU_QH_OBR
:
18065 case OPC_PRECEQU_QH_OBLA
:
18066 case OPC_PRECEQU_QH_OBRA
:
18067 case OPC_PRECEU_QH_OBL
:
18068 case OPC_PRECEU_QH_OBR
:
18069 case OPC_PRECEU_QH_OBLA
:
18070 case OPC_PRECEU_QH_OBRA
:
18071 case OPC_ABSQ_S_OB
:
18072 case OPC_ABSQ_S_PW
:
18073 case OPC_ABSQ_S_QH
:
18074 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
18082 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
18084 default: /* Invalid */
18085 MIPS_INVAL("MASK ABSQ_S.QH");
18086 generate_exception(ctx
, EXCP_RI
);
18090 case OPC_ADDU_OB_DSP
:
18091 op2
= MASK_ADDU_OB(ctx
->opcode
);
18093 case OPC_RADDU_L_OB
:
18095 case OPC_SUBQ_S_PW
:
18097 case OPC_SUBQ_S_QH
:
18099 case OPC_SUBU_S_OB
:
18101 case OPC_SUBU_S_QH
:
18103 case OPC_SUBUH_R_OB
:
18105 case OPC_ADDQ_S_PW
:
18107 case OPC_ADDQ_S_QH
:
18109 case OPC_ADDU_S_OB
:
18111 case OPC_ADDU_S_QH
:
18113 case OPC_ADDUH_R_OB
:
18114 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
18116 case OPC_MULEQ_S_PW_QHL
:
18117 case OPC_MULEQ_S_PW_QHR
:
18118 case OPC_MULEU_S_QH_OBL
:
18119 case OPC_MULEU_S_QH_OBR
:
18120 case OPC_MULQ_RS_QH
:
18121 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
18123 default: /* Invalid */
18124 MIPS_INVAL("MASK ADDU.OB");
18125 generate_exception(ctx
, EXCP_RI
);
18129 case OPC_CMPU_EQ_OB_DSP
:
18130 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
18132 case OPC_PRECR_SRA_QH_PW
:
18133 case OPC_PRECR_SRA_R_QH_PW
:
18134 /* Return value is rt. */
18135 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
18137 case OPC_PRECR_OB_QH
:
18138 case OPC_PRECRQ_OB_QH
:
18139 case OPC_PRECRQ_PW_L
:
18140 case OPC_PRECRQ_QH_PW
:
18141 case OPC_PRECRQ_RS_QH_PW
:
18142 case OPC_PRECRQU_S_OB_QH
:
18143 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
18145 case OPC_CMPU_EQ_OB
:
18146 case OPC_CMPU_LT_OB
:
18147 case OPC_CMPU_LE_OB
:
18148 case OPC_CMP_EQ_QH
:
18149 case OPC_CMP_LT_QH
:
18150 case OPC_CMP_LE_QH
:
18151 case OPC_CMP_EQ_PW
:
18152 case OPC_CMP_LT_PW
:
18153 case OPC_CMP_LE_PW
:
18154 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18156 case OPC_CMPGDU_EQ_OB
:
18157 case OPC_CMPGDU_LT_OB
:
18158 case OPC_CMPGDU_LE_OB
:
18159 case OPC_CMPGU_EQ_OB
:
18160 case OPC_CMPGU_LT_OB
:
18161 case OPC_CMPGU_LE_OB
:
18162 case OPC_PACKRL_PW
:
18166 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
18168 default: /* Invalid */
18169 MIPS_INVAL("MASK CMPU_EQ.OB");
18170 generate_exception(ctx
, EXCP_RI
);
18174 case OPC_DAPPEND_DSP
:
18175 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
18177 case OPC_DEXTR_W_DSP
:
18178 op2
= MASK_DEXTR_W(ctx
->opcode
);
18185 case OPC_DEXTR_R_L
:
18186 case OPC_DEXTR_RS_L
:
18188 case OPC_DEXTR_R_W
:
18189 case OPC_DEXTR_RS_W
:
18190 case OPC_DEXTR_S_H
:
18192 case OPC_DEXTRV_R_L
:
18193 case OPC_DEXTRV_RS_L
:
18194 case OPC_DEXTRV_S_H
:
18196 case OPC_DEXTRV_R_W
:
18197 case OPC_DEXTRV_RS_W
:
18198 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
18203 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18205 default: /* Invalid */
18206 MIPS_INVAL("MASK EXTR.W");
18207 generate_exception(ctx
, EXCP_RI
);
18211 case OPC_DPAQ_W_QH_DSP
:
18212 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
18214 case OPC_DPAU_H_OBL
:
18215 case OPC_DPAU_H_OBR
:
18216 case OPC_DPSU_H_OBL
:
18217 case OPC_DPSU_H_OBR
:
18219 case OPC_DPAQ_S_W_QH
:
18221 case OPC_DPSQ_S_W_QH
:
18222 case OPC_MULSAQ_S_W_QH
:
18223 case OPC_DPAQ_SA_L_PW
:
18224 case OPC_DPSQ_SA_L_PW
:
18225 case OPC_MULSAQ_S_L_PW
:
18226 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18228 case OPC_MAQ_S_W_QHLL
:
18229 case OPC_MAQ_S_W_QHLR
:
18230 case OPC_MAQ_S_W_QHRL
:
18231 case OPC_MAQ_S_W_QHRR
:
18232 case OPC_MAQ_SA_W_QHLL
:
18233 case OPC_MAQ_SA_W_QHLR
:
18234 case OPC_MAQ_SA_W_QHRL
:
18235 case OPC_MAQ_SA_W_QHRR
:
18236 case OPC_MAQ_S_L_PWL
:
18237 case OPC_MAQ_S_L_PWR
:
18242 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18244 default: /* Invalid */
18245 MIPS_INVAL("MASK DPAQ.W.QH");
18246 generate_exception(ctx
, EXCP_RI
);
18250 case OPC_DINSV_DSP
:
18251 op2
= MASK_INSV(ctx
->opcode
);
18263 t0
= tcg_temp_new();
18264 t1
= tcg_temp_new();
18266 gen_load_gpr(t0
, rt
);
18267 gen_load_gpr(t1
, rs
);
18269 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
18275 default: /* Invalid */
18276 MIPS_INVAL("MASK DINSV");
18277 generate_exception(ctx
, EXCP_RI
);
18281 case OPC_SHLL_OB_DSP
:
18282 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
18285 default: /* Invalid */
18286 MIPS_INVAL("special3_legacy");
18287 generate_exception(ctx
, EXCP_RI
);
18292 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
18294 int rs
, rt
, rd
, sa
;
18297 rs
= (ctx
->opcode
>> 21) & 0x1f;
18298 rt
= (ctx
->opcode
>> 16) & 0x1f;
18299 rd
= (ctx
->opcode
>> 11) & 0x1f;
18300 sa
= (ctx
->opcode
>> 6) & 0x1f;
18302 op1
= MASK_SPECIAL3(ctx
->opcode
);
18306 check_insn(ctx
, ISA_MIPS32R2
);
18307 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
18310 op2
= MASK_BSHFL(ctx
->opcode
);
18312 case OPC_ALIGN
... OPC_ALIGN_END
:
18314 check_insn(ctx
, ISA_MIPS32R6
);
18315 decode_opc_special3_r6(env
, ctx
);
18318 check_insn(ctx
, ISA_MIPS32R2
);
18319 gen_bshfl(ctx
, op2
, rt
, rd
);
18323 #if defined(TARGET_MIPS64)
18324 case OPC_DEXTM
... OPC_DEXT
:
18325 case OPC_DINSM
... OPC_DINS
:
18326 check_insn(ctx
, ISA_MIPS64R2
);
18327 check_mips_64(ctx
);
18328 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
18331 op2
= MASK_DBSHFL(ctx
->opcode
);
18333 case OPC_DALIGN
... OPC_DALIGN_END
:
18335 check_insn(ctx
, ISA_MIPS32R6
);
18336 decode_opc_special3_r6(env
, ctx
);
18339 check_insn(ctx
, ISA_MIPS64R2
);
18340 check_mips_64(ctx
);
18341 op2
= MASK_DBSHFL(ctx
->opcode
);
18342 gen_bshfl(ctx
, op2
, rt
, rd
);
18348 gen_rdhwr(ctx
, rt
, rd
);
18351 check_insn(ctx
, ASE_MT
);
18353 TCGv t0
= tcg_temp_new();
18354 TCGv t1
= tcg_temp_new();
18356 gen_load_gpr(t0
, rt
);
18357 gen_load_gpr(t1
, rs
);
18358 gen_helper_fork(t0
, t1
);
18364 check_insn(ctx
, ASE_MT
);
18366 TCGv t0
= tcg_temp_new();
18368 save_cpu_state(ctx
, 1);
18369 gen_load_gpr(t0
, rs
);
18370 gen_helper_yield(t0
, cpu_env
, t0
);
18371 gen_store_gpr(t0
, rd
);
18376 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18377 decode_opc_special3_r6(env
, ctx
);
18379 decode_opc_special3_legacy(env
, ctx
);
18384 /* MIPS SIMD Architecture (MSA) */
18385 static inline int check_msa_access(DisasContext
*ctx
)
18387 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
18388 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
18389 generate_exception(ctx
, EXCP_RI
);
18393 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
18394 if (ctx
->insn_flags
& ASE_MSA
) {
18395 generate_exception(ctx
, EXCP_MSADIS
);
18398 generate_exception(ctx
, EXCP_RI
);
18405 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
18407 /* generates tcg ops to check if any element is 0 */
18408 /* Note this function only works with MSA_WRLEN = 128 */
18409 uint64_t eval_zero_or_big
= 0;
18410 uint64_t eval_big
= 0;
18411 TCGv_i64 t0
= tcg_temp_new_i64();
18412 TCGv_i64 t1
= tcg_temp_new_i64();
18415 eval_zero_or_big
= 0x0101010101010101ULL
;
18416 eval_big
= 0x8080808080808080ULL
;
18419 eval_zero_or_big
= 0x0001000100010001ULL
;
18420 eval_big
= 0x8000800080008000ULL
;
18423 eval_zero_or_big
= 0x0000000100000001ULL
;
18424 eval_big
= 0x8000000080000000ULL
;
18427 eval_zero_or_big
= 0x0000000000000001ULL
;
18428 eval_big
= 0x8000000000000000ULL
;
18431 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<<1], eval_zero_or_big
);
18432 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<<1]);
18433 tcg_gen_andi_i64(t0
, t0
, eval_big
);
18434 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<<1)+1], eval_zero_or_big
);
18435 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<<1)+1]);
18436 tcg_gen_andi_i64(t1
, t1
, eval_big
);
18437 tcg_gen_or_i64(t0
, t0
, t1
);
18438 /* if all bits are zero then all elements are not zero */
18439 /* if some bit is non-zero then some element is zero */
18440 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
18441 tcg_gen_trunc_i64_tl(tresult
, t0
);
18442 tcg_temp_free_i64(t0
);
18443 tcg_temp_free_i64(t1
);
18446 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
18448 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18449 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18450 int64_t s16
= (int16_t)ctx
->opcode
;
18452 check_msa_access(ctx
);
18454 if (ctx
->insn_flags
& ISA_MIPS32R6
&& ctx
->hflags
& MIPS_HFLAG_BMASK
) {
18455 MIPS_DEBUG("CTI in delay / forbidden slot");
18456 generate_exception(ctx
, EXCP_RI
);
18463 TCGv_i64 t0
= tcg_temp_new_i64();
18464 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<<1], msa_wr_d
[(wt
<<1)+1]);
18465 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
18466 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
18467 tcg_gen_trunc_i64_tl(bcond
, t0
);
18468 tcg_temp_free_i64(t0
);
18475 gen_check_zero_element(bcond
, df
, wt
);
18481 gen_check_zero_element(bcond
, df
, wt
);
18482 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
18486 ctx
->btarget
= ctx
->pc
+ (s16
<< 2) + 4;
18488 ctx
->hflags
|= MIPS_HFLAG_BC
;
18489 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
18492 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
18494 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18495 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
18496 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18497 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18499 TCGv_i32 twd
= tcg_const_i32(wd
);
18500 TCGv_i32 tws
= tcg_const_i32(ws
);
18501 TCGv_i32 ti8
= tcg_const_i32(i8
);
18503 switch (MASK_MSA_I8(ctx
->opcode
)) {
18505 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
18508 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
18511 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
18514 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
18517 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
18520 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
18523 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
18529 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
18530 if (df
== DF_DOUBLE
) {
18531 generate_exception(ctx
, EXCP_RI
);
18533 TCGv_i32 tdf
= tcg_const_i32(df
);
18534 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
18535 tcg_temp_free_i32(tdf
);
18540 MIPS_INVAL("MSA instruction");
18541 generate_exception(ctx
, EXCP_RI
);
18545 tcg_temp_free_i32(twd
);
18546 tcg_temp_free_i32(tws
);
18547 tcg_temp_free_i32(ti8
);
18550 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
18552 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18553 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18554 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
18555 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
18556 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18557 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18559 TCGv_i32 tdf
= tcg_const_i32(df
);
18560 TCGv_i32 twd
= tcg_const_i32(wd
);
18561 TCGv_i32 tws
= tcg_const_i32(ws
);
18562 TCGv_i32 timm
= tcg_temp_new_i32();
18563 tcg_gen_movi_i32(timm
, u5
);
18565 switch (MASK_MSA_I5(ctx
->opcode
)) {
18567 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18570 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18572 case OPC_MAXI_S_df
:
18573 tcg_gen_movi_i32(timm
, s5
);
18574 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18576 case OPC_MAXI_U_df
:
18577 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18579 case OPC_MINI_S_df
:
18580 tcg_gen_movi_i32(timm
, s5
);
18581 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18583 case OPC_MINI_U_df
:
18584 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18587 tcg_gen_movi_i32(timm
, s5
);
18588 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18590 case OPC_CLTI_S_df
:
18591 tcg_gen_movi_i32(timm
, s5
);
18592 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18594 case OPC_CLTI_U_df
:
18595 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18597 case OPC_CLEI_S_df
:
18598 tcg_gen_movi_i32(timm
, s5
);
18599 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18601 case OPC_CLEI_U_df
:
18602 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18606 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
18607 tcg_gen_movi_i32(timm
, s10
);
18608 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
18612 MIPS_INVAL("MSA instruction");
18613 generate_exception(ctx
, EXCP_RI
);
18617 tcg_temp_free_i32(tdf
);
18618 tcg_temp_free_i32(twd
);
18619 tcg_temp_free_i32(tws
);
18620 tcg_temp_free_i32(timm
);
18623 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
18625 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18626 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
18627 uint32_t df
= 0, m
= 0;
18628 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18629 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18636 if ((dfm
& 0x40) == 0x00) {
18639 } else if ((dfm
& 0x60) == 0x40) {
18642 } else if ((dfm
& 0x70) == 0x60) {
18645 } else if ((dfm
& 0x78) == 0x70) {
18649 generate_exception(ctx
, EXCP_RI
);
18653 tdf
= tcg_const_i32(df
);
18654 tm
= tcg_const_i32(m
);
18655 twd
= tcg_const_i32(wd
);
18656 tws
= tcg_const_i32(ws
);
18658 switch (MASK_MSA_BIT(ctx
->opcode
)) {
18660 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18663 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
18666 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18669 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18672 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
18675 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
18677 case OPC_BINSLI_df
:
18678 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18680 case OPC_BINSRI_df
:
18681 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18684 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
18687 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
18690 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
18693 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18696 MIPS_INVAL("MSA instruction");
18697 generate_exception(ctx
, EXCP_RI
);
18701 tcg_temp_free_i32(tdf
);
18702 tcg_temp_free_i32(tm
);
18703 tcg_temp_free_i32(twd
);
18704 tcg_temp_free_i32(tws
);
18707 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
18709 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18710 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18711 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18712 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18713 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18715 TCGv_i32 tdf
= tcg_const_i32(df
);
18716 TCGv_i32 twd
= tcg_const_i32(wd
);
18717 TCGv_i32 tws
= tcg_const_i32(ws
);
18718 TCGv_i32 twt
= tcg_const_i32(wt
);
18720 switch (MASK_MSA_3R(ctx
->opcode
)) {
18722 gen_helper_msa_sll_df(cpu_env
, tdf
, twd
, tws
, twt
);
18725 gen_helper_msa_addv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18728 gen_helper_msa_ceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18731 gen_helper_msa_add_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18733 case OPC_SUBS_S_df
:
18734 gen_helper_msa_subs_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18737 gen_helper_msa_mulv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18740 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
18743 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18746 gen_helper_msa_sra_df(cpu_env
, tdf
, twd
, tws
, twt
);
18749 gen_helper_msa_subv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18751 case OPC_ADDS_A_df
:
18752 gen_helper_msa_adds_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18754 case OPC_SUBS_U_df
:
18755 gen_helper_msa_subs_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18758 gen_helper_msa_maddv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18761 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
18764 gen_helper_msa_srar_df(cpu_env
, tdf
, twd
, tws
, twt
);
18767 gen_helper_msa_srl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18770 gen_helper_msa_max_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18773 gen_helper_msa_clt_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18775 case OPC_ADDS_S_df
:
18776 gen_helper_msa_adds_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18778 case OPC_SUBSUS_U_df
:
18779 gen_helper_msa_subsus_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18782 gen_helper_msa_msubv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18785 gen_helper_msa_pckev_df(cpu_env
, tdf
, twd
, tws
, twt
);
18788 gen_helper_msa_srlr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18791 gen_helper_msa_bclr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18794 gen_helper_msa_max_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18797 gen_helper_msa_clt_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18799 case OPC_ADDS_U_df
:
18800 gen_helper_msa_adds_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18802 case OPC_SUBSUU_S_df
:
18803 gen_helper_msa_subsuu_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18806 gen_helper_msa_pckod_df(cpu_env
, tdf
, twd
, tws
, twt
);
18809 gen_helper_msa_bset_df(cpu_env
, tdf
, twd
, tws
, twt
);
18812 gen_helper_msa_min_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18815 gen_helper_msa_cle_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18818 gen_helper_msa_ave_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18820 case OPC_ASUB_S_df
:
18821 gen_helper_msa_asub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18824 gen_helper_msa_div_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18827 gen_helper_msa_ilvl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18830 gen_helper_msa_bneg_df(cpu_env
, tdf
, twd
, tws
, twt
);
18833 gen_helper_msa_min_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18836 gen_helper_msa_cle_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18839 gen_helper_msa_ave_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18841 case OPC_ASUB_U_df
:
18842 gen_helper_msa_asub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18845 gen_helper_msa_div_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18848 gen_helper_msa_ilvr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18851 gen_helper_msa_binsl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18854 gen_helper_msa_max_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18856 case OPC_AVER_S_df
:
18857 gen_helper_msa_aver_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18860 gen_helper_msa_mod_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18863 gen_helper_msa_ilvev_df(cpu_env
, tdf
, twd
, tws
, twt
);
18866 gen_helper_msa_binsr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18869 gen_helper_msa_min_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18871 case OPC_AVER_U_df
:
18872 gen_helper_msa_aver_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18875 gen_helper_msa_mod_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18878 gen_helper_msa_ilvod_df(cpu_env
, tdf
, twd
, tws
, twt
);
18881 case OPC_DOTP_S_df
:
18882 case OPC_DOTP_U_df
:
18883 case OPC_DPADD_S_df
:
18884 case OPC_DPADD_U_df
:
18885 case OPC_DPSUB_S_df
:
18886 case OPC_HADD_S_df
:
18887 case OPC_DPSUB_U_df
:
18888 case OPC_HADD_U_df
:
18889 case OPC_HSUB_S_df
:
18890 case OPC_HSUB_U_df
:
18891 if (df
== DF_BYTE
) {
18892 generate_exception(ctx
, EXCP_RI
);
18894 switch (MASK_MSA_3R(ctx
->opcode
)) {
18895 case OPC_DOTP_S_df
:
18896 gen_helper_msa_dotp_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18898 case OPC_DOTP_U_df
:
18899 gen_helper_msa_dotp_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18901 case OPC_DPADD_S_df
:
18902 gen_helper_msa_dpadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18904 case OPC_DPADD_U_df
:
18905 gen_helper_msa_dpadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18907 case OPC_DPSUB_S_df
:
18908 gen_helper_msa_dpsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18910 case OPC_HADD_S_df
:
18911 gen_helper_msa_hadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18913 case OPC_DPSUB_U_df
:
18914 gen_helper_msa_dpsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18916 case OPC_HADD_U_df
:
18917 gen_helper_msa_hadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18919 case OPC_HSUB_S_df
:
18920 gen_helper_msa_hsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18922 case OPC_HSUB_U_df
:
18923 gen_helper_msa_hsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18928 MIPS_INVAL("MSA instruction");
18929 generate_exception(ctx
, EXCP_RI
);
18932 tcg_temp_free_i32(twd
);
18933 tcg_temp_free_i32(tws
);
18934 tcg_temp_free_i32(twt
);
18935 tcg_temp_free_i32(tdf
);
18938 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
18940 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18941 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
18942 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
18943 TCGv telm
= tcg_temp_new();
18944 TCGv_i32 tsr
= tcg_const_i32(source
);
18945 TCGv_i32 tdt
= tcg_const_i32(dest
);
18947 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
18949 gen_load_gpr(telm
, source
);
18950 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
18953 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
18954 gen_store_gpr(telm
, dest
);
18957 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
18960 MIPS_INVAL("MSA instruction");
18961 generate_exception(ctx
, EXCP_RI
);
18965 tcg_temp_free(telm
);
18966 tcg_temp_free_i32(tdt
);
18967 tcg_temp_free_i32(tsr
);
18970 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
18973 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18974 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18975 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18977 TCGv_i32 tws
= tcg_const_i32(ws
);
18978 TCGv_i32 twd
= tcg_const_i32(wd
);
18979 TCGv_i32 tn
= tcg_const_i32(n
);
18980 TCGv_i32 tdf
= tcg_const_i32(df
);
18982 switch (MASK_MSA_ELM(ctx
->opcode
)) {
18984 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
18986 case OPC_SPLATI_df
:
18987 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
18990 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
18992 case OPC_COPY_S_df
:
18993 case OPC_COPY_U_df
:
18994 case OPC_INSERT_df
:
18995 #if !defined(TARGET_MIPS64)
18996 /* Double format valid only for MIPS64 */
18997 if (df
== DF_DOUBLE
) {
18998 generate_exception(ctx
, EXCP_RI
);
19002 switch (MASK_MSA_ELM(ctx
->opcode
)) {
19003 case OPC_COPY_S_df
:
19004 gen_helper_msa_copy_s_df(cpu_env
, tdf
, twd
, tws
, tn
);
19006 case OPC_COPY_U_df
:
19007 gen_helper_msa_copy_u_df(cpu_env
, tdf
, twd
, tws
, tn
);
19009 case OPC_INSERT_df
:
19010 gen_helper_msa_insert_df(cpu_env
, tdf
, twd
, tws
, tn
);
19015 MIPS_INVAL("MSA instruction");
19016 generate_exception(ctx
, EXCP_RI
);
19018 tcg_temp_free_i32(twd
);
19019 tcg_temp_free_i32(tws
);
19020 tcg_temp_free_i32(tn
);
19021 tcg_temp_free_i32(tdf
);
19024 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
19026 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
19027 uint32_t df
= 0, n
= 0;
19029 if ((dfn
& 0x30) == 0x00) {
19032 } else if ((dfn
& 0x38) == 0x20) {
19035 } else if ((dfn
& 0x3c) == 0x30) {
19038 } else if ((dfn
& 0x3e) == 0x38) {
19041 } else if (dfn
== 0x3E) {
19042 /* CTCMSA, CFCMSA, MOVE.V */
19043 gen_msa_elm_3e(env
, ctx
);
19046 generate_exception(ctx
, EXCP_RI
);
19050 gen_msa_elm_df(env
, ctx
, df
, n
);
19053 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
19055 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19056 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
19057 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19058 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19059 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19061 TCGv_i32 twd
= tcg_const_i32(wd
);
19062 TCGv_i32 tws
= tcg_const_i32(ws
);
19063 TCGv_i32 twt
= tcg_const_i32(wt
);
19064 TCGv_i32 tdf
= tcg_temp_new_i32();
19066 /* adjust df value for floating-point instruction */
19067 tcg_gen_movi_i32(tdf
, df
+ 2);
19069 switch (MASK_MSA_3RF(ctx
->opcode
)) {
19071 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
19074 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
19077 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
19080 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
19083 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
19086 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19089 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
19092 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
19095 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19098 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
19101 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
19104 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
19107 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
19110 tcg_gen_movi_i32(tdf
, df
+ 1);
19111 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19114 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
19117 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
19119 case OPC_MADD_Q_df
:
19120 tcg_gen_movi_i32(tdf
, df
+ 1);
19121 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19124 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
19126 case OPC_MSUB_Q_df
:
19127 tcg_gen_movi_i32(tdf
, df
+ 1);
19128 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19131 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
19134 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
19137 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
19140 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
19143 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
19146 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
19149 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19152 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19155 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
19158 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19161 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
19164 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
19167 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
19169 case OPC_MULR_Q_df
:
19170 tcg_gen_movi_i32(tdf
, df
+ 1);
19171 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19174 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
19176 case OPC_FMIN_A_df
:
19177 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
19179 case OPC_MADDR_Q_df
:
19180 tcg_gen_movi_i32(tdf
, df
+ 1);
19181 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19184 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
19187 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
19189 case OPC_MSUBR_Q_df
:
19190 tcg_gen_movi_i32(tdf
, df
+ 1);
19191 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19194 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
19196 case OPC_FMAX_A_df
:
19197 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
19200 MIPS_INVAL("MSA instruction");
19201 generate_exception(ctx
, EXCP_RI
);
19205 tcg_temp_free_i32(twd
);
19206 tcg_temp_free_i32(tws
);
19207 tcg_temp_free_i32(twt
);
19208 tcg_temp_free_i32(tdf
);
19211 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
19213 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19214 (op & (0x7 << 18)))
19215 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19216 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19217 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19218 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
19219 TCGv_i32 twd
= tcg_const_i32(wd
);
19220 TCGv_i32 tws
= tcg_const_i32(ws
);
19221 TCGv_i32 twt
= tcg_const_i32(wt
);
19222 TCGv_i32 tdf
= tcg_const_i32(df
);
19224 switch (MASK_MSA_2R(ctx
->opcode
)) {
19226 #if !defined(TARGET_MIPS64)
19227 /* Double format valid only for MIPS64 */
19228 if (df
== DF_DOUBLE
) {
19229 generate_exception(ctx
, EXCP_RI
);
19233 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
19236 gen_helper_msa_pcnt_df(cpu_env
, tdf
, twd
, tws
);
19239 gen_helper_msa_nloc_df(cpu_env
, tdf
, twd
, tws
);
19242 gen_helper_msa_nlzc_df(cpu_env
, tdf
, twd
, tws
);
19245 MIPS_INVAL("MSA instruction");
19246 generate_exception(ctx
, EXCP_RI
);
19250 tcg_temp_free_i32(twd
);
19251 tcg_temp_free_i32(tws
);
19252 tcg_temp_free_i32(twt
);
19253 tcg_temp_free_i32(tdf
);
19256 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
19258 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19259 (op & (0xf << 17)))
19260 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19261 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19262 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19263 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
19264 TCGv_i32 twd
= tcg_const_i32(wd
);
19265 TCGv_i32 tws
= tcg_const_i32(ws
);
19266 TCGv_i32 twt
= tcg_const_i32(wt
);
19267 /* adjust df value for floating-point instruction */
19268 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
19270 switch (MASK_MSA_2RF(ctx
->opcode
)) {
19271 case OPC_FCLASS_df
:
19272 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
19274 case OPC_FTRUNC_S_df
:
19275 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
19277 case OPC_FTRUNC_U_df
:
19278 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
19281 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
19283 case OPC_FRSQRT_df
:
19284 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
19287 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
19290 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
19293 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
19295 case OPC_FEXUPL_df
:
19296 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
19298 case OPC_FEXUPR_df
:
19299 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
19302 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
19305 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
19307 case OPC_FTINT_S_df
:
19308 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
19310 case OPC_FTINT_U_df
:
19311 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
19313 case OPC_FFINT_S_df
:
19314 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
19316 case OPC_FFINT_U_df
:
19317 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
19321 tcg_temp_free_i32(twd
);
19322 tcg_temp_free_i32(tws
);
19323 tcg_temp_free_i32(twt
);
19324 tcg_temp_free_i32(tdf
);
19327 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
19329 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19330 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19331 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19332 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19333 TCGv_i32 twd
= tcg_const_i32(wd
);
19334 TCGv_i32 tws
= tcg_const_i32(ws
);
19335 TCGv_i32 twt
= tcg_const_i32(wt
);
19337 switch (MASK_MSA_VEC(ctx
->opcode
)) {
19339 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
19342 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
19345 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
19348 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
19351 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
19354 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
19357 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
19360 MIPS_INVAL("MSA instruction");
19361 generate_exception(ctx
, EXCP_RI
);
19365 tcg_temp_free_i32(twd
);
19366 tcg_temp_free_i32(tws
);
19367 tcg_temp_free_i32(twt
);
19370 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
19372 switch (MASK_MSA_VEC(ctx
->opcode
)) {
19380 gen_msa_vec_v(env
, ctx
);
19383 gen_msa_2r(env
, ctx
);
19386 gen_msa_2rf(env
, ctx
);
19389 MIPS_INVAL("MSA instruction");
19390 generate_exception(ctx
, EXCP_RI
);
19395 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
19397 uint32_t opcode
= ctx
->opcode
;
19398 check_insn(ctx
, ASE_MSA
);
19399 check_msa_access(ctx
);
19401 switch (MASK_MSA_MINOR(opcode
)) {
19402 case OPC_MSA_I8_00
:
19403 case OPC_MSA_I8_01
:
19404 case OPC_MSA_I8_02
:
19405 gen_msa_i8(env
, ctx
);
19407 case OPC_MSA_I5_06
:
19408 case OPC_MSA_I5_07
:
19409 gen_msa_i5(env
, ctx
);
19411 case OPC_MSA_BIT_09
:
19412 case OPC_MSA_BIT_0A
:
19413 gen_msa_bit(env
, ctx
);
19415 case OPC_MSA_3R_0D
:
19416 case OPC_MSA_3R_0E
:
19417 case OPC_MSA_3R_0F
:
19418 case OPC_MSA_3R_10
:
19419 case OPC_MSA_3R_11
:
19420 case OPC_MSA_3R_12
:
19421 case OPC_MSA_3R_13
:
19422 case OPC_MSA_3R_14
:
19423 case OPC_MSA_3R_15
:
19424 gen_msa_3r(env
, ctx
);
19427 gen_msa_elm(env
, ctx
);
19429 case OPC_MSA_3RF_1A
:
19430 case OPC_MSA_3RF_1B
:
19431 case OPC_MSA_3RF_1C
:
19432 gen_msa_3rf(env
, ctx
);
19435 gen_msa_vec(env
, ctx
);
19446 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
19447 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
19448 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19449 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
19451 TCGv_i32 twd
= tcg_const_i32(wd
);
19452 TCGv taddr
= tcg_temp_new();
19453 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
19455 switch (MASK_MSA_MINOR(opcode
)) {
19457 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
19460 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
19463 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
19466 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
19469 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
19472 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
19475 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
19478 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
19482 tcg_temp_free_i32(twd
);
19483 tcg_temp_free(taddr
);
19487 MIPS_INVAL("MSA instruction");
19488 generate_exception(ctx
, EXCP_RI
);
19494 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
19497 int rs
, rt
, rd
, sa
;
19501 /* make sure instructions are on a word boundary */
19502 if (ctx
->pc
& 0x3) {
19503 env
->CP0_BadVAddr
= ctx
->pc
;
19504 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
19505 ctx
->bstate
= BS_STOP
;
19509 /* Handle blikely not taken case */
19510 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
19511 TCGLabel
*l1
= gen_new_label();
19513 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
19514 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
19515 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
19516 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
19520 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
19521 tcg_gen_debug_insn_start(ctx
->pc
);
19524 op
= MASK_OP_MAJOR(ctx
->opcode
);
19525 rs
= (ctx
->opcode
>> 21) & 0x1f;
19526 rt
= (ctx
->opcode
>> 16) & 0x1f;
19527 rd
= (ctx
->opcode
>> 11) & 0x1f;
19528 sa
= (ctx
->opcode
>> 6) & 0x1f;
19529 imm
= (int16_t)ctx
->opcode
;
19532 decode_opc_special(env
, ctx
);
19535 decode_opc_special2_legacy(env
, ctx
);
19538 decode_opc_special3(env
, ctx
);
19541 op1
= MASK_REGIMM(ctx
->opcode
);
19543 case OPC_BLTZL
: /* REGIMM branches */
19547 check_insn(ctx
, ISA_MIPS2
);
19548 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19552 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
19556 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19558 /* OPC_NAL, OPC_BAL */
19559 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
19561 generate_exception(ctx
, EXCP_RI
);
19564 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
19567 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
19569 check_insn(ctx
, ISA_MIPS2
);
19570 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19571 gen_trap(ctx
, op1
, rs
, -1, imm
);
19574 check_insn(ctx
, ISA_MIPS32R2
);
19575 /* Break the TB to be able to sync copied instructions
19577 ctx
->bstate
= BS_STOP
;
19579 case OPC_BPOSGE32
: /* MIPS DSP branch */
19580 #if defined(TARGET_MIPS64)
19584 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
19586 #if defined(TARGET_MIPS64)
19588 check_insn(ctx
, ISA_MIPS32R6
);
19589 check_mips_64(ctx
);
19591 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
19593 MIPS_DEBUG("dahi %s, %04x", regnames
[rs
], imm
);
19596 check_insn(ctx
, ISA_MIPS32R6
);
19597 check_mips_64(ctx
);
19599 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
19601 MIPS_DEBUG("dati %s, %04x", regnames
[rs
], imm
);
19604 default: /* Invalid */
19605 MIPS_INVAL("regimm");
19606 generate_exception(ctx
, EXCP_RI
);
19611 check_cp0_enabled(ctx
);
19612 op1
= MASK_CP0(ctx
->opcode
);
19620 #if defined(TARGET_MIPS64)
19624 #ifndef CONFIG_USER_ONLY
19625 gen_cp0(env
, ctx
, op1
, rt
, rd
);
19626 #endif /* !CONFIG_USER_ONLY */
19628 case OPC_C0_FIRST
... OPC_C0_LAST
:
19629 #ifndef CONFIG_USER_ONLY
19630 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
19631 #endif /* !CONFIG_USER_ONLY */
19634 #ifndef CONFIG_USER_ONLY
19637 TCGv t0
= tcg_temp_new();
19639 op2
= MASK_MFMC0(ctx
->opcode
);
19642 check_insn(ctx
, ASE_MT
);
19643 gen_helper_dmt(t0
);
19644 gen_store_gpr(t0
, rt
);
19647 check_insn(ctx
, ASE_MT
);
19648 gen_helper_emt(t0
);
19649 gen_store_gpr(t0
, rt
);
19652 check_insn(ctx
, ASE_MT
);
19653 gen_helper_dvpe(t0
, cpu_env
);
19654 gen_store_gpr(t0
, rt
);
19657 check_insn(ctx
, ASE_MT
);
19658 gen_helper_evpe(t0
, cpu_env
);
19659 gen_store_gpr(t0
, rt
);
19662 check_insn(ctx
, ISA_MIPS32R2
);
19663 save_cpu_state(ctx
, 1);
19664 gen_helper_di(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
;
19671 check_insn(ctx
, ISA_MIPS32R2
);
19672 save_cpu_state(ctx
, 1);
19673 gen_helper_ei(t0
, cpu_env
);
19674 gen_store_gpr(t0
, rt
);
19675 /* Stop translation as we may have switched
19676 the execution mode. */
19677 ctx
->bstate
= BS_STOP
;
19679 default: /* Invalid */
19680 MIPS_INVAL("mfmc0");
19681 generate_exception(ctx
, EXCP_RI
);
19686 #endif /* !CONFIG_USER_ONLY */
19689 check_insn(ctx
, ISA_MIPS32R2
);
19690 gen_load_srsgpr(rt
, rd
);
19693 check_insn(ctx
, ISA_MIPS32R2
);
19694 gen_store_srsgpr(rt
, rd
);
19698 generate_exception(ctx
, EXCP_RI
);
19702 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19703 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19704 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19705 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19708 /* Arithmetic with immediate opcode */
19709 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19713 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19715 case OPC_SLTI
: /* Set on less than with immediate opcode */
19717 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
19719 case OPC_ANDI
: /* Arithmetic with immediate opcode */
19720 case OPC_LUI
: /* OPC_AUI */
19723 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
19725 case OPC_J
... OPC_JAL
: /* Jump */
19726 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
19727 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
19730 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19731 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19733 generate_exception(ctx
, EXCP_RI
);
19736 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19737 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19740 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19743 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19744 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19746 generate_exception(ctx
, EXCP_RI
);
19749 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19750 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19753 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19756 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19759 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19761 check_insn(ctx
, ISA_MIPS32R6
);
19762 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19763 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19766 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19769 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19771 check_insn(ctx
, ISA_MIPS32R6
);
19772 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19773 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19778 check_insn(ctx
, ISA_MIPS2
);
19779 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19783 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19785 case OPC_LL
: /* Load and stores */
19786 check_insn(ctx
, ISA_MIPS2
);
19790 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19792 case OPC_LB
... OPC_LH
:
19793 case OPC_LW
... OPC_LHU
:
19794 gen_ld(ctx
, op
, rt
, rs
, imm
);
19798 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19800 case OPC_SB
... OPC_SH
:
19802 gen_st(ctx
, op
, rt
, rs
, imm
);
19805 check_insn(ctx
, ISA_MIPS2
);
19806 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19807 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
19810 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19811 check_cp0_enabled(ctx
);
19812 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
19813 /* Treat as NOP. */
19816 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19817 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
19818 /* Treat as NOP. */
19821 /* Floating point (COP1). */
19826 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
19830 op1
= MASK_CP1(ctx
->opcode
);
19835 check_cp1_enabled(ctx
);
19836 check_insn(ctx
, ISA_MIPS32R2
);
19841 check_cp1_enabled(ctx
);
19842 gen_cp1(ctx
, op1
, rt
, rd
);
19844 #if defined(TARGET_MIPS64)
19847 check_cp1_enabled(ctx
);
19848 check_insn(ctx
, ISA_MIPS3
);
19849 check_mips_64(ctx
);
19850 gen_cp1(ctx
, op1
, rt
, rd
);
19853 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
19854 check_cp1_enabled(ctx
);
19855 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19857 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
19862 check_insn(ctx
, ASE_MIPS3D
);
19863 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
19864 (rt
>> 2) & 0x7, imm
<< 2);
19868 check_cp1_enabled(ctx
);
19869 check_insn(ctx
, ISA_MIPS32R6
);
19870 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
19874 check_cp1_enabled(ctx
);
19875 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19877 check_insn(ctx
, ASE_MIPS3D
);
19880 check_cp1_enabled(ctx
);
19881 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19882 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
19883 (rt
>> 2) & 0x7, imm
<< 2);
19890 check_cp1_enabled(ctx
);
19891 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
19897 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
19898 check_cp1_enabled(ctx
);
19899 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19901 case R6_OPC_CMP_AF_S
:
19902 case R6_OPC_CMP_UN_S
:
19903 case R6_OPC_CMP_EQ_S
:
19904 case R6_OPC_CMP_UEQ_S
:
19905 case R6_OPC_CMP_LT_S
:
19906 case R6_OPC_CMP_ULT_S
:
19907 case R6_OPC_CMP_LE_S
:
19908 case R6_OPC_CMP_ULE_S
:
19909 case R6_OPC_CMP_SAF_S
:
19910 case R6_OPC_CMP_SUN_S
:
19911 case R6_OPC_CMP_SEQ_S
:
19912 case R6_OPC_CMP_SEUQ_S
:
19913 case R6_OPC_CMP_SLT_S
:
19914 case R6_OPC_CMP_SULT_S
:
19915 case R6_OPC_CMP_SLE_S
:
19916 case R6_OPC_CMP_SULE_S
:
19917 case R6_OPC_CMP_OR_S
:
19918 case R6_OPC_CMP_UNE_S
:
19919 case R6_OPC_CMP_NE_S
:
19920 case R6_OPC_CMP_SOR_S
:
19921 case R6_OPC_CMP_SUNE_S
:
19922 case R6_OPC_CMP_SNE_S
:
19923 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
19925 case R6_OPC_CMP_AF_D
:
19926 case R6_OPC_CMP_UN_D
:
19927 case R6_OPC_CMP_EQ_D
:
19928 case R6_OPC_CMP_UEQ_D
:
19929 case R6_OPC_CMP_LT_D
:
19930 case R6_OPC_CMP_ULT_D
:
19931 case R6_OPC_CMP_LE_D
:
19932 case R6_OPC_CMP_ULE_D
:
19933 case R6_OPC_CMP_SAF_D
:
19934 case R6_OPC_CMP_SUN_D
:
19935 case R6_OPC_CMP_SEQ_D
:
19936 case R6_OPC_CMP_SEUQ_D
:
19937 case R6_OPC_CMP_SLT_D
:
19938 case R6_OPC_CMP_SULT_D
:
19939 case R6_OPC_CMP_SLE_D
:
19940 case R6_OPC_CMP_SULE_D
:
19941 case R6_OPC_CMP_OR_D
:
19942 case R6_OPC_CMP_UNE_D
:
19943 case R6_OPC_CMP_NE_D
:
19944 case R6_OPC_CMP_SOR_D
:
19945 case R6_OPC_CMP_SUNE_D
:
19946 case R6_OPC_CMP_SNE_D
:
19947 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
19950 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
19951 rt
, rd
, sa
, (imm
>> 8) & 0x7);
19956 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
19971 check_insn(ctx
, ASE_MSA
);
19972 gen_msa_branch(env
, ctx
, op1
);
19976 generate_exception(ctx
, EXCP_RI
);
19981 /* Compact branches [R6] and COP2 [non-R6] */
19982 case OPC_BC
: /* OPC_LWC2 */
19983 case OPC_BALC
: /* OPC_SWC2 */
19984 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19985 /* OPC_BC, OPC_BALC */
19986 gen_compute_compact_branch(ctx
, op
, 0, 0,
19987 sextract32(ctx
->opcode
<< 2, 0, 28));
19989 /* OPC_LWC2, OPC_SWC2 */
19990 /* COP2: Not implemented. */
19991 generate_exception_err(ctx
, EXCP_CpU
, 2);
19994 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
19995 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
19996 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19998 /* OPC_BEQZC, OPC_BNEZC */
19999 gen_compute_compact_branch(ctx
, op
, rs
, 0,
20000 sextract32(ctx
->opcode
<< 2, 0, 23));
20002 /* OPC_JIC, OPC_JIALC */
20003 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
20006 /* OPC_LWC2, OPC_SWC2 */
20007 /* COP2: Not implemented. */
20008 generate_exception_err(ctx
, EXCP_CpU
, 2);
20012 check_insn(ctx
, INSN_LOONGSON2F
);
20013 /* Note that these instructions use different fields. */
20014 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
20018 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20019 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20020 check_cp1_enabled(ctx
);
20021 op1
= MASK_CP3(ctx
->opcode
);
20025 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
20031 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
20032 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
20035 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
20036 /* Treat as NOP. */
20039 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
20053 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
20054 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
20058 generate_exception (ctx
, EXCP_RI
);
20062 generate_exception_err(ctx
, EXCP_CpU
, 1);
20066 #if defined(TARGET_MIPS64)
20067 /* MIPS64 opcodes */
20068 case OPC_LDL
... OPC_LDR
:
20070 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20074 check_insn(ctx
, ISA_MIPS3
);
20075 check_mips_64(ctx
);
20076 gen_ld(ctx
, op
, rt
, rs
, imm
);
20078 case OPC_SDL
... OPC_SDR
:
20079 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20082 check_insn(ctx
, ISA_MIPS3
);
20083 check_mips_64(ctx
);
20084 gen_st(ctx
, op
, rt
, rs
, imm
);
20087 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20088 check_insn(ctx
, ISA_MIPS3
);
20089 check_mips_64(ctx
);
20090 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
20092 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
20093 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
20094 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
20095 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
20098 check_insn(ctx
, ISA_MIPS3
);
20099 check_mips_64(ctx
);
20100 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
20104 check_insn(ctx
, ISA_MIPS3
);
20105 check_mips_64(ctx
);
20106 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
20109 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
20110 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
20111 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
20113 MIPS_INVAL("major opcode");
20114 generate_exception(ctx
, EXCP_RI
);
20118 case OPC_DAUI
: /* OPC_JALX */
20119 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
20120 #if defined(TARGET_MIPS64)
20122 check_mips_64(ctx
);
20124 TCGv t0
= tcg_temp_new();
20125 gen_load_gpr(t0
, rs
);
20126 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
20129 MIPS_DEBUG("daui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
20131 generate_exception(ctx
, EXCP_RI
);
20132 MIPS_INVAL("major opcode");
20136 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
20137 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
20138 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
20141 case OPC_MSA
: /* OPC_MDMX */
20142 /* MDMX: Not implemented. */
20146 check_insn(ctx
, ISA_MIPS32R6
);
20147 gen_pcrel(ctx
, ctx
->opcode
, ctx
->pc
, rs
);
20149 default: /* Invalid */
20150 MIPS_INVAL("major opcode");
20151 generate_exception(ctx
, EXCP_RI
);
20157 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
20160 CPUState
*cs
= CPU(cpu
);
20161 CPUMIPSState
*env
= &cpu
->env
;
20163 target_ulong pc_start
;
20164 target_ulong next_page_start
;
20173 qemu_log("search pc %d\n", search_pc
);
20176 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
20179 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
20180 ctx
.insn_flags
= env
->insn_flags
;
20181 ctx
.CP0_Config1
= env
->CP0_Config1
;
20183 ctx
.bstate
= BS_NONE
;
20184 ctx
.kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
20185 ctx
.rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
20186 ctx
.ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
20187 ctx
.bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
20188 ctx
.bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
20189 ctx
.PAMask
= env
->PAMask
;
20190 ctx
.mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
20191 ctx
.CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
20192 /* Restore delay slot state from the tb context. */
20193 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
20194 ctx
.ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
20195 ctx
.ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
20196 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
20197 restore_cpu_state(env
, &ctx
);
20198 #ifdef CONFIG_USER_ONLY
20199 ctx
.mem_idx
= MIPS_HFLAG_UM
;
20201 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
20203 ctx
.default_tcg_memop_mask
= (ctx
.insn_flags
& ISA_MIPS32R6
) ?
20204 MO_UNALN
: MO_ALIGN
;
20206 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
20207 if (max_insns
== 0)
20208 max_insns
= CF_COUNT_MASK
;
20209 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
20211 while (ctx
.bstate
== BS_NONE
) {
20212 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
20213 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
20214 if (bp
->pc
== ctx
.pc
) {
20215 save_cpu_state(&ctx
, 1);
20216 ctx
.bstate
= BS_BRANCH
;
20217 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
20218 /* Include the breakpoint location or the tb won't
20219 * be flushed when it must be. */
20221 goto done_generating
;
20227 j
= tcg_op_buf_count();
20231 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
20233 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
20234 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
20235 gen_opc_btarget
[lj
] = ctx
.btarget
;
20236 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
20237 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
20239 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
20242 is_slot
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
20243 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
20244 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
20246 decode_opc(env
, &ctx
);
20247 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
20248 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
20249 insn_bytes
= decode_micromips_opc(env
, &ctx
);
20250 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
20251 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
20252 insn_bytes
= decode_mips16_opc(env
, &ctx
);
20254 generate_exception(&ctx
, EXCP_RI
);
20255 ctx
.bstate
= BS_STOP
;
20259 if (ctx
.hflags
& MIPS_HFLAG_BMASK
) {
20260 if (!(ctx
.hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
20261 MIPS_HFLAG_FBNSLOT
))) {
20262 /* force to generate branch as there is neither delay nor
20266 if ((ctx
.hflags
& MIPS_HFLAG_M16
) &&
20267 (ctx
.hflags
& MIPS_HFLAG_FBNSLOT
)) {
20268 /* Force to generate branch as microMIPS R6 doesn't restrict
20269 branches in the forbidden slot. */
20274 gen_branch(&ctx
, insn_bytes
);
20276 ctx
.pc
+= insn_bytes
;
20280 /* Execute a branch and its delay slot as a single instruction.
20281 This is what GDB expects and is consistent with what the
20282 hardware does (e.g. if a delay slot instruction faults, the
20283 reported PC is the PC of the branch). */
20284 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
20288 if (ctx
.pc
>= next_page_start
) {
20292 if (tcg_op_buf_full()) {
20296 if (num_insns
>= max_insns
)
20302 if (tb
->cflags
& CF_LAST_IO
) {
20305 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
20306 save_cpu_state(&ctx
, ctx
.bstate
!= BS_EXCP
);
20307 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
20309 switch (ctx
.bstate
) {
20311 gen_goto_tb(&ctx
, 0, ctx
.pc
);
20314 save_cpu_state(&ctx
, 0);
20315 gen_goto_tb(&ctx
, 0, ctx
.pc
);
20318 tcg_gen_exit_tb(0);
20326 gen_tb_end(tb
, num_insns
);
20329 j
= tcg_op_buf_count();
20332 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
20334 tb
->size
= ctx
.pc
- pc_start
;
20335 tb
->icount
= num_insns
;
20339 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
20340 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
20341 log_target_disas(cs
, pc_start
, ctx
.pc
- pc_start
, 0);
20347 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
20349 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
20352 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
20354 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
20357 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
20361 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
20363 #define printfpr(fp) \
20366 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20367 " fd:%13g fs:%13g psu: %13g\n", \
20368 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20369 (double)(fp)->fd, \
20370 (double)(fp)->fs[FP_ENDIAN_IDX], \
20371 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20374 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20375 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20376 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20377 " fd:%13g fs:%13g psu:%13g\n", \
20378 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20380 (double)tmp.fs[FP_ENDIAN_IDX], \
20381 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20386 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20387 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
20388 get_float_exception_flags(&env
->active_fpu
.fp_status
));
20389 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
20390 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
20391 printfpr(&env
->active_fpu
.fpr
[i
]);
20397 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
20398 /* Debug help: The architecture requires 32bit code to maintain proper
20399 sign-extended values on 64bit machines. */
20401 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
20404 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
20405 fprintf_function cpu_fprintf
,
20410 if (!SIGN_EXT_P(env
->active_tc
.PC
))
20411 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
20412 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
20413 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
20414 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
20415 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
20416 if (!SIGN_EXT_P(env
->btarget
))
20417 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
20419 for (i
= 0; i
< 32; i
++) {
20420 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
20421 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
20424 if (!SIGN_EXT_P(env
->CP0_EPC
))
20425 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
20426 if (!SIGN_EXT_P(env
->lladdr
))
20427 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
20431 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
20434 MIPSCPU
*cpu
= MIPS_CPU(cs
);
20435 CPUMIPSState
*env
= &cpu
->env
;
20438 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
20439 " LO=0x" TARGET_FMT_lx
" ds %04x "
20440 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
20441 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
20442 env
->hflags
, env
->btarget
, env
->bcond
);
20443 for (i
= 0; i
< 32; i
++) {
20445 cpu_fprintf(f
, "GPR%02d:", i
);
20446 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
20448 cpu_fprintf(f
, "\n");
20451 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
20452 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
20453 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20455 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
20456 cpu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
20457 env
->CP0_Config2
, env
->CP0_Config3
);
20458 cpu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
20459 env
->CP0_Config4
, env
->CP0_Config5
);
20460 if (env
->hflags
& MIPS_HFLAG_FPU
)
20461 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
20462 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
20463 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
20467 void mips_tcg_init(void)
20472 /* Initialize various static tables. */
20476 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
20477 TCGV_UNUSED(cpu_gpr
[0]);
20478 for (i
= 1; i
< 32; i
++)
20479 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
20480 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
20483 for (i
= 0; i
< 32; i
++) {
20484 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
20486 tcg_global_mem_new_i64(TCG_AREG0
, off
, msaregnames
[i
* 2]);
20487 /* The scalar floating-point unit (FPU) registers are mapped on
20488 * the MSA vector registers. */
20489 fpu_f64
[i
] = msa_wr_d
[i
* 2];
20490 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
20491 msa_wr_d
[i
* 2 + 1] =
20492 tcg_global_mem_new_i64(TCG_AREG0
, off
, msaregnames
[i
* 2 + 1]);
20495 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
20496 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
20497 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
20498 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
20499 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
20501 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
20502 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
20505 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
20506 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
20508 bcond
= tcg_global_mem_new(TCG_AREG0
,
20509 offsetof(CPUMIPSState
, bcond
), "bcond");
20510 btarget
= tcg_global_mem_new(TCG_AREG0
,
20511 offsetof(CPUMIPSState
, btarget
), "btarget");
20512 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
20513 offsetof(CPUMIPSState
, hflags
), "hflags");
20515 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
20516 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
20518 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
20519 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
20525 #include "translate_init.c"
20527 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
20531 const mips_def_t
*def
;
20533 def
= cpu_mips_find_by_name(cpu_model
);
20536 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
20538 env
->cpu_model
= def
;
20540 #ifndef CONFIG_USER_ONLY
20541 mmu_init(env
, def
);
20543 fpu_init(env
, def
);
20544 mvp_init(env
, def
);
20546 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
20551 void cpu_state_reset(CPUMIPSState
*env
)
20553 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
20554 CPUState
*cs
= CPU(cpu
);
20556 /* Reset registers to their default values */
20557 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
20558 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
20559 #ifdef TARGET_WORDS_BIGENDIAN
20560 env
->CP0_Config0
|= (1 << CP0C0_BE
);
20562 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
20563 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
20564 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
20565 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
20566 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
20567 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
20568 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
20569 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
20570 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
20571 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
20572 << env
->cpu_model
->CP0_LLAddr_shift
;
20573 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
20574 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
20575 env
->CCRes
= env
->cpu_model
->CCRes
;
20576 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
20577 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
20578 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
20579 env
->current_tc
= 0;
20580 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
20581 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
20582 #if defined(TARGET_MIPS64)
20583 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
20584 env
->SEGMask
|= 3ULL << 62;
20587 env
->PABITS
= env
->cpu_model
->PABITS
;
20588 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
20589 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
20590 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
20591 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
20592 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
20593 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
20594 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
20595 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
20596 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
20597 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
20598 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
20599 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
20600 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
20601 env
->msair
= env
->cpu_model
->MSAIR
;
20602 env
->insn_flags
= env
->cpu_model
->insn_flags
;
20604 #if defined(CONFIG_USER_ONLY)
20605 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
20606 # ifdef TARGET_MIPS64
20607 /* Enable 64-bit register mode. */
20608 env
->CP0_Status
|= (1 << CP0St_PX
);
20610 # ifdef TARGET_ABI_MIPSN64
20611 /* Enable 64-bit address mode. */
20612 env
->CP0_Status
|= (1 << CP0St_UX
);
20614 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20615 hardware registers. */
20616 env
->CP0_HWREna
|= 0x0000000F;
20617 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
20618 env
->CP0_Status
|= (1 << CP0St_CU1
);
20620 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
20621 env
->CP0_Status
|= (1 << CP0St_MX
);
20623 # if defined(TARGET_MIPS64)
20624 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20625 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
20626 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
20627 env
->CP0_Status
|= (1 << CP0St_FR
);
20631 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
20632 /* If the exception was raised from a delay slot,
20633 come back to the jump. */
20634 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
20635 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
20637 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
20639 env
->active_tc
.PC
= (int32_t)0xBFC00000;
20640 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
20641 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
20642 env
->CP0_Wired
= 0;
20643 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
20644 if (kvm_enabled()) {
20645 env
->CP0_EBase
|= 0x40000000;
20647 env
->CP0_EBase
|= 0x80000000;
20649 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
20650 /* vectored interrupts not implemented, timer on int 7,
20651 no performance counters. */
20652 env
->CP0_IntCtl
= 0xe0000000;
20656 for (i
= 0; i
< 7; i
++) {
20657 env
->CP0_WatchLo
[i
] = 0;
20658 env
->CP0_WatchHi
[i
] = 0x80000000;
20660 env
->CP0_WatchLo
[7] = 0;
20661 env
->CP0_WatchHi
[7] = 0;
20663 /* Count register increments in debug mode, EJTAG version 1 */
20664 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
20666 cpu_mips_store_count(env
, 1);
20668 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
20671 /* Only TC0 on VPE 0 starts as active. */
20672 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
20673 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
20674 env
->tcs
[i
].CP0_TCHalt
= 1;
20676 env
->active_tc
.CP0_TCHalt
= 1;
20679 if (cs
->cpu_index
== 0) {
20680 /* VPE0 starts up enabled. */
20681 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
20682 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
20684 /* TC0 starts up unhalted. */
20686 env
->active_tc
.CP0_TCHalt
= 0;
20687 env
->tcs
[0].CP0_TCHalt
= 0;
20688 /* With thread 0 active. */
20689 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
20690 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
20694 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
20695 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
20696 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20697 env
->CP0_Status
|= (1 << CP0St_FR
);
20701 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
20705 compute_hflags(env
);
20706 restore_rounding_mode(env
);
20707 restore_flush_mode(env
);
20708 restore_pamask(env
);
20709 cs
->exception_index
= EXCP_NONE
;
20711 if (semihosting_get_argc()) {
20712 /* UHI interface can be used to obtain argc and argv */
20713 env
->active_tc
.gpr
[4] = -1;
20717 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
20719 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
20720 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
20721 env
->hflags
|= gen_opc_hflags
[pc_pos
];
20722 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
20723 case MIPS_HFLAG_BR
:
20725 case MIPS_HFLAG_BC
:
20726 case MIPS_HFLAG_BL
:
20728 env
->btarget
= gen_opc_btarget
[pc_pos
];