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_extrl_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_extrl_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 t2
= tcg_const_tl(-1);
2157 tcg_gen_shl_tl(t2
, t2
, t1
);
2158 gen_load_gpr(t1
, rt
);
2159 tcg_gen_andc_tl(t1
, t1
, t2
);
2161 tcg_gen_or_tl(t0
, t0
, t1
);
2163 gen_store_gpr(t0
, rt
);
2167 t1
= tcg_temp_new();
2168 /* Do a byte access to possibly trigger a page
2169 fault with the unaligned address. */
2170 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
2171 tcg_gen_andi_tl(t1
, t0
, 7);
2172 #ifdef TARGET_WORDS_BIGENDIAN
2173 tcg_gen_xori_tl(t1
, t1
, 7);
2175 tcg_gen_shli_tl(t1
, t1
, 3);
2176 tcg_gen_andi_tl(t0
, t0
, ~7);
2177 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2178 tcg_gen_shr_tl(t0
, t0
, t1
);
2179 tcg_gen_xori_tl(t1
, t1
, 63);
2180 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2181 tcg_gen_shl_tl(t2
, t2
, t1
);
2182 gen_load_gpr(t1
, rt
);
2183 tcg_gen_and_tl(t1
, t1
, t2
);
2185 tcg_gen_or_tl(t0
, t0
, t1
);
2187 gen_store_gpr(t0
, rt
);
2191 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2192 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2194 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2195 gen_store_gpr(t0
, rt
);
2200 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2201 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2203 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
2204 gen_store_gpr(t0
, rt
);
2208 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
2209 ctx
->default_tcg_memop_mask
);
2210 gen_store_gpr(t0
, rt
);
2214 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
2215 ctx
->default_tcg_memop_mask
);
2216 gen_store_gpr(t0
, rt
);
2220 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
|
2221 ctx
->default_tcg_memop_mask
);
2222 gen_store_gpr(t0
, rt
);
2226 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
2227 gen_store_gpr(t0
, rt
);
2231 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
2232 gen_store_gpr(t0
, rt
);
2236 t1
= tcg_temp_new();
2237 /* Do a byte access to possibly trigger a page
2238 fault with the unaligned address. */
2239 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
2240 tcg_gen_andi_tl(t1
, t0
, 3);
2241 #ifndef TARGET_WORDS_BIGENDIAN
2242 tcg_gen_xori_tl(t1
, t1
, 3);
2244 tcg_gen_shli_tl(t1
, t1
, 3);
2245 tcg_gen_andi_tl(t0
, t0
, ~3);
2246 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2247 tcg_gen_shl_tl(t0
, t0
, t1
);
2248 t2
= tcg_const_tl(-1);
2249 tcg_gen_shl_tl(t2
, t2
, t1
);
2250 gen_load_gpr(t1
, rt
);
2251 tcg_gen_andc_tl(t1
, t1
, t2
);
2253 tcg_gen_or_tl(t0
, t0
, t1
);
2255 tcg_gen_ext32s_tl(t0
, t0
);
2256 gen_store_gpr(t0
, rt
);
2260 t1
= tcg_temp_new();
2261 /* Do a byte access to possibly trigger a page
2262 fault with the unaligned address. */
2263 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
2264 tcg_gen_andi_tl(t1
, t0
, 3);
2265 #ifdef TARGET_WORDS_BIGENDIAN
2266 tcg_gen_xori_tl(t1
, t1
, 3);
2268 tcg_gen_shli_tl(t1
, t1
, 3);
2269 tcg_gen_andi_tl(t0
, t0
, ~3);
2270 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2271 tcg_gen_shr_tl(t0
, t0
, t1
);
2272 tcg_gen_xori_tl(t1
, t1
, 31);
2273 t2
= tcg_const_tl(0xfffffffeull
);
2274 tcg_gen_shl_tl(t2
, t2
, t1
);
2275 gen_load_gpr(t1
, rt
);
2276 tcg_gen_and_tl(t1
, t1
, t2
);
2278 tcg_gen_or_tl(t0
, t0
, t1
);
2280 tcg_gen_ext32s_tl(t0
, t0
);
2281 gen_store_gpr(t0
, rt
);
2286 save_cpu_state(ctx
, 1);
2287 op_ld_ll(t0
, t0
, ctx
);
2288 gen_store_gpr(t0
, rt
);
2292 (void)opn
; /* avoid a compiler warning */
2293 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2298 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
2299 int base
, int16_t offset
)
2301 const char *opn
= "st";
2302 TCGv t0
= tcg_temp_new();
2303 TCGv t1
= tcg_temp_new();
2305 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2306 gen_load_gpr(t1
, rt
);
2308 #if defined(TARGET_MIPS64)
2310 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
2311 ctx
->default_tcg_memop_mask
);
2315 save_cpu_state(ctx
, 1);
2316 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
2320 save_cpu_state(ctx
, 1);
2321 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
2326 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
2327 ctx
->default_tcg_memop_mask
);
2331 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
2332 ctx
->default_tcg_memop_mask
);
2336 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
2340 save_cpu_state(ctx
, 1);
2341 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
2345 save_cpu_state(ctx
, 1);
2346 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
2350 (void)opn
; /* avoid a compiler warning */
2351 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2357 /* Store conditional */
2358 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
2359 int base
, int16_t offset
)
2361 const char *opn
= "st_cond";
2364 #ifdef CONFIG_USER_ONLY
2365 t0
= tcg_temp_local_new();
2366 t1
= tcg_temp_local_new();
2368 t0
= tcg_temp_new();
2369 t1
= tcg_temp_new();
2371 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2372 gen_load_gpr(t1
, rt
);
2374 #if defined(TARGET_MIPS64)
2377 save_cpu_state(ctx
, 1);
2378 op_st_scd(t1
, t0
, rt
, ctx
);
2384 save_cpu_state(ctx
, 1);
2385 op_st_sc(t1
, t0
, rt
, ctx
);
2389 (void)opn
; /* avoid a compiler warning */
2390 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2395 /* Load and store */
2396 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
2397 int base
, int16_t offset
)
2399 const char *opn
= "flt_ldst";
2400 TCGv t0
= tcg_temp_new();
2402 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2403 /* Don't do NOP if destination is zero: we must perform the actual
2408 TCGv_i32 fp0
= tcg_temp_new_i32();
2409 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
2410 ctx
->default_tcg_memop_mask
);
2411 gen_store_fpr32(ctx
, fp0
, ft
);
2412 tcg_temp_free_i32(fp0
);
2418 TCGv_i32 fp0
= tcg_temp_new_i32();
2419 gen_load_fpr32(ctx
, fp0
, ft
);
2420 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2421 ctx
->default_tcg_memop_mask
);
2422 tcg_temp_free_i32(fp0
);
2428 TCGv_i64 fp0
= tcg_temp_new_i64();
2429 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2430 ctx
->default_tcg_memop_mask
);
2431 gen_store_fpr64(ctx
, fp0
, ft
);
2432 tcg_temp_free_i64(fp0
);
2438 TCGv_i64 fp0
= tcg_temp_new_i64();
2439 gen_load_fpr64(ctx
, fp0
, ft
);
2440 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2441 ctx
->default_tcg_memop_mask
);
2442 tcg_temp_free_i64(fp0
);
2448 generate_exception(ctx
, EXCP_RI
);
2451 (void)opn
; /* avoid a compiler warning */
2452 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
2457 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2458 int rs
, int16_t imm
)
2460 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2461 check_cp1_enabled(ctx
);
2465 check_insn(ctx
, ISA_MIPS2
);
2468 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
2471 generate_exception_err(ctx
, EXCP_CpU
, 1);
2475 /* Arithmetic with immediate operand */
2476 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2477 int rt
, int rs
, int16_t imm
)
2479 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2480 const char *opn
= "imm arith";
2482 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2483 /* If no destination, treat it as a NOP.
2484 For addi, we must generate the overflow exception when needed. */
2491 TCGv t0
= tcg_temp_local_new();
2492 TCGv t1
= tcg_temp_new();
2493 TCGv t2
= tcg_temp_new();
2494 TCGLabel
*l1
= gen_new_label();
2496 gen_load_gpr(t1
, rs
);
2497 tcg_gen_addi_tl(t0
, t1
, uimm
);
2498 tcg_gen_ext32s_tl(t0
, t0
);
2500 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2501 tcg_gen_xori_tl(t2
, t0
, uimm
);
2502 tcg_gen_and_tl(t1
, t1
, t2
);
2504 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2506 /* operands of same sign, result different sign */
2507 generate_exception(ctx
, EXCP_OVERFLOW
);
2509 tcg_gen_ext32s_tl(t0
, t0
);
2510 gen_store_gpr(t0
, rt
);
2517 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2518 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2520 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2524 #if defined(TARGET_MIPS64)
2527 TCGv t0
= tcg_temp_local_new();
2528 TCGv t1
= tcg_temp_new();
2529 TCGv t2
= tcg_temp_new();
2530 TCGLabel
*l1
= gen_new_label();
2532 gen_load_gpr(t1
, rs
);
2533 tcg_gen_addi_tl(t0
, t1
, uimm
);
2535 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2536 tcg_gen_xori_tl(t2
, t0
, uimm
);
2537 tcg_gen_and_tl(t1
, t1
, t2
);
2539 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2541 /* operands of same sign, result different sign */
2542 generate_exception(ctx
, EXCP_OVERFLOW
);
2544 gen_store_gpr(t0
, rt
);
2551 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2553 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2559 (void)opn
; /* avoid a compiler warning */
2560 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2563 /* Logic with immediate operand */
2564 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2565 int rt
, int rs
, int16_t imm
)
2570 /* If no destination, treat it as a NOP. */
2574 uimm
= (uint16_t)imm
;
2577 if (likely(rs
!= 0))
2578 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2580 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2581 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2582 regnames
[rs
], uimm
);
2586 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2588 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2589 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2590 regnames
[rs
], uimm
);
2593 if (likely(rs
!= 0))
2594 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2596 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2597 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2598 regnames
[rs
], uimm
);
2601 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
2603 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2604 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2605 MIPS_DEBUG("aui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
2607 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2608 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2613 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2618 /* Set on less than with immediate operand */
2619 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2620 int rt
, int rs
, int16_t imm
)
2622 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2623 const char *opn
= "imm arith";
2627 /* If no destination, treat it as a NOP. */
2631 t0
= tcg_temp_new();
2632 gen_load_gpr(t0
, rs
);
2635 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2639 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2643 (void)opn
; /* avoid a compiler warning */
2644 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2648 /* Shifts with immediate operand */
2649 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2650 int rt
, int rs
, int16_t imm
)
2652 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2653 const char *opn
= "imm shift";
2657 /* If no destination, treat it as a NOP. */
2662 t0
= tcg_temp_new();
2663 gen_load_gpr(t0
, rs
);
2666 tcg_gen_shli_tl(t0
, t0
, uimm
);
2667 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2671 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2676 tcg_gen_ext32u_tl(t0
, t0
);
2677 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2679 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2685 TCGv_i32 t1
= tcg_temp_new_i32();
2687 tcg_gen_trunc_tl_i32(t1
, t0
);
2688 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2689 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2690 tcg_temp_free_i32(t1
);
2692 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2696 #if defined(TARGET_MIPS64)
2698 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2702 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2706 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2711 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2713 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2718 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2722 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2726 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2730 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2735 (void)opn
; /* avoid a compiler warning */
2736 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2741 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2742 int rd
, int rs
, int rt
)
2744 const char *opn
= "arith";
2746 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2747 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2748 /* If no destination, treat it as a NOP.
2749 For add & sub, we must generate the overflow exception when needed. */
2757 TCGv t0
= tcg_temp_local_new();
2758 TCGv t1
= tcg_temp_new();
2759 TCGv t2
= tcg_temp_new();
2760 TCGLabel
*l1
= gen_new_label();
2762 gen_load_gpr(t1
, rs
);
2763 gen_load_gpr(t2
, rt
);
2764 tcg_gen_add_tl(t0
, t1
, t2
);
2765 tcg_gen_ext32s_tl(t0
, t0
);
2766 tcg_gen_xor_tl(t1
, t1
, t2
);
2767 tcg_gen_xor_tl(t2
, t0
, t2
);
2768 tcg_gen_andc_tl(t1
, t2
, t1
);
2770 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2772 /* operands of same sign, result different sign */
2773 generate_exception(ctx
, EXCP_OVERFLOW
);
2775 gen_store_gpr(t0
, rd
);
2781 if (rs
!= 0 && rt
!= 0) {
2782 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2783 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2784 } else if (rs
== 0 && rt
!= 0) {
2785 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2786 } else if (rs
!= 0 && rt
== 0) {
2787 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2789 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2795 TCGv t0
= tcg_temp_local_new();
2796 TCGv t1
= tcg_temp_new();
2797 TCGv t2
= tcg_temp_new();
2798 TCGLabel
*l1
= gen_new_label();
2800 gen_load_gpr(t1
, rs
);
2801 gen_load_gpr(t2
, rt
);
2802 tcg_gen_sub_tl(t0
, t1
, t2
);
2803 tcg_gen_ext32s_tl(t0
, t0
);
2804 tcg_gen_xor_tl(t2
, t1
, t2
);
2805 tcg_gen_xor_tl(t1
, t0
, t1
);
2806 tcg_gen_and_tl(t1
, t1
, t2
);
2808 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2810 /* operands of different sign, first operand and result different sign */
2811 generate_exception(ctx
, EXCP_OVERFLOW
);
2813 gen_store_gpr(t0
, rd
);
2819 if (rs
!= 0 && rt
!= 0) {
2820 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2821 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2822 } else if (rs
== 0 && rt
!= 0) {
2823 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2824 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2825 } else if (rs
!= 0 && rt
== 0) {
2826 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2828 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2832 #if defined(TARGET_MIPS64)
2835 TCGv t0
= tcg_temp_local_new();
2836 TCGv t1
= tcg_temp_new();
2837 TCGv t2
= tcg_temp_new();
2838 TCGLabel
*l1
= gen_new_label();
2840 gen_load_gpr(t1
, rs
);
2841 gen_load_gpr(t2
, rt
);
2842 tcg_gen_add_tl(t0
, t1
, t2
);
2843 tcg_gen_xor_tl(t1
, t1
, t2
);
2844 tcg_gen_xor_tl(t2
, t0
, t2
);
2845 tcg_gen_andc_tl(t1
, t2
, t1
);
2847 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2849 /* operands of same sign, result different sign */
2850 generate_exception(ctx
, EXCP_OVERFLOW
);
2852 gen_store_gpr(t0
, rd
);
2858 if (rs
!= 0 && rt
!= 0) {
2859 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2860 } else if (rs
== 0 && rt
!= 0) {
2861 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2862 } else if (rs
!= 0 && rt
== 0) {
2863 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2865 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2871 TCGv t0
= tcg_temp_local_new();
2872 TCGv t1
= tcg_temp_new();
2873 TCGv t2
= tcg_temp_new();
2874 TCGLabel
*l1
= gen_new_label();
2876 gen_load_gpr(t1
, rs
);
2877 gen_load_gpr(t2
, rt
);
2878 tcg_gen_sub_tl(t0
, t1
, t2
);
2879 tcg_gen_xor_tl(t2
, t1
, t2
);
2880 tcg_gen_xor_tl(t1
, t0
, t1
);
2881 tcg_gen_and_tl(t1
, t1
, t2
);
2883 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2885 /* operands of different sign, first operand and result different sign */
2886 generate_exception(ctx
, EXCP_OVERFLOW
);
2888 gen_store_gpr(t0
, rd
);
2894 if (rs
!= 0 && rt
!= 0) {
2895 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2896 } else if (rs
== 0 && rt
!= 0) {
2897 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2898 } else if (rs
!= 0 && rt
== 0) {
2899 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2901 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2907 if (likely(rs
!= 0 && rt
!= 0)) {
2908 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2909 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2911 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2916 (void)opn
; /* avoid a compiler warning */
2917 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2920 /* Conditional move */
2921 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2922 int rd
, int rs
, int rt
)
2924 const char *opn
= "cond move";
2928 /* If no destination, treat it as a NOP. */
2933 t0
= tcg_temp_new();
2934 gen_load_gpr(t0
, rt
);
2935 t1
= tcg_const_tl(0);
2936 t2
= tcg_temp_new();
2937 gen_load_gpr(t2
, rs
);
2940 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2944 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2948 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2952 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2960 (void)opn
; /* avoid a compiler warning */
2961 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2965 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2966 int rd
, int rs
, int rt
)
2968 const char *opn
= "logic";
2971 /* If no destination, treat it as a NOP. */
2978 if (likely(rs
!= 0 && rt
!= 0)) {
2979 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2981 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2986 if (rs
!= 0 && rt
!= 0) {
2987 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2988 } else if (rs
== 0 && rt
!= 0) {
2989 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2990 } else if (rs
!= 0 && rt
== 0) {
2991 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2993 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2998 if (likely(rs
!= 0 && rt
!= 0)) {
2999 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3000 } else if (rs
== 0 && rt
!= 0) {
3001 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3002 } else if (rs
!= 0 && rt
== 0) {
3003 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3005 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3010 if (likely(rs
!= 0 && rt
!= 0)) {
3011 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
3012 } else if (rs
== 0 && rt
!= 0) {
3013 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
3014 } else if (rs
!= 0 && rt
== 0) {
3015 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
3017 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3022 (void)opn
; /* avoid a compiler warning */
3023 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3026 /* Set on lower than */
3027 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
3028 int rd
, int rs
, int rt
)
3030 const char *opn
= "slt";
3034 /* If no destination, treat it as a NOP. */
3039 t0
= tcg_temp_new();
3040 t1
= tcg_temp_new();
3041 gen_load_gpr(t0
, rs
);
3042 gen_load_gpr(t1
, rt
);
3045 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
3049 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
3053 (void)opn
; /* avoid a compiler warning */
3054 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3060 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
3061 int rd
, int rs
, int rt
)
3063 const char *opn
= "shifts";
3067 /* If no destination, treat it as a NOP.
3068 For add & sub, we must generate the overflow exception when needed. */
3073 t0
= tcg_temp_new();
3074 t1
= tcg_temp_new();
3075 gen_load_gpr(t0
, rs
);
3076 gen_load_gpr(t1
, rt
);
3079 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3080 tcg_gen_shl_tl(t0
, t1
, t0
);
3081 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3085 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3086 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3090 tcg_gen_ext32u_tl(t1
, t1
);
3091 tcg_gen_andi_tl(t0
, t0
, 0x1f);
3092 tcg_gen_shr_tl(t0
, t1
, t0
);
3093 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3098 TCGv_i32 t2
= tcg_temp_new_i32();
3099 TCGv_i32 t3
= tcg_temp_new_i32();
3101 tcg_gen_trunc_tl_i32(t2
, t0
);
3102 tcg_gen_trunc_tl_i32(t3
, t1
);
3103 tcg_gen_andi_i32(t2
, t2
, 0x1f);
3104 tcg_gen_rotr_i32(t2
, t3
, t2
);
3105 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3106 tcg_temp_free_i32(t2
);
3107 tcg_temp_free_i32(t3
);
3111 #if defined(TARGET_MIPS64)
3113 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3114 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
3118 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3119 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3123 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3124 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3128 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3129 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3134 (void)opn
; /* avoid a compiler warning */
3135 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3140 /* Arithmetic on HI/LO registers */
3141 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3143 const char *opn
= "hilo";
3145 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3157 #if defined(TARGET_MIPS64)
3159 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3163 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3168 #if defined(TARGET_MIPS64)
3170 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3174 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3180 #if defined(TARGET_MIPS64)
3182 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3186 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3189 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3195 #if defined(TARGET_MIPS64)
3197 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3201 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3204 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3209 (void)opn
; /* avoid a compiler warning */
3210 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
3213 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3216 TCGv t0
= tcg_const_tl(addr
);
3217 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3218 gen_store_gpr(t0
, reg
);
3222 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
3228 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
3231 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3232 addr
= addr_add(ctx
, pc
, offset
);
3233 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3237 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3238 addr
= addr_add(ctx
, pc
, offset
);
3239 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3241 #if defined(TARGET_MIPS64)
3244 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3245 addr
= addr_add(ctx
, pc
, offset
);
3246 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3250 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
3253 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3254 addr
= addr_add(ctx
, pc
, offset
);
3255 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3260 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3261 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
3262 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3265 #if defined(TARGET_MIPS64)
3266 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3267 case R6_OPC_LDPC
+ (1 << 16):
3268 case R6_OPC_LDPC
+ (2 << 16):
3269 case R6_OPC_LDPC
+ (3 << 16):
3271 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3272 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
3273 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3277 MIPS_INVAL("OPC_PCREL");
3278 generate_exception(ctx
, EXCP_RI
);
3285 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3287 const char *opn
= "r6 mul/div";
3296 t0
= tcg_temp_new();
3297 t1
= tcg_temp_new();
3299 gen_load_gpr(t0
, rs
);
3300 gen_load_gpr(t1
, rt
);
3305 TCGv t2
= tcg_temp_new();
3306 TCGv t3
= tcg_temp_new();
3307 tcg_gen_ext32s_tl(t0
, t0
);
3308 tcg_gen_ext32s_tl(t1
, t1
);
3309 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3310 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3311 tcg_gen_and_tl(t2
, t2
, t3
);
3312 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3313 tcg_gen_or_tl(t2
, t2
, t3
);
3314 tcg_gen_movi_tl(t3
, 0);
3315 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3316 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3317 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3325 TCGv t2
= tcg_temp_new();
3326 TCGv t3
= tcg_temp_new();
3327 tcg_gen_ext32s_tl(t0
, t0
);
3328 tcg_gen_ext32s_tl(t1
, t1
);
3329 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3330 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3331 tcg_gen_and_tl(t2
, t2
, t3
);
3332 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3333 tcg_gen_or_tl(t2
, t2
, t3
);
3334 tcg_gen_movi_tl(t3
, 0);
3335 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3336 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3337 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3345 TCGv t2
= tcg_const_tl(0);
3346 TCGv t3
= tcg_const_tl(1);
3347 tcg_gen_ext32u_tl(t0
, t0
);
3348 tcg_gen_ext32u_tl(t1
, t1
);
3349 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3350 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3351 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3359 TCGv t2
= tcg_const_tl(0);
3360 TCGv t3
= tcg_const_tl(1);
3361 tcg_gen_ext32u_tl(t0
, t0
);
3362 tcg_gen_ext32u_tl(t1
, t1
);
3363 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3364 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3365 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3373 TCGv_i32 t2
= tcg_temp_new_i32();
3374 TCGv_i32 t3
= tcg_temp_new_i32();
3375 tcg_gen_trunc_tl_i32(t2
, t0
);
3376 tcg_gen_trunc_tl_i32(t3
, t1
);
3377 tcg_gen_mul_i32(t2
, t2
, t3
);
3378 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3379 tcg_temp_free_i32(t2
);
3380 tcg_temp_free_i32(t3
);
3386 TCGv_i32 t2
= tcg_temp_new_i32();
3387 TCGv_i32 t3
= tcg_temp_new_i32();
3388 tcg_gen_trunc_tl_i32(t2
, t0
);
3389 tcg_gen_trunc_tl_i32(t3
, t1
);
3390 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3391 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3392 tcg_temp_free_i32(t2
);
3393 tcg_temp_free_i32(t3
);
3399 TCGv_i32 t2
= tcg_temp_new_i32();
3400 TCGv_i32 t3
= tcg_temp_new_i32();
3401 tcg_gen_trunc_tl_i32(t2
, t0
);
3402 tcg_gen_trunc_tl_i32(t3
, t1
);
3403 tcg_gen_mul_i32(t2
, t2
, t3
);
3404 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3405 tcg_temp_free_i32(t2
);
3406 tcg_temp_free_i32(t3
);
3412 TCGv_i32 t2
= tcg_temp_new_i32();
3413 TCGv_i32 t3
= tcg_temp_new_i32();
3414 tcg_gen_trunc_tl_i32(t2
, t0
);
3415 tcg_gen_trunc_tl_i32(t3
, t1
);
3416 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3417 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3418 tcg_temp_free_i32(t2
);
3419 tcg_temp_free_i32(t3
);
3423 #if defined(TARGET_MIPS64)
3426 TCGv t2
= tcg_temp_new();
3427 TCGv t3
= tcg_temp_new();
3428 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3429 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3430 tcg_gen_and_tl(t2
, t2
, t3
);
3431 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3432 tcg_gen_or_tl(t2
, t2
, t3
);
3433 tcg_gen_movi_tl(t3
, 0);
3434 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3435 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3443 TCGv t2
= tcg_temp_new();
3444 TCGv t3
= tcg_temp_new();
3445 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3446 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3447 tcg_gen_and_tl(t2
, t2
, t3
);
3448 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3449 tcg_gen_or_tl(t2
, t2
, t3
);
3450 tcg_gen_movi_tl(t3
, 0);
3451 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3452 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3460 TCGv t2
= tcg_const_tl(0);
3461 TCGv t3
= tcg_const_tl(1);
3462 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3463 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3471 TCGv t2
= tcg_const_tl(0);
3472 TCGv t3
= tcg_const_tl(1);
3473 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3474 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3481 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3486 TCGv t2
= tcg_temp_new();
3487 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3493 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3498 TCGv t2
= tcg_temp_new();
3499 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3507 generate_exception(ctx
, EXCP_RI
);
3510 (void)opn
; /* avoid a compiler warning */
3511 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3517 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3518 int acc
, int rs
, int rt
)
3520 const char *opn
= "mul/div";
3523 t0
= tcg_temp_new();
3524 t1
= tcg_temp_new();
3526 gen_load_gpr(t0
, rs
);
3527 gen_load_gpr(t1
, rt
);
3536 TCGv t2
= tcg_temp_new();
3537 TCGv t3
= tcg_temp_new();
3538 tcg_gen_ext32s_tl(t0
, t0
);
3539 tcg_gen_ext32s_tl(t1
, t1
);
3540 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3541 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3542 tcg_gen_and_tl(t2
, t2
, t3
);
3543 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3544 tcg_gen_or_tl(t2
, t2
, t3
);
3545 tcg_gen_movi_tl(t3
, 0);
3546 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3547 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3548 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3549 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3550 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3558 TCGv t2
= tcg_const_tl(0);
3559 TCGv t3
= tcg_const_tl(1);
3560 tcg_gen_ext32u_tl(t0
, t0
);
3561 tcg_gen_ext32u_tl(t1
, t1
);
3562 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3563 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3564 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3565 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3566 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3574 TCGv_i32 t2
= tcg_temp_new_i32();
3575 TCGv_i32 t3
= tcg_temp_new_i32();
3576 tcg_gen_trunc_tl_i32(t2
, t0
);
3577 tcg_gen_trunc_tl_i32(t3
, t1
);
3578 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3579 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3580 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3581 tcg_temp_free_i32(t2
);
3582 tcg_temp_free_i32(t3
);
3588 TCGv_i32 t2
= tcg_temp_new_i32();
3589 TCGv_i32 t3
= tcg_temp_new_i32();
3590 tcg_gen_trunc_tl_i32(t2
, t0
);
3591 tcg_gen_trunc_tl_i32(t3
, t1
);
3592 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3593 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3594 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3595 tcg_temp_free_i32(t2
);
3596 tcg_temp_free_i32(t3
);
3600 #if defined(TARGET_MIPS64)
3603 TCGv t2
= tcg_temp_new();
3604 TCGv t3
= tcg_temp_new();
3605 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3606 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3607 tcg_gen_and_tl(t2
, t2
, t3
);
3608 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3609 tcg_gen_or_tl(t2
, t2
, t3
);
3610 tcg_gen_movi_tl(t3
, 0);
3611 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3612 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3613 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3621 TCGv t2
= tcg_const_tl(0);
3622 TCGv t3
= tcg_const_tl(1);
3623 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3624 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3625 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3632 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3636 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3642 TCGv_i64 t2
= tcg_temp_new_i64();
3643 TCGv_i64 t3
= tcg_temp_new_i64();
3645 tcg_gen_ext_tl_i64(t2
, t0
);
3646 tcg_gen_ext_tl_i64(t3
, t1
);
3647 tcg_gen_mul_i64(t2
, t2
, t3
);
3648 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3649 tcg_gen_add_i64(t2
, t2
, t3
);
3650 tcg_temp_free_i64(t3
);
3651 tcg_gen_trunc_i64_tl(t0
, t2
);
3652 tcg_gen_shri_i64(t2
, t2
, 32);
3653 tcg_gen_trunc_i64_tl(t1
, t2
);
3654 tcg_temp_free_i64(t2
);
3655 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3656 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3662 TCGv_i64 t2
= tcg_temp_new_i64();
3663 TCGv_i64 t3
= tcg_temp_new_i64();
3665 tcg_gen_ext32u_tl(t0
, t0
);
3666 tcg_gen_ext32u_tl(t1
, t1
);
3667 tcg_gen_extu_tl_i64(t2
, t0
);
3668 tcg_gen_extu_tl_i64(t3
, t1
);
3669 tcg_gen_mul_i64(t2
, t2
, t3
);
3670 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3671 tcg_gen_add_i64(t2
, t2
, t3
);
3672 tcg_temp_free_i64(t3
);
3673 tcg_gen_trunc_i64_tl(t0
, t2
);
3674 tcg_gen_shri_i64(t2
, t2
, 32);
3675 tcg_gen_trunc_i64_tl(t1
, t2
);
3676 tcg_temp_free_i64(t2
);
3677 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3678 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3684 TCGv_i64 t2
= tcg_temp_new_i64();
3685 TCGv_i64 t3
= tcg_temp_new_i64();
3687 tcg_gen_ext_tl_i64(t2
, t0
);
3688 tcg_gen_ext_tl_i64(t3
, t1
);
3689 tcg_gen_mul_i64(t2
, t2
, t3
);
3690 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3691 tcg_gen_sub_i64(t2
, t3
, t2
);
3692 tcg_temp_free_i64(t3
);
3693 tcg_gen_trunc_i64_tl(t0
, t2
);
3694 tcg_gen_shri_i64(t2
, t2
, 32);
3695 tcg_gen_trunc_i64_tl(t1
, t2
);
3696 tcg_temp_free_i64(t2
);
3697 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3698 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3704 TCGv_i64 t2
= tcg_temp_new_i64();
3705 TCGv_i64 t3
= tcg_temp_new_i64();
3707 tcg_gen_ext32u_tl(t0
, t0
);
3708 tcg_gen_ext32u_tl(t1
, t1
);
3709 tcg_gen_extu_tl_i64(t2
, t0
);
3710 tcg_gen_extu_tl_i64(t3
, t1
);
3711 tcg_gen_mul_i64(t2
, t2
, t3
);
3712 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3713 tcg_gen_sub_i64(t2
, t3
, t2
);
3714 tcg_temp_free_i64(t3
);
3715 tcg_gen_trunc_i64_tl(t0
, t2
);
3716 tcg_gen_shri_i64(t2
, t2
, 32);
3717 tcg_gen_trunc_i64_tl(t1
, t2
);
3718 tcg_temp_free_i64(t2
);
3719 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3720 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3726 generate_exception(ctx
, EXCP_RI
);
3729 (void)opn
; /* avoid a compiler warning */
3730 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3736 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
3737 int rd
, int rs
, int rt
)
3739 const char *opn
= "mul vr54xx";
3740 TCGv t0
= tcg_temp_new();
3741 TCGv t1
= tcg_temp_new();
3743 gen_load_gpr(t0
, rs
);
3744 gen_load_gpr(t1
, rt
);
3747 case OPC_VR54XX_MULS
:
3748 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3751 case OPC_VR54XX_MULSU
:
3752 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3755 case OPC_VR54XX_MACC
:
3756 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3759 case OPC_VR54XX_MACCU
:
3760 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3763 case OPC_VR54XX_MSAC
:
3764 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3767 case OPC_VR54XX_MSACU
:
3768 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3771 case OPC_VR54XX_MULHI
:
3772 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3775 case OPC_VR54XX_MULHIU
:
3776 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3779 case OPC_VR54XX_MULSHI
:
3780 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3783 case OPC_VR54XX_MULSHIU
:
3784 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3787 case OPC_VR54XX_MACCHI
:
3788 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3791 case OPC_VR54XX_MACCHIU
:
3792 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3795 case OPC_VR54XX_MSACHI
:
3796 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3799 case OPC_VR54XX_MSACHIU
:
3800 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3804 MIPS_INVAL("mul vr54xx");
3805 generate_exception(ctx
, EXCP_RI
);
3808 gen_store_gpr(t0
, rd
);
3809 (void)opn
; /* avoid a compiler warning */
3810 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3817 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
3820 const char *opn
= "CLx";
3828 t0
= tcg_temp_new();
3829 gen_load_gpr(t0
, rs
);
3833 gen_helper_clo(cpu_gpr
[rd
], t0
);
3838 gen_helper_clz(cpu_gpr
[rd
], t0
);
3841 #if defined(TARGET_MIPS64)
3844 gen_helper_dclo(cpu_gpr
[rd
], t0
);
3849 gen_helper_dclz(cpu_gpr
[rd
], t0
);
3854 (void)opn
; /* avoid a compiler warning */
3855 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3859 /* Godson integer instructions */
3860 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3861 int rd
, int rs
, int rt
)
3863 const char *opn
= "loongson";
3875 case OPC_MULTU_G_2E
:
3876 case OPC_MULTU_G_2F
:
3877 #if defined(TARGET_MIPS64)
3878 case OPC_DMULT_G_2E
:
3879 case OPC_DMULT_G_2F
:
3880 case OPC_DMULTU_G_2E
:
3881 case OPC_DMULTU_G_2F
:
3883 t0
= tcg_temp_new();
3884 t1
= tcg_temp_new();
3887 t0
= tcg_temp_local_new();
3888 t1
= tcg_temp_local_new();
3892 gen_load_gpr(t0
, rs
);
3893 gen_load_gpr(t1
, rt
);
3898 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3899 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3902 case OPC_MULTU_G_2E
:
3903 case OPC_MULTU_G_2F
:
3904 tcg_gen_ext32u_tl(t0
, t0
);
3905 tcg_gen_ext32u_tl(t1
, t1
);
3906 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3907 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3913 TCGLabel
*l1
= gen_new_label();
3914 TCGLabel
*l2
= gen_new_label();
3915 TCGLabel
*l3
= gen_new_label();
3916 tcg_gen_ext32s_tl(t0
, t0
);
3917 tcg_gen_ext32s_tl(t1
, t1
);
3918 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3919 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3922 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3923 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3924 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3927 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3928 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3936 TCGLabel
*l1
= gen_new_label();
3937 TCGLabel
*l2
= gen_new_label();
3938 tcg_gen_ext32u_tl(t0
, t0
);
3939 tcg_gen_ext32u_tl(t1
, t1
);
3940 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3941 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3944 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3945 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3953 TCGLabel
*l1
= gen_new_label();
3954 TCGLabel
*l2
= gen_new_label();
3955 TCGLabel
*l3
= gen_new_label();
3956 tcg_gen_ext32u_tl(t0
, t0
);
3957 tcg_gen_ext32u_tl(t1
, t1
);
3958 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3959 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3960 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3962 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3965 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3966 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3974 TCGLabel
*l1
= gen_new_label();
3975 TCGLabel
*l2
= gen_new_label();
3976 tcg_gen_ext32u_tl(t0
, t0
);
3977 tcg_gen_ext32u_tl(t1
, t1
);
3978 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3979 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3982 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3983 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3988 #if defined(TARGET_MIPS64)
3989 case OPC_DMULT_G_2E
:
3990 case OPC_DMULT_G_2F
:
3991 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3994 case OPC_DMULTU_G_2E
:
3995 case OPC_DMULTU_G_2F
:
3996 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
4002 TCGLabel
*l1
= gen_new_label();
4003 TCGLabel
*l2
= gen_new_label();
4004 TCGLabel
*l3
= gen_new_label();
4005 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4006 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4009 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4010 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4011 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4014 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
4019 case OPC_DDIVU_G_2E
:
4020 case OPC_DDIVU_G_2F
:
4022 TCGLabel
*l1
= gen_new_label();
4023 TCGLabel
*l2
= gen_new_label();
4024 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4025 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4028 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
4036 TCGLabel
*l1
= gen_new_label();
4037 TCGLabel
*l2
= gen_new_label();
4038 TCGLabel
*l3
= gen_new_label();
4039 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
4040 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
4041 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
4043 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4046 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
4051 case OPC_DMODU_G_2E
:
4052 case OPC_DMODU_G_2F
:
4054 TCGLabel
*l1
= gen_new_label();
4055 TCGLabel
*l2
= gen_new_label();
4056 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
4057 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
4060 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
4068 (void)opn
; /* avoid a compiler warning */
4069 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
4074 /* Loongson multimedia instructions */
4075 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
4077 const char *opn
= "loongson_cp2";
4078 uint32_t opc
, shift_max
;
4081 opc
= MASK_LMI(ctx
->opcode
);
4087 t0
= tcg_temp_local_new_i64();
4088 t1
= tcg_temp_local_new_i64();
4091 t0
= tcg_temp_new_i64();
4092 t1
= tcg_temp_new_i64();
4096 gen_load_fpr64(ctx
, t0
, rs
);
4097 gen_load_fpr64(ctx
, t1
, rt
);
4099 #define LMI_HELPER(UP, LO) \
4100 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
4101 #define LMI_HELPER_1(UP, LO) \
4102 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
4103 #define LMI_DIRECT(UP, LO, OP) \
4104 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
4107 LMI_HELPER(PADDSH
, paddsh
);
4108 LMI_HELPER(PADDUSH
, paddush
);
4109 LMI_HELPER(PADDH
, paddh
);
4110 LMI_HELPER(PADDW
, paddw
);
4111 LMI_HELPER(PADDSB
, paddsb
);
4112 LMI_HELPER(PADDUSB
, paddusb
);
4113 LMI_HELPER(PADDB
, paddb
);
4115 LMI_HELPER(PSUBSH
, psubsh
);
4116 LMI_HELPER(PSUBUSH
, psubush
);
4117 LMI_HELPER(PSUBH
, psubh
);
4118 LMI_HELPER(PSUBW
, psubw
);
4119 LMI_HELPER(PSUBSB
, psubsb
);
4120 LMI_HELPER(PSUBUSB
, psubusb
);
4121 LMI_HELPER(PSUBB
, psubb
);
4123 LMI_HELPER(PSHUFH
, pshufh
);
4124 LMI_HELPER(PACKSSWH
, packsswh
);
4125 LMI_HELPER(PACKSSHB
, packsshb
);
4126 LMI_HELPER(PACKUSHB
, packushb
);
4128 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
4129 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
4130 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
4131 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
4132 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
4133 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
4135 LMI_HELPER(PAVGH
, pavgh
);
4136 LMI_HELPER(PAVGB
, pavgb
);
4137 LMI_HELPER(PMAXSH
, pmaxsh
);
4138 LMI_HELPER(PMINSH
, pminsh
);
4139 LMI_HELPER(PMAXUB
, pmaxub
);
4140 LMI_HELPER(PMINUB
, pminub
);
4142 LMI_HELPER(PCMPEQW
, pcmpeqw
);
4143 LMI_HELPER(PCMPGTW
, pcmpgtw
);
4144 LMI_HELPER(PCMPEQH
, pcmpeqh
);
4145 LMI_HELPER(PCMPGTH
, pcmpgth
);
4146 LMI_HELPER(PCMPEQB
, pcmpeqb
);
4147 LMI_HELPER(PCMPGTB
, pcmpgtb
);
4149 LMI_HELPER(PSLLW
, psllw
);
4150 LMI_HELPER(PSLLH
, psllh
);
4151 LMI_HELPER(PSRLW
, psrlw
);
4152 LMI_HELPER(PSRLH
, psrlh
);
4153 LMI_HELPER(PSRAW
, psraw
);
4154 LMI_HELPER(PSRAH
, psrah
);
4156 LMI_HELPER(PMULLH
, pmullh
);
4157 LMI_HELPER(PMULHH
, pmulhh
);
4158 LMI_HELPER(PMULHUH
, pmulhuh
);
4159 LMI_HELPER(PMADDHW
, pmaddhw
);
4161 LMI_HELPER(PASUBUB
, pasubub
);
4162 LMI_HELPER_1(BIADD
, biadd
);
4163 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
4165 LMI_DIRECT(PADDD
, paddd
, add
);
4166 LMI_DIRECT(PSUBD
, psubd
, sub
);
4167 LMI_DIRECT(XOR_CP2
, xor, xor);
4168 LMI_DIRECT(NOR_CP2
, nor
, nor
);
4169 LMI_DIRECT(AND_CP2
, and, and);
4170 LMI_DIRECT(PANDN
, pandn
, andc
);
4171 LMI_DIRECT(OR
, or, or);
4174 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
4178 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
4182 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
4186 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
4191 tcg_gen_andi_i64(t1
, t1
, 3);
4192 tcg_gen_shli_i64(t1
, t1
, 4);
4193 tcg_gen_shr_i64(t0
, t0
, t1
);
4194 tcg_gen_ext16u_i64(t0
, t0
);
4199 tcg_gen_add_i64(t0
, t0
, t1
);
4200 tcg_gen_ext32s_i64(t0
, t0
);
4204 tcg_gen_sub_i64(t0
, t0
, t1
);
4205 tcg_gen_ext32s_i64(t0
, t0
);
4234 /* Make sure shift count isn't TCG undefined behaviour. */
4235 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4240 tcg_gen_shl_i64(t0
, t0
, t1
);
4244 /* Since SRA is UndefinedResult without sign-extended inputs,
4245 we can treat SRA and DSRA the same. */
4246 tcg_gen_sar_i64(t0
, t0
, t1
);
4249 /* We want to shift in zeros for SRL; zero-extend first. */
4250 tcg_gen_ext32u_i64(t0
, t0
);
4253 tcg_gen_shr_i64(t0
, t0
, t1
);
4257 if (shift_max
== 32) {
4258 tcg_gen_ext32s_i64(t0
, t0
);
4261 /* Shifts larger than MAX produce zero. */
4262 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4263 tcg_gen_neg_i64(t1
, t1
);
4264 tcg_gen_and_i64(t0
, t0
, t1
);
4270 TCGv_i64 t2
= tcg_temp_new_i64();
4271 TCGLabel
*lab
= gen_new_label();
4273 tcg_gen_mov_i64(t2
, t0
);
4274 tcg_gen_add_i64(t0
, t1
, t2
);
4275 if (opc
== OPC_ADD_CP2
) {
4276 tcg_gen_ext32s_i64(t0
, t0
);
4278 tcg_gen_xor_i64(t1
, t1
, t2
);
4279 tcg_gen_xor_i64(t2
, t2
, t0
);
4280 tcg_gen_andc_i64(t1
, t2
, t1
);
4281 tcg_temp_free_i64(t2
);
4282 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4283 generate_exception(ctx
, EXCP_OVERFLOW
);
4286 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
4293 TCGv_i64 t2
= tcg_temp_new_i64();
4294 TCGLabel
*lab
= gen_new_label();
4296 tcg_gen_mov_i64(t2
, t0
);
4297 tcg_gen_sub_i64(t0
, t1
, t2
);
4298 if (opc
== OPC_SUB_CP2
) {
4299 tcg_gen_ext32s_i64(t0
, t0
);
4301 tcg_gen_xor_i64(t1
, t1
, t2
);
4302 tcg_gen_xor_i64(t2
, t2
, t0
);
4303 tcg_gen_and_i64(t1
, t1
, t2
);
4304 tcg_temp_free_i64(t2
);
4305 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4306 generate_exception(ctx
, EXCP_OVERFLOW
);
4309 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
4314 tcg_gen_ext32u_i64(t0
, t0
);
4315 tcg_gen_ext32u_i64(t1
, t1
);
4316 tcg_gen_mul_i64(t0
, t0
, t1
);
4326 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4327 FD field is the CC field? */
4330 generate_exception(ctx
, EXCP_RI
);
4337 gen_store_fpr64(ctx
, t0
, rd
);
4339 (void)opn
; /* avoid a compiler warning */
4340 MIPS_DEBUG("%s %s, %s, %s", opn
,
4341 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
4342 tcg_temp_free_i64(t0
);
4343 tcg_temp_free_i64(t1
);
4347 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
4348 int rs
, int rt
, int16_t imm
)
4351 TCGv t0
= tcg_temp_new();
4352 TCGv t1
= tcg_temp_new();
4355 /* Load needed operands */
4363 /* Compare two registers */
4365 gen_load_gpr(t0
, rs
);
4366 gen_load_gpr(t1
, rt
);
4376 /* Compare register to immediate */
4377 if (rs
!= 0 || imm
!= 0) {
4378 gen_load_gpr(t0
, rs
);
4379 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4386 case OPC_TEQ
: /* rs == rs */
4387 case OPC_TEQI
: /* r0 == 0 */
4388 case OPC_TGE
: /* rs >= rs */
4389 case OPC_TGEI
: /* r0 >= 0 */
4390 case OPC_TGEU
: /* rs >= rs unsigned */
4391 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4393 generate_exception(ctx
, EXCP_TRAP
);
4395 case OPC_TLT
: /* rs < rs */
4396 case OPC_TLTI
: /* r0 < 0 */
4397 case OPC_TLTU
: /* rs < rs unsigned */
4398 case OPC_TLTIU
: /* r0 < 0 unsigned */
4399 case OPC_TNE
: /* rs != rs */
4400 case OPC_TNEI
: /* r0 != 0 */
4401 /* Never trap: treat as NOP. */
4405 TCGLabel
*l1
= gen_new_label();
4410 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4414 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4418 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
4422 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
4426 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
4430 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
4433 generate_exception(ctx
, EXCP_TRAP
);
4440 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
4442 TranslationBlock
*tb
;
4444 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
4445 likely(!ctx
->singlestep_enabled
)) {
4448 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
4451 if (ctx
->singlestep_enabled
) {
4452 save_cpu_state(ctx
, 0);
4453 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
4459 /* Branches (before delay slot) */
4460 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
4462 int rs
, int rt
, int32_t offset
,
4465 target_ulong btgt
= -1;
4467 int bcond_compute
= 0;
4468 TCGv t0
= tcg_temp_new();
4469 TCGv t1
= tcg_temp_new();
4471 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
4472 #ifdef MIPS_DEBUG_DISAS
4473 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4474 TARGET_FMT_lx
"\n", ctx
->pc
);
4476 generate_exception(ctx
, EXCP_RI
);
4480 /* Load needed operands */
4486 /* Compare two registers */
4488 gen_load_gpr(t0
, rs
);
4489 gen_load_gpr(t1
, rt
);
4492 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4506 /* Compare to zero */
4508 gen_load_gpr(t0
, rs
);
4511 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4514 #if defined(TARGET_MIPS64)
4516 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
4518 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
4521 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4526 /* Jump to immediate */
4527 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
4531 /* Jump to register */
4532 if (offset
!= 0 && offset
!= 16) {
4533 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4534 others are reserved. */
4535 MIPS_INVAL("jump hint");
4536 generate_exception(ctx
, EXCP_RI
);
4539 gen_load_gpr(btarget
, rs
);
4542 MIPS_INVAL("branch/jump");
4543 generate_exception(ctx
, EXCP_RI
);
4546 if (bcond_compute
== 0) {
4547 /* No condition to be computed */
4549 case OPC_BEQ
: /* rx == rx */
4550 case OPC_BEQL
: /* rx == rx likely */
4551 case OPC_BGEZ
: /* 0 >= 0 */
4552 case OPC_BGEZL
: /* 0 >= 0 likely */
4553 case OPC_BLEZ
: /* 0 <= 0 */
4554 case OPC_BLEZL
: /* 0 <= 0 likely */
4556 ctx
->hflags
|= MIPS_HFLAG_B
;
4557 MIPS_DEBUG("balways");
4559 case OPC_BGEZAL
: /* 0 >= 0 */
4560 case OPC_BGEZALL
: /* 0 >= 0 likely */
4561 /* Always take and link */
4563 ctx
->hflags
|= MIPS_HFLAG_B
;
4564 MIPS_DEBUG("balways and link");
4566 case OPC_BNE
: /* rx != rx */
4567 case OPC_BGTZ
: /* 0 > 0 */
4568 case OPC_BLTZ
: /* 0 < 0 */
4570 MIPS_DEBUG("bnever (NOP)");
4572 case OPC_BLTZAL
: /* 0 < 0 */
4573 /* Handle as an unconditional branch to get correct delay
4576 btgt
= ctx
->pc
+ insn_bytes
+ delayslot_size
;
4577 ctx
->hflags
|= MIPS_HFLAG_B
;
4578 MIPS_DEBUG("bnever and link");
4580 case OPC_BLTZALL
: /* 0 < 0 likely */
4581 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
4582 /* Skip the instruction in the delay slot */
4583 MIPS_DEBUG("bnever, link and skip");
4586 case OPC_BNEL
: /* rx != rx likely */
4587 case OPC_BGTZL
: /* 0 > 0 likely */
4588 case OPC_BLTZL
: /* 0 < 0 likely */
4589 /* Skip the instruction in the delay slot */
4590 MIPS_DEBUG("bnever and skip");
4594 ctx
->hflags
|= MIPS_HFLAG_B
;
4595 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
4598 ctx
->hflags
|= MIPS_HFLAG_BX
;
4602 ctx
->hflags
|= MIPS_HFLAG_B
;
4603 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
4606 ctx
->hflags
|= MIPS_HFLAG_BR
;
4607 MIPS_DEBUG("jr %s", regnames
[rs
]);
4611 ctx
->hflags
|= MIPS_HFLAG_BR
;
4612 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
4615 MIPS_INVAL("branch/jump");
4616 generate_exception(ctx
, EXCP_RI
);
4622 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4623 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
4624 regnames
[rs
], regnames
[rt
], btgt
);
4627 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4628 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
4629 regnames
[rs
], regnames
[rt
], btgt
);
4632 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4633 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
4634 regnames
[rs
], regnames
[rt
], btgt
);
4637 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4638 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
4639 regnames
[rs
], regnames
[rt
], btgt
);
4642 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4643 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4646 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4647 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4650 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4651 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4655 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4657 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4660 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4661 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4664 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4665 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4668 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4669 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4672 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4673 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4676 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4677 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4680 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4681 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4684 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
4685 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
4687 #if defined(TARGET_MIPS64)
4689 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
4690 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
4694 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4696 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4698 ctx
->hflags
|= MIPS_HFLAG_BC
;
4701 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4703 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4705 ctx
->hflags
|= MIPS_HFLAG_BL
;
4708 MIPS_INVAL("conditional branch/jump");
4709 generate_exception(ctx
, EXCP_RI
);
4713 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
4714 blink
, ctx
->hflags
, btgt
);
4716 ctx
->btarget
= btgt
;
4718 switch (delayslot_size
) {
4720 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
4723 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
4728 int post_delay
= insn_bytes
+ delayslot_size
;
4729 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
4731 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
4735 if (insn_bytes
== 2)
4736 ctx
->hflags
|= MIPS_HFLAG_B16
;
4741 /* special3 bitfield operations */
4742 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
4743 int rs
, int lsb
, int msb
)
4745 TCGv t0
= tcg_temp_new();
4746 TCGv t1
= tcg_temp_new();
4748 gen_load_gpr(t1
, rs
);
4751 if (lsb
+ msb
> 31) {
4754 tcg_gen_shri_tl(t0
, t1
, lsb
);
4756 tcg_gen_andi_tl(t0
, t0
, (1U << (msb
+ 1)) - 1);
4758 tcg_gen_ext32s_tl(t0
, t0
);
4761 #if defined(TARGET_MIPS64)
4770 if (lsb
+ msb
> 63) {
4773 tcg_gen_shri_tl(t0
, t1
, lsb
);
4775 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4783 gen_load_gpr(t0
, rt
);
4784 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4785 tcg_gen_ext32s_tl(t0
, t0
);
4787 #if defined(TARGET_MIPS64)
4798 gen_load_gpr(t0
, rt
);
4799 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4804 MIPS_INVAL("bitops");
4805 generate_exception(ctx
, EXCP_RI
);
4810 gen_store_gpr(t0
, rt
);
4815 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4820 /* If no destination, treat it as a NOP. */
4825 t0
= tcg_temp_new();
4826 gen_load_gpr(t0
, rt
);
4830 TCGv t1
= tcg_temp_new();
4832 tcg_gen_shri_tl(t1
, t0
, 8);
4833 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4834 tcg_gen_shli_tl(t0
, t0
, 8);
4835 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4836 tcg_gen_or_tl(t0
, t0
, t1
);
4838 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4842 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4845 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4847 #if defined(TARGET_MIPS64)
4850 TCGv t1
= tcg_temp_new();
4852 tcg_gen_shri_tl(t1
, t0
, 8);
4853 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4854 tcg_gen_shli_tl(t0
, t0
, 8);
4855 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4856 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4862 TCGv t1
= tcg_temp_new();
4864 tcg_gen_shri_tl(t1
, t0
, 16);
4865 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4866 tcg_gen_shli_tl(t0
, t0
, 16);
4867 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4868 tcg_gen_or_tl(t0
, t0
, t1
);
4869 tcg_gen_shri_tl(t1
, t0
, 32);
4870 tcg_gen_shli_tl(t0
, t0
, 32);
4871 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4877 MIPS_INVAL("bsfhl");
4878 generate_exception(ctx
, EXCP_RI
);
4885 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
4894 t0
= tcg_temp_new();
4895 t1
= tcg_temp_new();
4896 gen_load_gpr(t0
, rs
);
4897 gen_load_gpr(t1
, rt
);
4898 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
4899 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
4900 if (opc
== OPC_LSA
) {
4901 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4910 static void gen_align(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
4918 t0
= tcg_temp_new();
4919 gen_load_gpr(t0
, rt
);
4921 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4923 TCGv t1
= tcg_temp_new();
4924 gen_load_gpr(t1
, rs
);
4928 TCGv_i64 t2
= tcg_temp_new_i64();
4929 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
4930 tcg_gen_shri_i64(t2
, t2
, 8 * (4 - bp
));
4931 gen_move_low32(cpu_gpr
[rd
], t2
);
4932 tcg_temp_free_i64(t2
);
4935 #if defined(TARGET_MIPS64)
4937 tcg_gen_shli_tl(t0
, t0
, 8 * bp
);
4938 tcg_gen_shri_tl(t1
, t1
, 8 * (8 - bp
));
4939 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
4949 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
4956 t0
= tcg_temp_new();
4957 gen_load_gpr(t0
, rt
);
4960 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
4962 #if defined(TARGET_MIPS64)
4964 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
4971 #ifndef CONFIG_USER_ONLY
4972 /* CP0 (MMU and control) */
4973 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
4975 TCGv_i64 t0
= tcg_temp_new_i64();
4976 TCGv_i64 t1
= tcg_temp_new_i64();
4978 tcg_gen_ext_tl_i64(t0
, arg
);
4979 tcg_gen_ld_i64(t1
, cpu_env
, off
);
4980 #if defined(TARGET_MIPS64)
4981 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
4983 tcg_gen_concat32_i64(t1
, t1
, t0
);
4985 tcg_gen_st_i64(t1
, cpu_env
, off
);
4986 tcg_temp_free_i64(t1
);
4987 tcg_temp_free_i64(t0
);
4990 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
4992 TCGv_i64 t0
= tcg_temp_new_i64();
4993 TCGv_i64 t1
= tcg_temp_new_i64();
4995 tcg_gen_ext_tl_i64(t0
, arg
);
4996 tcg_gen_ld_i64(t1
, cpu_env
, off
);
4997 tcg_gen_concat32_i64(t1
, t1
, t0
);
4998 tcg_gen_st_i64(t1
, cpu_env
, off
);
4999 tcg_temp_free_i64(t1
);
5000 tcg_temp_free_i64(t0
);
5003 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
5005 TCGv_i64 t0
= tcg_temp_new_i64();
5007 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5008 #if defined(TARGET_MIPS64)
5009 tcg_gen_shri_i64(t0
, t0
, 30);
5011 tcg_gen_shri_i64(t0
, t0
, 32);
5013 gen_move_low32(arg
, t0
);
5014 tcg_temp_free_i64(t0
);
5017 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
5019 TCGv_i64 t0
= tcg_temp_new_i64();
5021 tcg_gen_ld_i64(t0
, cpu_env
, off
);
5022 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
5023 gen_move_low32(arg
, t0
);
5024 tcg_temp_free_i64(t0
);
5027 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
5029 TCGv_i32 t0
= tcg_temp_new_i32();
5031 tcg_gen_ld_i32(t0
, cpu_env
, off
);
5032 tcg_gen_ext_i32_tl(arg
, t0
);
5033 tcg_temp_free_i32(t0
);
5036 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
5038 tcg_gen_ld_tl(arg
, cpu_env
, off
);
5039 tcg_gen_ext32s_tl(arg
, arg
);
5042 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
5044 TCGv_i32 t0
= tcg_temp_new_i32();
5046 tcg_gen_trunc_tl_i32(t0
, arg
);
5047 tcg_gen_st_i32(t0
, cpu_env
, off
);
5048 tcg_temp_free_i32(t0
);
5051 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
5053 tcg_gen_ext32s_tl(arg
, arg
);
5054 tcg_gen_st_tl(arg
, cpu_env
, off
);
5057 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5059 const char *rn
= "invalid";
5061 if (!(ctx
->hflags
& MIPS_HFLAG_ELPA
)) {
5062 goto mfhc0_read_zero
;
5069 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5073 goto mfhc0_read_zero
;
5079 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5083 goto mfhc0_read_zero
;
5089 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, lladdr
),
5090 ctx
->CP0_LLAddr_shift
);
5094 goto mfhc0_read_zero
;
5103 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
5107 goto mfhc0_read_zero
;
5111 goto mfhc0_read_zero
;
5114 (void)rn
; /* avoid a compiler warning */
5115 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5119 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5120 tcg_gen_movi_tl(arg
, 0);
5123 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5125 const char *rn
= "invalid";
5126 uint64_t mask
= ctx
->PAMask
>> 36;
5128 if (!(ctx
->hflags
& MIPS_HFLAG_ELPA
)) {
5136 tcg_gen_andi_tl(arg
, arg
, mask
);
5137 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5147 tcg_gen_andi_tl(arg
, arg
, mask
);
5148 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5158 /* LLAddr is read-only (the only exception is bit 0 if LLB is
5159 supported); the CP0_LLAddr_rw_bitmask does not seem to be
5160 relevant for modern MIPS cores supporting MTHC0, therefore
5161 treating MTHC0 to LLAddr as NOP. */
5174 tcg_gen_andi_tl(arg
, arg
, mask
);
5175 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5186 (void)rn
; /* avoid a compiler warning */
5188 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5191 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
5193 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
5194 tcg_gen_movi_tl(arg
, 0);
5196 tcg_gen_movi_tl(arg
, ~0);
5200 #define CP0_CHECK(c) \
5203 goto cp0_unimplemented; \
5207 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5209 const char *rn
= "invalid";
5212 check_insn(ctx
, ISA_MIPS32
);
5218 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5222 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5223 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5227 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5228 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5232 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5233 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5237 goto cp0_unimplemented
;
5243 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5244 gen_helper_mfc0_random(arg
, cpu_env
);
5248 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5249 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5253 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5254 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5258 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5259 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5263 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5264 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
5268 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5269 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5273 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5274 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5275 rn
= "VPEScheFBack";
5278 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5279 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5283 goto cp0_unimplemented
;
5290 TCGv_i64 tmp
= tcg_temp_new_i64();
5291 tcg_gen_ld_i64(tmp
, cpu_env
,
5292 offsetof(CPUMIPSState
, CP0_EntryLo0
));
5293 #if defined(TARGET_MIPS64)
5295 /* Move RI/XI fields to bits 31:30 */
5296 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
5297 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
5300 gen_move_low32(arg
, tmp
);
5301 tcg_temp_free_i64(tmp
);
5306 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5307 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5311 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5312 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5316 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5317 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
5321 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5322 gen_helper_mfc0_tchalt(arg
, cpu_env
);
5326 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5327 gen_helper_mfc0_tccontext(arg
, cpu_env
);
5331 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5332 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
5336 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5337 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
5341 goto cp0_unimplemented
;
5348 TCGv_i64 tmp
= tcg_temp_new_i64();
5349 tcg_gen_ld_i64(tmp
, cpu_env
,
5350 offsetof(CPUMIPSState
, CP0_EntryLo1
));
5351 #if defined(TARGET_MIPS64)
5353 /* Move RI/XI fields to bits 31:30 */
5354 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
5355 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
5358 gen_move_low32(arg
, tmp
);
5359 tcg_temp_free_i64(tmp
);
5364 goto cp0_unimplemented
;
5370 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5371 tcg_gen_ext32s_tl(arg
, arg
);
5375 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5376 rn
= "ContextConfig";
5377 goto cp0_unimplemented
;
5380 CP0_CHECK(ctx
->ulri
);
5381 tcg_gen_ld32s_tl(arg
, cpu_env
,
5382 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5386 goto cp0_unimplemented
;
5392 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5396 check_insn(ctx
, ISA_MIPS32R2
);
5397 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5401 goto cp0_unimplemented
;
5407 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5411 check_insn(ctx
, ISA_MIPS32R2
);
5412 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5416 check_insn(ctx
, ISA_MIPS32R2
);
5417 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5421 check_insn(ctx
, ISA_MIPS32R2
);
5422 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5426 check_insn(ctx
, ISA_MIPS32R2
);
5427 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5431 check_insn(ctx
, ISA_MIPS32R2
);
5432 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5436 goto cp0_unimplemented
;
5442 check_insn(ctx
, ISA_MIPS32R2
);
5443 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5447 goto cp0_unimplemented
;
5453 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5454 tcg_gen_ext32s_tl(arg
, arg
);
5459 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
5464 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
5468 goto cp0_unimplemented
;
5474 /* Mark as an IO operation because we read the time. */
5475 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5478 gen_helper_mfc0_count(arg
, cpu_env
);
5479 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5482 /* Break the TB to be able to take timer interrupts immediately
5483 after reading count. */
5484 ctx
->bstate
= BS_STOP
;
5487 /* 6,7 are implementation dependent */
5489 goto cp0_unimplemented
;
5495 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5496 tcg_gen_ext32s_tl(arg
, arg
);
5500 goto cp0_unimplemented
;
5506 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5509 /* 6,7 are implementation dependent */
5511 goto cp0_unimplemented
;
5517 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5521 check_insn(ctx
, ISA_MIPS32R2
);
5522 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5526 check_insn(ctx
, ISA_MIPS32R2
);
5527 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5531 check_insn(ctx
, ISA_MIPS32R2
);
5532 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5536 goto cp0_unimplemented
;
5542 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5546 goto cp0_unimplemented
;
5552 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5553 tcg_gen_ext32s_tl(arg
, arg
);
5557 goto cp0_unimplemented
;
5563 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5567 check_insn(ctx
, ISA_MIPS32R2
);
5568 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5572 goto cp0_unimplemented
;
5578 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5582 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5586 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5590 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5594 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
5598 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
5601 /* 6,7 are implementation dependent */
5603 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5607 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5611 goto cp0_unimplemented
;
5617 gen_helper_mfc0_lladdr(arg
, cpu_env
);
5621 goto cp0_unimplemented
;
5627 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
5631 goto cp0_unimplemented
;
5637 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5641 goto cp0_unimplemented
;
5647 #if defined(TARGET_MIPS64)
5648 check_insn(ctx
, ISA_MIPS3
);
5649 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5650 tcg_gen_ext32s_tl(arg
, arg
);
5655 goto cp0_unimplemented
;
5659 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5660 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5663 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5667 goto cp0_unimplemented
;
5671 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5672 rn
= "'Diagnostic"; /* implementation dependent */
5677 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5681 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5682 rn
= "TraceControl";
5685 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5686 rn
= "TraceControl2";
5689 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5690 rn
= "UserTraceData";
5693 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5697 goto cp0_unimplemented
;
5704 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5705 tcg_gen_ext32s_tl(arg
, arg
);
5709 goto cp0_unimplemented
;
5715 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5716 rn
= "Performance0";
5719 // gen_helper_mfc0_performance1(arg);
5720 rn
= "Performance1";
5723 // gen_helper_mfc0_performance2(arg);
5724 rn
= "Performance2";
5727 // gen_helper_mfc0_performance3(arg);
5728 rn
= "Performance3";
5731 // gen_helper_mfc0_performance4(arg);
5732 rn
= "Performance4";
5735 // gen_helper_mfc0_performance5(arg);
5736 rn
= "Performance5";
5739 // gen_helper_mfc0_performance6(arg);
5740 rn
= "Performance6";
5743 // gen_helper_mfc0_performance7(arg);
5744 rn
= "Performance7";
5747 goto cp0_unimplemented
;
5751 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5757 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5761 goto cp0_unimplemented
;
5771 TCGv_i64 tmp
= tcg_temp_new_i64();
5772 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
5773 gen_move_low32(arg
, tmp
);
5774 tcg_temp_free_i64(tmp
);
5782 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5786 goto cp0_unimplemented
;
5795 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5802 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5806 goto cp0_unimplemented
;
5812 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5813 tcg_gen_ext32s_tl(arg
, arg
);
5817 goto cp0_unimplemented
;
5824 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5828 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
5829 tcg_gen_ld_tl(arg
, cpu_env
,
5830 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
5831 tcg_gen_ext32s_tl(arg
, arg
);
5835 goto cp0_unimplemented
;
5839 goto cp0_unimplemented
;
5841 (void)rn
; /* avoid a compiler warning */
5842 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5846 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5847 gen_mfc0_unimplemented(ctx
, arg
);
5850 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5852 const char *rn
= "invalid";
5855 check_insn(ctx
, ISA_MIPS32
);
5857 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5865 gen_helper_mtc0_index(cpu_env
, arg
);
5869 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5870 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5874 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5879 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5884 goto cp0_unimplemented
;
5894 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5895 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5899 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5900 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5904 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5905 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5909 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5910 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5914 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5915 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5919 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5920 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5921 rn
= "VPEScheFBack";
5924 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5925 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5929 goto cp0_unimplemented
;
5935 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5939 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5940 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5944 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5945 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5949 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5950 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5954 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5955 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5959 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5960 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5964 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5965 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5969 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5970 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5974 goto cp0_unimplemented
;
5980 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5984 goto cp0_unimplemented
;
5990 gen_helper_mtc0_context(cpu_env
, arg
);
5994 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5995 rn
= "ContextConfig";
5996 goto cp0_unimplemented
;
5999 CP0_CHECK(ctx
->ulri
);
6000 tcg_gen_st_tl(arg
, cpu_env
,
6001 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6005 goto cp0_unimplemented
;
6011 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6015 check_insn(ctx
, ISA_MIPS32R2
);
6016 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6018 ctx
->bstate
= BS_STOP
;
6021 goto cp0_unimplemented
;
6027 gen_helper_mtc0_wired(cpu_env
, arg
);
6031 check_insn(ctx
, ISA_MIPS32R2
);
6032 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6036 check_insn(ctx
, ISA_MIPS32R2
);
6037 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6041 check_insn(ctx
, ISA_MIPS32R2
);
6042 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6046 check_insn(ctx
, ISA_MIPS32R2
);
6047 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6051 check_insn(ctx
, ISA_MIPS32R2
);
6052 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6056 goto cp0_unimplemented
;
6062 check_insn(ctx
, ISA_MIPS32R2
);
6063 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6064 ctx
->bstate
= BS_STOP
;
6068 goto cp0_unimplemented
;
6086 goto cp0_unimplemented
;
6092 gen_helper_mtc0_count(cpu_env
, arg
);
6095 /* 6,7 are implementation dependent */
6097 goto cp0_unimplemented
;
6103 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6107 goto cp0_unimplemented
;
6113 gen_helper_mtc0_compare(cpu_env
, arg
);
6116 /* 6,7 are implementation dependent */
6118 goto cp0_unimplemented
;
6124 save_cpu_state(ctx
, 1);
6125 gen_helper_mtc0_status(cpu_env
, arg
);
6126 /* BS_STOP isn't good enough here, hflags may have changed. */
6127 gen_save_pc(ctx
->pc
+ 4);
6128 ctx
->bstate
= BS_EXCP
;
6132 check_insn(ctx
, ISA_MIPS32R2
);
6133 gen_helper_mtc0_intctl(cpu_env
, arg
);
6134 /* Stop translation as we may have switched the execution mode */
6135 ctx
->bstate
= BS_STOP
;
6139 check_insn(ctx
, ISA_MIPS32R2
);
6140 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6141 /* Stop translation as we may have switched the execution mode */
6142 ctx
->bstate
= BS_STOP
;
6146 check_insn(ctx
, ISA_MIPS32R2
);
6147 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6148 /* Stop translation as we may have switched the execution mode */
6149 ctx
->bstate
= BS_STOP
;
6153 goto cp0_unimplemented
;
6159 save_cpu_state(ctx
, 1);
6160 gen_helper_mtc0_cause(cpu_env
, arg
);
6164 goto cp0_unimplemented
;
6170 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
6174 goto cp0_unimplemented
;
6184 check_insn(ctx
, ISA_MIPS32R2
);
6185 gen_helper_mtc0_ebase(cpu_env
, arg
);
6189 goto cp0_unimplemented
;
6195 gen_helper_mtc0_config0(cpu_env
, arg
);
6197 /* Stop translation as we may have switched the execution mode */
6198 ctx
->bstate
= BS_STOP
;
6201 /* ignored, read only */
6205 gen_helper_mtc0_config2(cpu_env
, arg
);
6207 /* Stop translation as we may have switched the execution mode */
6208 ctx
->bstate
= BS_STOP
;
6211 gen_helper_mtc0_config3(cpu_env
, arg
);
6213 /* Stop translation as we may have switched the execution mode */
6214 ctx
->bstate
= BS_STOP
;
6217 gen_helper_mtc0_config4(cpu_env
, arg
);
6219 ctx
->bstate
= BS_STOP
;
6222 gen_helper_mtc0_config5(cpu_env
, arg
);
6224 /* Stop translation as we may have switched the execution mode */
6225 ctx
->bstate
= BS_STOP
;
6227 /* 6,7 are implementation dependent */
6237 rn
= "Invalid config selector";
6238 goto cp0_unimplemented
;
6244 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6248 goto cp0_unimplemented
;
6254 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6258 goto cp0_unimplemented
;
6264 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6268 goto cp0_unimplemented
;
6274 #if defined(TARGET_MIPS64)
6275 check_insn(ctx
, ISA_MIPS3
);
6276 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6281 goto cp0_unimplemented
;
6285 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6286 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6289 gen_helper_mtc0_framemask(cpu_env
, arg
);
6293 goto cp0_unimplemented
;
6298 rn
= "Diagnostic"; /* implementation dependent */
6303 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6304 /* BS_STOP isn't good enough here, hflags may have changed. */
6305 gen_save_pc(ctx
->pc
+ 4);
6306 ctx
->bstate
= BS_EXCP
;
6310 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6311 rn
= "TraceControl";
6312 /* Stop translation as we may have switched the execution mode */
6313 ctx
->bstate
= BS_STOP
;
6316 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6317 rn
= "TraceControl2";
6318 /* Stop translation as we may have switched the execution mode */
6319 ctx
->bstate
= BS_STOP
;
6322 /* Stop translation as we may have switched the execution mode */
6323 ctx
->bstate
= BS_STOP
;
6324 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6325 rn
= "UserTraceData";
6326 /* Stop translation as we may have switched the execution mode */
6327 ctx
->bstate
= BS_STOP
;
6330 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6331 /* Stop translation as we may have switched the execution mode */
6332 ctx
->bstate
= BS_STOP
;
6336 goto cp0_unimplemented
;
6343 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
6347 goto cp0_unimplemented
;
6353 gen_helper_mtc0_performance0(cpu_env
, arg
);
6354 rn
= "Performance0";
6357 // gen_helper_mtc0_performance1(arg);
6358 rn
= "Performance1";
6361 // gen_helper_mtc0_performance2(arg);
6362 rn
= "Performance2";
6365 // gen_helper_mtc0_performance3(arg);
6366 rn
= "Performance3";
6369 // gen_helper_mtc0_performance4(arg);
6370 rn
= "Performance4";
6373 // gen_helper_mtc0_performance5(arg);
6374 rn
= "Performance5";
6377 // gen_helper_mtc0_performance6(arg);
6378 rn
= "Performance6";
6381 // gen_helper_mtc0_performance7(arg);
6382 rn
= "Performance7";
6385 goto cp0_unimplemented
;
6399 goto cp0_unimplemented
;
6408 gen_helper_mtc0_taglo(cpu_env
, arg
);
6415 gen_helper_mtc0_datalo(cpu_env
, arg
);
6419 goto cp0_unimplemented
;
6428 gen_helper_mtc0_taghi(cpu_env
, arg
);
6435 gen_helper_mtc0_datahi(cpu_env
, arg
);
6440 goto cp0_unimplemented
;
6446 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6450 goto cp0_unimplemented
;
6457 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6461 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6462 tcg_gen_st_tl(arg
, cpu_env
,
6463 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6467 goto cp0_unimplemented
;
6469 /* Stop translation as we may have switched the execution mode */
6470 ctx
->bstate
= BS_STOP
;
6473 goto cp0_unimplemented
;
6475 (void)rn
; /* avoid a compiler warning */
6476 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6477 /* For simplicity assume that all writes can cause interrupts. */
6478 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6480 ctx
->bstate
= BS_STOP
;
6485 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6488 #if defined(TARGET_MIPS64)
6489 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6491 const char *rn
= "invalid";
6494 check_insn(ctx
, ISA_MIPS64
);
6500 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6504 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6505 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6509 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6510 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6514 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6515 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6519 goto cp0_unimplemented
;
6525 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6526 gen_helper_mfc0_random(arg
, cpu_env
);
6530 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6531 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6535 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6536 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6540 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6541 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6545 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6546 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
6550 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6551 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6555 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6556 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6557 rn
= "VPEScheFBack";
6560 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6561 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6565 goto cp0_unimplemented
;
6571 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6575 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6576 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6580 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6581 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6585 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6586 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
6590 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6591 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
6595 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6596 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
6600 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6601 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
6605 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6606 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
6610 goto cp0_unimplemented
;
6616 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6620 goto cp0_unimplemented
;
6626 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6630 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6631 rn
= "ContextConfig";
6632 goto cp0_unimplemented
;
6635 CP0_CHECK(ctx
->ulri
);
6636 tcg_gen_ld_tl(arg
, cpu_env
,
6637 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6641 goto cp0_unimplemented
;
6647 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6651 check_insn(ctx
, ISA_MIPS32R2
);
6652 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6656 goto cp0_unimplemented
;
6662 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6666 check_insn(ctx
, ISA_MIPS32R2
);
6667 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6671 check_insn(ctx
, ISA_MIPS32R2
);
6672 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6676 check_insn(ctx
, ISA_MIPS32R2
);
6677 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6681 check_insn(ctx
, ISA_MIPS32R2
);
6682 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6686 check_insn(ctx
, ISA_MIPS32R2
);
6687 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6691 goto cp0_unimplemented
;
6697 check_insn(ctx
, ISA_MIPS32R2
);
6698 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6702 goto cp0_unimplemented
;
6708 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6713 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6718 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6722 goto cp0_unimplemented
;
6728 /* Mark as an IO operation because we read the time. */
6729 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6732 gen_helper_mfc0_count(arg
, cpu_env
);
6733 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6736 /* Break the TB to be able to take timer interrupts immediately
6737 after reading count. */
6738 ctx
->bstate
= BS_STOP
;
6741 /* 6,7 are implementation dependent */
6743 goto cp0_unimplemented
;
6749 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6753 goto cp0_unimplemented
;
6759 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6762 /* 6,7 are implementation dependent */
6764 goto cp0_unimplemented
;
6770 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6774 check_insn(ctx
, ISA_MIPS32R2
);
6775 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6779 check_insn(ctx
, ISA_MIPS32R2
);
6780 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6784 check_insn(ctx
, ISA_MIPS32R2
);
6785 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6789 goto cp0_unimplemented
;
6795 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6799 goto cp0_unimplemented
;
6805 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6809 goto cp0_unimplemented
;
6815 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6819 check_insn(ctx
, ISA_MIPS32R2
);
6820 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
6824 goto cp0_unimplemented
;
6830 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6834 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6838 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6842 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6846 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6850 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6853 /* 6,7 are implementation dependent */
6855 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6859 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6863 goto cp0_unimplemented
;
6869 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
6873 goto cp0_unimplemented
;
6879 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
6883 goto cp0_unimplemented
;
6889 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6893 goto cp0_unimplemented
;
6899 check_insn(ctx
, ISA_MIPS3
);
6900 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6904 goto cp0_unimplemented
;
6908 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6909 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6912 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6916 goto cp0_unimplemented
;
6920 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6921 rn
= "'Diagnostic"; /* implementation dependent */
6926 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6930 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6931 rn
= "TraceControl";
6934 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6935 rn
= "TraceControl2";
6938 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6939 rn
= "UserTraceData";
6942 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6946 goto cp0_unimplemented
;
6953 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6957 goto cp0_unimplemented
;
6963 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6964 rn
= "Performance0";
6967 // gen_helper_dmfc0_performance1(arg);
6968 rn
= "Performance1";
6971 // gen_helper_dmfc0_performance2(arg);
6972 rn
= "Performance2";
6975 // gen_helper_dmfc0_performance3(arg);
6976 rn
= "Performance3";
6979 // gen_helper_dmfc0_performance4(arg);
6980 rn
= "Performance4";
6983 // gen_helper_dmfc0_performance5(arg);
6984 rn
= "Performance5";
6987 // gen_helper_dmfc0_performance6(arg);
6988 rn
= "Performance6";
6991 // gen_helper_dmfc0_performance7(arg);
6992 rn
= "Performance7";
6995 goto cp0_unimplemented
;
6999 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7006 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
7010 goto cp0_unimplemented
;
7019 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
7026 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
7030 goto cp0_unimplemented
;
7039 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
7046 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
7050 goto cp0_unimplemented
;
7056 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7060 goto cp0_unimplemented
;
7067 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7071 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7072 tcg_gen_ld_tl(arg
, cpu_env
,
7073 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7077 goto cp0_unimplemented
;
7081 goto cp0_unimplemented
;
7083 (void)rn
; /* avoid a compiler warning */
7084 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7088 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7089 gen_mfc0_unimplemented(ctx
, arg
);
7092 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
7094 const char *rn
= "invalid";
7097 check_insn(ctx
, ISA_MIPS64
);
7099 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7107 gen_helper_mtc0_index(cpu_env
, arg
);
7111 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7112 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
7116 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7121 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7126 goto cp0_unimplemented
;
7136 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7137 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
7141 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7142 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
7146 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7147 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
7151 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7152 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7156 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7157 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7161 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7162 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7163 rn
= "VPEScheFBack";
7166 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7167 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7171 goto cp0_unimplemented
;
7177 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
7181 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7182 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7186 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7187 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7191 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7192 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7196 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7197 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7201 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7202 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7206 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7207 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7211 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7212 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7216 goto cp0_unimplemented
;
7222 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
7226 goto cp0_unimplemented
;
7232 gen_helper_mtc0_context(cpu_env
, arg
);
7236 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7237 rn
= "ContextConfig";
7238 goto cp0_unimplemented
;
7241 CP0_CHECK(ctx
->ulri
);
7242 tcg_gen_st_tl(arg
, cpu_env
,
7243 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7247 goto cp0_unimplemented
;
7253 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7257 check_insn(ctx
, ISA_MIPS32R2
);
7258 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7262 goto cp0_unimplemented
;
7268 gen_helper_mtc0_wired(cpu_env
, arg
);
7272 check_insn(ctx
, ISA_MIPS32R2
);
7273 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7277 check_insn(ctx
, ISA_MIPS32R2
);
7278 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7282 check_insn(ctx
, ISA_MIPS32R2
);
7283 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7287 check_insn(ctx
, ISA_MIPS32R2
);
7288 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7292 check_insn(ctx
, ISA_MIPS32R2
);
7293 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7297 goto cp0_unimplemented
;
7303 check_insn(ctx
, ISA_MIPS32R2
);
7304 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7305 ctx
->bstate
= BS_STOP
;
7309 goto cp0_unimplemented
;
7327 goto cp0_unimplemented
;
7333 gen_helper_mtc0_count(cpu_env
, arg
);
7336 /* 6,7 are implementation dependent */
7338 goto cp0_unimplemented
;
7340 /* Stop translation as we may have switched the execution mode */
7341 ctx
->bstate
= BS_STOP
;
7346 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7350 goto cp0_unimplemented
;
7356 gen_helper_mtc0_compare(cpu_env
, arg
);
7359 /* 6,7 are implementation dependent */
7361 goto cp0_unimplemented
;
7363 /* Stop translation as we may have switched the execution mode */
7364 ctx
->bstate
= BS_STOP
;
7369 save_cpu_state(ctx
, 1);
7370 gen_helper_mtc0_status(cpu_env
, arg
);
7371 /* BS_STOP isn't good enough here, hflags may have changed. */
7372 gen_save_pc(ctx
->pc
+ 4);
7373 ctx
->bstate
= BS_EXCP
;
7377 check_insn(ctx
, ISA_MIPS32R2
);
7378 gen_helper_mtc0_intctl(cpu_env
, arg
);
7379 /* Stop translation as we may have switched the execution mode */
7380 ctx
->bstate
= BS_STOP
;
7384 check_insn(ctx
, ISA_MIPS32R2
);
7385 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7386 /* Stop translation as we may have switched the execution mode */
7387 ctx
->bstate
= BS_STOP
;
7391 check_insn(ctx
, ISA_MIPS32R2
);
7392 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7393 /* Stop translation as we may have switched the execution mode */
7394 ctx
->bstate
= BS_STOP
;
7398 goto cp0_unimplemented
;
7404 save_cpu_state(ctx
, 1);
7405 /* Mark as an IO operation because we may trigger a software
7407 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7410 gen_helper_mtc0_cause(cpu_env
, arg
);
7411 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7414 /* Stop translation as we may have triggered an intetrupt */
7415 ctx
->bstate
= BS_STOP
;
7419 goto cp0_unimplemented
;
7425 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7429 goto cp0_unimplemented
;
7439 check_insn(ctx
, ISA_MIPS32R2
);
7440 gen_helper_mtc0_ebase(cpu_env
, arg
);
7444 goto cp0_unimplemented
;
7450 gen_helper_mtc0_config0(cpu_env
, arg
);
7452 /* Stop translation as we may have switched the execution mode */
7453 ctx
->bstate
= BS_STOP
;
7456 /* ignored, read only */
7460 gen_helper_mtc0_config2(cpu_env
, arg
);
7462 /* Stop translation as we may have switched the execution mode */
7463 ctx
->bstate
= BS_STOP
;
7466 gen_helper_mtc0_config3(cpu_env
, arg
);
7468 /* Stop translation as we may have switched the execution mode */
7469 ctx
->bstate
= BS_STOP
;
7472 /* currently ignored */
7476 gen_helper_mtc0_config5(cpu_env
, arg
);
7478 /* Stop translation as we may have switched the execution mode */
7479 ctx
->bstate
= BS_STOP
;
7481 /* 6,7 are implementation dependent */
7483 rn
= "Invalid config selector";
7484 goto cp0_unimplemented
;
7490 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7494 goto cp0_unimplemented
;
7500 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7504 goto cp0_unimplemented
;
7510 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7514 goto cp0_unimplemented
;
7520 check_insn(ctx
, ISA_MIPS3
);
7521 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7525 goto cp0_unimplemented
;
7529 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7530 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7533 gen_helper_mtc0_framemask(cpu_env
, arg
);
7537 goto cp0_unimplemented
;
7542 rn
= "Diagnostic"; /* implementation dependent */
7547 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7548 /* BS_STOP isn't good enough here, hflags may have changed. */
7549 gen_save_pc(ctx
->pc
+ 4);
7550 ctx
->bstate
= BS_EXCP
;
7554 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7555 /* Stop translation as we may have switched the execution mode */
7556 ctx
->bstate
= BS_STOP
;
7557 rn
= "TraceControl";
7560 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7561 /* Stop translation as we may have switched the execution mode */
7562 ctx
->bstate
= BS_STOP
;
7563 rn
= "TraceControl2";
7566 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7567 /* Stop translation as we may have switched the execution mode */
7568 ctx
->bstate
= BS_STOP
;
7569 rn
= "UserTraceData";
7572 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7573 /* Stop translation as we may have switched the execution mode */
7574 ctx
->bstate
= BS_STOP
;
7578 goto cp0_unimplemented
;
7585 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7589 goto cp0_unimplemented
;
7595 gen_helper_mtc0_performance0(cpu_env
, arg
);
7596 rn
= "Performance0";
7599 // gen_helper_mtc0_performance1(cpu_env, arg);
7600 rn
= "Performance1";
7603 // gen_helper_mtc0_performance2(cpu_env, arg);
7604 rn
= "Performance2";
7607 // gen_helper_mtc0_performance3(cpu_env, arg);
7608 rn
= "Performance3";
7611 // gen_helper_mtc0_performance4(cpu_env, arg);
7612 rn
= "Performance4";
7615 // gen_helper_mtc0_performance5(cpu_env, arg);
7616 rn
= "Performance5";
7619 // gen_helper_mtc0_performance6(cpu_env, arg);
7620 rn
= "Performance6";
7623 // gen_helper_mtc0_performance7(cpu_env, arg);
7624 rn
= "Performance7";
7627 goto cp0_unimplemented
;
7641 goto cp0_unimplemented
;
7650 gen_helper_mtc0_taglo(cpu_env
, arg
);
7657 gen_helper_mtc0_datalo(cpu_env
, arg
);
7661 goto cp0_unimplemented
;
7670 gen_helper_mtc0_taghi(cpu_env
, arg
);
7677 gen_helper_mtc0_datahi(cpu_env
, arg
);
7682 goto cp0_unimplemented
;
7688 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7692 goto cp0_unimplemented
;
7699 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7703 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7704 tcg_gen_st_tl(arg
, cpu_env
,
7705 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7709 goto cp0_unimplemented
;
7711 /* Stop translation as we may have switched the execution mode */
7712 ctx
->bstate
= BS_STOP
;
7715 goto cp0_unimplemented
;
7717 (void)rn
; /* avoid a compiler warning */
7718 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7719 /* For simplicity assume that all writes can cause interrupts. */
7720 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7722 ctx
->bstate
= BS_STOP
;
7727 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7729 #endif /* TARGET_MIPS64 */
7731 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
7732 int u
, int sel
, int h
)
7734 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7735 TCGv t0
= tcg_temp_local_new();
7737 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7738 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7739 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7740 tcg_gen_movi_tl(t0
, -1);
7741 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7742 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7743 tcg_gen_movi_tl(t0
, -1);
7749 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
7752 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
7762 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
7765 gen_helper_mftc0_tcbind(t0
, cpu_env
);
7768 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
7771 gen_helper_mftc0_tchalt(t0
, cpu_env
);
7774 gen_helper_mftc0_tccontext(t0
, cpu_env
);
7777 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
7780 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
7783 gen_mfc0(ctx
, t0
, rt
, sel
);
7790 gen_helper_mftc0_entryhi(t0
, cpu_env
);
7793 gen_mfc0(ctx
, t0
, rt
, sel
);
7799 gen_helper_mftc0_status(t0
, cpu_env
);
7802 gen_mfc0(ctx
, t0
, rt
, sel
);
7808 gen_helper_mftc0_cause(t0
, cpu_env
);
7818 gen_helper_mftc0_epc(t0
, cpu_env
);
7828 gen_helper_mftc0_ebase(t0
, cpu_env
);
7838 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
7848 gen_helper_mftc0_debug(t0
, cpu_env
);
7851 gen_mfc0(ctx
, t0
, rt
, sel
);
7856 gen_mfc0(ctx
, t0
, rt
, sel
);
7858 } else switch (sel
) {
7859 /* GPR registers. */
7861 gen_helper_1e0i(mftgpr
, t0
, rt
);
7863 /* Auxiliary CPU registers */
7867 gen_helper_1e0i(mftlo
, t0
, 0);
7870 gen_helper_1e0i(mfthi
, t0
, 0);
7873 gen_helper_1e0i(mftacx
, t0
, 0);
7876 gen_helper_1e0i(mftlo
, t0
, 1);
7879 gen_helper_1e0i(mfthi
, t0
, 1);
7882 gen_helper_1e0i(mftacx
, t0
, 1);
7885 gen_helper_1e0i(mftlo
, t0
, 2);
7888 gen_helper_1e0i(mfthi
, t0
, 2);
7891 gen_helper_1e0i(mftacx
, t0
, 2);
7894 gen_helper_1e0i(mftlo
, t0
, 3);
7897 gen_helper_1e0i(mfthi
, t0
, 3);
7900 gen_helper_1e0i(mftacx
, t0
, 3);
7903 gen_helper_mftdsp(t0
, cpu_env
);
7909 /* Floating point (COP1). */
7911 /* XXX: For now we support only a single FPU context. */
7913 TCGv_i32 fp0
= tcg_temp_new_i32();
7915 gen_load_fpr32(ctx
, fp0
, rt
);
7916 tcg_gen_ext_i32_tl(t0
, fp0
);
7917 tcg_temp_free_i32(fp0
);
7919 TCGv_i32 fp0
= tcg_temp_new_i32();
7921 gen_load_fpr32h(ctx
, fp0
, rt
);
7922 tcg_gen_ext_i32_tl(t0
, fp0
);
7923 tcg_temp_free_i32(fp0
);
7927 /* XXX: For now we support only a single FPU context. */
7928 gen_helper_1e0i(cfc1
, t0
, rt
);
7930 /* COP2: Not implemented. */
7937 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7938 gen_store_gpr(t0
, rd
);
7944 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7945 generate_exception(ctx
, EXCP_RI
);
7948 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
7949 int u
, int sel
, int h
)
7951 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7952 TCGv t0
= tcg_temp_local_new();
7954 gen_load_gpr(t0
, rt
);
7955 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7956 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7957 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7959 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7960 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7967 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
7970 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
7980 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
7983 gen_helper_mttc0_tcbind(cpu_env
, t0
);
7986 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
7989 gen_helper_mttc0_tchalt(cpu_env
, t0
);
7992 gen_helper_mttc0_tccontext(cpu_env
, t0
);
7995 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
7998 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
8001 gen_mtc0(ctx
, t0
, rd
, sel
);
8008 gen_helper_mttc0_entryhi(cpu_env
, t0
);
8011 gen_mtc0(ctx
, t0
, rd
, sel
);
8017 gen_helper_mttc0_status(cpu_env
, t0
);
8020 gen_mtc0(ctx
, t0
, rd
, sel
);
8026 gen_helper_mttc0_cause(cpu_env
, t0
);
8036 gen_helper_mttc0_ebase(cpu_env
, t0
);
8046 gen_helper_mttc0_debug(cpu_env
, t0
);
8049 gen_mtc0(ctx
, t0
, rd
, sel
);
8054 gen_mtc0(ctx
, t0
, rd
, sel
);
8056 } else switch (sel
) {
8057 /* GPR registers. */
8059 gen_helper_0e1i(mttgpr
, t0
, rd
);
8061 /* Auxiliary CPU registers */
8065 gen_helper_0e1i(mttlo
, t0
, 0);
8068 gen_helper_0e1i(mtthi
, t0
, 0);
8071 gen_helper_0e1i(mttacx
, t0
, 0);
8074 gen_helper_0e1i(mttlo
, t0
, 1);
8077 gen_helper_0e1i(mtthi
, t0
, 1);
8080 gen_helper_0e1i(mttacx
, t0
, 1);
8083 gen_helper_0e1i(mttlo
, t0
, 2);
8086 gen_helper_0e1i(mtthi
, t0
, 2);
8089 gen_helper_0e1i(mttacx
, t0
, 2);
8092 gen_helper_0e1i(mttlo
, t0
, 3);
8095 gen_helper_0e1i(mtthi
, t0
, 3);
8098 gen_helper_0e1i(mttacx
, t0
, 3);
8101 gen_helper_mttdsp(cpu_env
, t0
);
8107 /* Floating point (COP1). */
8109 /* XXX: For now we support only a single FPU context. */
8111 TCGv_i32 fp0
= tcg_temp_new_i32();
8113 tcg_gen_trunc_tl_i32(fp0
, t0
);
8114 gen_store_fpr32(ctx
, fp0
, rd
);
8115 tcg_temp_free_i32(fp0
);
8117 TCGv_i32 fp0
= tcg_temp_new_i32();
8119 tcg_gen_trunc_tl_i32(fp0
, t0
);
8120 gen_store_fpr32h(ctx
, fp0
, rd
);
8121 tcg_temp_free_i32(fp0
);
8125 /* XXX: For now we support only a single FPU context. */
8126 save_cpu_state(ctx
, 1);
8128 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
8130 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8131 tcg_temp_free_i32(fs_tmp
);
8133 /* Stop translation as we may have changed hflags */
8134 ctx
->bstate
= BS_STOP
;
8136 /* COP2: Not implemented. */
8143 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
8149 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
8150 generate_exception(ctx
, EXCP_RI
);
8153 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
8155 const char *opn
= "ldst";
8157 check_cp0_enabled(ctx
);
8164 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8169 TCGv t0
= tcg_temp_new();
8171 gen_load_gpr(t0
, rt
);
8172 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8177 #if defined(TARGET_MIPS64)
8179 check_insn(ctx
, ISA_MIPS3
);
8184 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8188 check_insn(ctx
, ISA_MIPS3
);
8190 TCGv t0
= tcg_temp_new();
8192 gen_load_gpr(t0
, rt
);
8193 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8205 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8211 TCGv t0
= tcg_temp_new();
8212 gen_load_gpr(t0
, rt
);
8213 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8219 check_insn(ctx
, ASE_MT
);
8224 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
8225 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
8229 check_insn(ctx
, ASE_MT
);
8230 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
8231 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
8236 if (!env
->tlb
->helper_tlbwi
)
8238 gen_helper_tlbwi(cpu_env
);
8243 if (!env
->tlb
->helper_tlbinv
) {
8246 gen_helper_tlbinv(cpu_env
);
8247 } /* treat as nop if TLBINV not supported */
8252 if (!env
->tlb
->helper_tlbinvf
) {
8255 gen_helper_tlbinvf(cpu_env
);
8256 } /* treat as nop if TLBINV not supported */
8260 if (!env
->tlb
->helper_tlbwr
)
8262 gen_helper_tlbwr(cpu_env
);
8266 if (!env
->tlb
->helper_tlbp
)
8268 gen_helper_tlbp(cpu_env
);
8272 if (!env
->tlb
->helper_tlbr
)
8274 gen_helper_tlbr(cpu_env
);
8276 case OPC_ERET
: /* OPC_ERETNC */
8277 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8278 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8279 MIPS_DEBUG("CTI in delay / forbidden slot");
8282 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
8283 if (ctx
->opcode
& (1 << bit_shift
)) {
8286 check_insn(ctx
, ISA_MIPS32R5
);
8287 gen_helper_eretnc(cpu_env
);
8291 check_insn(ctx
, ISA_MIPS2
);
8292 gen_helper_eret(cpu_env
);
8294 ctx
->bstate
= BS_EXCP
;
8299 check_insn(ctx
, ISA_MIPS32
);
8300 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8301 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8302 MIPS_DEBUG("CTI in delay / forbidden slot");
8305 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
8307 generate_exception(ctx
, EXCP_RI
);
8309 gen_helper_deret(cpu_env
);
8310 ctx
->bstate
= BS_EXCP
;
8315 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
8316 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8317 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8318 MIPS_DEBUG("CTI in delay / forbidden slot");
8321 /* If we get an exception, we want to restart at next instruction */
8323 save_cpu_state(ctx
, 1);
8325 gen_helper_wait(cpu_env
);
8326 ctx
->bstate
= BS_EXCP
;
8331 generate_exception(ctx
, EXCP_RI
);
8334 (void)opn
; /* avoid a compiler warning */
8335 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
8337 #endif /* !CONFIG_USER_ONLY */
8339 /* CP1 Branches (before delay slot) */
8340 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
8341 int32_t cc
, int32_t offset
)
8343 target_ulong btarget
;
8344 const char *opn
= "cp1 cond branch";
8345 TCGv_i32 t0
= tcg_temp_new_i32();
8347 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8348 MIPS_DEBUG("CTI in delay / forbidden slot");
8349 generate_exception(ctx
, EXCP_RI
);
8354 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
8356 btarget
= ctx
->pc
+ 4 + offset
;
8360 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8361 tcg_gen_not_i32(t0
, t0
);
8362 tcg_gen_andi_i32(t0
, t0
, 1);
8363 tcg_gen_extu_i32_tl(bcond
, t0
);
8367 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8368 tcg_gen_not_i32(t0
, t0
);
8369 tcg_gen_andi_i32(t0
, t0
, 1);
8370 tcg_gen_extu_i32_tl(bcond
, t0
);
8374 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8375 tcg_gen_andi_i32(t0
, t0
, 1);
8376 tcg_gen_extu_i32_tl(bcond
, t0
);
8380 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8381 tcg_gen_andi_i32(t0
, t0
, 1);
8382 tcg_gen_extu_i32_tl(bcond
, t0
);
8385 ctx
->hflags
|= MIPS_HFLAG_BL
;
8389 TCGv_i32 t1
= tcg_temp_new_i32();
8390 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8391 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8392 tcg_gen_nand_i32(t0
, t0
, t1
);
8393 tcg_temp_free_i32(t1
);
8394 tcg_gen_andi_i32(t0
, t0
, 1);
8395 tcg_gen_extu_i32_tl(bcond
, t0
);
8401 TCGv_i32 t1
= tcg_temp_new_i32();
8402 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8403 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8404 tcg_gen_or_i32(t0
, t0
, t1
);
8405 tcg_temp_free_i32(t1
);
8406 tcg_gen_andi_i32(t0
, t0
, 1);
8407 tcg_gen_extu_i32_tl(bcond
, t0
);
8413 TCGv_i32 t1
= tcg_temp_new_i32();
8414 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8415 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8416 tcg_gen_and_i32(t0
, t0
, t1
);
8417 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8418 tcg_gen_and_i32(t0
, t0
, t1
);
8419 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8420 tcg_gen_nand_i32(t0
, t0
, t1
);
8421 tcg_temp_free_i32(t1
);
8422 tcg_gen_andi_i32(t0
, t0
, 1);
8423 tcg_gen_extu_i32_tl(bcond
, t0
);
8429 TCGv_i32 t1
= tcg_temp_new_i32();
8430 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8431 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8432 tcg_gen_or_i32(t0
, t0
, t1
);
8433 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8434 tcg_gen_or_i32(t0
, t0
, t1
);
8435 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8436 tcg_gen_or_i32(t0
, t0
, t1
);
8437 tcg_temp_free_i32(t1
);
8438 tcg_gen_andi_i32(t0
, t0
, 1);
8439 tcg_gen_extu_i32_tl(bcond
, t0
);
8443 ctx
->hflags
|= MIPS_HFLAG_BC
;
8447 generate_exception (ctx
, EXCP_RI
);
8450 (void)opn
; /* avoid a compiler warning */
8451 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
8452 ctx
->hflags
, btarget
);
8453 ctx
->btarget
= btarget
;
8454 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8456 tcg_temp_free_i32(t0
);
8459 /* R6 CP1 Branches */
8460 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
8461 int32_t ft
, int32_t offset
,
8464 target_ulong btarget
;
8465 const char *opn
= "cp1 cond branch";
8466 TCGv_i64 t0
= tcg_temp_new_i64();
8468 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
8469 #ifdef MIPS_DEBUG_DISAS
8470 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8473 generate_exception(ctx
, EXCP_RI
);
8477 gen_load_fpr64(ctx
, t0
, ft
);
8478 tcg_gen_andi_i64(t0
, t0
, 1);
8480 btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
8484 tcg_gen_xori_i64(t0
, t0
, 1);
8486 ctx
->hflags
|= MIPS_HFLAG_BC
;
8489 /* t0 already set */
8491 ctx
->hflags
|= MIPS_HFLAG_BC
;
8495 generate_exception(ctx
, EXCP_RI
);
8499 tcg_gen_trunc_i64_tl(bcond
, t0
);
8501 (void)opn
; /* avoid a compiler warning */
8502 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
8503 ctx
->hflags
, btarget
);
8504 ctx
->btarget
= btarget
;
8506 switch (delayslot_size
) {
8508 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
8511 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8516 tcg_temp_free_i64(t0
);
8519 /* Coprocessor 1 (FPU) */
8521 #define FOP(func, fmt) (((fmt) << 21) | (func))
8524 OPC_ADD_S
= FOP(0, FMT_S
),
8525 OPC_SUB_S
= FOP(1, FMT_S
),
8526 OPC_MUL_S
= FOP(2, FMT_S
),
8527 OPC_DIV_S
= FOP(3, FMT_S
),
8528 OPC_SQRT_S
= FOP(4, FMT_S
),
8529 OPC_ABS_S
= FOP(5, FMT_S
),
8530 OPC_MOV_S
= FOP(6, FMT_S
),
8531 OPC_NEG_S
= FOP(7, FMT_S
),
8532 OPC_ROUND_L_S
= FOP(8, FMT_S
),
8533 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
8534 OPC_CEIL_L_S
= FOP(10, FMT_S
),
8535 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
8536 OPC_ROUND_W_S
= FOP(12, FMT_S
),
8537 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
8538 OPC_CEIL_W_S
= FOP(14, FMT_S
),
8539 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
8540 OPC_SEL_S
= FOP(16, FMT_S
),
8541 OPC_MOVCF_S
= FOP(17, FMT_S
),
8542 OPC_MOVZ_S
= FOP(18, FMT_S
),
8543 OPC_MOVN_S
= FOP(19, FMT_S
),
8544 OPC_SELEQZ_S
= FOP(20, FMT_S
),
8545 OPC_RECIP_S
= FOP(21, FMT_S
),
8546 OPC_RSQRT_S
= FOP(22, FMT_S
),
8547 OPC_SELNEZ_S
= FOP(23, FMT_S
),
8548 OPC_MADDF_S
= FOP(24, FMT_S
),
8549 OPC_MSUBF_S
= FOP(25, FMT_S
),
8550 OPC_RINT_S
= FOP(26, FMT_S
),
8551 OPC_CLASS_S
= FOP(27, FMT_S
),
8552 OPC_MIN_S
= FOP(28, FMT_S
),
8553 OPC_RECIP2_S
= FOP(28, FMT_S
),
8554 OPC_MINA_S
= FOP(29, FMT_S
),
8555 OPC_RECIP1_S
= FOP(29, FMT_S
),
8556 OPC_MAX_S
= FOP(30, FMT_S
),
8557 OPC_RSQRT1_S
= FOP(30, FMT_S
),
8558 OPC_MAXA_S
= FOP(31, FMT_S
),
8559 OPC_RSQRT2_S
= FOP(31, FMT_S
),
8560 OPC_CVT_D_S
= FOP(33, FMT_S
),
8561 OPC_CVT_W_S
= FOP(36, FMT_S
),
8562 OPC_CVT_L_S
= FOP(37, FMT_S
),
8563 OPC_CVT_PS_S
= FOP(38, FMT_S
),
8564 OPC_CMP_F_S
= FOP (48, FMT_S
),
8565 OPC_CMP_UN_S
= FOP (49, FMT_S
),
8566 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
8567 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
8568 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
8569 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
8570 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
8571 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
8572 OPC_CMP_SF_S
= FOP (56, FMT_S
),
8573 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
8574 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
8575 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
8576 OPC_CMP_LT_S
= FOP (60, FMT_S
),
8577 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
8578 OPC_CMP_LE_S
= FOP (62, FMT_S
),
8579 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
8581 OPC_ADD_D
= FOP(0, FMT_D
),
8582 OPC_SUB_D
= FOP(1, FMT_D
),
8583 OPC_MUL_D
= FOP(2, FMT_D
),
8584 OPC_DIV_D
= FOP(3, FMT_D
),
8585 OPC_SQRT_D
= FOP(4, FMT_D
),
8586 OPC_ABS_D
= FOP(5, FMT_D
),
8587 OPC_MOV_D
= FOP(6, FMT_D
),
8588 OPC_NEG_D
= FOP(7, FMT_D
),
8589 OPC_ROUND_L_D
= FOP(8, FMT_D
),
8590 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
8591 OPC_CEIL_L_D
= FOP(10, FMT_D
),
8592 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
8593 OPC_ROUND_W_D
= FOP(12, FMT_D
),
8594 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
8595 OPC_CEIL_W_D
= FOP(14, FMT_D
),
8596 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
8597 OPC_SEL_D
= FOP(16, FMT_D
),
8598 OPC_MOVCF_D
= FOP(17, FMT_D
),
8599 OPC_MOVZ_D
= FOP(18, FMT_D
),
8600 OPC_MOVN_D
= FOP(19, FMT_D
),
8601 OPC_SELEQZ_D
= FOP(20, FMT_D
),
8602 OPC_RECIP_D
= FOP(21, FMT_D
),
8603 OPC_RSQRT_D
= FOP(22, FMT_D
),
8604 OPC_SELNEZ_D
= FOP(23, FMT_D
),
8605 OPC_MADDF_D
= FOP(24, FMT_D
),
8606 OPC_MSUBF_D
= FOP(25, FMT_D
),
8607 OPC_RINT_D
= FOP(26, FMT_D
),
8608 OPC_CLASS_D
= FOP(27, FMT_D
),
8609 OPC_MIN_D
= FOP(28, FMT_D
),
8610 OPC_RECIP2_D
= FOP(28, FMT_D
),
8611 OPC_MINA_D
= FOP(29, FMT_D
),
8612 OPC_RECIP1_D
= FOP(29, FMT_D
),
8613 OPC_MAX_D
= FOP(30, FMT_D
),
8614 OPC_RSQRT1_D
= FOP(30, FMT_D
),
8615 OPC_MAXA_D
= FOP(31, FMT_D
),
8616 OPC_RSQRT2_D
= FOP(31, FMT_D
),
8617 OPC_CVT_S_D
= FOP(32, FMT_D
),
8618 OPC_CVT_W_D
= FOP(36, FMT_D
),
8619 OPC_CVT_L_D
= FOP(37, FMT_D
),
8620 OPC_CMP_F_D
= FOP (48, FMT_D
),
8621 OPC_CMP_UN_D
= FOP (49, FMT_D
),
8622 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
8623 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
8624 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
8625 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
8626 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
8627 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
8628 OPC_CMP_SF_D
= FOP (56, FMT_D
),
8629 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
8630 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
8631 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
8632 OPC_CMP_LT_D
= FOP (60, FMT_D
),
8633 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
8634 OPC_CMP_LE_D
= FOP (62, FMT_D
),
8635 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
8637 OPC_CVT_S_W
= FOP(32, FMT_W
),
8638 OPC_CVT_D_W
= FOP(33, FMT_W
),
8639 OPC_CVT_S_L
= FOP(32, FMT_L
),
8640 OPC_CVT_D_L
= FOP(33, FMT_L
),
8641 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
8643 OPC_ADD_PS
= FOP(0, FMT_PS
),
8644 OPC_SUB_PS
= FOP(1, FMT_PS
),
8645 OPC_MUL_PS
= FOP(2, FMT_PS
),
8646 OPC_DIV_PS
= FOP(3, FMT_PS
),
8647 OPC_ABS_PS
= FOP(5, FMT_PS
),
8648 OPC_MOV_PS
= FOP(6, FMT_PS
),
8649 OPC_NEG_PS
= FOP(7, FMT_PS
),
8650 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
8651 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
8652 OPC_MOVN_PS
= FOP(19, FMT_PS
),
8653 OPC_ADDR_PS
= FOP(24, FMT_PS
),
8654 OPC_MULR_PS
= FOP(26, FMT_PS
),
8655 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
8656 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
8657 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
8658 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
8660 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
8661 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
8662 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
8663 OPC_PLL_PS
= FOP(44, FMT_PS
),
8664 OPC_PLU_PS
= FOP(45, FMT_PS
),
8665 OPC_PUL_PS
= FOP(46, FMT_PS
),
8666 OPC_PUU_PS
= FOP(47, FMT_PS
),
8667 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
8668 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
8669 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
8670 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
8671 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
8672 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
8673 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
8674 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
8675 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
8676 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
8677 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
8678 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
8679 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
8680 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
8681 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
8682 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
8686 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
8687 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
8688 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
8689 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
8690 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
8691 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
8692 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
8693 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
8694 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
8695 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
8696 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
8697 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
8698 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
8699 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
8700 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
8701 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
8702 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
8703 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
8704 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
8705 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
8706 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
8707 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
8709 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
8710 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
8711 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
8712 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
8713 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
8714 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
8715 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
8716 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
8717 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
8718 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
8719 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
8720 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
8721 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
8722 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
8723 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
8724 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
8725 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
8726 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
8727 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
8728 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
8729 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
8730 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
8732 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
8734 const char *opn
= "cp1 move";
8735 TCGv t0
= tcg_temp_new();
8740 TCGv_i32 fp0
= tcg_temp_new_i32();
8742 gen_load_fpr32(ctx
, fp0
, fs
);
8743 tcg_gen_ext_i32_tl(t0
, fp0
);
8744 tcg_temp_free_i32(fp0
);
8746 gen_store_gpr(t0
, rt
);
8750 gen_load_gpr(t0
, rt
);
8752 TCGv_i32 fp0
= tcg_temp_new_i32();
8754 tcg_gen_trunc_tl_i32(fp0
, t0
);
8755 gen_store_fpr32(ctx
, fp0
, fs
);
8756 tcg_temp_free_i32(fp0
);
8761 gen_helper_1e0i(cfc1
, t0
, fs
);
8762 gen_store_gpr(t0
, rt
);
8766 gen_load_gpr(t0
, rt
);
8767 save_cpu_state(ctx
, 1);
8769 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
8771 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8772 tcg_temp_free_i32(fs_tmp
);
8774 /* Stop translation as we may have changed hflags */
8775 ctx
->bstate
= BS_STOP
;
8778 #if defined(TARGET_MIPS64)
8780 gen_load_fpr64(ctx
, t0
, fs
);
8781 gen_store_gpr(t0
, rt
);
8785 gen_load_gpr(t0
, rt
);
8786 gen_store_fpr64(ctx
, t0
, fs
);
8792 TCGv_i32 fp0
= tcg_temp_new_i32();
8794 gen_load_fpr32h(ctx
, fp0
, fs
);
8795 tcg_gen_ext_i32_tl(t0
, fp0
);
8796 tcg_temp_free_i32(fp0
);
8798 gen_store_gpr(t0
, rt
);
8802 gen_load_gpr(t0
, rt
);
8804 TCGv_i32 fp0
= tcg_temp_new_i32();
8806 tcg_gen_trunc_tl_i32(fp0
, t0
);
8807 gen_store_fpr32h(ctx
, fp0
, fs
);
8808 tcg_temp_free_i32(fp0
);
8814 generate_exception (ctx
, EXCP_RI
);
8817 (void)opn
; /* avoid a compiler warning */
8818 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
8824 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
8840 l1
= gen_new_label();
8841 t0
= tcg_temp_new_i32();
8842 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8843 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8844 tcg_temp_free_i32(t0
);
8846 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
8848 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
8853 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
8857 TCGv_i32 t0
= tcg_temp_new_i32();
8858 TCGLabel
*l1
= gen_new_label();
8865 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8866 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8867 gen_load_fpr32(ctx
, t0
, fs
);
8868 gen_store_fpr32(ctx
, t0
, fd
);
8870 tcg_temp_free_i32(t0
);
8873 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
8876 TCGv_i32 t0
= tcg_temp_new_i32();
8878 TCGLabel
*l1
= gen_new_label();
8885 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8886 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8887 tcg_temp_free_i32(t0
);
8888 fp0
= tcg_temp_new_i64();
8889 gen_load_fpr64(ctx
, fp0
, fs
);
8890 gen_store_fpr64(ctx
, fp0
, fd
);
8891 tcg_temp_free_i64(fp0
);
8895 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
8899 TCGv_i32 t0
= tcg_temp_new_i32();
8900 TCGLabel
*l1
= gen_new_label();
8901 TCGLabel
*l2
= gen_new_label();
8908 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8909 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8910 gen_load_fpr32(ctx
, t0
, fs
);
8911 gen_store_fpr32(ctx
, t0
, fd
);
8914 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
8915 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
8916 gen_load_fpr32h(ctx
, t0
, fs
);
8917 gen_store_fpr32h(ctx
, t0
, fd
);
8918 tcg_temp_free_i32(t0
);
8922 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8925 TCGv_i32 t1
= tcg_const_i32(0);
8926 TCGv_i32 fp0
= tcg_temp_new_i32();
8927 TCGv_i32 fp1
= tcg_temp_new_i32();
8928 TCGv_i32 fp2
= tcg_temp_new_i32();
8929 gen_load_fpr32(ctx
, fp0
, fd
);
8930 gen_load_fpr32(ctx
, fp1
, ft
);
8931 gen_load_fpr32(ctx
, fp2
, fs
);
8935 tcg_gen_andi_i32(fp0
, fp0
, 1);
8936 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8939 tcg_gen_andi_i32(fp1
, fp1
, 1);
8940 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8943 tcg_gen_andi_i32(fp1
, fp1
, 1);
8944 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8947 MIPS_INVAL("gen_sel_s");
8948 generate_exception (ctx
, EXCP_RI
);
8952 gen_store_fpr32(ctx
, fp0
, fd
);
8953 tcg_temp_free_i32(fp2
);
8954 tcg_temp_free_i32(fp1
);
8955 tcg_temp_free_i32(fp0
);
8956 tcg_temp_free_i32(t1
);
8959 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8962 TCGv_i64 t1
= tcg_const_i64(0);
8963 TCGv_i64 fp0
= tcg_temp_new_i64();
8964 TCGv_i64 fp1
= tcg_temp_new_i64();
8965 TCGv_i64 fp2
= tcg_temp_new_i64();
8966 gen_load_fpr64(ctx
, fp0
, fd
);
8967 gen_load_fpr64(ctx
, fp1
, ft
);
8968 gen_load_fpr64(ctx
, fp2
, fs
);
8972 tcg_gen_andi_i64(fp0
, fp0
, 1);
8973 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8976 tcg_gen_andi_i64(fp1
, fp1
, 1);
8977 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8980 tcg_gen_andi_i64(fp1
, fp1
, 1);
8981 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8984 MIPS_INVAL("gen_sel_d");
8985 generate_exception (ctx
, EXCP_RI
);
8989 gen_store_fpr64(ctx
, fp0
, fd
);
8990 tcg_temp_free_i64(fp2
);
8991 tcg_temp_free_i64(fp1
);
8992 tcg_temp_free_i64(fp0
);
8993 tcg_temp_free_i64(t1
);
8996 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
8997 int ft
, int fs
, int fd
, int cc
)
8999 const char *opn
= "farith";
9000 const char *condnames
[] = {
9018 const char *condnames_abs
[] = {
9036 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
9037 uint32_t func
= ctx
->opcode
& 0x3f;
9041 TCGv_i32 fp0
= tcg_temp_new_i32();
9042 TCGv_i32 fp1
= tcg_temp_new_i32();
9044 gen_load_fpr32(ctx
, fp0
, fs
);
9045 gen_load_fpr32(ctx
, fp1
, ft
);
9046 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
9047 tcg_temp_free_i32(fp1
);
9048 gen_store_fpr32(ctx
, fp0
, fd
);
9049 tcg_temp_free_i32(fp0
);
9056 TCGv_i32 fp0
= tcg_temp_new_i32();
9057 TCGv_i32 fp1
= tcg_temp_new_i32();
9059 gen_load_fpr32(ctx
, fp0
, fs
);
9060 gen_load_fpr32(ctx
, fp1
, ft
);
9061 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
9062 tcg_temp_free_i32(fp1
);
9063 gen_store_fpr32(ctx
, fp0
, fd
);
9064 tcg_temp_free_i32(fp0
);
9071 TCGv_i32 fp0
= tcg_temp_new_i32();
9072 TCGv_i32 fp1
= tcg_temp_new_i32();
9074 gen_load_fpr32(ctx
, fp0
, fs
);
9075 gen_load_fpr32(ctx
, fp1
, ft
);
9076 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
9077 tcg_temp_free_i32(fp1
);
9078 gen_store_fpr32(ctx
, fp0
, fd
);
9079 tcg_temp_free_i32(fp0
);
9086 TCGv_i32 fp0
= tcg_temp_new_i32();
9087 TCGv_i32 fp1
= tcg_temp_new_i32();
9089 gen_load_fpr32(ctx
, fp0
, fs
);
9090 gen_load_fpr32(ctx
, fp1
, ft
);
9091 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
9092 tcg_temp_free_i32(fp1
);
9093 gen_store_fpr32(ctx
, fp0
, fd
);
9094 tcg_temp_free_i32(fp0
);
9101 TCGv_i32 fp0
= tcg_temp_new_i32();
9103 gen_load_fpr32(ctx
, fp0
, fs
);
9104 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
9105 gen_store_fpr32(ctx
, fp0
, fd
);
9106 tcg_temp_free_i32(fp0
);
9112 TCGv_i32 fp0
= tcg_temp_new_i32();
9114 gen_load_fpr32(ctx
, fp0
, fs
);
9115 gen_helper_float_abs_s(fp0
, fp0
);
9116 gen_store_fpr32(ctx
, fp0
, fd
);
9117 tcg_temp_free_i32(fp0
);
9123 TCGv_i32 fp0
= tcg_temp_new_i32();
9125 gen_load_fpr32(ctx
, fp0
, fs
);
9126 gen_store_fpr32(ctx
, fp0
, fd
);
9127 tcg_temp_free_i32(fp0
);
9133 TCGv_i32 fp0
= tcg_temp_new_i32();
9135 gen_load_fpr32(ctx
, fp0
, fs
);
9136 gen_helper_float_chs_s(fp0
, fp0
);
9137 gen_store_fpr32(ctx
, fp0
, fd
);
9138 tcg_temp_free_i32(fp0
);
9143 check_cp1_64bitmode(ctx
);
9145 TCGv_i32 fp32
= tcg_temp_new_i32();
9146 TCGv_i64 fp64
= tcg_temp_new_i64();
9148 gen_load_fpr32(ctx
, fp32
, fs
);
9149 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
9150 tcg_temp_free_i32(fp32
);
9151 gen_store_fpr64(ctx
, fp64
, fd
);
9152 tcg_temp_free_i64(fp64
);
9157 check_cp1_64bitmode(ctx
);
9159 TCGv_i32 fp32
= tcg_temp_new_i32();
9160 TCGv_i64 fp64
= tcg_temp_new_i64();
9162 gen_load_fpr32(ctx
, fp32
, fs
);
9163 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
9164 tcg_temp_free_i32(fp32
);
9165 gen_store_fpr64(ctx
, fp64
, fd
);
9166 tcg_temp_free_i64(fp64
);
9171 check_cp1_64bitmode(ctx
);
9173 TCGv_i32 fp32
= tcg_temp_new_i32();
9174 TCGv_i64 fp64
= tcg_temp_new_i64();
9176 gen_load_fpr32(ctx
, fp32
, fs
);
9177 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
9178 tcg_temp_free_i32(fp32
);
9179 gen_store_fpr64(ctx
, fp64
, fd
);
9180 tcg_temp_free_i64(fp64
);
9185 check_cp1_64bitmode(ctx
);
9187 TCGv_i32 fp32
= tcg_temp_new_i32();
9188 TCGv_i64 fp64
= tcg_temp_new_i64();
9190 gen_load_fpr32(ctx
, fp32
, fs
);
9191 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
9192 tcg_temp_free_i32(fp32
);
9193 gen_store_fpr64(ctx
, fp64
, fd
);
9194 tcg_temp_free_i64(fp64
);
9200 TCGv_i32 fp0
= tcg_temp_new_i32();
9202 gen_load_fpr32(ctx
, fp0
, fs
);
9203 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
9204 gen_store_fpr32(ctx
, fp0
, fd
);
9205 tcg_temp_free_i32(fp0
);
9211 TCGv_i32 fp0
= tcg_temp_new_i32();
9213 gen_load_fpr32(ctx
, fp0
, fs
);
9214 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
9215 gen_store_fpr32(ctx
, fp0
, fd
);
9216 tcg_temp_free_i32(fp0
);
9222 TCGv_i32 fp0
= tcg_temp_new_i32();
9224 gen_load_fpr32(ctx
, fp0
, fs
);
9225 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
9226 gen_store_fpr32(ctx
, fp0
, fd
);
9227 tcg_temp_free_i32(fp0
);
9233 TCGv_i32 fp0
= tcg_temp_new_i32();
9235 gen_load_fpr32(ctx
, fp0
, fs
);
9236 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
9237 gen_store_fpr32(ctx
, fp0
, fd
);
9238 tcg_temp_free_i32(fp0
);
9243 check_insn(ctx
, ISA_MIPS32R6
);
9244 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9248 check_insn(ctx
, ISA_MIPS32R6
);
9249 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9253 check_insn(ctx
, ISA_MIPS32R6
);
9254 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9258 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9259 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9263 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9265 TCGLabel
*l1
= gen_new_label();
9269 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9271 fp0
= tcg_temp_new_i32();
9272 gen_load_fpr32(ctx
, fp0
, fs
);
9273 gen_store_fpr32(ctx
, fp0
, fd
);
9274 tcg_temp_free_i32(fp0
);
9280 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9282 TCGLabel
*l1
= gen_new_label();
9286 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9287 fp0
= tcg_temp_new_i32();
9288 gen_load_fpr32(ctx
, fp0
, fs
);
9289 gen_store_fpr32(ctx
, fp0
, fd
);
9290 tcg_temp_free_i32(fp0
);
9299 TCGv_i32 fp0
= tcg_temp_new_i32();
9301 gen_load_fpr32(ctx
, fp0
, fs
);
9302 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
9303 gen_store_fpr32(ctx
, fp0
, fd
);
9304 tcg_temp_free_i32(fp0
);
9311 TCGv_i32 fp0
= tcg_temp_new_i32();
9313 gen_load_fpr32(ctx
, fp0
, fs
);
9314 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
9315 gen_store_fpr32(ctx
, fp0
, fd
);
9316 tcg_temp_free_i32(fp0
);
9321 check_insn(ctx
, ISA_MIPS32R6
);
9323 TCGv_i32 fp0
= tcg_temp_new_i32();
9324 TCGv_i32 fp1
= tcg_temp_new_i32();
9325 TCGv_i32 fp2
= tcg_temp_new_i32();
9326 gen_load_fpr32(ctx
, fp0
, fs
);
9327 gen_load_fpr32(ctx
, fp1
, ft
);
9328 gen_load_fpr32(ctx
, fp2
, fd
);
9329 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9330 gen_store_fpr32(ctx
, fp2
, fd
);
9331 tcg_temp_free_i32(fp2
);
9332 tcg_temp_free_i32(fp1
);
9333 tcg_temp_free_i32(fp0
);
9338 check_insn(ctx
, ISA_MIPS32R6
);
9340 TCGv_i32 fp0
= tcg_temp_new_i32();
9341 TCGv_i32 fp1
= tcg_temp_new_i32();
9342 TCGv_i32 fp2
= tcg_temp_new_i32();
9343 gen_load_fpr32(ctx
, fp0
, fs
);
9344 gen_load_fpr32(ctx
, fp1
, ft
);
9345 gen_load_fpr32(ctx
, fp2
, fd
);
9346 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9347 gen_store_fpr32(ctx
, fp2
, fd
);
9348 tcg_temp_free_i32(fp2
);
9349 tcg_temp_free_i32(fp1
);
9350 tcg_temp_free_i32(fp0
);
9355 check_insn(ctx
, ISA_MIPS32R6
);
9357 TCGv_i32 fp0
= tcg_temp_new_i32();
9358 gen_load_fpr32(ctx
, fp0
, fs
);
9359 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
9360 gen_store_fpr32(ctx
, fp0
, fd
);
9361 tcg_temp_free_i32(fp0
);
9366 check_insn(ctx
, ISA_MIPS32R6
);
9368 TCGv_i32 fp0
= tcg_temp_new_i32();
9369 gen_load_fpr32(ctx
, fp0
, fs
);
9370 gen_helper_float_class_s(fp0
, fp0
);
9371 gen_store_fpr32(ctx
, fp0
, fd
);
9372 tcg_temp_free_i32(fp0
);
9376 case OPC_MIN_S
: /* OPC_RECIP2_S */
9377 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9379 TCGv_i32 fp0
= tcg_temp_new_i32();
9380 TCGv_i32 fp1
= tcg_temp_new_i32();
9381 TCGv_i32 fp2
= tcg_temp_new_i32();
9382 gen_load_fpr32(ctx
, fp0
, fs
);
9383 gen_load_fpr32(ctx
, fp1
, ft
);
9384 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
9385 gen_store_fpr32(ctx
, fp2
, fd
);
9386 tcg_temp_free_i32(fp2
);
9387 tcg_temp_free_i32(fp1
);
9388 tcg_temp_free_i32(fp0
);
9392 check_cp1_64bitmode(ctx
);
9394 TCGv_i32 fp0
= tcg_temp_new_i32();
9395 TCGv_i32 fp1
= tcg_temp_new_i32();
9397 gen_load_fpr32(ctx
, fp0
, fs
);
9398 gen_load_fpr32(ctx
, fp1
, ft
);
9399 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
9400 tcg_temp_free_i32(fp1
);
9401 gen_store_fpr32(ctx
, fp0
, fd
);
9402 tcg_temp_free_i32(fp0
);
9407 case OPC_MINA_S
: /* OPC_RECIP1_S */
9408 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9410 TCGv_i32 fp0
= tcg_temp_new_i32();
9411 TCGv_i32 fp1
= tcg_temp_new_i32();
9412 TCGv_i32 fp2
= tcg_temp_new_i32();
9413 gen_load_fpr32(ctx
, fp0
, fs
);
9414 gen_load_fpr32(ctx
, fp1
, ft
);
9415 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
9416 gen_store_fpr32(ctx
, fp2
, fd
);
9417 tcg_temp_free_i32(fp2
);
9418 tcg_temp_free_i32(fp1
);
9419 tcg_temp_free_i32(fp0
);
9423 check_cp1_64bitmode(ctx
);
9425 TCGv_i32 fp0
= tcg_temp_new_i32();
9427 gen_load_fpr32(ctx
, fp0
, fs
);
9428 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
9429 gen_store_fpr32(ctx
, fp0
, fd
);
9430 tcg_temp_free_i32(fp0
);
9435 case OPC_MAX_S
: /* OPC_RSQRT1_S */
9436 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9438 TCGv_i32 fp0
= tcg_temp_new_i32();
9439 TCGv_i32 fp1
= tcg_temp_new_i32();
9440 gen_load_fpr32(ctx
, fp0
, fs
);
9441 gen_load_fpr32(ctx
, fp1
, ft
);
9442 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
9443 gen_store_fpr32(ctx
, fp1
, fd
);
9444 tcg_temp_free_i32(fp1
);
9445 tcg_temp_free_i32(fp0
);
9449 check_cp1_64bitmode(ctx
);
9451 TCGv_i32 fp0
= tcg_temp_new_i32();
9453 gen_load_fpr32(ctx
, fp0
, fs
);
9454 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
9455 gen_store_fpr32(ctx
, fp0
, fd
);
9456 tcg_temp_free_i32(fp0
);
9461 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
9462 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9464 TCGv_i32 fp0
= tcg_temp_new_i32();
9465 TCGv_i32 fp1
= tcg_temp_new_i32();
9466 gen_load_fpr32(ctx
, fp0
, fs
);
9467 gen_load_fpr32(ctx
, fp1
, ft
);
9468 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
9469 gen_store_fpr32(ctx
, fp1
, fd
);
9470 tcg_temp_free_i32(fp1
);
9471 tcg_temp_free_i32(fp0
);
9475 check_cp1_64bitmode(ctx
);
9477 TCGv_i32 fp0
= tcg_temp_new_i32();
9478 TCGv_i32 fp1
= tcg_temp_new_i32();
9480 gen_load_fpr32(ctx
, fp0
, fs
);
9481 gen_load_fpr32(ctx
, fp1
, ft
);
9482 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
9483 tcg_temp_free_i32(fp1
);
9484 gen_store_fpr32(ctx
, fp0
, fd
);
9485 tcg_temp_free_i32(fp0
);
9491 check_cp1_registers(ctx
, fd
);
9493 TCGv_i32 fp32
= tcg_temp_new_i32();
9494 TCGv_i64 fp64
= tcg_temp_new_i64();
9496 gen_load_fpr32(ctx
, fp32
, fs
);
9497 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
9498 tcg_temp_free_i32(fp32
);
9499 gen_store_fpr64(ctx
, fp64
, fd
);
9500 tcg_temp_free_i64(fp64
);
9506 TCGv_i32 fp0
= tcg_temp_new_i32();
9508 gen_load_fpr32(ctx
, fp0
, fs
);
9509 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
9510 gen_store_fpr32(ctx
, fp0
, fd
);
9511 tcg_temp_free_i32(fp0
);
9516 check_cp1_64bitmode(ctx
);
9518 TCGv_i32 fp32
= tcg_temp_new_i32();
9519 TCGv_i64 fp64
= tcg_temp_new_i64();
9521 gen_load_fpr32(ctx
, fp32
, fs
);
9522 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
9523 tcg_temp_free_i32(fp32
);
9524 gen_store_fpr64(ctx
, fp64
, fd
);
9525 tcg_temp_free_i64(fp64
);
9532 TCGv_i64 fp64
= tcg_temp_new_i64();
9533 TCGv_i32 fp32_0
= tcg_temp_new_i32();
9534 TCGv_i32 fp32_1
= tcg_temp_new_i32();
9536 gen_load_fpr32(ctx
, fp32_0
, fs
);
9537 gen_load_fpr32(ctx
, fp32_1
, ft
);
9538 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
9539 tcg_temp_free_i32(fp32_1
);
9540 tcg_temp_free_i32(fp32_0
);
9541 gen_store_fpr64(ctx
, fp64
, fd
);
9542 tcg_temp_free_i64(fp64
);
9555 case OPC_CMP_NGLE_S
:
9562 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9563 if (ctx
->opcode
& (1 << 6)) {
9564 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
9565 opn
= condnames_abs
[func
-48];
9567 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
9568 opn
= condnames
[func
-48];
9573 check_cp1_registers(ctx
, fs
| ft
| fd
);
9575 TCGv_i64 fp0
= tcg_temp_new_i64();
9576 TCGv_i64 fp1
= tcg_temp_new_i64();
9578 gen_load_fpr64(ctx
, fp0
, fs
);
9579 gen_load_fpr64(ctx
, fp1
, ft
);
9580 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
9581 tcg_temp_free_i64(fp1
);
9582 gen_store_fpr64(ctx
, fp0
, fd
);
9583 tcg_temp_free_i64(fp0
);
9589 check_cp1_registers(ctx
, fs
| ft
| fd
);
9591 TCGv_i64 fp0
= tcg_temp_new_i64();
9592 TCGv_i64 fp1
= tcg_temp_new_i64();
9594 gen_load_fpr64(ctx
, fp0
, fs
);
9595 gen_load_fpr64(ctx
, fp1
, ft
);
9596 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
9597 tcg_temp_free_i64(fp1
);
9598 gen_store_fpr64(ctx
, fp0
, fd
);
9599 tcg_temp_free_i64(fp0
);
9605 check_cp1_registers(ctx
, fs
| ft
| fd
);
9607 TCGv_i64 fp0
= tcg_temp_new_i64();
9608 TCGv_i64 fp1
= tcg_temp_new_i64();
9610 gen_load_fpr64(ctx
, fp0
, fs
);
9611 gen_load_fpr64(ctx
, fp1
, ft
);
9612 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
9613 tcg_temp_free_i64(fp1
);
9614 gen_store_fpr64(ctx
, fp0
, fd
);
9615 tcg_temp_free_i64(fp0
);
9621 check_cp1_registers(ctx
, fs
| ft
| fd
);
9623 TCGv_i64 fp0
= tcg_temp_new_i64();
9624 TCGv_i64 fp1
= tcg_temp_new_i64();
9626 gen_load_fpr64(ctx
, fp0
, fs
);
9627 gen_load_fpr64(ctx
, fp1
, ft
);
9628 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
9629 tcg_temp_free_i64(fp1
);
9630 gen_store_fpr64(ctx
, fp0
, fd
);
9631 tcg_temp_free_i64(fp0
);
9637 check_cp1_registers(ctx
, fs
| fd
);
9639 TCGv_i64 fp0
= tcg_temp_new_i64();
9641 gen_load_fpr64(ctx
, fp0
, fs
);
9642 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
9643 gen_store_fpr64(ctx
, fp0
, fd
);
9644 tcg_temp_free_i64(fp0
);
9649 check_cp1_registers(ctx
, fs
| fd
);
9651 TCGv_i64 fp0
= tcg_temp_new_i64();
9653 gen_load_fpr64(ctx
, fp0
, fs
);
9654 gen_helper_float_abs_d(fp0
, fp0
);
9655 gen_store_fpr64(ctx
, fp0
, fd
);
9656 tcg_temp_free_i64(fp0
);
9661 check_cp1_registers(ctx
, fs
| fd
);
9663 TCGv_i64 fp0
= tcg_temp_new_i64();
9665 gen_load_fpr64(ctx
, fp0
, fs
);
9666 gen_store_fpr64(ctx
, fp0
, fd
);
9667 tcg_temp_free_i64(fp0
);
9672 check_cp1_registers(ctx
, fs
| fd
);
9674 TCGv_i64 fp0
= tcg_temp_new_i64();
9676 gen_load_fpr64(ctx
, fp0
, fs
);
9677 gen_helper_float_chs_d(fp0
, fp0
);
9678 gen_store_fpr64(ctx
, fp0
, fd
);
9679 tcg_temp_free_i64(fp0
);
9684 check_cp1_64bitmode(ctx
);
9686 TCGv_i64 fp0
= tcg_temp_new_i64();
9688 gen_load_fpr64(ctx
, fp0
, fs
);
9689 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
9690 gen_store_fpr64(ctx
, fp0
, fd
);
9691 tcg_temp_free_i64(fp0
);
9696 check_cp1_64bitmode(ctx
);
9698 TCGv_i64 fp0
= tcg_temp_new_i64();
9700 gen_load_fpr64(ctx
, fp0
, fs
);
9701 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
9702 gen_store_fpr64(ctx
, fp0
, fd
);
9703 tcg_temp_free_i64(fp0
);
9708 check_cp1_64bitmode(ctx
);
9710 TCGv_i64 fp0
= tcg_temp_new_i64();
9712 gen_load_fpr64(ctx
, fp0
, fs
);
9713 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
9714 gen_store_fpr64(ctx
, fp0
, fd
);
9715 tcg_temp_free_i64(fp0
);
9720 check_cp1_64bitmode(ctx
);
9722 TCGv_i64 fp0
= tcg_temp_new_i64();
9724 gen_load_fpr64(ctx
, fp0
, fs
);
9725 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
9726 gen_store_fpr64(ctx
, fp0
, fd
);
9727 tcg_temp_free_i64(fp0
);
9732 check_cp1_registers(ctx
, fs
);
9734 TCGv_i32 fp32
= tcg_temp_new_i32();
9735 TCGv_i64 fp64
= tcg_temp_new_i64();
9737 gen_load_fpr64(ctx
, fp64
, fs
);
9738 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
9739 tcg_temp_free_i64(fp64
);
9740 gen_store_fpr32(ctx
, fp32
, fd
);
9741 tcg_temp_free_i32(fp32
);
9746 check_cp1_registers(ctx
, fs
);
9748 TCGv_i32 fp32
= tcg_temp_new_i32();
9749 TCGv_i64 fp64
= tcg_temp_new_i64();
9751 gen_load_fpr64(ctx
, fp64
, fs
);
9752 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
9753 tcg_temp_free_i64(fp64
);
9754 gen_store_fpr32(ctx
, fp32
, fd
);
9755 tcg_temp_free_i32(fp32
);
9760 check_cp1_registers(ctx
, fs
);
9762 TCGv_i32 fp32
= tcg_temp_new_i32();
9763 TCGv_i64 fp64
= tcg_temp_new_i64();
9765 gen_load_fpr64(ctx
, fp64
, fs
);
9766 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
9767 tcg_temp_free_i64(fp64
);
9768 gen_store_fpr32(ctx
, fp32
, fd
);
9769 tcg_temp_free_i32(fp32
);
9774 check_cp1_registers(ctx
, fs
);
9776 TCGv_i32 fp32
= tcg_temp_new_i32();
9777 TCGv_i64 fp64
= tcg_temp_new_i64();
9779 gen_load_fpr64(ctx
, fp64
, fs
);
9780 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
9781 tcg_temp_free_i64(fp64
);
9782 gen_store_fpr32(ctx
, fp32
, fd
);
9783 tcg_temp_free_i32(fp32
);
9788 check_insn(ctx
, ISA_MIPS32R6
);
9789 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9793 check_insn(ctx
, ISA_MIPS32R6
);
9794 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9798 check_insn(ctx
, ISA_MIPS32R6
);
9799 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9803 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9804 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9808 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9810 TCGLabel
*l1
= gen_new_label();
9814 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9816 fp0
= tcg_temp_new_i64();
9817 gen_load_fpr64(ctx
, fp0
, fs
);
9818 gen_store_fpr64(ctx
, fp0
, fd
);
9819 tcg_temp_free_i64(fp0
);
9825 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9827 TCGLabel
*l1
= gen_new_label();
9831 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9832 fp0
= tcg_temp_new_i64();
9833 gen_load_fpr64(ctx
, fp0
, fs
);
9834 gen_store_fpr64(ctx
, fp0
, fd
);
9835 tcg_temp_free_i64(fp0
);
9842 check_cp1_64bitmode(ctx
);
9844 TCGv_i64 fp0
= tcg_temp_new_i64();
9846 gen_load_fpr64(ctx
, fp0
, fs
);
9847 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
9848 gen_store_fpr64(ctx
, fp0
, fd
);
9849 tcg_temp_free_i64(fp0
);
9854 check_cp1_64bitmode(ctx
);
9856 TCGv_i64 fp0
= tcg_temp_new_i64();
9858 gen_load_fpr64(ctx
, fp0
, fs
);
9859 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
9860 gen_store_fpr64(ctx
, fp0
, fd
);
9861 tcg_temp_free_i64(fp0
);
9866 check_insn(ctx
, ISA_MIPS32R6
);
9868 TCGv_i64 fp0
= tcg_temp_new_i64();
9869 TCGv_i64 fp1
= tcg_temp_new_i64();
9870 TCGv_i64 fp2
= tcg_temp_new_i64();
9871 gen_load_fpr64(ctx
, fp0
, fs
);
9872 gen_load_fpr64(ctx
, fp1
, ft
);
9873 gen_load_fpr64(ctx
, fp2
, fd
);
9874 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9875 gen_store_fpr64(ctx
, fp2
, fd
);
9876 tcg_temp_free_i64(fp2
);
9877 tcg_temp_free_i64(fp1
);
9878 tcg_temp_free_i64(fp0
);
9883 check_insn(ctx
, ISA_MIPS32R6
);
9885 TCGv_i64 fp0
= tcg_temp_new_i64();
9886 TCGv_i64 fp1
= tcg_temp_new_i64();
9887 TCGv_i64 fp2
= tcg_temp_new_i64();
9888 gen_load_fpr64(ctx
, fp0
, fs
);
9889 gen_load_fpr64(ctx
, fp1
, ft
);
9890 gen_load_fpr64(ctx
, fp2
, fd
);
9891 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9892 gen_store_fpr64(ctx
, fp2
, fd
);
9893 tcg_temp_free_i64(fp2
);
9894 tcg_temp_free_i64(fp1
);
9895 tcg_temp_free_i64(fp0
);
9900 check_insn(ctx
, ISA_MIPS32R6
);
9902 TCGv_i64 fp0
= tcg_temp_new_i64();
9903 gen_load_fpr64(ctx
, fp0
, fs
);
9904 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
9905 gen_store_fpr64(ctx
, fp0
, fd
);
9906 tcg_temp_free_i64(fp0
);
9911 check_insn(ctx
, ISA_MIPS32R6
);
9913 TCGv_i64 fp0
= tcg_temp_new_i64();
9914 gen_load_fpr64(ctx
, fp0
, fs
);
9915 gen_helper_float_class_d(fp0
, fp0
);
9916 gen_store_fpr64(ctx
, fp0
, fd
);
9917 tcg_temp_free_i64(fp0
);
9921 case OPC_MIN_D
: /* OPC_RECIP2_D */
9922 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9924 TCGv_i64 fp0
= tcg_temp_new_i64();
9925 TCGv_i64 fp1
= tcg_temp_new_i64();
9926 gen_load_fpr64(ctx
, fp0
, fs
);
9927 gen_load_fpr64(ctx
, fp1
, ft
);
9928 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
9929 gen_store_fpr64(ctx
, fp1
, fd
);
9930 tcg_temp_free_i64(fp1
);
9931 tcg_temp_free_i64(fp0
);
9935 check_cp1_64bitmode(ctx
);
9937 TCGv_i64 fp0
= tcg_temp_new_i64();
9938 TCGv_i64 fp1
= tcg_temp_new_i64();
9940 gen_load_fpr64(ctx
, fp0
, fs
);
9941 gen_load_fpr64(ctx
, fp1
, ft
);
9942 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
9943 tcg_temp_free_i64(fp1
);
9944 gen_store_fpr64(ctx
, fp0
, fd
);
9945 tcg_temp_free_i64(fp0
);
9950 case OPC_MINA_D
: /* OPC_RECIP1_D */
9951 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9953 TCGv_i64 fp0
= tcg_temp_new_i64();
9954 TCGv_i64 fp1
= tcg_temp_new_i64();
9955 gen_load_fpr64(ctx
, fp0
, fs
);
9956 gen_load_fpr64(ctx
, fp1
, ft
);
9957 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
9958 gen_store_fpr64(ctx
, fp1
, fd
);
9959 tcg_temp_free_i64(fp1
);
9960 tcg_temp_free_i64(fp0
);
9964 check_cp1_64bitmode(ctx
);
9966 TCGv_i64 fp0
= tcg_temp_new_i64();
9968 gen_load_fpr64(ctx
, fp0
, fs
);
9969 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
9970 gen_store_fpr64(ctx
, fp0
, fd
);
9971 tcg_temp_free_i64(fp0
);
9976 case OPC_MAX_D
: /* OPC_RSQRT1_D */
9977 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9979 TCGv_i64 fp0
= tcg_temp_new_i64();
9980 TCGv_i64 fp1
= tcg_temp_new_i64();
9981 gen_load_fpr64(ctx
, fp0
, fs
);
9982 gen_load_fpr64(ctx
, fp1
, ft
);
9983 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
9984 gen_store_fpr64(ctx
, fp1
, fd
);
9985 tcg_temp_free_i64(fp1
);
9986 tcg_temp_free_i64(fp0
);
9990 check_cp1_64bitmode(ctx
);
9992 TCGv_i64 fp0
= tcg_temp_new_i64();
9994 gen_load_fpr64(ctx
, fp0
, fs
);
9995 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
9996 gen_store_fpr64(ctx
, fp0
, fd
);
9997 tcg_temp_free_i64(fp0
);
10002 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
10003 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
10005 TCGv_i64 fp0
= tcg_temp_new_i64();
10006 TCGv_i64 fp1
= tcg_temp_new_i64();
10007 gen_load_fpr64(ctx
, fp0
, fs
);
10008 gen_load_fpr64(ctx
, fp1
, ft
);
10009 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
10010 gen_store_fpr64(ctx
, fp1
, fd
);
10011 tcg_temp_free_i64(fp1
);
10012 tcg_temp_free_i64(fp0
);
10016 check_cp1_64bitmode(ctx
);
10018 TCGv_i64 fp0
= tcg_temp_new_i64();
10019 TCGv_i64 fp1
= tcg_temp_new_i64();
10021 gen_load_fpr64(ctx
, fp0
, fs
);
10022 gen_load_fpr64(ctx
, fp1
, ft
);
10023 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
10024 tcg_temp_free_i64(fp1
);
10025 gen_store_fpr64(ctx
, fp0
, fd
);
10026 tcg_temp_free_i64(fp0
);
10034 case OPC_CMP_UEQ_D
:
10035 case OPC_CMP_OLT_D
:
10036 case OPC_CMP_ULT_D
:
10037 case OPC_CMP_OLE_D
:
10038 case OPC_CMP_ULE_D
:
10040 case OPC_CMP_NGLE_D
:
10041 case OPC_CMP_SEQ_D
:
10042 case OPC_CMP_NGL_D
:
10044 case OPC_CMP_NGE_D
:
10046 case OPC_CMP_NGT_D
:
10047 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
10048 if (ctx
->opcode
& (1 << 6)) {
10049 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
10050 opn
= condnames_abs
[func
-48];
10052 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
10053 opn
= condnames
[func
-48];
10058 check_cp1_registers(ctx
, fs
);
10060 TCGv_i32 fp32
= tcg_temp_new_i32();
10061 TCGv_i64 fp64
= tcg_temp_new_i64();
10063 gen_load_fpr64(ctx
, fp64
, fs
);
10064 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
10065 tcg_temp_free_i64(fp64
);
10066 gen_store_fpr32(ctx
, fp32
, fd
);
10067 tcg_temp_free_i32(fp32
);
10072 check_cp1_registers(ctx
, fs
);
10074 TCGv_i32 fp32
= tcg_temp_new_i32();
10075 TCGv_i64 fp64
= tcg_temp_new_i64();
10077 gen_load_fpr64(ctx
, fp64
, fs
);
10078 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
10079 tcg_temp_free_i64(fp64
);
10080 gen_store_fpr32(ctx
, fp32
, fd
);
10081 tcg_temp_free_i32(fp32
);
10086 check_cp1_64bitmode(ctx
);
10088 TCGv_i64 fp0
= tcg_temp_new_i64();
10090 gen_load_fpr64(ctx
, fp0
, fs
);
10091 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
10092 gen_store_fpr64(ctx
, fp0
, fd
);
10093 tcg_temp_free_i64(fp0
);
10099 TCGv_i32 fp0
= tcg_temp_new_i32();
10101 gen_load_fpr32(ctx
, fp0
, fs
);
10102 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
10103 gen_store_fpr32(ctx
, fp0
, fd
);
10104 tcg_temp_free_i32(fp0
);
10109 check_cp1_registers(ctx
, fd
);
10111 TCGv_i32 fp32
= tcg_temp_new_i32();
10112 TCGv_i64 fp64
= tcg_temp_new_i64();
10114 gen_load_fpr32(ctx
, fp32
, fs
);
10115 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
10116 tcg_temp_free_i32(fp32
);
10117 gen_store_fpr64(ctx
, fp64
, fd
);
10118 tcg_temp_free_i64(fp64
);
10123 check_cp1_64bitmode(ctx
);
10125 TCGv_i32 fp32
= tcg_temp_new_i32();
10126 TCGv_i64 fp64
= tcg_temp_new_i64();
10128 gen_load_fpr64(ctx
, fp64
, fs
);
10129 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
10130 tcg_temp_free_i64(fp64
);
10131 gen_store_fpr32(ctx
, fp32
, fd
);
10132 tcg_temp_free_i32(fp32
);
10137 check_cp1_64bitmode(ctx
);
10139 TCGv_i64 fp0
= tcg_temp_new_i64();
10141 gen_load_fpr64(ctx
, fp0
, fs
);
10142 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
10143 gen_store_fpr64(ctx
, fp0
, fd
);
10144 tcg_temp_free_i64(fp0
);
10148 case OPC_CVT_PS_PW
:
10151 TCGv_i64 fp0
= tcg_temp_new_i64();
10153 gen_load_fpr64(ctx
, fp0
, fs
);
10154 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
10155 gen_store_fpr64(ctx
, fp0
, fd
);
10156 tcg_temp_free_i64(fp0
);
10163 TCGv_i64 fp0
= tcg_temp_new_i64();
10164 TCGv_i64 fp1
= tcg_temp_new_i64();
10166 gen_load_fpr64(ctx
, fp0
, fs
);
10167 gen_load_fpr64(ctx
, fp1
, ft
);
10168 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
10169 tcg_temp_free_i64(fp1
);
10170 gen_store_fpr64(ctx
, fp0
, fd
);
10171 tcg_temp_free_i64(fp0
);
10178 TCGv_i64 fp0
= tcg_temp_new_i64();
10179 TCGv_i64 fp1
= tcg_temp_new_i64();
10181 gen_load_fpr64(ctx
, fp0
, fs
);
10182 gen_load_fpr64(ctx
, fp1
, ft
);
10183 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
10184 tcg_temp_free_i64(fp1
);
10185 gen_store_fpr64(ctx
, fp0
, fd
);
10186 tcg_temp_free_i64(fp0
);
10193 TCGv_i64 fp0
= tcg_temp_new_i64();
10194 TCGv_i64 fp1
= tcg_temp_new_i64();
10196 gen_load_fpr64(ctx
, fp0
, fs
);
10197 gen_load_fpr64(ctx
, fp1
, ft
);
10198 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
10199 tcg_temp_free_i64(fp1
);
10200 gen_store_fpr64(ctx
, fp0
, fd
);
10201 tcg_temp_free_i64(fp0
);
10208 TCGv_i64 fp0
= tcg_temp_new_i64();
10210 gen_load_fpr64(ctx
, fp0
, fs
);
10211 gen_helper_float_abs_ps(fp0
, fp0
);
10212 gen_store_fpr64(ctx
, fp0
, fd
);
10213 tcg_temp_free_i64(fp0
);
10220 TCGv_i64 fp0
= tcg_temp_new_i64();
10222 gen_load_fpr64(ctx
, fp0
, fs
);
10223 gen_store_fpr64(ctx
, fp0
, fd
);
10224 tcg_temp_free_i64(fp0
);
10231 TCGv_i64 fp0
= tcg_temp_new_i64();
10233 gen_load_fpr64(ctx
, fp0
, fs
);
10234 gen_helper_float_chs_ps(fp0
, fp0
);
10235 gen_store_fpr64(ctx
, fp0
, fd
);
10236 tcg_temp_free_i64(fp0
);
10242 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10248 TCGLabel
*l1
= gen_new_label();
10252 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10253 fp0
= tcg_temp_new_i64();
10254 gen_load_fpr64(ctx
, fp0
, fs
);
10255 gen_store_fpr64(ctx
, fp0
, fd
);
10256 tcg_temp_free_i64(fp0
);
10264 TCGLabel
*l1
= gen_new_label();
10268 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10269 fp0
= tcg_temp_new_i64();
10270 gen_load_fpr64(ctx
, fp0
, fs
);
10271 gen_store_fpr64(ctx
, fp0
, fd
);
10272 tcg_temp_free_i64(fp0
);
10281 TCGv_i64 fp0
= tcg_temp_new_i64();
10282 TCGv_i64 fp1
= tcg_temp_new_i64();
10284 gen_load_fpr64(ctx
, fp0
, ft
);
10285 gen_load_fpr64(ctx
, fp1
, fs
);
10286 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
10287 tcg_temp_free_i64(fp1
);
10288 gen_store_fpr64(ctx
, fp0
, fd
);
10289 tcg_temp_free_i64(fp0
);
10296 TCGv_i64 fp0
= tcg_temp_new_i64();
10297 TCGv_i64 fp1
= tcg_temp_new_i64();
10299 gen_load_fpr64(ctx
, fp0
, ft
);
10300 gen_load_fpr64(ctx
, fp1
, fs
);
10301 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
10302 tcg_temp_free_i64(fp1
);
10303 gen_store_fpr64(ctx
, fp0
, fd
);
10304 tcg_temp_free_i64(fp0
);
10308 case OPC_RECIP2_PS
:
10311 TCGv_i64 fp0
= tcg_temp_new_i64();
10312 TCGv_i64 fp1
= tcg_temp_new_i64();
10314 gen_load_fpr64(ctx
, fp0
, fs
);
10315 gen_load_fpr64(ctx
, fp1
, ft
);
10316 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
10317 tcg_temp_free_i64(fp1
);
10318 gen_store_fpr64(ctx
, fp0
, fd
);
10319 tcg_temp_free_i64(fp0
);
10323 case OPC_RECIP1_PS
:
10326 TCGv_i64 fp0
= tcg_temp_new_i64();
10328 gen_load_fpr64(ctx
, fp0
, fs
);
10329 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
10330 gen_store_fpr64(ctx
, fp0
, fd
);
10331 tcg_temp_free_i64(fp0
);
10335 case OPC_RSQRT1_PS
:
10338 TCGv_i64 fp0
= tcg_temp_new_i64();
10340 gen_load_fpr64(ctx
, fp0
, fs
);
10341 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
10342 gen_store_fpr64(ctx
, fp0
, fd
);
10343 tcg_temp_free_i64(fp0
);
10347 case OPC_RSQRT2_PS
:
10350 TCGv_i64 fp0
= tcg_temp_new_i64();
10351 TCGv_i64 fp1
= tcg_temp_new_i64();
10353 gen_load_fpr64(ctx
, fp0
, fs
);
10354 gen_load_fpr64(ctx
, fp1
, ft
);
10355 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
10356 tcg_temp_free_i64(fp1
);
10357 gen_store_fpr64(ctx
, fp0
, fd
);
10358 tcg_temp_free_i64(fp0
);
10363 check_cp1_64bitmode(ctx
);
10365 TCGv_i32 fp0
= tcg_temp_new_i32();
10367 gen_load_fpr32h(ctx
, fp0
, fs
);
10368 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
10369 gen_store_fpr32(ctx
, fp0
, fd
);
10370 tcg_temp_free_i32(fp0
);
10374 case OPC_CVT_PW_PS
:
10377 TCGv_i64 fp0
= tcg_temp_new_i64();
10379 gen_load_fpr64(ctx
, fp0
, fs
);
10380 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
10381 gen_store_fpr64(ctx
, fp0
, fd
);
10382 tcg_temp_free_i64(fp0
);
10387 check_cp1_64bitmode(ctx
);
10389 TCGv_i32 fp0
= tcg_temp_new_i32();
10391 gen_load_fpr32(ctx
, fp0
, fs
);
10392 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
10393 gen_store_fpr32(ctx
, fp0
, fd
);
10394 tcg_temp_free_i32(fp0
);
10401 TCGv_i32 fp0
= tcg_temp_new_i32();
10402 TCGv_i32 fp1
= tcg_temp_new_i32();
10404 gen_load_fpr32(ctx
, fp0
, fs
);
10405 gen_load_fpr32(ctx
, fp1
, ft
);
10406 gen_store_fpr32h(ctx
, fp0
, fd
);
10407 gen_store_fpr32(ctx
, fp1
, fd
);
10408 tcg_temp_free_i32(fp0
);
10409 tcg_temp_free_i32(fp1
);
10416 TCGv_i32 fp0
= tcg_temp_new_i32();
10417 TCGv_i32 fp1
= tcg_temp_new_i32();
10419 gen_load_fpr32(ctx
, fp0
, fs
);
10420 gen_load_fpr32h(ctx
, fp1
, ft
);
10421 gen_store_fpr32(ctx
, fp1
, fd
);
10422 gen_store_fpr32h(ctx
, fp0
, fd
);
10423 tcg_temp_free_i32(fp0
);
10424 tcg_temp_free_i32(fp1
);
10431 TCGv_i32 fp0
= tcg_temp_new_i32();
10432 TCGv_i32 fp1
= tcg_temp_new_i32();
10434 gen_load_fpr32h(ctx
, fp0
, fs
);
10435 gen_load_fpr32(ctx
, fp1
, ft
);
10436 gen_store_fpr32(ctx
, fp1
, fd
);
10437 gen_store_fpr32h(ctx
, fp0
, fd
);
10438 tcg_temp_free_i32(fp0
);
10439 tcg_temp_free_i32(fp1
);
10446 TCGv_i32 fp0
= tcg_temp_new_i32();
10447 TCGv_i32 fp1
= tcg_temp_new_i32();
10449 gen_load_fpr32h(ctx
, fp0
, fs
);
10450 gen_load_fpr32h(ctx
, fp1
, ft
);
10451 gen_store_fpr32(ctx
, fp1
, fd
);
10452 gen_store_fpr32h(ctx
, fp0
, fd
);
10453 tcg_temp_free_i32(fp0
);
10454 tcg_temp_free_i32(fp1
);
10459 case OPC_CMP_UN_PS
:
10460 case OPC_CMP_EQ_PS
:
10461 case OPC_CMP_UEQ_PS
:
10462 case OPC_CMP_OLT_PS
:
10463 case OPC_CMP_ULT_PS
:
10464 case OPC_CMP_OLE_PS
:
10465 case OPC_CMP_ULE_PS
:
10466 case OPC_CMP_SF_PS
:
10467 case OPC_CMP_NGLE_PS
:
10468 case OPC_CMP_SEQ_PS
:
10469 case OPC_CMP_NGL_PS
:
10470 case OPC_CMP_LT_PS
:
10471 case OPC_CMP_NGE_PS
:
10472 case OPC_CMP_LE_PS
:
10473 case OPC_CMP_NGT_PS
:
10474 if (ctx
->opcode
& (1 << 6)) {
10475 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
10476 opn
= condnames_abs
[func
-48];
10478 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
10479 opn
= condnames
[func
-48];
10485 generate_exception (ctx
, EXCP_RI
);
10488 (void)opn
; /* avoid a compiler warning */
10491 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
10494 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
10497 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
10502 /* Coprocessor 3 (FPU) */
10503 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
10504 int fd
, int fs
, int base
, int index
)
10506 const char *opn
= "extended float load/store";
10508 TCGv t0
= tcg_temp_new();
10511 gen_load_gpr(t0
, index
);
10512 } else if (index
== 0) {
10513 gen_load_gpr(t0
, base
);
10515 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
10517 /* Don't do NOP if destination is zero: we must perform the actual
10523 TCGv_i32 fp0
= tcg_temp_new_i32();
10525 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
10526 tcg_gen_trunc_tl_i32(fp0
, t0
);
10527 gen_store_fpr32(ctx
, fp0
, fd
);
10528 tcg_temp_free_i32(fp0
);
10534 check_cp1_registers(ctx
, fd
);
10536 TCGv_i64 fp0
= tcg_temp_new_i64();
10537 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10538 gen_store_fpr64(ctx
, fp0
, fd
);
10539 tcg_temp_free_i64(fp0
);
10544 check_cp1_64bitmode(ctx
);
10545 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10547 TCGv_i64 fp0
= tcg_temp_new_i64();
10549 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10550 gen_store_fpr64(ctx
, fp0
, fd
);
10551 tcg_temp_free_i64(fp0
);
10558 TCGv_i32 fp0
= tcg_temp_new_i32();
10559 gen_load_fpr32(ctx
, fp0
, fs
);
10560 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
10561 tcg_temp_free_i32(fp0
);
10568 check_cp1_registers(ctx
, fs
);
10570 TCGv_i64 fp0
= tcg_temp_new_i64();
10571 gen_load_fpr64(ctx
, fp0
, fs
);
10572 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10573 tcg_temp_free_i64(fp0
);
10579 check_cp1_64bitmode(ctx
);
10580 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10582 TCGv_i64 fp0
= tcg_temp_new_i64();
10583 gen_load_fpr64(ctx
, fp0
, fs
);
10584 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10585 tcg_temp_free_i64(fp0
);
10592 (void)opn
; (void)store
; /* avoid compiler warnings */
10593 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
10594 regnames
[index
], regnames
[base
]);
10597 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
10598 int fd
, int fr
, int fs
, int ft
)
10600 const char *opn
= "flt3_arith";
10606 TCGv t0
= tcg_temp_local_new();
10607 TCGv_i32 fp
= tcg_temp_new_i32();
10608 TCGv_i32 fph
= tcg_temp_new_i32();
10609 TCGLabel
*l1
= gen_new_label();
10610 TCGLabel
*l2
= gen_new_label();
10612 gen_load_gpr(t0
, fr
);
10613 tcg_gen_andi_tl(t0
, t0
, 0x7);
10615 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
10616 gen_load_fpr32(ctx
, fp
, fs
);
10617 gen_load_fpr32h(ctx
, fph
, fs
);
10618 gen_store_fpr32(ctx
, fp
, fd
);
10619 gen_store_fpr32h(ctx
, fph
, fd
);
10622 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
10624 #ifdef TARGET_WORDS_BIGENDIAN
10625 gen_load_fpr32(ctx
, fp
, fs
);
10626 gen_load_fpr32h(ctx
, fph
, ft
);
10627 gen_store_fpr32h(ctx
, fp
, fd
);
10628 gen_store_fpr32(ctx
, fph
, fd
);
10630 gen_load_fpr32h(ctx
, fph
, fs
);
10631 gen_load_fpr32(ctx
, fp
, ft
);
10632 gen_store_fpr32(ctx
, fph
, fd
);
10633 gen_store_fpr32h(ctx
, fp
, fd
);
10636 tcg_temp_free_i32(fp
);
10637 tcg_temp_free_i32(fph
);
10644 TCGv_i32 fp0
= tcg_temp_new_i32();
10645 TCGv_i32 fp1
= tcg_temp_new_i32();
10646 TCGv_i32 fp2
= tcg_temp_new_i32();
10648 gen_load_fpr32(ctx
, fp0
, fs
);
10649 gen_load_fpr32(ctx
, fp1
, ft
);
10650 gen_load_fpr32(ctx
, fp2
, fr
);
10651 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10652 tcg_temp_free_i32(fp0
);
10653 tcg_temp_free_i32(fp1
);
10654 gen_store_fpr32(ctx
, fp2
, fd
);
10655 tcg_temp_free_i32(fp2
);
10661 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10663 TCGv_i64 fp0
= tcg_temp_new_i64();
10664 TCGv_i64 fp1
= tcg_temp_new_i64();
10665 TCGv_i64 fp2
= tcg_temp_new_i64();
10667 gen_load_fpr64(ctx
, fp0
, fs
);
10668 gen_load_fpr64(ctx
, fp1
, ft
);
10669 gen_load_fpr64(ctx
, fp2
, fr
);
10670 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10671 tcg_temp_free_i64(fp0
);
10672 tcg_temp_free_i64(fp1
);
10673 gen_store_fpr64(ctx
, fp2
, fd
);
10674 tcg_temp_free_i64(fp2
);
10681 TCGv_i64 fp0
= tcg_temp_new_i64();
10682 TCGv_i64 fp1
= tcg_temp_new_i64();
10683 TCGv_i64 fp2
= tcg_temp_new_i64();
10685 gen_load_fpr64(ctx
, fp0
, fs
);
10686 gen_load_fpr64(ctx
, fp1
, ft
);
10687 gen_load_fpr64(ctx
, fp2
, fr
);
10688 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10689 tcg_temp_free_i64(fp0
);
10690 tcg_temp_free_i64(fp1
);
10691 gen_store_fpr64(ctx
, fp2
, fd
);
10692 tcg_temp_free_i64(fp2
);
10699 TCGv_i32 fp0
= tcg_temp_new_i32();
10700 TCGv_i32 fp1
= tcg_temp_new_i32();
10701 TCGv_i32 fp2
= tcg_temp_new_i32();
10703 gen_load_fpr32(ctx
, fp0
, fs
);
10704 gen_load_fpr32(ctx
, fp1
, ft
);
10705 gen_load_fpr32(ctx
, fp2
, fr
);
10706 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10707 tcg_temp_free_i32(fp0
);
10708 tcg_temp_free_i32(fp1
);
10709 gen_store_fpr32(ctx
, fp2
, fd
);
10710 tcg_temp_free_i32(fp2
);
10716 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10718 TCGv_i64 fp0
= tcg_temp_new_i64();
10719 TCGv_i64 fp1
= tcg_temp_new_i64();
10720 TCGv_i64 fp2
= tcg_temp_new_i64();
10722 gen_load_fpr64(ctx
, fp0
, fs
);
10723 gen_load_fpr64(ctx
, fp1
, ft
);
10724 gen_load_fpr64(ctx
, fp2
, fr
);
10725 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10726 tcg_temp_free_i64(fp0
);
10727 tcg_temp_free_i64(fp1
);
10728 gen_store_fpr64(ctx
, fp2
, fd
);
10729 tcg_temp_free_i64(fp2
);
10736 TCGv_i64 fp0
= tcg_temp_new_i64();
10737 TCGv_i64 fp1
= tcg_temp_new_i64();
10738 TCGv_i64 fp2
= tcg_temp_new_i64();
10740 gen_load_fpr64(ctx
, fp0
, fs
);
10741 gen_load_fpr64(ctx
, fp1
, ft
);
10742 gen_load_fpr64(ctx
, fp2
, fr
);
10743 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10744 tcg_temp_free_i64(fp0
);
10745 tcg_temp_free_i64(fp1
);
10746 gen_store_fpr64(ctx
, fp2
, fd
);
10747 tcg_temp_free_i64(fp2
);
10754 TCGv_i32 fp0
= tcg_temp_new_i32();
10755 TCGv_i32 fp1
= tcg_temp_new_i32();
10756 TCGv_i32 fp2
= tcg_temp_new_i32();
10758 gen_load_fpr32(ctx
, fp0
, fs
);
10759 gen_load_fpr32(ctx
, fp1
, ft
);
10760 gen_load_fpr32(ctx
, fp2
, fr
);
10761 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10762 tcg_temp_free_i32(fp0
);
10763 tcg_temp_free_i32(fp1
);
10764 gen_store_fpr32(ctx
, fp2
, fd
);
10765 tcg_temp_free_i32(fp2
);
10771 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10773 TCGv_i64 fp0
= tcg_temp_new_i64();
10774 TCGv_i64 fp1
= tcg_temp_new_i64();
10775 TCGv_i64 fp2
= tcg_temp_new_i64();
10777 gen_load_fpr64(ctx
, fp0
, fs
);
10778 gen_load_fpr64(ctx
, fp1
, ft
);
10779 gen_load_fpr64(ctx
, fp2
, fr
);
10780 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10781 tcg_temp_free_i64(fp0
);
10782 tcg_temp_free_i64(fp1
);
10783 gen_store_fpr64(ctx
, fp2
, fd
);
10784 tcg_temp_free_i64(fp2
);
10791 TCGv_i64 fp0
= tcg_temp_new_i64();
10792 TCGv_i64 fp1
= tcg_temp_new_i64();
10793 TCGv_i64 fp2
= tcg_temp_new_i64();
10795 gen_load_fpr64(ctx
, fp0
, fs
);
10796 gen_load_fpr64(ctx
, fp1
, ft
);
10797 gen_load_fpr64(ctx
, fp2
, fr
);
10798 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10799 tcg_temp_free_i64(fp0
);
10800 tcg_temp_free_i64(fp1
);
10801 gen_store_fpr64(ctx
, fp2
, fd
);
10802 tcg_temp_free_i64(fp2
);
10809 TCGv_i32 fp0
= tcg_temp_new_i32();
10810 TCGv_i32 fp1
= tcg_temp_new_i32();
10811 TCGv_i32 fp2
= tcg_temp_new_i32();
10813 gen_load_fpr32(ctx
, fp0
, fs
);
10814 gen_load_fpr32(ctx
, fp1
, ft
);
10815 gen_load_fpr32(ctx
, fp2
, fr
);
10816 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10817 tcg_temp_free_i32(fp0
);
10818 tcg_temp_free_i32(fp1
);
10819 gen_store_fpr32(ctx
, fp2
, fd
);
10820 tcg_temp_free_i32(fp2
);
10826 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10828 TCGv_i64 fp0
= tcg_temp_new_i64();
10829 TCGv_i64 fp1
= tcg_temp_new_i64();
10830 TCGv_i64 fp2
= tcg_temp_new_i64();
10832 gen_load_fpr64(ctx
, fp0
, fs
);
10833 gen_load_fpr64(ctx
, fp1
, ft
);
10834 gen_load_fpr64(ctx
, fp2
, fr
);
10835 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10836 tcg_temp_free_i64(fp0
);
10837 tcg_temp_free_i64(fp1
);
10838 gen_store_fpr64(ctx
, fp2
, fd
);
10839 tcg_temp_free_i64(fp2
);
10846 TCGv_i64 fp0
= tcg_temp_new_i64();
10847 TCGv_i64 fp1
= tcg_temp_new_i64();
10848 TCGv_i64 fp2
= tcg_temp_new_i64();
10850 gen_load_fpr64(ctx
, fp0
, fs
);
10851 gen_load_fpr64(ctx
, fp1
, ft
);
10852 gen_load_fpr64(ctx
, fp2
, fr
);
10853 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10854 tcg_temp_free_i64(fp0
);
10855 tcg_temp_free_i64(fp1
);
10856 gen_store_fpr64(ctx
, fp2
, fd
);
10857 tcg_temp_free_i64(fp2
);
10863 generate_exception (ctx
, EXCP_RI
);
10866 (void)opn
; /* avoid a compiler warning */
10867 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
10868 fregnames
[fs
], fregnames
[ft
]);
10871 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
10875 #if !defined(CONFIG_USER_ONLY)
10876 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10877 Therefore only check the ISA in system mode. */
10878 check_insn(ctx
, ISA_MIPS32R2
);
10880 t0
= tcg_temp_new();
10884 save_cpu_state(ctx
, 1);
10885 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
10886 gen_store_gpr(t0
, rt
);
10889 save_cpu_state(ctx
, 1);
10890 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
10891 gen_store_gpr(t0
, rt
);
10894 save_cpu_state(ctx
, 1);
10895 gen_helper_rdhwr_cc(t0
, cpu_env
);
10896 gen_store_gpr(t0
, rt
);
10899 save_cpu_state(ctx
, 1);
10900 gen_helper_rdhwr_ccres(t0
, cpu_env
);
10901 gen_store_gpr(t0
, rt
);
10904 #if defined(CONFIG_USER_ONLY)
10905 tcg_gen_ld_tl(t0
, cpu_env
,
10906 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10907 gen_store_gpr(t0
, rt
);
10910 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
10911 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
10912 tcg_gen_ld_tl(t0
, cpu_env
,
10913 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10914 gen_store_gpr(t0
, rt
);
10916 generate_exception(ctx
, EXCP_RI
);
10920 default: /* Invalid */
10921 MIPS_INVAL("rdhwr");
10922 generate_exception(ctx
, EXCP_RI
);
10928 static inline void clear_branch_hflags(DisasContext
*ctx
)
10930 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
10931 if (ctx
->bstate
== BS_NONE
) {
10932 save_cpu_state(ctx
, 0);
10934 /* it is not safe to save ctx->hflags as hflags may be changed
10935 in execution time by the instruction in delay / forbidden slot. */
10936 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
10940 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
10942 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10943 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
10944 /* Branches completion */
10945 clear_branch_hflags(ctx
);
10946 ctx
->bstate
= BS_BRANCH
;
10947 /* FIXME: Need to clear can_do_io. */
10948 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
10949 case MIPS_HFLAG_FBNSLOT
:
10950 MIPS_DEBUG("forbidden slot");
10951 gen_goto_tb(ctx
, 0, ctx
->pc
+ insn_bytes
);
10954 /* unconditional branch */
10955 MIPS_DEBUG("unconditional branch");
10956 if (proc_hflags
& MIPS_HFLAG_BX
) {
10957 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
10959 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10961 case MIPS_HFLAG_BL
:
10962 /* blikely taken case */
10963 MIPS_DEBUG("blikely branch taken");
10964 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10966 case MIPS_HFLAG_BC
:
10967 /* Conditional branch */
10968 MIPS_DEBUG("conditional branch");
10970 TCGLabel
*l1
= gen_new_label();
10972 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
10973 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
10975 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10978 case MIPS_HFLAG_BR
:
10979 /* unconditional branch to register */
10980 MIPS_DEBUG("branch to register");
10981 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
10982 TCGv t0
= tcg_temp_new();
10983 TCGv_i32 t1
= tcg_temp_new_i32();
10985 tcg_gen_andi_tl(t0
, btarget
, 0x1);
10986 tcg_gen_trunc_tl_i32(t1
, t0
);
10988 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
10989 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
10990 tcg_gen_or_i32(hflags
, hflags
, t1
);
10991 tcg_temp_free_i32(t1
);
10993 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
10995 tcg_gen_mov_tl(cpu_PC
, btarget
);
10997 if (ctx
->singlestep_enabled
) {
10998 save_cpu_state(ctx
, 0);
10999 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
11001 tcg_gen_exit_tb(0);
11004 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
11010 /* Compact Branches */
11011 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
11012 int rs
, int rt
, int32_t offset
)
11014 int bcond_compute
= 0;
11015 TCGv t0
= tcg_temp_new();
11016 TCGv t1
= tcg_temp_new();
11017 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
11019 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11020 #ifdef MIPS_DEBUG_DISAS
11021 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11024 generate_exception(ctx
, EXCP_RI
);
11028 /* Load needed operands and calculate btarget */
11030 /* compact branch */
11031 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
11032 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
11033 gen_load_gpr(t0
, rs
);
11034 gen_load_gpr(t1
, rt
);
11036 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11037 if (rs
<= rt
&& rs
== 0) {
11038 /* OPC_BEQZALC, OPC_BNEZALC */
11039 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11042 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
11043 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
11044 gen_load_gpr(t0
, rs
);
11045 gen_load_gpr(t1
, rt
);
11047 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11049 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
11050 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
11051 if (rs
== 0 || rs
== rt
) {
11052 /* OPC_BLEZALC, OPC_BGEZALC */
11053 /* OPC_BGTZALC, OPC_BLTZALC */
11054 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11056 gen_load_gpr(t0
, rs
);
11057 gen_load_gpr(t1
, rt
);
11059 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11063 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11068 /* OPC_BEQZC, OPC_BNEZC */
11069 gen_load_gpr(t0
, rs
);
11071 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
11073 /* OPC_JIC, OPC_JIALC */
11074 TCGv tbase
= tcg_temp_new();
11075 TCGv toffset
= tcg_temp_new();
11077 gen_load_gpr(tbase
, rt
);
11078 tcg_gen_movi_tl(toffset
, offset
);
11079 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
11080 tcg_temp_free(tbase
);
11081 tcg_temp_free(toffset
);
11085 MIPS_INVAL("Compact branch/jump");
11086 generate_exception(ctx
, EXCP_RI
);
11090 if (bcond_compute
== 0) {
11091 /* Uncoditional compact branch */
11094 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11097 ctx
->hflags
|= MIPS_HFLAG_BR
;
11100 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
11103 ctx
->hflags
|= MIPS_HFLAG_B
;
11106 MIPS_INVAL("Compact branch/jump");
11107 generate_exception(ctx
, EXCP_RI
);
11111 /* Generating branch here as compact branches don't have delay slot */
11112 gen_branch(ctx
, 4);
11114 /* Conditional compact branch */
11115 TCGLabel
*fs
= gen_new_label();
11116 save_cpu_state(ctx
, 0);
11119 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
11120 if (rs
== 0 && rt
!= 0) {
11122 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
11123 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11125 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
11128 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
11131 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
11132 if (rs
== 0 && rt
!= 0) {
11134 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
11135 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11137 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
11140 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
11143 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
11144 if (rs
== 0 && rt
!= 0) {
11146 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
11147 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11149 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
11152 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
11155 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
11156 if (rs
== 0 && rt
!= 0) {
11158 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
11159 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
11161 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
11164 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
11167 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
11168 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
11170 /* OPC_BOVC, OPC_BNVC */
11171 TCGv t2
= tcg_temp_new();
11172 TCGv t3
= tcg_temp_new();
11173 TCGv t4
= tcg_temp_new();
11174 TCGv input_overflow
= tcg_temp_new();
11176 gen_load_gpr(t0
, rs
);
11177 gen_load_gpr(t1
, rt
);
11178 tcg_gen_ext32s_tl(t2
, t0
);
11179 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
11180 tcg_gen_ext32s_tl(t3
, t1
);
11181 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
11182 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
11184 tcg_gen_add_tl(t4
, t2
, t3
);
11185 tcg_gen_ext32s_tl(t4
, t4
);
11186 tcg_gen_xor_tl(t2
, t2
, t3
);
11187 tcg_gen_xor_tl(t3
, t4
, t3
);
11188 tcg_gen_andc_tl(t2
, t3
, t2
);
11189 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
11190 tcg_gen_or_tl(t4
, t4
, input_overflow
);
11191 if (opc
== OPC_BOVC
) {
11193 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
11196 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
11198 tcg_temp_free(input_overflow
);
11202 } else if (rs
< rt
&& rs
== 0) {
11203 /* OPC_BEQZALC, OPC_BNEZALC */
11204 if (opc
== OPC_BEQZALC
) {
11206 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
11209 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
11212 /* OPC_BEQC, OPC_BNEC */
11213 if (opc
== OPC_BEQC
) {
11215 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
11218 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
11223 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
11226 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
11229 MIPS_INVAL("Compact conditional branch/jump");
11230 generate_exception(ctx
, EXCP_RI
);
11234 /* Generating branch here as compact branches don't have delay slot */
11235 gen_goto_tb(ctx
, 1, ctx
->btarget
);
11238 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
11239 MIPS_DEBUG("Compact conditional branch");
11247 /* ISA extensions (ASEs) */
11248 /* MIPS16 extension to MIPS32 */
11250 /* MIPS16 major opcodes */
11252 M16_OPC_ADDIUSP
= 0x00,
11253 M16_OPC_ADDIUPC
= 0x01,
11255 M16_OPC_JAL
= 0x03,
11256 M16_OPC_BEQZ
= 0x04,
11257 M16_OPC_BNEQZ
= 0x05,
11258 M16_OPC_SHIFT
= 0x06,
11260 M16_OPC_RRIA
= 0x08,
11261 M16_OPC_ADDIU8
= 0x09,
11262 M16_OPC_SLTI
= 0x0a,
11263 M16_OPC_SLTIU
= 0x0b,
11266 M16_OPC_CMPI
= 0x0e,
11270 M16_OPC_LWSP
= 0x12,
11272 M16_OPC_LBU
= 0x14,
11273 M16_OPC_LHU
= 0x15,
11274 M16_OPC_LWPC
= 0x16,
11275 M16_OPC_LWU
= 0x17,
11278 M16_OPC_SWSP
= 0x1a,
11280 M16_OPC_RRR
= 0x1c,
11282 M16_OPC_EXTEND
= 0x1e,
11286 /* I8 funct field */
11305 /* RR funct field */
11339 /* I64 funct field */
11347 I64_DADDIUPC
= 0x6,
11351 /* RR ry field for CNVT */
11353 RR_RY_CNVT_ZEB
= 0x0,
11354 RR_RY_CNVT_ZEH
= 0x1,
11355 RR_RY_CNVT_ZEW
= 0x2,
11356 RR_RY_CNVT_SEB
= 0x4,
11357 RR_RY_CNVT_SEH
= 0x5,
11358 RR_RY_CNVT_SEW
= 0x6,
11361 static int xlat (int r
)
11363 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11368 static void gen_mips16_save (DisasContext
*ctx
,
11369 int xsregs
, int aregs
,
11370 int do_ra
, int do_s0
, int do_s1
,
11373 TCGv t0
= tcg_temp_new();
11374 TCGv t1
= tcg_temp_new();
11375 TCGv t2
= tcg_temp_new();
11405 generate_exception(ctx
, EXCP_RI
);
11411 gen_base_offset_addr(ctx
, t0
, 29, 12);
11412 gen_load_gpr(t1
, 7);
11413 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11416 gen_base_offset_addr(ctx
, t0
, 29, 8);
11417 gen_load_gpr(t1
, 6);
11418 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11421 gen_base_offset_addr(ctx
, t0
, 29, 4);
11422 gen_load_gpr(t1
, 5);
11423 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11426 gen_base_offset_addr(ctx
, t0
, 29, 0);
11427 gen_load_gpr(t1
, 4);
11428 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11431 gen_load_gpr(t0
, 29);
11433 #define DECR_AND_STORE(reg) do { \
11434 tcg_gen_movi_tl(t2, -4); \
11435 gen_op_addr_add(ctx, t0, t0, t2); \
11436 gen_load_gpr(t1, reg); \
11437 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11441 DECR_AND_STORE(31);
11446 DECR_AND_STORE(30);
11449 DECR_AND_STORE(23);
11452 DECR_AND_STORE(22);
11455 DECR_AND_STORE(21);
11458 DECR_AND_STORE(20);
11461 DECR_AND_STORE(19);
11464 DECR_AND_STORE(18);
11468 DECR_AND_STORE(17);
11471 DECR_AND_STORE(16);
11501 generate_exception(ctx
, EXCP_RI
);
11517 #undef DECR_AND_STORE
11519 tcg_gen_movi_tl(t2
, -framesize
);
11520 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11526 static void gen_mips16_restore (DisasContext
*ctx
,
11527 int xsregs
, int aregs
,
11528 int do_ra
, int do_s0
, int do_s1
,
11532 TCGv t0
= tcg_temp_new();
11533 TCGv t1
= tcg_temp_new();
11534 TCGv t2
= tcg_temp_new();
11536 tcg_gen_movi_tl(t2
, framesize
);
11537 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
11539 #define DECR_AND_LOAD(reg) do { \
11540 tcg_gen_movi_tl(t2, -4); \
11541 gen_op_addr_add(ctx, t0, t0, t2); \
11542 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11543 gen_store_gpr(t1, reg); \
11607 generate_exception(ctx
, EXCP_RI
);
11623 #undef DECR_AND_LOAD
11625 tcg_gen_movi_tl(t2
, framesize
);
11626 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11632 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
11633 int is_64_bit
, int extended
)
11637 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11638 generate_exception(ctx
, EXCP_RI
);
11642 t0
= tcg_temp_new();
11644 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
11645 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
11647 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11653 #if defined(TARGET_MIPS64)
11654 static void decode_i64_mips16 (DisasContext
*ctx
,
11655 int ry
, int funct
, int16_t offset
,
11660 check_insn(ctx
, ISA_MIPS3
);
11661 check_mips_64(ctx
);
11662 offset
= extended
? offset
: offset
<< 3;
11663 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
11666 check_insn(ctx
, ISA_MIPS3
);
11667 check_mips_64(ctx
);
11668 offset
= extended
? offset
: offset
<< 3;
11669 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
11672 check_insn(ctx
, ISA_MIPS3
);
11673 check_mips_64(ctx
);
11674 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
11675 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
11678 check_insn(ctx
, ISA_MIPS3
);
11679 check_mips_64(ctx
);
11680 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
11681 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
11684 check_insn(ctx
, ISA_MIPS3
);
11685 check_mips_64(ctx
);
11686 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11687 generate_exception(ctx
, EXCP_RI
);
11689 offset
= extended
? offset
: offset
<< 3;
11690 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
11694 check_insn(ctx
, ISA_MIPS3
);
11695 check_mips_64(ctx
);
11696 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
11697 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
11700 check_insn(ctx
, ISA_MIPS3
);
11701 check_mips_64(ctx
);
11702 offset
= extended
? offset
: offset
<< 2;
11703 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
11706 check_insn(ctx
, ISA_MIPS3
);
11707 check_mips_64(ctx
);
11708 offset
= extended
? offset
: offset
<< 2;
11709 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
11715 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11717 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11718 int op
, rx
, ry
, funct
, sa
;
11719 int16_t imm
, offset
;
11721 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
11722 op
= (ctx
->opcode
>> 11) & 0x1f;
11723 sa
= (ctx
->opcode
>> 22) & 0x1f;
11724 funct
= (ctx
->opcode
>> 8) & 0x7;
11725 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11726 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11727 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
11728 | ((ctx
->opcode
>> 21) & 0x3f) << 5
11729 | (ctx
->opcode
& 0x1f));
11731 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11734 case M16_OPC_ADDIUSP
:
11735 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11737 case M16_OPC_ADDIUPC
:
11738 gen_addiupc(ctx
, rx
, imm
, 0, 1);
11741 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
11742 /* No delay slot, so just process as a normal instruction */
11745 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
11746 /* No delay slot, so just process as a normal instruction */
11748 case M16_OPC_BNEQZ
:
11749 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
11750 /* No delay slot, so just process as a normal instruction */
11752 case M16_OPC_SHIFT
:
11753 switch (ctx
->opcode
& 0x3) {
11755 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11758 #if defined(TARGET_MIPS64)
11759 check_mips_64(ctx
);
11760 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11762 generate_exception(ctx
, EXCP_RI
);
11766 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11769 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11773 #if defined(TARGET_MIPS64)
11775 check_insn(ctx
, ISA_MIPS3
);
11776 check_mips_64(ctx
);
11777 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
11781 imm
= ctx
->opcode
& 0xf;
11782 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
11783 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
11784 imm
= (int16_t) (imm
<< 1) >> 1;
11785 if ((ctx
->opcode
>> 4) & 0x1) {
11786 #if defined(TARGET_MIPS64)
11787 check_mips_64(ctx
);
11788 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11790 generate_exception(ctx
, EXCP_RI
);
11793 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11796 case M16_OPC_ADDIU8
:
11797 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11800 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11802 case M16_OPC_SLTIU
:
11803 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11808 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
11811 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
11814 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
11817 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
11820 check_insn(ctx
, ISA_MIPS32
);
11822 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
11823 int aregs
= (ctx
->opcode
>> 16) & 0xf;
11824 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
11825 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
11826 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
11827 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
11828 | (ctx
->opcode
& 0xf)) << 3;
11830 if (ctx
->opcode
& (1 << 7)) {
11831 gen_mips16_save(ctx
, xsregs
, aregs
,
11832 do_ra
, do_s0
, do_s1
,
11835 gen_mips16_restore(ctx
, xsregs
, aregs
,
11836 do_ra
, do_s0
, do_s1
,
11842 generate_exception(ctx
, EXCP_RI
);
11847 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
11850 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
11852 #if defined(TARGET_MIPS64)
11854 check_insn(ctx
, ISA_MIPS3
);
11855 check_mips_64(ctx
);
11856 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
11860 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11863 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
11866 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
11869 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
11872 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11875 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
11878 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
11880 #if defined(TARGET_MIPS64)
11882 check_insn(ctx
, ISA_MIPS3
);
11883 check_mips_64(ctx
);
11884 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
11888 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11891 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
11894 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
11897 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
11899 #if defined(TARGET_MIPS64)
11901 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
11905 generate_exception(ctx
, EXCP_RI
);
11912 static inline bool is_uhi(int sdbbp_code
)
11914 #ifdef CONFIG_USER_ONLY
11917 return semihosting_enabled() && sdbbp_code
== 1;
11921 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11925 int op
, cnvt_op
, op1
, offset
;
11929 op
= (ctx
->opcode
>> 11) & 0x1f;
11930 sa
= (ctx
->opcode
>> 2) & 0x7;
11931 sa
= sa
== 0 ? 8 : sa
;
11932 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11933 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
11934 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11935 op1
= offset
= ctx
->opcode
& 0x1f;
11940 case M16_OPC_ADDIUSP
:
11942 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
11944 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11947 case M16_OPC_ADDIUPC
:
11948 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
11951 offset
= (ctx
->opcode
& 0x7ff) << 1;
11952 offset
= (int16_t)(offset
<< 4) >> 4;
11953 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
11954 /* No delay slot, so just process as a normal instruction */
11957 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11958 offset
= (((ctx
->opcode
& 0x1f) << 21)
11959 | ((ctx
->opcode
>> 5) & 0x1f) << 16
11961 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
11962 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
11966 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
11967 ((int8_t)ctx
->opcode
) << 1, 0);
11968 /* No delay slot, so just process as a normal instruction */
11970 case M16_OPC_BNEQZ
:
11971 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
11972 ((int8_t)ctx
->opcode
) << 1, 0);
11973 /* No delay slot, so just process as a normal instruction */
11975 case M16_OPC_SHIFT
:
11976 switch (ctx
->opcode
& 0x3) {
11978 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11981 #if defined(TARGET_MIPS64)
11982 check_insn(ctx
, ISA_MIPS3
);
11983 check_mips_64(ctx
);
11984 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11986 generate_exception(ctx
, EXCP_RI
);
11990 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11993 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11997 #if defined(TARGET_MIPS64)
11999 check_insn(ctx
, ISA_MIPS3
);
12000 check_mips_64(ctx
);
12001 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
12006 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
12008 if ((ctx
->opcode
>> 4) & 1) {
12009 #if defined(TARGET_MIPS64)
12010 check_insn(ctx
, ISA_MIPS3
);
12011 check_mips_64(ctx
);
12012 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
12014 generate_exception(ctx
, EXCP_RI
);
12017 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
12021 case M16_OPC_ADDIU8
:
12023 int16_t imm
= (int8_t) ctx
->opcode
;
12025 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
12030 int16_t imm
= (uint8_t) ctx
->opcode
;
12031 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
12034 case M16_OPC_SLTIU
:
12036 int16_t imm
= (uint8_t) ctx
->opcode
;
12037 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
12044 funct
= (ctx
->opcode
>> 8) & 0x7;
12047 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
12048 ((int8_t)ctx
->opcode
) << 1, 0);
12051 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
12052 ((int8_t)ctx
->opcode
) << 1, 0);
12055 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
12058 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
12059 ((int8_t)ctx
->opcode
) << 3);
12062 check_insn(ctx
, ISA_MIPS32
);
12064 int do_ra
= ctx
->opcode
& (1 << 6);
12065 int do_s0
= ctx
->opcode
& (1 << 5);
12066 int do_s1
= ctx
->opcode
& (1 << 4);
12067 int framesize
= ctx
->opcode
& 0xf;
12069 if (framesize
== 0) {
12072 framesize
= framesize
<< 3;
12075 if (ctx
->opcode
& (1 << 7)) {
12076 gen_mips16_save(ctx
, 0, 0,
12077 do_ra
, do_s0
, do_s1
, framesize
);
12079 gen_mips16_restore(ctx
, 0, 0,
12080 do_ra
, do_s0
, do_s1
, framesize
);
12086 int rz
= xlat(ctx
->opcode
& 0x7);
12088 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
12089 ((ctx
->opcode
>> 5) & 0x7);
12090 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
12094 reg32
= ctx
->opcode
& 0x1f;
12095 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
12098 generate_exception(ctx
, EXCP_RI
);
12105 int16_t imm
= (uint8_t) ctx
->opcode
;
12107 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
12112 int16_t imm
= (uint8_t) ctx
->opcode
;
12113 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
12116 #if defined(TARGET_MIPS64)
12118 check_insn(ctx
, ISA_MIPS3
);
12119 check_mips_64(ctx
);
12120 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
12124 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
12127 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
12130 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
12133 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
12136 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
12139 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
12142 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
12144 #if defined (TARGET_MIPS64)
12146 check_insn(ctx
, ISA_MIPS3
);
12147 check_mips_64(ctx
);
12148 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
12152 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
12155 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
12158 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
12161 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
12165 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
12168 switch (ctx
->opcode
& 0x3) {
12170 mips32_op
= OPC_ADDU
;
12173 mips32_op
= OPC_SUBU
;
12175 #if defined(TARGET_MIPS64)
12177 mips32_op
= OPC_DADDU
;
12178 check_insn(ctx
, ISA_MIPS3
);
12179 check_mips_64(ctx
);
12182 mips32_op
= OPC_DSUBU
;
12183 check_insn(ctx
, ISA_MIPS3
);
12184 check_mips_64(ctx
);
12188 generate_exception(ctx
, EXCP_RI
);
12192 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
12201 int nd
= (ctx
->opcode
>> 7) & 0x1;
12202 int link
= (ctx
->opcode
>> 6) & 0x1;
12203 int ra
= (ctx
->opcode
>> 5) & 0x1;
12206 check_insn(ctx
, ISA_MIPS32
);
12215 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
12220 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
12221 gen_helper_do_semihosting(cpu_env
);
12223 /* XXX: not clear which exception should be raised
12224 * when in debug mode...
12226 check_insn(ctx
, ISA_MIPS32
);
12227 generate_exception(ctx
, EXCP_DBp
);
12231 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
12234 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
12237 generate_exception(ctx
, EXCP_BREAK
);
12240 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
12243 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
12246 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
12248 #if defined (TARGET_MIPS64)
12250 check_insn(ctx
, ISA_MIPS3
);
12251 check_mips_64(ctx
);
12252 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
12256 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
12259 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
12262 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
12265 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
12268 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
12271 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
12274 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
12277 check_insn(ctx
, ISA_MIPS32
);
12279 case RR_RY_CNVT_ZEB
:
12280 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12282 case RR_RY_CNVT_ZEH
:
12283 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12285 case RR_RY_CNVT_SEB
:
12286 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12288 case RR_RY_CNVT_SEH
:
12289 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12291 #if defined (TARGET_MIPS64)
12292 case RR_RY_CNVT_ZEW
:
12293 check_insn(ctx
, ISA_MIPS64
);
12294 check_mips_64(ctx
);
12295 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12297 case RR_RY_CNVT_SEW
:
12298 check_insn(ctx
, ISA_MIPS64
);
12299 check_mips_64(ctx
);
12300 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12304 generate_exception(ctx
, EXCP_RI
);
12309 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
12311 #if defined (TARGET_MIPS64)
12313 check_insn(ctx
, ISA_MIPS3
);
12314 check_mips_64(ctx
);
12315 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
12318 check_insn(ctx
, ISA_MIPS3
);
12319 check_mips_64(ctx
);
12320 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
12323 check_insn(ctx
, ISA_MIPS3
);
12324 check_mips_64(ctx
);
12325 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
12328 check_insn(ctx
, ISA_MIPS3
);
12329 check_mips_64(ctx
);
12330 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
12334 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
12337 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
12340 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
12343 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
12345 #if defined (TARGET_MIPS64)
12347 check_insn(ctx
, ISA_MIPS3
);
12348 check_mips_64(ctx
);
12349 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
12352 check_insn(ctx
, ISA_MIPS3
);
12353 check_mips_64(ctx
);
12354 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
12357 check_insn(ctx
, ISA_MIPS3
);
12358 check_mips_64(ctx
);
12359 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
12362 check_insn(ctx
, ISA_MIPS3
);
12363 check_mips_64(ctx
);
12364 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
12368 generate_exception(ctx
, EXCP_RI
);
12372 case M16_OPC_EXTEND
:
12373 decode_extended_mips16_opc(env
, ctx
);
12376 #if defined(TARGET_MIPS64)
12378 funct
= (ctx
->opcode
>> 8) & 0x7;
12379 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
12383 generate_exception(ctx
, EXCP_RI
);
12390 /* microMIPS extension to MIPS32/MIPS64 */
12393 * microMIPS32/microMIPS64 major opcodes
12395 * 1. MIPS Architecture for Programmers Volume II-B:
12396 * The microMIPS32 Instruction Set (Revision 3.05)
12398 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12400 * 2. MIPS Architecture For Programmers Volume II-A:
12401 * The MIPS64 Instruction Set (Revision 3.51)
12431 POOL32S
= 0x16, /* MIPS64 */
12432 DADDIU32
= 0x17, /* MIPS64 */
12461 /* 0x29 is reserved */
12474 /* 0x31 is reserved */
12487 SD32
= 0x36, /* MIPS64 */
12488 LD32
= 0x37, /* MIPS64 */
12490 /* 0x39 is reserved */
12506 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12516 /* POOL32A encoding of minor opcode field */
12519 /* These opcodes are distinguished only by bits 9..6; those bits are
12520 * what are recorded below. */
12556 /* The following can be distinguished by their lower 6 bits. */
12564 /* POOL32AXF encoding of minor opcode field extension */
12567 * 1. MIPS Architecture for Programmers Volume II-B:
12568 * The microMIPS32 Instruction Set (Revision 3.05)
12570 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12572 * 2. MIPS Architecture for Programmers VolumeIV-e:
12573 * The MIPS DSP Application-Specific Extension
12574 * to the microMIPS32 Architecture (Revision 2.34)
12576 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12591 /* begin of microMIPS32 DSP */
12593 /* bits 13..12 for 0x01 */
12599 /* bits 13..12 for 0x2a */
12605 /* bits 13..12 for 0x32 */
12609 /* end of microMIPS32 DSP */
12611 /* bits 15..12 for 0x2c */
12628 /* bits 15..12 for 0x34 */
12636 /* bits 15..12 for 0x3c */
12638 JR
= 0x0, /* alias */
12646 /* bits 15..12 for 0x05 */
12650 /* bits 15..12 for 0x0d */
12662 /* bits 15..12 for 0x15 */
12668 /* bits 15..12 for 0x1d */
12672 /* bits 15..12 for 0x2d */
12677 /* bits 15..12 for 0x35 */
12684 /* POOL32B encoding of minor opcode field (bits 15..12) */
12700 /* POOL32C encoding of minor opcode field (bits 15..12) */
12708 /* 0xa is reserved */
12715 /* 0x6 is reserved */
12721 /* POOL32F encoding of minor opcode field (bits 5..0) */
12724 /* These are the bit 7..6 values */
12733 /* These are the bit 8..6 values */
12758 MOVZ_FMT_05
= 0x05,
12792 CABS_COND_FMT
= 0x1c, /* MIPS3D */
12799 /* POOL32Fxf encoding of minor opcode extension field */
12837 /* POOL32I encoding of minor opcode field (bits 25..21) */
12867 /* These overlap and are distinguished by bit16 of the instruction */
12876 /* POOL16A encoding of minor opcode field */
12883 /* POOL16B encoding of minor opcode field */
12890 /* POOL16C encoding of minor opcode field */
12910 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12930 /* POOL16D encoding of minor opcode field */
12937 /* POOL16E encoding of minor opcode field */
12944 static int mmreg (int r
)
12946 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12951 /* Used for 16-bit store instructions. */
12952 static int mmreg2 (int r
)
12954 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12959 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12960 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12961 #define uMIPS_RS2(op) uMIPS_RS(op)
12962 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12963 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12964 #define uMIPS_RS5(op) (op & 0x1f)
12966 /* Signed immediate */
12967 #define SIMM(op, start, width) \
12968 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12971 /* Zero-extended immediate */
12972 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12974 static void gen_addiur1sp(DisasContext
*ctx
)
12976 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12978 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
12981 static void gen_addiur2(DisasContext
*ctx
)
12983 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12984 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12985 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12987 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
12990 static void gen_addiusp(DisasContext
*ctx
)
12992 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
12995 if (encoded
<= 1) {
12996 decoded
= 256 + encoded
;
12997 } else if (encoded
<= 255) {
12999 } else if (encoded
<= 509) {
13000 decoded
= encoded
- 512;
13002 decoded
= encoded
- 768;
13005 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
13008 static void gen_addius5(DisasContext
*ctx
)
13010 int imm
= SIMM(ctx
->opcode
, 1, 4);
13011 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13013 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
13016 static void gen_andi16(DisasContext
*ctx
)
13018 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
13019 31, 32, 63, 64, 255, 32768, 65535 };
13020 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13021 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
13022 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
13024 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
13027 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
13028 int base
, int16_t offset
)
13030 const char *opn
= "ldst_multiple";
13034 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13035 generate_exception(ctx
, EXCP_RI
);
13039 t0
= tcg_temp_new();
13041 gen_base_offset_addr(ctx
, t0
, base
, offset
);
13043 t1
= tcg_const_tl(reglist
);
13044 t2
= tcg_const_i32(ctx
->mem_idx
);
13046 save_cpu_state(ctx
, 1);
13049 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
13053 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
13056 #ifdef TARGET_MIPS64
13058 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
13062 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
13068 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
13071 tcg_temp_free_i32(t2
);
13075 static void gen_pool16c_insn(DisasContext
*ctx
)
13077 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
13078 int rs
= mmreg(ctx
->opcode
& 0x7);
13080 switch (((ctx
->opcode
) >> 4) & 0x3f) {
13085 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
13091 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
13097 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
13103 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
13110 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
13111 int offset
= ZIMM(ctx
->opcode
, 0, 4);
13113 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
13122 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
13123 int offset
= ZIMM(ctx
->opcode
, 0, 4);
13125 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
13132 int reg
= ctx
->opcode
& 0x1f;
13134 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
13140 int reg
= ctx
->opcode
& 0x1f;
13141 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
13142 /* Let normal delay slot handling in our caller take us
13143 to the branch target. */
13148 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
13149 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13153 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
13154 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13158 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
13162 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
13165 generate_exception(ctx
, EXCP_BREAK
);
13168 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
13169 gen_helper_do_semihosting(cpu_env
);
13171 /* XXX: not clear which exception should be raised
13172 * when in debug mode...
13174 check_insn(ctx
, ISA_MIPS32
);
13175 generate_exception(ctx
, EXCP_DBp
);
13178 case JRADDIUSP
+ 0:
13179 case JRADDIUSP
+ 1:
13181 int imm
= ZIMM(ctx
->opcode
, 0, 5);
13182 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
13183 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
13184 /* Let normal delay slot handling in our caller take us
13185 to the branch target. */
13189 generate_exception(ctx
, EXCP_RI
);
13194 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
13197 int rd
, rs
, re
, rt
;
13198 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13199 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13200 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13201 rd
= rd_enc
[enc_dest
];
13202 re
= re_enc
[enc_dest
];
13203 rs
= rs_rt_enc
[enc_rs
];
13204 rt
= rs_rt_enc
[enc_rt
];
13206 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
13208 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
13211 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
13213 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
13217 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
13219 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
13220 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
13222 switch (ctx
->opcode
& 0xf) {
13224 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
13227 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
13231 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
13232 int offset
= extract32(ctx
->opcode
, 4, 4);
13233 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
13236 case R6_JRC16
: /* JRCADDIUSP */
13237 if ((ctx
->opcode
>> 4) & 1) {
13239 int imm
= extract32(ctx
->opcode
, 5, 5);
13240 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
13241 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
13244 int rs
= extract32(ctx
->opcode
, 5, 5);
13245 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
13248 case MOVEP
... MOVEP_07
:
13249 case MOVEP_0C
... MOVEP_0F
:
13251 int enc_dest
= uMIPS_RD(ctx
->opcode
);
13252 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
13253 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
13254 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
13258 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
13261 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
13265 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
13266 int offset
= extract32(ctx
->opcode
, 4, 4);
13267 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
13270 case JALRC16
: /* BREAK16, SDBBP16 */
13271 switch (ctx
->opcode
& 0x3f) {
13273 case JALRC16
+ 0x20:
13275 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
13280 generate_exception(ctx
, EXCP_BREAK
);
13284 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
13285 gen_helper_do_semihosting(cpu_env
);
13287 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
13288 generate_exception(ctx
, EXCP_RI
);
13290 generate_exception(ctx
, EXCP_DBp
);
13297 generate_exception(ctx
, EXCP_RI
);
13302 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
13304 TCGv t0
= tcg_temp_new();
13305 TCGv t1
= tcg_temp_new();
13307 gen_load_gpr(t0
, base
);
13310 gen_load_gpr(t1
, index
);
13311 tcg_gen_shli_tl(t1
, t1
, 2);
13312 gen_op_addr_add(ctx
, t0
, t1
, t0
);
13315 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13316 gen_store_gpr(t1
, rd
);
13322 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
13323 int base
, int16_t offset
)
13325 const char *opn
= "ldst_pair";
13328 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
13329 generate_exception(ctx
, EXCP_RI
);
13333 t0
= tcg_temp_new();
13334 t1
= tcg_temp_new();
13336 gen_base_offset_addr(ctx
, t0
, base
, offset
);
13341 generate_exception(ctx
, EXCP_RI
);
13344 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13345 gen_store_gpr(t1
, rd
);
13346 tcg_gen_movi_tl(t1
, 4);
13347 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13348 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13349 gen_store_gpr(t1
, rd
+1);
13353 gen_load_gpr(t1
, rd
);
13354 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13355 tcg_gen_movi_tl(t1
, 4);
13356 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13357 gen_load_gpr(t1
, rd
+1);
13358 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13361 #ifdef TARGET_MIPS64
13364 generate_exception(ctx
, EXCP_RI
);
13367 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13368 gen_store_gpr(t1
, rd
);
13369 tcg_gen_movi_tl(t1
, 8);
13370 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13371 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13372 gen_store_gpr(t1
, rd
+1);
13376 gen_load_gpr(t1
, rd
);
13377 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13378 tcg_gen_movi_tl(t1
, 8);
13379 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13380 gen_load_gpr(t1
, rd
+1);
13381 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13386 (void)opn
; /* avoid a compiler warning */
13387 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
13392 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
13394 int extension
= (ctx
->opcode
>> 6) & 0x3f;
13395 int minor
= (ctx
->opcode
>> 12) & 0xf;
13396 uint32_t mips32_op
;
13398 switch (extension
) {
13400 mips32_op
= OPC_TEQ
;
13403 mips32_op
= OPC_TGE
;
13406 mips32_op
= OPC_TGEU
;
13409 mips32_op
= OPC_TLT
;
13412 mips32_op
= OPC_TLTU
;
13415 mips32_op
= OPC_TNE
;
13417 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
13419 #ifndef CONFIG_USER_ONLY
13422 check_cp0_enabled(ctx
);
13424 /* Treat as NOP. */
13427 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
13431 check_cp0_enabled(ctx
);
13433 TCGv t0
= tcg_temp_new();
13435 gen_load_gpr(t0
, rt
);
13436 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
13442 switch (minor
& 3) {
13444 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13447 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13450 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13453 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13456 goto pool32axf_invalid
;
13460 switch (minor
& 3) {
13462 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13465 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13468 goto pool32axf_invalid
;
13474 check_insn(ctx
, ISA_MIPS32R6
);
13475 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
13478 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
13481 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
13484 mips32_op
= OPC_CLO
;
13487 mips32_op
= OPC_CLZ
;
13489 check_insn(ctx
, ISA_MIPS32
);
13490 gen_cl(ctx
, mips32_op
, rt
, rs
);
13493 gen_rdhwr(ctx
, rt
, rs
);
13496 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
13499 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13500 mips32_op
= OPC_MULT
;
13503 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13504 mips32_op
= OPC_MULTU
;
13507 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13508 mips32_op
= OPC_DIV
;
13511 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13512 mips32_op
= OPC_DIVU
;
13515 check_insn(ctx
, ISA_MIPS32
);
13516 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
13519 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13520 mips32_op
= OPC_MADD
;
13523 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13524 mips32_op
= OPC_MADDU
;
13527 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13528 mips32_op
= OPC_MSUB
;
13531 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13532 mips32_op
= OPC_MSUBU
;
13534 check_insn(ctx
, ISA_MIPS32
);
13535 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
13538 goto pool32axf_invalid
;
13549 generate_exception_err(ctx
, EXCP_CpU
, 2);
13552 goto pool32axf_invalid
;
13557 case JALR
: /* JALRC */
13558 case JALR_HB
: /* JALRC_HB */
13559 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13560 /* JALRC, JALRC_HB */
13561 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
13563 /* JALR, JALR_HB */
13564 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
13565 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13570 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13571 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
13572 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13575 goto pool32axf_invalid
;
13581 check_cp0_enabled(ctx
);
13582 check_insn(ctx
, ISA_MIPS32R2
);
13583 gen_load_srsgpr(rs
, rt
);
13586 check_cp0_enabled(ctx
);
13587 check_insn(ctx
, ISA_MIPS32R2
);
13588 gen_store_srsgpr(rs
, rt
);
13591 goto pool32axf_invalid
;
13594 #ifndef CONFIG_USER_ONLY
13598 mips32_op
= OPC_TLBP
;
13601 mips32_op
= OPC_TLBR
;
13604 mips32_op
= OPC_TLBWI
;
13607 mips32_op
= OPC_TLBWR
;
13610 mips32_op
= OPC_TLBINV
;
13613 mips32_op
= OPC_TLBINVF
;
13616 mips32_op
= OPC_WAIT
;
13619 mips32_op
= OPC_DERET
;
13622 mips32_op
= OPC_ERET
;
13624 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
13627 goto pool32axf_invalid
;
13633 check_cp0_enabled(ctx
);
13635 TCGv t0
= tcg_temp_new();
13637 save_cpu_state(ctx
, 1);
13638 gen_helper_di(t0
, cpu_env
);
13639 gen_store_gpr(t0
, rs
);
13640 /* Stop translation as we may have switched the execution mode */
13641 ctx
->bstate
= BS_STOP
;
13646 check_cp0_enabled(ctx
);
13648 TCGv t0
= tcg_temp_new();
13650 save_cpu_state(ctx
, 1);
13651 gen_helper_ei(t0
, cpu_env
);
13652 gen_store_gpr(t0
, rs
);
13653 /* Stop translation as we may have switched the execution mode */
13654 ctx
->bstate
= BS_STOP
;
13659 goto pool32axf_invalid
;
13669 generate_exception(ctx
, EXCP_SYSCALL
);
13670 ctx
->bstate
= BS_STOP
;
13673 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
13674 gen_helper_do_semihosting(cpu_env
);
13676 check_insn(ctx
, ISA_MIPS32
);
13677 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
13678 generate_exception(ctx
, EXCP_RI
);
13680 generate_exception(ctx
, EXCP_DBp
);
13685 goto pool32axf_invalid
;
13689 switch (minor
& 3) {
13691 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
13694 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
13697 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
13700 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
13703 goto pool32axf_invalid
;
13707 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13710 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
13713 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
13716 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
13719 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
13722 goto pool32axf_invalid
;
13727 MIPS_INVAL("pool32axf");
13728 generate_exception(ctx
, EXCP_RI
);
13733 /* Values for microMIPS fmt field. Variable-width, depending on which
13734 formats the instruction supports. */
13753 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
13755 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
13756 uint32_t mips32_op
;
13758 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13759 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13760 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13762 switch (extension
) {
13763 case FLOAT_1BIT_FMT(CFC1
, 0):
13764 mips32_op
= OPC_CFC1
;
13766 case FLOAT_1BIT_FMT(CTC1
, 0):
13767 mips32_op
= OPC_CTC1
;
13769 case FLOAT_1BIT_FMT(MFC1
, 0):
13770 mips32_op
= OPC_MFC1
;
13772 case FLOAT_1BIT_FMT(MTC1
, 0):
13773 mips32_op
= OPC_MTC1
;
13775 case FLOAT_1BIT_FMT(MFHC1
, 0):
13776 mips32_op
= OPC_MFHC1
;
13778 case FLOAT_1BIT_FMT(MTHC1
, 0):
13779 mips32_op
= OPC_MTHC1
;
13781 gen_cp1(ctx
, mips32_op
, rt
, rs
);
13784 /* Reciprocal square root */
13785 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
13786 mips32_op
= OPC_RSQRT_S
;
13788 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
13789 mips32_op
= OPC_RSQRT_D
;
13793 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
13794 mips32_op
= OPC_SQRT_S
;
13796 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
13797 mips32_op
= OPC_SQRT_D
;
13801 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
13802 mips32_op
= OPC_RECIP_S
;
13804 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
13805 mips32_op
= OPC_RECIP_D
;
13809 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
13810 mips32_op
= OPC_FLOOR_L_S
;
13812 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
13813 mips32_op
= OPC_FLOOR_L_D
;
13815 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
13816 mips32_op
= OPC_FLOOR_W_S
;
13818 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
13819 mips32_op
= OPC_FLOOR_W_D
;
13823 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
13824 mips32_op
= OPC_CEIL_L_S
;
13826 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
13827 mips32_op
= OPC_CEIL_L_D
;
13829 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
13830 mips32_op
= OPC_CEIL_W_S
;
13832 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
13833 mips32_op
= OPC_CEIL_W_D
;
13837 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
13838 mips32_op
= OPC_TRUNC_L_S
;
13840 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
13841 mips32_op
= OPC_TRUNC_L_D
;
13843 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
13844 mips32_op
= OPC_TRUNC_W_S
;
13846 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
13847 mips32_op
= OPC_TRUNC_W_D
;
13851 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
13852 mips32_op
= OPC_ROUND_L_S
;
13854 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
13855 mips32_op
= OPC_ROUND_L_D
;
13857 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
13858 mips32_op
= OPC_ROUND_W_S
;
13860 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
13861 mips32_op
= OPC_ROUND_W_D
;
13864 /* Integer to floating-point conversion */
13865 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
13866 mips32_op
= OPC_CVT_L_S
;
13868 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
13869 mips32_op
= OPC_CVT_L_D
;
13871 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
13872 mips32_op
= OPC_CVT_W_S
;
13874 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
13875 mips32_op
= OPC_CVT_W_D
;
13878 /* Paired-foo conversions */
13879 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
13880 mips32_op
= OPC_CVT_S_PL
;
13882 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
13883 mips32_op
= OPC_CVT_S_PU
;
13885 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
13886 mips32_op
= OPC_CVT_PW_PS
;
13888 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
13889 mips32_op
= OPC_CVT_PS_PW
;
13892 /* Floating-point moves */
13893 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
13894 mips32_op
= OPC_MOV_S
;
13896 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
13897 mips32_op
= OPC_MOV_D
;
13899 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
13900 mips32_op
= OPC_MOV_PS
;
13903 /* Absolute value */
13904 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
13905 mips32_op
= OPC_ABS_S
;
13907 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
13908 mips32_op
= OPC_ABS_D
;
13910 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
13911 mips32_op
= OPC_ABS_PS
;
13915 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
13916 mips32_op
= OPC_NEG_S
;
13918 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
13919 mips32_op
= OPC_NEG_D
;
13921 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
13922 mips32_op
= OPC_NEG_PS
;
13925 /* Reciprocal square root step */
13926 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
13927 mips32_op
= OPC_RSQRT1_S
;
13929 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
13930 mips32_op
= OPC_RSQRT1_D
;
13932 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
13933 mips32_op
= OPC_RSQRT1_PS
;
13936 /* Reciprocal step */
13937 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
13938 mips32_op
= OPC_RECIP1_S
;
13940 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
13941 mips32_op
= OPC_RECIP1_S
;
13943 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
13944 mips32_op
= OPC_RECIP1_PS
;
13947 /* Conversions from double */
13948 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
13949 mips32_op
= OPC_CVT_D_S
;
13951 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
13952 mips32_op
= OPC_CVT_D_W
;
13954 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
13955 mips32_op
= OPC_CVT_D_L
;
13958 /* Conversions from single */
13959 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
13960 mips32_op
= OPC_CVT_S_D
;
13962 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
13963 mips32_op
= OPC_CVT_S_W
;
13965 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
13966 mips32_op
= OPC_CVT_S_L
;
13968 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
13971 /* Conditional moves on floating-point codes */
13972 case COND_FLOAT_MOV(MOVT
, 0):
13973 case COND_FLOAT_MOV(MOVT
, 1):
13974 case COND_FLOAT_MOV(MOVT
, 2):
13975 case COND_FLOAT_MOV(MOVT
, 3):
13976 case COND_FLOAT_MOV(MOVT
, 4):
13977 case COND_FLOAT_MOV(MOVT
, 5):
13978 case COND_FLOAT_MOV(MOVT
, 6):
13979 case COND_FLOAT_MOV(MOVT
, 7):
13980 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13981 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
13983 case COND_FLOAT_MOV(MOVF
, 0):
13984 case COND_FLOAT_MOV(MOVF
, 1):
13985 case COND_FLOAT_MOV(MOVF
, 2):
13986 case COND_FLOAT_MOV(MOVF
, 3):
13987 case COND_FLOAT_MOV(MOVF
, 4):
13988 case COND_FLOAT_MOV(MOVF
, 5):
13989 case COND_FLOAT_MOV(MOVF
, 6):
13990 case COND_FLOAT_MOV(MOVF
, 7):
13991 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13992 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
13995 MIPS_INVAL("pool32fxf");
13996 generate_exception(ctx
, EXCP_RI
);
14001 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
14005 int rt
, rs
, rd
, rr
;
14007 uint32_t op
, minor
, mips32_op
;
14008 uint32_t cond
, fmt
, cc
;
14010 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
14011 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
14013 rt
= (ctx
->opcode
>> 21) & 0x1f;
14014 rs
= (ctx
->opcode
>> 16) & 0x1f;
14015 rd
= (ctx
->opcode
>> 11) & 0x1f;
14016 rr
= (ctx
->opcode
>> 6) & 0x1f;
14017 imm
= (int16_t) ctx
->opcode
;
14019 op
= (ctx
->opcode
>> 26) & 0x3f;
14022 minor
= ctx
->opcode
& 0x3f;
14025 minor
= (ctx
->opcode
>> 6) & 0xf;
14028 mips32_op
= OPC_SLL
;
14031 mips32_op
= OPC_SRA
;
14034 mips32_op
= OPC_SRL
;
14037 mips32_op
= OPC_ROTR
;
14039 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
14042 check_insn(ctx
, ISA_MIPS32R6
);
14043 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
14046 check_insn(ctx
, ISA_MIPS32R6
);
14047 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
14050 goto pool32a_invalid
;
14054 minor
= (ctx
->opcode
>> 6) & 0xf;
14058 mips32_op
= OPC_ADD
;
14061 mips32_op
= OPC_ADDU
;
14064 mips32_op
= OPC_SUB
;
14067 mips32_op
= OPC_SUBU
;
14070 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14071 mips32_op
= OPC_MUL
;
14073 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
14077 mips32_op
= OPC_SLLV
;
14080 mips32_op
= OPC_SRLV
;
14083 mips32_op
= OPC_SRAV
;
14086 mips32_op
= OPC_ROTRV
;
14088 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
14090 /* Logical operations */
14092 mips32_op
= OPC_AND
;
14095 mips32_op
= OPC_OR
;
14098 mips32_op
= OPC_NOR
;
14101 mips32_op
= OPC_XOR
;
14103 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
14105 /* Set less than */
14107 mips32_op
= OPC_SLT
;
14110 mips32_op
= OPC_SLTU
;
14112 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
14115 goto pool32a_invalid
;
14119 minor
= (ctx
->opcode
>> 6) & 0xf;
14121 /* Conditional moves */
14122 case MOVN
: /* MUL */
14123 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14125 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
14128 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
14131 case MOVZ
: /* MUH */
14132 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14134 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
14137 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
14141 check_insn(ctx
, ISA_MIPS32R6
);
14142 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
14145 check_insn(ctx
, ISA_MIPS32R6
);
14146 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
14148 case LWXS
: /* DIV */
14149 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14151 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
14154 gen_ldxs(ctx
, rs
, rt
, rd
);
14158 check_insn(ctx
, ISA_MIPS32R6
);
14159 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
14162 check_insn(ctx
, ISA_MIPS32R6
);
14163 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
14166 check_insn(ctx
, ISA_MIPS32R6
);
14167 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
14170 goto pool32a_invalid
;
14174 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
14177 check_insn(ctx
, ISA_MIPS32R6
);
14178 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
14179 extract32(ctx
->opcode
, 9, 2));
14182 check_insn(ctx
, ISA_MIPS32R6
);
14183 gen_align(ctx
, OPC_ALIGN
, rd
, rs
, rt
,
14184 extract32(ctx
->opcode
, 9, 2));
14187 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
14190 gen_pool32axf(env
, ctx
, rt
, rs
);
14193 generate_exception(ctx
, EXCP_BREAK
);
14197 MIPS_INVAL("pool32a");
14198 generate_exception(ctx
, EXCP_RI
);
14203 minor
= (ctx
->opcode
>> 12) & 0xf;
14206 check_cp0_enabled(ctx
);
14207 /* Treat as no-op. */
14211 /* COP2: Not implemented. */
14212 generate_exception_err(ctx
, EXCP_CpU
, 2);
14214 #ifdef TARGET_MIPS64
14217 check_insn(ctx
, ISA_MIPS3
);
14218 check_mips_64(ctx
);
14223 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14225 #ifdef TARGET_MIPS64
14228 check_insn(ctx
, ISA_MIPS3
);
14229 check_mips_64(ctx
);
14234 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14237 MIPS_INVAL("pool32b");
14238 generate_exception(ctx
, EXCP_RI
);
14243 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
14244 minor
= ctx
->opcode
& 0x3f;
14245 check_cp1_enabled(ctx
);
14248 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14249 mips32_op
= OPC_ALNV_PS
;
14252 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14253 mips32_op
= OPC_MADD_S
;
14256 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14257 mips32_op
= OPC_MADD_D
;
14260 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14261 mips32_op
= OPC_MADD_PS
;
14264 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14265 mips32_op
= OPC_MSUB_S
;
14268 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14269 mips32_op
= OPC_MSUB_D
;
14272 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14273 mips32_op
= OPC_MSUB_PS
;
14276 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14277 mips32_op
= OPC_NMADD_S
;
14280 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14281 mips32_op
= OPC_NMADD_D
;
14284 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14285 mips32_op
= OPC_NMADD_PS
;
14288 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14289 mips32_op
= OPC_NMSUB_S
;
14292 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14293 mips32_op
= OPC_NMSUB_D
;
14296 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14297 mips32_op
= OPC_NMSUB_PS
;
14299 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
14301 case CABS_COND_FMT
:
14302 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14303 cond
= (ctx
->opcode
>> 6) & 0xf;
14304 cc
= (ctx
->opcode
>> 13) & 0x7;
14305 fmt
= (ctx
->opcode
>> 10) & 0x3;
14308 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
14311 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
14314 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
14317 goto pool32f_invalid
;
14321 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14322 cond
= (ctx
->opcode
>> 6) & 0xf;
14323 cc
= (ctx
->opcode
>> 13) & 0x7;
14324 fmt
= (ctx
->opcode
>> 10) & 0x3;
14327 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
14330 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
14333 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
14336 goto pool32f_invalid
;
14340 check_insn(ctx
, ISA_MIPS32R6
);
14341 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
14344 check_insn(ctx
, ISA_MIPS32R6
);
14345 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
14348 gen_pool32fxf(ctx
, rt
, rs
);
14352 switch ((ctx
->opcode
>> 6) & 0x7) {
14354 mips32_op
= OPC_PLL_PS
;
14357 mips32_op
= OPC_PLU_PS
;
14360 mips32_op
= OPC_PUL_PS
;
14363 mips32_op
= OPC_PUU_PS
;
14366 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14367 mips32_op
= OPC_CVT_PS_S
;
14369 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14372 goto pool32f_invalid
;
14376 check_insn(ctx
, ISA_MIPS32R6
);
14377 switch ((ctx
->opcode
>> 9) & 0x3) {
14379 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
14382 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
14385 goto pool32f_invalid
;
14390 switch ((ctx
->opcode
>> 6) & 0x7) {
14392 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14393 mips32_op
= OPC_LWXC1
;
14396 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14397 mips32_op
= OPC_SWXC1
;
14400 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14401 mips32_op
= OPC_LDXC1
;
14404 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14405 mips32_op
= OPC_SDXC1
;
14408 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14409 mips32_op
= OPC_LUXC1
;
14412 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14413 mips32_op
= OPC_SUXC1
;
14415 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
14418 goto pool32f_invalid
;
14422 check_insn(ctx
, ISA_MIPS32R6
);
14423 switch ((ctx
->opcode
>> 9) & 0x3) {
14425 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
14428 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
14431 goto pool32f_invalid
;
14436 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14437 fmt
= (ctx
->opcode
>> 9) & 0x3;
14438 switch ((ctx
->opcode
>> 6) & 0x7) {
14442 mips32_op
= OPC_RSQRT2_S
;
14445 mips32_op
= OPC_RSQRT2_D
;
14448 mips32_op
= OPC_RSQRT2_PS
;
14451 goto pool32f_invalid
;
14457 mips32_op
= OPC_RECIP2_S
;
14460 mips32_op
= OPC_RECIP2_D
;
14463 mips32_op
= OPC_RECIP2_PS
;
14466 goto pool32f_invalid
;
14470 mips32_op
= OPC_ADDR_PS
;
14473 mips32_op
= OPC_MULR_PS
;
14475 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14478 goto pool32f_invalid
;
14482 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14483 cc
= (ctx
->opcode
>> 13) & 0x7;
14484 fmt
= (ctx
->opcode
>> 9) & 0x3;
14485 switch ((ctx
->opcode
>> 6) & 0x7) {
14486 case MOVF_FMT
: /* RINT_FMT */
14487 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14491 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
14494 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
14497 goto pool32f_invalid
;
14503 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
14506 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
14510 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
14513 goto pool32f_invalid
;
14517 case MOVT_FMT
: /* CLASS_FMT */
14518 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14522 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
14525 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
14528 goto pool32f_invalid
;
14534 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
14537 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
14541 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
14544 goto pool32f_invalid
;
14549 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14552 goto pool32f_invalid
;
14555 #define FINSN_3ARG_SDPS(prfx) \
14556 switch ((ctx->opcode >> 8) & 0x3) { \
14558 mips32_op = OPC_##prfx##_S; \
14561 mips32_op = OPC_##prfx##_D; \
14563 case FMT_SDPS_PS: \
14565 mips32_op = OPC_##prfx##_PS; \
14568 goto pool32f_invalid; \
14571 check_insn(ctx
, ISA_MIPS32R6
);
14572 switch ((ctx
->opcode
>> 9) & 0x3) {
14574 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
14577 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
14580 goto pool32f_invalid
;
14584 check_insn(ctx
, ISA_MIPS32R6
);
14585 switch ((ctx
->opcode
>> 9) & 0x3) {
14587 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
14590 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
14593 goto pool32f_invalid
;
14597 /* regular FP ops */
14598 switch ((ctx
->opcode
>> 6) & 0x3) {
14600 FINSN_3ARG_SDPS(ADD
);
14603 FINSN_3ARG_SDPS(SUB
);
14606 FINSN_3ARG_SDPS(MUL
);
14609 fmt
= (ctx
->opcode
>> 8) & 0x3;
14611 mips32_op
= OPC_DIV_D
;
14612 } else if (fmt
== 0) {
14613 mips32_op
= OPC_DIV_S
;
14615 goto pool32f_invalid
;
14619 goto pool32f_invalid
;
14624 switch ((ctx
->opcode
>> 6) & 0x7) {
14625 case MOVN_FMT
: /* SELNEZ_FMT */
14626 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14628 switch ((ctx
->opcode
>> 9) & 0x3) {
14630 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
14633 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
14636 goto pool32f_invalid
;
14640 FINSN_3ARG_SDPS(MOVN
);
14644 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14645 FINSN_3ARG_SDPS(MOVN
);
14647 case MOVZ_FMT
: /* SELEQZ_FMT */
14648 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14650 switch ((ctx
->opcode
>> 9) & 0x3) {
14652 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
14655 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
14658 goto pool32f_invalid
;
14662 FINSN_3ARG_SDPS(MOVZ
);
14666 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14667 FINSN_3ARG_SDPS(MOVZ
);
14670 check_insn(ctx
, ISA_MIPS32R6
);
14671 switch ((ctx
->opcode
>> 9) & 0x3) {
14673 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
14676 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
14679 goto pool32f_invalid
;
14683 check_insn(ctx
, ISA_MIPS32R6
);
14684 switch ((ctx
->opcode
>> 9) & 0x3) {
14686 mips32_op
= OPC_MADDF_S
;
14689 mips32_op
= OPC_MADDF_D
;
14692 goto pool32f_invalid
;
14696 check_insn(ctx
, ISA_MIPS32R6
);
14697 switch ((ctx
->opcode
>> 9) & 0x3) {
14699 mips32_op
= OPC_MSUBF_S
;
14702 mips32_op
= OPC_MSUBF_D
;
14705 goto pool32f_invalid
;
14709 goto pool32f_invalid
;
14713 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14717 MIPS_INVAL("pool32f");
14718 generate_exception(ctx
, EXCP_RI
);
14722 generate_exception_err(ctx
, EXCP_CpU
, 1);
14726 minor
= (ctx
->opcode
>> 21) & 0x1f;
14729 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14730 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
14733 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14734 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
14735 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14738 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14739 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
14740 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14743 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14744 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
14747 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14748 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
14749 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14752 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14753 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
14754 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14757 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14758 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
14761 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14762 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
14766 case TLTI
: /* BC1EQZC */
14767 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14769 check_cp1_enabled(ctx
);
14770 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
14773 mips32_op
= OPC_TLTI
;
14777 case TGEI
: /* BC1NEZC */
14778 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14780 check_cp1_enabled(ctx
);
14781 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
14784 mips32_op
= OPC_TGEI
;
14789 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14790 mips32_op
= OPC_TLTIU
;
14793 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14794 mips32_op
= OPC_TGEIU
;
14796 case TNEI
: /* SYNCI */
14797 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14799 /* Break the TB to be able to sync copied instructions
14801 ctx
->bstate
= BS_STOP
;
14804 mips32_op
= OPC_TNEI
;
14809 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14810 mips32_op
= OPC_TEQI
;
14812 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
14817 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14818 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
14819 4, rs
, 0, imm
<< 1, 0);
14820 /* Compact branches don't have a delay slot, so just let
14821 the normal delay slot handling take us to the branch
14825 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14826 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
14829 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14830 /* Break the TB to be able to sync copied instructions
14832 ctx
->bstate
= BS_STOP
;
14836 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14837 /* COP2: Not implemented. */
14838 generate_exception_err(ctx
, EXCP_CpU
, 2);
14841 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14842 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
14845 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14846 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
14849 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14850 mips32_op
= OPC_BC1FANY4
;
14853 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14854 mips32_op
= OPC_BC1TANY4
;
14857 check_insn(ctx
, ASE_MIPS3D
);
14860 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14861 check_cp1_enabled(ctx
);
14862 gen_compute_branch1(ctx
, mips32_op
,
14863 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
14865 generate_exception_err(ctx
, EXCP_CpU
, 1);
14870 /* MIPS DSP: not implemented */
14873 MIPS_INVAL("pool32i");
14874 generate_exception(ctx
, EXCP_RI
);
14879 minor
= (ctx
->opcode
>> 12) & 0xf;
14880 offset
= sextract32(ctx
->opcode
, 0,
14881 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
14884 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14885 mips32_op
= OPC_LWL
;
14888 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14889 mips32_op
= OPC_SWL
;
14892 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14893 mips32_op
= OPC_LWR
;
14896 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14897 mips32_op
= OPC_SWR
;
14899 #if defined(TARGET_MIPS64)
14901 check_insn(ctx
, ISA_MIPS3
);
14902 check_mips_64(ctx
);
14903 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14904 mips32_op
= OPC_LDL
;
14907 check_insn(ctx
, ISA_MIPS3
);
14908 check_mips_64(ctx
);
14909 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14910 mips32_op
= OPC_SDL
;
14913 check_insn(ctx
, ISA_MIPS3
);
14914 check_mips_64(ctx
);
14915 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14916 mips32_op
= OPC_LDR
;
14919 check_insn(ctx
, ISA_MIPS3
);
14920 check_mips_64(ctx
);
14921 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14922 mips32_op
= OPC_SDR
;
14925 check_insn(ctx
, ISA_MIPS3
);
14926 check_mips_64(ctx
);
14927 mips32_op
= OPC_LWU
;
14930 check_insn(ctx
, ISA_MIPS3
);
14931 check_mips_64(ctx
);
14932 mips32_op
= OPC_LLD
;
14936 mips32_op
= OPC_LL
;
14939 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
14942 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14945 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, offset
);
14947 #if defined(TARGET_MIPS64)
14949 check_insn(ctx
, ISA_MIPS3
);
14950 check_mips_64(ctx
);
14951 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, offset
);
14955 /* Treat as no-op */
14956 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
14957 /* hint codes 24-31 are reserved and signal RI */
14958 generate_exception(ctx
, EXCP_RI
);
14962 MIPS_INVAL("pool32c");
14963 generate_exception(ctx
, EXCP_RI
);
14967 case ADDI32
: /* AUI, LUI */
14968 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14970 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
14973 mips32_op
= OPC_ADDI
;
14978 mips32_op
= OPC_ADDIU
;
14980 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14983 /* Logical operations */
14985 mips32_op
= OPC_ORI
;
14988 mips32_op
= OPC_XORI
;
14991 mips32_op
= OPC_ANDI
;
14993 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14996 /* Set less than immediate */
14998 mips32_op
= OPC_SLTI
;
15001 mips32_op
= OPC_SLTIU
;
15003 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
15006 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15007 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15008 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
15009 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15011 case JALS32
: /* BOVC, BEQC, BEQZALC */
15012 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15015 mips32_op
= OPC_BOVC
;
15016 } else if (rs
< rt
&& rs
== 0) {
15018 mips32_op
= OPC_BEQZALC
;
15021 mips32_op
= OPC_BEQC
;
15023 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15026 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
15027 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
15028 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15031 case BEQ32
: /* BC */
15032 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15034 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
15035 sextract32(ctx
->opcode
<< 1, 0, 27));
15038 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
15041 case BNE32
: /* BALC */
15042 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15044 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
15045 sextract32(ctx
->opcode
<< 1, 0, 27));
15048 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
15051 case J32
: /* BGTZC, BLTZC, BLTC */
15052 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15053 if (rs
== 0 && rt
!= 0) {
15055 mips32_op
= OPC_BGTZC
;
15056 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15058 mips32_op
= OPC_BLTZC
;
15061 mips32_op
= OPC_BLTC
;
15063 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15066 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
15067 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
15070 case JAL32
: /* BLEZC, BGEZC, BGEC */
15071 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15072 if (rs
== 0 && rt
!= 0) {
15074 mips32_op
= OPC_BLEZC
;
15075 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15077 mips32_op
= OPC_BGEZC
;
15080 mips32_op
= OPC_BGEC
;
15082 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15085 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
15086 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
15087 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
15090 /* Floating point (COP1) */
15092 mips32_op
= OPC_LWC1
;
15095 mips32_op
= OPC_LDC1
;
15098 mips32_op
= OPC_SWC1
;
15101 mips32_op
= OPC_SDC1
;
15103 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
15105 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15106 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15107 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
15108 switch ((ctx
->opcode
>> 16) & 0x1f) {
15109 case ADDIUPC_00
... ADDIUPC_07
:
15110 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->pc
& ~0x3, rt
);
15113 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->pc
, rt
);
15116 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->pc
, rt
);
15118 case LWPC_08
... LWPC_0F
:
15119 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->pc
& ~0x3, rt
);
15122 generate_exception(ctx
, EXCP_RI
);
15127 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
15128 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
15130 gen_addiupc(ctx
, reg
, offset
, 0, 0);
15133 case BNVC
: /* BNEC, BNEZALC */
15134 check_insn(ctx
, ISA_MIPS32R6
);
15137 mips32_op
= OPC_BNVC
;
15138 } else if (rs
< rt
&& rs
== 0) {
15140 mips32_op
= OPC_BNEZALC
;
15143 mips32_op
= OPC_BNEC
;
15145 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15147 case R6_BNEZC
: /* JIALC */
15148 check_insn(ctx
, ISA_MIPS32R6
);
15151 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
15152 sextract32(ctx
->opcode
<< 1, 0, 22));
15155 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
15158 case R6_BEQZC
: /* JIC */
15159 check_insn(ctx
, ISA_MIPS32R6
);
15162 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
15163 sextract32(ctx
->opcode
<< 1, 0, 22));
15166 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
15169 case BLEZALC
: /* BGEZALC, BGEUC */
15170 check_insn(ctx
, ISA_MIPS32R6
);
15171 if (rs
== 0 && rt
!= 0) {
15173 mips32_op
= OPC_BLEZALC
;
15174 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15176 mips32_op
= OPC_BGEZALC
;
15179 mips32_op
= OPC_BGEUC
;
15181 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15183 case BGTZALC
: /* BLTZALC, BLTUC */
15184 check_insn(ctx
, ISA_MIPS32R6
);
15185 if (rs
== 0 && rt
!= 0) {
15187 mips32_op
= OPC_BGTZALC
;
15188 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15190 mips32_op
= OPC_BLTZALC
;
15193 mips32_op
= OPC_BLTUC
;
15195 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
15197 /* Loads and stores */
15199 mips32_op
= OPC_LB
;
15202 mips32_op
= OPC_LBU
;
15205 mips32_op
= OPC_LH
;
15208 mips32_op
= OPC_LHU
;
15211 mips32_op
= OPC_LW
;
15213 #ifdef TARGET_MIPS64
15215 check_insn(ctx
, ISA_MIPS3
);
15216 check_mips_64(ctx
);
15217 mips32_op
= OPC_LD
;
15220 check_insn(ctx
, ISA_MIPS3
);
15221 check_mips_64(ctx
);
15222 mips32_op
= OPC_SD
;
15226 mips32_op
= OPC_SB
;
15229 mips32_op
= OPC_SH
;
15232 mips32_op
= OPC_SW
;
15235 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
15238 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
15241 generate_exception(ctx
, EXCP_RI
);
15246 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
15250 /* make sure instructions are on a halfword boundary */
15251 if (ctx
->pc
& 0x1) {
15252 env
->CP0_BadVAddr
= ctx
->pc
;
15253 generate_exception(ctx
, EXCP_AdEL
);
15254 ctx
->bstate
= BS_STOP
;
15258 op
= (ctx
->opcode
>> 10) & 0x3f;
15259 /* Enforce properly-sized instructions in a delay slot */
15260 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
15261 switch (op
& 0x7) { /* MSB-3..MSB-5 */
15263 /* POOL32A, POOL32B, POOL32I, POOL32C */
15265 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15267 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15269 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15271 /* LB32, LH32, LWC132, LDC132, LW32 */
15272 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
15273 generate_exception(ctx
, EXCP_RI
);
15274 /* Just stop translation; the user is confused. */
15275 ctx
->bstate
= BS_STOP
;
15280 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15282 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15284 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15285 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
15286 generate_exception(ctx
, EXCP_RI
);
15287 /* Just stop translation; the user is confused. */
15288 ctx
->bstate
= BS_STOP
;
15298 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15299 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
15300 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
15303 switch (ctx
->opcode
& 0x1) {
15311 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15312 /* In the Release 6 the register number location in
15313 * the instruction encoding has changed.
15315 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
15317 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
15323 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15324 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15325 int amount
= (ctx
->opcode
>> 1) & 0x7;
15327 amount
= amount
== 0 ? 8 : amount
;
15329 switch (ctx
->opcode
& 0x1) {
15338 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
15342 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15343 gen_pool16c_r6_insn(ctx
);
15345 gen_pool16c_insn(ctx
);
15350 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15351 int rb
= 28; /* GP */
15352 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
15354 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15358 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15359 if (ctx
->opcode
& 1) {
15360 generate_exception(ctx
, EXCP_RI
);
15363 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15364 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15365 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
15366 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15371 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15372 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15373 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
15374 offset
= (offset
== 0xf ? -1 : offset
);
15376 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
15381 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15382 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15383 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
15385 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
15390 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15391 int rb
= 29; /* SP */
15392 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
15394 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15399 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15400 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15401 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
15403 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15408 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15409 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15410 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
15412 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
15417 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15418 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15419 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
15421 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
15426 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15427 int rb
= 29; /* SP */
15428 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
15430 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
15435 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15436 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15437 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
15439 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
15444 int rd
= uMIPS_RD5(ctx
->opcode
);
15445 int rs
= uMIPS_RS5(ctx
->opcode
);
15447 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
15454 switch (ctx
->opcode
& 0x1) {
15464 switch (ctx
->opcode
& 0x1) {
15469 gen_addiur1sp(ctx
);
15473 case B16
: /* BC16 */
15474 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
15475 sextract32(ctx
->opcode
, 0, 10) << 1,
15476 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
15478 case BNEZ16
: /* BNEZC16 */
15479 case BEQZ16
: /* BEQZC16 */
15480 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
15481 mmreg(uMIPS_RD(ctx
->opcode
)),
15482 0, sextract32(ctx
->opcode
, 0, 7) << 1,
15483 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
15488 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
15489 int imm
= ZIMM(ctx
->opcode
, 0, 7);
15491 imm
= (imm
== 0x7f ? -1 : imm
);
15492 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
15498 generate_exception(ctx
, EXCP_RI
);
15501 decode_micromips32_opc(env
, ctx
);
15508 /* SmartMIPS extension to MIPS32 */
15510 #if defined(TARGET_MIPS64)
15512 /* MDMX extension to MIPS64 */
15516 /* MIPSDSP functions. */
15517 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
15518 int rd
, int base
, int offset
)
15520 const char *opn
= "ldx";
15524 t0
= tcg_temp_new();
15527 gen_load_gpr(t0
, offset
);
15528 } else if (offset
== 0) {
15529 gen_load_gpr(t0
, base
);
15531 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
15536 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
15537 gen_store_gpr(t0
, rd
);
15541 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
15542 gen_store_gpr(t0
, rd
);
15546 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
15547 gen_store_gpr(t0
, rd
);
15550 #if defined(TARGET_MIPS64)
15552 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
15553 gen_store_gpr(t0
, rd
);
15558 (void)opn
; /* avoid a compiler warning */
15559 MIPS_DEBUG("%s %s, %s(%s)", opn
,
15560 regnames
[rd
], regnames
[offset
], regnames
[base
]);
15564 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15565 int ret
, int v1
, int v2
)
15567 const char *opn
= "mipsdsp arith";
15572 /* Treat as NOP. */
15577 v1_t
= tcg_temp_new();
15578 v2_t
= tcg_temp_new();
15580 gen_load_gpr(v1_t
, v1
);
15581 gen_load_gpr(v2_t
, v2
);
15584 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15585 case OPC_MULT_G_2E
:
15589 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15591 case OPC_ADDUH_R_QB
:
15592 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15595 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15597 case OPC_ADDQH_R_PH
:
15598 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15601 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15603 case OPC_ADDQH_R_W
:
15604 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15607 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15609 case OPC_SUBUH_R_QB
:
15610 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15613 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15615 case OPC_SUBQH_R_PH
:
15616 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15619 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15621 case OPC_SUBQH_R_W
:
15622 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15626 case OPC_ABSQ_S_PH_DSP
:
15628 case OPC_ABSQ_S_QB
:
15630 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
15632 case OPC_ABSQ_S_PH
:
15634 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
15638 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
15640 case OPC_PRECEQ_W_PHL
:
15642 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
15643 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15645 case OPC_PRECEQ_W_PHR
:
15647 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
15648 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
15649 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15651 case OPC_PRECEQU_PH_QBL
:
15653 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
15655 case OPC_PRECEQU_PH_QBR
:
15657 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
15659 case OPC_PRECEQU_PH_QBLA
:
15661 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
15663 case OPC_PRECEQU_PH_QBRA
:
15665 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
15667 case OPC_PRECEU_PH_QBL
:
15669 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
15671 case OPC_PRECEU_PH_QBR
:
15673 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
15675 case OPC_PRECEU_PH_QBLA
:
15677 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
15679 case OPC_PRECEU_PH_QBRA
:
15681 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
15685 case OPC_ADDU_QB_DSP
:
15689 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15691 case OPC_ADDQ_S_PH
:
15693 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15697 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15701 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15703 case OPC_ADDU_S_QB
:
15705 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15709 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15711 case OPC_ADDU_S_PH
:
15713 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15717 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15719 case OPC_SUBQ_S_PH
:
15721 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15725 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15729 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15731 case OPC_SUBU_S_QB
:
15733 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15737 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15739 case OPC_SUBU_S_PH
:
15741 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15745 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15749 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15753 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
15755 case OPC_RADDU_W_QB
:
15757 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
15761 case OPC_CMPU_EQ_QB_DSP
:
15763 case OPC_PRECR_QB_PH
:
15765 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15767 case OPC_PRECRQ_QB_PH
:
15769 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15771 case OPC_PRECR_SRA_PH_W
:
15774 TCGv_i32 sa_t
= tcg_const_i32(v2
);
15775 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
15777 tcg_temp_free_i32(sa_t
);
15780 case OPC_PRECR_SRA_R_PH_W
:
15783 TCGv_i32 sa_t
= tcg_const_i32(v2
);
15784 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
15786 tcg_temp_free_i32(sa_t
);
15789 case OPC_PRECRQ_PH_W
:
15791 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15793 case OPC_PRECRQ_RS_PH_W
:
15795 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15797 case OPC_PRECRQU_S_QB_PH
:
15799 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15803 #ifdef TARGET_MIPS64
15804 case OPC_ABSQ_S_QH_DSP
:
15806 case OPC_PRECEQ_L_PWL
:
15808 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
15810 case OPC_PRECEQ_L_PWR
:
15812 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
15814 case OPC_PRECEQ_PW_QHL
:
15816 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
15818 case OPC_PRECEQ_PW_QHR
:
15820 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
15822 case OPC_PRECEQ_PW_QHLA
:
15824 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
15826 case OPC_PRECEQ_PW_QHRA
:
15828 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
15830 case OPC_PRECEQU_QH_OBL
:
15832 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
15834 case OPC_PRECEQU_QH_OBR
:
15836 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
15838 case OPC_PRECEQU_QH_OBLA
:
15840 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
15842 case OPC_PRECEQU_QH_OBRA
:
15844 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
15846 case OPC_PRECEU_QH_OBL
:
15848 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
15850 case OPC_PRECEU_QH_OBR
:
15852 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
15854 case OPC_PRECEU_QH_OBLA
:
15856 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
15858 case OPC_PRECEU_QH_OBRA
:
15860 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
15862 case OPC_ABSQ_S_OB
:
15864 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
15866 case OPC_ABSQ_S_PW
:
15868 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
15870 case OPC_ABSQ_S_QH
:
15872 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
15876 case OPC_ADDU_OB_DSP
:
15878 case OPC_RADDU_L_OB
:
15880 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
15884 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15886 case OPC_SUBQ_S_PW
:
15888 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15892 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15894 case OPC_SUBQ_S_QH
:
15896 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15900 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15902 case OPC_SUBU_S_OB
:
15904 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15908 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15910 case OPC_SUBU_S_QH
:
15912 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15916 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15918 case OPC_SUBUH_R_OB
:
15920 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15924 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15926 case OPC_ADDQ_S_PW
:
15928 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15932 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15934 case OPC_ADDQ_S_QH
:
15936 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15940 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15942 case OPC_ADDU_S_OB
:
15944 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15948 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15950 case OPC_ADDU_S_QH
:
15952 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15956 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15958 case OPC_ADDUH_R_OB
:
15960 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15964 case OPC_CMPU_EQ_OB_DSP
:
15966 case OPC_PRECR_OB_QH
:
15968 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
15970 case OPC_PRECR_SRA_QH_PW
:
15973 TCGv_i32 ret_t
= tcg_const_i32(ret
);
15974 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
15975 tcg_temp_free_i32(ret_t
);
15978 case OPC_PRECR_SRA_R_QH_PW
:
15981 TCGv_i32 sa_v
= tcg_const_i32(ret
);
15982 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
15983 tcg_temp_free_i32(sa_v
);
15986 case OPC_PRECRQ_OB_QH
:
15988 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
15990 case OPC_PRECRQ_PW_L
:
15992 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
15994 case OPC_PRECRQ_QH_PW
:
15996 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
15998 case OPC_PRECRQ_RS_QH_PW
:
16000 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16002 case OPC_PRECRQU_S_OB_QH
:
16004 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16011 tcg_temp_free(v1_t
);
16012 tcg_temp_free(v2_t
);
16014 (void)opn
; /* avoid a compiler warning */
16015 MIPS_DEBUG("%s", opn
);
16018 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
16019 int ret
, int v1
, int v2
)
16022 const char *opn
= "mipsdsp shift";
16028 /* Treat as NOP. */
16033 t0
= tcg_temp_new();
16034 v1_t
= tcg_temp_new();
16035 v2_t
= tcg_temp_new();
16037 tcg_gen_movi_tl(t0
, v1
);
16038 gen_load_gpr(v1_t
, v1
);
16039 gen_load_gpr(v2_t
, v2
);
16042 case OPC_SHLL_QB_DSP
:
16044 op2
= MASK_SHLL_QB(ctx
->opcode
);
16048 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16052 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16056 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16060 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16062 case OPC_SHLL_S_PH
:
16064 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16066 case OPC_SHLLV_S_PH
:
16068 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16072 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
16074 case OPC_SHLLV_S_W
:
16076 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16080 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
16084 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16088 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
16092 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16096 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
16098 case OPC_SHRA_R_QB
:
16100 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
16104 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16106 case OPC_SHRAV_R_QB
:
16108 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16112 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
16114 case OPC_SHRA_R_PH
:
16116 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
16120 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16122 case OPC_SHRAV_R_PH
:
16124 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16128 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
16130 case OPC_SHRAV_R_W
:
16132 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
16134 default: /* Invalid */
16135 MIPS_INVAL("MASK SHLL.QB");
16136 generate_exception(ctx
, EXCP_RI
);
16141 #ifdef TARGET_MIPS64
16142 case OPC_SHLL_OB_DSP
:
16143 op2
= MASK_SHLL_OB(ctx
->opcode
);
16147 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16151 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16153 case OPC_SHLL_S_PW
:
16155 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16157 case OPC_SHLLV_S_PW
:
16159 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16163 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16167 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16171 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16175 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16177 case OPC_SHLL_S_QH
:
16179 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
16181 case OPC_SHLLV_S_QH
:
16183 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
16187 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
16191 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
16193 case OPC_SHRA_R_OB
:
16195 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
16197 case OPC_SHRAV_R_OB
:
16199 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
16203 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
16207 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
16209 case OPC_SHRA_R_PW
:
16211 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
16213 case OPC_SHRAV_R_PW
:
16215 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
16219 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
16223 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
16225 case OPC_SHRA_R_QH
:
16227 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
16229 case OPC_SHRAV_R_QH
:
16231 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
16235 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
16239 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
16243 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
16247 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
16249 default: /* Invalid */
16250 MIPS_INVAL("MASK SHLL.OB");
16251 generate_exception(ctx
, EXCP_RI
);
16259 tcg_temp_free(v1_t
);
16260 tcg_temp_free(v2_t
);
16261 (void)opn
; /* avoid a compiler warning */
16262 MIPS_DEBUG("%s", opn
);
16265 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16266 int ret
, int v1
, int v2
, int check_ret
)
16268 const char *opn
= "mipsdsp multiply";
16273 if ((ret
== 0) && (check_ret
== 1)) {
16274 /* Treat as NOP. */
16279 t0
= tcg_temp_new_i32();
16280 v1_t
= tcg_temp_new();
16281 v2_t
= tcg_temp_new();
16283 tcg_gen_movi_i32(t0
, ret
);
16284 gen_load_gpr(v1_t
, v1
);
16285 gen_load_gpr(v2_t
, v2
);
16288 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16289 * the same mask and op1. */
16290 case OPC_MULT_G_2E
:
16294 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16297 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16300 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16302 case OPC_MULQ_RS_W
:
16303 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16307 case OPC_DPA_W_PH_DSP
:
16309 case OPC_DPAU_H_QBL
:
16311 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
16313 case OPC_DPAU_H_QBR
:
16315 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
16317 case OPC_DPSU_H_QBL
:
16319 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
16321 case OPC_DPSU_H_QBR
:
16323 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
16327 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16329 case OPC_DPAX_W_PH
:
16331 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16333 case OPC_DPAQ_S_W_PH
:
16335 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16337 case OPC_DPAQX_S_W_PH
:
16339 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16341 case OPC_DPAQX_SA_W_PH
:
16343 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16347 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16349 case OPC_DPSX_W_PH
:
16351 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16353 case OPC_DPSQ_S_W_PH
:
16355 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16357 case OPC_DPSQX_S_W_PH
:
16359 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16361 case OPC_DPSQX_SA_W_PH
:
16363 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16365 case OPC_MULSAQ_S_W_PH
:
16367 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16369 case OPC_DPAQ_SA_L_W
:
16371 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
16373 case OPC_DPSQ_SA_L_W
:
16375 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
16377 case OPC_MAQ_S_W_PHL
:
16379 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
16381 case OPC_MAQ_S_W_PHR
:
16383 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
16385 case OPC_MAQ_SA_W_PHL
:
16387 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
16389 case OPC_MAQ_SA_W_PHR
:
16391 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
16393 case OPC_MULSA_W_PH
:
16395 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16399 #ifdef TARGET_MIPS64
16400 case OPC_DPAQ_W_QH_DSP
:
16402 int ac
= ret
& 0x03;
16403 tcg_gen_movi_i32(t0
, ac
);
16408 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
16412 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
16416 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
16420 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
16424 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16426 case OPC_DPAQ_S_W_QH
:
16428 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16430 case OPC_DPAQ_SA_L_PW
:
16432 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16434 case OPC_DPAU_H_OBL
:
16436 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
16438 case OPC_DPAU_H_OBR
:
16440 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
16444 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16446 case OPC_DPSQ_S_W_QH
:
16448 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16450 case OPC_DPSQ_SA_L_PW
:
16452 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16454 case OPC_DPSU_H_OBL
:
16456 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
16458 case OPC_DPSU_H_OBR
:
16460 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
16462 case OPC_MAQ_S_L_PWL
:
16464 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
16466 case OPC_MAQ_S_L_PWR
:
16468 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
16470 case OPC_MAQ_S_W_QHLL
:
16472 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
16474 case OPC_MAQ_SA_W_QHLL
:
16476 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
16478 case OPC_MAQ_S_W_QHLR
:
16480 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
16482 case OPC_MAQ_SA_W_QHLR
:
16484 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
16486 case OPC_MAQ_S_W_QHRL
:
16488 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
16490 case OPC_MAQ_SA_W_QHRL
:
16492 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
16494 case OPC_MAQ_S_W_QHRR
:
16496 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
16498 case OPC_MAQ_SA_W_QHRR
:
16500 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
16502 case OPC_MULSAQ_S_L_PW
:
16504 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16506 case OPC_MULSAQ_S_W_QH
:
16508 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16514 case OPC_ADDU_QB_DSP
:
16516 case OPC_MULEU_S_PH_QBL
:
16518 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16520 case OPC_MULEU_S_PH_QBR
:
16522 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16524 case OPC_MULQ_RS_PH
:
16526 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16528 case OPC_MULEQ_S_W_PHL
:
16530 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16532 case OPC_MULEQ_S_W_PHR
:
16534 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16536 case OPC_MULQ_S_PH
:
16538 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16542 #ifdef TARGET_MIPS64
16543 case OPC_ADDU_OB_DSP
:
16545 case OPC_MULEQ_S_PW_QHL
:
16547 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16549 case OPC_MULEQ_S_PW_QHR
:
16551 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16553 case OPC_MULEU_S_QH_OBL
:
16555 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16557 case OPC_MULEU_S_QH_OBR
:
16559 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16561 case OPC_MULQ_RS_QH
:
16563 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16570 tcg_temp_free_i32(t0
);
16571 tcg_temp_free(v1_t
);
16572 tcg_temp_free(v2_t
);
16574 (void)opn
; /* avoid a compiler warning */
16575 MIPS_DEBUG("%s", opn
);
16579 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16582 const char *opn
= "mipsdsp Bit/ Manipulation";
16588 /* Treat as NOP. */
16593 t0
= tcg_temp_new();
16594 val_t
= tcg_temp_new();
16595 gen_load_gpr(val_t
, val
);
16598 case OPC_ABSQ_S_PH_DSP
:
16602 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
16607 target_long result
;
16608 imm
= (ctx
->opcode
>> 16) & 0xFF;
16609 result
= (uint32_t)imm
<< 24 |
16610 (uint32_t)imm
<< 16 |
16611 (uint32_t)imm
<< 8 |
16613 result
= (int32_t)result
;
16614 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
16619 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
16620 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
16621 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16622 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16623 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16624 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
16629 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16630 imm
= (int16_t)(imm
<< 6) >> 6;
16631 tcg_gen_movi_tl(cpu_gpr
[ret
], \
16632 (target_long
)((int32_t)imm
<< 16 | \
16638 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
16639 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16640 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16641 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
16645 #ifdef TARGET_MIPS64
16646 case OPC_ABSQ_S_QH_DSP
:
16653 imm
= (ctx
->opcode
>> 16) & 0xFF;
16654 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
16655 temp
= (temp
<< 16) | temp
;
16656 temp
= (temp
<< 32) | temp
;
16657 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16665 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16666 imm
= (int16_t)(imm
<< 6) >> 6;
16667 temp
= ((target_long
)imm
<< 32) \
16668 | ((target_long
)imm
& 0xFFFFFFFF);
16669 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16677 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16678 imm
= (int16_t)(imm
<< 6) >> 6;
16680 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
16681 ((uint64_t)(uint16_t)imm
<< 32) |
16682 ((uint64_t)(uint16_t)imm
<< 16) |
16683 (uint64_t)(uint16_t)imm
;
16684 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16689 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
16690 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
16691 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16692 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16693 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16694 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16695 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16699 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
16700 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16701 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16705 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
16706 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16707 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16708 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16709 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16716 tcg_temp_free(val_t
);
16718 (void)opn
; /* avoid a compiler warning */
16719 MIPS_DEBUG("%s", opn
);
16722 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
16723 uint32_t op1
, uint32_t op2
,
16724 int ret
, int v1
, int v2
, int check_ret
)
16726 const char *opn
= "mipsdsp add compare pick";
16731 if ((ret
== 0) && (check_ret
== 1)) {
16732 /* Treat as NOP. */
16737 t1
= tcg_temp_new();
16738 v1_t
= tcg_temp_new();
16739 v2_t
= tcg_temp_new();
16741 gen_load_gpr(v1_t
, v1
);
16742 gen_load_gpr(v2_t
, v2
);
16745 case OPC_CMPU_EQ_QB_DSP
:
16747 case OPC_CMPU_EQ_QB
:
16749 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
16751 case OPC_CMPU_LT_QB
:
16753 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
16755 case OPC_CMPU_LE_QB
:
16757 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
16759 case OPC_CMPGU_EQ_QB
:
16761 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16763 case OPC_CMPGU_LT_QB
:
16765 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16767 case OPC_CMPGU_LE_QB
:
16769 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16771 case OPC_CMPGDU_EQ_QB
:
16773 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
16774 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16775 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16776 tcg_gen_shli_tl(t1
, t1
, 24);
16777 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16779 case OPC_CMPGDU_LT_QB
:
16781 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
16782 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16783 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16784 tcg_gen_shli_tl(t1
, t1
, 24);
16785 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16787 case OPC_CMPGDU_LE_QB
:
16789 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
16790 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16791 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16792 tcg_gen_shli_tl(t1
, t1
, 24);
16793 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16795 case OPC_CMP_EQ_PH
:
16797 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
16799 case OPC_CMP_LT_PH
:
16801 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
16803 case OPC_CMP_LE_PH
:
16805 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
16809 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16813 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16815 case OPC_PACKRL_PH
:
16817 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16821 #ifdef TARGET_MIPS64
16822 case OPC_CMPU_EQ_OB_DSP
:
16824 case OPC_CMP_EQ_PW
:
16826 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
16828 case OPC_CMP_LT_PW
:
16830 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
16832 case OPC_CMP_LE_PW
:
16834 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
16836 case OPC_CMP_EQ_QH
:
16838 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
16840 case OPC_CMP_LT_QH
:
16842 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
16844 case OPC_CMP_LE_QH
:
16846 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
16848 case OPC_CMPGDU_EQ_OB
:
16850 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16852 case OPC_CMPGDU_LT_OB
:
16854 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16856 case OPC_CMPGDU_LE_OB
:
16858 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16860 case OPC_CMPGU_EQ_OB
:
16862 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16864 case OPC_CMPGU_LT_OB
:
16866 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16868 case OPC_CMPGU_LE_OB
:
16870 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16872 case OPC_CMPU_EQ_OB
:
16874 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
16876 case OPC_CMPU_LT_OB
:
16878 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
16880 case OPC_CMPU_LE_OB
:
16882 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
16884 case OPC_PACKRL_PW
:
16886 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
16890 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16894 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16898 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16906 tcg_temp_free(v1_t
);
16907 tcg_temp_free(v2_t
);
16909 (void)opn
; /* avoid a compiler warning */
16910 MIPS_DEBUG("%s", opn
);
16913 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
16914 uint32_t op1
, int rt
, int rs
, int sa
)
16916 const char *opn
= "mipsdsp append/dappend";
16922 /* Treat as NOP. */
16927 t0
= tcg_temp_new();
16928 gen_load_gpr(t0
, rs
);
16931 case OPC_APPEND_DSP
:
16932 switch (MASK_APPEND(ctx
->opcode
)) {
16935 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
16937 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16941 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16942 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
16943 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
16944 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16946 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16950 if (sa
!= 0 && sa
!= 2) {
16951 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
16952 tcg_gen_ext32u_tl(t0
, t0
);
16953 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
16954 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16956 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16958 default: /* Invalid */
16959 MIPS_INVAL("MASK APPEND");
16960 generate_exception(ctx
, EXCP_RI
);
16964 #ifdef TARGET_MIPS64
16965 case OPC_DAPPEND_DSP
:
16966 switch (MASK_DAPPEND(ctx
->opcode
)) {
16969 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
16973 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
16974 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
16975 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
16979 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
16980 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
16981 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16986 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
16987 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
16988 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
16989 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16992 default: /* Invalid */
16993 MIPS_INVAL("MASK DAPPEND");
16994 generate_exception(ctx
, EXCP_RI
);
17001 (void)opn
; /* avoid a compiler warning */
17002 MIPS_DEBUG("%s", opn
);
17005 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
17006 int ret
, int v1
, int v2
, int check_ret
)
17009 const char *opn
= "mipsdsp accumulator";
17016 if ((ret
== 0) && (check_ret
== 1)) {
17017 /* Treat as NOP. */
17022 t0
= tcg_temp_new();
17023 t1
= tcg_temp_new();
17024 v1_t
= tcg_temp_new();
17025 v2_t
= tcg_temp_new();
17027 gen_load_gpr(v1_t
, v1
);
17028 gen_load_gpr(v2_t
, v2
);
17031 case OPC_EXTR_W_DSP
:
17035 tcg_gen_movi_tl(t0
, v2
);
17036 tcg_gen_movi_tl(t1
, v1
);
17037 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17040 tcg_gen_movi_tl(t0
, v2
);
17041 tcg_gen_movi_tl(t1
, v1
);
17042 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17044 case OPC_EXTR_RS_W
:
17045 tcg_gen_movi_tl(t0
, v2
);
17046 tcg_gen_movi_tl(t1
, v1
);
17047 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17050 tcg_gen_movi_tl(t0
, v2
);
17051 tcg_gen_movi_tl(t1
, v1
);
17052 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17054 case OPC_EXTRV_S_H
:
17055 tcg_gen_movi_tl(t0
, v2
);
17056 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17059 tcg_gen_movi_tl(t0
, v2
);
17060 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17062 case OPC_EXTRV_R_W
:
17063 tcg_gen_movi_tl(t0
, v2
);
17064 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17066 case OPC_EXTRV_RS_W
:
17067 tcg_gen_movi_tl(t0
, v2
);
17068 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17071 tcg_gen_movi_tl(t0
, v2
);
17072 tcg_gen_movi_tl(t1
, v1
);
17073 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17076 tcg_gen_movi_tl(t0
, v2
);
17077 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17080 tcg_gen_movi_tl(t0
, v2
);
17081 tcg_gen_movi_tl(t1
, v1
);
17082 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17085 tcg_gen_movi_tl(t0
, v2
);
17086 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17089 imm
= (ctx
->opcode
>> 20) & 0x3F;
17090 tcg_gen_movi_tl(t0
, ret
);
17091 tcg_gen_movi_tl(t1
, imm
);
17092 gen_helper_shilo(t0
, t1
, cpu_env
);
17095 tcg_gen_movi_tl(t0
, ret
);
17096 gen_helper_shilo(t0
, v1_t
, cpu_env
);
17099 tcg_gen_movi_tl(t0
, ret
);
17100 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
17103 imm
= (ctx
->opcode
>> 11) & 0x3FF;
17104 tcg_gen_movi_tl(t0
, imm
);
17105 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
17108 imm
= (ctx
->opcode
>> 16) & 0x03FF;
17109 tcg_gen_movi_tl(t0
, imm
);
17110 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
17114 #ifdef TARGET_MIPS64
17115 case OPC_DEXTR_W_DSP
:
17119 tcg_gen_movi_tl(t0
, ret
);
17120 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
17124 int shift
= (ctx
->opcode
>> 19) & 0x7F;
17125 int ac
= (ctx
->opcode
>> 11) & 0x03;
17126 tcg_gen_movi_tl(t0
, shift
);
17127 tcg_gen_movi_tl(t1
, ac
);
17128 gen_helper_dshilo(t0
, t1
, cpu_env
);
17133 int ac
= (ctx
->opcode
>> 11) & 0x03;
17134 tcg_gen_movi_tl(t0
, ac
);
17135 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
17139 tcg_gen_movi_tl(t0
, v2
);
17140 tcg_gen_movi_tl(t1
, v1
);
17142 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17145 tcg_gen_movi_tl(t0
, v2
);
17146 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17149 tcg_gen_movi_tl(t0
, v2
);
17150 tcg_gen_movi_tl(t1
, v1
);
17151 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17154 tcg_gen_movi_tl(t0
, v2
);
17155 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17158 tcg_gen_movi_tl(t0
, v2
);
17159 tcg_gen_movi_tl(t1
, v1
);
17160 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17162 case OPC_DEXTR_R_L
:
17163 tcg_gen_movi_tl(t0
, v2
);
17164 tcg_gen_movi_tl(t1
, v1
);
17165 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17167 case OPC_DEXTR_RS_L
:
17168 tcg_gen_movi_tl(t0
, v2
);
17169 tcg_gen_movi_tl(t1
, v1
);
17170 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17173 tcg_gen_movi_tl(t0
, v2
);
17174 tcg_gen_movi_tl(t1
, v1
);
17175 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17177 case OPC_DEXTR_R_W
:
17178 tcg_gen_movi_tl(t0
, v2
);
17179 tcg_gen_movi_tl(t1
, v1
);
17180 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17182 case OPC_DEXTR_RS_W
:
17183 tcg_gen_movi_tl(t0
, v2
);
17184 tcg_gen_movi_tl(t1
, v1
);
17185 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17187 case OPC_DEXTR_S_H
:
17188 tcg_gen_movi_tl(t0
, v2
);
17189 tcg_gen_movi_tl(t1
, v1
);
17190 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17192 case OPC_DEXTRV_S_H
:
17193 tcg_gen_movi_tl(t0
, v2
);
17194 tcg_gen_movi_tl(t1
, v1
);
17195 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
17198 tcg_gen_movi_tl(t0
, v2
);
17199 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17201 case OPC_DEXTRV_R_L
:
17202 tcg_gen_movi_tl(t0
, v2
);
17203 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17205 case OPC_DEXTRV_RS_L
:
17206 tcg_gen_movi_tl(t0
, v2
);
17207 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17210 tcg_gen_movi_tl(t0
, v2
);
17211 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17213 case OPC_DEXTRV_R_W
:
17214 tcg_gen_movi_tl(t0
, v2
);
17215 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17217 case OPC_DEXTRV_RS_W
:
17218 tcg_gen_movi_tl(t0
, v2
);
17219 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
17228 tcg_temp_free(v1_t
);
17229 tcg_temp_free(v2_t
);
17231 (void)opn
; /* avoid a compiler warning */
17232 MIPS_DEBUG("%s", opn
);
17235 /* End MIPSDSP functions. */
17237 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
17239 int rs
, rt
, rd
, sa
;
17242 rs
= (ctx
->opcode
>> 21) & 0x1f;
17243 rt
= (ctx
->opcode
>> 16) & 0x1f;
17244 rd
= (ctx
->opcode
>> 11) & 0x1f;
17245 sa
= (ctx
->opcode
>> 6) & 0x1f;
17247 op1
= MASK_SPECIAL(ctx
->opcode
);
17250 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
17252 case OPC_MULT
... OPC_DIVU
:
17253 op2
= MASK_R6_MULDIV(ctx
->opcode
);
17263 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
17266 MIPS_INVAL("special_r6 muldiv");
17267 generate_exception(ctx
, EXCP_RI
);
17273 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
17277 if (rt
== 0 && sa
== 1) {
17278 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17279 We need additionally to check other fields */
17280 gen_cl(ctx
, op1
, rd
, rs
);
17282 generate_exception(ctx
, EXCP_RI
);
17286 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
17287 gen_helper_do_semihosting(cpu_env
);
17289 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
17290 generate_exception(ctx
, EXCP_RI
);
17292 generate_exception(ctx
, EXCP_DBp
);
17296 #if defined(TARGET_MIPS64)
17298 check_mips_64(ctx
);
17299 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
17303 if (rt
== 0 && sa
== 1) {
17304 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17305 We need additionally to check other fields */
17306 check_mips_64(ctx
);
17307 gen_cl(ctx
, op1
, rd
, rs
);
17309 generate_exception(ctx
, EXCP_RI
);
17312 case OPC_DMULT
... OPC_DDIVU
:
17313 op2
= MASK_R6_MULDIV(ctx
->opcode
);
17323 check_mips_64(ctx
);
17324 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
17327 MIPS_INVAL("special_r6 muldiv");
17328 generate_exception(ctx
, EXCP_RI
);
17333 default: /* Invalid */
17334 MIPS_INVAL("special_r6");
17335 generate_exception(ctx
, EXCP_RI
);
17340 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17342 int rs
, rt
, rd
, sa
;
17345 rs
= (ctx
->opcode
>> 21) & 0x1f;
17346 rt
= (ctx
->opcode
>> 16) & 0x1f;
17347 rd
= (ctx
->opcode
>> 11) & 0x1f;
17348 sa
= (ctx
->opcode
>> 6) & 0x1f;
17350 op1
= MASK_SPECIAL(ctx
->opcode
);
17352 case OPC_MOVN
: /* Conditional move */
17354 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
17355 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
17356 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
17358 case OPC_MFHI
: /* Move from HI/LO */
17360 gen_HILO(ctx
, op1
, rs
& 3, rd
);
17363 case OPC_MTLO
: /* Move to HI/LO */
17364 gen_HILO(ctx
, op1
, rd
& 3, rs
);
17367 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
17368 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17369 check_cp1_enabled(ctx
);
17370 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
17371 (ctx
->opcode
>> 16) & 1);
17373 generate_exception_err(ctx
, EXCP_CpU
, 1);
17379 check_insn(ctx
, INSN_VR54XX
);
17380 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
17381 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
17383 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
17388 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
17390 #if defined(TARGET_MIPS64)
17391 case OPC_DMULT
... OPC_DDIVU
:
17392 check_insn(ctx
, ISA_MIPS3
);
17393 check_mips_64(ctx
);
17394 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
17398 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
17401 #ifdef MIPS_STRICT_STANDARD
17402 MIPS_INVAL("SPIM");
17403 generate_exception(ctx
, EXCP_RI
);
17405 /* Implemented as RI exception for now. */
17406 MIPS_INVAL("spim (unofficial)");
17407 generate_exception(ctx
, EXCP_RI
);
17410 default: /* Invalid */
17411 MIPS_INVAL("special_legacy");
17412 generate_exception(ctx
, EXCP_RI
);
17417 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
17419 int rs
, rt
, rd
, sa
;
17422 rs
= (ctx
->opcode
>> 21) & 0x1f;
17423 rt
= (ctx
->opcode
>> 16) & 0x1f;
17424 rd
= (ctx
->opcode
>> 11) & 0x1f;
17425 sa
= (ctx
->opcode
>> 6) & 0x1f;
17427 op1
= MASK_SPECIAL(ctx
->opcode
);
17429 case OPC_SLL
: /* Shift with immediate */
17430 if (sa
== 5 && rd
== 0 &&
17431 rs
== 0 && rt
== 0) { /* PAUSE */
17432 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
17433 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
17434 MIPS_DEBUG("CTI in delay / forbidden slot");
17435 generate_exception(ctx
, EXCP_RI
);
17441 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17444 switch ((ctx
->opcode
>> 21) & 0x1f) {
17446 /* rotr is decoded as srl on non-R2 CPUs */
17447 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17452 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17455 generate_exception(ctx
, EXCP_RI
);
17459 case OPC_ADD
... OPC_SUBU
:
17460 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17462 case OPC_SLLV
: /* Shifts */
17464 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17467 switch ((ctx
->opcode
>> 6) & 0x1f) {
17469 /* rotrv is decoded as srlv on non-R2 CPUs */
17470 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17475 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17478 generate_exception(ctx
, EXCP_RI
);
17482 case OPC_SLT
: /* Set on less than */
17484 gen_slt(ctx
, op1
, rd
, rs
, rt
);
17486 case OPC_AND
: /* Logic*/
17490 gen_logic(ctx
, op1
, rd
, rs
, rt
);
17493 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
17495 case OPC_TGE
... OPC_TEQ
: /* Traps */
17497 check_insn(ctx
, ISA_MIPS2
);
17498 gen_trap(ctx
, op1
, rs
, rt
, -1);
17500 case OPC_LSA
: /* OPC_PMON */
17501 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
17502 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
17503 decode_opc_special_r6(env
, ctx
);
17505 /* Pmon entry point, also R4010 selsl */
17506 #ifdef MIPS_STRICT_STANDARD
17507 MIPS_INVAL("PMON / selsl");
17508 generate_exception(ctx
, EXCP_RI
);
17510 gen_helper_0e0i(pmon
, sa
);
17515 generate_exception(ctx
, EXCP_SYSCALL
);
17516 ctx
->bstate
= BS_STOP
;
17519 generate_exception(ctx
, EXCP_BREAK
);
17522 check_insn(ctx
, ISA_MIPS2
);
17523 /* Treat as NOP. */
17526 #if defined(TARGET_MIPS64)
17527 /* MIPS64 specific opcodes */
17532 check_insn(ctx
, ISA_MIPS3
);
17533 check_mips_64(ctx
);
17534 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17537 switch ((ctx
->opcode
>> 21) & 0x1f) {
17539 /* drotr is decoded as dsrl on non-R2 CPUs */
17540 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17545 check_insn(ctx
, ISA_MIPS3
);
17546 check_mips_64(ctx
);
17547 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17550 generate_exception(ctx
, EXCP_RI
);
17555 switch ((ctx
->opcode
>> 21) & 0x1f) {
17557 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17558 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17563 check_insn(ctx
, ISA_MIPS3
);
17564 check_mips_64(ctx
);
17565 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17568 generate_exception(ctx
, EXCP_RI
);
17572 case OPC_DADD
... OPC_DSUBU
:
17573 check_insn(ctx
, ISA_MIPS3
);
17574 check_mips_64(ctx
);
17575 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17579 check_insn(ctx
, ISA_MIPS3
);
17580 check_mips_64(ctx
);
17581 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17584 switch ((ctx
->opcode
>> 6) & 0x1f) {
17586 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17587 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17592 check_insn(ctx
, ISA_MIPS3
);
17593 check_mips_64(ctx
);
17594 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17597 generate_exception(ctx
, EXCP_RI
);
17602 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
17603 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
17604 decode_opc_special_r6(env
, ctx
);
17609 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17610 decode_opc_special_r6(env
, ctx
);
17612 decode_opc_special_legacy(env
, ctx
);
17617 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17622 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17624 rs
= (ctx
->opcode
>> 21) & 0x1f;
17625 rt
= (ctx
->opcode
>> 16) & 0x1f;
17626 rd
= (ctx
->opcode
>> 11) & 0x1f;
17628 op1
= MASK_SPECIAL2(ctx
->opcode
);
17630 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
17631 case OPC_MSUB
... OPC_MSUBU
:
17632 check_insn(ctx
, ISA_MIPS32
);
17633 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
17636 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17639 case OPC_DIVU_G_2F
:
17640 case OPC_MULT_G_2F
:
17641 case OPC_MULTU_G_2F
:
17643 case OPC_MODU_G_2F
:
17644 check_insn(ctx
, INSN_LOONGSON2F
);
17645 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17649 check_insn(ctx
, ISA_MIPS32
);
17650 gen_cl(ctx
, op1
, rd
, rs
);
17653 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
17654 gen_helper_do_semihosting(cpu_env
);
17656 /* XXX: not clear which exception should be raised
17657 * when in debug mode...
17659 check_insn(ctx
, ISA_MIPS32
);
17660 generate_exception(ctx
, EXCP_DBp
);
17663 #if defined(TARGET_MIPS64)
17666 check_insn(ctx
, ISA_MIPS64
);
17667 check_mips_64(ctx
);
17668 gen_cl(ctx
, op1
, rd
, rs
);
17670 case OPC_DMULT_G_2F
:
17671 case OPC_DMULTU_G_2F
:
17672 case OPC_DDIV_G_2F
:
17673 case OPC_DDIVU_G_2F
:
17674 case OPC_DMOD_G_2F
:
17675 case OPC_DMODU_G_2F
:
17676 check_insn(ctx
, INSN_LOONGSON2F
);
17677 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17680 default: /* Invalid */
17681 MIPS_INVAL("special2_legacy");
17682 generate_exception(ctx
, EXCP_RI
);
17687 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
17689 int rs
, rt
, rd
, sa
;
17693 rs
= (ctx
->opcode
>> 21) & 0x1f;
17694 rt
= (ctx
->opcode
>> 16) & 0x1f;
17695 rd
= (ctx
->opcode
>> 11) & 0x1f;
17696 sa
= (ctx
->opcode
>> 6) & 0x1f;
17697 imm
= (int16_t)ctx
->opcode
>> 7;
17699 op1
= MASK_SPECIAL3(ctx
->opcode
);
17703 /* hint codes 24-31 are reserved and signal RI */
17704 generate_exception(ctx
, EXCP_RI
);
17706 /* Treat as NOP. */
17709 /* Treat as NOP. */
17712 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
17715 gen_ld(ctx
, op1
, rt
, rs
, imm
);
17720 /* Treat as NOP. */
17723 op2
= MASK_BSHFL(ctx
->opcode
);
17725 case OPC_ALIGN
... OPC_ALIGN_END
:
17726 gen_align(ctx
, OPC_ALIGN
, rd
, rs
, rt
, sa
& 3);
17729 gen_bitswap(ctx
, op2
, rd
, rt
);
17734 #if defined(TARGET_MIPS64)
17736 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
17739 gen_ld(ctx
, op1
, rt
, rs
, imm
);
17742 check_mips_64(ctx
);
17745 /* Treat as NOP. */
17748 op2
= MASK_DBSHFL(ctx
->opcode
);
17750 case OPC_DALIGN
... OPC_DALIGN_END
:
17751 gen_align(ctx
, OPC_DALIGN
, rd
, rs
, rt
, sa
& 7);
17754 gen_bitswap(ctx
, op2
, rd
, rt
);
17761 default: /* Invalid */
17762 MIPS_INVAL("special3_r6");
17763 generate_exception(ctx
, EXCP_RI
);
17768 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17773 rs
= (ctx
->opcode
>> 21) & 0x1f;
17774 rt
= (ctx
->opcode
>> 16) & 0x1f;
17775 rd
= (ctx
->opcode
>> 11) & 0x1f;
17777 op1
= MASK_SPECIAL3(ctx
->opcode
);
17779 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
17780 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
17781 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
17782 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17783 * the same mask and op1. */
17784 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
17785 op2
= MASK_ADDUH_QB(ctx
->opcode
);
17788 case OPC_ADDUH_R_QB
:
17790 case OPC_ADDQH_R_PH
:
17792 case OPC_ADDQH_R_W
:
17794 case OPC_SUBUH_R_QB
:
17796 case OPC_SUBQH_R_PH
:
17798 case OPC_SUBQH_R_W
:
17799 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17804 case OPC_MULQ_RS_W
:
17805 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17808 MIPS_INVAL("MASK ADDUH.QB");
17809 generate_exception(ctx
, EXCP_RI
);
17812 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
17813 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17815 generate_exception(ctx
, EXCP_RI
);
17819 op2
= MASK_LX(ctx
->opcode
);
17821 #if defined(TARGET_MIPS64)
17827 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
17829 default: /* Invalid */
17830 MIPS_INVAL("MASK LX");
17831 generate_exception(ctx
, EXCP_RI
);
17835 case OPC_ABSQ_S_PH_DSP
:
17836 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
17838 case OPC_ABSQ_S_QB
:
17839 case OPC_ABSQ_S_PH
:
17841 case OPC_PRECEQ_W_PHL
:
17842 case OPC_PRECEQ_W_PHR
:
17843 case OPC_PRECEQU_PH_QBL
:
17844 case OPC_PRECEQU_PH_QBR
:
17845 case OPC_PRECEQU_PH_QBLA
:
17846 case OPC_PRECEQU_PH_QBRA
:
17847 case OPC_PRECEU_PH_QBL
:
17848 case OPC_PRECEU_PH_QBR
:
17849 case OPC_PRECEU_PH_QBLA
:
17850 case OPC_PRECEU_PH_QBRA
:
17851 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17858 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
17861 MIPS_INVAL("MASK ABSQ_S.PH");
17862 generate_exception(ctx
, EXCP_RI
);
17866 case OPC_ADDU_QB_DSP
:
17867 op2
= MASK_ADDU_QB(ctx
->opcode
);
17870 case OPC_ADDQ_S_PH
:
17873 case OPC_ADDU_S_QB
:
17875 case OPC_ADDU_S_PH
:
17877 case OPC_SUBQ_S_PH
:
17880 case OPC_SUBU_S_QB
:
17882 case OPC_SUBU_S_PH
:
17886 case OPC_RADDU_W_QB
:
17887 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17889 case OPC_MULEU_S_PH_QBL
:
17890 case OPC_MULEU_S_PH_QBR
:
17891 case OPC_MULQ_RS_PH
:
17892 case OPC_MULEQ_S_W_PHL
:
17893 case OPC_MULEQ_S_W_PHR
:
17894 case OPC_MULQ_S_PH
:
17895 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17897 default: /* Invalid */
17898 MIPS_INVAL("MASK ADDU.QB");
17899 generate_exception(ctx
, EXCP_RI
);
17904 case OPC_CMPU_EQ_QB_DSP
:
17905 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
17907 case OPC_PRECR_SRA_PH_W
:
17908 case OPC_PRECR_SRA_R_PH_W
:
17909 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
17911 case OPC_PRECR_QB_PH
:
17912 case OPC_PRECRQ_QB_PH
:
17913 case OPC_PRECRQ_PH_W
:
17914 case OPC_PRECRQ_RS_PH_W
:
17915 case OPC_PRECRQU_S_QB_PH
:
17916 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17918 case OPC_CMPU_EQ_QB
:
17919 case OPC_CMPU_LT_QB
:
17920 case OPC_CMPU_LE_QB
:
17921 case OPC_CMP_EQ_PH
:
17922 case OPC_CMP_LT_PH
:
17923 case OPC_CMP_LE_PH
:
17924 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17926 case OPC_CMPGU_EQ_QB
:
17927 case OPC_CMPGU_LT_QB
:
17928 case OPC_CMPGU_LE_QB
:
17929 case OPC_CMPGDU_EQ_QB
:
17930 case OPC_CMPGDU_LT_QB
:
17931 case OPC_CMPGDU_LE_QB
:
17934 case OPC_PACKRL_PH
:
17935 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17937 default: /* Invalid */
17938 MIPS_INVAL("MASK CMPU.EQ.QB");
17939 generate_exception(ctx
, EXCP_RI
);
17943 case OPC_SHLL_QB_DSP
:
17944 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
17946 case OPC_DPA_W_PH_DSP
:
17947 op2
= MASK_DPA_W_PH(ctx
->opcode
);
17949 case OPC_DPAU_H_QBL
:
17950 case OPC_DPAU_H_QBR
:
17951 case OPC_DPSU_H_QBL
:
17952 case OPC_DPSU_H_QBR
:
17954 case OPC_DPAX_W_PH
:
17955 case OPC_DPAQ_S_W_PH
:
17956 case OPC_DPAQX_S_W_PH
:
17957 case OPC_DPAQX_SA_W_PH
:
17959 case OPC_DPSX_W_PH
:
17960 case OPC_DPSQ_S_W_PH
:
17961 case OPC_DPSQX_S_W_PH
:
17962 case OPC_DPSQX_SA_W_PH
:
17963 case OPC_MULSAQ_S_W_PH
:
17964 case OPC_DPAQ_SA_L_W
:
17965 case OPC_DPSQ_SA_L_W
:
17966 case OPC_MAQ_S_W_PHL
:
17967 case OPC_MAQ_S_W_PHR
:
17968 case OPC_MAQ_SA_W_PHL
:
17969 case OPC_MAQ_SA_W_PHR
:
17970 case OPC_MULSA_W_PH
:
17971 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17973 default: /* Invalid */
17974 MIPS_INVAL("MASK DPAW.PH");
17975 generate_exception(ctx
, EXCP_RI
);
17980 op2
= MASK_INSV(ctx
->opcode
);
17992 t0
= tcg_temp_new();
17993 t1
= tcg_temp_new();
17995 gen_load_gpr(t0
, rt
);
17996 gen_load_gpr(t1
, rs
);
17998 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
18004 default: /* Invalid */
18005 MIPS_INVAL("MASK INSV");
18006 generate_exception(ctx
, EXCP_RI
);
18010 case OPC_APPEND_DSP
:
18011 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
18013 case OPC_EXTR_W_DSP
:
18014 op2
= MASK_EXTR_W(ctx
->opcode
);
18018 case OPC_EXTR_RS_W
:
18020 case OPC_EXTRV_S_H
:
18022 case OPC_EXTRV_R_W
:
18023 case OPC_EXTRV_RS_W
:
18028 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
18031 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
18037 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18039 default: /* Invalid */
18040 MIPS_INVAL("MASK EXTR.W");
18041 generate_exception(ctx
, EXCP_RI
);
18045 #if defined(TARGET_MIPS64)
18046 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
18047 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
18048 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
18049 check_insn(ctx
, INSN_LOONGSON2E
);
18050 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
18052 case OPC_ABSQ_S_QH_DSP
:
18053 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
18055 case OPC_PRECEQ_L_PWL
:
18056 case OPC_PRECEQ_L_PWR
:
18057 case OPC_PRECEQ_PW_QHL
:
18058 case OPC_PRECEQ_PW_QHR
:
18059 case OPC_PRECEQ_PW_QHLA
:
18060 case OPC_PRECEQ_PW_QHRA
:
18061 case OPC_PRECEQU_QH_OBL
:
18062 case OPC_PRECEQU_QH_OBR
:
18063 case OPC_PRECEQU_QH_OBLA
:
18064 case OPC_PRECEQU_QH_OBRA
:
18065 case OPC_PRECEU_QH_OBL
:
18066 case OPC_PRECEU_QH_OBR
:
18067 case OPC_PRECEU_QH_OBLA
:
18068 case OPC_PRECEU_QH_OBRA
:
18069 case OPC_ABSQ_S_OB
:
18070 case OPC_ABSQ_S_PW
:
18071 case OPC_ABSQ_S_QH
:
18072 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
18080 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
18082 default: /* Invalid */
18083 MIPS_INVAL("MASK ABSQ_S.QH");
18084 generate_exception(ctx
, EXCP_RI
);
18088 case OPC_ADDU_OB_DSP
:
18089 op2
= MASK_ADDU_OB(ctx
->opcode
);
18091 case OPC_RADDU_L_OB
:
18093 case OPC_SUBQ_S_PW
:
18095 case OPC_SUBQ_S_QH
:
18097 case OPC_SUBU_S_OB
:
18099 case OPC_SUBU_S_QH
:
18101 case OPC_SUBUH_R_OB
:
18103 case OPC_ADDQ_S_PW
:
18105 case OPC_ADDQ_S_QH
:
18107 case OPC_ADDU_S_OB
:
18109 case OPC_ADDU_S_QH
:
18111 case OPC_ADDUH_R_OB
:
18112 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
18114 case OPC_MULEQ_S_PW_QHL
:
18115 case OPC_MULEQ_S_PW_QHR
:
18116 case OPC_MULEU_S_QH_OBL
:
18117 case OPC_MULEU_S_QH_OBR
:
18118 case OPC_MULQ_RS_QH
:
18119 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
18121 default: /* Invalid */
18122 MIPS_INVAL("MASK ADDU.OB");
18123 generate_exception(ctx
, EXCP_RI
);
18127 case OPC_CMPU_EQ_OB_DSP
:
18128 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
18130 case OPC_PRECR_SRA_QH_PW
:
18131 case OPC_PRECR_SRA_R_QH_PW
:
18132 /* Return value is rt. */
18133 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
18135 case OPC_PRECR_OB_QH
:
18136 case OPC_PRECRQ_OB_QH
:
18137 case OPC_PRECRQ_PW_L
:
18138 case OPC_PRECRQ_QH_PW
:
18139 case OPC_PRECRQ_RS_QH_PW
:
18140 case OPC_PRECRQU_S_OB_QH
:
18141 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
18143 case OPC_CMPU_EQ_OB
:
18144 case OPC_CMPU_LT_OB
:
18145 case OPC_CMPU_LE_OB
:
18146 case OPC_CMP_EQ_QH
:
18147 case OPC_CMP_LT_QH
:
18148 case OPC_CMP_LE_QH
:
18149 case OPC_CMP_EQ_PW
:
18150 case OPC_CMP_LT_PW
:
18151 case OPC_CMP_LE_PW
:
18152 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18154 case OPC_CMPGDU_EQ_OB
:
18155 case OPC_CMPGDU_LT_OB
:
18156 case OPC_CMPGDU_LE_OB
:
18157 case OPC_CMPGU_EQ_OB
:
18158 case OPC_CMPGU_LT_OB
:
18159 case OPC_CMPGU_LE_OB
:
18160 case OPC_PACKRL_PW
:
18164 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
18166 default: /* Invalid */
18167 MIPS_INVAL("MASK CMPU_EQ.OB");
18168 generate_exception(ctx
, EXCP_RI
);
18172 case OPC_DAPPEND_DSP
:
18173 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
18175 case OPC_DEXTR_W_DSP
:
18176 op2
= MASK_DEXTR_W(ctx
->opcode
);
18183 case OPC_DEXTR_R_L
:
18184 case OPC_DEXTR_RS_L
:
18186 case OPC_DEXTR_R_W
:
18187 case OPC_DEXTR_RS_W
:
18188 case OPC_DEXTR_S_H
:
18190 case OPC_DEXTRV_R_L
:
18191 case OPC_DEXTRV_RS_L
:
18192 case OPC_DEXTRV_S_H
:
18194 case OPC_DEXTRV_R_W
:
18195 case OPC_DEXTRV_RS_W
:
18196 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
18201 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18203 default: /* Invalid */
18204 MIPS_INVAL("MASK EXTR.W");
18205 generate_exception(ctx
, EXCP_RI
);
18209 case OPC_DPAQ_W_QH_DSP
:
18210 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
18212 case OPC_DPAU_H_OBL
:
18213 case OPC_DPAU_H_OBR
:
18214 case OPC_DPSU_H_OBL
:
18215 case OPC_DPSU_H_OBR
:
18217 case OPC_DPAQ_S_W_QH
:
18219 case OPC_DPSQ_S_W_QH
:
18220 case OPC_MULSAQ_S_W_QH
:
18221 case OPC_DPAQ_SA_L_PW
:
18222 case OPC_DPSQ_SA_L_PW
:
18223 case OPC_MULSAQ_S_L_PW
:
18224 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18226 case OPC_MAQ_S_W_QHLL
:
18227 case OPC_MAQ_S_W_QHLR
:
18228 case OPC_MAQ_S_W_QHRL
:
18229 case OPC_MAQ_S_W_QHRR
:
18230 case OPC_MAQ_SA_W_QHLL
:
18231 case OPC_MAQ_SA_W_QHLR
:
18232 case OPC_MAQ_SA_W_QHRL
:
18233 case OPC_MAQ_SA_W_QHRR
:
18234 case OPC_MAQ_S_L_PWL
:
18235 case OPC_MAQ_S_L_PWR
:
18240 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
18242 default: /* Invalid */
18243 MIPS_INVAL("MASK DPAQ.W.QH");
18244 generate_exception(ctx
, EXCP_RI
);
18248 case OPC_DINSV_DSP
:
18249 op2
= MASK_INSV(ctx
->opcode
);
18261 t0
= tcg_temp_new();
18262 t1
= tcg_temp_new();
18264 gen_load_gpr(t0
, rt
);
18265 gen_load_gpr(t1
, rs
);
18267 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
18273 default: /* Invalid */
18274 MIPS_INVAL("MASK DINSV");
18275 generate_exception(ctx
, EXCP_RI
);
18279 case OPC_SHLL_OB_DSP
:
18280 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
18283 default: /* Invalid */
18284 MIPS_INVAL("special3_legacy");
18285 generate_exception(ctx
, EXCP_RI
);
18290 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
18292 int rs
, rt
, rd
, sa
;
18295 rs
= (ctx
->opcode
>> 21) & 0x1f;
18296 rt
= (ctx
->opcode
>> 16) & 0x1f;
18297 rd
= (ctx
->opcode
>> 11) & 0x1f;
18298 sa
= (ctx
->opcode
>> 6) & 0x1f;
18300 op1
= MASK_SPECIAL3(ctx
->opcode
);
18304 check_insn(ctx
, ISA_MIPS32R2
);
18305 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
18308 op2
= MASK_BSHFL(ctx
->opcode
);
18310 case OPC_ALIGN
... OPC_ALIGN_END
:
18312 check_insn(ctx
, ISA_MIPS32R6
);
18313 decode_opc_special3_r6(env
, ctx
);
18316 check_insn(ctx
, ISA_MIPS32R2
);
18317 gen_bshfl(ctx
, op2
, rt
, rd
);
18321 #if defined(TARGET_MIPS64)
18322 case OPC_DEXTM
... OPC_DEXT
:
18323 case OPC_DINSM
... OPC_DINS
:
18324 check_insn(ctx
, ISA_MIPS64R2
);
18325 check_mips_64(ctx
);
18326 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
18329 op2
= MASK_DBSHFL(ctx
->opcode
);
18331 case OPC_DALIGN
... OPC_DALIGN_END
:
18333 check_insn(ctx
, ISA_MIPS32R6
);
18334 decode_opc_special3_r6(env
, ctx
);
18337 check_insn(ctx
, ISA_MIPS64R2
);
18338 check_mips_64(ctx
);
18339 op2
= MASK_DBSHFL(ctx
->opcode
);
18340 gen_bshfl(ctx
, op2
, rt
, rd
);
18346 gen_rdhwr(ctx
, rt
, rd
);
18349 check_insn(ctx
, ASE_MT
);
18351 TCGv t0
= tcg_temp_new();
18352 TCGv t1
= tcg_temp_new();
18354 gen_load_gpr(t0
, rt
);
18355 gen_load_gpr(t1
, rs
);
18356 gen_helper_fork(t0
, t1
);
18362 check_insn(ctx
, ASE_MT
);
18364 TCGv t0
= tcg_temp_new();
18366 save_cpu_state(ctx
, 1);
18367 gen_load_gpr(t0
, rs
);
18368 gen_helper_yield(t0
, cpu_env
, t0
);
18369 gen_store_gpr(t0
, rd
);
18374 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18375 decode_opc_special3_r6(env
, ctx
);
18377 decode_opc_special3_legacy(env
, ctx
);
18382 /* MIPS SIMD Architecture (MSA) */
18383 static inline int check_msa_access(DisasContext
*ctx
)
18385 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
18386 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
18387 generate_exception(ctx
, EXCP_RI
);
18391 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
18392 if (ctx
->insn_flags
& ASE_MSA
) {
18393 generate_exception(ctx
, EXCP_MSADIS
);
18396 generate_exception(ctx
, EXCP_RI
);
18403 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
18405 /* generates tcg ops to check if any element is 0 */
18406 /* Note this function only works with MSA_WRLEN = 128 */
18407 uint64_t eval_zero_or_big
= 0;
18408 uint64_t eval_big
= 0;
18409 TCGv_i64 t0
= tcg_temp_new_i64();
18410 TCGv_i64 t1
= tcg_temp_new_i64();
18413 eval_zero_or_big
= 0x0101010101010101ULL
;
18414 eval_big
= 0x8080808080808080ULL
;
18417 eval_zero_or_big
= 0x0001000100010001ULL
;
18418 eval_big
= 0x8000800080008000ULL
;
18421 eval_zero_or_big
= 0x0000000100000001ULL
;
18422 eval_big
= 0x8000000080000000ULL
;
18425 eval_zero_or_big
= 0x0000000000000001ULL
;
18426 eval_big
= 0x8000000000000000ULL
;
18429 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<<1], eval_zero_or_big
);
18430 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<<1]);
18431 tcg_gen_andi_i64(t0
, t0
, eval_big
);
18432 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<<1)+1], eval_zero_or_big
);
18433 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<<1)+1]);
18434 tcg_gen_andi_i64(t1
, t1
, eval_big
);
18435 tcg_gen_or_i64(t0
, t0
, t1
);
18436 /* if all bits are zero then all elements are not zero */
18437 /* if some bit is non-zero then some element is zero */
18438 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
18439 tcg_gen_trunc_i64_tl(tresult
, t0
);
18440 tcg_temp_free_i64(t0
);
18441 tcg_temp_free_i64(t1
);
18444 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
18446 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18447 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18448 int64_t s16
= (int16_t)ctx
->opcode
;
18450 check_msa_access(ctx
);
18452 if (ctx
->insn_flags
& ISA_MIPS32R6
&& ctx
->hflags
& MIPS_HFLAG_BMASK
) {
18453 MIPS_DEBUG("CTI in delay / forbidden slot");
18454 generate_exception(ctx
, EXCP_RI
);
18461 TCGv_i64 t0
= tcg_temp_new_i64();
18462 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<<1], msa_wr_d
[(wt
<<1)+1]);
18463 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
18464 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
18465 tcg_gen_trunc_i64_tl(bcond
, t0
);
18466 tcg_temp_free_i64(t0
);
18473 gen_check_zero_element(bcond
, df
, wt
);
18479 gen_check_zero_element(bcond
, df
, wt
);
18480 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
18484 ctx
->btarget
= ctx
->pc
+ (s16
<< 2) + 4;
18486 ctx
->hflags
|= MIPS_HFLAG_BC
;
18487 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
18490 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
18492 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18493 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
18494 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18495 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18497 TCGv_i32 twd
= tcg_const_i32(wd
);
18498 TCGv_i32 tws
= tcg_const_i32(ws
);
18499 TCGv_i32 ti8
= tcg_const_i32(i8
);
18501 switch (MASK_MSA_I8(ctx
->opcode
)) {
18503 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
18506 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
18509 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
18512 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
18515 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
18518 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
18521 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
18527 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
18528 if (df
== DF_DOUBLE
) {
18529 generate_exception(ctx
, EXCP_RI
);
18531 TCGv_i32 tdf
= tcg_const_i32(df
);
18532 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
18533 tcg_temp_free_i32(tdf
);
18538 MIPS_INVAL("MSA instruction");
18539 generate_exception(ctx
, EXCP_RI
);
18543 tcg_temp_free_i32(twd
);
18544 tcg_temp_free_i32(tws
);
18545 tcg_temp_free_i32(ti8
);
18548 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
18550 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18551 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18552 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
18553 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
18554 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18555 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18557 TCGv_i32 tdf
= tcg_const_i32(df
);
18558 TCGv_i32 twd
= tcg_const_i32(wd
);
18559 TCGv_i32 tws
= tcg_const_i32(ws
);
18560 TCGv_i32 timm
= tcg_temp_new_i32();
18561 tcg_gen_movi_i32(timm
, u5
);
18563 switch (MASK_MSA_I5(ctx
->opcode
)) {
18565 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18568 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18570 case OPC_MAXI_S_df
:
18571 tcg_gen_movi_i32(timm
, s5
);
18572 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18574 case OPC_MAXI_U_df
:
18575 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18577 case OPC_MINI_S_df
:
18578 tcg_gen_movi_i32(timm
, s5
);
18579 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18581 case OPC_MINI_U_df
:
18582 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18585 tcg_gen_movi_i32(timm
, s5
);
18586 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18588 case OPC_CLTI_S_df
:
18589 tcg_gen_movi_i32(timm
, s5
);
18590 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18592 case OPC_CLTI_U_df
:
18593 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18595 case OPC_CLEI_S_df
:
18596 tcg_gen_movi_i32(timm
, s5
);
18597 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18599 case OPC_CLEI_U_df
:
18600 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18604 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
18605 tcg_gen_movi_i32(timm
, s10
);
18606 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
18610 MIPS_INVAL("MSA instruction");
18611 generate_exception(ctx
, EXCP_RI
);
18615 tcg_temp_free_i32(tdf
);
18616 tcg_temp_free_i32(twd
);
18617 tcg_temp_free_i32(tws
);
18618 tcg_temp_free_i32(timm
);
18621 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
18623 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18624 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
18625 uint32_t df
= 0, m
= 0;
18626 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18627 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18634 if ((dfm
& 0x40) == 0x00) {
18637 } else if ((dfm
& 0x60) == 0x40) {
18640 } else if ((dfm
& 0x70) == 0x60) {
18643 } else if ((dfm
& 0x78) == 0x70) {
18647 generate_exception(ctx
, EXCP_RI
);
18651 tdf
= tcg_const_i32(df
);
18652 tm
= tcg_const_i32(m
);
18653 twd
= tcg_const_i32(wd
);
18654 tws
= tcg_const_i32(ws
);
18656 switch (MASK_MSA_BIT(ctx
->opcode
)) {
18658 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18661 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
18664 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18667 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18670 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
18673 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
18675 case OPC_BINSLI_df
:
18676 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18678 case OPC_BINSRI_df
:
18679 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18682 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
18685 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
18688 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
18691 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18694 MIPS_INVAL("MSA instruction");
18695 generate_exception(ctx
, EXCP_RI
);
18699 tcg_temp_free_i32(tdf
);
18700 tcg_temp_free_i32(tm
);
18701 tcg_temp_free_i32(twd
);
18702 tcg_temp_free_i32(tws
);
18705 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
18707 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18708 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18709 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18710 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18711 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18713 TCGv_i32 tdf
= tcg_const_i32(df
);
18714 TCGv_i32 twd
= tcg_const_i32(wd
);
18715 TCGv_i32 tws
= tcg_const_i32(ws
);
18716 TCGv_i32 twt
= tcg_const_i32(wt
);
18718 switch (MASK_MSA_3R(ctx
->opcode
)) {
18720 gen_helper_msa_sll_df(cpu_env
, tdf
, twd
, tws
, twt
);
18723 gen_helper_msa_addv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18726 gen_helper_msa_ceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18729 gen_helper_msa_add_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18731 case OPC_SUBS_S_df
:
18732 gen_helper_msa_subs_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18735 gen_helper_msa_mulv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18738 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
18741 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18744 gen_helper_msa_sra_df(cpu_env
, tdf
, twd
, tws
, twt
);
18747 gen_helper_msa_subv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18749 case OPC_ADDS_A_df
:
18750 gen_helper_msa_adds_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18752 case OPC_SUBS_U_df
:
18753 gen_helper_msa_subs_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18756 gen_helper_msa_maddv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18759 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
18762 gen_helper_msa_srar_df(cpu_env
, tdf
, twd
, tws
, twt
);
18765 gen_helper_msa_srl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18768 gen_helper_msa_max_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18771 gen_helper_msa_clt_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18773 case OPC_ADDS_S_df
:
18774 gen_helper_msa_adds_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18776 case OPC_SUBSUS_U_df
:
18777 gen_helper_msa_subsus_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18780 gen_helper_msa_msubv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18783 gen_helper_msa_pckev_df(cpu_env
, tdf
, twd
, tws
, twt
);
18786 gen_helper_msa_srlr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18789 gen_helper_msa_bclr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18792 gen_helper_msa_max_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18795 gen_helper_msa_clt_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18797 case OPC_ADDS_U_df
:
18798 gen_helper_msa_adds_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18800 case OPC_SUBSUU_S_df
:
18801 gen_helper_msa_subsuu_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18804 gen_helper_msa_pckod_df(cpu_env
, tdf
, twd
, tws
, twt
);
18807 gen_helper_msa_bset_df(cpu_env
, tdf
, twd
, tws
, twt
);
18810 gen_helper_msa_min_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18813 gen_helper_msa_cle_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18816 gen_helper_msa_ave_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18818 case OPC_ASUB_S_df
:
18819 gen_helper_msa_asub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18822 gen_helper_msa_div_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18825 gen_helper_msa_ilvl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18828 gen_helper_msa_bneg_df(cpu_env
, tdf
, twd
, tws
, twt
);
18831 gen_helper_msa_min_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18834 gen_helper_msa_cle_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18837 gen_helper_msa_ave_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18839 case OPC_ASUB_U_df
:
18840 gen_helper_msa_asub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18843 gen_helper_msa_div_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18846 gen_helper_msa_ilvr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18849 gen_helper_msa_binsl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18852 gen_helper_msa_max_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18854 case OPC_AVER_S_df
:
18855 gen_helper_msa_aver_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18858 gen_helper_msa_mod_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18861 gen_helper_msa_ilvev_df(cpu_env
, tdf
, twd
, tws
, twt
);
18864 gen_helper_msa_binsr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18867 gen_helper_msa_min_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18869 case OPC_AVER_U_df
:
18870 gen_helper_msa_aver_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18873 gen_helper_msa_mod_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18876 gen_helper_msa_ilvod_df(cpu_env
, tdf
, twd
, tws
, twt
);
18879 case OPC_DOTP_S_df
:
18880 case OPC_DOTP_U_df
:
18881 case OPC_DPADD_S_df
:
18882 case OPC_DPADD_U_df
:
18883 case OPC_DPSUB_S_df
:
18884 case OPC_HADD_S_df
:
18885 case OPC_DPSUB_U_df
:
18886 case OPC_HADD_U_df
:
18887 case OPC_HSUB_S_df
:
18888 case OPC_HSUB_U_df
:
18889 if (df
== DF_BYTE
) {
18890 generate_exception(ctx
, EXCP_RI
);
18892 switch (MASK_MSA_3R(ctx
->opcode
)) {
18893 case OPC_DOTP_S_df
:
18894 gen_helper_msa_dotp_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18896 case OPC_DOTP_U_df
:
18897 gen_helper_msa_dotp_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18899 case OPC_DPADD_S_df
:
18900 gen_helper_msa_dpadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18902 case OPC_DPADD_U_df
:
18903 gen_helper_msa_dpadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18905 case OPC_DPSUB_S_df
:
18906 gen_helper_msa_dpsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18908 case OPC_HADD_S_df
:
18909 gen_helper_msa_hadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18911 case OPC_DPSUB_U_df
:
18912 gen_helper_msa_dpsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18914 case OPC_HADD_U_df
:
18915 gen_helper_msa_hadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18917 case OPC_HSUB_S_df
:
18918 gen_helper_msa_hsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18920 case OPC_HSUB_U_df
:
18921 gen_helper_msa_hsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18926 MIPS_INVAL("MSA instruction");
18927 generate_exception(ctx
, EXCP_RI
);
18930 tcg_temp_free_i32(twd
);
18931 tcg_temp_free_i32(tws
);
18932 tcg_temp_free_i32(twt
);
18933 tcg_temp_free_i32(tdf
);
18936 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
18938 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18939 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
18940 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
18941 TCGv telm
= tcg_temp_new();
18942 TCGv_i32 tsr
= tcg_const_i32(source
);
18943 TCGv_i32 tdt
= tcg_const_i32(dest
);
18945 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
18947 gen_load_gpr(telm
, source
);
18948 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
18951 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
18952 gen_store_gpr(telm
, dest
);
18955 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
18958 MIPS_INVAL("MSA instruction");
18959 generate_exception(ctx
, EXCP_RI
);
18963 tcg_temp_free(telm
);
18964 tcg_temp_free_i32(tdt
);
18965 tcg_temp_free_i32(tsr
);
18968 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
18971 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18972 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18973 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18975 TCGv_i32 tws
= tcg_const_i32(ws
);
18976 TCGv_i32 twd
= tcg_const_i32(wd
);
18977 TCGv_i32 tn
= tcg_const_i32(n
);
18978 TCGv_i32 tdf
= tcg_const_i32(df
);
18980 switch (MASK_MSA_ELM(ctx
->opcode
)) {
18982 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
18984 case OPC_SPLATI_df
:
18985 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
18988 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
18990 case OPC_COPY_S_df
:
18991 case OPC_COPY_U_df
:
18992 case OPC_INSERT_df
:
18993 #if !defined(TARGET_MIPS64)
18994 /* Double format valid only for MIPS64 */
18995 if (df
== DF_DOUBLE
) {
18996 generate_exception(ctx
, EXCP_RI
);
19000 switch (MASK_MSA_ELM(ctx
->opcode
)) {
19001 case OPC_COPY_S_df
:
19002 gen_helper_msa_copy_s_df(cpu_env
, tdf
, twd
, tws
, tn
);
19004 case OPC_COPY_U_df
:
19005 gen_helper_msa_copy_u_df(cpu_env
, tdf
, twd
, tws
, tn
);
19007 case OPC_INSERT_df
:
19008 gen_helper_msa_insert_df(cpu_env
, tdf
, twd
, tws
, tn
);
19013 MIPS_INVAL("MSA instruction");
19014 generate_exception(ctx
, EXCP_RI
);
19016 tcg_temp_free_i32(twd
);
19017 tcg_temp_free_i32(tws
);
19018 tcg_temp_free_i32(tn
);
19019 tcg_temp_free_i32(tdf
);
19022 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
19024 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
19025 uint32_t df
= 0, n
= 0;
19027 if ((dfn
& 0x30) == 0x00) {
19030 } else if ((dfn
& 0x38) == 0x20) {
19033 } else if ((dfn
& 0x3c) == 0x30) {
19036 } else if ((dfn
& 0x3e) == 0x38) {
19039 } else if (dfn
== 0x3E) {
19040 /* CTCMSA, CFCMSA, MOVE.V */
19041 gen_msa_elm_3e(env
, ctx
);
19044 generate_exception(ctx
, EXCP_RI
);
19048 gen_msa_elm_df(env
, ctx
, df
, n
);
19051 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
19053 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
19054 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
19055 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19056 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19057 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19059 TCGv_i32 twd
= tcg_const_i32(wd
);
19060 TCGv_i32 tws
= tcg_const_i32(ws
);
19061 TCGv_i32 twt
= tcg_const_i32(wt
);
19062 TCGv_i32 tdf
= tcg_temp_new_i32();
19064 /* adjust df value for floating-point instruction */
19065 tcg_gen_movi_i32(tdf
, df
+ 2);
19067 switch (MASK_MSA_3RF(ctx
->opcode
)) {
19069 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
19072 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
19075 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
19078 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
19081 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
19084 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19087 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
19090 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
19093 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19096 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
19099 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
19102 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
19105 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
19108 tcg_gen_movi_i32(tdf
, df
+ 1);
19109 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19112 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
19115 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
19117 case OPC_MADD_Q_df
:
19118 tcg_gen_movi_i32(tdf
, df
+ 1);
19119 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19122 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
19124 case OPC_MSUB_Q_df
:
19125 tcg_gen_movi_i32(tdf
, df
+ 1);
19126 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19129 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
19132 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
19135 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
19138 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
19141 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
19144 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
19147 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19150 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19153 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
19156 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
19159 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
19162 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
19165 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
19167 case OPC_MULR_Q_df
:
19168 tcg_gen_movi_i32(tdf
, df
+ 1);
19169 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19172 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
19174 case OPC_FMIN_A_df
:
19175 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
19177 case OPC_MADDR_Q_df
:
19178 tcg_gen_movi_i32(tdf
, df
+ 1);
19179 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19182 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
19185 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
19187 case OPC_MSUBR_Q_df
:
19188 tcg_gen_movi_i32(tdf
, df
+ 1);
19189 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
19192 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
19194 case OPC_FMAX_A_df
:
19195 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
19198 MIPS_INVAL("MSA instruction");
19199 generate_exception(ctx
, EXCP_RI
);
19203 tcg_temp_free_i32(twd
);
19204 tcg_temp_free_i32(tws
);
19205 tcg_temp_free_i32(twt
);
19206 tcg_temp_free_i32(tdf
);
19209 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
19211 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19212 (op & (0x7 << 18)))
19213 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19214 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19215 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19216 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
19217 TCGv_i32 twd
= tcg_const_i32(wd
);
19218 TCGv_i32 tws
= tcg_const_i32(ws
);
19219 TCGv_i32 twt
= tcg_const_i32(wt
);
19220 TCGv_i32 tdf
= tcg_const_i32(df
);
19222 switch (MASK_MSA_2R(ctx
->opcode
)) {
19224 #if !defined(TARGET_MIPS64)
19225 /* Double format valid only for MIPS64 */
19226 if (df
== DF_DOUBLE
) {
19227 generate_exception(ctx
, EXCP_RI
);
19231 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
19234 gen_helper_msa_pcnt_df(cpu_env
, tdf
, twd
, tws
);
19237 gen_helper_msa_nloc_df(cpu_env
, tdf
, twd
, tws
);
19240 gen_helper_msa_nlzc_df(cpu_env
, tdf
, twd
, tws
);
19243 MIPS_INVAL("MSA instruction");
19244 generate_exception(ctx
, EXCP_RI
);
19248 tcg_temp_free_i32(twd
);
19249 tcg_temp_free_i32(tws
);
19250 tcg_temp_free_i32(twt
);
19251 tcg_temp_free_i32(tdf
);
19254 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
19256 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
19257 (op & (0xf << 17)))
19258 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19259 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19260 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19261 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
19262 TCGv_i32 twd
= tcg_const_i32(wd
);
19263 TCGv_i32 tws
= tcg_const_i32(ws
);
19264 TCGv_i32 twt
= tcg_const_i32(wt
);
19265 /* adjust df value for floating-point instruction */
19266 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
19268 switch (MASK_MSA_2RF(ctx
->opcode
)) {
19269 case OPC_FCLASS_df
:
19270 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
19272 case OPC_FTRUNC_S_df
:
19273 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
19275 case OPC_FTRUNC_U_df
:
19276 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
19279 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
19281 case OPC_FRSQRT_df
:
19282 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
19285 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
19288 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
19291 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
19293 case OPC_FEXUPL_df
:
19294 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
19296 case OPC_FEXUPR_df
:
19297 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
19300 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
19303 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
19305 case OPC_FTINT_S_df
:
19306 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
19308 case OPC_FTINT_U_df
:
19309 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
19311 case OPC_FFINT_S_df
:
19312 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
19314 case OPC_FFINT_U_df
:
19315 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
19319 tcg_temp_free_i32(twd
);
19320 tcg_temp_free_i32(tws
);
19321 tcg_temp_free_i32(twt
);
19322 tcg_temp_free_i32(tdf
);
19325 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
19327 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19328 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19329 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19330 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19331 TCGv_i32 twd
= tcg_const_i32(wd
);
19332 TCGv_i32 tws
= tcg_const_i32(ws
);
19333 TCGv_i32 twt
= tcg_const_i32(wt
);
19335 switch (MASK_MSA_VEC(ctx
->opcode
)) {
19337 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
19340 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
19343 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
19346 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
19349 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
19352 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
19355 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
19358 MIPS_INVAL("MSA instruction");
19359 generate_exception(ctx
, EXCP_RI
);
19363 tcg_temp_free_i32(twd
);
19364 tcg_temp_free_i32(tws
);
19365 tcg_temp_free_i32(twt
);
19368 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
19370 switch (MASK_MSA_VEC(ctx
->opcode
)) {
19378 gen_msa_vec_v(env
, ctx
);
19381 gen_msa_2r(env
, ctx
);
19384 gen_msa_2rf(env
, ctx
);
19387 MIPS_INVAL("MSA instruction");
19388 generate_exception(ctx
, EXCP_RI
);
19393 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
19395 uint32_t opcode
= ctx
->opcode
;
19396 check_insn(ctx
, ASE_MSA
);
19397 check_msa_access(ctx
);
19399 switch (MASK_MSA_MINOR(opcode
)) {
19400 case OPC_MSA_I8_00
:
19401 case OPC_MSA_I8_01
:
19402 case OPC_MSA_I8_02
:
19403 gen_msa_i8(env
, ctx
);
19405 case OPC_MSA_I5_06
:
19406 case OPC_MSA_I5_07
:
19407 gen_msa_i5(env
, ctx
);
19409 case OPC_MSA_BIT_09
:
19410 case OPC_MSA_BIT_0A
:
19411 gen_msa_bit(env
, ctx
);
19413 case OPC_MSA_3R_0D
:
19414 case OPC_MSA_3R_0E
:
19415 case OPC_MSA_3R_0F
:
19416 case OPC_MSA_3R_10
:
19417 case OPC_MSA_3R_11
:
19418 case OPC_MSA_3R_12
:
19419 case OPC_MSA_3R_13
:
19420 case OPC_MSA_3R_14
:
19421 case OPC_MSA_3R_15
:
19422 gen_msa_3r(env
, ctx
);
19425 gen_msa_elm(env
, ctx
);
19427 case OPC_MSA_3RF_1A
:
19428 case OPC_MSA_3RF_1B
:
19429 case OPC_MSA_3RF_1C
:
19430 gen_msa_3rf(env
, ctx
);
19433 gen_msa_vec(env
, ctx
);
19444 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
19445 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
19446 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19447 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
19449 TCGv_i32 twd
= tcg_const_i32(wd
);
19450 TCGv taddr
= tcg_temp_new();
19451 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
19453 switch (MASK_MSA_MINOR(opcode
)) {
19455 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
19458 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
19461 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
19464 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
19467 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
19470 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
19473 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
19476 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
19480 tcg_temp_free_i32(twd
);
19481 tcg_temp_free(taddr
);
19485 MIPS_INVAL("MSA instruction");
19486 generate_exception(ctx
, EXCP_RI
);
19492 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
19495 int rs
, rt
, rd
, sa
;
19499 /* make sure instructions are on a word boundary */
19500 if (ctx
->pc
& 0x3) {
19501 env
->CP0_BadVAddr
= ctx
->pc
;
19502 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
19503 ctx
->bstate
= BS_STOP
;
19507 /* Handle blikely not taken case */
19508 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
19509 TCGLabel
*l1
= gen_new_label();
19511 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
19512 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
19513 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
19514 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
19518 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
19519 tcg_gen_debug_insn_start(ctx
->pc
);
19522 op
= MASK_OP_MAJOR(ctx
->opcode
);
19523 rs
= (ctx
->opcode
>> 21) & 0x1f;
19524 rt
= (ctx
->opcode
>> 16) & 0x1f;
19525 rd
= (ctx
->opcode
>> 11) & 0x1f;
19526 sa
= (ctx
->opcode
>> 6) & 0x1f;
19527 imm
= (int16_t)ctx
->opcode
;
19530 decode_opc_special(env
, ctx
);
19533 decode_opc_special2_legacy(env
, ctx
);
19536 decode_opc_special3(env
, ctx
);
19539 op1
= MASK_REGIMM(ctx
->opcode
);
19541 case OPC_BLTZL
: /* REGIMM branches */
19545 check_insn(ctx
, ISA_MIPS2
);
19546 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19550 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
19554 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19556 /* OPC_NAL, OPC_BAL */
19557 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
19559 generate_exception(ctx
, EXCP_RI
);
19562 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
19565 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
19567 check_insn(ctx
, ISA_MIPS2
);
19568 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19569 gen_trap(ctx
, op1
, rs
, -1, imm
);
19572 check_insn(ctx
, ISA_MIPS32R2
);
19573 /* Break the TB to be able to sync copied instructions
19575 ctx
->bstate
= BS_STOP
;
19577 case OPC_BPOSGE32
: /* MIPS DSP branch */
19578 #if defined(TARGET_MIPS64)
19582 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
19584 #if defined(TARGET_MIPS64)
19586 check_insn(ctx
, ISA_MIPS32R6
);
19587 check_mips_64(ctx
);
19589 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
19591 MIPS_DEBUG("dahi %s, %04x", regnames
[rs
], imm
);
19594 check_insn(ctx
, ISA_MIPS32R6
);
19595 check_mips_64(ctx
);
19597 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
19599 MIPS_DEBUG("dati %s, %04x", regnames
[rs
], imm
);
19602 default: /* Invalid */
19603 MIPS_INVAL("regimm");
19604 generate_exception(ctx
, EXCP_RI
);
19609 check_cp0_enabled(ctx
);
19610 op1
= MASK_CP0(ctx
->opcode
);
19618 #if defined(TARGET_MIPS64)
19622 #ifndef CONFIG_USER_ONLY
19623 gen_cp0(env
, ctx
, op1
, rt
, rd
);
19624 #endif /* !CONFIG_USER_ONLY */
19626 case OPC_C0_FIRST
... OPC_C0_LAST
:
19627 #ifndef CONFIG_USER_ONLY
19628 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
19629 #endif /* !CONFIG_USER_ONLY */
19632 #ifndef CONFIG_USER_ONLY
19635 TCGv t0
= tcg_temp_new();
19637 op2
= MASK_MFMC0(ctx
->opcode
);
19640 check_insn(ctx
, ASE_MT
);
19641 gen_helper_dmt(t0
);
19642 gen_store_gpr(t0
, rt
);
19645 check_insn(ctx
, ASE_MT
);
19646 gen_helper_emt(t0
);
19647 gen_store_gpr(t0
, rt
);
19650 check_insn(ctx
, ASE_MT
);
19651 gen_helper_dvpe(t0
, cpu_env
);
19652 gen_store_gpr(t0
, rt
);
19655 check_insn(ctx
, ASE_MT
);
19656 gen_helper_evpe(t0
, cpu_env
);
19657 gen_store_gpr(t0
, rt
);
19660 check_insn(ctx
, ISA_MIPS32R2
);
19661 save_cpu_state(ctx
, 1);
19662 gen_helper_di(t0
, cpu_env
);
19663 gen_store_gpr(t0
, rt
);
19664 /* Stop translation as we may have switched
19665 the execution mode. */
19666 ctx
->bstate
= BS_STOP
;
19669 check_insn(ctx
, ISA_MIPS32R2
);
19670 save_cpu_state(ctx
, 1);
19671 gen_helper_ei(t0
, cpu_env
);
19672 gen_store_gpr(t0
, rt
);
19673 /* Stop translation as we may have switched
19674 the execution mode. */
19675 ctx
->bstate
= BS_STOP
;
19677 default: /* Invalid */
19678 MIPS_INVAL("mfmc0");
19679 generate_exception(ctx
, EXCP_RI
);
19684 #endif /* !CONFIG_USER_ONLY */
19687 check_insn(ctx
, ISA_MIPS32R2
);
19688 gen_load_srsgpr(rt
, rd
);
19691 check_insn(ctx
, ISA_MIPS32R2
);
19692 gen_store_srsgpr(rt
, rd
);
19696 generate_exception(ctx
, EXCP_RI
);
19700 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19701 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19702 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19703 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19706 /* Arithmetic with immediate opcode */
19707 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19711 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19713 case OPC_SLTI
: /* Set on less than with immediate opcode */
19715 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
19717 case OPC_ANDI
: /* Arithmetic with immediate opcode */
19718 case OPC_LUI
: /* OPC_AUI */
19721 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
19723 case OPC_J
... OPC_JAL
: /* Jump */
19724 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
19725 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
19728 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19729 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19731 generate_exception(ctx
, EXCP_RI
);
19734 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19735 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19738 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19741 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19742 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19744 generate_exception(ctx
, EXCP_RI
);
19747 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19748 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19751 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19754 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19757 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19759 check_insn(ctx
, ISA_MIPS32R6
);
19760 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19761 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19764 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19767 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19769 check_insn(ctx
, ISA_MIPS32R6
);
19770 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19771 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19776 check_insn(ctx
, ISA_MIPS2
);
19777 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19781 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19783 case OPC_LL
: /* Load and stores */
19784 check_insn(ctx
, ISA_MIPS2
);
19788 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19790 case OPC_LB
... OPC_LH
:
19791 case OPC_LW
... OPC_LHU
:
19792 gen_ld(ctx
, op
, rt
, rs
, imm
);
19796 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19798 case OPC_SB
... OPC_SH
:
19800 gen_st(ctx
, op
, rt
, rs
, imm
);
19803 check_insn(ctx
, ISA_MIPS2
);
19804 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19805 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
19808 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19809 check_cp0_enabled(ctx
);
19810 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
19811 /* Treat as NOP. */
19814 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19815 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
19816 /* Treat as NOP. */
19819 /* Floating point (COP1). */
19824 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
19828 op1
= MASK_CP1(ctx
->opcode
);
19833 check_cp1_enabled(ctx
);
19834 check_insn(ctx
, ISA_MIPS32R2
);
19839 check_cp1_enabled(ctx
);
19840 gen_cp1(ctx
, op1
, rt
, rd
);
19842 #if defined(TARGET_MIPS64)
19845 check_cp1_enabled(ctx
);
19846 check_insn(ctx
, ISA_MIPS3
);
19847 check_mips_64(ctx
);
19848 gen_cp1(ctx
, op1
, rt
, rd
);
19851 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
19852 check_cp1_enabled(ctx
);
19853 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19855 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
19860 check_insn(ctx
, ASE_MIPS3D
);
19861 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
19862 (rt
>> 2) & 0x7, imm
<< 2);
19866 check_cp1_enabled(ctx
);
19867 check_insn(ctx
, ISA_MIPS32R6
);
19868 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
19872 check_cp1_enabled(ctx
);
19873 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19875 check_insn(ctx
, ASE_MIPS3D
);
19878 check_cp1_enabled(ctx
);
19879 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19880 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
19881 (rt
>> 2) & 0x7, imm
<< 2);
19888 check_cp1_enabled(ctx
);
19889 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
19895 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
19896 check_cp1_enabled(ctx
);
19897 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19899 case R6_OPC_CMP_AF_S
:
19900 case R6_OPC_CMP_UN_S
:
19901 case R6_OPC_CMP_EQ_S
:
19902 case R6_OPC_CMP_UEQ_S
:
19903 case R6_OPC_CMP_LT_S
:
19904 case R6_OPC_CMP_ULT_S
:
19905 case R6_OPC_CMP_LE_S
:
19906 case R6_OPC_CMP_ULE_S
:
19907 case R6_OPC_CMP_SAF_S
:
19908 case R6_OPC_CMP_SUN_S
:
19909 case R6_OPC_CMP_SEQ_S
:
19910 case R6_OPC_CMP_SEUQ_S
:
19911 case R6_OPC_CMP_SLT_S
:
19912 case R6_OPC_CMP_SULT_S
:
19913 case R6_OPC_CMP_SLE_S
:
19914 case R6_OPC_CMP_SULE_S
:
19915 case R6_OPC_CMP_OR_S
:
19916 case R6_OPC_CMP_UNE_S
:
19917 case R6_OPC_CMP_NE_S
:
19918 case R6_OPC_CMP_SOR_S
:
19919 case R6_OPC_CMP_SUNE_S
:
19920 case R6_OPC_CMP_SNE_S
:
19921 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
19923 case R6_OPC_CMP_AF_D
:
19924 case R6_OPC_CMP_UN_D
:
19925 case R6_OPC_CMP_EQ_D
:
19926 case R6_OPC_CMP_UEQ_D
:
19927 case R6_OPC_CMP_LT_D
:
19928 case R6_OPC_CMP_ULT_D
:
19929 case R6_OPC_CMP_LE_D
:
19930 case R6_OPC_CMP_ULE_D
:
19931 case R6_OPC_CMP_SAF_D
:
19932 case R6_OPC_CMP_SUN_D
:
19933 case R6_OPC_CMP_SEQ_D
:
19934 case R6_OPC_CMP_SEUQ_D
:
19935 case R6_OPC_CMP_SLT_D
:
19936 case R6_OPC_CMP_SULT_D
:
19937 case R6_OPC_CMP_SLE_D
:
19938 case R6_OPC_CMP_SULE_D
:
19939 case R6_OPC_CMP_OR_D
:
19940 case R6_OPC_CMP_UNE_D
:
19941 case R6_OPC_CMP_NE_D
:
19942 case R6_OPC_CMP_SOR_D
:
19943 case R6_OPC_CMP_SUNE_D
:
19944 case R6_OPC_CMP_SNE_D
:
19945 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
19948 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
19949 rt
, rd
, sa
, (imm
>> 8) & 0x7);
19954 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
19969 check_insn(ctx
, ASE_MSA
);
19970 gen_msa_branch(env
, ctx
, op1
);
19974 generate_exception(ctx
, EXCP_RI
);
19979 /* Compact branches [R6] and COP2 [non-R6] */
19980 case OPC_BC
: /* OPC_LWC2 */
19981 case OPC_BALC
: /* OPC_SWC2 */
19982 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19983 /* OPC_BC, OPC_BALC */
19984 gen_compute_compact_branch(ctx
, op
, 0, 0,
19985 sextract32(ctx
->opcode
<< 2, 0, 28));
19987 /* OPC_LWC2, OPC_SWC2 */
19988 /* COP2: Not implemented. */
19989 generate_exception_err(ctx
, EXCP_CpU
, 2);
19992 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
19993 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
19994 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19996 /* OPC_BEQZC, OPC_BNEZC */
19997 gen_compute_compact_branch(ctx
, op
, rs
, 0,
19998 sextract32(ctx
->opcode
<< 2, 0, 23));
20000 /* OPC_JIC, OPC_JIALC */
20001 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
20004 /* OPC_LWC2, OPC_SWC2 */
20005 /* COP2: Not implemented. */
20006 generate_exception_err(ctx
, EXCP_CpU
, 2);
20010 check_insn(ctx
, INSN_LOONGSON2F
);
20011 /* Note that these instructions use different fields. */
20012 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
20016 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20017 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
20018 check_cp1_enabled(ctx
);
20019 op1
= MASK_CP3(ctx
->opcode
);
20023 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
20029 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
20030 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
20033 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
20034 /* Treat as NOP. */
20037 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
20051 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
20052 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
20056 generate_exception (ctx
, EXCP_RI
);
20060 generate_exception_err(ctx
, EXCP_CpU
, 1);
20064 #if defined(TARGET_MIPS64)
20065 /* MIPS64 opcodes */
20066 case OPC_LDL
... OPC_LDR
:
20068 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20072 check_insn(ctx
, ISA_MIPS3
);
20073 check_mips_64(ctx
);
20074 gen_ld(ctx
, op
, rt
, rs
, imm
);
20076 case OPC_SDL
... OPC_SDR
:
20077 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20080 check_insn(ctx
, ISA_MIPS3
);
20081 check_mips_64(ctx
);
20082 gen_st(ctx
, op
, rt
, rs
, imm
);
20085 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
20086 check_insn(ctx
, ISA_MIPS3
);
20087 check_mips_64(ctx
);
20088 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
20090 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
20091 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
20092 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
20093 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
20096 check_insn(ctx
, ISA_MIPS3
);
20097 check_mips_64(ctx
);
20098 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
20102 check_insn(ctx
, ISA_MIPS3
);
20103 check_mips_64(ctx
);
20104 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
20107 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
20108 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
20109 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
20111 MIPS_INVAL("major opcode");
20112 generate_exception(ctx
, EXCP_RI
);
20116 case OPC_DAUI
: /* OPC_JALX */
20117 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
20118 #if defined(TARGET_MIPS64)
20120 check_mips_64(ctx
);
20122 TCGv t0
= tcg_temp_new();
20123 gen_load_gpr(t0
, rs
);
20124 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
20127 MIPS_DEBUG("daui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
20129 generate_exception(ctx
, EXCP_RI
);
20130 MIPS_INVAL("major opcode");
20134 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
20135 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
20136 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
20139 case OPC_MSA
: /* OPC_MDMX */
20140 /* MDMX: Not implemented. */
20144 check_insn(ctx
, ISA_MIPS32R6
);
20145 gen_pcrel(ctx
, ctx
->opcode
, ctx
->pc
, rs
);
20147 default: /* Invalid */
20148 MIPS_INVAL("major opcode");
20149 generate_exception(ctx
, EXCP_RI
);
20155 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
20158 CPUState
*cs
= CPU(cpu
);
20159 CPUMIPSState
*env
= &cpu
->env
;
20161 target_ulong pc_start
;
20162 target_ulong next_page_start
;
20171 qemu_log("search pc %d\n", search_pc
);
20174 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
20177 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
20178 ctx
.insn_flags
= env
->insn_flags
;
20179 ctx
.CP0_Config1
= env
->CP0_Config1
;
20181 ctx
.bstate
= BS_NONE
;
20182 ctx
.kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
20183 ctx
.rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
20184 ctx
.ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
20185 ctx
.bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
20186 ctx
.bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
20187 ctx
.PAMask
= env
->PAMask
;
20188 ctx
.mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
20189 ctx
.CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
20190 /* Restore delay slot state from the tb context. */
20191 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
20192 ctx
.ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
20193 ctx
.ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
20194 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
20195 restore_cpu_state(env
, &ctx
);
20196 #ifdef CONFIG_USER_ONLY
20197 ctx
.mem_idx
= MIPS_HFLAG_UM
;
20199 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
20201 ctx
.default_tcg_memop_mask
= (ctx
.insn_flags
& ISA_MIPS32R6
) ?
20202 MO_UNALN
: MO_ALIGN
;
20204 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
20205 if (max_insns
== 0)
20206 max_insns
= CF_COUNT_MASK
;
20207 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
20209 while (ctx
.bstate
== BS_NONE
) {
20210 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
20211 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
20212 if (bp
->pc
== ctx
.pc
) {
20213 save_cpu_state(&ctx
, 1);
20214 ctx
.bstate
= BS_BRANCH
;
20215 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
20216 /* Include the breakpoint location or the tb won't
20217 * be flushed when it must be. */
20219 goto done_generating
;
20225 j
= tcg_op_buf_count();
20229 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
20231 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
20232 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
20233 gen_opc_btarget
[lj
] = ctx
.btarget
;
20234 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
20235 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
20237 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
20240 is_slot
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
20241 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
20242 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
20244 decode_opc(env
, &ctx
);
20245 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
20246 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
20247 insn_bytes
= decode_micromips_opc(env
, &ctx
);
20248 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
20249 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
20250 insn_bytes
= decode_mips16_opc(env
, &ctx
);
20252 generate_exception(&ctx
, EXCP_RI
);
20253 ctx
.bstate
= BS_STOP
;
20257 if (ctx
.hflags
& MIPS_HFLAG_BMASK
) {
20258 if (!(ctx
.hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
20259 MIPS_HFLAG_FBNSLOT
))) {
20260 /* force to generate branch as there is neither delay nor
20264 if ((ctx
.hflags
& MIPS_HFLAG_M16
) &&
20265 (ctx
.hflags
& MIPS_HFLAG_FBNSLOT
)) {
20266 /* Force to generate branch as microMIPS R6 doesn't restrict
20267 branches in the forbidden slot. */
20272 gen_branch(&ctx
, insn_bytes
);
20274 ctx
.pc
+= insn_bytes
;
20278 /* Execute a branch and its delay slot as a single instruction.
20279 This is what GDB expects and is consistent with what the
20280 hardware does (e.g. if a delay slot instruction faults, the
20281 reported PC is the PC of the branch). */
20282 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
20286 if (ctx
.pc
>= next_page_start
) {
20290 if (tcg_op_buf_full()) {
20294 if (num_insns
>= max_insns
)
20300 if (tb
->cflags
& CF_LAST_IO
) {
20303 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
20304 save_cpu_state(&ctx
, ctx
.bstate
!= BS_EXCP
);
20305 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
20307 switch (ctx
.bstate
) {
20309 gen_goto_tb(&ctx
, 0, ctx
.pc
);
20312 save_cpu_state(&ctx
, 0);
20313 gen_goto_tb(&ctx
, 0, ctx
.pc
);
20316 tcg_gen_exit_tb(0);
20324 gen_tb_end(tb
, num_insns
);
20327 j
= tcg_op_buf_count();
20330 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
20332 tb
->size
= ctx
.pc
- pc_start
;
20333 tb
->icount
= num_insns
;
20337 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
20338 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
20339 log_target_disas(cs
, pc_start
, ctx
.pc
- pc_start
, 0);
20345 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
20347 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
20350 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
20352 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
20355 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
20359 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
20361 #define printfpr(fp) \
20364 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20365 " fd:%13g fs:%13g psu: %13g\n", \
20366 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20367 (double)(fp)->fd, \
20368 (double)(fp)->fs[FP_ENDIAN_IDX], \
20369 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20372 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20373 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20374 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20375 " fd:%13g fs:%13g psu:%13g\n", \
20376 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20378 (double)tmp.fs[FP_ENDIAN_IDX], \
20379 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20384 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20385 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
20386 get_float_exception_flags(&env
->active_fpu
.fp_status
));
20387 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
20388 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
20389 printfpr(&env
->active_fpu
.fpr
[i
]);
20395 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
20396 /* Debug help: The architecture requires 32bit code to maintain proper
20397 sign-extended values on 64bit machines. */
20399 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
20402 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
20403 fprintf_function cpu_fprintf
,
20408 if (!SIGN_EXT_P(env
->active_tc
.PC
))
20409 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
20410 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
20411 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
20412 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
20413 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
20414 if (!SIGN_EXT_P(env
->btarget
))
20415 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
20417 for (i
= 0; i
< 32; i
++) {
20418 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
20419 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
20422 if (!SIGN_EXT_P(env
->CP0_EPC
))
20423 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
20424 if (!SIGN_EXT_P(env
->lladdr
))
20425 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
20429 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
20432 MIPSCPU
*cpu
= MIPS_CPU(cs
);
20433 CPUMIPSState
*env
= &cpu
->env
;
20436 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
20437 " LO=0x" TARGET_FMT_lx
" ds %04x "
20438 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
20439 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
20440 env
->hflags
, env
->btarget
, env
->bcond
);
20441 for (i
= 0; i
< 32; i
++) {
20443 cpu_fprintf(f
, "GPR%02d:", i
);
20444 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
20446 cpu_fprintf(f
, "\n");
20449 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
20450 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
20451 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20453 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
20454 cpu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
20455 env
->CP0_Config2
, env
->CP0_Config3
);
20456 cpu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
20457 env
->CP0_Config4
, env
->CP0_Config5
);
20458 if (env
->hflags
& MIPS_HFLAG_FPU
)
20459 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
20460 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
20461 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
20465 void mips_tcg_init(void)
20470 /* Initialize various static tables. */
20474 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
20475 TCGV_UNUSED(cpu_gpr
[0]);
20476 for (i
= 1; i
< 32; i
++)
20477 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
20478 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
20481 for (i
= 0; i
< 32; i
++) {
20482 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
20484 tcg_global_mem_new_i64(TCG_AREG0
, off
, msaregnames
[i
* 2]);
20485 /* The scalar floating-point unit (FPU) registers are mapped on
20486 * the MSA vector registers. */
20487 fpu_f64
[i
] = msa_wr_d
[i
* 2];
20488 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
20489 msa_wr_d
[i
* 2 + 1] =
20490 tcg_global_mem_new_i64(TCG_AREG0
, off
, msaregnames
[i
* 2 + 1]);
20493 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
20494 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
20495 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
20496 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
20497 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
20499 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
20500 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
20503 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
20504 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
20506 bcond
= tcg_global_mem_new(TCG_AREG0
,
20507 offsetof(CPUMIPSState
, bcond
), "bcond");
20508 btarget
= tcg_global_mem_new(TCG_AREG0
,
20509 offsetof(CPUMIPSState
, btarget
), "btarget");
20510 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
20511 offsetof(CPUMIPSState
, hflags
), "hflags");
20513 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
20514 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
20516 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
20517 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
20523 #include "translate_init.c"
20525 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
20529 const mips_def_t
*def
;
20531 def
= cpu_mips_find_by_name(cpu_model
);
20534 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
20536 env
->cpu_model
= def
;
20538 #ifndef CONFIG_USER_ONLY
20539 mmu_init(env
, def
);
20541 fpu_init(env
, def
);
20542 mvp_init(env
, def
);
20544 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
20549 void cpu_state_reset(CPUMIPSState
*env
)
20551 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
20552 CPUState
*cs
= CPU(cpu
);
20554 /* Reset registers to their default values */
20555 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
20556 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
20557 #ifdef TARGET_WORDS_BIGENDIAN
20558 env
->CP0_Config0
|= (1 << CP0C0_BE
);
20560 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
20561 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
20562 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
20563 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
20564 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
20565 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
20566 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
20567 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
20568 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
20569 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
20570 << env
->cpu_model
->CP0_LLAddr_shift
;
20571 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
20572 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
20573 env
->CCRes
= env
->cpu_model
->CCRes
;
20574 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
20575 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
20576 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
20577 env
->current_tc
= 0;
20578 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
20579 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
20580 #if defined(TARGET_MIPS64)
20581 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
20582 env
->SEGMask
|= 3ULL << 62;
20585 env
->PABITS
= env
->cpu_model
->PABITS
;
20586 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
20587 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
20588 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
20589 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
20590 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
20591 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
20592 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
20593 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
20594 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
20595 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
20596 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
20597 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
20598 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
20599 env
->msair
= env
->cpu_model
->MSAIR
;
20600 env
->insn_flags
= env
->cpu_model
->insn_flags
;
20602 #if defined(CONFIG_USER_ONLY)
20603 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
20604 # ifdef TARGET_MIPS64
20605 /* Enable 64-bit register mode. */
20606 env
->CP0_Status
|= (1 << CP0St_PX
);
20608 # ifdef TARGET_ABI_MIPSN64
20609 /* Enable 64-bit address mode. */
20610 env
->CP0_Status
|= (1 << CP0St_UX
);
20612 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20613 hardware registers. */
20614 env
->CP0_HWREna
|= 0x0000000F;
20615 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
20616 env
->CP0_Status
|= (1 << CP0St_CU1
);
20618 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
20619 env
->CP0_Status
|= (1 << CP0St_MX
);
20621 # if defined(TARGET_MIPS64)
20622 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20623 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
20624 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
20625 env
->CP0_Status
|= (1 << CP0St_FR
);
20629 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
20630 /* If the exception was raised from a delay slot,
20631 come back to the jump. */
20632 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
20633 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
20635 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
20637 env
->active_tc
.PC
= (int32_t)0xBFC00000;
20638 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
20639 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
20640 env
->CP0_Wired
= 0;
20641 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
20642 if (kvm_enabled()) {
20643 env
->CP0_EBase
|= 0x40000000;
20645 env
->CP0_EBase
|= 0x80000000;
20647 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
20648 /* vectored interrupts not implemented, timer on int 7,
20649 no performance counters. */
20650 env
->CP0_IntCtl
= 0xe0000000;
20654 for (i
= 0; i
< 7; i
++) {
20655 env
->CP0_WatchLo
[i
] = 0;
20656 env
->CP0_WatchHi
[i
] = 0x80000000;
20658 env
->CP0_WatchLo
[7] = 0;
20659 env
->CP0_WatchHi
[7] = 0;
20661 /* Count register increments in debug mode, EJTAG version 1 */
20662 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
20664 cpu_mips_store_count(env
, 1);
20666 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
20669 /* Only TC0 on VPE 0 starts as active. */
20670 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
20671 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
20672 env
->tcs
[i
].CP0_TCHalt
= 1;
20674 env
->active_tc
.CP0_TCHalt
= 1;
20677 if (cs
->cpu_index
== 0) {
20678 /* VPE0 starts up enabled. */
20679 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
20680 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
20682 /* TC0 starts up unhalted. */
20684 env
->active_tc
.CP0_TCHalt
= 0;
20685 env
->tcs
[0].CP0_TCHalt
= 0;
20686 /* With thread 0 active. */
20687 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
20688 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
20692 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
20693 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
20694 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20695 env
->CP0_Status
|= (1 << CP0St_FR
);
20699 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
20703 compute_hflags(env
);
20704 restore_rounding_mode(env
);
20705 restore_flush_mode(env
);
20706 restore_pamask(env
);
20707 cs
->exception_index
= EXCP_NONE
;
20709 if (semihosting_get_argc()) {
20710 /* UHI interface can be used to obtain argc and argv */
20711 env
->active_tc
.gpr
[4] = -1;
20715 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
20717 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
20718 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
20719 env
->hflags
|= gen_opc_hflags
[pc_pos
];
20720 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
20721 case MIPS_HFLAG_BR
:
20723 case MIPS_HFLAG_BC
:
20724 case MIPS_HFLAG_BL
:
20726 env
->btarget
= gen_opc_btarget
[pc_pos
];