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/>.
24 #include "qemu/osdep.h"
26 #include "disas/disas.h"
27 #include "exec/exec-all.h"
29 #include "exec/cpu_ldst.h"
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
33 #include "sysemu/kvm.h"
34 #include "exec/semihost.h"
36 #include "trace-tcg.h"
39 #define MIPS_DEBUG_DISAS 0
41 /* MIPS major opcodes */
42 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
45 /* indirect opcode tables */
46 OPC_SPECIAL
= (0x00 << 26),
47 OPC_REGIMM
= (0x01 << 26),
48 OPC_CP0
= (0x10 << 26),
49 OPC_CP1
= (0x11 << 26),
50 OPC_CP2
= (0x12 << 26),
51 OPC_CP3
= (0x13 << 26),
52 OPC_SPECIAL2
= (0x1C << 26),
53 OPC_SPECIAL3
= (0x1F << 26),
54 /* arithmetic with immediate */
55 OPC_ADDI
= (0x08 << 26),
56 OPC_ADDIU
= (0x09 << 26),
57 OPC_SLTI
= (0x0A << 26),
58 OPC_SLTIU
= (0x0B << 26),
59 /* logic with immediate */
60 OPC_ANDI
= (0x0C << 26),
61 OPC_ORI
= (0x0D << 26),
62 OPC_XORI
= (0x0E << 26),
63 OPC_LUI
= (0x0F << 26),
64 /* arithmetic with immediate */
65 OPC_DADDI
= (0x18 << 26),
66 OPC_DADDIU
= (0x19 << 26),
67 /* Jump and branches */
69 OPC_JAL
= (0x03 << 26),
70 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
71 OPC_BEQL
= (0x14 << 26),
72 OPC_BNE
= (0x05 << 26),
73 OPC_BNEL
= (0x15 << 26),
74 OPC_BLEZ
= (0x06 << 26),
75 OPC_BLEZL
= (0x16 << 26),
76 OPC_BGTZ
= (0x07 << 26),
77 OPC_BGTZL
= (0x17 << 26),
78 OPC_JALX
= (0x1D << 26),
79 OPC_DAUI
= (0x1D << 26),
81 OPC_LDL
= (0x1A << 26),
82 OPC_LDR
= (0x1B << 26),
83 OPC_LB
= (0x20 << 26),
84 OPC_LH
= (0x21 << 26),
85 OPC_LWL
= (0x22 << 26),
86 OPC_LW
= (0x23 << 26),
87 OPC_LWPC
= OPC_LW
| 0x5,
88 OPC_LBU
= (0x24 << 26),
89 OPC_LHU
= (0x25 << 26),
90 OPC_LWR
= (0x26 << 26),
91 OPC_LWU
= (0x27 << 26),
92 OPC_SB
= (0x28 << 26),
93 OPC_SH
= (0x29 << 26),
94 OPC_SWL
= (0x2A << 26),
95 OPC_SW
= (0x2B << 26),
96 OPC_SDL
= (0x2C << 26),
97 OPC_SDR
= (0x2D << 26),
98 OPC_SWR
= (0x2E << 26),
99 OPC_LL
= (0x30 << 26),
100 OPC_LLD
= (0x34 << 26),
101 OPC_LD
= (0x37 << 26),
102 OPC_LDPC
= OPC_LD
| 0x5,
103 OPC_SC
= (0x38 << 26),
104 OPC_SCD
= (0x3C << 26),
105 OPC_SD
= (0x3F << 26),
106 /* Floating point load/store */
107 OPC_LWC1
= (0x31 << 26),
108 OPC_LWC2
= (0x32 << 26),
109 OPC_LDC1
= (0x35 << 26),
110 OPC_LDC2
= (0x36 << 26),
111 OPC_SWC1
= (0x39 << 26),
112 OPC_SWC2
= (0x3A << 26),
113 OPC_SDC1
= (0x3D << 26),
114 OPC_SDC2
= (0x3E << 26),
115 /* Compact Branches */
116 OPC_BLEZALC
= (0x06 << 26),
117 OPC_BGEZALC
= (0x06 << 26),
118 OPC_BGEUC
= (0x06 << 26),
119 OPC_BGTZALC
= (0x07 << 26),
120 OPC_BLTZALC
= (0x07 << 26),
121 OPC_BLTUC
= (0x07 << 26),
122 OPC_BOVC
= (0x08 << 26),
123 OPC_BEQZALC
= (0x08 << 26),
124 OPC_BEQC
= (0x08 << 26),
125 OPC_BLEZC
= (0x16 << 26),
126 OPC_BGEZC
= (0x16 << 26),
127 OPC_BGEC
= (0x16 << 26),
128 OPC_BGTZC
= (0x17 << 26),
129 OPC_BLTZC
= (0x17 << 26),
130 OPC_BLTC
= (0x17 << 26),
131 OPC_BNVC
= (0x18 << 26),
132 OPC_BNEZALC
= (0x18 << 26),
133 OPC_BNEC
= (0x18 << 26),
134 OPC_BC
= (0x32 << 26),
135 OPC_BEQZC
= (0x36 << 26),
136 OPC_JIC
= (0x36 << 26),
137 OPC_BALC
= (0x3A << 26),
138 OPC_BNEZC
= (0x3E << 26),
139 OPC_JIALC
= (0x3E << 26),
140 /* MDMX ASE specific */
141 OPC_MDMX
= (0x1E << 26),
142 /* MSA ASE, same as MDMX */
144 /* Cache and prefetch */
145 OPC_CACHE
= (0x2F << 26),
146 OPC_PREF
= (0x33 << 26),
147 /* PC-relative address computation / loads */
148 OPC_PCREL
= (0x3B << 26),
151 /* PC-relative address computation / loads */
152 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
153 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
155 /* Instructions determined by bits 19 and 20 */
156 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
157 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
158 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
160 /* Instructions determined by bits 16 ... 20 */
161 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
162 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
165 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
168 /* MIPS special opcodes */
169 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
173 OPC_SLL
= 0x00 | OPC_SPECIAL
,
174 /* NOP is SLL r0, r0, 0 */
175 /* SSNOP is SLL r0, r0, 1 */
176 /* EHB is SLL r0, r0, 3 */
177 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
178 OPC_ROTR
= OPC_SRL
| (1 << 21),
179 OPC_SRA
= 0x03 | OPC_SPECIAL
,
180 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
181 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
182 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
183 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
184 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
185 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
186 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
187 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
188 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
189 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
190 OPC_DROTR
= OPC_DSRL
| (1 << 21),
191 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
192 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
193 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
194 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
195 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
196 /* Multiplication / division */
197 OPC_MULT
= 0x18 | OPC_SPECIAL
,
198 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
199 OPC_DIV
= 0x1A | OPC_SPECIAL
,
200 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
201 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
202 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
203 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
204 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
206 /* 2 registers arithmetic / logic */
207 OPC_ADD
= 0x20 | OPC_SPECIAL
,
208 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
209 OPC_SUB
= 0x22 | OPC_SPECIAL
,
210 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
211 OPC_AND
= 0x24 | OPC_SPECIAL
,
212 OPC_OR
= 0x25 | OPC_SPECIAL
,
213 OPC_XOR
= 0x26 | OPC_SPECIAL
,
214 OPC_NOR
= 0x27 | OPC_SPECIAL
,
215 OPC_SLT
= 0x2A | OPC_SPECIAL
,
216 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
217 OPC_DADD
= 0x2C | OPC_SPECIAL
,
218 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
219 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
220 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
222 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
223 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
225 OPC_TGE
= 0x30 | OPC_SPECIAL
,
226 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
227 OPC_TLT
= 0x32 | OPC_SPECIAL
,
228 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
229 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
230 OPC_TNE
= 0x36 | OPC_SPECIAL
,
231 /* HI / LO registers load & stores */
232 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
233 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
234 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
235 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
236 /* Conditional moves */
237 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
238 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
240 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
241 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
243 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
246 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
247 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
248 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
249 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
250 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
252 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
253 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
254 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
255 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
258 /* R6 Multiply and Divide instructions have the same Opcode
259 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
260 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
263 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
264 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
265 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
266 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
267 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
268 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
269 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
270 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
272 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
273 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
274 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
275 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
276 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
277 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
278 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
279 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
281 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
282 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
283 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
284 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
285 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
287 OPC_LSA
= 0x05 | OPC_SPECIAL
,
288 OPC_DLSA
= 0x15 | OPC_SPECIAL
,
291 /* Multiplication variants of the vr54xx. */
292 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
295 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
296 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
297 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
298 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
299 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
300 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
301 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
302 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
303 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
304 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
305 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
306 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
307 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
308 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
311 /* REGIMM (rt field) opcodes */
312 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
315 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
316 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
317 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
318 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
319 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
320 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
321 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
322 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
323 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
324 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
325 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
326 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
327 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
328 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
329 OPC_SIGRIE
= (0x17 << 16) | OPC_REGIMM
,
330 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
332 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
333 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
336 /* Special2 opcodes */
337 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
340 /* Multiply & xxx operations */
341 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
342 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
343 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
344 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
345 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
347 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
348 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
349 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
350 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
351 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
352 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
353 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
354 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
355 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
356 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
357 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
358 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
360 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
361 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
362 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
363 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
365 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
368 /* Special3 opcodes */
369 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
372 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
373 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
374 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
375 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
376 OPC_INS
= 0x04 | OPC_SPECIAL3
,
377 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
378 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
379 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
380 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
381 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
382 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
383 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
384 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
387 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
388 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
389 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
390 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
391 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
392 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
393 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
394 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
395 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
396 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
397 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
398 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
401 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
402 /* MIPS DSP Arithmetic */
403 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
404 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
405 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
406 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
407 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
408 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
409 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
410 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
411 /* MIPS DSP GPR-Based Shift Sub-class */
412 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
413 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
414 /* MIPS DSP Multiply Sub-class insns */
415 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
416 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
417 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
418 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
419 /* DSP Bit/Manipulation Sub-class */
420 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
421 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
422 /* MIPS DSP Append Sub-class */
423 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
424 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
425 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
426 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
427 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
430 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
431 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
432 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
433 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
434 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
435 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
439 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
442 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
443 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
444 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
445 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp */
446 OPC_ALIGN_END
= (0x0B << 6) | OPC_BSHFL
, /* 010.00 to 010.11 */
447 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
451 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
454 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
455 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
456 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp */
457 OPC_DALIGN_END
= (0x0F << 6) | OPC_DBSHFL
, /* 01.000 to 01.111 */
458 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
461 /* MIPS DSP REGIMM opcodes */
463 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
464 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
467 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
470 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
471 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
472 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
473 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
476 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
478 /* MIPS DSP Arithmetic Sub-class */
479 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
480 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
481 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
482 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
483 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
484 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
485 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
486 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
487 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
488 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
489 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
490 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
491 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
492 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
493 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
494 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
495 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
496 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
497 /* MIPS DSP Multiply Sub-class insns */
498 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
499 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
500 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
501 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
502 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
503 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
506 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
507 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
509 /* MIPS DSP Arithmetic Sub-class */
510 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
511 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
512 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
513 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
514 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
515 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
516 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
517 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
518 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
519 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
520 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
521 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
522 /* MIPS DSP Multiply Sub-class insns */
523 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
524 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
525 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
526 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
529 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
531 /* MIPS DSP Arithmetic Sub-class */
532 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
533 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
534 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
535 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
536 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
537 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
538 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
539 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
540 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
541 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
542 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
543 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
544 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
545 /* DSP Bit/Manipulation Sub-class */
546 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
547 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
548 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
549 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
550 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
553 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
555 /* MIPS DSP Arithmetic Sub-class */
556 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
557 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
558 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
559 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
560 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
561 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
562 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
563 /* DSP Compare-Pick Sub-class */
564 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
565 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
566 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
567 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
568 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
569 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
570 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
571 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
572 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
573 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
574 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
575 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
576 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
577 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
578 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
581 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583 /* MIPS DSP GPR-Based Shift Sub-class */
584 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
585 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
586 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
587 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
588 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
589 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
590 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
591 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
592 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
593 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
594 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
595 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
596 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
597 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
598 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
599 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
600 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
601 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
602 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
603 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
604 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
605 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
608 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
610 /* MIPS DSP Multiply Sub-class insns */
611 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
612 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
613 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
614 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
615 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
616 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
617 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
618 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
619 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
620 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
621 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
622 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
623 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
624 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
625 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
626 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
627 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
628 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
629 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
630 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
631 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
632 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
635 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Bit/Manipulation Sub-class */
638 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
641 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
643 /* MIPS DSP Append Sub-class */
644 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
645 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
646 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
649 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
651 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
652 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
653 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
654 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
655 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
656 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
657 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
658 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
659 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
660 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
661 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
662 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
663 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
664 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
665 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
666 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
667 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
668 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
671 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
673 /* MIPS DSP Arithmetic Sub-class */
674 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
675 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
676 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
677 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
678 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
679 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
680 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
681 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
682 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
683 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
684 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
685 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
686 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
687 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
688 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
689 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
690 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
691 /* DSP Bit/Manipulation Sub-class */
692 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
693 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
694 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
695 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
696 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
697 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
700 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
702 /* MIPS DSP Multiply Sub-class insns */
703 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
704 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
705 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
706 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
707 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
708 /* MIPS DSP Arithmetic Sub-class */
709 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
710 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
711 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
712 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
713 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
714 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
715 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
716 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
717 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
718 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
719 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
720 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
721 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
722 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
723 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
724 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
725 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
726 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
727 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
728 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
729 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
732 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
734 /* DSP Compare-Pick Sub-class */
735 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
736 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
737 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
738 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
739 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
740 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
741 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
742 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
743 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
744 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
745 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
746 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
747 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
748 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
749 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
750 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
751 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
752 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
753 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
754 /* MIPS DSP Arithmetic Sub-class */
755 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
756 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
757 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
758 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
759 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
760 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
761 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
762 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
765 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
767 /* DSP Append Sub-class */
768 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
769 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
770 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
771 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
774 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
776 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
777 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
778 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
779 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
780 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
781 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
782 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
783 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
784 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
785 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
786 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
787 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
788 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
789 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
790 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
791 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
792 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
793 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
794 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
795 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
796 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
797 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
800 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
802 /* DSP Bit/Manipulation Sub-class */
803 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
806 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
808 /* MIPS DSP Multiply Sub-class insns */
809 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
810 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
811 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
812 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
813 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
814 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
815 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
816 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
817 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
818 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
819 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
820 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
821 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
822 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
823 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
824 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
825 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
826 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
827 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
828 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
829 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
830 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
831 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
832 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
833 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
834 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
837 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
839 /* MIPS DSP GPR-Based Shift Sub-class */
840 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
841 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
842 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
843 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
844 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
845 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
846 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
847 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
848 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
849 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
850 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
851 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
852 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
853 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
854 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
855 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
856 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
857 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
858 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
859 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
860 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
861 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
862 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
863 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
864 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
865 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
868 /* Coprocessor 0 (rs field) */
869 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
872 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
873 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
874 OPC_MFHC0
= (0x02 << 21) | OPC_CP0
,
875 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
876 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
877 OPC_MTHC0
= (0x06 << 21) | OPC_CP0
,
878 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
879 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
880 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
881 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
882 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
883 OPC_C0
= (0x10 << 21) | OPC_CP0
,
884 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
885 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
889 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
892 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
893 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
894 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
895 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
896 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
897 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
898 OPC_DVP
= 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0
,
899 OPC_EVP
= 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0
,
902 /* Coprocessor 0 (with rs == C0) */
903 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
906 OPC_TLBR
= 0x01 | OPC_C0
,
907 OPC_TLBWI
= 0x02 | OPC_C0
,
908 OPC_TLBINV
= 0x03 | OPC_C0
,
909 OPC_TLBINVF
= 0x04 | OPC_C0
,
910 OPC_TLBWR
= 0x06 | OPC_C0
,
911 OPC_TLBP
= 0x08 | OPC_C0
,
912 OPC_RFE
= 0x10 | OPC_C0
,
913 OPC_ERET
= 0x18 | OPC_C0
,
914 OPC_DERET
= 0x1F | OPC_C0
,
915 OPC_WAIT
= 0x20 | OPC_C0
,
918 /* Coprocessor 1 (rs field) */
919 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
921 /* Values for the fmt field in FP instructions */
923 /* 0 - 15 are reserved */
924 FMT_S
= 16, /* single fp */
925 FMT_D
= 17, /* double fp */
926 FMT_E
= 18, /* extended fp */
927 FMT_Q
= 19, /* quad fp */
928 FMT_W
= 20, /* 32-bit fixed */
929 FMT_L
= 21, /* 64-bit fixed */
930 FMT_PS
= 22, /* paired single fp */
931 /* 23 - 31 are reserved */
935 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
936 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
937 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
938 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
939 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
940 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
941 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
942 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
943 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
944 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
945 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
946 OPC_BZ_V
= (0x0B << 21) | OPC_CP1
,
947 OPC_BNZ_V
= (0x0F << 21) | OPC_CP1
,
948 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
949 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
950 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
951 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
952 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
953 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
954 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
955 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
956 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
957 OPC_BZ_B
= (0x18 << 21) | OPC_CP1
,
958 OPC_BZ_H
= (0x19 << 21) | OPC_CP1
,
959 OPC_BZ_W
= (0x1A << 21) | OPC_CP1
,
960 OPC_BZ_D
= (0x1B << 21) | OPC_CP1
,
961 OPC_BNZ_B
= (0x1C << 21) | OPC_CP1
,
962 OPC_BNZ_H
= (0x1D << 21) | OPC_CP1
,
963 OPC_BNZ_W
= (0x1E << 21) | OPC_CP1
,
964 OPC_BNZ_D
= (0x1F << 21) | OPC_CP1
,
967 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
968 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
971 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
972 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
973 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
974 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
978 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
979 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
983 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
984 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
987 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
990 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
991 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
992 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
993 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
994 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
995 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
996 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
997 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
998 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
999 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
1000 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
1003 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1006 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
1007 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
1008 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
1009 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
1010 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
1011 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
1012 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
1013 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1015 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1016 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1017 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1018 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1019 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1020 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1021 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1022 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1024 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1025 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1026 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1027 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1028 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1029 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1030 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1031 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1033 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1034 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1035 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1036 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1037 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1038 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1039 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1040 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1042 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1043 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1044 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1045 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1046 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1047 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1049 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1050 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1051 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1052 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1053 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1054 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1056 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1057 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1058 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1059 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1060 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1061 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1063 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1064 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1065 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1066 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1067 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1068 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1070 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1071 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1072 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1073 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1074 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1075 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1077 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1078 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1079 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1080 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1081 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1082 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1084 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1085 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1086 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1087 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1088 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1089 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1091 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1092 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1093 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1094 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1095 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1096 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1100 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1103 OPC_LWXC1
= 0x00 | OPC_CP3
,
1104 OPC_LDXC1
= 0x01 | OPC_CP3
,
1105 OPC_LUXC1
= 0x05 | OPC_CP3
,
1106 OPC_SWXC1
= 0x08 | OPC_CP3
,
1107 OPC_SDXC1
= 0x09 | OPC_CP3
,
1108 OPC_SUXC1
= 0x0D | OPC_CP3
,
1109 OPC_PREFX
= 0x0F | OPC_CP3
,
1110 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1111 OPC_MADD_S
= 0x20 | OPC_CP3
,
1112 OPC_MADD_D
= 0x21 | OPC_CP3
,
1113 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1114 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1115 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1116 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1117 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1118 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1119 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1120 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1121 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1122 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1126 #define MASK_MSA_MINOR(op) (MASK_OP_MAJOR(op) | (op & 0x3F))
1128 OPC_MSA_I8_00
= 0x00 | OPC_MSA
,
1129 OPC_MSA_I8_01
= 0x01 | OPC_MSA
,
1130 OPC_MSA_I8_02
= 0x02 | OPC_MSA
,
1131 OPC_MSA_I5_06
= 0x06 | OPC_MSA
,
1132 OPC_MSA_I5_07
= 0x07 | OPC_MSA
,
1133 OPC_MSA_BIT_09
= 0x09 | OPC_MSA
,
1134 OPC_MSA_BIT_0A
= 0x0A | OPC_MSA
,
1135 OPC_MSA_3R_0D
= 0x0D | OPC_MSA
,
1136 OPC_MSA_3R_0E
= 0x0E | OPC_MSA
,
1137 OPC_MSA_3R_0F
= 0x0F | OPC_MSA
,
1138 OPC_MSA_3R_10
= 0x10 | OPC_MSA
,
1139 OPC_MSA_3R_11
= 0x11 | OPC_MSA
,
1140 OPC_MSA_3R_12
= 0x12 | OPC_MSA
,
1141 OPC_MSA_3R_13
= 0x13 | OPC_MSA
,
1142 OPC_MSA_3R_14
= 0x14 | OPC_MSA
,
1143 OPC_MSA_3R_15
= 0x15 | OPC_MSA
,
1144 OPC_MSA_ELM
= 0x19 | OPC_MSA
,
1145 OPC_MSA_3RF_1A
= 0x1A | OPC_MSA
,
1146 OPC_MSA_3RF_1B
= 0x1B | OPC_MSA
,
1147 OPC_MSA_3RF_1C
= 0x1C | OPC_MSA
,
1148 OPC_MSA_VEC
= 0x1E | OPC_MSA
,
1150 /* MI10 instruction */
1151 OPC_LD_B
= (0x20) | OPC_MSA
,
1152 OPC_LD_H
= (0x21) | OPC_MSA
,
1153 OPC_LD_W
= (0x22) | OPC_MSA
,
1154 OPC_LD_D
= (0x23) | OPC_MSA
,
1155 OPC_ST_B
= (0x24) | OPC_MSA
,
1156 OPC_ST_H
= (0x25) | OPC_MSA
,
1157 OPC_ST_W
= (0x26) | OPC_MSA
,
1158 OPC_ST_D
= (0x27) | OPC_MSA
,
1162 /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1163 OPC_ADDVI_df
= (0x0 << 23) | OPC_MSA_I5_06
,
1164 OPC_CEQI_df
= (0x0 << 23) | OPC_MSA_I5_07
,
1165 OPC_SUBVI_df
= (0x1 << 23) | OPC_MSA_I5_06
,
1166 OPC_MAXI_S_df
= (0x2 << 23) | OPC_MSA_I5_06
,
1167 OPC_CLTI_S_df
= (0x2 << 23) | OPC_MSA_I5_07
,
1168 OPC_MAXI_U_df
= (0x3 << 23) | OPC_MSA_I5_06
,
1169 OPC_CLTI_U_df
= (0x3 << 23) | OPC_MSA_I5_07
,
1170 OPC_MINI_S_df
= (0x4 << 23) | OPC_MSA_I5_06
,
1171 OPC_CLEI_S_df
= (0x4 << 23) | OPC_MSA_I5_07
,
1172 OPC_MINI_U_df
= (0x5 << 23) | OPC_MSA_I5_06
,
1173 OPC_CLEI_U_df
= (0x5 << 23) | OPC_MSA_I5_07
,
1174 OPC_LDI_df
= (0x6 << 23) | OPC_MSA_I5_07
,
1176 /* I8 instruction */
1177 OPC_ANDI_B
= (0x0 << 24) | OPC_MSA_I8_00
,
1178 OPC_BMNZI_B
= (0x0 << 24) | OPC_MSA_I8_01
,
1179 OPC_SHF_B
= (0x0 << 24) | OPC_MSA_I8_02
,
1180 OPC_ORI_B
= (0x1 << 24) | OPC_MSA_I8_00
,
1181 OPC_BMZI_B
= (0x1 << 24) | OPC_MSA_I8_01
,
1182 OPC_SHF_H
= (0x1 << 24) | OPC_MSA_I8_02
,
1183 OPC_NORI_B
= (0x2 << 24) | OPC_MSA_I8_00
,
1184 OPC_BSELI_B
= (0x2 << 24) | OPC_MSA_I8_01
,
1185 OPC_SHF_W
= (0x2 << 24) | OPC_MSA_I8_02
,
1186 OPC_XORI_B
= (0x3 << 24) | OPC_MSA_I8_00
,
1188 /* VEC/2R/2RF instruction */
1189 OPC_AND_V
= (0x00 << 21) | OPC_MSA_VEC
,
1190 OPC_OR_V
= (0x01 << 21) | OPC_MSA_VEC
,
1191 OPC_NOR_V
= (0x02 << 21) | OPC_MSA_VEC
,
1192 OPC_XOR_V
= (0x03 << 21) | OPC_MSA_VEC
,
1193 OPC_BMNZ_V
= (0x04 << 21) | OPC_MSA_VEC
,
1194 OPC_BMZ_V
= (0x05 << 21) | OPC_MSA_VEC
,
1195 OPC_BSEL_V
= (0x06 << 21) | OPC_MSA_VEC
,
1197 OPC_MSA_2R
= (0x18 << 21) | OPC_MSA_VEC
,
1198 OPC_MSA_2RF
= (0x19 << 21) | OPC_MSA_VEC
,
1200 /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1201 OPC_FILL_df
= (0x00 << 18) | OPC_MSA_2R
,
1202 OPC_PCNT_df
= (0x01 << 18) | OPC_MSA_2R
,
1203 OPC_NLOC_df
= (0x02 << 18) | OPC_MSA_2R
,
1204 OPC_NLZC_df
= (0x03 << 18) | OPC_MSA_2R
,
1206 /* 2RF instruction df(bit 16) = _w, _d */
1207 OPC_FCLASS_df
= (0x00 << 17) | OPC_MSA_2RF
,
1208 OPC_FTRUNC_S_df
= (0x01 << 17) | OPC_MSA_2RF
,
1209 OPC_FTRUNC_U_df
= (0x02 << 17) | OPC_MSA_2RF
,
1210 OPC_FSQRT_df
= (0x03 << 17) | OPC_MSA_2RF
,
1211 OPC_FRSQRT_df
= (0x04 << 17) | OPC_MSA_2RF
,
1212 OPC_FRCP_df
= (0x05 << 17) | OPC_MSA_2RF
,
1213 OPC_FRINT_df
= (0x06 << 17) | OPC_MSA_2RF
,
1214 OPC_FLOG2_df
= (0x07 << 17) | OPC_MSA_2RF
,
1215 OPC_FEXUPL_df
= (0x08 << 17) | OPC_MSA_2RF
,
1216 OPC_FEXUPR_df
= (0x09 << 17) | OPC_MSA_2RF
,
1217 OPC_FFQL_df
= (0x0A << 17) | OPC_MSA_2RF
,
1218 OPC_FFQR_df
= (0x0B << 17) | OPC_MSA_2RF
,
1219 OPC_FTINT_S_df
= (0x0C << 17) | OPC_MSA_2RF
,
1220 OPC_FTINT_U_df
= (0x0D << 17) | OPC_MSA_2RF
,
1221 OPC_FFINT_S_df
= (0x0E << 17) | OPC_MSA_2RF
,
1222 OPC_FFINT_U_df
= (0x0F << 17) | OPC_MSA_2RF
,
1224 /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1225 OPC_SLL_df
= (0x0 << 23) | OPC_MSA_3R_0D
,
1226 OPC_ADDV_df
= (0x0 << 23) | OPC_MSA_3R_0E
,
1227 OPC_CEQ_df
= (0x0 << 23) | OPC_MSA_3R_0F
,
1228 OPC_ADD_A_df
= (0x0 << 23) | OPC_MSA_3R_10
,
1229 OPC_SUBS_S_df
= (0x0 << 23) | OPC_MSA_3R_11
,
1230 OPC_MULV_df
= (0x0 << 23) | OPC_MSA_3R_12
,
1231 OPC_DOTP_S_df
= (0x0 << 23) | OPC_MSA_3R_13
,
1232 OPC_SLD_df
= (0x0 << 23) | OPC_MSA_3R_14
,
1233 OPC_VSHF_df
= (0x0 << 23) | OPC_MSA_3R_15
,
1234 OPC_SRA_df
= (0x1 << 23) | OPC_MSA_3R_0D
,
1235 OPC_SUBV_df
= (0x1 << 23) | OPC_MSA_3R_0E
,
1236 OPC_ADDS_A_df
= (0x1 << 23) | OPC_MSA_3R_10
,
1237 OPC_SUBS_U_df
= (0x1 << 23) | OPC_MSA_3R_11
,
1238 OPC_MADDV_df
= (0x1 << 23) | OPC_MSA_3R_12
,
1239 OPC_DOTP_U_df
= (0x1 << 23) | OPC_MSA_3R_13
,
1240 OPC_SPLAT_df
= (0x1 << 23) | OPC_MSA_3R_14
,
1241 OPC_SRAR_df
= (0x1 << 23) | OPC_MSA_3R_15
,
1242 OPC_SRL_df
= (0x2 << 23) | OPC_MSA_3R_0D
,
1243 OPC_MAX_S_df
= (0x2 << 23) | OPC_MSA_3R_0E
,
1244 OPC_CLT_S_df
= (0x2 << 23) | OPC_MSA_3R_0F
,
1245 OPC_ADDS_S_df
= (0x2 << 23) | OPC_MSA_3R_10
,
1246 OPC_SUBSUS_U_df
= (0x2 << 23) | OPC_MSA_3R_11
,
1247 OPC_MSUBV_df
= (0x2 << 23) | OPC_MSA_3R_12
,
1248 OPC_DPADD_S_df
= (0x2 << 23) | OPC_MSA_3R_13
,
1249 OPC_PCKEV_df
= (0x2 << 23) | OPC_MSA_3R_14
,
1250 OPC_SRLR_df
= (0x2 << 23) | OPC_MSA_3R_15
,
1251 OPC_BCLR_df
= (0x3 << 23) | OPC_MSA_3R_0D
,
1252 OPC_MAX_U_df
= (0x3 << 23) | OPC_MSA_3R_0E
,
1253 OPC_CLT_U_df
= (0x3 << 23) | OPC_MSA_3R_0F
,
1254 OPC_ADDS_U_df
= (0x3 << 23) | OPC_MSA_3R_10
,
1255 OPC_SUBSUU_S_df
= (0x3 << 23) | OPC_MSA_3R_11
,
1256 OPC_DPADD_U_df
= (0x3 << 23) | OPC_MSA_3R_13
,
1257 OPC_PCKOD_df
= (0x3 << 23) | OPC_MSA_3R_14
,
1258 OPC_BSET_df
= (0x4 << 23) | OPC_MSA_3R_0D
,
1259 OPC_MIN_S_df
= (0x4 << 23) | OPC_MSA_3R_0E
,
1260 OPC_CLE_S_df
= (0x4 << 23) | OPC_MSA_3R_0F
,
1261 OPC_AVE_S_df
= (0x4 << 23) | OPC_MSA_3R_10
,
1262 OPC_ASUB_S_df
= (0x4 << 23) | OPC_MSA_3R_11
,
1263 OPC_DIV_S_df
= (0x4 << 23) | OPC_MSA_3R_12
,
1264 OPC_DPSUB_S_df
= (0x4 << 23) | OPC_MSA_3R_13
,
1265 OPC_ILVL_df
= (0x4 << 23) | OPC_MSA_3R_14
,
1266 OPC_HADD_S_df
= (0x4 << 23) | OPC_MSA_3R_15
,
1267 OPC_BNEG_df
= (0x5 << 23) | OPC_MSA_3R_0D
,
1268 OPC_MIN_U_df
= (0x5 << 23) | OPC_MSA_3R_0E
,
1269 OPC_CLE_U_df
= (0x5 << 23) | OPC_MSA_3R_0F
,
1270 OPC_AVE_U_df
= (0x5 << 23) | OPC_MSA_3R_10
,
1271 OPC_ASUB_U_df
= (0x5 << 23) | OPC_MSA_3R_11
,
1272 OPC_DIV_U_df
= (0x5 << 23) | OPC_MSA_3R_12
,
1273 OPC_DPSUB_U_df
= (0x5 << 23) | OPC_MSA_3R_13
,
1274 OPC_ILVR_df
= (0x5 << 23) | OPC_MSA_3R_14
,
1275 OPC_HADD_U_df
= (0x5 << 23) | OPC_MSA_3R_15
,
1276 OPC_BINSL_df
= (0x6 << 23) | OPC_MSA_3R_0D
,
1277 OPC_MAX_A_df
= (0x6 << 23) | OPC_MSA_3R_0E
,
1278 OPC_AVER_S_df
= (0x6 << 23) | OPC_MSA_3R_10
,
1279 OPC_MOD_S_df
= (0x6 << 23) | OPC_MSA_3R_12
,
1280 OPC_ILVEV_df
= (0x6 << 23) | OPC_MSA_3R_14
,
1281 OPC_HSUB_S_df
= (0x6 << 23) | OPC_MSA_3R_15
,
1282 OPC_BINSR_df
= (0x7 << 23) | OPC_MSA_3R_0D
,
1283 OPC_MIN_A_df
= (0x7 << 23) | OPC_MSA_3R_0E
,
1284 OPC_AVER_U_df
= (0x7 << 23) | OPC_MSA_3R_10
,
1285 OPC_MOD_U_df
= (0x7 << 23) | OPC_MSA_3R_12
,
1286 OPC_ILVOD_df
= (0x7 << 23) | OPC_MSA_3R_14
,
1287 OPC_HSUB_U_df
= (0x7 << 23) | OPC_MSA_3R_15
,
1289 /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1290 OPC_SLDI_df
= (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1291 OPC_CTCMSA
= (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1292 OPC_SPLATI_df
= (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1293 OPC_CFCMSA
= (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1294 OPC_COPY_S_df
= (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1295 OPC_MOVE_V
= (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM
,
1296 OPC_COPY_U_df
= (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1297 OPC_INSERT_df
= (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1298 OPC_INSVE_df
= (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM
,
1300 /* 3RF instruction _df(bit 21) = _w, _d */
1301 OPC_FCAF_df
= (0x0 << 22) | OPC_MSA_3RF_1A
,
1302 OPC_FADD_df
= (0x0 << 22) | OPC_MSA_3RF_1B
,
1303 OPC_FCUN_df
= (0x1 << 22) | OPC_MSA_3RF_1A
,
1304 OPC_FSUB_df
= (0x1 << 22) | OPC_MSA_3RF_1B
,
1305 OPC_FCOR_df
= (0x1 << 22) | OPC_MSA_3RF_1C
,
1306 OPC_FCEQ_df
= (0x2 << 22) | OPC_MSA_3RF_1A
,
1307 OPC_FMUL_df
= (0x2 << 22) | OPC_MSA_3RF_1B
,
1308 OPC_FCUNE_df
= (0x2 << 22) | OPC_MSA_3RF_1C
,
1309 OPC_FCUEQ_df
= (0x3 << 22) | OPC_MSA_3RF_1A
,
1310 OPC_FDIV_df
= (0x3 << 22) | OPC_MSA_3RF_1B
,
1311 OPC_FCNE_df
= (0x3 << 22) | OPC_MSA_3RF_1C
,
1312 OPC_FCLT_df
= (0x4 << 22) | OPC_MSA_3RF_1A
,
1313 OPC_FMADD_df
= (0x4 << 22) | OPC_MSA_3RF_1B
,
1314 OPC_MUL_Q_df
= (0x4 << 22) | OPC_MSA_3RF_1C
,
1315 OPC_FCULT_df
= (0x5 << 22) | OPC_MSA_3RF_1A
,
1316 OPC_FMSUB_df
= (0x5 << 22) | OPC_MSA_3RF_1B
,
1317 OPC_MADD_Q_df
= (0x5 << 22) | OPC_MSA_3RF_1C
,
1318 OPC_FCLE_df
= (0x6 << 22) | OPC_MSA_3RF_1A
,
1319 OPC_MSUB_Q_df
= (0x6 << 22) | OPC_MSA_3RF_1C
,
1320 OPC_FCULE_df
= (0x7 << 22) | OPC_MSA_3RF_1A
,
1321 OPC_FEXP2_df
= (0x7 << 22) | OPC_MSA_3RF_1B
,
1322 OPC_FSAF_df
= (0x8 << 22) | OPC_MSA_3RF_1A
,
1323 OPC_FEXDO_df
= (0x8 << 22) | OPC_MSA_3RF_1B
,
1324 OPC_FSUN_df
= (0x9 << 22) | OPC_MSA_3RF_1A
,
1325 OPC_FSOR_df
= (0x9 << 22) | OPC_MSA_3RF_1C
,
1326 OPC_FSEQ_df
= (0xA << 22) | OPC_MSA_3RF_1A
,
1327 OPC_FTQ_df
= (0xA << 22) | OPC_MSA_3RF_1B
,
1328 OPC_FSUNE_df
= (0xA << 22) | OPC_MSA_3RF_1C
,
1329 OPC_FSUEQ_df
= (0xB << 22) | OPC_MSA_3RF_1A
,
1330 OPC_FSNE_df
= (0xB << 22) | OPC_MSA_3RF_1C
,
1331 OPC_FSLT_df
= (0xC << 22) | OPC_MSA_3RF_1A
,
1332 OPC_FMIN_df
= (0xC << 22) | OPC_MSA_3RF_1B
,
1333 OPC_MULR_Q_df
= (0xC << 22) | OPC_MSA_3RF_1C
,
1334 OPC_FSULT_df
= (0xD << 22) | OPC_MSA_3RF_1A
,
1335 OPC_FMIN_A_df
= (0xD << 22) | OPC_MSA_3RF_1B
,
1336 OPC_MADDR_Q_df
= (0xD << 22) | OPC_MSA_3RF_1C
,
1337 OPC_FSLE_df
= (0xE << 22) | OPC_MSA_3RF_1A
,
1338 OPC_FMAX_df
= (0xE << 22) | OPC_MSA_3RF_1B
,
1339 OPC_MSUBR_Q_df
= (0xE << 22) | OPC_MSA_3RF_1C
,
1340 OPC_FSULE_df
= (0xF << 22) | OPC_MSA_3RF_1A
,
1341 OPC_FMAX_A_df
= (0xF << 22) | OPC_MSA_3RF_1B
,
1343 /* BIT instruction df(bits 22..16) = _B _H _W _D */
1344 OPC_SLLI_df
= (0x0 << 23) | OPC_MSA_BIT_09
,
1345 OPC_SAT_S_df
= (0x0 << 23) | OPC_MSA_BIT_0A
,
1346 OPC_SRAI_df
= (0x1 << 23) | OPC_MSA_BIT_09
,
1347 OPC_SAT_U_df
= (0x1 << 23) | OPC_MSA_BIT_0A
,
1348 OPC_SRLI_df
= (0x2 << 23) | OPC_MSA_BIT_09
,
1349 OPC_SRARI_df
= (0x2 << 23) | OPC_MSA_BIT_0A
,
1350 OPC_BCLRI_df
= (0x3 << 23) | OPC_MSA_BIT_09
,
1351 OPC_SRLRI_df
= (0x3 << 23) | OPC_MSA_BIT_0A
,
1352 OPC_BSETI_df
= (0x4 << 23) | OPC_MSA_BIT_09
,
1353 OPC_BNEGI_df
= (0x5 << 23) | OPC_MSA_BIT_09
,
1354 OPC_BINSLI_df
= (0x6 << 23) | OPC_MSA_BIT_09
,
1355 OPC_BINSRI_df
= (0x7 << 23) | OPC_MSA_BIT_09
,
1358 /* global register indices */
1359 static TCGv_env cpu_env
;
1360 static TCGv cpu_gpr
[32], cpu_PC
;
1361 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1362 static TCGv cpu_dspctrl
, btarget
, bcond
;
1363 static TCGv_i32 hflags
;
1364 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1365 static TCGv_i64 fpu_f64
[32];
1366 static TCGv_i64 msa_wr_d
[64];
1368 #include "exec/gen-icount.h"
1370 #define gen_helper_0e0i(name, arg) do { \
1371 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1372 gen_helper_##name(cpu_env, helper_tmp); \
1373 tcg_temp_free_i32(helper_tmp); \
1376 #define gen_helper_0e1i(name, arg1, arg2) do { \
1377 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1378 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1379 tcg_temp_free_i32(helper_tmp); \
1382 #define gen_helper_1e0i(name, ret, arg1) do { \
1383 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1384 gen_helper_##name(ret, cpu_env, helper_tmp); \
1385 tcg_temp_free_i32(helper_tmp); \
1388 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1389 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1390 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1391 tcg_temp_free_i32(helper_tmp); \
1394 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1395 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1396 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1397 tcg_temp_free_i32(helper_tmp); \
1400 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1401 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1402 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1403 tcg_temp_free_i32(helper_tmp); \
1406 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1407 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1408 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1409 tcg_temp_free_i32(helper_tmp); \
1412 typedef struct DisasContext
{
1413 struct TranslationBlock
*tb
;
1414 target_ulong pc
, saved_pc
;
1416 int singlestep_enabled
;
1418 int32_t CP0_Config1
;
1419 /* Routine used to access memory */
1421 TCGMemOp default_tcg_memop_mask
;
1422 uint32_t hflags
, saved_hflags
;
1424 target_ulong btarget
;
1433 int CP0_LLAddr_shift
;
1443 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1444 * exception condition */
1445 BS_STOP
= 1, /* We want to stop translation for any reason */
1446 BS_BRANCH
= 2, /* We reached a branch condition */
1447 BS_EXCP
= 3, /* We reached an exception condition */
1450 static const char * const regnames
[] = {
1451 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1452 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1453 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1454 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1457 static const char * const regnames_HI
[] = {
1458 "HI0", "HI1", "HI2", "HI3",
1461 static const char * const regnames_LO
[] = {
1462 "LO0", "LO1", "LO2", "LO3",
1465 static const char * const fregnames
[] = {
1466 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1467 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1468 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1469 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1472 static const char * const msaregnames
[] = {
1473 "w0.d0", "w0.d1", "w1.d0", "w1.d1",
1474 "w2.d0", "w2.d1", "w3.d0", "w3.d1",
1475 "w4.d0", "w4.d1", "w5.d0", "w5.d1",
1476 "w6.d0", "w6.d1", "w7.d0", "w7.d1",
1477 "w8.d0", "w8.d1", "w9.d0", "w9.d1",
1478 "w10.d0", "w10.d1", "w11.d0", "w11.d1",
1479 "w12.d0", "w12.d1", "w13.d0", "w13.d1",
1480 "w14.d0", "w14.d1", "w15.d0", "w15.d1",
1481 "w16.d0", "w16.d1", "w17.d0", "w17.d1",
1482 "w18.d0", "w18.d1", "w19.d0", "w19.d1",
1483 "w20.d0", "w20.d1", "w21.d0", "w21.d1",
1484 "w22.d0", "w22.d1", "w23.d0", "w23.d1",
1485 "w24.d0", "w24.d1", "w25.d0", "w25.d1",
1486 "w26.d0", "w26.d1", "w27.d0", "w27.d1",
1487 "w28.d0", "w28.d1", "w29.d0", "w29.d1",
1488 "w30.d0", "w30.d1", "w31.d0", "w31.d1",
1491 #define LOG_DISAS(...) \
1493 if (MIPS_DEBUG_DISAS) { \
1494 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1498 #define MIPS_INVAL(op) \
1500 if (MIPS_DEBUG_DISAS) { \
1501 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1502 TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
1503 ctx->pc, ctx->opcode, op, ctx->opcode >> 26, \
1504 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F)); \
1508 /* General purpose registers moves. */
1509 static inline void gen_load_gpr (TCGv t
, int reg
)
1512 tcg_gen_movi_tl(t
, 0);
1514 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1517 static inline void gen_store_gpr (TCGv t
, int reg
)
1520 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1523 /* Moves to/from shadow registers. */
1524 static inline void gen_load_srsgpr (int from
, int to
)
1526 TCGv t0
= tcg_temp_new();
1529 tcg_gen_movi_tl(t0
, 0);
1531 TCGv_i32 t2
= tcg_temp_new_i32();
1532 TCGv_ptr addr
= tcg_temp_new_ptr();
1534 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1535 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1536 tcg_gen_andi_i32(t2
, t2
, 0xf);
1537 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1538 tcg_gen_ext_i32_ptr(addr
, t2
);
1539 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1541 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1542 tcg_temp_free_ptr(addr
);
1543 tcg_temp_free_i32(t2
);
1545 gen_store_gpr(t0
, to
);
1549 static inline void gen_store_srsgpr (int from
, int to
)
1552 TCGv t0
= tcg_temp_new();
1553 TCGv_i32 t2
= tcg_temp_new_i32();
1554 TCGv_ptr addr
= tcg_temp_new_ptr();
1556 gen_load_gpr(t0
, from
);
1557 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1558 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1559 tcg_gen_andi_i32(t2
, t2
, 0xf);
1560 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1561 tcg_gen_ext_i32_ptr(addr
, t2
);
1562 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1564 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1565 tcg_temp_free_ptr(addr
);
1566 tcg_temp_free_i32(t2
);
1572 static inline void gen_save_pc(target_ulong pc
)
1574 tcg_gen_movi_tl(cpu_PC
, pc
);
1577 static inline void save_cpu_state(DisasContext
*ctx
, int do_save_pc
)
1579 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1580 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1581 gen_save_pc(ctx
->pc
);
1582 ctx
->saved_pc
= ctx
->pc
;
1584 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1585 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1586 ctx
->saved_hflags
= ctx
->hflags
;
1587 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1593 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1599 static inline void restore_cpu_state(CPUMIPSState
*env
, DisasContext
*ctx
)
1601 ctx
->saved_hflags
= ctx
->hflags
;
1602 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1608 ctx
->btarget
= env
->btarget
;
1613 static inline void generate_exception_err(DisasContext
*ctx
, int excp
, int err
)
1615 TCGv_i32 texcp
= tcg_const_i32(excp
);
1616 TCGv_i32 terr
= tcg_const_i32(err
);
1617 save_cpu_state(ctx
, 1);
1618 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1619 tcg_temp_free_i32(terr
);
1620 tcg_temp_free_i32(texcp
);
1621 ctx
->bstate
= BS_EXCP
;
1624 static inline void generate_exception(DisasContext
*ctx
, int excp
)
1626 gen_helper_0e0i(raise_exception
, excp
);
1629 static inline void generate_exception_end(DisasContext
*ctx
, int excp
)
1631 generate_exception_err(ctx
, excp
, 0);
1634 /* Floating point register moves. */
1635 static void gen_load_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1637 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1638 generate_exception(ctx
, EXCP_RI
);
1640 tcg_gen_extrl_i64_i32(t
, fpu_f64
[reg
]);
1643 static void gen_store_fpr32(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1646 if (ctx
->hflags
& MIPS_HFLAG_FRE
) {
1647 generate_exception(ctx
, EXCP_RI
);
1649 t64
= tcg_temp_new_i64();
1650 tcg_gen_extu_i32_i64(t64
, t
);
1651 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1652 tcg_temp_free_i64(t64
);
1655 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1657 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1658 tcg_gen_extrh_i64_i32(t
, fpu_f64
[reg
]);
1660 gen_load_fpr32(ctx
, t
, reg
| 1);
1664 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1666 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1667 TCGv_i64 t64
= tcg_temp_new_i64();
1668 tcg_gen_extu_i32_i64(t64
, t
);
1669 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1670 tcg_temp_free_i64(t64
);
1672 gen_store_fpr32(ctx
, t
, reg
| 1);
1676 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1678 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1679 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1681 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1685 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1687 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1688 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1691 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1692 t0
= tcg_temp_new_i64();
1693 tcg_gen_shri_i64(t0
, t
, 32);
1694 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1695 tcg_temp_free_i64(t0
);
1699 static inline int get_fp_bit (int cc
)
1707 /* Addresses computation */
1708 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1710 tcg_gen_add_tl(ret
, arg0
, arg1
);
1712 #if defined(TARGET_MIPS64)
1713 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1714 tcg_gen_ext32s_i64(ret
, ret
);
1719 /* Addresses computation (translation time) */
1720 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1723 target_long sum
= base
+ offset
;
1725 #if defined(TARGET_MIPS64)
1726 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1733 /* Sign-extract the low 32-bits to a target_long. */
1734 static inline void gen_move_low32(TCGv ret
, TCGv_i64 arg
)
1736 #if defined(TARGET_MIPS64)
1737 tcg_gen_ext32s_i64(ret
, arg
);
1739 tcg_gen_extrl_i64_i32(ret
, arg
);
1743 /* Sign-extract the high 32-bits to a target_long. */
1744 static inline void gen_move_high32(TCGv ret
, TCGv_i64 arg
)
1746 #if defined(TARGET_MIPS64)
1747 tcg_gen_sari_i64(ret
, arg
, 32);
1749 tcg_gen_extrh_i64_i32(ret
, arg
);
1753 static inline void check_cp0_enabled(DisasContext
*ctx
)
1755 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1756 generate_exception_err(ctx
, EXCP_CpU
, 0);
1759 static inline void check_cp1_enabled(DisasContext
*ctx
)
1761 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1762 generate_exception_err(ctx
, EXCP_CpU
, 1);
1765 /* Verify that the processor is running with COP1X instructions enabled.
1766 This is associated with the nabla symbol in the MIPS32 and MIPS64
1769 static inline void check_cop1x(DisasContext
*ctx
)
1771 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1772 generate_exception_end(ctx
, EXCP_RI
);
1775 /* Verify that the processor is running with 64-bit floating-point
1776 operations enabled. */
1778 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1780 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1781 generate_exception_end(ctx
, EXCP_RI
);
1785 * Verify if floating point register is valid; an operation is not defined
1786 * if bit 0 of any register specification is set and the FR bit in the
1787 * Status register equals zero, since the register numbers specify an
1788 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1789 * in the Status register equals one, both even and odd register numbers
1790 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1792 * Multiple 64 bit wide registers can be checked by calling
1793 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1795 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1797 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1798 generate_exception_end(ctx
, EXCP_RI
);
1801 /* Verify that the processor is running with DSP instructions enabled.
1802 This is enabled by CP0 Status register MX(24) bit.
1805 static inline void check_dsp(DisasContext
*ctx
)
1807 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1808 if (ctx
->insn_flags
& ASE_DSP
) {
1809 generate_exception_end(ctx
, EXCP_DSPDIS
);
1811 generate_exception_end(ctx
, EXCP_RI
);
1816 static inline void check_dspr2(DisasContext
*ctx
)
1818 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1819 if (ctx
->insn_flags
& ASE_DSP
) {
1820 generate_exception_end(ctx
, EXCP_DSPDIS
);
1822 generate_exception_end(ctx
, EXCP_RI
);
1827 /* This code generates a "reserved instruction" exception if the
1828 CPU does not support the instruction set corresponding to flags. */
1829 static inline void check_insn(DisasContext
*ctx
, int flags
)
1831 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1832 generate_exception_end(ctx
, EXCP_RI
);
1836 /* This code generates a "reserved instruction" exception if the
1837 CPU has corresponding flag set which indicates that the instruction
1838 has been removed. */
1839 static inline void check_insn_opc_removed(DisasContext
*ctx
, int flags
)
1841 if (unlikely(ctx
->insn_flags
& flags
)) {
1842 generate_exception_end(ctx
, EXCP_RI
);
1846 /* This code generates a "reserved instruction" exception if the
1847 CPU does not support 64-bit paired-single (PS) floating point data type */
1848 static inline void check_ps(DisasContext
*ctx
)
1850 if (unlikely(!ctx
->ps
)) {
1851 generate_exception(ctx
, EXCP_RI
);
1853 check_cp1_64bitmode(ctx
);
1856 #ifdef TARGET_MIPS64
1857 /* This code generates a "reserved instruction" exception if 64-bit
1858 instructions are not enabled. */
1859 static inline void check_mips_64(DisasContext
*ctx
)
1861 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1862 generate_exception_end(ctx
, EXCP_RI
);
1866 #ifndef CONFIG_USER_ONLY
1867 static inline void check_mvh(DisasContext
*ctx
)
1869 if (unlikely(!ctx
->mvh
)) {
1870 generate_exception(ctx
, EXCP_RI
);
1875 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1876 calling interface for 32 and 64-bit FPRs. No sense in changing
1877 all callers for gen_load_fpr32 when we need the CTX parameter for
1879 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1880 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1881 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1882 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1883 int ft, int fs, int cc) \
1885 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1886 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1895 check_cp1_registers(ctx, fs | ft); \
1903 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1904 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1906 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1907 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1908 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1909 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1910 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1911 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1912 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1913 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1914 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1915 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1916 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1917 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1918 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1919 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1920 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1921 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1924 tcg_temp_free_i##bits (fp0); \
1925 tcg_temp_free_i##bits (fp1); \
1928 FOP_CONDS(, 0, d
, FMT_D
, 64)
1929 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1930 FOP_CONDS(, 0, s
, FMT_S
, 32)
1931 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1932 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1933 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1936 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1937 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1938 int ft, int fs, int fd) \
1940 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1941 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1942 if (ifmt == FMT_D) { \
1943 check_cp1_registers(ctx, fs | ft | fd); \
1945 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1946 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1949 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1952 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1955 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1958 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1961 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1964 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1967 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1970 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1973 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1976 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1979 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1982 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1985 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1988 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1991 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1994 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1997 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
2000 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
2003 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
2006 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
2009 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
2012 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
2018 tcg_temp_free_i ## bits (fp0); \
2019 tcg_temp_free_i ## bits (fp1); \
2022 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
2023 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(ctx
, fp0
, fd
))
2025 #undef gen_ldcmp_fpr32
2026 #undef gen_ldcmp_fpr64
2028 /* load/store instructions. */
2029 #ifdef CONFIG_USER_ONLY
2030 #define OP_LD_ATOMIC(insn,fname) \
2031 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2033 TCGv t0 = tcg_temp_new(); \
2034 tcg_gen_mov_tl(t0, arg1); \
2035 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
2036 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2037 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
2038 tcg_temp_free(t0); \
2041 #define OP_LD_ATOMIC(insn,fname) \
2042 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
2044 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
2047 OP_LD_ATOMIC(ll
,ld32s
);
2048 #if defined(TARGET_MIPS64)
2049 OP_LD_ATOMIC(lld
,ld64
);
2053 #ifdef CONFIG_USER_ONLY
2054 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2055 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2057 TCGv t0 = tcg_temp_new(); \
2058 TCGLabel *l1 = gen_new_label(); \
2059 TCGLabel *l2 = gen_new_label(); \
2061 tcg_gen_andi_tl(t0, arg2, almask); \
2062 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
2063 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
2064 generate_exception(ctx, EXCP_AdES); \
2065 gen_set_label(l1); \
2066 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
2067 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
2068 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
2069 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
2070 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
2071 generate_exception_end(ctx, EXCP_SC); \
2072 gen_set_label(l2); \
2073 tcg_gen_movi_tl(t0, 0); \
2074 gen_store_gpr(t0, rt); \
2075 tcg_temp_free(t0); \
2078 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
2079 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
2081 TCGv t0 = tcg_temp_new(); \
2082 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
2083 gen_store_gpr(t0, rt); \
2084 tcg_temp_free(t0); \
2087 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
2088 #if defined(TARGET_MIPS64)
2089 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
2093 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
2094 int base
, int16_t offset
)
2097 tcg_gen_movi_tl(addr
, offset
);
2098 } else if (offset
== 0) {
2099 gen_load_gpr(addr
, base
);
2101 tcg_gen_movi_tl(addr
, offset
);
2102 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
2106 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
2108 target_ulong pc
= ctx
->pc
;
2110 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
2111 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
2116 pc
&= ~(target_ulong
)3;
2121 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
2122 int rt
, int base
, int16_t offset
)
2126 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
2127 /* Loongson CPU uses a load to zero register for prefetch.
2128 We emulate it as a NOP. On other CPU we must perform the
2129 actual memory access. */
2133 t0
= tcg_temp_new();
2134 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2137 #if defined(TARGET_MIPS64)
2139 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2140 ctx
->default_tcg_memop_mask
);
2141 gen_store_gpr(t0
, rt
);
2144 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2145 ctx
->default_tcg_memop_mask
);
2146 gen_store_gpr(t0
, rt
);
2150 op_ld_lld(t0
, t0
, ctx
);
2151 gen_store_gpr(t0
, rt
);
2154 t1
= tcg_temp_new();
2155 /* Do a byte access to possibly trigger a page
2156 fault with the unaligned address. */
2157 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
2158 tcg_gen_andi_tl(t1
, t0
, 7);
2159 #ifndef TARGET_WORDS_BIGENDIAN
2160 tcg_gen_xori_tl(t1
, t1
, 7);
2162 tcg_gen_shli_tl(t1
, t1
, 3);
2163 tcg_gen_andi_tl(t0
, t0
, ~7);
2164 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2165 tcg_gen_shl_tl(t0
, t0
, t1
);
2166 t2
= tcg_const_tl(-1);
2167 tcg_gen_shl_tl(t2
, t2
, t1
);
2168 gen_load_gpr(t1
, rt
);
2169 tcg_gen_andc_tl(t1
, t1
, t2
);
2171 tcg_gen_or_tl(t0
, t0
, t1
);
2173 gen_store_gpr(t0
, rt
);
2176 t1
= tcg_temp_new();
2177 /* Do a byte access to possibly trigger a page
2178 fault with the unaligned address. */
2179 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
2180 tcg_gen_andi_tl(t1
, t0
, 7);
2181 #ifdef TARGET_WORDS_BIGENDIAN
2182 tcg_gen_xori_tl(t1
, t1
, 7);
2184 tcg_gen_shli_tl(t1
, t1
, 3);
2185 tcg_gen_andi_tl(t0
, t0
, ~7);
2186 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2187 tcg_gen_shr_tl(t0
, t0
, t1
);
2188 tcg_gen_xori_tl(t1
, t1
, 63);
2189 t2
= tcg_const_tl(0xfffffffffffffffeull
);
2190 tcg_gen_shl_tl(t2
, t2
, t1
);
2191 gen_load_gpr(t1
, rt
);
2192 tcg_gen_and_tl(t1
, t1
, t2
);
2194 tcg_gen_or_tl(t0
, t0
, t1
);
2196 gen_store_gpr(t0
, rt
);
2199 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2200 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2202 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2203 gen_store_gpr(t0
, rt
);
2207 t1
= tcg_const_tl(pc_relative_pc(ctx
));
2208 gen_op_addr_add(ctx
, t0
, t0
, t1
);
2210 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
2211 gen_store_gpr(t0
, rt
);
2214 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
|
2215 ctx
->default_tcg_memop_mask
);
2216 gen_store_gpr(t0
, rt
);
2219 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
|
2220 ctx
->default_tcg_memop_mask
);
2221 gen_store_gpr(t0
, rt
);
2224 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
|
2225 ctx
->default_tcg_memop_mask
);
2226 gen_store_gpr(t0
, rt
);
2229 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
2230 gen_store_gpr(t0
, rt
);
2233 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
2234 gen_store_gpr(t0
, rt
);
2237 t1
= tcg_temp_new();
2238 /* Do a byte access to possibly trigger a page
2239 fault with the unaligned address. */
2240 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_UB
);
2241 tcg_gen_andi_tl(t1
, t0
, 3);
2242 #ifndef TARGET_WORDS_BIGENDIAN
2243 tcg_gen_xori_tl(t1
, t1
, 3);
2245 tcg_gen_shli_tl(t1
, t1
, 3);
2246 tcg_gen_andi_tl(t0
, t0
, ~3);
2247 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2248 tcg_gen_shl_tl(t0
, t0
, t1
);
2249 t2
= tcg_const_tl(-1);
2250 tcg_gen_shl_tl(t2
, t2
, t1
);
2251 gen_load_gpr(t1
, rt
);
2252 tcg_gen_andc_tl(t1
, t1
, t2
);
2254 tcg_gen_or_tl(t0
, t0
, t1
);
2256 tcg_gen_ext32s_tl(t0
, t0
);
2257 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
);
2285 op_ld_ll(t0
, t0
, ctx
);
2286 gen_store_gpr(t0
, rt
);
2293 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
2294 int base
, int16_t offset
)
2296 TCGv t0
= tcg_temp_new();
2297 TCGv t1
= tcg_temp_new();
2299 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2300 gen_load_gpr(t1
, rt
);
2302 #if defined(TARGET_MIPS64)
2304 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
|
2305 ctx
->default_tcg_memop_mask
);
2308 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
2311 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
2315 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
|
2316 ctx
->default_tcg_memop_mask
);
2319 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
|
2320 ctx
->default_tcg_memop_mask
);
2323 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
2326 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
2329 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
2337 /* Store conditional */
2338 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
2339 int base
, int16_t offset
)
2343 #ifdef CONFIG_USER_ONLY
2344 t0
= tcg_temp_local_new();
2345 t1
= tcg_temp_local_new();
2347 t0
= tcg_temp_new();
2348 t1
= tcg_temp_new();
2350 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2351 gen_load_gpr(t1
, rt
);
2353 #if defined(TARGET_MIPS64)
2356 op_st_scd(t1
, t0
, rt
, ctx
);
2361 op_st_sc(t1
, t0
, rt
, ctx
);
2368 /* Load and store */
2369 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
2370 int base
, int16_t offset
)
2372 TCGv t0
= tcg_temp_new();
2374 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2375 /* Don't do NOP if destination is zero: we must perform the actual
2380 TCGv_i32 fp0
= tcg_temp_new_i32();
2381 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
|
2382 ctx
->default_tcg_memop_mask
);
2383 gen_store_fpr32(ctx
, fp0
, ft
);
2384 tcg_temp_free_i32(fp0
);
2389 TCGv_i32 fp0
= tcg_temp_new_i32();
2390 gen_load_fpr32(ctx
, fp0
, ft
);
2391 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
|
2392 ctx
->default_tcg_memop_mask
);
2393 tcg_temp_free_i32(fp0
);
2398 TCGv_i64 fp0
= tcg_temp_new_i64();
2399 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2400 ctx
->default_tcg_memop_mask
);
2401 gen_store_fpr64(ctx
, fp0
, ft
);
2402 tcg_temp_free_i64(fp0
);
2407 TCGv_i64 fp0
= tcg_temp_new_i64();
2408 gen_load_fpr64(ctx
, fp0
, ft
);
2409 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
|
2410 ctx
->default_tcg_memop_mask
);
2411 tcg_temp_free_i64(fp0
);
2415 MIPS_INVAL("flt_ldst");
2416 generate_exception_end(ctx
, EXCP_RI
);
2423 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2424 int rs
, int16_t imm
)
2426 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2427 check_cp1_enabled(ctx
);
2431 check_insn(ctx
, ISA_MIPS2
);
2434 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
2437 generate_exception_err(ctx
, EXCP_CpU
, 1);
2441 /* Arithmetic with immediate operand */
2442 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2443 int rt
, int rs
, int16_t imm
)
2445 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2447 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2448 /* If no destination, treat it as a NOP.
2449 For addi, we must generate the overflow exception when needed. */
2455 TCGv t0
= tcg_temp_local_new();
2456 TCGv t1
= tcg_temp_new();
2457 TCGv t2
= tcg_temp_new();
2458 TCGLabel
*l1
= gen_new_label();
2460 gen_load_gpr(t1
, rs
);
2461 tcg_gen_addi_tl(t0
, t1
, uimm
);
2462 tcg_gen_ext32s_tl(t0
, t0
);
2464 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2465 tcg_gen_xori_tl(t2
, t0
, uimm
);
2466 tcg_gen_and_tl(t1
, t1
, t2
);
2468 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2470 /* operands of same sign, result different sign */
2471 generate_exception(ctx
, EXCP_OVERFLOW
);
2473 tcg_gen_ext32s_tl(t0
, t0
);
2474 gen_store_gpr(t0
, rt
);
2480 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2481 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2483 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2486 #if defined(TARGET_MIPS64)
2489 TCGv t0
= tcg_temp_local_new();
2490 TCGv t1
= tcg_temp_new();
2491 TCGv t2
= tcg_temp_new();
2492 TCGLabel
*l1
= gen_new_label();
2494 gen_load_gpr(t1
, rs
);
2495 tcg_gen_addi_tl(t0
, t1
, uimm
);
2497 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2498 tcg_gen_xori_tl(t2
, t0
, uimm
);
2499 tcg_gen_and_tl(t1
, t1
, t2
);
2501 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2503 /* operands of same sign, result different sign */
2504 generate_exception(ctx
, EXCP_OVERFLOW
);
2506 gen_store_gpr(t0
, rt
);
2512 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2514 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2521 /* Logic with immediate operand */
2522 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2523 int rt
, int rs
, int16_t imm
)
2528 /* If no destination, treat it as a NOP. */
2531 uimm
= (uint16_t)imm
;
2534 if (likely(rs
!= 0))
2535 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2537 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2541 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2543 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2546 if (likely(rs
!= 0))
2547 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2549 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2552 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
2554 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2555 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2557 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2566 /* Set on less than with immediate operand */
2567 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2568 int rt
, int rs
, int16_t imm
)
2570 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2574 /* If no destination, treat it as a NOP. */
2577 t0
= tcg_temp_new();
2578 gen_load_gpr(t0
, rs
);
2581 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2584 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2590 /* Shifts with immediate operand */
2591 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2592 int rt
, int rs
, int16_t imm
)
2594 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2598 /* If no destination, treat it as a NOP. */
2602 t0
= tcg_temp_new();
2603 gen_load_gpr(t0
, rs
);
2606 tcg_gen_shli_tl(t0
, t0
, uimm
);
2607 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2610 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2614 tcg_gen_ext32u_tl(t0
, t0
);
2615 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2617 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2622 TCGv_i32 t1
= tcg_temp_new_i32();
2624 tcg_gen_trunc_tl_i32(t1
, t0
);
2625 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2626 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2627 tcg_temp_free_i32(t1
);
2629 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2632 #if defined(TARGET_MIPS64)
2634 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2637 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2640 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2644 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2646 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2650 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2653 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2656 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2659 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2667 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2668 int rd
, int rs
, int rt
)
2670 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2671 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2672 /* If no destination, treat it as a NOP.
2673 For add & sub, we must generate the overflow exception when needed. */
2680 TCGv t0
= tcg_temp_local_new();
2681 TCGv t1
= tcg_temp_new();
2682 TCGv t2
= tcg_temp_new();
2683 TCGLabel
*l1
= gen_new_label();
2685 gen_load_gpr(t1
, rs
);
2686 gen_load_gpr(t2
, rt
);
2687 tcg_gen_add_tl(t0
, t1
, t2
);
2688 tcg_gen_ext32s_tl(t0
, t0
);
2689 tcg_gen_xor_tl(t1
, t1
, t2
);
2690 tcg_gen_xor_tl(t2
, t0
, t2
);
2691 tcg_gen_andc_tl(t1
, t2
, t1
);
2693 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2695 /* operands of same sign, result different sign */
2696 generate_exception(ctx
, EXCP_OVERFLOW
);
2698 gen_store_gpr(t0
, rd
);
2703 if (rs
!= 0 && rt
!= 0) {
2704 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2705 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2706 } else if (rs
== 0 && rt
!= 0) {
2707 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2708 } else if (rs
!= 0 && rt
== 0) {
2709 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2711 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2716 TCGv t0
= tcg_temp_local_new();
2717 TCGv t1
= tcg_temp_new();
2718 TCGv t2
= tcg_temp_new();
2719 TCGLabel
*l1
= gen_new_label();
2721 gen_load_gpr(t1
, rs
);
2722 gen_load_gpr(t2
, rt
);
2723 tcg_gen_sub_tl(t0
, t1
, t2
);
2724 tcg_gen_ext32s_tl(t0
, t0
);
2725 tcg_gen_xor_tl(t2
, t1
, t2
);
2726 tcg_gen_xor_tl(t1
, t0
, t1
);
2727 tcg_gen_and_tl(t1
, t1
, t2
);
2729 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2731 /* operands of different sign, first operand and result different sign */
2732 generate_exception(ctx
, EXCP_OVERFLOW
);
2734 gen_store_gpr(t0
, rd
);
2739 if (rs
!= 0 && rt
!= 0) {
2740 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2741 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2742 } else if (rs
== 0 && rt
!= 0) {
2743 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2744 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2745 } else if (rs
!= 0 && rt
== 0) {
2746 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2748 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2751 #if defined(TARGET_MIPS64)
2754 TCGv t0
= tcg_temp_local_new();
2755 TCGv t1
= tcg_temp_new();
2756 TCGv t2
= tcg_temp_new();
2757 TCGLabel
*l1
= gen_new_label();
2759 gen_load_gpr(t1
, rs
);
2760 gen_load_gpr(t2
, rt
);
2761 tcg_gen_add_tl(t0
, t1
, t2
);
2762 tcg_gen_xor_tl(t1
, t1
, t2
);
2763 tcg_gen_xor_tl(t2
, t0
, t2
);
2764 tcg_gen_andc_tl(t1
, t2
, t1
);
2766 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2768 /* operands of same sign, result different sign */
2769 generate_exception(ctx
, EXCP_OVERFLOW
);
2771 gen_store_gpr(t0
, rd
);
2776 if (rs
!= 0 && rt
!= 0) {
2777 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2778 } else if (rs
== 0 && rt
!= 0) {
2779 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2780 } else if (rs
!= 0 && rt
== 0) {
2781 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2783 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2788 TCGv t0
= tcg_temp_local_new();
2789 TCGv t1
= tcg_temp_new();
2790 TCGv t2
= tcg_temp_new();
2791 TCGLabel
*l1
= gen_new_label();
2793 gen_load_gpr(t1
, rs
);
2794 gen_load_gpr(t2
, rt
);
2795 tcg_gen_sub_tl(t0
, t1
, t2
);
2796 tcg_gen_xor_tl(t2
, t1
, t2
);
2797 tcg_gen_xor_tl(t1
, t0
, t1
);
2798 tcg_gen_and_tl(t1
, t1
, t2
);
2800 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2802 /* operands of different sign, first operand and result different sign */
2803 generate_exception(ctx
, EXCP_OVERFLOW
);
2805 gen_store_gpr(t0
, rd
);
2810 if (rs
!= 0 && rt
!= 0) {
2811 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2812 } else if (rs
== 0 && rt
!= 0) {
2813 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2814 } else if (rs
!= 0 && rt
== 0) {
2815 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2817 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2822 if (likely(rs
!= 0 && rt
!= 0)) {
2823 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2824 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2826 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2832 /* Conditional move */
2833 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2834 int rd
, int rs
, int rt
)
2839 /* If no destination, treat it as a NOP. */
2843 t0
= tcg_temp_new();
2844 gen_load_gpr(t0
, rt
);
2845 t1
= tcg_const_tl(0);
2846 t2
= tcg_temp_new();
2847 gen_load_gpr(t2
, rs
);
2850 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2853 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2856 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2859 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2868 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2869 int rd
, int rs
, int rt
)
2872 /* If no destination, treat it as a NOP. */
2878 if (likely(rs
!= 0 && rt
!= 0)) {
2879 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2881 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2885 if (rs
!= 0 && rt
!= 0) {
2886 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2887 } else if (rs
== 0 && rt
!= 0) {
2888 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2889 } else if (rs
!= 0 && rt
== 0) {
2890 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2892 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2896 if (likely(rs
!= 0 && rt
!= 0)) {
2897 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2898 } else if (rs
== 0 && rt
!= 0) {
2899 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2900 } else if (rs
!= 0 && rt
== 0) {
2901 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2903 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2907 if (likely(rs
!= 0 && rt
!= 0)) {
2908 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2909 } else if (rs
== 0 && rt
!= 0) {
2910 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2911 } else if (rs
!= 0 && rt
== 0) {
2912 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2914 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2920 /* Set on lower than */
2921 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2922 int rd
, int rs
, int rt
)
2927 /* If no destination, treat it as a NOP. */
2931 t0
= tcg_temp_new();
2932 t1
= tcg_temp_new();
2933 gen_load_gpr(t0
, rs
);
2934 gen_load_gpr(t1
, rt
);
2937 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2940 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2948 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2949 int rd
, int rs
, int rt
)
2954 /* If no destination, treat it as a NOP.
2955 For add & sub, we must generate the overflow exception when needed. */
2959 t0
= tcg_temp_new();
2960 t1
= tcg_temp_new();
2961 gen_load_gpr(t0
, rs
);
2962 gen_load_gpr(t1
, rt
);
2965 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2966 tcg_gen_shl_tl(t0
, t1
, t0
);
2967 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2970 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2971 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2974 tcg_gen_ext32u_tl(t1
, t1
);
2975 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2976 tcg_gen_shr_tl(t0
, t1
, t0
);
2977 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2981 TCGv_i32 t2
= tcg_temp_new_i32();
2982 TCGv_i32 t3
= tcg_temp_new_i32();
2984 tcg_gen_trunc_tl_i32(t2
, t0
);
2985 tcg_gen_trunc_tl_i32(t3
, t1
);
2986 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2987 tcg_gen_rotr_i32(t2
, t3
, t2
);
2988 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2989 tcg_temp_free_i32(t2
);
2990 tcg_temp_free_i32(t3
);
2993 #if defined(TARGET_MIPS64)
2995 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2996 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2999 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3000 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
3003 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3004 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
3007 tcg_gen_andi_tl(t0
, t0
, 0x3f);
3008 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
3016 /* Arithmetic on HI/LO registers */
3017 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
3019 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
3030 #if defined(TARGET_MIPS64)
3032 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3036 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
3040 #if defined(TARGET_MIPS64)
3042 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3046 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
3051 #if defined(TARGET_MIPS64)
3053 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3057 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
3060 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
3065 #if defined(TARGET_MIPS64)
3067 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3071 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
3074 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
3080 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
3083 TCGv t0
= tcg_const_tl(addr
);
3084 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
3085 gen_store_gpr(t0
, reg
);
3089 static inline void gen_pcrel(DisasContext
*ctx
, int opc
, target_ulong pc
,
3095 switch (MASK_OPC_PCREL_TOP2BITS(opc
)) {
3098 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3099 addr
= addr_add(ctx
, pc
, offset
);
3100 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3104 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3105 addr
= addr_add(ctx
, pc
, offset
);
3106 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
3108 #if defined(TARGET_MIPS64)
3111 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
3112 addr
= addr_add(ctx
, pc
, offset
);
3113 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
3117 switch (MASK_OPC_PCREL_TOP5BITS(opc
)) {
3120 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3121 addr
= addr_add(ctx
, pc
, offset
);
3122 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3127 offset
= sextract32(ctx
->opcode
, 0, 16) << 16;
3128 addr
= ~0xFFFF & addr_add(ctx
, pc
, offset
);
3129 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
3132 #if defined(TARGET_MIPS64)
3133 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
3134 case R6_OPC_LDPC
+ (1 << 16):
3135 case R6_OPC_LDPC
+ (2 << 16):
3136 case R6_OPC_LDPC
+ (3 << 16):
3138 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
3139 addr
= addr_add(ctx
, (pc
& ~0x7), offset
);
3140 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
3144 MIPS_INVAL("OPC_PCREL");
3145 generate_exception_end(ctx
, EXCP_RI
);
3152 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
3161 t0
= tcg_temp_new();
3162 t1
= tcg_temp_new();
3164 gen_load_gpr(t0
, rs
);
3165 gen_load_gpr(t1
, rt
);
3170 TCGv t2
= tcg_temp_new();
3171 TCGv t3
= tcg_temp_new();
3172 tcg_gen_ext32s_tl(t0
, t0
);
3173 tcg_gen_ext32s_tl(t1
, t1
);
3174 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3175 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3176 tcg_gen_and_tl(t2
, t2
, t3
);
3177 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3178 tcg_gen_or_tl(t2
, t2
, t3
);
3179 tcg_gen_movi_tl(t3
, 0);
3180 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3181 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3182 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3189 TCGv t2
= tcg_temp_new();
3190 TCGv t3
= tcg_temp_new();
3191 tcg_gen_ext32s_tl(t0
, t0
);
3192 tcg_gen_ext32s_tl(t1
, t1
);
3193 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3194 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3195 tcg_gen_and_tl(t2
, t2
, t3
);
3196 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3197 tcg_gen_or_tl(t2
, t2
, t3
);
3198 tcg_gen_movi_tl(t3
, 0);
3199 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3200 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3201 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3208 TCGv t2
= tcg_const_tl(0);
3209 TCGv t3
= tcg_const_tl(1);
3210 tcg_gen_ext32u_tl(t0
, t0
);
3211 tcg_gen_ext32u_tl(t1
, t1
);
3212 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3213 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3214 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3221 TCGv t2
= tcg_const_tl(0);
3222 TCGv t3
= tcg_const_tl(1);
3223 tcg_gen_ext32u_tl(t0
, t0
);
3224 tcg_gen_ext32u_tl(t1
, t1
);
3225 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3226 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3227 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3234 TCGv_i32 t2
= tcg_temp_new_i32();
3235 TCGv_i32 t3
= tcg_temp_new_i32();
3236 tcg_gen_trunc_tl_i32(t2
, t0
);
3237 tcg_gen_trunc_tl_i32(t3
, t1
);
3238 tcg_gen_mul_i32(t2
, t2
, t3
);
3239 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3240 tcg_temp_free_i32(t2
);
3241 tcg_temp_free_i32(t3
);
3246 TCGv_i32 t2
= tcg_temp_new_i32();
3247 TCGv_i32 t3
= tcg_temp_new_i32();
3248 tcg_gen_trunc_tl_i32(t2
, t0
);
3249 tcg_gen_trunc_tl_i32(t3
, t1
);
3250 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3251 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3252 tcg_temp_free_i32(t2
);
3253 tcg_temp_free_i32(t3
);
3258 TCGv_i32 t2
= tcg_temp_new_i32();
3259 TCGv_i32 t3
= tcg_temp_new_i32();
3260 tcg_gen_trunc_tl_i32(t2
, t0
);
3261 tcg_gen_trunc_tl_i32(t3
, t1
);
3262 tcg_gen_mul_i32(t2
, t2
, t3
);
3263 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3264 tcg_temp_free_i32(t2
);
3265 tcg_temp_free_i32(t3
);
3270 TCGv_i32 t2
= tcg_temp_new_i32();
3271 TCGv_i32 t3
= tcg_temp_new_i32();
3272 tcg_gen_trunc_tl_i32(t2
, t0
);
3273 tcg_gen_trunc_tl_i32(t3
, t1
);
3274 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3275 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3276 tcg_temp_free_i32(t2
);
3277 tcg_temp_free_i32(t3
);
3280 #if defined(TARGET_MIPS64)
3283 TCGv t2
= tcg_temp_new();
3284 TCGv t3
= tcg_temp_new();
3285 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3286 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3287 tcg_gen_and_tl(t2
, t2
, t3
);
3288 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3289 tcg_gen_or_tl(t2
, t2
, t3
);
3290 tcg_gen_movi_tl(t3
, 0);
3291 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3292 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3299 TCGv t2
= tcg_temp_new();
3300 TCGv t3
= tcg_temp_new();
3301 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3302 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3303 tcg_gen_and_tl(t2
, t2
, t3
);
3304 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3305 tcg_gen_or_tl(t2
, t2
, t3
);
3306 tcg_gen_movi_tl(t3
, 0);
3307 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3308 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3315 TCGv t2
= tcg_const_tl(0);
3316 TCGv t3
= tcg_const_tl(1);
3317 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3318 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3325 TCGv t2
= tcg_const_tl(0);
3326 TCGv t3
= tcg_const_tl(1);
3327 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3328 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3334 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3338 TCGv t2
= tcg_temp_new();
3339 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3344 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3348 TCGv t2
= tcg_temp_new();
3349 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3355 MIPS_INVAL("r6 mul/div");
3356 generate_exception_end(ctx
, EXCP_RI
);
3364 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3365 int acc
, int rs
, int rt
)
3369 t0
= tcg_temp_new();
3370 t1
= tcg_temp_new();
3372 gen_load_gpr(t0
, rs
);
3373 gen_load_gpr(t1
, rt
);
3382 TCGv t2
= tcg_temp_new();
3383 TCGv t3
= tcg_temp_new();
3384 tcg_gen_ext32s_tl(t0
, t0
);
3385 tcg_gen_ext32s_tl(t1
, t1
);
3386 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3387 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3388 tcg_gen_and_tl(t2
, t2
, t3
);
3389 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3390 tcg_gen_or_tl(t2
, t2
, t3
);
3391 tcg_gen_movi_tl(t3
, 0);
3392 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3393 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3394 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3395 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3396 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3403 TCGv t2
= tcg_const_tl(0);
3404 TCGv t3
= tcg_const_tl(1);
3405 tcg_gen_ext32u_tl(t0
, t0
);
3406 tcg_gen_ext32u_tl(t1
, t1
);
3407 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3408 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3409 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3410 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3411 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3418 TCGv_i32 t2
= tcg_temp_new_i32();
3419 TCGv_i32 t3
= tcg_temp_new_i32();
3420 tcg_gen_trunc_tl_i32(t2
, t0
);
3421 tcg_gen_trunc_tl_i32(t3
, t1
);
3422 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3423 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3424 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3425 tcg_temp_free_i32(t2
);
3426 tcg_temp_free_i32(t3
);
3431 TCGv_i32 t2
= tcg_temp_new_i32();
3432 TCGv_i32 t3
= tcg_temp_new_i32();
3433 tcg_gen_trunc_tl_i32(t2
, t0
);
3434 tcg_gen_trunc_tl_i32(t3
, t1
);
3435 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3436 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3437 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3438 tcg_temp_free_i32(t2
);
3439 tcg_temp_free_i32(t3
);
3442 #if defined(TARGET_MIPS64)
3445 TCGv t2
= tcg_temp_new();
3446 TCGv t3
= tcg_temp_new();
3447 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3448 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3449 tcg_gen_and_tl(t2
, t2
, t3
);
3450 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3451 tcg_gen_or_tl(t2
, t2
, t3
);
3452 tcg_gen_movi_tl(t3
, 0);
3453 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3454 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3455 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3462 TCGv t2
= tcg_const_tl(0);
3463 TCGv t3
= tcg_const_tl(1);
3464 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3465 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3466 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3472 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3475 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3480 TCGv_i64 t2
= tcg_temp_new_i64();
3481 TCGv_i64 t3
= tcg_temp_new_i64();
3483 tcg_gen_ext_tl_i64(t2
, t0
);
3484 tcg_gen_ext_tl_i64(t3
, t1
);
3485 tcg_gen_mul_i64(t2
, t2
, t3
);
3486 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3487 tcg_gen_add_i64(t2
, t2
, t3
);
3488 tcg_temp_free_i64(t3
);
3489 gen_move_low32(cpu_LO
[acc
], t2
);
3490 gen_move_high32(cpu_HI
[acc
], t2
);
3491 tcg_temp_free_i64(t2
);
3496 TCGv_i64 t2
= tcg_temp_new_i64();
3497 TCGv_i64 t3
= tcg_temp_new_i64();
3499 tcg_gen_ext32u_tl(t0
, t0
);
3500 tcg_gen_ext32u_tl(t1
, t1
);
3501 tcg_gen_extu_tl_i64(t2
, t0
);
3502 tcg_gen_extu_tl_i64(t3
, t1
);
3503 tcg_gen_mul_i64(t2
, t2
, t3
);
3504 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3505 tcg_gen_add_i64(t2
, t2
, t3
);
3506 tcg_temp_free_i64(t3
);
3507 gen_move_low32(cpu_LO
[acc
], t2
);
3508 gen_move_high32(cpu_HI
[acc
], t2
);
3509 tcg_temp_free_i64(t2
);
3514 TCGv_i64 t2
= tcg_temp_new_i64();
3515 TCGv_i64 t3
= tcg_temp_new_i64();
3517 tcg_gen_ext_tl_i64(t2
, t0
);
3518 tcg_gen_ext_tl_i64(t3
, t1
);
3519 tcg_gen_mul_i64(t2
, t2
, t3
);
3520 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3521 tcg_gen_sub_i64(t2
, t3
, t2
);
3522 tcg_temp_free_i64(t3
);
3523 gen_move_low32(cpu_LO
[acc
], t2
);
3524 gen_move_high32(cpu_HI
[acc
], t2
);
3525 tcg_temp_free_i64(t2
);
3530 TCGv_i64 t2
= tcg_temp_new_i64();
3531 TCGv_i64 t3
= tcg_temp_new_i64();
3533 tcg_gen_ext32u_tl(t0
, t0
);
3534 tcg_gen_ext32u_tl(t1
, t1
);
3535 tcg_gen_extu_tl_i64(t2
, t0
);
3536 tcg_gen_extu_tl_i64(t3
, t1
);
3537 tcg_gen_mul_i64(t2
, t2
, t3
);
3538 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3539 tcg_gen_sub_i64(t2
, t3
, t2
);
3540 tcg_temp_free_i64(t3
);
3541 gen_move_low32(cpu_LO
[acc
], t2
);
3542 gen_move_high32(cpu_HI
[acc
], t2
);
3543 tcg_temp_free_i64(t2
);
3547 MIPS_INVAL("mul/div");
3548 generate_exception_end(ctx
, EXCP_RI
);
3556 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
3557 int rd
, int rs
, int rt
)
3559 TCGv t0
= tcg_temp_new();
3560 TCGv t1
= tcg_temp_new();
3562 gen_load_gpr(t0
, rs
);
3563 gen_load_gpr(t1
, rt
);
3566 case OPC_VR54XX_MULS
:
3567 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3569 case OPC_VR54XX_MULSU
:
3570 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3572 case OPC_VR54XX_MACC
:
3573 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3575 case OPC_VR54XX_MACCU
:
3576 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3578 case OPC_VR54XX_MSAC
:
3579 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3581 case OPC_VR54XX_MSACU
:
3582 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3584 case OPC_VR54XX_MULHI
:
3585 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3587 case OPC_VR54XX_MULHIU
:
3588 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3590 case OPC_VR54XX_MULSHI
:
3591 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3593 case OPC_VR54XX_MULSHIU
:
3594 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3596 case OPC_VR54XX_MACCHI
:
3597 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3599 case OPC_VR54XX_MACCHIU
:
3600 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3602 case OPC_VR54XX_MSACHI
:
3603 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3605 case OPC_VR54XX_MSACHIU
:
3606 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3609 MIPS_INVAL("mul vr54xx");
3610 generate_exception_end(ctx
, EXCP_RI
);
3613 gen_store_gpr(t0
, rd
);
3620 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
3630 gen_load_gpr(t0
, rs
);
3635 #if defined(TARGET_MIPS64)
3639 tcg_gen_not_tl(t0
, t0
);
3648 tcg_gen_ext32u_tl(t0
, t0
);
3649 tcg_gen_clzi_tl(t0
, t0
, TARGET_LONG_BITS
);
3650 tcg_gen_subi_tl(t0
, t0
, TARGET_LONG_BITS
- 32);
3652 #if defined(TARGET_MIPS64)
3657 tcg_gen_clzi_i64(t0
, t0
, 64);
3663 /* Godson integer instructions */
3664 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3665 int rd
, int rs
, int rt
)
3677 case OPC_MULTU_G_2E
:
3678 case OPC_MULTU_G_2F
:
3679 #if defined(TARGET_MIPS64)
3680 case OPC_DMULT_G_2E
:
3681 case OPC_DMULT_G_2F
:
3682 case OPC_DMULTU_G_2E
:
3683 case OPC_DMULTU_G_2F
:
3685 t0
= tcg_temp_new();
3686 t1
= tcg_temp_new();
3689 t0
= tcg_temp_local_new();
3690 t1
= tcg_temp_local_new();
3694 gen_load_gpr(t0
, rs
);
3695 gen_load_gpr(t1
, rt
);
3700 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3701 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3703 case OPC_MULTU_G_2E
:
3704 case OPC_MULTU_G_2F
:
3705 tcg_gen_ext32u_tl(t0
, t0
);
3706 tcg_gen_ext32u_tl(t1
, t1
);
3707 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3708 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3713 TCGLabel
*l1
= gen_new_label();
3714 TCGLabel
*l2
= gen_new_label();
3715 TCGLabel
*l3
= gen_new_label();
3716 tcg_gen_ext32s_tl(t0
, t0
);
3717 tcg_gen_ext32s_tl(t1
, t1
);
3718 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3719 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3722 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3723 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3724 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3727 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3728 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3735 TCGLabel
*l1
= gen_new_label();
3736 TCGLabel
*l2
= gen_new_label();
3737 tcg_gen_ext32u_tl(t0
, t0
);
3738 tcg_gen_ext32u_tl(t1
, t1
);
3739 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3740 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3743 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3744 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3751 TCGLabel
*l1
= gen_new_label();
3752 TCGLabel
*l2
= gen_new_label();
3753 TCGLabel
*l3
= gen_new_label();
3754 tcg_gen_ext32u_tl(t0
, t0
);
3755 tcg_gen_ext32u_tl(t1
, t1
);
3756 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3757 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3758 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3760 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3763 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3764 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3771 TCGLabel
*l1
= gen_new_label();
3772 TCGLabel
*l2
= gen_new_label();
3773 tcg_gen_ext32u_tl(t0
, t0
);
3774 tcg_gen_ext32u_tl(t1
, t1
);
3775 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3776 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3779 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3780 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3784 #if defined(TARGET_MIPS64)
3785 case OPC_DMULT_G_2E
:
3786 case OPC_DMULT_G_2F
:
3787 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3789 case OPC_DMULTU_G_2E
:
3790 case OPC_DMULTU_G_2F
:
3791 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3796 TCGLabel
*l1
= gen_new_label();
3797 TCGLabel
*l2
= gen_new_label();
3798 TCGLabel
*l3
= gen_new_label();
3799 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3800 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3803 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3804 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3805 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3808 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3812 case OPC_DDIVU_G_2E
:
3813 case OPC_DDIVU_G_2F
:
3815 TCGLabel
*l1
= gen_new_label();
3816 TCGLabel
*l2
= gen_new_label();
3817 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3818 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3821 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3828 TCGLabel
*l1
= gen_new_label();
3829 TCGLabel
*l2
= gen_new_label();
3830 TCGLabel
*l3
= gen_new_label();
3831 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3832 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3833 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3835 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3838 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3842 case OPC_DMODU_G_2E
:
3843 case OPC_DMODU_G_2F
:
3845 TCGLabel
*l1
= gen_new_label();
3846 TCGLabel
*l2
= gen_new_label();
3847 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3848 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3851 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3862 /* Loongson multimedia instructions */
3863 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3865 uint32_t opc
, shift_max
;
3868 opc
= MASK_LMI(ctx
->opcode
);
3874 t0
= tcg_temp_local_new_i64();
3875 t1
= tcg_temp_local_new_i64();
3878 t0
= tcg_temp_new_i64();
3879 t1
= tcg_temp_new_i64();
3883 check_cp1_enabled(ctx
);
3884 gen_load_fpr64(ctx
, t0
, rs
);
3885 gen_load_fpr64(ctx
, t1
, rt
);
3887 #define LMI_HELPER(UP, LO) \
3888 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3889 #define LMI_HELPER_1(UP, LO) \
3890 case OPC_##UP: gen_helper_##LO(t0, t0); break
3891 #define LMI_DIRECT(UP, LO, OP) \
3892 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3895 LMI_HELPER(PADDSH
, paddsh
);
3896 LMI_HELPER(PADDUSH
, paddush
);
3897 LMI_HELPER(PADDH
, paddh
);
3898 LMI_HELPER(PADDW
, paddw
);
3899 LMI_HELPER(PADDSB
, paddsb
);
3900 LMI_HELPER(PADDUSB
, paddusb
);
3901 LMI_HELPER(PADDB
, paddb
);
3903 LMI_HELPER(PSUBSH
, psubsh
);
3904 LMI_HELPER(PSUBUSH
, psubush
);
3905 LMI_HELPER(PSUBH
, psubh
);
3906 LMI_HELPER(PSUBW
, psubw
);
3907 LMI_HELPER(PSUBSB
, psubsb
);
3908 LMI_HELPER(PSUBUSB
, psubusb
);
3909 LMI_HELPER(PSUBB
, psubb
);
3911 LMI_HELPER(PSHUFH
, pshufh
);
3912 LMI_HELPER(PACKSSWH
, packsswh
);
3913 LMI_HELPER(PACKSSHB
, packsshb
);
3914 LMI_HELPER(PACKUSHB
, packushb
);
3916 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3917 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3918 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3919 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3920 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3921 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3923 LMI_HELPER(PAVGH
, pavgh
);
3924 LMI_HELPER(PAVGB
, pavgb
);
3925 LMI_HELPER(PMAXSH
, pmaxsh
);
3926 LMI_HELPER(PMINSH
, pminsh
);
3927 LMI_HELPER(PMAXUB
, pmaxub
);
3928 LMI_HELPER(PMINUB
, pminub
);
3930 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3931 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3932 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3933 LMI_HELPER(PCMPGTH
, pcmpgth
);
3934 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3935 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3937 LMI_HELPER(PSLLW
, psllw
);
3938 LMI_HELPER(PSLLH
, psllh
);
3939 LMI_HELPER(PSRLW
, psrlw
);
3940 LMI_HELPER(PSRLH
, psrlh
);
3941 LMI_HELPER(PSRAW
, psraw
);
3942 LMI_HELPER(PSRAH
, psrah
);
3944 LMI_HELPER(PMULLH
, pmullh
);
3945 LMI_HELPER(PMULHH
, pmulhh
);
3946 LMI_HELPER(PMULHUH
, pmulhuh
);
3947 LMI_HELPER(PMADDHW
, pmaddhw
);
3949 LMI_HELPER(PASUBUB
, pasubub
);
3950 LMI_HELPER_1(BIADD
, biadd
);
3951 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3953 LMI_DIRECT(PADDD
, paddd
, add
);
3954 LMI_DIRECT(PSUBD
, psubd
, sub
);
3955 LMI_DIRECT(XOR_CP2
, xor, xor);
3956 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3957 LMI_DIRECT(AND_CP2
, and, and);
3958 LMI_DIRECT(OR_CP2
, or, or);
3961 tcg_gen_andc_i64(t0
, t1
, t0
);
3965 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3968 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3971 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3974 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3978 tcg_gen_andi_i64(t1
, t1
, 3);
3979 tcg_gen_shli_i64(t1
, t1
, 4);
3980 tcg_gen_shr_i64(t0
, t0
, t1
);
3981 tcg_gen_ext16u_i64(t0
, t0
);
3985 tcg_gen_add_i64(t0
, t0
, t1
);
3986 tcg_gen_ext32s_i64(t0
, t0
);
3989 tcg_gen_sub_i64(t0
, t0
, t1
);
3990 tcg_gen_ext32s_i64(t0
, t0
);
4012 /* Make sure shift count isn't TCG undefined behaviour. */
4013 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4018 tcg_gen_shl_i64(t0
, t0
, t1
);
4022 /* Since SRA is UndefinedResult without sign-extended inputs,
4023 we can treat SRA and DSRA the same. */
4024 tcg_gen_sar_i64(t0
, t0
, t1
);
4027 /* We want to shift in zeros for SRL; zero-extend first. */
4028 tcg_gen_ext32u_i64(t0
, t0
);
4031 tcg_gen_shr_i64(t0
, t0
, t1
);
4035 if (shift_max
== 32) {
4036 tcg_gen_ext32s_i64(t0
, t0
);
4039 /* Shifts larger than MAX produce zero. */
4040 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4041 tcg_gen_neg_i64(t1
, t1
);
4042 tcg_gen_and_i64(t0
, t0
, t1
);
4048 TCGv_i64 t2
= tcg_temp_new_i64();
4049 TCGLabel
*lab
= gen_new_label();
4051 tcg_gen_mov_i64(t2
, t0
);
4052 tcg_gen_add_i64(t0
, t1
, t2
);
4053 if (opc
== OPC_ADD_CP2
) {
4054 tcg_gen_ext32s_i64(t0
, t0
);
4056 tcg_gen_xor_i64(t1
, t1
, t2
);
4057 tcg_gen_xor_i64(t2
, t2
, t0
);
4058 tcg_gen_andc_i64(t1
, t2
, t1
);
4059 tcg_temp_free_i64(t2
);
4060 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4061 generate_exception(ctx
, EXCP_OVERFLOW
);
4069 TCGv_i64 t2
= tcg_temp_new_i64();
4070 TCGLabel
*lab
= gen_new_label();
4072 tcg_gen_mov_i64(t2
, t0
);
4073 tcg_gen_sub_i64(t0
, t1
, t2
);
4074 if (opc
== OPC_SUB_CP2
) {
4075 tcg_gen_ext32s_i64(t0
, t0
);
4077 tcg_gen_xor_i64(t1
, t1
, t2
);
4078 tcg_gen_xor_i64(t2
, t2
, t0
);
4079 tcg_gen_and_i64(t1
, t1
, t2
);
4080 tcg_temp_free_i64(t2
);
4081 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4082 generate_exception(ctx
, EXCP_OVERFLOW
);
4088 tcg_gen_ext32u_i64(t0
, t0
);
4089 tcg_gen_ext32u_i64(t1
, t1
);
4090 tcg_gen_mul_i64(t0
, t0
, t1
);
4099 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4100 FD field is the CC field? */
4102 MIPS_INVAL("loongson_cp2");
4103 generate_exception_end(ctx
, EXCP_RI
);
4110 gen_store_fpr64(ctx
, t0
, rd
);
4112 tcg_temp_free_i64(t0
);
4113 tcg_temp_free_i64(t1
);
4117 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
4118 int rs
, int rt
, int16_t imm
)
4121 TCGv t0
= tcg_temp_new();
4122 TCGv t1
= tcg_temp_new();
4125 /* Load needed operands */
4133 /* Compare two registers */
4135 gen_load_gpr(t0
, rs
);
4136 gen_load_gpr(t1
, rt
);
4146 /* Compare register to immediate */
4147 if (rs
!= 0 || imm
!= 0) {
4148 gen_load_gpr(t0
, rs
);
4149 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4156 case OPC_TEQ
: /* rs == rs */
4157 case OPC_TEQI
: /* r0 == 0 */
4158 case OPC_TGE
: /* rs >= rs */
4159 case OPC_TGEI
: /* r0 >= 0 */
4160 case OPC_TGEU
: /* rs >= rs unsigned */
4161 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4163 generate_exception_end(ctx
, EXCP_TRAP
);
4165 case OPC_TLT
: /* rs < rs */
4166 case OPC_TLTI
: /* r0 < 0 */
4167 case OPC_TLTU
: /* rs < rs unsigned */
4168 case OPC_TLTIU
: /* r0 < 0 unsigned */
4169 case OPC_TNE
: /* rs != rs */
4170 case OPC_TNEI
: /* r0 != 0 */
4171 /* Never trap: treat as NOP. */
4175 TCGLabel
*l1
= gen_new_label();
4180 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4184 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4188 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
4192 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
4196 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
4200 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
4203 generate_exception(ctx
, EXCP_TRAP
);
4210 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
4212 if (unlikely(ctx
->singlestep_enabled
)) {
4216 #ifndef CONFIG_USER_ONLY
4217 return (ctx
->tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4223 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
4225 if (use_goto_tb(ctx
, dest
)) {
4228 tcg_gen_exit_tb((uintptr_t)ctx
->tb
+ n
);
4231 if (ctx
->singlestep_enabled
) {
4232 save_cpu_state(ctx
, 0);
4233 gen_helper_raise_exception_debug(cpu_env
);
4239 /* Branches (before delay slot) */
4240 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
4242 int rs
, int rt
, int32_t offset
,
4245 target_ulong btgt
= -1;
4247 int bcond_compute
= 0;
4248 TCGv t0
= tcg_temp_new();
4249 TCGv t1
= tcg_temp_new();
4251 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
4252 #ifdef MIPS_DEBUG_DISAS
4253 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4254 TARGET_FMT_lx
"\n", ctx
->pc
);
4256 generate_exception_end(ctx
, EXCP_RI
);
4260 /* Load needed operands */
4266 /* Compare two registers */
4268 gen_load_gpr(t0
, rs
);
4269 gen_load_gpr(t1
, rt
);
4272 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4286 /* Compare to zero */
4288 gen_load_gpr(t0
, rs
);
4291 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4294 #if defined(TARGET_MIPS64)
4296 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
4298 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
4301 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4306 /* Jump to immediate */
4307 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
4311 /* Jump to register */
4312 if (offset
!= 0 && offset
!= 16) {
4313 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4314 others are reserved. */
4315 MIPS_INVAL("jump hint");
4316 generate_exception_end(ctx
, EXCP_RI
);
4319 gen_load_gpr(btarget
, rs
);
4322 MIPS_INVAL("branch/jump");
4323 generate_exception_end(ctx
, EXCP_RI
);
4326 if (bcond_compute
== 0) {
4327 /* No condition to be computed */
4329 case OPC_BEQ
: /* rx == rx */
4330 case OPC_BEQL
: /* rx == rx likely */
4331 case OPC_BGEZ
: /* 0 >= 0 */
4332 case OPC_BGEZL
: /* 0 >= 0 likely */
4333 case OPC_BLEZ
: /* 0 <= 0 */
4334 case OPC_BLEZL
: /* 0 <= 0 likely */
4336 ctx
->hflags
|= MIPS_HFLAG_B
;
4338 case OPC_BGEZAL
: /* 0 >= 0 */
4339 case OPC_BGEZALL
: /* 0 >= 0 likely */
4340 /* Always take and link */
4342 ctx
->hflags
|= MIPS_HFLAG_B
;
4344 case OPC_BNE
: /* rx != rx */
4345 case OPC_BGTZ
: /* 0 > 0 */
4346 case OPC_BLTZ
: /* 0 < 0 */
4349 case OPC_BLTZAL
: /* 0 < 0 */
4350 /* Handle as an unconditional branch to get correct delay
4353 btgt
= ctx
->pc
+ insn_bytes
+ delayslot_size
;
4354 ctx
->hflags
|= MIPS_HFLAG_B
;
4356 case OPC_BLTZALL
: /* 0 < 0 likely */
4357 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
4358 /* Skip the instruction in the delay slot */
4361 case OPC_BNEL
: /* rx != rx likely */
4362 case OPC_BGTZL
: /* 0 > 0 likely */
4363 case OPC_BLTZL
: /* 0 < 0 likely */
4364 /* Skip the instruction in the delay slot */
4368 ctx
->hflags
|= MIPS_HFLAG_B
;
4371 ctx
->hflags
|= MIPS_HFLAG_BX
;
4375 ctx
->hflags
|= MIPS_HFLAG_B
;
4378 ctx
->hflags
|= MIPS_HFLAG_BR
;
4382 ctx
->hflags
|= MIPS_HFLAG_BR
;
4385 MIPS_INVAL("branch/jump");
4386 generate_exception_end(ctx
, EXCP_RI
);
4392 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4395 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4398 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4401 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4404 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4407 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4410 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4414 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4418 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4421 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4424 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4427 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4430 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4433 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4436 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
4438 #if defined(TARGET_MIPS64)
4440 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
4444 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4447 ctx
->hflags
|= MIPS_HFLAG_BC
;
4450 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4453 ctx
->hflags
|= MIPS_HFLAG_BL
;
4456 MIPS_INVAL("conditional branch/jump");
4457 generate_exception_end(ctx
, EXCP_RI
);
4462 ctx
->btarget
= btgt
;
4464 switch (delayslot_size
) {
4466 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
4469 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
4474 int post_delay
= insn_bytes
+ delayslot_size
;
4475 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
4477 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
4481 if (insn_bytes
== 2)
4482 ctx
->hflags
|= MIPS_HFLAG_B16
;
4487 /* special3 bitfield operations */
4488 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
4489 int rs
, int lsb
, int msb
)
4491 TCGv t0
= tcg_temp_new();
4492 TCGv t1
= tcg_temp_new();
4494 gen_load_gpr(t1
, rs
);
4497 if (lsb
+ msb
> 31) {
4501 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
4503 /* The two checks together imply that lsb == 0,
4504 so this is a simple sign-extension. */
4505 tcg_gen_ext32s_tl(t0
, t1
);
4508 #if defined(TARGET_MIPS64)
4517 if (lsb
+ msb
> 63) {
4520 tcg_gen_extract_tl(t0
, t1
, lsb
, msb
+ 1);
4527 gen_load_gpr(t0
, rt
);
4528 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4529 tcg_gen_ext32s_tl(t0
, t0
);
4531 #if defined(TARGET_MIPS64)
4542 gen_load_gpr(t0
, rt
);
4543 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4548 MIPS_INVAL("bitops");
4549 generate_exception_end(ctx
, EXCP_RI
);
4554 gen_store_gpr(t0
, rt
);
4559 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4564 /* If no destination, treat it as a NOP. */
4568 t0
= tcg_temp_new();
4569 gen_load_gpr(t0
, rt
);
4573 TCGv t1
= tcg_temp_new();
4575 tcg_gen_shri_tl(t1
, t0
, 8);
4576 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4577 tcg_gen_shli_tl(t0
, t0
, 8);
4578 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4579 tcg_gen_or_tl(t0
, t0
, t1
);
4581 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4585 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4588 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4590 #if defined(TARGET_MIPS64)
4593 TCGv t1
= tcg_temp_new();
4595 tcg_gen_shri_tl(t1
, t0
, 8);
4596 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4597 tcg_gen_shli_tl(t0
, t0
, 8);
4598 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4599 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4605 TCGv t1
= tcg_temp_new();
4607 tcg_gen_shri_tl(t1
, t0
, 16);
4608 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4609 tcg_gen_shli_tl(t0
, t0
, 16);
4610 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4611 tcg_gen_or_tl(t0
, t0
, t1
);
4612 tcg_gen_shri_tl(t1
, t0
, 32);
4613 tcg_gen_shli_tl(t0
, t0
, 32);
4614 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4620 MIPS_INVAL("bsfhl");
4621 generate_exception_end(ctx
, EXCP_RI
);
4628 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
4637 t0
= tcg_temp_new();
4638 t1
= tcg_temp_new();
4639 gen_load_gpr(t0
, rs
);
4640 gen_load_gpr(t1
, rt
);
4641 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
4642 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
4643 if (opc
== OPC_LSA
) {
4644 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4653 static void gen_align(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
4661 t0
= tcg_temp_new();
4662 gen_load_gpr(t0
, rt
);
4666 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4668 #if defined(TARGET_MIPS64)
4670 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4675 TCGv t1
= tcg_temp_new();
4676 gen_load_gpr(t1
, rs
);
4680 TCGv_i64 t2
= tcg_temp_new_i64();
4681 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
4682 tcg_gen_shri_i64(t2
, t2
, 8 * (4 - bp
));
4683 gen_move_low32(cpu_gpr
[rd
], t2
);
4684 tcg_temp_free_i64(t2
);
4687 #if defined(TARGET_MIPS64)
4689 tcg_gen_shli_tl(t0
, t0
, 8 * bp
);
4690 tcg_gen_shri_tl(t1
, t1
, 8 * (8 - bp
));
4691 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
4701 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
4708 t0
= tcg_temp_new();
4709 gen_load_gpr(t0
, rt
);
4712 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
4714 #if defined(TARGET_MIPS64)
4716 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
4723 #ifndef CONFIG_USER_ONLY
4724 /* CP0 (MMU and control) */
4725 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
4727 TCGv_i64 t0
= tcg_temp_new_i64();
4728 TCGv_i64 t1
= tcg_temp_new_i64();
4730 tcg_gen_ext_tl_i64(t0
, arg
);
4731 tcg_gen_ld_i64(t1
, cpu_env
, off
);
4732 #if defined(TARGET_MIPS64)
4733 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
4735 tcg_gen_concat32_i64(t1
, t1
, t0
);
4737 tcg_gen_st_i64(t1
, cpu_env
, off
);
4738 tcg_temp_free_i64(t1
);
4739 tcg_temp_free_i64(t0
);
4742 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
4744 TCGv_i64 t0
= tcg_temp_new_i64();
4745 TCGv_i64 t1
= tcg_temp_new_i64();
4747 tcg_gen_ext_tl_i64(t0
, arg
);
4748 tcg_gen_ld_i64(t1
, cpu_env
, off
);
4749 tcg_gen_concat32_i64(t1
, t1
, t0
);
4750 tcg_gen_st_i64(t1
, cpu_env
, off
);
4751 tcg_temp_free_i64(t1
);
4752 tcg_temp_free_i64(t0
);
4755 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
4757 TCGv_i64 t0
= tcg_temp_new_i64();
4759 tcg_gen_ld_i64(t0
, cpu_env
, off
);
4760 #if defined(TARGET_MIPS64)
4761 tcg_gen_shri_i64(t0
, t0
, 30);
4763 tcg_gen_shri_i64(t0
, t0
, 32);
4765 gen_move_low32(arg
, t0
);
4766 tcg_temp_free_i64(t0
);
4769 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
4771 TCGv_i64 t0
= tcg_temp_new_i64();
4773 tcg_gen_ld_i64(t0
, cpu_env
, off
);
4774 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
4775 gen_move_low32(arg
, t0
);
4776 tcg_temp_free_i64(t0
);
4779 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4781 TCGv_i32 t0
= tcg_temp_new_i32();
4783 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4784 tcg_gen_ext_i32_tl(arg
, t0
);
4785 tcg_temp_free_i32(t0
);
4788 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4790 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4791 tcg_gen_ext32s_tl(arg
, arg
);
4794 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4796 TCGv_i32 t0
= tcg_temp_new_i32();
4798 tcg_gen_trunc_tl_i32(t0
, arg
);
4799 tcg_gen_st_i32(t0
, cpu_env
, off
);
4800 tcg_temp_free_i32(t0
);
4803 #define CP0_CHECK(c) \
4806 goto cp0_unimplemented; \
4810 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4812 const char *rn
= "invalid";
4814 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
4820 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4824 goto cp0_unimplemented
;
4830 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4834 goto cp0_unimplemented
;
4840 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, lladdr
),
4841 ctx
->CP0_LLAddr_shift
);
4845 CP0_CHECK(ctx
->mrp
);
4846 gen_helper_mfhc0_maar(arg
, cpu_env
);
4850 goto cp0_unimplemented
;
4859 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
4863 goto cp0_unimplemented
;
4867 goto cp0_unimplemented
;
4870 (void)rn
; /* avoid a compiler warning */
4871 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4875 qemu_log_mask(LOG_UNIMP
, "mfhc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4876 tcg_gen_movi_tl(arg
, 0);
4879 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4881 const char *rn
= "invalid";
4882 uint64_t mask
= ctx
->PAMask
>> 36;
4884 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
4890 tcg_gen_andi_tl(arg
, arg
, mask
);
4891 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4895 goto cp0_unimplemented
;
4901 tcg_gen_andi_tl(arg
, arg
, mask
);
4902 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4906 goto cp0_unimplemented
;
4912 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4913 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4914 relevant for modern MIPS cores supporting MTHC0, therefore
4915 treating MTHC0 to LLAddr as NOP. */
4919 CP0_CHECK(ctx
->mrp
);
4920 gen_helper_mthc0_maar(cpu_env
, arg
);
4924 goto cp0_unimplemented
;
4933 tcg_gen_andi_tl(arg
, arg
, mask
);
4934 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4938 goto cp0_unimplemented
;
4942 goto cp0_unimplemented
;
4945 (void)rn
; /* avoid a compiler warning */
4947 qemu_log_mask(LOG_UNIMP
, "mthc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4950 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
4952 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
4953 tcg_gen_movi_tl(arg
, 0);
4955 tcg_gen_movi_tl(arg
, ~0);
4959 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4961 const char *rn
= "invalid";
4964 check_insn(ctx
, ISA_MIPS32
);
4970 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4974 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4975 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4979 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4980 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4984 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4985 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4990 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
4994 goto cp0_unimplemented
;
5000 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5001 gen_helper_mfc0_random(arg
, cpu_env
);
5005 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5006 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5010 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5011 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5015 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5016 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5020 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5021 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
5025 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5026 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5030 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5031 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5032 rn
= "VPEScheFBack";
5035 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5036 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5040 goto cp0_unimplemented
;
5047 TCGv_i64 tmp
= tcg_temp_new_i64();
5048 tcg_gen_ld_i64(tmp
, cpu_env
,
5049 offsetof(CPUMIPSState
, CP0_EntryLo0
));
5050 #if defined(TARGET_MIPS64)
5052 /* Move RI/XI fields to bits 31:30 */
5053 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
5054 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
5057 gen_move_low32(arg
, tmp
);
5058 tcg_temp_free_i64(tmp
);
5063 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5064 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5068 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5069 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5073 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5074 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
5078 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5079 gen_helper_mfc0_tchalt(arg
, cpu_env
);
5083 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5084 gen_helper_mfc0_tccontext(arg
, cpu_env
);
5088 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5089 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
5093 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5094 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
5098 goto cp0_unimplemented
;
5105 TCGv_i64 tmp
= tcg_temp_new_i64();
5106 tcg_gen_ld_i64(tmp
, cpu_env
,
5107 offsetof(CPUMIPSState
, CP0_EntryLo1
));
5108 #if defined(TARGET_MIPS64)
5110 /* Move RI/XI fields to bits 31:30 */
5111 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
5112 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
5115 gen_move_low32(arg
, tmp
);
5116 tcg_temp_free_i64(tmp
);
5122 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
5123 rn
= "GlobalNumber";
5126 goto cp0_unimplemented
;
5132 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5133 tcg_gen_ext32s_tl(arg
, arg
);
5137 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5138 rn
= "ContextConfig";
5139 goto cp0_unimplemented
;
5141 CP0_CHECK(ctx
->ulri
);
5142 tcg_gen_ld32s_tl(arg
, cpu_env
,
5143 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5147 goto cp0_unimplemented
;
5153 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5157 check_insn(ctx
, ISA_MIPS32R2
);
5158 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5162 goto cp0_unimplemented
;
5168 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5172 check_insn(ctx
, ISA_MIPS32R2
);
5173 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5177 check_insn(ctx
, ISA_MIPS32R2
);
5178 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5182 check_insn(ctx
, ISA_MIPS32R2
);
5183 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5187 check_insn(ctx
, ISA_MIPS32R2
);
5188 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5192 check_insn(ctx
, ISA_MIPS32R2
);
5193 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5197 goto cp0_unimplemented
;
5203 check_insn(ctx
, ISA_MIPS32R2
);
5204 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5208 goto cp0_unimplemented
;
5214 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5215 tcg_gen_ext32s_tl(arg
, arg
);
5220 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
5225 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
5229 goto cp0_unimplemented
;
5235 /* Mark as an IO operation because we read the time. */
5236 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5239 gen_helper_mfc0_count(arg
, cpu_env
);
5240 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5243 /* Break the TB to be able to take timer interrupts immediately
5244 after reading count. */
5245 ctx
->bstate
= BS_STOP
;
5248 /* 6,7 are implementation dependent */
5250 goto cp0_unimplemented
;
5256 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5257 tcg_gen_ext32s_tl(arg
, arg
);
5261 goto cp0_unimplemented
;
5267 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5270 /* 6,7 are implementation dependent */
5272 goto cp0_unimplemented
;
5278 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5282 check_insn(ctx
, ISA_MIPS32R2
);
5283 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5287 check_insn(ctx
, ISA_MIPS32R2
);
5288 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5292 check_insn(ctx
, ISA_MIPS32R2
);
5293 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5297 goto cp0_unimplemented
;
5303 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5307 goto cp0_unimplemented
;
5313 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5314 tcg_gen_ext32s_tl(arg
, arg
);
5318 goto cp0_unimplemented
;
5324 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5328 check_insn(ctx
, ISA_MIPS32R2
);
5329 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5333 check_insn(ctx
, ISA_MIPS32R2
);
5334 CP0_CHECK(ctx
->cmgcr
);
5335 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
5336 tcg_gen_ext32s_tl(arg
, arg
);
5340 goto cp0_unimplemented
;
5346 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5350 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5354 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5358 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5362 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
5366 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
5369 /* 6,7 are implementation dependent */
5371 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5375 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5379 goto cp0_unimplemented
;
5385 gen_helper_mfc0_lladdr(arg
, cpu_env
);
5389 CP0_CHECK(ctx
->mrp
);
5390 gen_helper_mfc0_maar(arg
, cpu_env
);
5394 CP0_CHECK(ctx
->mrp
);
5395 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
5399 goto cp0_unimplemented
;
5405 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
5409 goto cp0_unimplemented
;
5415 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5419 goto cp0_unimplemented
;
5425 #if defined(TARGET_MIPS64)
5426 check_insn(ctx
, ISA_MIPS3
);
5427 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5428 tcg_gen_ext32s_tl(arg
, arg
);
5433 goto cp0_unimplemented
;
5437 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5438 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5441 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5445 goto cp0_unimplemented
;
5449 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5450 rn
= "'Diagnostic"; /* implementation dependent */
5455 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5459 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5460 rn
= "TraceControl";
5461 goto cp0_unimplemented
;
5463 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5464 rn
= "TraceControl2";
5465 goto cp0_unimplemented
;
5467 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5468 rn
= "UserTraceData";
5469 goto cp0_unimplemented
;
5471 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5473 goto cp0_unimplemented
;
5475 goto cp0_unimplemented
;
5482 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5483 tcg_gen_ext32s_tl(arg
, arg
);
5487 goto cp0_unimplemented
;
5493 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5494 rn
= "Performance0";
5497 // gen_helper_mfc0_performance1(arg);
5498 rn
= "Performance1";
5499 goto cp0_unimplemented
;
5501 // gen_helper_mfc0_performance2(arg);
5502 rn
= "Performance2";
5503 goto cp0_unimplemented
;
5505 // gen_helper_mfc0_performance3(arg);
5506 rn
= "Performance3";
5507 goto cp0_unimplemented
;
5509 // gen_helper_mfc0_performance4(arg);
5510 rn
= "Performance4";
5511 goto cp0_unimplemented
;
5513 // gen_helper_mfc0_performance5(arg);
5514 rn
= "Performance5";
5515 goto cp0_unimplemented
;
5517 // gen_helper_mfc0_performance6(arg);
5518 rn
= "Performance6";
5519 goto cp0_unimplemented
;
5521 // gen_helper_mfc0_performance7(arg);
5522 rn
= "Performance7";
5523 goto cp0_unimplemented
;
5525 goto cp0_unimplemented
;
5531 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
5535 goto cp0_unimplemented
;
5541 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5545 goto cp0_unimplemented
;
5555 TCGv_i64 tmp
= tcg_temp_new_i64();
5556 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
5557 gen_move_low32(arg
, tmp
);
5558 tcg_temp_free_i64(tmp
);
5566 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5570 goto cp0_unimplemented
;
5579 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5586 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5590 goto cp0_unimplemented
;
5596 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5597 tcg_gen_ext32s_tl(arg
, arg
);
5601 goto cp0_unimplemented
;
5608 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5612 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
5613 tcg_gen_ld_tl(arg
, cpu_env
,
5614 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
5615 tcg_gen_ext32s_tl(arg
, arg
);
5619 goto cp0_unimplemented
;
5623 goto cp0_unimplemented
;
5625 (void)rn
; /* avoid a compiler warning */
5626 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5630 qemu_log_mask(LOG_UNIMP
, "mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5631 gen_mfc0_unimplemented(ctx
, arg
);
5634 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5636 const char *rn
= "invalid";
5639 check_insn(ctx
, ISA_MIPS32
);
5641 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5649 gen_helper_mtc0_index(cpu_env
, arg
);
5653 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5654 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5658 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5663 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5673 goto cp0_unimplemented
;
5683 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5684 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5688 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5689 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5693 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5694 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5698 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5699 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5703 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5704 tcg_gen_st_tl(arg
, cpu_env
,
5705 offsetof(CPUMIPSState
, CP0_VPESchedule
));
5709 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5710 tcg_gen_st_tl(arg
, cpu_env
,
5711 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5712 rn
= "VPEScheFBack";
5715 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5716 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5720 goto cp0_unimplemented
;
5726 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5730 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5731 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5735 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5736 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5740 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5741 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5745 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5746 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5750 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5751 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5755 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5756 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5760 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5761 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5765 goto cp0_unimplemented
;
5771 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5777 rn
= "GlobalNumber";
5780 goto cp0_unimplemented
;
5786 gen_helper_mtc0_context(cpu_env
, arg
);
5790 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5791 rn
= "ContextConfig";
5792 goto cp0_unimplemented
;
5794 CP0_CHECK(ctx
->ulri
);
5795 tcg_gen_st_tl(arg
, cpu_env
,
5796 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5800 goto cp0_unimplemented
;
5806 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5810 check_insn(ctx
, ISA_MIPS32R2
);
5811 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5813 ctx
->bstate
= BS_STOP
;
5816 goto cp0_unimplemented
;
5822 gen_helper_mtc0_wired(cpu_env
, arg
);
5826 check_insn(ctx
, ISA_MIPS32R2
);
5827 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5831 check_insn(ctx
, ISA_MIPS32R2
);
5832 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
5836 check_insn(ctx
, ISA_MIPS32R2
);
5837 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
5841 check_insn(ctx
, ISA_MIPS32R2
);
5842 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
5846 check_insn(ctx
, ISA_MIPS32R2
);
5847 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
5851 goto cp0_unimplemented
;
5857 check_insn(ctx
, ISA_MIPS32R2
);
5858 gen_helper_mtc0_hwrena(cpu_env
, arg
);
5859 ctx
->bstate
= BS_STOP
;
5863 goto cp0_unimplemented
;
5881 goto cp0_unimplemented
;
5887 gen_helper_mtc0_count(cpu_env
, arg
);
5890 /* 6,7 are implementation dependent */
5892 goto cp0_unimplemented
;
5898 gen_helper_mtc0_entryhi(cpu_env
, arg
);
5902 goto cp0_unimplemented
;
5908 gen_helper_mtc0_compare(cpu_env
, arg
);
5911 /* 6,7 are implementation dependent */
5913 goto cp0_unimplemented
;
5919 save_cpu_state(ctx
, 1);
5920 gen_helper_mtc0_status(cpu_env
, arg
);
5921 /* BS_STOP isn't good enough here, hflags may have changed. */
5922 gen_save_pc(ctx
->pc
+ 4);
5923 ctx
->bstate
= BS_EXCP
;
5927 check_insn(ctx
, ISA_MIPS32R2
);
5928 gen_helper_mtc0_intctl(cpu_env
, arg
);
5929 /* Stop translation as we may have switched the execution mode */
5930 ctx
->bstate
= BS_STOP
;
5934 check_insn(ctx
, ISA_MIPS32R2
);
5935 gen_helper_mtc0_srsctl(cpu_env
, arg
);
5936 /* Stop translation as we may have switched the execution mode */
5937 ctx
->bstate
= BS_STOP
;
5941 check_insn(ctx
, ISA_MIPS32R2
);
5942 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5943 /* Stop translation as we may have switched the execution mode */
5944 ctx
->bstate
= BS_STOP
;
5948 goto cp0_unimplemented
;
5954 save_cpu_state(ctx
, 1);
5955 gen_helper_mtc0_cause(cpu_env
, arg
);
5959 goto cp0_unimplemented
;
5965 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5969 goto cp0_unimplemented
;
5979 check_insn(ctx
, ISA_MIPS32R2
);
5980 gen_helper_mtc0_ebase(cpu_env
, arg
);
5984 goto cp0_unimplemented
;
5990 gen_helper_mtc0_config0(cpu_env
, arg
);
5992 /* Stop translation as we may have switched the execution mode */
5993 ctx
->bstate
= BS_STOP
;
5996 /* ignored, read only */
6000 gen_helper_mtc0_config2(cpu_env
, arg
);
6002 /* Stop translation as we may have switched the execution mode */
6003 ctx
->bstate
= BS_STOP
;
6006 gen_helper_mtc0_config3(cpu_env
, arg
);
6008 /* Stop translation as we may have switched the execution mode */
6009 ctx
->bstate
= BS_STOP
;
6012 gen_helper_mtc0_config4(cpu_env
, arg
);
6014 ctx
->bstate
= BS_STOP
;
6017 gen_helper_mtc0_config5(cpu_env
, arg
);
6019 /* Stop translation as we may have switched the execution mode */
6020 ctx
->bstate
= BS_STOP
;
6022 /* 6,7 are implementation dependent */
6032 rn
= "Invalid config selector";
6033 goto cp0_unimplemented
;
6039 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6043 CP0_CHECK(ctx
->mrp
);
6044 gen_helper_mtc0_maar(cpu_env
, arg
);
6048 CP0_CHECK(ctx
->mrp
);
6049 gen_helper_mtc0_maari(cpu_env
, arg
);
6053 goto cp0_unimplemented
;
6059 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6063 goto cp0_unimplemented
;
6069 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6073 goto cp0_unimplemented
;
6079 #if defined(TARGET_MIPS64)
6080 check_insn(ctx
, ISA_MIPS3
);
6081 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6086 goto cp0_unimplemented
;
6090 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6091 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6094 gen_helper_mtc0_framemask(cpu_env
, arg
);
6098 goto cp0_unimplemented
;
6103 rn
= "Diagnostic"; /* implementation dependent */
6108 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6109 /* BS_STOP isn't good enough here, hflags may have changed. */
6110 gen_save_pc(ctx
->pc
+ 4);
6111 ctx
->bstate
= BS_EXCP
;
6115 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6116 rn
= "TraceControl";
6117 /* Stop translation as we may have switched the execution mode */
6118 ctx
->bstate
= BS_STOP
;
6119 goto cp0_unimplemented
;
6121 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6122 rn
= "TraceControl2";
6123 /* Stop translation as we may have switched the execution mode */
6124 ctx
->bstate
= BS_STOP
;
6125 goto cp0_unimplemented
;
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx
->bstate
= BS_STOP
;
6129 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6130 rn
= "UserTraceData";
6131 /* Stop translation as we may have switched the execution mode */
6132 ctx
->bstate
= BS_STOP
;
6133 goto cp0_unimplemented
;
6135 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6136 /* Stop translation as we may have switched the execution mode */
6137 ctx
->bstate
= BS_STOP
;
6139 goto cp0_unimplemented
;
6141 goto cp0_unimplemented
;
6148 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6152 goto cp0_unimplemented
;
6158 gen_helper_mtc0_performance0(cpu_env
, arg
);
6159 rn
= "Performance0";
6162 // gen_helper_mtc0_performance1(arg);
6163 rn
= "Performance1";
6164 goto cp0_unimplemented
;
6166 // gen_helper_mtc0_performance2(arg);
6167 rn
= "Performance2";
6168 goto cp0_unimplemented
;
6170 // gen_helper_mtc0_performance3(arg);
6171 rn
= "Performance3";
6172 goto cp0_unimplemented
;
6174 // gen_helper_mtc0_performance4(arg);
6175 rn
= "Performance4";
6176 goto cp0_unimplemented
;
6178 // gen_helper_mtc0_performance5(arg);
6179 rn
= "Performance5";
6180 goto cp0_unimplemented
;
6182 // gen_helper_mtc0_performance6(arg);
6183 rn
= "Performance6";
6184 goto cp0_unimplemented
;
6186 // gen_helper_mtc0_performance7(arg);
6187 rn
= "Performance7";
6188 goto cp0_unimplemented
;
6190 goto cp0_unimplemented
;
6196 gen_helper_mtc0_errctl(cpu_env
, arg
);
6197 ctx
->bstate
= BS_STOP
;
6201 goto cp0_unimplemented
;
6211 goto cp0_unimplemented
;
6220 gen_helper_mtc0_taglo(cpu_env
, arg
);
6227 gen_helper_mtc0_datalo(cpu_env
, arg
);
6231 goto cp0_unimplemented
;
6240 gen_helper_mtc0_taghi(cpu_env
, arg
);
6247 gen_helper_mtc0_datahi(cpu_env
, arg
);
6252 goto cp0_unimplemented
;
6258 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6262 goto cp0_unimplemented
;
6269 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6273 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6274 tcg_gen_st_tl(arg
, cpu_env
,
6275 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6279 goto cp0_unimplemented
;
6281 /* Stop translation as we may have switched the execution mode */
6282 ctx
->bstate
= BS_STOP
;
6285 goto cp0_unimplemented
;
6287 (void)rn
; /* avoid a compiler warning */
6288 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6289 /* For simplicity assume that all writes can cause interrupts. */
6290 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6292 ctx
->bstate
= BS_STOP
;
6297 qemu_log_mask(LOG_UNIMP
, "mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6300 #if defined(TARGET_MIPS64)
6301 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6303 const char *rn
= "invalid";
6306 check_insn(ctx
, ISA_MIPS64
);
6312 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6316 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6317 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6321 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6322 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6326 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6327 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6332 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
6336 goto cp0_unimplemented
;
6342 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6343 gen_helper_mfc0_random(arg
, cpu_env
);
6347 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6348 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6352 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6353 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6357 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6358 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6362 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6363 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
6367 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6368 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6372 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6373 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6374 rn
= "VPEScheFBack";
6377 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6378 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6382 goto cp0_unimplemented
;
6388 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6392 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6393 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6397 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6398 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6402 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6403 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
6407 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6408 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
6412 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6413 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
6417 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6418 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
6422 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6423 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
6427 goto cp0_unimplemented
;
6433 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6438 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6439 rn
= "GlobalNumber";
6442 goto cp0_unimplemented
;
6448 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6452 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6453 rn
= "ContextConfig";
6454 goto cp0_unimplemented
;
6456 CP0_CHECK(ctx
->ulri
);
6457 tcg_gen_ld_tl(arg
, cpu_env
,
6458 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6462 goto cp0_unimplemented
;
6468 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6472 check_insn(ctx
, ISA_MIPS32R2
);
6473 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6477 goto cp0_unimplemented
;
6483 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6487 check_insn(ctx
, ISA_MIPS32R2
);
6488 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6492 check_insn(ctx
, ISA_MIPS32R2
);
6493 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6497 check_insn(ctx
, ISA_MIPS32R2
);
6498 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6502 check_insn(ctx
, ISA_MIPS32R2
);
6503 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6507 check_insn(ctx
, ISA_MIPS32R2
);
6508 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6512 goto cp0_unimplemented
;
6518 check_insn(ctx
, ISA_MIPS32R2
);
6519 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6523 goto cp0_unimplemented
;
6529 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6534 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6539 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6543 goto cp0_unimplemented
;
6549 /* Mark as an IO operation because we read the time. */
6550 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6553 gen_helper_mfc0_count(arg
, cpu_env
);
6554 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6557 /* Break the TB to be able to take timer interrupts immediately
6558 after reading count. */
6559 ctx
->bstate
= BS_STOP
;
6562 /* 6,7 are implementation dependent */
6564 goto cp0_unimplemented
;
6570 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6574 goto cp0_unimplemented
;
6580 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6583 /* 6,7 are implementation dependent */
6585 goto cp0_unimplemented
;
6591 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6595 check_insn(ctx
, ISA_MIPS32R2
);
6596 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6600 check_insn(ctx
, ISA_MIPS32R2
);
6601 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6605 check_insn(ctx
, ISA_MIPS32R2
);
6606 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6610 goto cp0_unimplemented
;
6616 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6620 goto cp0_unimplemented
;
6626 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6630 goto cp0_unimplemented
;
6636 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6640 check_insn(ctx
, ISA_MIPS32R2
);
6641 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
6645 check_insn(ctx
, ISA_MIPS32R2
);
6646 CP0_CHECK(ctx
->cmgcr
);
6647 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
6651 goto cp0_unimplemented
;
6657 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6661 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6665 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6669 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6673 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6677 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6680 /* 6,7 are implementation dependent */
6682 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6686 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6690 goto cp0_unimplemented
;
6696 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
6700 CP0_CHECK(ctx
->mrp
);
6701 gen_helper_dmfc0_maar(arg
, cpu_env
);
6705 CP0_CHECK(ctx
->mrp
);
6706 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
6710 goto cp0_unimplemented
;
6716 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
6720 goto cp0_unimplemented
;
6726 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6730 goto cp0_unimplemented
;
6736 check_insn(ctx
, ISA_MIPS3
);
6737 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6741 goto cp0_unimplemented
;
6745 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6746 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6749 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6753 goto cp0_unimplemented
;
6757 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6758 rn
= "'Diagnostic"; /* implementation dependent */
6763 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6767 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6768 rn
= "TraceControl";
6769 goto cp0_unimplemented
;
6771 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6772 rn
= "TraceControl2";
6773 goto cp0_unimplemented
;
6775 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6776 rn
= "UserTraceData";
6777 goto cp0_unimplemented
;
6779 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6781 goto cp0_unimplemented
;
6783 goto cp0_unimplemented
;
6790 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6794 goto cp0_unimplemented
;
6800 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6801 rn
= "Performance0";
6804 // gen_helper_dmfc0_performance1(arg);
6805 rn
= "Performance1";
6806 goto cp0_unimplemented
;
6808 // gen_helper_dmfc0_performance2(arg);
6809 rn
= "Performance2";
6810 goto cp0_unimplemented
;
6812 // gen_helper_dmfc0_performance3(arg);
6813 rn
= "Performance3";
6814 goto cp0_unimplemented
;
6816 // gen_helper_dmfc0_performance4(arg);
6817 rn
= "Performance4";
6818 goto cp0_unimplemented
;
6820 // gen_helper_dmfc0_performance5(arg);
6821 rn
= "Performance5";
6822 goto cp0_unimplemented
;
6824 // gen_helper_dmfc0_performance6(arg);
6825 rn
= "Performance6";
6826 goto cp0_unimplemented
;
6828 // gen_helper_dmfc0_performance7(arg);
6829 rn
= "Performance7";
6830 goto cp0_unimplemented
;
6832 goto cp0_unimplemented
;
6838 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
6842 goto cp0_unimplemented
;
6849 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6853 goto cp0_unimplemented
;
6862 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6869 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6873 goto cp0_unimplemented
;
6882 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6889 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6893 goto cp0_unimplemented
;
6899 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6903 goto cp0_unimplemented
;
6910 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6914 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6915 tcg_gen_ld_tl(arg
, cpu_env
,
6916 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6920 goto cp0_unimplemented
;
6924 goto cp0_unimplemented
;
6926 (void)rn
; /* avoid a compiler warning */
6927 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6931 qemu_log_mask(LOG_UNIMP
, "dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6932 gen_mfc0_unimplemented(ctx
, arg
);
6935 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6937 const char *rn
= "invalid";
6940 check_insn(ctx
, ISA_MIPS64
);
6942 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6950 gen_helper_mtc0_index(cpu_env
, arg
);
6954 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6955 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6959 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6964 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6974 goto cp0_unimplemented
;
6984 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6985 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6989 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6990 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6994 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6995 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6999 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7000 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7004 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7005 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7009 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7010 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7011 rn
= "VPEScheFBack";
7014 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7015 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7019 goto cp0_unimplemented
;
7025 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
7029 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7030 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7034 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7035 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7039 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7040 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7044 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7045 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7049 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7050 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7054 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7055 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7059 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7060 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7064 goto cp0_unimplemented
;
7070 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
7076 rn
= "GlobalNumber";
7079 goto cp0_unimplemented
;
7085 gen_helper_mtc0_context(cpu_env
, arg
);
7089 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7090 rn
= "ContextConfig";
7091 goto cp0_unimplemented
;
7093 CP0_CHECK(ctx
->ulri
);
7094 tcg_gen_st_tl(arg
, cpu_env
,
7095 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7099 goto cp0_unimplemented
;
7105 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7109 check_insn(ctx
, ISA_MIPS32R2
);
7110 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7114 goto cp0_unimplemented
;
7120 gen_helper_mtc0_wired(cpu_env
, arg
);
7124 check_insn(ctx
, ISA_MIPS32R2
);
7125 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7129 check_insn(ctx
, ISA_MIPS32R2
);
7130 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7134 check_insn(ctx
, ISA_MIPS32R2
);
7135 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7139 check_insn(ctx
, ISA_MIPS32R2
);
7140 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7144 check_insn(ctx
, ISA_MIPS32R2
);
7145 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7149 goto cp0_unimplemented
;
7155 check_insn(ctx
, ISA_MIPS32R2
);
7156 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7157 ctx
->bstate
= BS_STOP
;
7161 goto cp0_unimplemented
;
7179 goto cp0_unimplemented
;
7185 gen_helper_mtc0_count(cpu_env
, arg
);
7188 /* 6,7 are implementation dependent */
7190 goto cp0_unimplemented
;
7192 /* Stop translation as we may have switched the execution mode */
7193 ctx
->bstate
= BS_STOP
;
7198 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7202 goto cp0_unimplemented
;
7208 gen_helper_mtc0_compare(cpu_env
, arg
);
7211 /* 6,7 are implementation dependent */
7213 goto cp0_unimplemented
;
7215 /* Stop translation as we may have switched the execution mode */
7216 ctx
->bstate
= BS_STOP
;
7221 save_cpu_state(ctx
, 1);
7222 gen_helper_mtc0_status(cpu_env
, arg
);
7223 /* BS_STOP isn't good enough here, hflags may have changed. */
7224 gen_save_pc(ctx
->pc
+ 4);
7225 ctx
->bstate
= BS_EXCP
;
7229 check_insn(ctx
, ISA_MIPS32R2
);
7230 gen_helper_mtc0_intctl(cpu_env
, arg
);
7231 /* Stop translation as we may have switched the execution mode */
7232 ctx
->bstate
= BS_STOP
;
7236 check_insn(ctx
, ISA_MIPS32R2
);
7237 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7238 /* Stop translation as we may have switched the execution mode */
7239 ctx
->bstate
= BS_STOP
;
7243 check_insn(ctx
, ISA_MIPS32R2
);
7244 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7245 /* Stop translation as we may have switched the execution mode */
7246 ctx
->bstate
= BS_STOP
;
7250 goto cp0_unimplemented
;
7256 save_cpu_state(ctx
, 1);
7257 /* Mark as an IO operation because we may trigger a software
7259 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7262 gen_helper_mtc0_cause(cpu_env
, arg
);
7263 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7266 /* Stop translation as we may have triggered an intetrupt */
7267 ctx
->bstate
= BS_STOP
;
7271 goto cp0_unimplemented
;
7277 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7281 goto cp0_unimplemented
;
7291 check_insn(ctx
, ISA_MIPS32R2
);
7292 gen_helper_mtc0_ebase(cpu_env
, arg
);
7296 goto cp0_unimplemented
;
7302 gen_helper_mtc0_config0(cpu_env
, arg
);
7304 /* Stop translation as we may have switched the execution mode */
7305 ctx
->bstate
= BS_STOP
;
7308 /* ignored, read only */
7312 gen_helper_mtc0_config2(cpu_env
, arg
);
7314 /* Stop translation as we may have switched the execution mode */
7315 ctx
->bstate
= BS_STOP
;
7318 gen_helper_mtc0_config3(cpu_env
, arg
);
7320 /* Stop translation as we may have switched the execution mode */
7321 ctx
->bstate
= BS_STOP
;
7324 /* currently ignored */
7328 gen_helper_mtc0_config5(cpu_env
, arg
);
7330 /* Stop translation as we may have switched the execution mode */
7331 ctx
->bstate
= BS_STOP
;
7333 /* 6,7 are implementation dependent */
7335 rn
= "Invalid config selector";
7336 goto cp0_unimplemented
;
7342 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7346 CP0_CHECK(ctx
->mrp
);
7347 gen_helper_mtc0_maar(cpu_env
, arg
);
7351 CP0_CHECK(ctx
->mrp
);
7352 gen_helper_mtc0_maari(cpu_env
, arg
);
7356 goto cp0_unimplemented
;
7362 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7366 goto cp0_unimplemented
;
7372 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7376 goto cp0_unimplemented
;
7382 check_insn(ctx
, ISA_MIPS3
);
7383 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7387 goto cp0_unimplemented
;
7391 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7392 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7395 gen_helper_mtc0_framemask(cpu_env
, arg
);
7399 goto cp0_unimplemented
;
7404 rn
= "Diagnostic"; /* implementation dependent */
7409 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7410 /* BS_STOP isn't good enough here, hflags may have changed. */
7411 gen_save_pc(ctx
->pc
+ 4);
7412 ctx
->bstate
= BS_EXCP
;
7416 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7417 /* Stop translation as we may have switched the execution mode */
7418 ctx
->bstate
= BS_STOP
;
7419 rn
= "TraceControl";
7420 goto cp0_unimplemented
;
7422 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7423 /* Stop translation as we may have switched the execution mode */
7424 ctx
->bstate
= BS_STOP
;
7425 rn
= "TraceControl2";
7426 goto cp0_unimplemented
;
7428 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7429 /* Stop translation as we may have switched the execution mode */
7430 ctx
->bstate
= BS_STOP
;
7431 rn
= "UserTraceData";
7432 goto cp0_unimplemented
;
7434 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7435 /* Stop translation as we may have switched the execution mode */
7436 ctx
->bstate
= BS_STOP
;
7438 goto cp0_unimplemented
;
7440 goto cp0_unimplemented
;
7447 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7451 goto cp0_unimplemented
;
7457 gen_helper_mtc0_performance0(cpu_env
, arg
);
7458 rn
= "Performance0";
7461 // gen_helper_mtc0_performance1(cpu_env, arg);
7462 rn
= "Performance1";
7463 goto cp0_unimplemented
;
7465 // gen_helper_mtc0_performance2(cpu_env, arg);
7466 rn
= "Performance2";
7467 goto cp0_unimplemented
;
7469 // gen_helper_mtc0_performance3(cpu_env, arg);
7470 rn
= "Performance3";
7471 goto cp0_unimplemented
;
7473 // gen_helper_mtc0_performance4(cpu_env, arg);
7474 rn
= "Performance4";
7475 goto cp0_unimplemented
;
7477 // gen_helper_mtc0_performance5(cpu_env, arg);
7478 rn
= "Performance5";
7479 goto cp0_unimplemented
;
7481 // gen_helper_mtc0_performance6(cpu_env, arg);
7482 rn
= "Performance6";
7483 goto cp0_unimplemented
;
7485 // gen_helper_mtc0_performance7(cpu_env, arg);
7486 rn
= "Performance7";
7487 goto cp0_unimplemented
;
7489 goto cp0_unimplemented
;
7495 gen_helper_mtc0_errctl(cpu_env
, arg
);
7496 ctx
->bstate
= BS_STOP
;
7500 goto cp0_unimplemented
;
7510 goto cp0_unimplemented
;
7519 gen_helper_mtc0_taglo(cpu_env
, arg
);
7526 gen_helper_mtc0_datalo(cpu_env
, arg
);
7530 goto cp0_unimplemented
;
7539 gen_helper_mtc0_taghi(cpu_env
, arg
);
7546 gen_helper_mtc0_datahi(cpu_env
, arg
);
7551 goto cp0_unimplemented
;
7557 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7561 goto cp0_unimplemented
;
7568 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7572 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7573 tcg_gen_st_tl(arg
, cpu_env
,
7574 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7578 goto cp0_unimplemented
;
7580 /* Stop translation as we may have switched the execution mode */
7581 ctx
->bstate
= BS_STOP
;
7584 goto cp0_unimplemented
;
7586 (void)rn
; /* avoid a compiler warning */
7587 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7588 /* For simplicity assume that all writes can cause interrupts. */
7589 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7591 ctx
->bstate
= BS_STOP
;
7596 qemu_log_mask(LOG_UNIMP
, "dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7598 #endif /* TARGET_MIPS64 */
7600 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
7601 int u
, int sel
, int h
)
7603 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7604 TCGv t0
= tcg_temp_local_new();
7606 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7607 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7608 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7609 tcg_gen_movi_tl(t0
, -1);
7610 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7611 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7612 tcg_gen_movi_tl(t0
, -1);
7618 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
7621 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
7631 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
7634 gen_helper_mftc0_tcbind(t0
, cpu_env
);
7637 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
7640 gen_helper_mftc0_tchalt(t0
, cpu_env
);
7643 gen_helper_mftc0_tccontext(t0
, cpu_env
);
7646 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
7649 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
7652 gen_mfc0(ctx
, t0
, rt
, sel
);
7659 gen_helper_mftc0_entryhi(t0
, cpu_env
);
7662 gen_mfc0(ctx
, t0
, rt
, sel
);
7668 gen_helper_mftc0_status(t0
, cpu_env
);
7671 gen_mfc0(ctx
, t0
, rt
, sel
);
7677 gen_helper_mftc0_cause(t0
, cpu_env
);
7687 gen_helper_mftc0_epc(t0
, cpu_env
);
7697 gen_helper_mftc0_ebase(t0
, cpu_env
);
7707 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
7717 gen_helper_mftc0_debug(t0
, cpu_env
);
7720 gen_mfc0(ctx
, t0
, rt
, sel
);
7725 gen_mfc0(ctx
, t0
, rt
, sel
);
7727 } else switch (sel
) {
7728 /* GPR registers. */
7730 gen_helper_1e0i(mftgpr
, t0
, rt
);
7732 /* Auxiliary CPU registers */
7736 gen_helper_1e0i(mftlo
, t0
, 0);
7739 gen_helper_1e0i(mfthi
, t0
, 0);
7742 gen_helper_1e0i(mftacx
, t0
, 0);
7745 gen_helper_1e0i(mftlo
, t0
, 1);
7748 gen_helper_1e0i(mfthi
, t0
, 1);
7751 gen_helper_1e0i(mftacx
, t0
, 1);
7754 gen_helper_1e0i(mftlo
, t0
, 2);
7757 gen_helper_1e0i(mfthi
, t0
, 2);
7760 gen_helper_1e0i(mftacx
, t0
, 2);
7763 gen_helper_1e0i(mftlo
, t0
, 3);
7766 gen_helper_1e0i(mfthi
, t0
, 3);
7769 gen_helper_1e0i(mftacx
, t0
, 3);
7772 gen_helper_mftdsp(t0
, cpu_env
);
7778 /* Floating point (COP1). */
7780 /* XXX: For now we support only a single FPU context. */
7782 TCGv_i32 fp0
= tcg_temp_new_i32();
7784 gen_load_fpr32(ctx
, fp0
, rt
);
7785 tcg_gen_ext_i32_tl(t0
, fp0
);
7786 tcg_temp_free_i32(fp0
);
7788 TCGv_i32 fp0
= tcg_temp_new_i32();
7790 gen_load_fpr32h(ctx
, fp0
, rt
);
7791 tcg_gen_ext_i32_tl(t0
, fp0
);
7792 tcg_temp_free_i32(fp0
);
7796 /* XXX: For now we support only a single FPU context. */
7797 gen_helper_1e0i(cfc1
, t0
, rt
);
7799 /* COP2: Not implemented. */
7806 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7807 gen_store_gpr(t0
, rd
);
7813 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7814 generate_exception_end(ctx
, EXCP_RI
);
7817 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
7818 int u
, int sel
, int h
)
7820 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7821 TCGv t0
= tcg_temp_local_new();
7823 gen_load_gpr(t0
, rt
);
7824 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7825 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7826 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7828 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7829 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7836 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
7839 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
7849 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
7852 gen_helper_mttc0_tcbind(cpu_env
, t0
);
7855 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
7858 gen_helper_mttc0_tchalt(cpu_env
, t0
);
7861 gen_helper_mttc0_tccontext(cpu_env
, t0
);
7864 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
7867 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
7870 gen_mtc0(ctx
, t0
, rd
, sel
);
7877 gen_helper_mttc0_entryhi(cpu_env
, t0
);
7880 gen_mtc0(ctx
, t0
, rd
, sel
);
7886 gen_helper_mttc0_status(cpu_env
, t0
);
7889 gen_mtc0(ctx
, t0
, rd
, sel
);
7895 gen_helper_mttc0_cause(cpu_env
, t0
);
7905 gen_helper_mttc0_ebase(cpu_env
, t0
);
7915 gen_helper_mttc0_debug(cpu_env
, t0
);
7918 gen_mtc0(ctx
, t0
, rd
, sel
);
7923 gen_mtc0(ctx
, t0
, rd
, sel
);
7925 } else switch (sel
) {
7926 /* GPR registers. */
7928 gen_helper_0e1i(mttgpr
, t0
, rd
);
7930 /* Auxiliary CPU registers */
7934 gen_helper_0e1i(mttlo
, t0
, 0);
7937 gen_helper_0e1i(mtthi
, t0
, 0);
7940 gen_helper_0e1i(mttacx
, t0
, 0);
7943 gen_helper_0e1i(mttlo
, t0
, 1);
7946 gen_helper_0e1i(mtthi
, t0
, 1);
7949 gen_helper_0e1i(mttacx
, t0
, 1);
7952 gen_helper_0e1i(mttlo
, t0
, 2);
7955 gen_helper_0e1i(mtthi
, t0
, 2);
7958 gen_helper_0e1i(mttacx
, t0
, 2);
7961 gen_helper_0e1i(mttlo
, t0
, 3);
7964 gen_helper_0e1i(mtthi
, t0
, 3);
7967 gen_helper_0e1i(mttacx
, t0
, 3);
7970 gen_helper_mttdsp(cpu_env
, t0
);
7976 /* Floating point (COP1). */
7978 /* XXX: For now we support only a single FPU context. */
7980 TCGv_i32 fp0
= tcg_temp_new_i32();
7982 tcg_gen_trunc_tl_i32(fp0
, t0
);
7983 gen_store_fpr32(ctx
, fp0
, rd
);
7984 tcg_temp_free_i32(fp0
);
7986 TCGv_i32 fp0
= tcg_temp_new_i32();
7988 tcg_gen_trunc_tl_i32(fp0
, t0
);
7989 gen_store_fpr32h(ctx
, fp0
, rd
);
7990 tcg_temp_free_i32(fp0
);
7994 /* XXX: For now we support only a single FPU context. */
7996 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
7998 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7999 tcg_temp_free_i32(fs_tmp
);
8001 /* Stop translation as we may have changed hflags */
8002 ctx
->bstate
= BS_STOP
;
8004 /* COP2: Not implemented. */
8011 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
8017 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
8018 generate_exception_end(ctx
, EXCP_RI
);
8021 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
8023 const char *opn
= "ldst";
8025 check_cp0_enabled(ctx
);
8032 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8037 TCGv t0
= tcg_temp_new();
8039 gen_load_gpr(t0
, rt
);
8040 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8045 #if defined(TARGET_MIPS64)
8047 check_insn(ctx
, ISA_MIPS3
);
8052 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8056 check_insn(ctx
, ISA_MIPS3
);
8058 TCGv t0
= tcg_temp_new();
8060 gen_load_gpr(t0
, rt
);
8061 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8073 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8079 TCGv t0
= tcg_temp_new();
8080 gen_load_gpr(t0
, rt
);
8081 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8087 check_insn(ctx
, ASE_MT
);
8092 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
8093 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
8097 check_insn(ctx
, ASE_MT
);
8098 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
8099 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
8104 if (!env
->tlb
->helper_tlbwi
)
8106 gen_helper_tlbwi(cpu_env
);
8111 if (!env
->tlb
->helper_tlbinv
) {
8114 gen_helper_tlbinv(cpu_env
);
8115 } /* treat as nop if TLBINV not supported */
8120 if (!env
->tlb
->helper_tlbinvf
) {
8123 gen_helper_tlbinvf(cpu_env
);
8124 } /* treat as nop if TLBINV not supported */
8128 if (!env
->tlb
->helper_tlbwr
)
8130 gen_helper_tlbwr(cpu_env
);
8134 if (!env
->tlb
->helper_tlbp
)
8136 gen_helper_tlbp(cpu_env
);
8140 if (!env
->tlb
->helper_tlbr
)
8142 gen_helper_tlbr(cpu_env
);
8144 case OPC_ERET
: /* OPC_ERETNC */
8145 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8146 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8149 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
8150 if (ctx
->opcode
& (1 << bit_shift
)) {
8153 check_insn(ctx
, ISA_MIPS32R5
);
8154 gen_helper_eretnc(cpu_env
);
8158 check_insn(ctx
, ISA_MIPS2
);
8159 gen_helper_eret(cpu_env
);
8161 ctx
->bstate
= BS_EXCP
;
8166 check_insn(ctx
, ISA_MIPS32
);
8167 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8168 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8171 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
8173 generate_exception_end(ctx
, EXCP_RI
);
8175 gen_helper_deret(cpu_env
);
8176 ctx
->bstate
= BS_EXCP
;
8181 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
8182 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8183 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8186 /* If we get an exception, we want to restart at next instruction */
8188 save_cpu_state(ctx
, 1);
8190 gen_helper_wait(cpu_env
);
8191 ctx
->bstate
= BS_EXCP
;
8196 generate_exception_end(ctx
, EXCP_RI
);
8199 (void)opn
; /* avoid a compiler warning */
8201 #endif /* !CONFIG_USER_ONLY */
8203 /* CP1 Branches (before delay slot) */
8204 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
8205 int32_t cc
, int32_t offset
)
8207 target_ulong btarget
;
8208 TCGv_i32 t0
= tcg_temp_new_i32();
8210 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8211 generate_exception_end(ctx
, EXCP_RI
);
8216 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
8218 btarget
= ctx
->pc
+ 4 + offset
;
8222 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8223 tcg_gen_not_i32(t0
, t0
);
8224 tcg_gen_andi_i32(t0
, t0
, 1);
8225 tcg_gen_extu_i32_tl(bcond
, t0
);
8228 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8229 tcg_gen_not_i32(t0
, t0
);
8230 tcg_gen_andi_i32(t0
, t0
, 1);
8231 tcg_gen_extu_i32_tl(bcond
, t0
);
8234 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8235 tcg_gen_andi_i32(t0
, t0
, 1);
8236 tcg_gen_extu_i32_tl(bcond
, t0
);
8239 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8240 tcg_gen_andi_i32(t0
, t0
, 1);
8241 tcg_gen_extu_i32_tl(bcond
, t0
);
8243 ctx
->hflags
|= MIPS_HFLAG_BL
;
8247 TCGv_i32 t1
= tcg_temp_new_i32();
8248 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8249 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8250 tcg_gen_nand_i32(t0
, t0
, t1
);
8251 tcg_temp_free_i32(t1
);
8252 tcg_gen_andi_i32(t0
, t0
, 1);
8253 tcg_gen_extu_i32_tl(bcond
, t0
);
8258 TCGv_i32 t1
= tcg_temp_new_i32();
8259 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8260 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8261 tcg_gen_or_i32(t0
, t0
, t1
);
8262 tcg_temp_free_i32(t1
);
8263 tcg_gen_andi_i32(t0
, t0
, 1);
8264 tcg_gen_extu_i32_tl(bcond
, t0
);
8269 TCGv_i32 t1
= tcg_temp_new_i32();
8270 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8271 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8272 tcg_gen_and_i32(t0
, t0
, t1
);
8273 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8274 tcg_gen_and_i32(t0
, t0
, t1
);
8275 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8276 tcg_gen_nand_i32(t0
, t0
, t1
);
8277 tcg_temp_free_i32(t1
);
8278 tcg_gen_andi_i32(t0
, t0
, 1);
8279 tcg_gen_extu_i32_tl(bcond
, t0
);
8284 TCGv_i32 t1
= tcg_temp_new_i32();
8285 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8286 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8287 tcg_gen_or_i32(t0
, t0
, t1
);
8288 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8289 tcg_gen_or_i32(t0
, t0
, t1
);
8290 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8291 tcg_gen_or_i32(t0
, t0
, t1
);
8292 tcg_temp_free_i32(t1
);
8293 tcg_gen_andi_i32(t0
, t0
, 1);
8294 tcg_gen_extu_i32_tl(bcond
, t0
);
8297 ctx
->hflags
|= MIPS_HFLAG_BC
;
8300 MIPS_INVAL("cp1 cond branch");
8301 generate_exception_end(ctx
, EXCP_RI
);
8304 ctx
->btarget
= btarget
;
8305 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8307 tcg_temp_free_i32(t0
);
8310 /* R6 CP1 Branches */
8311 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
8312 int32_t ft
, int32_t offset
,
8315 target_ulong btarget
;
8316 TCGv_i64 t0
= tcg_temp_new_i64();
8318 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
8319 #ifdef MIPS_DEBUG_DISAS
8320 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8323 generate_exception_end(ctx
, EXCP_RI
);
8327 gen_load_fpr64(ctx
, t0
, ft
);
8328 tcg_gen_andi_i64(t0
, t0
, 1);
8330 btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
8334 tcg_gen_xori_i64(t0
, t0
, 1);
8335 ctx
->hflags
|= MIPS_HFLAG_BC
;
8338 /* t0 already set */
8339 ctx
->hflags
|= MIPS_HFLAG_BC
;
8342 MIPS_INVAL("cp1 cond branch");
8343 generate_exception_end(ctx
, EXCP_RI
);
8347 tcg_gen_trunc_i64_tl(bcond
, t0
);
8349 ctx
->btarget
= btarget
;
8351 switch (delayslot_size
) {
8353 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
8356 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8361 tcg_temp_free_i64(t0
);
8364 /* Coprocessor 1 (FPU) */
8366 #define FOP(func, fmt) (((fmt) << 21) | (func))
8369 OPC_ADD_S
= FOP(0, FMT_S
),
8370 OPC_SUB_S
= FOP(1, FMT_S
),
8371 OPC_MUL_S
= FOP(2, FMT_S
),
8372 OPC_DIV_S
= FOP(3, FMT_S
),
8373 OPC_SQRT_S
= FOP(4, FMT_S
),
8374 OPC_ABS_S
= FOP(5, FMT_S
),
8375 OPC_MOV_S
= FOP(6, FMT_S
),
8376 OPC_NEG_S
= FOP(7, FMT_S
),
8377 OPC_ROUND_L_S
= FOP(8, FMT_S
),
8378 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
8379 OPC_CEIL_L_S
= FOP(10, FMT_S
),
8380 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
8381 OPC_ROUND_W_S
= FOP(12, FMT_S
),
8382 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
8383 OPC_CEIL_W_S
= FOP(14, FMT_S
),
8384 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
8385 OPC_SEL_S
= FOP(16, FMT_S
),
8386 OPC_MOVCF_S
= FOP(17, FMT_S
),
8387 OPC_MOVZ_S
= FOP(18, FMT_S
),
8388 OPC_MOVN_S
= FOP(19, FMT_S
),
8389 OPC_SELEQZ_S
= FOP(20, FMT_S
),
8390 OPC_RECIP_S
= FOP(21, FMT_S
),
8391 OPC_RSQRT_S
= FOP(22, FMT_S
),
8392 OPC_SELNEZ_S
= FOP(23, FMT_S
),
8393 OPC_MADDF_S
= FOP(24, FMT_S
),
8394 OPC_MSUBF_S
= FOP(25, FMT_S
),
8395 OPC_RINT_S
= FOP(26, FMT_S
),
8396 OPC_CLASS_S
= FOP(27, FMT_S
),
8397 OPC_MIN_S
= FOP(28, FMT_S
),
8398 OPC_RECIP2_S
= FOP(28, FMT_S
),
8399 OPC_MINA_S
= FOP(29, FMT_S
),
8400 OPC_RECIP1_S
= FOP(29, FMT_S
),
8401 OPC_MAX_S
= FOP(30, FMT_S
),
8402 OPC_RSQRT1_S
= FOP(30, FMT_S
),
8403 OPC_MAXA_S
= FOP(31, FMT_S
),
8404 OPC_RSQRT2_S
= FOP(31, FMT_S
),
8405 OPC_CVT_D_S
= FOP(33, FMT_S
),
8406 OPC_CVT_W_S
= FOP(36, FMT_S
),
8407 OPC_CVT_L_S
= FOP(37, FMT_S
),
8408 OPC_CVT_PS_S
= FOP(38, FMT_S
),
8409 OPC_CMP_F_S
= FOP (48, FMT_S
),
8410 OPC_CMP_UN_S
= FOP (49, FMT_S
),
8411 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
8412 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
8413 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
8414 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
8415 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
8416 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
8417 OPC_CMP_SF_S
= FOP (56, FMT_S
),
8418 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
8419 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
8420 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
8421 OPC_CMP_LT_S
= FOP (60, FMT_S
),
8422 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
8423 OPC_CMP_LE_S
= FOP (62, FMT_S
),
8424 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
8426 OPC_ADD_D
= FOP(0, FMT_D
),
8427 OPC_SUB_D
= FOP(1, FMT_D
),
8428 OPC_MUL_D
= FOP(2, FMT_D
),
8429 OPC_DIV_D
= FOP(3, FMT_D
),
8430 OPC_SQRT_D
= FOP(4, FMT_D
),
8431 OPC_ABS_D
= FOP(5, FMT_D
),
8432 OPC_MOV_D
= FOP(6, FMT_D
),
8433 OPC_NEG_D
= FOP(7, FMT_D
),
8434 OPC_ROUND_L_D
= FOP(8, FMT_D
),
8435 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
8436 OPC_CEIL_L_D
= FOP(10, FMT_D
),
8437 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
8438 OPC_ROUND_W_D
= FOP(12, FMT_D
),
8439 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
8440 OPC_CEIL_W_D
= FOP(14, FMT_D
),
8441 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
8442 OPC_SEL_D
= FOP(16, FMT_D
),
8443 OPC_MOVCF_D
= FOP(17, FMT_D
),
8444 OPC_MOVZ_D
= FOP(18, FMT_D
),
8445 OPC_MOVN_D
= FOP(19, FMT_D
),
8446 OPC_SELEQZ_D
= FOP(20, FMT_D
),
8447 OPC_RECIP_D
= FOP(21, FMT_D
),
8448 OPC_RSQRT_D
= FOP(22, FMT_D
),
8449 OPC_SELNEZ_D
= FOP(23, FMT_D
),
8450 OPC_MADDF_D
= FOP(24, FMT_D
),
8451 OPC_MSUBF_D
= FOP(25, FMT_D
),
8452 OPC_RINT_D
= FOP(26, FMT_D
),
8453 OPC_CLASS_D
= FOP(27, FMT_D
),
8454 OPC_MIN_D
= FOP(28, FMT_D
),
8455 OPC_RECIP2_D
= FOP(28, FMT_D
),
8456 OPC_MINA_D
= FOP(29, FMT_D
),
8457 OPC_RECIP1_D
= FOP(29, FMT_D
),
8458 OPC_MAX_D
= FOP(30, FMT_D
),
8459 OPC_RSQRT1_D
= FOP(30, FMT_D
),
8460 OPC_MAXA_D
= FOP(31, FMT_D
),
8461 OPC_RSQRT2_D
= FOP(31, FMT_D
),
8462 OPC_CVT_S_D
= FOP(32, FMT_D
),
8463 OPC_CVT_W_D
= FOP(36, FMT_D
),
8464 OPC_CVT_L_D
= FOP(37, FMT_D
),
8465 OPC_CMP_F_D
= FOP (48, FMT_D
),
8466 OPC_CMP_UN_D
= FOP (49, FMT_D
),
8467 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
8468 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
8469 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
8470 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
8471 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
8472 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
8473 OPC_CMP_SF_D
= FOP (56, FMT_D
),
8474 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
8475 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
8476 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
8477 OPC_CMP_LT_D
= FOP (60, FMT_D
),
8478 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
8479 OPC_CMP_LE_D
= FOP (62, FMT_D
),
8480 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
8482 OPC_CVT_S_W
= FOP(32, FMT_W
),
8483 OPC_CVT_D_W
= FOP(33, FMT_W
),
8484 OPC_CVT_S_L
= FOP(32, FMT_L
),
8485 OPC_CVT_D_L
= FOP(33, FMT_L
),
8486 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
8488 OPC_ADD_PS
= FOP(0, FMT_PS
),
8489 OPC_SUB_PS
= FOP(1, FMT_PS
),
8490 OPC_MUL_PS
= FOP(2, FMT_PS
),
8491 OPC_DIV_PS
= FOP(3, FMT_PS
),
8492 OPC_ABS_PS
= FOP(5, FMT_PS
),
8493 OPC_MOV_PS
= FOP(6, FMT_PS
),
8494 OPC_NEG_PS
= FOP(7, FMT_PS
),
8495 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
8496 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
8497 OPC_MOVN_PS
= FOP(19, FMT_PS
),
8498 OPC_ADDR_PS
= FOP(24, FMT_PS
),
8499 OPC_MULR_PS
= FOP(26, FMT_PS
),
8500 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
8501 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
8502 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
8503 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
8505 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
8506 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
8507 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
8508 OPC_PLL_PS
= FOP(44, FMT_PS
),
8509 OPC_PLU_PS
= FOP(45, FMT_PS
),
8510 OPC_PUL_PS
= FOP(46, FMT_PS
),
8511 OPC_PUU_PS
= FOP(47, FMT_PS
),
8512 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
8513 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
8514 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
8515 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
8516 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
8517 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
8518 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
8519 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
8520 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
8521 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
8522 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
8523 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
8524 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
8525 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
8526 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
8527 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
8531 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
8532 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
8533 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
8534 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
8535 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
8536 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
8537 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
8538 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
8539 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
8540 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
8541 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
8542 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
8543 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
8544 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
8545 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
8546 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
8547 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
8548 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
8549 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
8550 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
8551 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
8552 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
8554 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
8555 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
8556 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
8557 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
8558 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
8559 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
8560 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
8561 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
8562 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
8563 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
8564 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
8565 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
8566 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
8567 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
8568 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
8569 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
8570 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
8571 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
8572 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
8573 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
8574 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
8575 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
8577 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
8579 TCGv t0
= tcg_temp_new();
8584 TCGv_i32 fp0
= tcg_temp_new_i32();
8586 gen_load_fpr32(ctx
, fp0
, fs
);
8587 tcg_gen_ext_i32_tl(t0
, fp0
);
8588 tcg_temp_free_i32(fp0
);
8590 gen_store_gpr(t0
, rt
);
8593 gen_load_gpr(t0
, rt
);
8595 TCGv_i32 fp0
= tcg_temp_new_i32();
8597 tcg_gen_trunc_tl_i32(fp0
, t0
);
8598 gen_store_fpr32(ctx
, fp0
, fs
);
8599 tcg_temp_free_i32(fp0
);
8603 gen_helper_1e0i(cfc1
, t0
, fs
);
8604 gen_store_gpr(t0
, rt
);
8607 gen_load_gpr(t0
, rt
);
8608 save_cpu_state(ctx
, 0);
8610 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
8612 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8613 tcg_temp_free_i32(fs_tmp
);
8615 /* Stop translation as we may have changed hflags */
8616 ctx
->bstate
= BS_STOP
;
8618 #if defined(TARGET_MIPS64)
8620 gen_load_fpr64(ctx
, t0
, fs
);
8621 gen_store_gpr(t0
, rt
);
8624 gen_load_gpr(t0
, rt
);
8625 gen_store_fpr64(ctx
, t0
, fs
);
8630 TCGv_i32 fp0
= tcg_temp_new_i32();
8632 gen_load_fpr32h(ctx
, fp0
, fs
);
8633 tcg_gen_ext_i32_tl(t0
, fp0
);
8634 tcg_temp_free_i32(fp0
);
8636 gen_store_gpr(t0
, rt
);
8639 gen_load_gpr(t0
, rt
);
8641 TCGv_i32 fp0
= tcg_temp_new_i32();
8643 tcg_gen_trunc_tl_i32(fp0
, t0
);
8644 gen_store_fpr32h(ctx
, fp0
, fs
);
8645 tcg_temp_free_i32(fp0
);
8649 MIPS_INVAL("cp1 move");
8650 generate_exception_end(ctx
, EXCP_RI
);
8658 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
8674 l1
= gen_new_label();
8675 t0
= tcg_temp_new_i32();
8676 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8677 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8678 tcg_temp_free_i32(t0
);
8680 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
8682 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
8687 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
8691 TCGv_i32 t0
= tcg_temp_new_i32();
8692 TCGLabel
*l1
= gen_new_label();
8699 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8700 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8701 gen_load_fpr32(ctx
, t0
, fs
);
8702 gen_store_fpr32(ctx
, t0
, fd
);
8704 tcg_temp_free_i32(t0
);
8707 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
8710 TCGv_i32 t0
= tcg_temp_new_i32();
8712 TCGLabel
*l1
= gen_new_label();
8719 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8720 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8721 tcg_temp_free_i32(t0
);
8722 fp0
= tcg_temp_new_i64();
8723 gen_load_fpr64(ctx
, fp0
, fs
);
8724 gen_store_fpr64(ctx
, fp0
, fd
);
8725 tcg_temp_free_i64(fp0
);
8729 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
8733 TCGv_i32 t0
= tcg_temp_new_i32();
8734 TCGLabel
*l1
= gen_new_label();
8735 TCGLabel
*l2
= gen_new_label();
8742 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8743 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8744 gen_load_fpr32(ctx
, t0
, fs
);
8745 gen_store_fpr32(ctx
, t0
, fd
);
8748 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
8749 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
8750 gen_load_fpr32h(ctx
, t0
, fs
);
8751 gen_store_fpr32h(ctx
, t0
, fd
);
8752 tcg_temp_free_i32(t0
);
8756 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8759 TCGv_i32 t1
= tcg_const_i32(0);
8760 TCGv_i32 fp0
= tcg_temp_new_i32();
8761 TCGv_i32 fp1
= tcg_temp_new_i32();
8762 TCGv_i32 fp2
= tcg_temp_new_i32();
8763 gen_load_fpr32(ctx
, fp0
, fd
);
8764 gen_load_fpr32(ctx
, fp1
, ft
);
8765 gen_load_fpr32(ctx
, fp2
, fs
);
8769 tcg_gen_andi_i32(fp0
, fp0
, 1);
8770 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8773 tcg_gen_andi_i32(fp1
, fp1
, 1);
8774 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8777 tcg_gen_andi_i32(fp1
, fp1
, 1);
8778 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8781 MIPS_INVAL("gen_sel_s");
8782 generate_exception_end(ctx
, EXCP_RI
);
8786 gen_store_fpr32(ctx
, fp0
, fd
);
8787 tcg_temp_free_i32(fp2
);
8788 tcg_temp_free_i32(fp1
);
8789 tcg_temp_free_i32(fp0
);
8790 tcg_temp_free_i32(t1
);
8793 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8796 TCGv_i64 t1
= tcg_const_i64(0);
8797 TCGv_i64 fp0
= tcg_temp_new_i64();
8798 TCGv_i64 fp1
= tcg_temp_new_i64();
8799 TCGv_i64 fp2
= tcg_temp_new_i64();
8800 gen_load_fpr64(ctx
, fp0
, fd
);
8801 gen_load_fpr64(ctx
, fp1
, ft
);
8802 gen_load_fpr64(ctx
, fp2
, fs
);
8806 tcg_gen_andi_i64(fp0
, fp0
, 1);
8807 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8810 tcg_gen_andi_i64(fp1
, fp1
, 1);
8811 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8814 tcg_gen_andi_i64(fp1
, fp1
, 1);
8815 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8818 MIPS_INVAL("gen_sel_d");
8819 generate_exception_end(ctx
, EXCP_RI
);
8823 gen_store_fpr64(ctx
, fp0
, fd
);
8824 tcg_temp_free_i64(fp2
);
8825 tcg_temp_free_i64(fp1
);
8826 tcg_temp_free_i64(fp0
);
8827 tcg_temp_free_i64(t1
);
8830 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
8831 int ft
, int fs
, int fd
, int cc
)
8833 uint32_t func
= ctx
->opcode
& 0x3f;
8837 TCGv_i32 fp0
= tcg_temp_new_i32();
8838 TCGv_i32 fp1
= tcg_temp_new_i32();
8840 gen_load_fpr32(ctx
, fp0
, fs
);
8841 gen_load_fpr32(ctx
, fp1
, ft
);
8842 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
8843 tcg_temp_free_i32(fp1
);
8844 gen_store_fpr32(ctx
, fp0
, fd
);
8845 tcg_temp_free_i32(fp0
);
8850 TCGv_i32 fp0
= tcg_temp_new_i32();
8851 TCGv_i32 fp1
= tcg_temp_new_i32();
8853 gen_load_fpr32(ctx
, fp0
, fs
);
8854 gen_load_fpr32(ctx
, fp1
, ft
);
8855 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
8856 tcg_temp_free_i32(fp1
);
8857 gen_store_fpr32(ctx
, fp0
, fd
);
8858 tcg_temp_free_i32(fp0
);
8863 TCGv_i32 fp0
= tcg_temp_new_i32();
8864 TCGv_i32 fp1
= tcg_temp_new_i32();
8866 gen_load_fpr32(ctx
, fp0
, fs
);
8867 gen_load_fpr32(ctx
, fp1
, ft
);
8868 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
8869 tcg_temp_free_i32(fp1
);
8870 gen_store_fpr32(ctx
, fp0
, fd
);
8871 tcg_temp_free_i32(fp0
);
8876 TCGv_i32 fp0
= tcg_temp_new_i32();
8877 TCGv_i32 fp1
= tcg_temp_new_i32();
8879 gen_load_fpr32(ctx
, fp0
, fs
);
8880 gen_load_fpr32(ctx
, fp1
, ft
);
8881 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
8882 tcg_temp_free_i32(fp1
);
8883 gen_store_fpr32(ctx
, fp0
, fd
);
8884 tcg_temp_free_i32(fp0
);
8889 TCGv_i32 fp0
= tcg_temp_new_i32();
8891 gen_load_fpr32(ctx
, fp0
, fs
);
8892 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
8893 gen_store_fpr32(ctx
, fp0
, fd
);
8894 tcg_temp_free_i32(fp0
);
8899 TCGv_i32 fp0
= tcg_temp_new_i32();
8901 gen_load_fpr32(ctx
, fp0
, fs
);
8903 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
8905 gen_helper_float_abs_s(fp0
, fp0
);
8907 gen_store_fpr32(ctx
, fp0
, fd
);
8908 tcg_temp_free_i32(fp0
);
8913 TCGv_i32 fp0
= tcg_temp_new_i32();
8915 gen_load_fpr32(ctx
, fp0
, fs
);
8916 gen_store_fpr32(ctx
, fp0
, fd
);
8917 tcg_temp_free_i32(fp0
);
8922 TCGv_i32 fp0
= tcg_temp_new_i32();
8924 gen_load_fpr32(ctx
, fp0
, fs
);
8926 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
8928 gen_helper_float_chs_s(fp0
, fp0
);
8930 gen_store_fpr32(ctx
, fp0
, fd
);
8931 tcg_temp_free_i32(fp0
);
8935 check_cp1_64bitmode(ctx
);
8937 TCGv_i32 fp32
= tcg_temp_new_i32();
8938 TCGv_i64 fp64
= tcg_temp_new_i64();
8940 gen_load_fpr32(ctx
, fp32
, fs
);
8942 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
8944 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
8946 tcg_temp_free_i32(fp32
);
8947 gen_store_fpr64(ctx
, fp64
, fd
);
8948 tcg_temp_free_i64(fp64
);
8952 check_cp1_64bitmode(ctx
);
8954 TCGv_i32 fp32
= tcg_temp_new_i32();
8955 TCGv_i64 fp64
= tcg_temp_new_i64();
8957 gen_load_fpr32(ctx
, fp32
, fs
);
8959 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
8961 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
8963 tcg_temp_free_i32(fp32
);
8964 gen_store_fpr64(ctx
, fp64
, fd
);
8965 tcg_temp_free_i64(fp64
);
8969 check_cp1_64bitmode(ctx
);
8971 TCGv_i32 fp32
= tcg_temp_new_i32();
8972 TCGv_i64 fp64
= tcg_temp_new_i64();
8974 gen_load_fpr32(ctx
, fp32
, fs
);
8976 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
8978 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
8980 tcg_temp_free_i32(fp32
);
8981 gen_store_fpr64(ctx
, fp64
, fd
);
8982 tcg_temp_free_i64(fp64
);
8986 check_cp1_64bitmode(ctx
);
8988 TCGv_i32 fp32
= tcg_temp_new_i32();
8989 TCGv_i64 fp64
= tcg_temp_new_i64();
8991 gen_load_fpr32(ctx
, fp32
, fs
);
8993 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
8995 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
8997 tcg_temp_free_i32(fp32
);
8998 gen_store_fpr64(ctx
, fp64
, fd
);
8999 tcg_temp_free_i64(fp64
);
9004 TCGv_i32 fp0
= tcg_temp_new_i32();
9006 gen_load_fpr32(ctx
, fp0
, fs
);
9008 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
9010 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
9012 gen_store_fpr32(ctx
, fp0
, fd
);
9013 tcg_temp_free_i32(fp0
);
9018 TCGv_i32 fp0
= tcg_temp_new_i32();
9020 gen_load_fpr32(ctx
, fp0
, fs
);
9022 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
9024 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
9026 gen_store_fpr32(ctx
, fp0
, fd
);
9027 tcg_temp_free_i32(fp0
);
9032 TCGv_i32 fp0
= tcg_temp_new_i32();
9034 gen_load_fpr32(ctx
, fp0
, fs
);
9036 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
9038 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
9040 gen_store_fpr32(ctx
, fp0
, fd
);
9041 tcg_temp_free_i32(fp0
);
9046 TCGv_i32 fp0
= tcg_temp_new_i32();
9048 gen_load_fpr32(ctx
, fp0
, fs
);
9050 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
9052 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
9054 gen_store_fpr32(ctx
, fp0
, fd
);
9055 tcg_temp_free_i32(fp0
);
9059 check_insn(ctx
, ISA_MIPS32R6
);
9060 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9063 check_insn(ctx
, ISA_MIPS32R6
);
9064 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9067 check_insn(ctx
, ISA_MIPS32R6
);
9068 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9071 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9072 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9075 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9077 TCGLabel
*l1
= gen_new_label();
9081 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9083 fp0
= tcg_temp_new_i32();
9084 gen_load_fpr32(ctx
, fp0
, fs
);
9085 gen_store_fpr32(ctx
, fp0
, fd
);
9086 tcg_temp_free_i32(fp0
);
9091 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9093 TCGLabel
*l1
= gen_new_label();
9097 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9098 fp0
= tcg_temp_new_i32();
9099 gen_load_fpr32(ctx
, fp0
, fs
);
9100 gen_store_fpr32(ctx
, fp0
, fd
);
9101 tcg_temp_free_i32(fp0
);
9108 TCGv_i32 fp0
= tcg_temp_new_i32();
9110 gen_load_fpr32(ctx
, fp0
, fs
);
9111 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
9112 gen_store_fpr32(ctx
, fp0
, fd
);
9113 tcg_temp_free_i32(fp0
);
9118 TCGv_i32 fp0
= tcg_temp_new_i32();
9120 gen_load_fpr32(ctx
, fp0
, fs
);
9121 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
9122 gen_store_fpr32(ctx
, fp0
, fd
);
9123 tcg_temp_free_i32(fp0
);
9127 check_insn(ctx
, ISA_MIPS32R6
);
9129 TCGv_i32 fp0
= tcg_temp_new_i32();
9130 TCGv_i32 fp1
= tcg_temp_new_i32();
9131 TCGv_i32 fp2
= tcg_temp_new_i32();
9132 gen_load_fpr32(ctx
, fp0
, fs
);
9133 gen_load_fpr32(ctx
, fp1
, ft
);
9134 gen_load_fpr32(ctx
, fp2
, fd
);
9135 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9136 gen_store_fpr32(ctx
, fp2
, fd
);
9137 tcg_temp_free_i32(fp2
);
9138 tcg_temp_free_i32(fp1
);
9139 tcg_temp_free_i32(fp0
);
9143 check_insn(ctx
, ISA_MIPS32R6
);
9145 TCGv_i32 fp0
= tcg_temp_new_i32();
9146 TCGv_i32 fp1
= tcg_temp_new_i32();
9147 TCGv_i32 fp2
= tcg_temp_new_i32();
9148 gen_load_fpr32(ctx
, fp0
, fs
);
9149 gen_load_fpr32(ctx
, fp1
, ft
);
9150 gen_load_fpr32(ctx
, fp2
, fd
);
9151 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9152 gen_store_fpr32(ctx
, fp2
, fd
);
9153 tcg_temp_free_i32(fp2
);
9154 tcg_temp_free_i32(fp1
);
9155 tcg_temp_free_i32(fp0
);
9159 check_insn(ctx
, ISA_MIPS32R6
);
9161 TCGv_i32 fp0
= tcg_temp_new_i32();
9162 gen_load_fpr32(ctx
, fp0
, fs
);
9163 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
9164 gen_store_fpr32(ctx
, fp0
, fd
);
9165 tcg_temp_free_i32(fp0
);
9169 check_insn(ctx
, ISA_MIPS32R6
);
9171 TCGv_i32 fp0
= tcg_temp_new_i32();
9172 gen_load_fpr32(ctx
, fp0
, fs
);
9173 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
9174 gen_store_fpr32(ctx
, fp0
, fd
);
9175 tcg_temp_free_i32(fp0
);
9178 case OPC_MIN_S
: /* OPC_RECIP2_S */
9179 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9181 TCGv_i32 fp0
= tcg_temp_new_i32();
9182 TCGv_i32 fp1
= tcg_temp_new_i32();
9183 TCGv_i32 fp2
= tcg_temp_new_i32();
9184 gen_load_fpr32(ctx
, fp0
, fs
);
9185 gen_load_fpr32(ctx
, fp1
, ft
);
9186 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
9187 gen_store_fpr32(ctx
, fp2
, fd
);
9188 tcg_temp_free_i32(fp2
);
9189 tcg_temp_free_i32(fp1
);
9190 tcg_temp_free_i32(fp0
);
9193 check_cp1_64bitmode(ctx
);
9195 TCGv_i32 fp0
= tcg_temp_new_i32();
9196 TCGv_i32 fp1
= tcg_temp_new_i32();
9198 gen_load_fpr32(ctx
, fp0
, fs
);
9199 gen_load_fpr32(ctx
, fp1
, ft
);
9200 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
9201 tcg_temp_free_i32(fp1
);
9202 gen_store_fpr32(ctx
, fp0
, fd
);
9203 tcg_temp_free_i32(fp0
);
9207 case OPC_MINA_S
: /* OPC_RECIP1_S */
9208 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9210 TCGv_i32 fp0
= tcg_temp_new_i32();
9211 TCGv_i32 fp1
= tcg_temp_new_i32();
9212 TCGv_i32 fp2
= tcg_temp_new_i32();
9213 gen_load_fpr32(ctx
, fp0
, fs
);
9214 gen_load_fpr32(ctx
, fp1
, ft
);
9215 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
9216 gen_store_fpr32(ctx
, fp2
, fd
);
9217 tcg_temp_free_i32(fp2
);
9218 tcg_temp_free_i32(fp1
);
9219 tcg_temp_free_i32(fp0
);
9222 check_cp1_64bitmode(ctx
);
9224 TCGv_i32 fp0
= tcg_temp_new_i32();
9226 gen_load_fpr32(ctx
, fp0
, fs
);
9227 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
9228 gen_store_fpr32(ctx
, fp0
, fd
);
9229 tcg_temp_free_i32(fp0
);
9233 case OPC_MAX_S
: /* OPC_RSQRT1_S */
9234 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9236 TCGv_i32 fp0
= tcg_temp_new_i32();
9237 TCGv_i32 fp1
= tcg_temp_new_i32();
9238 gen_load_fpr32(ctx
, fp0
, fs
);
9239 gen_load_fpr32(ctx
, fp1
, ft
);
9240 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
9241 gen_store_fpr32(ctx
, fp1
, fd
);
9242 tcg_temp_free_i32(fp1
);
9243 tcg_temp_free_i32(fp0
);
9246 check_cp1_64bitmode(ctx
);
9248 TCGv_i32 fp0
= tcg_temp_new_i32();
9250 gen_load_fpr32(ctx
, fp0
, fs
);
9251 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
9252 gen_store_fpr32(ctx
, fp0
, fd
);
9253 tcg_temp_free_i32(fp0
);
9257 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
9258 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9260 TCGv_i32 fp0
= tcg_temp_new_i32();
9261 TCGv_i32 fp1
= tcg_temp_new_i32();
9262 gen_load_fpr32(ctx
, fp0
, fs
);
9263 gen_load_fpr32(ctx
, fp1
, ft
);
9264 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
9265 gen_store_fpr32(ctx
, fp1
, fd
);
9266 tcg_temp_free_i32(fp1
);
9267 tcg_temp_free_i32(fp0
);
9270 check_cp1_64bitmode(ctx
);
9272 TCGv_i32 fp0
= tcg_temp_new_i32();
9273 TCGv_i32 fp1
= tcg_temp_new_i32();
9275 gen_load_fpr32(ctx
, fp0
, fs
);
9276 gen_load_fpr32(ctx
, fp1
, ft
);
9277 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
9278 tcg_temp_free_i32(fp1
);
9279 gen_store_fpr32(ctx
, fp0
, fd
);
9280 tcg_temp_free_i32(fp0
);
9285 check_cp1_registers(ctx
, fd
);
9287 TCGv_i32 fp32
= tcg_temp_new_i32();
9288 TCGv_i64 fp64
= tcg_temp_new_i64();
9290 gen_load_fpr32(ctx
, fp32
, fs
);
9291 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
9292 tcg_temp_free_i32(fp32
);
9293 gen_store_fpr64(ctx
, fp64
, fd
);
9294 tcg_temp_free_i64(fp64
);
9299 TCGv_i32 fp0
= tcg_temp_new_i32();
9301 gen_load_fpr32(ctx
, fp0
, fs
);
9303 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
9305 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
9307 gen_store_fpr32(ctx
, fp0
, fd
);
9308 tcg_temp_free_i32(fp0
);
9312 check_cp1_64bitmode(ctx
);
9314 TCGv_i32 fp32
= tcg_temp_new_i32();
9315 TCGv_i64 fp64
= tcg_temp_new_i64();
9317 gen_load_fpr32(ctx
, fp32
, fs
);
9319 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
9321 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
9323 tcg_temp_free_i32(fp32
);
9324 gen_store_fpr64(ctx
, fp64
, fd
);
9325 tcg_temp_free_i64(fp64
);
9331 TCGv_i64 fp64
= tcg_temp_new_i64();
9332 TCGv_i32 fp32_0
= tcg_temp_new_i32();
9333 TCGv_i32 fp32_1
= tcg_temp_new_i32();
9335 gen_load_fpr32(ctx
, fp32_0
, fs
);
9336 gen_load_fpr32(ctx
, fp32_1
, ft
);
9337 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
9338 tcg_temp_free_i32(fp32_1
);
9339 tcg_temp_free_i32(fp32_0
);
9340 gen_store_fpr64(ctx
, fp64
, fd
);
9341 tcg_temp_free_i64(fp64
);
9353 case OPC_CMP_NGLE_S
:
9360 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9361 if (ctx
->opcode
& (1 << 6)) {
9362 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
9364 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
9368 check_cp1_registers(ctx
, fs
| ft
| fd
);
9370 TCGv_i64 fp0
= tcg_temp_new_i64();
9371 TCGv_i64 fp1
= tcg_temp_new_i64();
9373 gen_load_fpr64(ctx
, fp0
, fs
);
9374 gen_load_fpr64(ctx
, fp1
, ft
);
9375 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
9376 tcg_temp_free_i64(fp1
);
9377 gen_store_fpr64(ctx
, fp0
, fd
);
9378 tcg_temp_free_i64(fp0
);
9382 check_cp1_registers(ctx
, fs
| ft
| fd
);
9384 TCGv_i64 fp0
= tcg_temp_new_i64();
9385 TCGv_i64 fp1
= tcg_temp_new_i64();
9387 gen_load_fpr64(ctx
, fp0
, fs
);
9388 gen_load_fpr64(ctx
, fp1
, ft
);
9389 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
9390 tcg_temp_free_i64(fp1
);
9391 gen_store_fpr64(ctx
, fp0
, fd
);
9392 tcg_temp_free_i64(fp0
);
9396 check_cp1_registers(ctx
, fs
| ft
| fd
);
9398 TCGv_i64 fp0
= tcg_temp_new_i64();
9399 TCGv_i64 fp1
= tcg_temp_new_i64();
9401 gen_load_fpr64(ctx
, fp0
, fs
);
9402 gen_load_fpr64(ctx
, fp1
, ft
);
9403 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
9404 tcg_temp_free_i64(fp1
);
9405 gen_store_fpr64(ctx
, fp0
, fd
);
9406 tcg_temp_free_i64(fp0
);
9410 check_cp1_registers(ctx
, fs
| ft
| fd
);
9412 TCGv_i64 fp0
= tcg_temp_new_i64();
9413 TCGv_i64 fp1
= tcg_temp_new_i64();
9415 gen_load_fpr64(ctx
, fp0
, fs
);
9416 gen_load_fpr64(ctx
, fp1
, ft
);
9417 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
9418 tcg_temp_free_i64(fp1
);
9419 gen_store_fpr64(ctx
, fp0
, fd
);
9420 tcg_temp_free_i64(fp0
);
9424 check_cp1_registers(ctx
, fs
| fd
);
9426 TCGv_i64 fp0
= tcg_temp_new_i64();
9428 gen_load_fpr64(ctx
, fp0
, fs
);
9429 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
9430 gen_store_fpr64(ctx
, fp0
, fd
);
9431 tcg_temp_free_i64(fp0
);
9435 check_cp1_registers(ctx
, fs
| fd
);
9437 TCGv_i64 fp0
= tcg_temp_new_i64();
9439 gen_load_fpr64(ctx
, fp0
, fs
);
9441 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
9443 gen_helper_float_abs_d(fp0
, fp0
);
9445 gen_store_fpr64(ctx
, fp0
, fd
);
9446 tcg_temp_free_i64(fp0
);
9450 check_cp1_registers(ctx
, fs
| fd
);
9452 TCGv_i64 fp0
= tcg_temp_new_i64();
9454 gen_load_fpr64(ctx
, fp0
, fs
);
9455 gen_store_fpr64(ctx
, fp0
, fd
);
9456 tcg_temp_free_i64(fp0
);
9460 check_cp1_registers(ctx
, fs
| fd
);
9462 TCGv_i64 fp0
= tcg_temp_new_i64();
9464 gen_load_fpr64(ctx
, fp0
, fs
);
9466 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
9468 gen_helper_float_chs_d(fp0
, fp0
);
9470 gen_store_fpr64(ctx
, fp0
, fd
);
9471 tcg_temp_free_i64(fp0
);
9475 check_cp1_64bitmode(ctx
);
9477 TCGv_i64 fp0
= tcg_temp_new_i64();
9479 gen_load_fpr64(ctx
, fp0
, fs
);
9481 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
9483 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
9485 gen_store_fpr64(ctx
, fp0
, fd
);
9486 tcg_temp_free_i64(fp0
);
9490 check_cp1_64bitmode(ctx
);
9492 TCGv_i64 fp0
= tcg_temp_new_i64();
9494 gen_load_fpr64(ctx
, fp0
, fs
);
9496 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
9498 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
9500 gen_store_fpr64(ctx
, fp0
, fd
);
9501 tcg_temp_free_i64(fp0
);
9505 check_cp1_64bitmode(ctx
);
9507 TCGv_i64 fp0
= tcg_temp_new_i64();
9509 gen_load_fpr64(ctx
, fp0
, fs
);
9511 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
9513 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
9515 gen_store_fpr64(ctx
, fp0
, fd
);
9516 tcg_temp_free_i64(fp0
);
9520 check_cp1_64bitmode(ctx
);
9522 TCGv_i64 fp0
= tcg_temp_new_i64();
9524 gen_load_fpr64(ctx
, fp0
, fs
);
9526 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
9528 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
9530 gen_store_fpr64(ctx
, fp0
, fd
);
9531 tcg_temp_free_i64(fp0
);
9535 check_cp1_registers(ctx
, fs
);
9537 TCGv_i32 fp32
= tcg_temp_new_i32();
9538 TCGv_i64 fp64
= tcg_temp_new_i64();
9540 gen_load_fpr64(ctx
, fp64
, fs
);
9542 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
9544 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
9546 tcg_temp_free_i64(fp64
);
9547 gen_store_fpr32(ctx
, fp32
, fd
);
9548 tcg_temp_free_i32(fp32
);
9552 check_cp1_registers(ctx
, fs
);
9554 TCGv_i32 fp32
= tcg_temp_new_i32();
9555 TCGv_i64 fp64
= tcg_temp_new_i64();
9557 gen_load_fpr64(ctx
, fp64
, fs
);
9559 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
9561 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
9563 tcg_temp_free_i64(fp64
);
9564 gen_store_fpr32(ctx
, fp32
, fd
);
9565 tcg_temp_free_i32(fp32
);
9569 check_cp1_registers(ctx
, fs
);
9571 TCGv_i32 fp32
= tcg_temp_new_i32();
9572 TCGv_i64 fp64
= tcg_temp_new_i64();
9574 gen_load_fpr64(ctx
, fp64
, fs
);
9576 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
9578 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
9580 tcg_temp_free_i64(fp64
);
9581 gen_store_fpr32(ctx
, fp32
, fd
);
9582 tcg_temp_free_i32(fp32
);
9586 check_cp1_registers(ctx
, fs
);
9588 TCGv_i32 fp32
= tcg_temp_new_i32();
9589 TCGv_i64 fp64
= tcg_temp_new_i64();
9591 gen_load_fpr64(ctx
, fp64
, fs
);
9593 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
9595 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
9597 tcg_temp_free_i64(fp64
);
9598 gen_store_fpr32(ctx
, fp32
, fd
);
9599 tcg_temp_free_i32(fp32
);
9603 check_insn(ctx
, ISA_MIPS32R6
);
9604 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9607 check_insn(ctx
, ISA_MIPS32R6
);
9608 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9611 check_insn(ctx
, ISA_MIPS32R6
);
9612 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9615 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9616 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9619 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9621 TCGLabel
*l1
= gen_new_label();
9625 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9627 fp0
= tcg_temp_new_i64();
9628 gen_load_fpr64(ctx
, fp0
, fs
);
9629 gen_store_fpr64(ctx
, fp0
, fd
);
9630 tcg_temp_free_i64(fp0
);
9635 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9637 TCGLabel
*l1
= gen_new_label();
9641 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9642 fp0
= tcg_temp_new_i64();
9643 gen_load_fpr64(ctx
, fp0
, fs
);
9644 gen_store_fpr64(ctx
, fp0
, fd
);
9645 tcg_temp_free_i64(fp0
);
9651 check_cp1_registers(ctx
, fs
| fd
);
9653 TCGv_i64 fp0
= tcg_temp_new_i64();
9655 gen_load_fpr64(ctx
, fp0
, fs
);
9656 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
9657 gen_store_fpr64(ctx
, fp0
, fd
);
9658 tcg_temp_free_i64(fp0
);
9662 check_cp1_registers(ctx
, fs
| fd
);
9664 TCGv_i64 fp0
= tcg_temp_new_i64();
9666 gen_load_fpr64(ctx
, fp0
, fs
);
9667 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
9668 gen_store_fpr64(ctx
, fp0
, fd
);
9669 tcg_temp_free_i64(fp0
);
9673 check_insn(ctx
, ISA_MIPS32R6
);
9675 TCGv_i64 fp0
= tcg_temp_new_i64();
9676 TCGv_i64 fp1
= tcg_temp_new_i64();
9677 TCGv_i64 fp2
= tcg_temp_new_i64();
9678 gen_load_fpr64(ctx
, fp0
, fs
);
9679 gen_load_fpr64(ctx
, fp1
, ft
);
9680 gen_load_fpr64(ctx
, fp2
, fd
);
9681 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9682 gen_store_fpr64(ctx
, fp2
, fd
);
9683 tcg_temp_free_i64(fp2
);
9684 tcg_temp_free_i64(fp1
);
9685 tcg_temp_free_i64(fp0
);
9689 check_insn(ctx
, ISA_MIPS32R6
);
9691 TCGv_i64 fp0
= tcg_temp_new_i64();
9692 TCGv_i64 fp1
= tcg_temp_new_i64();
9693 TCGv_i64 fp2
= tcg_temp_new_i64();
9694 gen_load_fpr64(ctx
, fp0
, fs
);
9695 gen_load_fpr64(ctx
, fp1
, ft
);
9696 gen_load_fpr64(ctx
, fp2
, fd
);
9697 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9698 gen_store_fpr64(ctx
, fp2
, fd
);
9699 tcg_temp_free_i64(fp2
);
9700 tcg_temp_free_i64(fp1
);
9701 tcg_temp_free_i64(fp0
);
9705 check_insn(ctx
, ISA_MIPS32R6
);
9707 TCGv_i64 fp0
= tcg_temp_new_i64();
9708 gen_load_fpr64(ctx
, fp0
, fs
);
9709 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
9710 gen_store_fpr64(ctx
, fp0
, fd
);
9711 tcg_temp_free_i64(fp0
);
9715 check_insn(ctx
, ISA_MIPS32R6
);
9717 TCGv_i64 fp0
= tcg_temp_new_i64();
9718 gen_load_fpr64(ctx
, fp0
, fs
);
9719 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
9720 gen_store_fpr64(ctx
, fp0
, fd
);
9721 tcg_temp_free_i64(fp0
);
9724 case OPC_MIN_D
: /* OPC_RECIP2_D */
9725 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9727 TCGv_i64 fp0
= tcg_temp_new_i64();
9728 TCGv_i64 fp1
= tcg_temp_new_i64();
9729 gen_load_fpr64(ctx
, fp0
, fs
);
9730 gen_load_fpr64(ctx
, fp1
, ft
);
9731 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
9732 gen_store_fpr64(ctx
, fp1
, fd
);
9733 tcg_temp_free_i64(fp1
);
9734 tcg_temp_free_i64(fp0
);
9737 check_cp1_64bitmode(ctx
);
9739 TCGv_i64 fp0
= tcg_temp_new_i64();
9740 TCGv_i64 fp1
= tcg_temp_new_i64();
9742 gen_load_fpr64(ctx
, fp0
, fs
);
9743 gen_load_fpr64(ctx
, fp1
, ft
);
9744 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
9745 tcg_temp_free_i64(fp1
);
9746 gen_store_fpr64(ctx
, fp0
, fd
);
9747 tcg_temp_free_i64(fp0
);
9751 case OPC_MINA_D
: /* OPC_RECIP1_D */
9752 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9754 TCGv_i64 fp0
= tcg_temp_new_i64();
9755 TCGv_i64 fp1
= tcg_temp_new_i64();
9756 gen_load_fpr64(ctx
, fp0
, fs
);
9757 gen_load_fpr64(ctx
, fp1
, ft
);
9758 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
9759 gen_store_fpr64(ctx
, fp1
, fd
);
9760 tcg_temp_free_i64(fp1
);
9761 tcg_temp_free_i64(fp0
);
9764 check_cp1_64bitmode(ctx
);
9766 TCGv_i64 fp0
= tcg_temp_new_i64();
9768 gen_load_fpr64(ctx
, fp0
, fs
);
9769 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
9770 gen_store_fpr64(ctx
, fp0
, fd
);
9771 tcg_temp_free_i64(fp0
);
9775 case OPC_MAX_D
: /* OPC_RSQRT1_D */
9776 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9778 TCGv_i64 fp0
= tcg_temp_new_i64();
9779 TCGv_i64 fp1
= tcg_temp_new_i64();
9780 gen_load_fpr64(ctx
, fp0
, fs
);
9781 gen_load_fpr64(ctx
, fp1
, ft
);
9782 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
9783 gen_store_fpr64(ctx
, fp1
, fd
);
9784 tcg_temp_free_i64(fp1
);
9785 tcg_temp_free_i64(fp0
);
9788 check_cp1_64bitmode(ctx
);
9790 TCGv_i64 fp0
= tcg_temp_new_i64();
9792 gen_load_fpr64(ctx
, fp0
, fs
);
9793 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
9794 gen_store_fpr64(ctx
, fp0
, fd
);
9795 tcg_temp_free_i64(fp0
);
9799 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
9800 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9802 TCGv_i64 fp0
= tcg_temp_new_i64();
9803 TCGv_i64 fp1
= tcg_temp_new_i64();
9804 gen_load_fpr64(ctx
, fp0
, fs
);
9805 gen_load_fpr64(ctx
, fp1
, ft
);
9806 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
9807 gen_store_fpr64(ctx
, fp1
, fd
);
9808 tcg_temp_free_i64(fp1
);
9809 tcg_temp_free_i64(fp0
);
9812 check_cp1_64bitmode(ctx
);
9814 TCGv_i64 fp0
= tcg_temp_new_i64();
9815 TCGv_i64 fp1
= tcg_temp_new_i64();
9817 gen_load_fpr64(ctx
, fp0
, fs
);
9818 gen_load_fpr64(ctx
, fp1
, ft
);
9819 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
9820 tcg_temp_free_i64(fp1
);
9821 gen_store_fpr64(ctx
, fp0
, fd
);
9822 tcg_temp_free_i64(fp0
);
9835 case OPC_CMP_NGLE_D
:
9842 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9843 if (ctx
->opcode
& (1 << 6)) {
9844 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
9846 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
9850 check_cp1_registers(ctx
, fs
);
9852 TCGv_i32 fp32
= tcg_temp_new_i32();
9853 TCGv_i64 fp64
= tcg_temp_new_i64();
9855 gen_load_fpr64(ctx
, fp64
, fs
);
9856 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
9857 tcg_temp_free_i64(fp64
);
9858 gen_store_fpr32(ctx
, fp32
, fd
);
9859 tcg_temp_free_i32(fp32
);
9863 check_cp1_registers(ctx
, fs
);
9865 TCGv_i32 fp32
= tcg_temp_new_i32();
9866 TCGv_i64 fp64
= tcg_temp_new_i64();
9868 gen_load_fpr64(ctx
, fp64
, fs
);
9870 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
9872 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
9874 tcg_temp_free_i64(fp64
);
9875 gen_store_fpr32(ctx
, fp32
, fd
);
9876 tcg_temp_free_i32(fp32
);
9880 check_cp1_64bitmode(ctx
);
9882 TCGv_i64 fp0
= tcg_temp_new_i64();
9884 gen_load_fpr64(ctx
, fp0
, fs
);
9886 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
9888 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
9890 gen_store_fpr64(ctx
, fp0
, fd
);
9891 tcg_temp_free_i64(fp0
);
9896 TCGv_i32 fp0
= tcg_temp_new_i32();
9898 gen_load_fpr32(ctx
, fp0
, fs
);
9899 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
9900 gen_store_fpr32(ctx
, fp0
, fd
);
9901 tcg_temp_free_i32(fp0
);
9905 check_cp1_registers(ctx
, fd
);
9907 TCGv_i32 fp32
= tcg_temp_new_i32();
9908 TCGv_i64 fp64
= tcg_temp_new_i64();
9910 gen_load_fpr32(ctx
, fp32
, fs
);
9911 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
9912 tcg_temp_free_i32(fp32
);
9913 gen_store_fpr64(ctx
, fp64
, fd
);
9914 tcg_temp_free_i64(fp64
);
9918 check_cp1_64bitmode(ctx
);
9920 TCGv_i32 fp32
= tcg_temp_new_i32();
9921 TCGv_i64 fp64
= tcg_temp_new_i64();
9923 gen_load_fpr64(ctx
, fp64
, fs
);
9924 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
9925 tcg_temp_free_i64(fp64
);
9926 gen_store_fpr32(ctx
, fp32
, fd
);
9927 tcg_temp_free_i32(fp32
);
9931 check_cp1_64bitmode(ctx
);
9933 TCGv_i64 fp0
= tcg_temp_new_i64();
9935 gen_load_fpr64(ctx
, fp0
, fs
);
9936 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
9937 gen_store_fpr64(ctx
, fp0
, fd
);
9938 tcg_temp_free_i64(fp0
);
9944 TCGv_i64 fp0
= tcg_temp_new_i64();
9946 gen_load_fpr64(ctx
, fp0
, fs
);
9947 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
9948 gen_store_fpr64(ctx
, fp0
, fd
);
9949 tcg_temp_free_i64(fp0
);
9955 TCGv_i64 fp0
= tcg_temp_new_i64();
9956 TCGv_i64 fp1
= tcg_temp_new_i64();
9958 gen_load_fpr64(ctx
, fp0
, fs
);
9959 gen_load_fpr64(ctx
, fp1
, ft
);
9960 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
9961 tcg_temp_free_i64(fp1
);
9962 gen_store_fpr64(ctx
, fp0
, fd
);
9963 tcg_temp_free_i64(fp0
);
9969 TCGv_i64 fp0
= tcg_temp_new_i64();
9970 TCGv_i64 fp1
= tcg_temp_new_i64();
9972 gen_load_fpr64(ctx
, fp0
, fs
);
9973 gen_load_fpr64(ctx
, fp1
, ft
);
9974 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
9975 tcg_temp_free_i64(fp1
);
9976 gen_store_fpr64(ctx
, fp0
, fd
);
9977 tcg_temp_free_i64(fp0
);
9983 TCGv_i64 fp0
= tcg_temp_new_i64();
9984 TCGv_i64 fp1
= tcg_temp_new_i64();
9986 gen_load_fpr64(ctx
, fp0
, fs
);
9987 gen_load_fpr64(ctx
, fp1
, ft
);
9988 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
9989 tcg_temp_free_i64(fp1
);
9990 gen_store_fpr64(ctx
, fp0
, fd
);
9991 tcg_temp_free_i64(fp0
);
9997 TCGv_i64 fp0
= tcg_temp_new_i64();
9999 gen_load_fpr64(ctx
, fp0
, fs
);
10000 gen_helper_float_abs_ps(fp0
, fp0
);
10001 gen_store_fpr64(ctx
, fp0
, fd
);
10002 tcg_temp_free_i64(fp0
);
10008 TCGv_i64 fp0
= tcg_temp_new_i64();
10010 gen_load_fpr64(ctx
, fp0
, fs
);
10011 gen_store_fpr64(ctx
, fp0
, fd
);
10012 tcg_temp_free_i64(fp0
);
10018 TCGv_i64 fp0
= tcg_temp_new_i64();
10020 gen_load_fpr64(ctx
, fp0
, fs
);
10021 gen_helper_float_chs_ps(fp0
, fp0
);
10022 gen_store_fpr64(ctx
, fp0
, fd
);
10023 tcg_temp_free_i64(fp0
);
10028 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10033 TCGLabel
*l1
= gen_new_label();
10037 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10038 fp0
= tcg_temp_new_i64();
10039 gen_load_fpr64(ctx
, fp0
, fs
);
10040 gen_store_fpr64(ctx
, fp0
, fd
);
10041 tcg_temp_free_i64(fp0
);
10048 TCGLabel
*l1
= gen_new_label();
10052 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10053 fp0
= tcg_temp_new_i64();
10054 gen_load_fpr64(ctx
, fp0
, fs
);
10055 gen_store_fpr64(ctx
, fp0
, fd
);
10056 tcg_temp_free_i64(fp0
);
10064 TCGv_i64 fp0
= tcg_temp_new_i64();
10065 TCGv_i64 fp1
= tcg_temp_new_i64();
10067 gen_load_fpr64(ctx
, fp0
, ft
);
10068 gen_load_fpr64(ctx
, fp1
, fs
);
10069 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
10070 tcg_temp_free_i64(fp1
);
10071 gen_store_fpr64(ctx
, fp0
, fd
);
10072 tcg_temp_free_i64(fp0
);
10078 TCGv_i64 fp0
= tcg_temp_new_i64();
10079 TCGv_i64 fp1
= tcg_temp_new_i64();
10081 gen_load_fpr64(ctx
, fp0
, ft
);
10082 gen_load_fpr64(ctx
, fp1
, fs
);
10083 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
10084 tcg_temp_free_i64(fp1
);
10085 gen_store_fpr64(ctx
, fp0
, fd
);
10086 tcg_temp_free_i64(fp0
);
10089 case OPC_RECIP2_PS
:
10092 TCGv_i64 fp0
= tcg_temp_new_i64();
10093 TCGv_i64 fp1
= tcg_temp_new_i64();
10095 gen_load_fpr64(ctx
, fp0
, fs
);
10096 gen_load_fpr64(ctx
, fp1
, ft
);
10097 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
10098 tcg_temp_free_i64(fp1
);
10099 gen_store_fpr64(ctx
, fp0
, fd
);
10100 tcg_temp_free_i64(fp0
);
10103 case OPC_RECIP1_PS
:
10106 TCGv_i64 fp0
= tcg_temp_new_i64();
10108 gen_load_fpr64(ctx
, fp0
, fs
);
10109 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
10110 gen_store_fpr64(ctx
, fp0
, fd
);
10111 tcg_temp_free_i64(fp0
);
10114 case OPC_RSQRT1_PS
:
10117 TCGv_i64 fp0
= tcg_temp_new_i64();
10119 gen_load_fpr64(ctx
, fp0
, fs
);
10120 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
10121 gen_store_fpr64(ctx
, fp0
, fd
);
10122 tcg_temp_free_i64(fp0
);
10125 case OPC_RSQRT2_PS
:
10128 TCGv_i64 fp0
= tcg_temp_new_i64();
10129 TCGv_i64 fp1
= tcg_temp_new_i64();
10131 gen_load_fpr64(ctx
, fp0
, fs
);
10132 gen_load_fpr64(ctx
, fp1
, ft
);
10133 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
10134 tcg_temp_free_i64(fp1
);
10135 gen_store_fpr64(ctx
, fp0
, fd
);
10136 tcg_temp_free_i64(fp0
);
10140 check_cp1_64bitmode(ctx
);
10142 TCGv_i32 fp0
= tcg_temp_new_i32();
10144 gen_load_fpr32h(ctx
, fp0
, fs
);
10145 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
10146 gen_store_fpr32(ctx
, fp0
, fd
);
10147 tcg_temp_free_i32(fp0
);
10150 case OPC_CVT_PW_PS
:
10153 TCGv_i64 fp0
= tcg_temp_new_i64();
10155 gen_load_fpr64(ctx
, fp0
, fs
);
10156 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
10157 gen_store_fpr64(ctx
, fp0
, fd
);
10158 tcg_temp_free_i64(fp0
);
10162 check_cp1_64bitmode(ctx
);
10164 TCGv_i32 fp0
= tcg_temp_new_i32();
10166 gen_load_fpr32(ctx
, fp0
, fs
);
10167 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
10168 gen_store_fpr32(ctx
, fp0
, fd
);
10169 tcg_temp_free_i32(fp0
);
10175 TCGv_i32 fp0
= tcg_temp_new_i32();
10176 TCGv_i32 fp1
= tcg_temp_new_i32();
10178 gen_load_fpr32(ctx
, fp0
, fs
);
10179 gen_load_fpr32(ctx
, fp1
, ft
);
10180 gen_store_fpr32h(ctx
, fp0
, fd
);
10181 gen_store_fpr32(ctx
, fp1
, fd
);
10182 tcg_temp_free_i32(fp0
);
10183 tcg_temp_free_i32(fp1
);
10189 TCGv_i32 fp0
= tcg_temp_new_i32();
10190 TCGv_i32 fp1
= tcg_temp_new_i32();
10192 gen_load_fpr32(ctx
, fp0
, fs
);
10193 gen_load_fpr32h(ctx
, fp1
, ft
);
10194 gen_store_fpr32(ctx
, fp1
, fd
);
10195 gen_store_fpr32h(ctx
, fp0
, fd
);
10196 tcg_temp_free_i32(fp0
);
10197 tcg_temp_free_i32(fp1
);
10203 TCGv_i32 fp0
= tcg_temp_new_i32();
10204 TCGv_i32 fp1
= tcg_temp_new_i32();
10206 gen_load_fpr32h(ctx
, fp0
, fs
);
10207 gen_load_fpr32(ctx
, fp1
, ft
);
10208 gen_store_fpr32(ctx
, fp1
, fd
);
10209 gen_store_fpr32h(ctx
, fp0
, fd
);
10210 tcg_temp_free_i32(fp0
);
10211 tcg_temp_free_i32(fp1
);
10217 TCGv_i32 fp0
= tcg_temp_new_i32();
10218 TCGv_i32 fp1
= tcg_temp_new_i32();
10220 gen_load_fpr32h(ctx
, fp0
, fs
);
10221 gen_load_fpr32h(ctx
, fp1
, ft
);
10222 gen_store_fpr32(ctx
, fp1
, fd
);
10223 gen_store_fpr32h(ctx
, fp0
, fd
);
10224 tcg_temp_free_i32(fp0
);
10225 tcg_temp_free_i32(fp1
);
10229 case OPC_CMP_UN_PS
:
10230 case OPC_CMP_EQ_PS
:
10231 case OPC_CMP_UEQ_PS
:
10232 case OPC_CMP_OLT_PS
:
10233 case OPC_CMP_ULT_PS
:
10234 case OPC_CMP_OLE_PS
:
10235 case OPC_CMP_ULE_PS
:
10236 case OPC_CMP_SF_PS
:
10237 case OPC_CMP_NGLE_PS
:
10238 case OPC_CMP_SEQ_PS
:
10239 case OPC_CMP_NGL_PS
:
10240 case OPC_CMP_LT_PS
:
10241 case OPC_CMP_NGE_PS
:
10242 case OPC_CMP_LE_PS
:
10243 case OPC_CMP_NGT_PS
:
10244 if (ctx
->opcode
& (1 << 6)) {
10245 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
10247 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
10251 MIPS_INVAL("farith");
10252 generate_exception_end(ctx
, EXCP_RI
);
10257 /* Coprocessor 3 (FPU) */
10258 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
10259 int fd
, int fs
, int base
, int index
)
10261 TCGv t0
= tcg_temp_new();
10264 gen_load_gpr(t0
, index
);
10265 } else if (index
== 0) {
10266 gen_load_gpr(t0
, base
);
10268 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
10270 /* Don't do NOP if destination is zero: we must perform the actual
10276 TCGv_i32 fp0
= tcg_temp_new_i32();
10278 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
10279 tcg_gen_trunc_tl_i32(fp0
, t0
);
10280 gen_store_fpr32(ctx
, fp0
, fd
);
10281 tcg_temp_free_i32(fp0
);
10286 check_cp1_registers(ctx
, fd
);
10288 TCGv_i64 fp0
= tcg_temp_new_i64();
10289 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10290 gen_store_fpr64(ctx
, fp0
, fd
);
10291 tcg_temp_free_i64(fp0
);
10295 check_cp1_64bitmode(ctx
);
10296 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10298 TCGv_i64 fp0
= tcg_temp_new_i64();
10300 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10301 gen_store_fpr64(ctx
, fp0
, fd
);
10302 tcg_temp_free_i64(fp0
);
10308 TCGv_i32 fp0
= tcg_temp_new_i32();
10309 gen_load_fpr32(ctx
, fp0
, fs
);
10310 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
10311 tcg_temp_free_i32(fp0
);
10316 check_cp1_registers(ctx
, fs
);
10318 TCGv_i64 fp0
= tcg_temp_new_i64();
10319 gen_load_fpr64(ctx
, fp0
, fs
);
10320 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10321 tcg_temp_free_i64(fp0
);
10325 check_cp1_64bitmode(ctx
);
10326 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10328 TCGv_i64 fp0
= tcg_temp_new_i64();
10329 gen_load_fpr64(ctx
, fp0
, fs
);
10330 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10331 tcg_temp_free_i64(fp0
);
10338 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
10339 int fd
, int fr
, int fs
, int ft
)
10345 TCGv t0
= tcg_temp_local_new();
10346 TCGv_i32 fp
= tcg_temp_new_i32();
10347 TCGv_i32 fph
= tcg_temp_new_i32();
10348 TCGLabel
*l1
= gen_new_label();
10349 TCGLabel
*l2
= gen_new_label();
10351 gen_load_gpr(t0
, fr
);
10352 tcg_gen_andi_tl(t0
, t0
, 0x7);
10354 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
10355 gen_load_fpr32(ctx
, fp
, fs
);
10356 gen_load_fpr32h(ctx
, fph
, fs
);
10357 gen_store_fpr32(ctx
, fp
, fd
);
10358 gen_store_fpr32h(ctx
, fph
, fd
);
10361 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
10363 #ifdef TARGET_WORDS_BIGENDIAN
10364 gen_load_fpr32(ctx
, fp
, fs
);
10365 gen_load_fpr32h(ctx
, fph
, ft
);
10366 gen_store_fpr32h(ctx
, fp
, fd
);
10367 gen_store_fpr32(ctx
, fph
, fd
);
10369 gen_load_fpr32h(ctx
, fph
, fs
);
10370 gen_load_fpr32(ctx
, fp
, ft
);
10371 gen_store_fpr32(ctx
, fph
, fd
);
10372 gen_store_fpr32h(ctx
, fp
, fd
);
10375 tcg_temp_free_i32(fp
);
10376 tcg_temp_free_i32(fph
);
10382 TCGv_i32 fp0
= tcg_temp_new_i32();
10383 TCGv_i32 fp1
= tcg_temp_new_i32();
10384 TCGv_i32 fp2
= tcg_temp_new_i32();
10386 gen_load_fpr32(ctx
, fp0
, fs
);
10387 gen_load_fpr32(ctx
, fp1
, ft
);
10388 gen_load_fpr32(ctx
, fp2
, fr
);
10389 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10390 tcg_temp_free_i32(fp0
);
10391 tcg_temp_free_i32(fp1
);
10392 gen_store_fpr32(ctx
, fp2
, fd
);
10393 tcg_temp_free_i32(fp2
);
10398 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10400 TCGv_i64 fp0
= tcg_temp_new_i64();
10401 TCGv_i64 fp1
= tcg_temp_new_i64();
10402 TCGv_i64 fp2
= tcg_temp_new_i64();
10404 gen_load_fpr64(ctx
, fp0
, fs
);
10405 gen_load_fpr64(ctx
, fp1
, ft
);
10406 gen_load_fpr64(ctx
, fp2
, fr
);
10407 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10408 tcg_temp_free_i64(fp0
);
10409 tcg_temp_free_i64(fp1
);
10410 gen_store_fpr64(ctx
, fp2
, fd
);
10411 tcg_temp_free_i64(fp2
);
10417 TCGv_i64 fp0
= tcg_temp_new_i64();
10418 TCGv_i64 fp1
= tcg_temp_new_i64();
10419 TCGv_i64 fp2
= tcg_temp_new_i64();
10421 gen_load_fpr64(ctx
, fp0
, fs
);
10422 gen_load_fpr64(ctx
, fp1
, ft
);
10423 gen_load_fpr64(ctx
, fp2
, fr
);
10424 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10425 tcg_temp_free_i64(fp0
);
10426 tcg_temp_free_i64(fp1
);
10427 gen_store_fpr64(ctx
, fp2
, fd
);
10428 tcg_temp_free_i64(fp2
);
10434 TCGv_i32 fp0
= tcg_temp_new_i32();
10435 TCGv_i32 fp1
= tcg_temp_new_i32();
10436 TCGv_i32 fp2
= tcg_temp_new_i32();
10438 gen_load_fpr32(ctx
, fp0
, fs
);
10439 gen_load_fpr32(ctx
, fp1
, ft
);
10440 gen_load_fpr32(ctx
, fp2
, fr
);
10441 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10442 tcg_temp_free_i32(fp0
);
10443 tcg_temp_free_i32(fp1
);
10444 gen_store_fpr32(ctx
, fp2
, fd
);
10445 tcg_temp_free_i32(fp2
);
10450 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10452 TCGv_i64 fp0
= tcg_temp_new_i64();
10453 TCGv_i64 fp1
= tcg_temp_new_i64();
10454 TCGv_i64 fp2
= tcg_temp_new_i64();
10456 gen_load_fpr64(ctx
, fp0
, fs
);
10457 gen_load_fpr64(ctx
, fp1
, ft
);
10458 gen_load_fpr64(ctx
, fp2
, fr
);
10459 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10460 tcg_temp_free_i64(fp0
);
10461 tcg_temp_free_i64(fp1
);
10462 gen_store_fpr64(ctx
, fp2
, fd
);
10463 tcg_temp_free_i64(fp2
);
10469 TCGv_i64 fp0
= tcg_temp_new_i64();
10470 TCGv_i64 fp1
= tcg_temp_new_i64();
10471 TCGv_i64 fp2
= tcg_temp_new_i64();
10473 gen_load_fpr64(ctx
, fp0
, fs
);
10474 gen_load_fpr64(ctx
, fp1
, ft
);
10475 gen_load_fpr64(ctx
, fp2
, fr
);
10476 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10477 tcg_temp_free_i64(fp0
);
10478 tcg_temp_free_i64(fp1
);
10479 gen_store_fpr64(ctx
, fp2
, fd
);
10480 tcg_temp_free_i64(fp2
);
10486 TCGv_i32 fp0
= tcg_temp_new_i32();
10487 TCGv_i32 fp1
= tcg_temp_new_i32();
10488 TCGv_i32 fp2
= tcg_temp_new_i32();
10490 gen_load_fpr32(ctx
, fp0
, fs
);
10491 gen_load_fpr32(ctx
, fp1
, ft
);
10492 gen_load_fpr32(ctx
, fp2
, fr
);
10493 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10494 tcg_temp_free_i32(fp0
);
10495 tcg_temp_free_i32(fp1
);
10496 gen_store_fpr32(ctx
, fp2
, fd
);
10497 tcg_temp_free_i32(fp2
);
10502 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10504 TCGv_i64 fp0
= tcg_temp_new_i64();
10505 TCGv_i64 fp1
= tcg_temp_new_i64();
10506 TCGv_i64 fp2
= tcg_temp_new_i64();
10508 gen_load_fpr64(ctx
, fp0
, fs
);
10509 gen_load_fpr64(ctx
, fp1
, ft
);
10510 gen_load_fpr64(ctx
, fp2
, fr
);
10511 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10512 tcg_temp_free_i64(fp0
);
10513 tcg_temp_free_i64(fp1
);
10514 gen_store_fpr64(ctx
, fp2
, fd
);
10515 tcg_temp_free_i64(fp2
);
10521 TCGv_i64 fp0
= tcg_temp_new_i64();
10522 TCGv_i64 fp1
= tcg_temp_new_i64();
10523 TCGv_i64 fp2
= tcg_temp_new_i64();
10525 gen_load_fpr64(ctx
, fp0
, fs
);
10526 gen_load_fpr64(ctx
, fp1
, ft
);
10527 gen_load_fpr64(ctx
, fp2
, fr
);
10528 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10529 tcg_temp_free_i64(fp0
);
10530 tcg_temp_free_i64(fp1
);
10531 gen_store_fpr64(ctx
, fp2
, fd
);
10532 tcg_temp_free_i64(fp2
);
10538 TCGv_i32 fp0
= tcg_temp_new_i32();
10539 TCGv_i32 fp1
= tcg_temp_new_i32();
10540 TCGv_i32 fp2
= tcg_temp_new_i32();
10542 gen_load_fpr32(ctx
, fp0
, fs
);
10543 gen_load_fpr32(ctx
, fp1
, ft
);
10544 gen_load_fpr32(ctx
, fp2
, fr
);
10545 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10546 tcg_temp_free_i32(fp0
);
10547 tcg_temp_free_i32(fp1
);
10548 gen_store_fpr32(ctx
, fp2
, fd
);
10549 tcg_temp_free_i32(fp2
);
10554 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10556 TCGv_i64 fp0
= tcg_temp_new_i64();
10557 TCGv_i64 fp1
= tcg_temp_new_i64();
10558 TCGv_i64 fp2
= tcg_temp_new_i64();
10560 gen_load_fpr64(ctx
, fp0
, fs
);
10561 gen_load_fpr64(ctx
, fp1
, ft
);
10562 gen_load_fpr64(ctx
, fp2
, fr
);
10563 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10564 tcg_temp_free_i64(fp0
);
10565 tcg_temp_free_i64(fp1
);
10566 gen_store_fpr64(ctx
, fp2
, fd
);
10567 tcg_temp_free_i64(fp2
);
10573 TCGv_i64 fp0
= tcg_temp_new_i64();
10574 TCGv_i64 fp1
= tcg_temp_new_i64();
10575 TCGv_i64 fp2
= tcg_temp_new_i64();
10577 gen_load_fpr64(ctx
, fp0
, fs
);
10578 gen_load_fpr64(ctx
, fp1
, ft
);
10579 gen_load_fpr64(ctx
, fp2
, fr
);
10580 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10581 tcg_temp_free_i64(fp0
);
10582 tcg_temp_free_i64(fp1
);
10583 gen_store_fpr64(ctx
, fp2
, fd
);
10584 tcg_temp_free_i64(fp2
);
10588 MIPS_INVAL("flt3_arith");
10589 generate_exception_end(ctx
, EXCP_RI
);
10594 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
10598 #if !defined(CONFIG_USER_ONLY)
10599 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10600 Therefore only check the ISA in system mode. */
10601 check_insn(ctx
, ISA_MIPS32R2
);
10603 t0
= tcg_temp_new();
10607 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
10608 gen_store_gpr(t0
, rt
);
10611 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
10612 gen_store_gpr(t0
, rt
);
10615 gen_helper_rdhwr_cc(t0
, cpu_env
);
10616 gen_store_gpr(t0
, rt
);
10619 gen_helper_rdhwr_ccres(t0
, cpu_env
);
10620 gen_store_gpr(t0
, rt
);
10623 check_insn(ctx
, ISA_MIPS32R6
);
10625 /* Performance counter registers are not implemented other than
10626 * control register 0.
10628 generate_exception(ctx
, EXCP_RI
);
10630 gen_helper_rdhwr_performance(t0
, cpu_env
);
10631 gen_store_gpr(t0
, rt
);
10634 check_insn(ctx
, ISA_MIPS32R6
);
10635 gen_helper_rdhwr_xnp(t0
, cpu_env
);
10636 gen_store_gpr(t0
, rt
);
10639 #if defined(CONFIG_USER_ONLY)
10640 tcg_gen_ld_tl(t0
, cpu_env
,
10641 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10642 gen_store_gpr(t0
, rt
);
10645 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
10646 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
10647 tcg_gen_ld_tl(t0
, cpu_env
,
10648 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10649 gen_store_gpr(t0
, rt
);
10651 generate_exception_end(ctx
, EXCP_RI
);
10655 default: /* Invalid */
10656 MIPS_INVAL("rdhwr");
10657 generate_exception_end(ctx
, EXCP_RI
);
10663 static inline void clear_branch_hflags(DisasContext
*ctx
)
10665 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
10666 if (ctx
->bstate
== BS_NONE
) {
10667 save_cpu_state(ctx
, 0);
10669 /* it is not safe to save ctx->hflags as hflags may be changed
10670 in execution time by the instruction in delay / forbidden slot. */
10671 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
10675 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
10677 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10678 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
10679 /* Branches completion */
10680 clear_branch_hflags(ctx
);
10681 ctx
->bstate
= BS_BRANCH
;
10682 /* FIXME: Need to clear can_do_io. */
10683 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
10684 case MIPS_HFLAG_FBNSLOT
:
10685 gen_goto_tb(ctx
, 0, ctx
->pc
+ insn_bytes
);
10688 /* unconditional branch */
10689 if (proc_hflags
& MIPS_HFLAG_BX
) {
10690 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
10692 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10694 case MIPS_HFLAG_BL
:
10695 /* blikely taken case */
10696 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10698 case MIPS_HFLAG_BC
:
10699 /* Conditional branch */
10701 TCGLabel
*l1
= gen_new_label();
10703 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
10704 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
10706 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10709 case MIPS_HFLAG_BR
:
10710 /* unconditional branch to register */
10711 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
10712 TCGv t0
= tcg_temp_new();
10713 TCGv_i32 t1
= tcg_temp_new_i32();
10715 tcg_gen_andi_tl(t0
, btarget
, 0x1);
10716 tcg_gen_trunc_tl_i32(t1
, t0
);
10718 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
10719 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
10720 tcg_gen_or_i32(hflags
, hflags
, t1
);
10721 tcg_temp_free_i32(t1
);
10723 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
10725 tcg_gen_mov_tl(cpu_PC
, btarget
);
10727 if (ctx
->singlestep_enabled
) {
10728 save_cpu_state(ctx
, 0);
10729 gen_helper_raise_exception_debug(cpu_env
);
10731 tcg_gen_exit_tb(0);
10734 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
10740 /* Compact Branches */
10741 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
10742 int rs
, int rt
, int32_t offset
)
10744 int bcond_compute
= 0;
10745 TCGv t0
= tcg_temp_new();
10746 TCGv t1
= tcg_temp_new();
10747 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
10749 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10750 #ifdef MIPS_DEBUG_DISAS
10751 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10754 generate_exception_end(ctx
, EXCP_RI
);
10758 /* Load needed operands and calculate btarget */
10760 /* compact branch */
10761 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
10762 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
10763 gen_load_gpr(t0
, rs
);
10764 gen_load_gpr(t1
, rt
);
10766 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
10767 if (rs
<= rt
&& rs
== 0) {
10768 /* OPC_BEQZALC, OPC_BNEZALC */
10769 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
10772 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
10773 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
10774 gen_load_gpr(t0
, rs
);
10775 gen_load_gpr(t1
, rt
);
10777 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
10779 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
10780 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
10781 if (rs
== 0 || rs
== rt
) {
10782 /* OPC_BLEZALC, OPC_BGEZALC */
10783 /* OPC_BGTZALC, OPC_BLTZALC */
10784 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
10786 gen_load_gpr(t0
, rs
);
10787 gen_load_gpr(t1
, rt
);
10789 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
10793 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
10798 /* OPC_BEQZC, OPC_BNEZC */
10799 gen_load_gpr(t0
, rs
);
10801 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
10803 /* OPC_JIC, OPC_JIALC */
10804 TCGv tbase
= tcg_temp_new();
10805 TCGv toffset
= tcg_temp_new();
10807 gen_load_gpr(tbase
, rt
);
10808 tcg_gen_movi_tl(toffset
, offset
);
10809 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
10810 tcg_temp_free(tbase
);
10811 tcg_temp_free(toffset
);
10815 MIPS_INVAL("Compact branch/jump");
10816 generate_exception_end(ctx
, EXCP_RI
);
10820 if (bcond_compute
== 0) {
10821 /* Uncoditional compact branch */
10824 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
10827 ctx
->hflags
|= MIPS_HFLAG_BR
;
10830 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
10833 ctx
->hflags
|= MIPS_HFLAG_B
;
10836 MIPS_INVAL("Compact branch/jump");
10837 generate_exception_end(ctx
, EXCP_RI
);
10841 /* Generating branch here as compact branches don't have delay slot */
10842 gen_branch(ctx
, 4);
10844 /* Conditional compact branch */
10845 TCGLabel
*fs
= gen_new_label();
10846 save_cpu_state(ctx
, 0);
10849 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
10850 if (rs
== 0 && rt
!= 0) {
10852 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
10853 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
10855 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
10858 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
10861 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
10862 if (rs
== 0 && rt
!= 0) {
10864 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
10865 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
10867 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
10870 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
10873 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
10874 if (rs
== 0 && rt
!= 0) {
10876 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
10877 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
10879 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
10882 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
10885 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
10886 if (rs
== 0 && rt
!= 0) {
10888 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
10889 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
10891 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
10894 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
10897 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
10898 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
10900 /* OPC_BOVC, OPC_BNVC */
10901 TCGv t2
= tcg_temp_new();
10902 TCGv t3
= tcg_temp_new();
10903 TCGv t4
= tcg_temp_new();
10904 TCGv input_overflow
= tcg_temp_new();
10906 gen_load_gpr(t0
, rs
);
10907 gen_load_gpr(t1
, rt
);
10908 tcg_gen_ext32s_tl(t2
, t0
);
10909 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
10910 tcg_gen_ext32s_tl(t3
, t1
);
10911 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
10912 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
10914 tcg_gen_add_tl(t4
, t2
, t3
);
10915 tcg_gen_ext32s_tl(t4
, t4
);
10916 tcg_gen_xor_tl(t2
, t2
, t3
);
10917 tcg_gen_xor_tl(t3
, t4
, t3
);
10918 tcg_gen_andc_tl(t2
, t3
, t2
);
10919 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
10920 tcg_gen_or_tl(t4
, t4
, input_overflow
);
10921 if (opc
== OPC_BOVC
) {
10923 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
10926 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
10928 tcg_temp_free(input_overflow
);
10932 } else if (rs
< rt
&& rs
== 0) {
10933 /* OPC_BEQZALC, OPC_BNEZALC */
10934 if (opc
== OPC_BEQZALC
) {
10936 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
10939 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
10942 /* OPC_BEQC, OPC_BNEC */
10943 if (opc
== OPC_BEQC
) {
10945 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
10948 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
10953 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
10956 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
10959 MIPS_INVAL("Compact conditional branch/jump");
10960 generate_exception_end(ctx
, EXCP_RI
);
10964 /* Generating branch here as compact branches don't have delay slot */
10965 gen_goto_tb(ctx
, 1, ctx
->btarget
);
10968 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
10976 /* ISA extensions (ASEs) */
10977 /* MIPS16 extension to MIPS32 */
10979 /* MIPS16 major opcodes */
10981 M16_OPC_ADDIUSP
= 0x00,
10982 M16_OPC_ADDIUPC
= 0x01,
10984 M16_OPC_JAL
= 0x03,
10985 M16_OPC_BEQZ
= 0x04,
10986 M16_OPC_BNEQZ
= 0x05,
10987 M16_OPC_SHIFT
= 0x06,
10989 M16_OPC_RRIA
= 0x08,
10990 M16_OPC_ADDIU8
= 0x09,
10991 M16_OPC_SLTI
= 0x0a,
10992 M16_OPC_SLTIU
= 0x0b,
10995 M16_OPC_CMPI
= 0x0e,
10999 M16_OPC_LWSP
= 0x12,
11001 M16_OPC_LBU
= 0x14,
11002 M16_OPC_LHU
= 0x15,
11003 M16_OPC_LWPC
= 0x16,
11004 M16_OPC_LWU
= 0x17,
11007 M16_OPC_SWSP
= 0x1a,
11009 M16_OPC_RRR
= 0x1c,
11011 M16_OPC_EXTEND
= 0x1e,
11015 /* I8 funct field */
11034 /* RR funct field */
11068 /* I64 funct field */
11076 I64_DADDIUPC
= 0x6,
11080 /* RR ry field for CNVT */
11082 RR_RY_CNVT_ZEB
= 0x0,
11083 RR_RY_CNVT_ZEH
= 0x1,
11084 RR_RY_CNVT_ZEW
= 0x2,
11085 RR_RY_CNVT_SEB
= 0x4,
11086 RR_RY_CNVT_SEH
= 0x5,
11087 RR_RY_CNVT_SEW
= 0x6,
11090 static int xlat (int r
)
11092 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11097 static void gen_mips16_save (DisasContext
*ctx
,
11098 int xsregs
, int aregs
,
11099 int do_ra
, int do_s0
, int do_s1
,
11102 TCGv t0
= tcg_temp_new();
11103 TCGv t1
= tcg_temp_new();
11104 TCGv t2
= tcg_temp_new();
11134 generate_exception_end(ctx
, EXCP_RI
);
11140 gen_base_offset_addr(ctx
, t0
, 29, 12);
11141 gen_load_gpr(t1
, 7);
11142 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11145 gen_base_offset_addr(ctx
, t0
, 29, 8);
11146 gen_load_gpr(t1
, 6);
11147 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11150 gen_base_offset_addr(ctx
, t0
, 29, 4);
11151 gen_load_gpr(t1
, 5);
11152 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11155 gen_base_offset_addr(ctx
, t0
, 29, 0);
11156 gen_load_gpr(t1
, 4);
11157 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11160 gen_load_gpr(t0
, 29);
11162 #define DECR_AND_STORE(reg) do { \
11163 tcg_gen_movi_tl(t2, -4); \
11164 gen_op_addr_add(ctx, t0, t0, t2); \
11165 gen_load_gpr(t1, reg); \
11166 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11170 DECR_AND_STORE(31);
11175 DECR_AND_STORE(30);
11178 DECR_AND_STORE(23);
11181 DECR_AND_STORE(22);
11184 DECR_AND_STORE(21);
11187 DECR_AND_STORE(20);
11190 DECR_AND_STORE(19);
11193 DECR_AND_STORE(18);
11197 DECR_AND_STORE(17);
11200 DECR_AND_STORE(16);
11230 generate_exception_end(ctx
, EXCP_RI
);
11246 #undef DECR_AND_STORE
11248 tcg_gen_movi_tl(t2
, -framesize
);
11249 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11255 static void gen_mips16_restore (DisasContext
*ctx
,
11256 int xsregs
, int aregs
,
11257 int do_ra
, int do_s0
, int do_s1
,
11261 TCGv t0
= tcg_temp_new();
11262 TCGv t1
= tcg_temp_new();
11263 TCGv t2
= tcg_temp_new();
11265 tcg_gen_movi_tl(t2
, framesize
);
11266 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
11268 #define DECR_AND_LOAD(reg) do { \
11269 tcg_gen_movi_tl(t2, -4); \
11270 gen_op_addr_add(ctx, t0, t0, t2); \
11271 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11272 gen_store_gpr(t1, reg); \
11336 generate_exception_end(ctx
, EXCP_RI
);
11352 #undef DECR_AND_LOAD
11354 tcg_gen_movi_tl(t2
, framesize
);
11355 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11361 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
11362 int is_64_bit
, int extended
)
11366 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11367 generate_exception_end(ctx
, EXCP_RI
);
11371 t0
= tcg_temp_new();
11373 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
11374 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
11376 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11382 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
11385 TCGv_i32 t0
= tcg_const_i32(op
);
11386 TCGv t1
= tcg_temp_new();
11387 gen_base_offset_addr(ctx
, t1
, base
, offset
);
11388 gen_helper_cache(cpu_env
, t1
, t0
);
11391 #if defined(TARGET_MIPS64)
11392 static void decode_i64_mips16 (DisasContext
*ctx
,
11393 int ry
, int funct
, int16_t offset
,
11398 check_insn(ctx
, ISA_MIPS3
);
11399 check_mips_64(ctx
);
11400 offset
= extended
? offset
: offset
<< 3;
11401 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
11404 check_insn(ctx
, ISA_MIPS3
);
11405 check_mips_64(ctx
);
11406 offset
= extended
? offset
: offset
<< 3;
11407 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
11410 check_insn(ctx
, ISA_MIPS3
);
11411 check_mips_64(ctx
);
11412 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
11413 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
11416 check_insn(ctx
, ISA_MIPS3
);
11417 check_mips_64(ctx
);
11418 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
11419 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
11422 check_insn(ctx
, ISA_MIPS3
);
11423 check_mips_64(ctx
);
11424 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11425 generate_exception_end(ctx
, EXCP_RI
);
11427 offset
= extended
? offset
: offset
<< 3;
11428 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
11432 check_insn(ctx
, ISA_MIPS3
);
11433 check_mips_64(ctx
);
11434 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
11435 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
11438 check_insn(ctx
, ISA_MIPS3
);
11439 check_mips_64(ctx
);
11440 offset
= extended
? offset
: offset
<< 2;
11441 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
11444 check_insn(ctx
, ISA_MIPS3
);
11445 check_mips_64(ctx
);
11446 offset
= extended
? offset
: offset
<< 2;
11447 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
11453 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11455 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11456 int op
, rx
, ry
, funct
, sa
;
11457 int16_t imm
, offset
;
11459 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
11460 op
= (ctx
->opcode
>> 11) & 0x1f;
11461 sa
= (ctx
->opcode
>> 22) & 0x1f;
11462 funct
= (ctx
->opcode
>> 8) & 0x7;
11463 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11464 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11465 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
11466 | ((ctx
->opcode
>> 21) & 0x3f) << 5
11467 | (ctx
->opcode
& 0x1f));
11469 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11472 case M16_OPC_ADDIUSP
:
11473 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11475 case M16_OPC_ADDIUPC
:
11476 gen_addiupc(ctx
, rx
, imm
, 0, 1);
11479 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
11480 /* No delay slot, so just process as a normal instruction */
11483 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
11484 /* No delay slot, so just process as a normal instruction */
11486 case M16_OPC_BNEQZ
:
11487 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
11488 /* No delay slot, so just process as a normal instruction */
11490 case M16_OPC_SHIFT
:
11491 switch (ctx
->opcode
& 0x3) {
11493 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11496 #if defined(TARGET_MIPS64)
11497 check_mips_64(ctx
);
11498 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11500 generate_exception_end(ctx
, EXCP_RI
);
11504 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11507 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11511 #if defined(TARGET_MIPS64)
11513 check_insn(ctx
, ISA_MIPS3
);
11514 check_mips_64(ctx
);
11515 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
11519 imm
= ctx
->opcode
& 0xf;
11520 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
11521 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
11522 imm
= (int16_t) (imm
<< 1) >> 1;
11523 if ((ctx
->opcode
>> 4) & 0x1) {
11524 #if defined(TARGET_MIPS64)
11525 check_mips_64(ctx
);
11526 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11528 generate_exception_end(ctx
, EXCP_RI
);
11531 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11534 case M16_OPC_ADDIU8
:
11535 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11538 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11540 case M16_OPC_SLTIU
:
11541 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11546 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
11549 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
11552 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
11555 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
11558 check_insn(ctx
, ISA_MIPS32
);
11560 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
11561 int aregs
= (ctx
->opcode
>> 16) & 0xf;
11562 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
11563 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
11564 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
11565 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
11566 | (ctx
->opcode
& 0xf)) << 3;
11568 if (ctx
->opcode
& (1 << 7)) {
11569 gen_mips16_save(ctx
, xsregs
, aregs
,
11570 do_ra
, do_s0
, do_s1
,
11573 gen_mips16_restore(ctx
, xsregs
, aregs
,
11574 do_ra
, do_s0
, do_s1
,
11580 generate_exception_end(ctx
, EXCP_RI
);
11585 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
11588 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
11590 #if defined(TARGET_MIPS64)
11592 check_insn(ctx
, ISA_MIPS3
);
11593 check_mips_64(ctx
);
11594 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
11598 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11601 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
11604 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
11607 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
11610 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11613 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
11616 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
11618 #if defined(TARGET_MIPS64)
11620 check_insn(ctx
, ISA_MIPS3
);
11621 check_mips_64(ctx
);
11622 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
11626 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11629 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
11632 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
11635 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
11637 #if defined(TARGET_MIPS64)
11639 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
11643 generate_exception_end(ctx
, EXCP_RI
);
11650 static inline bool is_uhi(int sdbbp_code
)
11652 #ifdef CONFIG_USER_ONLY
11655 return semihosting_enabled() && sdbbp_code
== 1;
11659 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11663 int op
, cnvt_op
, op1
, offset
;
11667 op
= (ctx
->opcode
>> 11) & 0x1f;
11668 sa
= (ctx
->opcode
>> 2) & 0x7;
11669 sa
= sa
== 0 ? 8 : sa
;
11670 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11671 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
11672 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11673 op1
= offset
= ctx
->opcode
& 0x1f;
11678 case M16_OPC_ADDIUSP
:
11680 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
11682 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11685 case M16_OPC_ADDIUPC
:
11686 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
11689 offset
= (ctx
->opcode
& 0x7ff) << 1;
11690 offset
= (int16_t)(offset
<< 4) >> 4;
11691 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
11692 /* No delay slot, so just process as a normal instruction */
11695 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11696 offset
= (((ctx
->opcode
& 0x1f) << 21)
11697 | ((ctx
->opcode
>> 5) & 0x1f) << 16
11699 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
11700 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
11704 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
11705 ((int8_t)ctx
->opcode
) << 1, 0);
11706 /* No delay slot, so just process as a normal instruction */
11708 case M16_OPC_BNEQZ
:
11709 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
11710 ((int8_t)ctx
->opcode
) << 1, 0);
11711 /* No delay slot, so just process as a normal instruction */
11713 case M16_OPC_SHIFT
:
11714 switch (ctx
->opcode
& 0x3) {
11716 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11719 #if defined(TARGET_MIPS64)
11720 check_insn(ctx
, ISA_MIPS3
);
11721 check_mips_64(ctx
);
11722 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11724 generate_exception_end(ctx
, EXCP_RI
);
11728 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11731 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11735 #if defined(TARGET_MIPS64)
11737 check_insn(ctx
, ISA_MIPS3
);
11738 check_mips_64(ctx
);
11739 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
11744 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
11746 if ((ctx
->opcode
>> 4) & 1) {
11747 #if defined(TARGET_MIPS64)
11748 check_insn(ctx
, ISA_MIPS3
);
11749 check_mips_64(ctx
);
11750 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11752 generate_exception_end(ctx
, EXCP_RI
);
11755 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11759 case M16_OPC_ADDIU8
:
11761 int16_t imm
= (int8_t) ctx
->opcode
;
11763 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11768 int16_t imm
= (uint8_t) ctx
->opcode
;
11769 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11772 case M16_OPC_SLTIU
:
11774 int16_t imm
= (uint8_t) ctx
->opcode
;
11775 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11782 funct
= (ctx
->opcode
>> 8) & 0x7;
11785 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
11786 ((int8_t)ctx
->opcode
) << 1, 0);
11789 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
11790 ((int8_t)ctx
->opcode
) << 1, 0);
11793 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
11796 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
11797 ((int8_t)ctx
->opcode
) << 3);
11800 check_insn(ctx
, ISA_MIPS32
);
11802 int do_ra
= ctx
->opcode
& (1 << 6);
11803 int do_s0
= ctx
->opcode
& (1 << 5);
11804 int do_s1
= ctx
->opcode
& (1 << 4);
11805 int framesize
= ctx
->opcode
& 0xf;
11807 if (framesize
== 0) {
11810 framesize
= framesize
<< 3;
11813 if (ctx
->opcode
& (1 << 7)) {
11814 gen_mips16_save(ctx
, 0, 0,
11815 do_ra
, do_s0
, do_s1
, framesize
);
11817 gen_mips16_restore(ctx
, 0, 0,
11818 do_ra
, do_s0
, do_s1
, framesize
);
11824 int rz
= xlat(ctx
->opcode
& 0x7);
11826 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
11827 ((ctx
->opcode
>> 5) & 0x7);
11828 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
11832 reg32
= ctx
->opcode
& 0x1f;
11833 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
11836 generate_exception_end(ctx
, EXCP_RI
);
11843 int16_t imm
= (uint8_t) ctx
->opcode
;
11845 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
11850 int16_t imm
= (uint8_t) ctx
->opcode
;
11851 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
11854 #if defined(TARGET_MIPS64)
11856 check_insn(ctx
, ISA_MIPS3
);
11857 check_mips_64(ctx
);
11858 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
11862 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11865 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
11868 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11871 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
11874 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11877 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
11880 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
11882 #if defined (TARGET_MIPS64)
11884 check_insn(ctx
, ISA_MIPS3
);
11885 check_mips_64(ctx
);
11886 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
11890 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11893 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
11896 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11899 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
11903 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
11906 switch (ctx
->opcode
& 0x3) {
11908 mips32_op
= OPC_ADDU
;
11911 mips32_op
= OPC_SUBU
;
11913 #if defined(TARGET_MIPS64)
11915 mips32_op
= OPC_DADDU
;
11916 check_insn(ctx
, ISA_MIPS3
);
11917 check_mips_64(ctx
);
11920 mips32_op
= OPC_DSUBU
;
11921 check_insn(ctx
, ISA_MIPS3
);
11922 check_mips_64(ctx
);
11926 generate_exception_end(ctx
, EXCP_RI
);
11930 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
11939 int nd
= (ctx
->opcode
>> 7) & 0x1;
11940 int link
= (ctx
->opcode
>> 6) & 0x1;
11941 int ra
= (ctx
->opcode
>> 5) & 0x1;
11944 check_insn(ctx
, ISA_MIPS32
);
11953 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
11958 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
11959 gen_helper_do_semihosting(cpu_env
);
11961 /* XXX: not clear which exception should be raised
11962 * when in debug mode...
11964 check_insn(ctx
, ISA_MIPS32
);
11965 generate_exception_end(ctx
, EXCP_DBp
);
11969 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
11972 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
11975 generate_exception_end(ctx
, EXCP_BREAK
);
11978 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
11981 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
11984 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
11986 #if defined (TARGET_MIPS64)
11988 check_insn(ctx
, ISA_MIPS3
);
11989 check_mips_64(ctx
);
11990 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
11994 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
11997 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
12000 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
12003 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
12006 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
12009 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
12012 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
12015 check_insn(ctx
, ISA_MIPS32
);
12017 case RR_RY_CNVT_ZEB
:
12018 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12020 case RR_RY_CNVT_ZEH
:
12021 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12023 case RR_RY_CNVT_SEB
:
12024 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12026 case RR_RY_CNVT_SEH
:
12027 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12029 #if defined (TARGET_MIPS64)
12030 case RR_RY_CNVT_ZEW
:
12031 check_insn(ctx
, ISA_MIPS64
);
12032 check_mips_64(ctx
);
12033 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12035 case RR_RY_CNVT_SEW
:
12036 check_insn(ctx
, ISA_MIPS64
);
12037 check_mips_64(ctx
);
12038 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12042 generate_exception_end(ctx
, EXCP_RI
);
12047 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
12049 #if defined (TARGET_MIPS64)
12051 check_insn(ctx
, ISA_MIPS3
);
12052 check_mips_64(ctx
);
12053 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
12056 check_insn(ctx
, ISA_MIPS3
);
12057 check_mips_64(ctx
);
12058 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
12061 check_insn(ctx
, ISA_MIPS3
);
12062 check_mips_64(ctx
);
12063 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
12066 check_insn(ctx
, ISA_MIPS3
);
12067 check_mips_64(ctx
);
12068 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
12072 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
12075 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
12078 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
12081 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
12083 #if defined (TARGET_MIPS64)
12085 check_insn(ctx
, ISA_MIPS3
);
12086 check_mips_64(ctx
);
12087 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
12090 check_insn(ctx
, ISA_MIPS3
);
12091 check_mips_64(ctx
);
12092 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
12095 check_insn(ctx
, ISA_MIPS3
);
12096 check_mips_64(ctx
);
12097 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
12100 check_insn(ctx
, ISA_MIPS3
);
12101 check_mips_64(ctx
);
12102 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
12106 generate_exception_end(ctx
, EXCP_RI
);
12110 case M16_OPC_EXTEND
:
12111 decode_extended_mips16_opc(env
, ctx
);
12114 #if defined(TARGET_MIPS64)
12116 funct
= (ctx
->opcode
>> 8) & 0x7;
12117 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
12121 generate_exception_end(ctx
, EXCP_RI
);
12128 /* microMIPS extension to MIPS32/MIPS64 */
12131 * microMIPS32/microMIPS64 major opcodes
12133 * 1. MIPS Architecture for Programmers Volume II-B:
12134 * The microMIPS32 Instruction Set (Revision 3.05)
12136 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12138 * 2. MIPS Architecture For Programmers Volume II-A:
12139 * The MIPS64 Instruction Set (Revision 3.51)
12169 POOL32S
= 0x16, /* MIPS64 */
12170 DADDIU32
= 0x17, /* MIPS64 */
12199 /* 0x29 is reserved */
12212 /* 0x31 is reserved */
12225 SD32
= 0x36, /* MIPS64 */
12226 LD32
= 0x37, /* MIPS64 */
12228 /* 0x39 is reserved */
12244 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12254 /* POOL32A encoding of minor opcode field */
12257 /* These opcodes are distinguished only by bits 9..6; those bits are
12258 * what are recorded below. */
12295 /* The following can be distinguished by their lower 6 bits. */
12305 /* POOL32AXF encoding of minor opcode field extension */
12308 * 1. MIPS Architecture for Programmers Volume II-B:
12309 * The microMIPS32 Instruction Set (Revision 3.05)
12311 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12313 * 2. MIPS Architecture for Programmers VolumeIV-e:
12314 * The MIPS DSP Application-Specific Extension
12315 * to the microMIPS32 Architecture (Revision 2.34)
12317 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12332 /* begin of microMIPS32 DSP */
12334 /* bits 13..12 for 0x01 */
12340 /* bits 13..12 for 0x2a */
12346 /* bits 13..12 for 0x32 */
12350 /* end of microMIPS32 DSP */
12352 /* bits 15..12 for 0x2c */
12369 /* bits 15..12 for 0x34 */
12377 /* bits 15..12 for 0x3c */
12379 JR
= 0x0, /* alias */
12387 /* bits 15..12 for 0x05 */
12391 /* bits 15..12 for 0x0d */
12403 /* bits 15..12 for 0x15 */
12409 /* bits 15..12 for 0x1d */
12413 /* bits 15..12 for 0x2d */
12418 /* bits 15..12 for 0x35 */
12425 /* POOL32B encoding of minor opcode field (bits 15..12) */
12441 /* POOL32C encoding of minor opcode field (bits 15..12) */
12449 /* 0xa is reserved */
12456 /* 0x6 is reserved */
12462 /* POOL32F encoding of minor opcode field (bits 5..0) */
12465 /* These are the bit 7..6 values */
12474 /* These are the bit 8..6 values */
12499 MOVZ_FMT_05
= 0x05,
12533 CABS_COND_FMT
= 0x1c, /* MIPS3D */
12540 /* POOL32Fxf encoding of minor opcode extension field */
12578 /* POOL32I encoding of minor opcode field (bits 25..21) */
12608 /* These overlap and are distinguished by bit16 of the instruction */
12617 /* POOL16A encoding of minor opcode field */
12624 /* POOL16B encoding of minor opcode field */
12631 /* POOL16C encoding of minor opcode field */
12651 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12671 /* POOL16D encoding of minor opcode field */
12678 /* POOL16E encoding of minor opcode field */
12685 static int mmreg (int r
)
12687 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12692 /* Used for 16-bit store instructions. */
12693 static int mmreg2 (int r
)
12695 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12700 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12701 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12702 #define uMIPS_RS2(op) uMIPS_RS(op)
12703 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12704 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12705 #define uMIPS_RS5(op) (op & 0x1f)
12707 /* Signed immediate */
12708 #define SIMM(op, start, width) \
12709 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12712 /* Zero-extended immediate */
12713 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12715 static void gen_addiur1sp(DisasContext
*ctx
)
12717 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12719 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
12722 static void gen_addiur2(DisasContext
*ctx
)
12724 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12725 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12726 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12728 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
12731 static void gen_addiusp(DisasContext
*ctx
)
12733 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
12736 if (encoded
<= 1) {
12737 decoded
= 256 + encoded
;
12738 } else if (encoded
<= 255) {
12740 } else if (encoded
<= 509) {
12741 decoded
= encoded
- 512;
12743 decoded
= encoded
- 768;
12746 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
12749 static void gen_addius5(DisasContext
*ctx
)
12751 int imm
= SIMM(ctx
->opcode
, 1, 4);
12752 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12754 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
12757 static void gen_andi16(DisasContext
*ctx
)
12759 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12760 31, 32, 63, 64, 255, 32768, 65535 };
12761 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12762 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12763 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
12765 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
12768 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
12769 int base
, int16_t offset
)
12774 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12775 generate_exception_end(ctx
, EXCP_RI
);
12779 t0
= tcg_temp_new();
12781 gen_base_offset_addr(ctx
, t0
, base
, offset
);
12783 t1
= tcg_const_tl(reglist
);
12784 t2
= tcg_const_i32(ctx
->mem_idx
);
12786 save_cpu_state(ctx
, 1);
12789 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
12792 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
12794 #ifdef TARGET_MIPS64
12796 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
12799 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
12805 tcg_temp_free_i32(t2
);
12809 static void gen_pool16c_insn(DisasContext
*ctx
)
12811 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
12812 int rs
= mmreg(ctx
->opcode
& 0x7);
12814 switch (((ctx
->opcode
) >> 4) & 0x3f) {
12819 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
12825 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
12831 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
12837 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
12844 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
12845 int offset
= ZIMM(ctx
->opcode
, 0, 4);
12847 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
12856 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
12857 int offset
= ZIMM(ctx
->opcode
, 0, 4);
12859 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
12866 int reg
= ctx
->opcode
& 0x1f;
12868 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
12874 int reg
= ctx
->opcode
& 0x1f;
12875 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
12876 /* Let normal delay slot handling in our caller take us
12877 to the branch target. */
12882 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
12883 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12887 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
12888 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12892 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
12896 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
12899 generate_exception_end(ctx
, EXCP_BREAK
);
12902 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
12903 gen_helper_do_semihosting(cpu_env
);
12905 /* XXX: not clear which exception should be raised
12906 * when in debug mode...
12908 check_insn(ctx
, ISA_MIPS32
);
12909 generate_exception_end(ctx
, EXCP_DBp
);
12912 case JRADDIUSP
+ 0:
12913 case JRADDIUSP
+ 1:
12915 int imm
= ZIMM(ctx
->opcode
, 0, 5);
12916 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
12917 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
12918 /* Let normal delay slot handling in our caller take us
12919 to the branch target. */
12923 generate_exception_end(ctx
, EXCP_RI
);
12928 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
12931 int rd
, rs
, re
, rt
;
12932 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12933 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12934 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12935 rd
= rd_enc
[enc_dest
];
12936 re
= re_enc
[enc_dest
];
12937 rs
= rs_rt_enc
[enc_rs
];
12938 rt
= rs_rt_enc
[enc_rt
];
12940 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
12942 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
12945 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
12947 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
12951 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
12953 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
12954 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
12956 switch (ctx
->opcode
& 0xf) {
12958 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
12961 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
12965 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
12966 int offset
= extract32(ctx
->opcode
, 4, 4);
12967 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
12970 case R6_JRC16
: /* JRCADDIUSP */
12971 if ((ctx
->opcode
>> 4) & 1) {
12973 int imm
= extract32(ctx
->opcode
, 5, 5);
12974 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
12975 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
12978 int rs
= extract32(ctx
->opcode
, 5, 5);
12979 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
12982 case MOVEP
... MOVEP_07
:
12983 case MOVEP_0C
... MOVEP_0F
:
12985 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12986 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12987 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
12988 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
12992 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
12995 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
12999 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
13000 int offset
= extract32(ctx
->opcode
, 4, 4);
13001 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
13004 case JALRC16
: /* BREAK16, SDBBP16 */
13005 switch (ctx
->opcode
& 0x3f) {
13007 case JALRC16
+ 0x20:
13009 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
13014 generate_exception(ctx
, EXCP_BREAK
);
13018 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
13019 gen_helper_do_semihosting(cpu_env
);
13021 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
13022 generate_exception(ctx
, EXCP_RI
);
13024 generate_exception(ctx
, EXCP_DBp
);
13031 generate_exception(ctx
, EXCP_RI
);
13036 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
13038 TCGv t0
= tcg_temp_new();
13039 TCGv t1
= tcg_temp_new();
13041 gen_load_gpr(t0
, base
);
13044 gen_load_gpr(t1
, index
);
13045 tcg_gen_shli_tl(t1
, t1
, 2);
13046 gen_op_addr_add(ctx
, t0
, t1
, t0
);
13049 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13050 gen_store_gpr(t1
, rd
);
13056 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
13057 int base
, int16_t offset
)
13061 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
13062 generate_exception_end(ctx
, EXCP_RI
);
13066 t0
= tcg_temp_new();
13067 t1
= tcg_temp_new();
13069 gen_base_offset_addr(ctx
, t0
, base
, offset
);
13074 generate_exception_end(ctx
, EXCP_RI
);
13077 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13078 gen_store_gpr(t1
, rd
);
13079 tcg_gen_movi_tl(t1
, 4);
13080 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13081 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13082 gen_store_gpr(t1
, rd
+1);
13085 gen_load_gpr(t1
, rd
);
13086 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13087 tcg_gen_movi_tl(t1
, 4);
13088 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13089 gen_load_gpr(t1
, rd
+1);
13090 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13092 #ifdef TARGET_MIPS64
13095 generate_exception_end(ctx
, EXCP_RI
);
13098 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13099 gen_store_gpr(t1
, rd
);
13100 tcg_gen_movi_tl(t1
, 8);
13101 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13102 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13103 gen_store_gpr(t1
, rd
+1);
13106 gen_load_gpr(t1
, rd
);
13107 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13108 tcg_gen_movi_tl(t1
, 8);
13109 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13110 gen_load_gpr(t1
, rd
+1);
13111 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13119 static void gen_sync(int stype
)
13121 TCGBar tcg_mo
= TCG_BAR_SC
;
13124 case 0x4: /* SYNC_WMB */
13125 tcg_mo
|= TCG_MO_ST_ST
;
13127 case 0x10: /* SYNC_MB */
13128 tcg_mo
|= TCG_MO_ALL
;
13130 case 0x11: /* SYNC_ACQUIRE */
13131 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
13133 case 0x12: /* SYNC_RELEASE */
13134 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
13136 case 0x13: /* SYNC_RMB */
13137 tcg_mo
|= TCG_MO_LD_LD
;
13140 tcg_mo
|= TCG_MO_ALL
;
13144 tcg_gen_mb(tcg_mo
);
13147 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
13149 int extension
= (ctx
->opcode
>> 6) & 0x3f;
13150 int minor
= (ctx
->opcode
>> 12) & 0xf;
13151 uint32_t mips32_op
;
13153 switch (extension
) {
13155 mips32_op
= OPC_TEQ
;
13158 mips32_op
= OPC_TGE
;
13161 mips32_op
= OPC_TGEU
;
13164 mips32_op
= OPC_TLT
;
13167 mips32_op
= OPC_TLTU
;
13170 mips32_op
= OPC_TNE
;
13172 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
13174 #ifndef CONFIG_USER_ONLY
13177 check_cp0_enabled(ctx
);
13179 /* Treat as NOP. */
13182 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
13186 check_cp0_enabled(ctx
);
13188 TCGv t0
= tcg_temp_new();
13190 gen_load_gpr(t0
, rt
);
13191 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
13197 switch (minor
& 3) {
13199 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13202 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13205 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13208 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13211 goto pool32axf_invalid
;
13215 switch (minor
& 3) {
13217 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13220 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13223 goto pool32axf_invalid
;
13229 check_insn(ctx
, ISA_MIPS32R6
);
13230 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
13233 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
13236 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
13239 mips32_op
= OPC_CLO
;
13242 mips32_op
= OPC_CLZ
;
13244 check_insn(ctx
, ISA_MIPS32
);
13245 gen_cl(ctx
, mips32_op
, rt
, rs
);
13248 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13249 gen_rdhwr(ctx
, rt
, rs
, 0);
13252 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
13255 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13256 mips32_op
= OPC_MULT
;
13259 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13260 mips32_op
= OPC_MULTU
;
13263 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13264 mips32_op
= OPC_DIV
;
13267 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13268 mips32_op
= OPC_DIVU
;
13271 check_insn(ctx
, ISA_MIPS32
);
13272 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
13275 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13276 mips32_op
= OPC_MADD
;
13279 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13280 mips32_op
= OPC_MADDU
;
13283 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13284 mips32_op
= OPC_MSUB
;
13287 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13288 mips32_op
= OPC_MSUBU
;
13290 check_insn(ctx
, ISA_MIPS32
);
13291 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
13294 goto pool32axf_invalid
;
13305 generate_exception_err(ctx
, EXCP_CpU
, 2);
13308 goto pool32axf_invalid
;
13313 case JALR
: /* JALRC */
13314 case JALR_HB
: /* JALRC_HB */
13315 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13316 /* JALRC, JALRC_HB */
13317 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
13319 /* JALR, JALR_HB */
13320 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
13321 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13326 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13327 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
13328 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13331 goto pool32axf_invalid
;
13337 check_cp0_enabled(ctx
);
13338 check_insn(ctx
, ISA_MIPS32R2
);
13339 gen_load_srsgpr(rs
, rt
);
13342 check_cp0_enabled(ctx
);
13343 check_insn(ctx
, ISA_MIPS32R2
);
13344 gen_store_srsgpr(rs
, rt
);
13347 goto pool32axf_invalid
;
13350 #ifndef CONFIG_USER_ONLY
13354 mips32_op
= OPC_TLBP
;
13357 mips32_op
= OPC_TLBR
;
13360 mips32_op
= OPC_TLBWI
;
13363 mips32_op
= OPC_TLBWR
;
13366 mips32_op
= OPC_TLBINV
;
13369 mips32_op
= OPC_TLBINVF
;
13372 mips32_op
= OPC_WAIT
;
13375 mips32_op
= OPC_DERET
;
13378 mips32_op
= OPC_ERET
;
13380 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
13383 goto pool32axf_invalid
;
13389 check_cp0_enabled(ctx
);
13391 TCGv t0
= tcg_temp_new();
13393 save_cpu_state(ctx
, 1);
13394 gen_helper_di(t0
, cpu_env
);
13395 gen_store_gpr(t0
, rs
);
13396 /* Stop translation as we may have switched the execution mode */
13397 ctx
->bstate
= BS_STOP
;
13402 check_cp0_enabled(ctx
);
13404 TCGv t0
= tcg_temp_new();
13406 save_cpu_state(ctx
, 1);
13407 gen_helper_ei(t0
, cpu_env
);
13408 gen_store_gpr(t0
, rs
);
13409 /* Stop translation as we may have switched the execution mode */
13410 ctx
->bstate
= BS_STOP
;
13415 goto pool32axf_invalid
;
13422 gen_sync(extract32(ctx
->opcode
, 16, 5));
13425 generate_exception_end(ctx
, EXCP_SYSCALL
);
13428 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
13429 gen_helper_do_semihosting(cpu_env
);
13431 check_insn(ctx
, ISA_MIPS32
);
13432 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
13433 generate_exception_end(ctx
, EXCP_RI
);
13435 generate_exception_end(ctx
, EXCP_DBp
);
13440 goto pool32axf_invalid
;
13444 switch (minor
& 3) {
13446 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
13449 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
13452 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
13455 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
13458 goto pool32axf_invalid
;
13462 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13465 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
13468 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
13471 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
13474 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
13477 goto pool32axf_invalid
;
13482 MIPS_INVAL("pool32axf");
13483 generate_exception_end(ctx
, EXCP_RI
);
13488 /* Values for microMIPS fmt field. Variable-width, depending on which
13489 formats the instruction supports. */
13508 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
13510 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
13511 uint32_t mips32_op
;
13513 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13514 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13515 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13517 switch (extension
) {
13518 case FLOAT_1BIT_FMT(CFC1
, 0):
13519 mips32_op
= OPC_CFC1
;
13521 case FLOAT_1BIT_FMT(CTC1
, 0):
13522 mips32_op
= OPC_CTC1
;
13524 case FLOAT_1BIT_FMT(MFC1
, 0):
13525 mips32_op
= OPC_MFC1
;
13527 case FLOAT_1BIT_FMT(MTC1
, 0):
13528 mips32_op
= OPC_MTC1
;
13530 case FLOAT_1BIT_FMT(MFHC1
, 0):
13531 mips32_op
= OPC_MFHC1
;
13533 case FLOAT_1BIT_FMT(MTHC1
, 0):
13534 mips32_op
= OPC_MTHC1
;
13536 gen_cp1(ctx
, mips32_op
, rt
, rs
);
13539 /* Reciprocal square root */
13540 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
13541 mips32_op
= OPC_RSQRT_S
;
13543 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
13544 mips32_op
= OPC_RSQRT_D
;
13548 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
13549 mips32_op
= OPC_SQRT_S
;
13551 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
13552 mips32_op
= OPC_SQRT_D
;
13556 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
13557 mips32_op
= OPC_RECIP_S
;
13559 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
13560 mips32_op
= OPC_RECIP_D
;
13564 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
13565 mips32_op
= OPC_FLOOR_L_S
;
13567 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
13568 mips32_op
= OPC_FLOOR_L_D
;
13570 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
13571 mips32_op
= OPC_FLOOR_W_S
;
13573 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
13574 mips32_op
= OPC_FLOOR_W_D
;
13578 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
13579 mips32_op
= OPC_CEIL_L_S
;
13581 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
13582 mips32_op
= OPC_CEIL_L_D
;
13584 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
13585 mips32_op
= OPC_CEIL_W_S
;
13587 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
13588 mips32_op
= OPC_CEIL_W_D
;
13592 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
13593 mips32_op
= OPC_TRUNC_L_S
;
13595 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
13596 mips32_op
= OPC_TRUNC_L_D
;
13598 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
13599 mips32_op
= OPC_TRUNC_W_S
;
13601 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
13602 mips32_op
= OPC_TRUNC_W_D
;
13606 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
13607 mips32_op
= OPC_ROUND_L_S
;
13609 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
13610 mips32_op
= OPC_ROUND_L_D
;
13612 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
13613 mips32_op
= OPC_ROUND_W_S
;
13615 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
13616 mips32_op
= OPC_ROUND_W_D
;
13619 /* Integer to floating-point conversion */
13620 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
13621 mips32_op
= OPC_CVT_L_S
;
13623 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
13624 mips32_op
= OPC_CVT_L_D
;
13626 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
13627 mips32_op
= OPC_CVT_W_S
;
13629 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
13630 mips32_op
= OPC_CVT_W_D
;
13633 /* Paired-foo conversions */
13634 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
13635 mips32_op
= OPC_CVT_S_PL
;
13637 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
13638 mips32_op
= OPC_CVT_S_PU
;
13640 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
13641 mips32_op
= OPC_CVT_PW_PS
;
13643 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
13644 mips32_op
= OPC_CVT_PS_PW
;
13647 /* Floating-point moves */
13648 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
13649 mips32_op
= OPC_MOV_S
;
13651 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
13652 mips32_op
= OPC_MOV_D
;
13654 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
13655 mips32_op
= OPC_MOV_PS
;
13658 /* Absolute value */
13659 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
13660 mips32_op
= OPC_ABS_S
;
13662 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
13663 mips32_op
= OPC_ABS_D
;
13665 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
13666 mips32_op
= OPC_ABS_PS
;
13670 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
13671 mips32_op
= OPC_NEG_S
;
13673 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
13674 mips32_op
= OPC_NEG_D
;
13676 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
13677 mips32_op
= OPC_NEG_PS
;
13680 /* Reciprocal square root step */
13681 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
13682 mips32_op
= OPC_RSQRT1_S
;
13684 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
13685 mips32_op
= OPC_RSQRT1_D
;
13687 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
13688 mips32_op
= OPC_RSQRT1_PS
;
13691 /* Reciprocal step */
13692 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
13693 mips32_op
= OPC_RECIP1_S
;
13695 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
13696 mips32_op
= OPC_RECIP1_S
;
13698 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
13699 mips32_op
= OPC_RECIP1_PS
;
13702 /* Conversions from double */
13703 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
13704 mips32_op
= OPC_CVT_D_S
;
13706 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
13707 mips32_op
= OPC_CVT_D_W
;
13709 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
13710 mips32_op
= OPC_CVT_D_L
;
13713 /* Conversions from single */
13714 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
13715 mips32_op
= OPC_CVT_S_D
;
13717 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
13718 mips32_op
= OPC_CVT_S_W
;
13720 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
13721 mips32_op
= OPC_CVT_S_L
;
13723 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
13726 /* Conditional moves on floating-point codes */
13727 case COND_FLOAT_MOV(MOVT
, 0):
13728 case COND_FLOAT_MOV(MOVT
, 1):
13729 case COND_FLOAT_MOV(MOVT
, 2):
13730 case COND_FLOAT_MOV(MOVT
, 3):
13731 case COND_FLOAT_MOV(MOVT
, 4):
13732 case COND_FLOAT_MOV(MOVT
, 5):
13733 case COND_FLOAT_MOV(MOVT
, 6):
13734 case COND_FLOAT_MOV(MOVT
, 7):
13735 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13736 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
13738 case COND_FLOAT_MOV(MOVF
, 0):
13739 case COND_FLOAT_MOV(MOVF
, 1):
13740 case COND_FLOAT_MOV(MOVF
, 2):
13741 case COND_FLOAT_MOV(MOVF
, 3):
13742 case COND_FLOAT_MOV(MOVF
, 4):
13743 case COND_FLOAT_MOV(MOVF
, 5):
13744 case COND_FLOAT_MOV(MOVF
, 6):
13745 case COND_FLOAT_MOV(MOVF
, 7):
13746 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13747 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
13750 MIPS_INVAL("pool32fxf");
13751 generate_exception_end(ctx
, EXCP_RI
);
13756 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13760 int rt
, rs
, rd
, rr
;
13762 uint32_t op
, minor
, mips32_op
;
13763 uint32_t cond
, fmt
, cc
;
13765 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
13766 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
13768 rt
= (ctx
->opcode
>> 21) & 0x1f;
13769 rs
= (ctx
->opcode
>> 16) & 0x1f;
13770 rd
= (ctx
->opcode
>> 11) & 0x1f;
13771 rr
= (ctx
->opcode
>> 6) & 0x1f;
13772 imm
= (int16_t) ctx
->opcode
;
13774 op
= (ctx
->opcode
>> 26) & 0x3f;
13777 minor
= ctx
->opcode
& 0x3f;
13780 minor
= (ctx
->opcode
>> 6) & 0xf;
13783 mips32_op
= OPC_SLL
;
13786 mips32_op
= OPC_SRA
;
13789 mips32_op
= OPC_SRL
;
13792 mips32_op
= OPC_ROTR
;
13794 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
13797 check_insn(ctx
, ISA_MIPS32R6
);
13798 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
13801 check_insn(ctx
, ISA_MIPS32R6
);
13802 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
13805 check_insn(ctx
, ISA_MIPS32R6
);
13806 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
13809 goto pool32a_invalid
;
13813 minor
= (ctx
->opcode
>> 6) & 0xf;
13817 mips32_op
= OPC_ADD
;
13820 mips32_op
= OPC_ADDU
;
13823 mips32_op
= OPC_SUB
;
13826 mips32_op
= OPC_SUBU
;
13829 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13830 mips32_op
= OPC_MUL
;
13832 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
13836 mips32_op
= OPC_SLLV
;
13839 mips32_op
= OPC_SRLV
;
13842 mips32_op
= OPC_SRAV
;
13845 mips32_op
= OPC_ROTRV
;
13847 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
13849 /* Logical operations */
13851 mips32_op
= OPC_AND
;
13854 mips32_op
= OPC_OR
;
13857 mips32_op
= OPC_NOR
;
13860 mips32_op
= OPC_XOR
;
13862 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
13864 /* Set less than */
13866 mips32_op
= OPC_SLT
;
13869 mips32_op
= OPC_SLTU
;
13871 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
13874 goto pool32a_invalid
;
13878 minor
= (ctx
->opcode
>> 6) & 0xf;
13880 /* Conditional moves */
13881 case MOVN
: /* MUL */
13882 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13884 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
13887 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
13890 case MOVZ
: /* MUH */
13891 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13893 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
13896 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
13900 check_insn(ctx
, ISA_MIPS32R6
);
13901 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
13904 check_insn(ctx
, ISA_MIPS32R6
);
13905 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
13907 case LWXS
: /* DIV */
13908 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13910 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
13913 gen_ldxs(ctx
, rs
, rt
, rd
);
13917 check_insn(ctx
, ISA_MIPS32R6
);
13918 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
13921 check_insn(ctx
, ISA_MIPS32R6
);
13922 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
13925 check_insn(ctx
, ISA_MIPS32R6
);
13926 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
13929 goto pool32a_invalid
;
13933 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
13936 check_insn(ctx
, ISA_MIPS32R6
);
13937 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
13938 extract32(ctx
->opcode
, 9, 2));
13941 check_insn(ctx
, ISA_MIPS32R6
);
13942 gen_align(ctx
, OPC_ALIGN
, rd
, rs
, rt
,
13943 extract32(ctx
->opcode
, 9, 2));
13946 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
13949 gen_pool32axf(env
, ctx
, rt
, rs
);
13952 generate_exception_end(ctx
, EXCP_BREAK
);
13955 check_insn(ctx
, ISA_MIPS32R6
);
13956 generate_exception_end(ctx
, EXCP_RI
);
13960 MIPS_INVAL("pool32a");
13961 generate_exception_end(ctx
, EXCP_RI
);
13966 minor
= (ctx
->opcode
>> 12) & 0xf;
13969 check_cp0_enabled(ctx
);
13970 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
13971 gen_cache_operation(ctx
, rt
, rs
, imm
);
13976 /* COP2: Not implemented. */
13977 generate_exception_err(ctx
, EXCP_CpU
, 2);
13979 #ifdef TARGET_MIPS64
13982 check_insn(ctx
, ISA_MIPS3
);
13983 check_mips_64(ctx
);
13988 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13990 #ifdef TARGET_MIPS64
13993 check_insn(ctx
, ISA_MIPS3
);
13994 check_mips_64(ctx
);
13999 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14002 MIPS_INVAL("pool32b");
14003 generate_exception_end(ctx
, EXCP_RI
);
14008 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
14009 minor
= ctx
->opcode
& 0x3f;
14010 check_cp1_enabled(ctx
);
14013 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14014 mips32_op
= OPC_ALNV_PS
;
14017 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14018 mips32_op
= OPC_MADD_S
;
14021 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14022 mips32_op
= OPC_MADD_D
;
14025 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14026 mips32_op
= OPC_MADD_PS
;
14029 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14030 mips32_op
= OPC_MSUB_S
;
14033 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14034 mips32_op
= OPC_MSUB_D
;
14037 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14038 mips32_op
= OPC_MSUB_PS
;
14041 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14042 mips32_op
= OPC_NMADD_S
;
14045 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14046 mips32_op
= OPC_NMADD_D
;
14049 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14050 mips32_op
= OPC_NMADD_PS
;
14053 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14054 mips32_op
= OPC_NMSUB_S
;
14057 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14058 mips32_op
= OPC_NMSUB_D
;
14061 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14062 mips32_op
= OPC_NMSUB_PS
;
14064 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
14066 case CABS_COND_FMT
:
14067 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14068 cond
= (ctx
->opcode
>> 6) & 0xf;
14069 cc
= (ctx
->opcode
>> 13) & 0x7;
14070 fmt
= (ctx
->opcode
>> 10) & 0x3;
14073 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
14076 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
14079 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
14082 goto pool32f_invalid
;
14086 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14087 cond
= (ctx
->opcode
>> 6) & 0xf;
14088 cc
= (ctx
->opcode
>> 13) & 0x7;
14089 fmt
= (ctx
->opcode
>> 10) & 0x3;
14092 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
14095 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
14098 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
14101 goto pool32f_invalid
;
14105 check_insn(ctx
, ISA_MIPS32R6
);
14106 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
14109 check_insn(ctx
, ISA_MIPS32R6
);
14110 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
14113 gen_pool32fxf(ctx
, rt
, rs
);
14117 switch ((ctx
->opcode
>> 6) & 0x7) {
14119 mips32_op
= OPC_PLL_PS
;
14122 mips32_op
= OPC_PLU_PS
;
14125 mips32_op
= OPC_PUL_PS
;
14128 mips32_op
= OPC_PUU_PS
;
14131 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14132 mips32_op
= OPC_CVT_PS_S
;
14134 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14137 goto pool32f_invalid
;
14141 check_insn(ctx
, ISA_MIPS32R6
);
14142 switch ((ctx
->opcode
>> 9) & 0x3) {
14144 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
14147 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
14150 goto pool32f_invalid
;
14155 switch ((ctx
->opcode
>> 6) & 0x7) {
14157 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14158 mips32_op
= OPC_LWXC1
;
14161 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14162 mips32_op
= OPC_SWXC1
;
14165 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14166 mips32_op
= OPC_LDXC1
;
14169 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14170 mips32_op
= OPC_SDXC1
;
14173 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14174 mips32_op
= OPC_LUXC1
;
14177 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14178 mips32_op
= OPC_SUXC1
;
14180 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
14183 goto pool32f_invalid
;
14187 check_insn(ctx
, ISA_MIPS32R6
);
14188 switch ((ctx
->opcode
>> 9) & 0x3) {
14190 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
14193 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
14196 goto pool32f_invalid
;
14201 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14202 fmt
= (ctx
->opcode
>> 9) & 0x3;
14203 switch ((ctx
->opcode
>> 6) & 0x7) {
14207 mips32_op
= OPC_RSQRT2_S
;
14210 mips32_op
= OPC_RSQRT2_D
;
14213 mips32_op
= OPC_RSQRT2_PS
;
14216 goto pool32f_invalid
;
14222 mips32_op
= OPC_RECIP2_S
;
14225 mips32_op
= OPC_RECIP2_D
;
14228 mips32_op
= OPC_RECIP2_PS
;
14231 goto pool32f_invalid
;
14235 mips32_op
= OPC_ADDR_PS
;
14238 mips32_op
= OPC_MULR_PS
;
14240 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14243 goto pool32f_invalid
;
14247 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14248 cc
= (ctx
->opcode
>> 13) & 0x7;
14249 fmt
= (ctx
->opcode
>> 9) & 0x3;
14250 switch ((ctx
->opcode
>> 6) & 0x7) {
14251 case MOVF_FMT
: /* RINT_FMT */
14252 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14256 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
14259 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
14262 goto pool32f_invalid
;
14268 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
14271 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
14275 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
14278 goto pool32f_invalid
;
14282 case MOVT_FMT
: /* CLASS_FMT */
14283 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14287 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
14290 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
14293 goto pool32f_invalid
;
14299 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
14302 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
14306 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
14309 goto pool32f_invalid
;
14314 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14317 goto pool32f_invalid
;
14320 #define FINSN_3ARG_SDPS(prfx) \
14321 switch ((ctx->opcode >> 8) & 0x3) { \
14323 mips32_op = OPC_##prfx##_S; \
14326 mips32_op = OPC_##prfx##_D; \
14328 case FMT_SDPS_PS: \
14330 mips32_op = OPC_##prfx##_PS; \
14333 goto pool32f_invalid; \
14336 check_insn(ctx
, ISA_MIPS32R6
);
14337 switch ((ctx
->opcode
>> 9) & 0x3) {
14339 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
14342 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
14345 goto pool32f_invalid
;
14349 check_insn(ctx
, ISA_MIPS32R6
);
14350 switch ((ctx
->opcode
>> 9) & 0x3) {
14352 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
14355 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
14358 goto pool32f_invalid
;
14362 /* regular FP ops */
14363 switch ((ctx
->opcode
>> 6) & 0x3) {
14365 FINSN_3ARG_SDPS(ADD
);
14368 FINSN_3ARG_SDPS(SUB
);
14371 FINSN_3ARG_SDPS(MUL
);
14374 fmt
= (ctx
->opcode
>> 8) & 0x3;
14376 mips32_op
= OPC_DIV_D
;
14377 } else if (fmt
== 0) {
14378 mips32_op
= OPC_DIV_S
;
14380 goto pool32f_invalid
;
14384 goto pool32f_invalid
;
14389 switch ((ctx
->opcode
>> 6) & 0x7) {
14390 case MOVN_FMT
: /* SELNEZ_FMT */
14391 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14393 switch ((ctx
->opcode
>> 9) & 0x3) {
14395 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
14398 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
14401 goto pool32f_invalid
;
14405 FINSN_3ARG_SDPS(MOVN
);
14409 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14410 FINSN_3ARG_SDPS(MOVN
);
14412 case MOVZ_FMT
: /* SELEQZ_FMT */
14413 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14415 switch ((ctx
->opcode
>> 9) & 0x3) {
14417 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
14420 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
14423 goto pool32f_invalid
;
14427 FINSN_3ARG_SDPS(MOVZ
);
14431 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14432 FINSN_3ARG_SDPS(MOVZ
);
14435 check_insn(ctx
, ISA_MIPS32R6
);
14436 switch ((ctx
->opcode
>> 9) & 0x3) {
14438 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
14441 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
14444 goto pool32f_invalid
;
14448 check_insn(ctx
, ISA_MIPS32R6
);
14449 switch ((ctx
->opcode
>> 9) & 0x3) {
14451 mips32_op
= OPC_MADDF_S
;
14454 mips32_op
= OPC_MADDF_D
;
14457 goto pool32f_invalid
;
14461 check_insn(ctx
, ISA_MIPS32R6
);
14462 switch ((ctx
->opcode
>> 9) & 0x3) {
14464 mips32_op
= OPC_MSUBF_S
;
14467 mips32_op
= OPC_MSUBF_D
;
14470 goto pool32f_invalid
;
14474 goto pool32f_invalid
;
14478 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14482 MIPS_INVAL("pool32f");
14483 generate_exception_end(ctx
, EXCP_RI
);
14487 generate_exception_err(ctx
, EXCP_CpU
, 1);
14491 minor
= (ctx
->opcode
>> 21) & 0x1f;
14494 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14495 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
14498 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14499 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
14500 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14503 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14504 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
14505 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14508 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14509 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
14512 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14513 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
14514 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14517 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14518 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
14519 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14522 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14523 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
14526 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14527 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
14531 case TLTI
: /* BC1EQZC */
14532 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14534 check_cp1_enabled(ctx
);
14535 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
14538 mips32_op
= OPC_TLTI
;
14542 case TGEI
: /* BC1NEZC */
14543 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14545 check_cp1_enabled(ctx
);
14546 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
14549 mips32_op
= OPC_TGEI
;
14554 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14555 mips32_op
= OPC_TLTIU
;
14558 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14559 mips32_op
= OPC_TGEIU
;
14561 case TNEI
: /* SYNCI */
14562 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14564 /* Break the TB to be able to sync copied instructions
14566 ctx
->bstate
= BS_STOP
;
14569 mips32_op
= OPC_TNEI
;
14574 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14575 mips32_op
= OPC_TEQI
;
14577 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
14582 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14583 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
14584 4, rs
, 0, imm
<< 1, 0);
14585 /* Compact branches don't have a delay slot, so just let
14586 the normal delay slot handling take us to the branch
14590 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14591 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
14594 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14595 /* Break the TB to be able to sync copied instructions
14597 ctx
->bstate
= BS_STOP
;
14601 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14602 /* COP2: Not implemented. */
14603 generate_exception_err(ctx
, EXCP_CpU
, 2);
14606 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14607 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
14610 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14611 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
14614 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14615 mips32_op
= OPC_BC1FANY4
;
14618 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14619 mips32_op
= OPC_BC1TANY4
;
14622 check_insn(ctx
, ASE_MIPS3D
);
14625 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14626 check_cp1_enabled(ctx
);
14627 gen_compute_branch1(ctx
, mips32_op
,
14628 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
14630 generate_exception_err(ctx
, EXCP_CpU
, 1);
14635 /* MIPS DSP: not implemented */
14638 MIPS_INVAL("pool32i");
14639 generate_exception_end(ctx
, EXCP_RI
);
14644 minor
= (ctx
->opcode
>> 12) & 0xf;
14645 offset
= sextract32(ctx
->opcode
, 0,
14646 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
14649 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14650 mips32_op
= OPC_LWL
;
14653 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14654 mips32_op
= OPC_SWL
;
14657 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14658 mips32_op
= OPC_LWR
;
14661 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14662 mips32_op
= OPC_SWR
;
14664 #if defined(TARGET_MIPS64)
14666 check_insn(ctx
, ISA_MIPS3
);
14667 check_mips_64(ctx
);
14668 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14669 mips32_op
= OPC_LDL
;
14672 check_insn(ctx
, ISA_MIPS3
);
14673 check_mips_64(ctx
);
14674 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14675 mips32_op
= OPC_SDL
;
14678 check_insn(ctx
, ISA_MIPS3
);
14679 check_mips_64(ctx
);
14680 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14681 mips32_op
= OPC_LDR
;
14684 check_insn(ctx
, ISA_MIPS3
);
14685 check_mips_64(ctx
);
14686 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14687 mips32_op
= OPC_SDR
;
14690 check_insn(ctx
, ISA_MIPS3
);
14691 check_mips_64(ctx
);
14692 mips32_op
= OPC_LWU
;
14695 check_insn(ctx
, ISA_MIPS3
);
14696 check_mips_64(ctx
);
14697 mips32_op
= OPC_LLD
;
14701 mips32_op
= OPC_LL
;
14704 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
14707 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14710 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, offset
);
14712 #if defined(TARGET_MIPS64)
14714 check_insn(ctx
, ISA_MIPS3
);
14715 check_mips_64(ctx
);
14716 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, offset
);
14720 /* Treat as no-op */
14721 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
14722 /* hint codes 24-31 are reserved and signal RI */
14723 generate_exception(ctx
, EXCP_RI
);
14727 MIPS_INVAL("pool32c");
14728 generate_exception_end(ctx
, EXCP_RI
);
14732 case ADDI32
: /* AUI, LUI */
14733 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14735 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
14738 mips32_op
= OPC_ADDI
;
14743 mips32_op
= OPC_ADDIU
;
14745 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14748 /* Logical operations */
14750 mips32_op
= OPC_ORI
;
14753 mips32_op
= OPC_XORI
;
14756 mips32_op
= OPC_ANDI
;
14758 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14761 /* Set less than immediate */
14763 mips32_op
= OPC_SLTI
;
14766 mips32_op
= OPC_SLTIU
;
14768 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14771 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14772 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
14773 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
14774 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14776 case JALS32
: /* BOVC, BEQC, BEQZALC */
14777 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14780 mips32_op
= OPC_BOVC
;
14781 } else if (rs
< rt
&& rs
== 0) {
14783 mips32_op
= OPC_BEQZALC
;
14786 mips32_op
= OPC_BEQC
;
14788 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14791 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
14792 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
14793 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14796 case BEQ32
: /* BC */
14797 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14799 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
14800 sextract32(ctx
->opcode
<< 1, 0, 27));
14803 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
14806 case BNE32
: /* BALC */
14807 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14809 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
14810 sextract32(ctx
->opcode
<< 1, 0, 27));
14813 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
14816 case J32
: /* BGTZC, BLTZC, BLTC */
14817 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14818 if (rs
== 0 && rt
!= 0) {
14820 mips32_op
= OPC_BGTZC
;
14821 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
14823 mips32_op
= OPC_BLTZC
;
14826 mips32_op
= OPC_BLTC
;
14828 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14831 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
14832 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
14835 case JAL32
: /* BLEZC, BGEZC, BGEC */
14836 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14837 if (rs
== 0 && rt
!= 0) {
14839 mips32_op
= OPC_BLEZC
;
14840 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
14842 mips32_op
= OPC_BGEZC
;
14845 mips32_op
= OPC_BGEC
;
14847 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14850 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
14851 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
14852 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14855 /* Floating point (COP1) */
14857 mips32_op
= OPC_LWC1
;
14860 mips32_op
= OPC_LDC1
;
14863 mips32_op
= OPC_SWC1
;
14866 mips32_op
= OPC_SDC1
;
14868 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
14870 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14871 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14872 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14873 switch ((ctx
->opcode
>> 16) & 0x1f) {
14874 case ADDIUPC_00
... ADDIUPC_07
:
14875 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->pc
& ~0x3, rt
);
14878 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->pc
, rt
);
14881 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->pc
, rt
);
14883 case LWPC_08
... LWPC_0F
:
14884 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->pc
& ~0x3, rt
);
14887 generate_exception(ctx
, EXCP_RI
);
14892 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
14893 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
14895 gen_addiupc(ctx
, reg
, offset
, 0, 0);
14898 case BNVC
: /* BNEC, BNEZALC */
14899 check_insn(ctx
, ISA_MIPS32R6
);
14902 mips32_op
= OPC_BNVC
;
14903 } else if (rs
< rt
&& rs
== 0) {
14905 mips32_op
= OPC_BNEZALC
;
14908 mips32_op
= OPC_BNEC
;
14910 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14912 case R6_BNEZC
: /* JIALC */
14913 check_insn(ctx
, ISA_MIPS32R6
);
14916 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
14917 sextract32(ctx
->opcode
<< 1, 0, 22));
14920 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
14923 case R6_BEQZC
: /* JIC */
14924 check_insn(ctx
, ISA_MIPS32R6
);
14927 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
14928 sextract32(ctx
->opcode
<< 1, 0, 22));
14931 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
14934 case BLEZALC
: /* BGEZALC, BGEUC */
14935 check_insn(ctx
, ISA_MIPS32R6
);
14936 if (rs
== 0 && rt
!= 0) {
14938 mips32_op
= OPC_BLEZALC
;
14939 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
14941 mips32_op
= OPC_BGEZALC
;
14944 mips32_op
= OPC_BGEUC
;
14946 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14948 case BGTZALC
: /* BLTZALC, BLTUC */
14949 check_insn(ctx
, ISA_MIPS32R6
);
14950 if (rs
== 0 && rt
!= 0) {
14952 mips32_op
= OPC_BGTZALC
;
14953 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
14955 mips32_op
= OPC_BLTZALC
;
14958 mips32_op
= OPC_BLTUC
;
14960 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14962 /* Loads and stores */
14964 mips32_op
= OPC_LB
;
14967 mips32_op
= OPC_LBU
;
14970 mips32_op
= OPC_LH
;
14973 mips32_op
= OPC_LHU
;
14976 mips32_op
= OPC_LW
;
14978 #ifdef TARGET_MIPS64
14980 check_insn(ctx
, ISA_MIPS3
);
14981 check_mips_64(ctx
);
14982 mips32_op
= OPC_LD
;
14985 check_insn(ctx
, ISA_MIPS3
);
14986 check_mips_64(ctx
);
14987 mips32_op
= OPC_SD
;
14991 mips32_op
= OPC_SB
;
14994 mips32_op
= OPC_SH
;
14997 mips32_op
= OPC_SW
;
15000 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
15003 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
15006 generate_exception_end(ctx
, EXCP_RI
);
15011 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
15015 /* make sure instructions are on a halfword boundary */
15016 if (ctx
->pc
& 0x1) {
15017 env
->CP0_BadVAddr
= ctx
->pc
;
15018 generate_exception_end(ctx
, EXCP_AdEL
);
15022 op
= (ctx
->opcode
>> 10) & 0x3f;
15023 /* Enforce properly-sized instructions in a delay slot */
15024 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
15025 switch (op
& 0x7) { /* MSB-3..MSB-5 */
15027 /* POOL32A, POOL32B, POOL32I, POOL32C */
15029 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15031 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15033 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15035 /* LB32, LH32, LWC132, LDC132, LW32 */
15036 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
15037 generate_exception_end(ctx
, EXCP_RI
);
15042 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15044 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15046 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15047 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
15048 generate_exception_end(ctx
, EXCP_RI
);
15058 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15059 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
15060 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
15063 switch (ctx
->opcode
& 0x1) {
15071 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15072 /* In the Release 6 the register number location in
15073 * the instruction encoding has changed.
15075 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
15077 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
15083 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15084 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15085 int amount
= (ctx
->opcode
>> 1) & 0x7;
15087 amount
= amount
== 0 ? 8 : amount
;
15089 switch (ctx
->opcode
& 0x1) {
15098 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
15102 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15103 gen_pool16c_r6_insn(ctx
);
15105 gen_pool16c_insn(ctx
);
15110 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15111 int rb
= 28; /* GP */
15112 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
15114 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15118 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15119 if (ctx
->opcode
& 1) {
15120 generate_exception_end(ctx
, EXCP_RI
);
15123 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15124 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15125 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
15126 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15131 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15132 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15133 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
15134 offset
= (offset
== 0xf ? -1 : offset
);
15136 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
15141 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15142 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15143 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
15145 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
15150 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15151 int rb
= 29; /* SP */
15152 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
15154 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15159 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15160 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15161 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
15163 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15168 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15169 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15170 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
15172 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
15177 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15178 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15179 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
15181 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
15186 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15187 int rb
= 29; /* SP */
15188 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
15190 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
15195 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15196 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15197 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
15199 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
15204 int rd
= uMIPS_RD5(ctx
->opcode
);
15205 int rs
= uMIPS_RS5(ctx
->opcode
);
15207 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
15214 switch (ctx
->opcode
& 0x1) {
15224 switch (ctx
->opcode
& 0x1) {
15229 gen_addiur1sp(ctx
);
15233 case B16
: /* BC16 */
15234 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
15235 sextract32(ctx
->opcode
, 0, 10) << 1,
15236 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
15238 case BNEZ16
: /* BNEZC16 */
15239 case BEQZ16
: /* BEQZC16 */
15240 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
15241 mmreg(uMIPS_RD(ctx
->opcode
)),
15242 0, sextract32(ctx
->opcode
, 0, 7) << 1,
15243 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
15248 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
15249 int imm
= ZIMM(ctx
->opcode
, 0, 7);
15251 imm
= (imm
== 0x7f ? -1 : imm
);
15252 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
15258 generate_exception_end(ctx
, EXCP_RI
);
15261 decode_micromips32_opc(env
, ctx
);
15268 /* SmartMIPS extension to MIPS32 */
15270 #if defined(TARGET_MIPS64)
15272 /* MDMX extension to MIPS64 */
15276 /* MIPSDSP functions. */
15277 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
15278 int rd
, int base
, int offset
)
15283 t0
= tcg_temp_new();
15286 gen_load_gpr(t0
, offset
);
15287 } else if (offset
== 0) {
15288 gen_load_gpr(t0
, base
);
15290 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
15295 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
15296 gen_store_gpr(t0
, rd
);
15299 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
15300 gen_store_gpr(t0
, rd
);
15303 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
15304 gen_store_gpr(t0
, rd
);
15306 #if defined(TARGET_MIPS64)
15308 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
15309 gen_store_gpr(t0
, rd
);
15316 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15317 int ret
, int v1
, int v2
)
15323 /* Treat as NOP. */
15327 v1_t
= tcg_temp_new();
15328 v2_t
= tcg_temp_new();
15330 gen_load_gpr(v1_t
, v1
);
15331 gen_load_gpr(v2_t
, v2
);
15334 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15335 case OPC_MULT_G_2E
:
15339 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15341 case OPC_ADDUH_R_QB
:
15342 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15345 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15347 case OPC_ADDQH_R_PH
:
15348 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15351 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15353 case OPC_ADDQH_R_W
:
15354 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15357 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15359 case OPC_SUBUH_R_QB
:
15360 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15363 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15365 case OPC_SUBQH_R_PH
:
15366 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15369 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15371 case OPC_SUBQH_R_W
:
15372 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15376 case OPC_ABSQ_S_PH_DSP
:
15378 case OPC_ABSQ_S_QB
:
15380 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
15382 case OPC_ABSQ_S_PH
:
15384 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
15388 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
15390 case OPC_PRECEQ_W_PHL
:
15392 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
15393 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15395 case OPC_PRECEQ_W_PHR
:
15397 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
15398 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
15399 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15401 case OPC_PRECEQU_PH_QBL
:
15403 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
15405 case OPC_PRECEQU_PH_QBR
:
15407 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
15409 case OPC_PRECEQU_PH_QBLA
:
15411 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
15413 case OPC_PRECEQU_PH_QBRA
:
15415 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
15417 case OPC_PRECEU_PH_QBL
:
15419 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
15421 case OPC_PRECEU_PH_QBR
:
15423 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
15425 case OPC_PRECEU_PH_QBLA
:
15427 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
15429 case OPC_PRECEU_PH_QBRA
:
15431 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
15435 case OPC_ADDU_QB_DSP
:
15439 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15441 case OPC_ADDQ_S_PH
:
15443 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15447 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15451 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15453 case OPC_ADDU_S_QB
:
15455 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15459 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15461 case OPC_ADDU_S_PH
:
15463 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15467 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15469 case OPC_SUBQ_S_PH
:
15471 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15475 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15479 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15481 case OPC_SUBU_S_QB
:
15483 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15487 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15489 case OPC_SUBU_S_PH
:
15491 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15495 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15499 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15503 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
15505 case OPC_RADDU_W_QB
:
15507 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
15511 case OPC_CMPU_EQ_QB_DSP
:
15513 case OPC_PRECR_QB_PH
:
15515 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15517 case OPC_PRECRQ_QB_PH
:
15519 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15521 case OPC_PRECR_SRA_PH_W
:
15524 TCGv_i32 sa_t
= tcg_const_i32(v2
);
15525 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
15527 tcg_temp_free_i32(sa_t
);
15530 case OPC_PRECR_SRA_R_PH_W
:
15533 TCGv_i32 sa_t
= tcg_const_i32(v2
);
15534 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
15536 tcg_temp_free_i32(sa_t
);
15539 case OPC_PRECRQ_PH_W
:
15541 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15543 case OPC_PRECRQ_RS_PH_W
:
15545 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15547 case OPC_PRECRQU_S_QB_PH
:
15549 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15553 #ifdef TARGET_MIPS64
15554 case OPC_ABSQ_S_QH_DSP
:
15556 case OPC_PRECEQ_L_PWL
:
15558 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
15560 case OPC_PRECEQ_L_PWR
:
15562 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
15564 case OPC_PRECEQ_PW_QHL
:
15566 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
15568 case OPC_PRECEQ_PW_QHR
:
15570 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
15572 case OPC_PRECEQ_PW_QHLA
:
15574 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
15576 case OPC_PRECEQ_PW_QHRA
:
15578 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
15580 case OPC_PRECEQU_QH_OBL
:
15582 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
15584 case OPC_PRECEQU_QH_OBR
:
15586 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
15588 case OPC_PRECEQU_QH_OBLA
:
15590 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
15592 case OPC_PRECEQU_QH_OBRA
:
15594 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
15596 case OPC_PRECEU_QH_OBL
:
15598 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
15600 case OPC_PRECEU_QH_OBR
:
15602 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
15604 case OPC_PRECEU_QH_OBLA
:
15606 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
15608 case OPC_PRECEU_QH_OBRA
:
15610 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
15612 case OPC_ABSQ_S_OB
:
15614 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
15616 case OPC_ABSQ_S_PW
:
15618 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
15620 case OPC_ABSQ_S_QH
:
15622 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
15626 case OPC_ADDU_OB_DSP
:
15628 case OPC_RADDU_L_OB
:
15630 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
15634 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15636 case OPC_SUBQ_S_PW
:
15638 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15642 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15644 case OPC_SUBQ_S_QH
:
15646 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15650 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15652 case OPC_SUBU_S_OB
:
15654 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15658 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15660 case OPC_SUBU_S_QH
:
15662 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15666 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15668 case OPC_SUBUH_R_OB
:
15670 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15674 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15676 case OPC_ADDQ_S_PW
:
15678 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15682 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15684 case OPC_ADDQ_S_QH
:
15686 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15690 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15692 case OPC_ADDU_S_OB
:
15694 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15698 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15700 case OPC_ADDU_S_QH
:
15702 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15706 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15708 case OPC_ADDUH_R_OB
:
15710 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15714 case OPC_CMPU_EQ_OB_DSP
:
15716 case OPC_PRECR_OB_QH
:
15718 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
15720 case OPC_PRECR_SRA_QH_PW
:
15723 TCGv_i32 ret_t
= tcg_const_i32(ret
);
15724 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
15725 tcg_temp_free_i32(ret_t
);
15728 case OPC_PRECR_SRA_R_QH_PW
:
15731 TCGv_i32 sa_v
= tcg_const_i32(ret
);
15732 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
15733 tcg_temp_free_i32(sa_v
);
15736 case OPC_PRECRQ_OB_QH
:
15738 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
15740 case OPC_PRECRQ_PW_L
:
15742 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
15744 case OPC_PRECRQ_QH_PW
:
15746 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
15748 case OPC_PRECRQ_RS_QH_PW
:
15750 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15752 case OPC_PRECRQU_S_OB_QH
:
15754 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15761 tcg_temp_free(v1_t
);
15762 tcg_temp_free(v2_t
);
15765 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
15766 int ret
, int v1
, int v2
)
15774 /* Treat as NOP. */
15778 t0
= tcg_temp_new();
15779 v1_t
= tcg_temp_new();
15780 v2_t
= tcg_temp_new();
15782 tcg_gen_movi_tl(t0
, v1
);
15783 gen_load_gpr(v1_t
, v1
);
15784 gen_load_gpr(v2_t
, v2
);
15787 case OPC_SHLL_QB_DSP
:
15789 op2
= MASK_SHLL_QB(ctx
->opcode
);
15793 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
15797 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15801 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
15805 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15807 case OPC_SHLL_S_PH
:
15809 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
15811 case OPC_SHLLV_S_PH
:
15813 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15817 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
15819 case OPC_SHLLV_S_W
:
15821 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15825 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
15829 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15833 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
15837 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15841 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
15843 case OPC_SHRA_R_QB
:
15845 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
15849 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15851 case OPC_SHRAV_R_QB
:
15853 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15857 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
15859 case OPC_SHRA_R_PH
:
15861 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
15865 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15867 case OPC_SHRAV_R_PH
:
15869 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15873 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
15875 case OPC_SHRAV_R_W
:
15877 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15879 default: /* Invalid */
15880 MIPS_INVAL("MASK SHLL.QB");
15881 generate_exception_end(ctx
, EXCP_RI
);
15886 #ifdef TARGET_MIPS64
15887 case OPC_SHLL_OB_DSP
:
15888 op2
= MASK_SHLL_OB(ctx
->opcode
);
15892 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
15896 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
15898 case OPC_SHLL_S_PW
:
15900 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
15902 case OPC_SHLLV_S_PW
:
15904 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
15908 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
15912 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
15916 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
15920 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
15922 case OPC_SHLL_S_QH
:
15924 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
15926 case OPC_SHLLV_S_QH
:
15928 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
15932 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
15936 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
15938 case OPC_SHRA_R_OB
:
15940 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
15942 case OPC_SHRAV_R_OB
:
15944 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
15948 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
15952 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
15954 case OPC_SHRA_R_PW
:
15956 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
15958 case OPC_SHRAV_R_PW
:
15960 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
15964 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
15968 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
15970 case OPC_SHRA_R_QH
:
15972 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
15974 case OPC_SHRAV_R_QH
:
15976 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
15980 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
15984 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
15988 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
15992 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
15994 default: /* Invalid */
15995 MIPS_INVAL("MASK SHLL.OB");
15996 generate_exception_end(ctx
, EXCP_RI
);
16004 tcg_temp_free(v1_t
);
16005 tcg_temp_free(v2_t
);
16008 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16009 int ret
, int v1
, int v2
, int check_ret
)
16015 if ((ret
== 0) && (check_ret
== 1)) {
16016 /* Treat as NOP. */
16020 t0
= tcg_temp_new_i32();
16021 v1_t
= tcg_temp_new();
16022 v2_t
= tcg_temp_new();
16024 tcg_gen_movi_i32(t0
, ret
);
16025 gen_load_gpr(v1_t
, v1
);
16026 gen_load_gpr(v2_t
, v2
);
16029 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16030 * the same mask and op1. */
16031 case OPC_MULT_G_2E
:
16035 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16038 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16041 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16043 case OPC_MULQ_RS_W
:
16044 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16048 case OPC_DPA_W_PH_DSP
:
16050 case OPC_DPAU_H_QBL
:
16052 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
16054 case OPC_DPAU_H_QBR
:
16056 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
16058 case OPC_DPSU_H_QBL
:
16060 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
16062 case OPC_DPSU_H_QBR
:
16064 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
16068 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16070 case OPC_DPAX_W_PH
:
16072 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16074 case OPC_DPAQ_S_W_PH
:
16076 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16078 case OPC_DPAQX_S_W_PH
:
16080 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16082 case OPC_DPAQX_SA_W_PH
:
16084 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16088 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16090 case OPC_DPSX_W_PH
:
16092 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16094 case OPC_DPSQ_S_W_PH
:
16096 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16098 case OPC_DPSQX_S_W_PH
:
16100 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16102 case OPC_DPSQX_SA_W_PH
:
16104 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16106 case OPC_MULSAQ_S_W_PH
:
16108 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16110 case OPC_DPAQ_SA_L_W
:
16112 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
16114 case OPC_DPSQ_SA_L_W
:
16116 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
16118 case OPC_MAQ_S_W_PHL
:
16120 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
16122 case OPC_MAQ_S_W_PHR
:
16124 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
16126 case OPC_MAQ_SA_W_PHL
:
16128 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
16130 case OPC_MAQ_SA_W_PHR
:
16132 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
16134 case OPC_MULSA_W_PH
:
16136 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16140 #ifdef TARGET_MIPS64
16141 case OPC_DPAQ_W_QH_DSP
:
16143 int ac
= ret
& 0x03;
16144 tcg_gen_movi_i32(t0
, ac
);
16149 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
16153 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
16157 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
16161 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
16165 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16167 case OPC_DPAQ_S_W_QH
:
16169 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16171 case OPC_DPAQ_SA_L_PW
:
16173 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16175 case OPC_DPAU_H_OBL
:
16177 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
16179 case OPC_DPAU_H_OBR
:
16181 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
16185 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16187 case OPC_DPSQ_S_W_QH
:
16189 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16191 case OPC_DPSQ_SA_L_PW
:
16193 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16195 case OPC_DPSU_H_OBL
:
16197 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
16199 case OPC_DPSU_H_OBR
:
16201 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
16203 case OPC_MAQ_S_L_PWL
:
16205 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
16207 case OPC_MAQ_S_L_PWR
:
16209 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
16211 case OPC_MAQ_S_W_QHLL
:
16213 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
16215 case OPC_MAQ_SA_W_QHLL
:
16217 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
16219 case OPC_MAQ_S_W_QHLR
:
16221 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
16223 case OPC_MAQ_SA_W_QHLR
:
16225 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
16227 case OPC_MAQ_S_W_QHRL
:
16229 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
16231 case OPC_MAQ_SA_W_QHRL
:
16233 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
16235 case OPC_MAQ_S_W_QHRR
:
16237 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
16239 case OPC_MAQ_SA_W_QHRR
:
16241 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
16243 case OPC_MULSAQ_S_L_PW
:
16245 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16247 case OPC_MULSAQ_S_W_QH
:
16249 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16255 case OPC_ADDU_QB_DSP
:
16257 case OPC_MULEU_S_PH_QBL
:
16259 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16261 case OPC_MULEU_S_PH_QBR
:
16263 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16265 case OPC_MULQ_RS_PH
:
16267 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16269 case OPC_MULEQ_S_W_PHL
:
16271 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16273 case OPC_MULEQ_S_W_PHR
:
16275 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16277 case OPC_MULQ_S_PH
:
16279 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16283 #ifdef TARGET_MIPS64
16284 case OPC_ADDU_OB_DSP
:
16286 case OPC_MULEQ_S_PW_QHL
:
16288 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16290 case OPC_MULEQ_S_PW_QHR
:
16292 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16294 case OPC_MULEU_S_QH_OBL
:
16296 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16298 case OPC_MULEU_S_QH_OBR
:
16300 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16302 case OPC_MULQ_RS_QH
:
16304 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16311 tcg_temp_free_i32(t0
);
16312 tcg_temp_free(v1_t
);
16313 tcg_temp_free(v2_t
);
16316 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16324 /* Treat as NOP. */
16328 t0
= tcg_temp_new();
16329 val_t
= tcg_temp_new();
16330 gen_load_gpr(val_t
, val
);
16333 case OPC_ABSQ_S_PH_DSP
:
16337 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
16342 target_long result
;
16343 imm
= (ctx
->opcode
>> 16) & 0xFF;
16344 result
= (uint32_t)imm
<< 24 |
16345 (uint32_t)imm
<< 16 |
16346 (uint32_t)imm
<< 8 |
16348 result
= (int32_t)result
;
16349 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
16354 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
16355 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
16356 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16357 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16358 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16359 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
16364 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16365 imm
= (int16_t)(imm
<< 6) >> 6;
16366 tcg_gen_movi_tl(cpu_gpr
[ret
], \
16367 (target_long
)((int32_t)imm
<< 16 | \
16373 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
16374 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16375 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16376 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
16380 #ifdef TARGET_MIPS64
16381 case OPC_ABSQ_S_QH_DSP
:
16388 imm
= (ctx
->opcode
>> 16) & 0xFF;
16389 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
16390 temp
= (temp
<< 16) | temp
;
16391 temp
= (temp
<< 32) | temp
;
16392 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16400 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16401 imm
= (int16_t)(imm
<< 6) >> 6;
16402 temp
= ((target_long
)imm
<< 32) \
16403 | ((target_long
)imm
& 0xFFFFFFFF);
16404 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16412 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16413 imm
= (int16_t)(imm
<< 6) >> 6;
16415 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
16416 ((uint64_t)(uint16_t)imm
<< 32) |
16417 ((uint64_t)(uint16_t)imm
<< 16) |
16418 (uint64_t)(uint16_t)imm
;
16419 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16424 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
16425 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
16426 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16427 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16428 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16429 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16430 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16434 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
16435 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16436 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16440 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
16441 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16442 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16443 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16444 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16451 tcg_temp_free(val_t
);
16454 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
16455 uint32_t op1
, uint32_t op2
,
16456 int ret
, int v1
, int v2
, int check_ret
)
16462 if ((ret
== 0) && (check_ret
== 1)) {
16463 /* Treat as NOP. */
16467 t1
= tcg_temp_new();
16468 v1_t
= tcg_temp_new();
16469 v2_t
= tcg_temp_new();
16471 gen_load_gpr(v1_t
, v1
);
16472 gen_load_gpr(v2_t
, v2
);
16475 case OPC_CMPU_EQ_QB_DSP
:
16477 case OPC_CMPU_EQ_QB
:
16479 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
16481 case OPC_CMPU_LT_QB
:
16483 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
16485 case OPC_CMPU_LE_QB
:
16487 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
16489 case OPC_CMPGU_EQ_QB
:
16491 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16493 case OPC_CMPGU_LT_QB
:
16495 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16497 case OPC_CMPGU_LE_QB
:
16499 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16501 case OPC_CMPGDU_EQ_QB
:
16503 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
16504 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16505 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16506 tcg_gen_shli_tl(t1
, t1
, 24);
16507 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16509 case OPC_CMPGDU_LT_QB
:
16511 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
16512 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16513 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16514 tcg_gen_shli_tl(t1
, t1
, 24);
16515 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16517 case OPC_CMPGDU_LE_QB
:
16519 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
16520 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16521 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16522 tcg_gen_shli_tl(t1
, t1
, 24);
16523 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16525 case OPC_CMP_EQ_PH
:
16527 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
16529 case OPC_CMP_LT_PH
:
16531 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
16533 case OPC_CMP_LE_PH
:
16535 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
16539 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16543 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16545 case OPC_PACKRL_PH
:
16547 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16551 #ifdef TARGET_MIPS64
16552 case OPC_CMPU_EQ_OB_DSP
:
16554 case OPC_CMP_EQ_PW
:
16556 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
16558 case OPC_CMP_LT_PW
:
16560 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
16562 case OPC_CMP_LE_PW
:
16564 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
16566 case OPC_CMP_EQ_QH
:
16568 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
16570 case OPC_CMP_LT_QH
:
16572 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
16574 case OPC_CMP_LE_QH
:
16576 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
16578 case OPC_CMPGDU_EQ_OB
:
16580 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16582 case OPC_CMPGDU_LT_OB
:
16584 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16586 case OPC_CMPGDU_LE_OB
:
16588 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16590 case OPC_CMPGU_EQ_OB
:
16592 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16594 case OPC_CMPGU_LT_OB
:
16596 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16598 case OPC_CMPGU_LE_OB
:
16600 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16602 case OPC_CMPU_EQ_OB
:
16604 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
16606 case OPC_CMPU_LT_OB
:
16608 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
16610 case OPC_CMPU_LE_OB
:
16612 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
16614 case OPC_PACKRL_PW
:
16616 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
16620 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16624 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16628 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16636 tcg_temp_free(v1_t
);
16637 tcg_temp_free(v2_t
);
16640 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
16641 uint32_t op1
, int rt
, int rs
, int sa
)
16648 /* Treat as NOP. */
16652 t0
= tcg_temp_new();
16653 gen_load_gpr(t0
, rs
);
16656 case OPC_APPEND_DSP
:
16657 switch (MASK_APPEND(ctx
->opcode
)) {
16660 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
16662 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16666 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16667 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
16668 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
16669 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16671 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16675 if (sa
!= 0 && sa
!= 2) {
16676 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
16677 tcg_gen_ext32u_tl(t0
, t0
);
16678 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
16679 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16681 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16683 default: /* Invalid */
16684 MIPS_INVAL("MASK APPEND");
16685 generate_exception_end(ctx
, EXCP_RI
);
16689 #ifdef TARGET_MIPS64
16690 case OPC_DAPPEND_DSP
:
16691 switch (MASK_DAPPEND(ctx
->opcode
)) {
16694 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
16698 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
16699 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
16700 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
16704 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
16705 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
16706 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16711 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
16712 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
16713 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
16714 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16717 default: /* Invalid */
16718 MIPS_INVAL("MASK DAPPEND");
16719 generate_exception_end(ctx
, EXCP_RI
);
16728 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16729 int ret
, int v1
, int v2
, int check_ret
)
16738 if ((ret
== 0) && (check_ret
== 1)) {
16739 /* Treat as NOP. */
16743 t0
= tcg_temp_new();
16744 t1
= tcg_temp_new();
16745 v1_t
= tcg_temp_new();
16746 v2_t
= tcg_temp_new();
16748 gen_load_gpr(v1_t
, v1
);
16749 gen_load_gpr(v2_t
, v2
);
16752 case OPC_EXTR_W_DSP
:
16756 tcg_gen_movi_tl(t0
, v2
);
16757 tcg_gen_movi_tl(t1
, v1
);
16758 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16761 tcg_gen_movi_tl(t0
, v2
);
16762 tcg_gen_movi_tl(t1
, v1
);
16763 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16765 case OPC_EXTR_RS_W
:
16766 tcg_gen_movi_tl(t0
, v2
);
16767 tcg_gen_movi_tl(t1
, v1
);
16768 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16771 tcg_gen_movi_tl(t0
, v2
);
16772 tcg_gen_movi_tl(t1
, v1
);
16773 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16775 case OPC_EXTRV_S_H
:
16776 tcg_gen_movi_tl(t0
, v2
);
16777 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16780 tcg_gen_movi_tl(t0
, v2
);
16781 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16783 case OPC_EXTRV_R_W
:
16784 tcg_gen_movi_tl(t0
, v2
);
16785 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16787 case OPC_EXTRV_RS_W
:
16788 tcg_gen_movi_tl(t0
, v2
);
16789 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16792 tcg_gen_movi_tl(t0
, v2
);
16793 tcg_gen_movi_tl(t1
, v1
);
16794 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16797 tcg_gen_movi_tl(t0
, v2
);
16798 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16801 tcg_gen_movi_tl(t0
, v2
);
16802 tcg_gen_movi_tl(t1
, v1
);
16803 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16806 tcg_gen_movi_tl(t0
, v2
);
16807 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16810 imm
= (ctx
->opcode
>> 20) & 0x3F;
16811 tcg_gen_movi_tl(t0
, ret
);
16812 tcg_gen_movi_tl(t1
, imm
);
16813 gen_helper_shilo(t0
, t1
, cpu_env
);
16816 tcg_gen_movi_tl(t0
, ret
);
16817 gen_helper_shilo(t0
, v1_t
, cpu_env
);
16820 tcg_gen_movi_tl(t0
, ret
);
16821 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
16824 imm
= (ctx
->opcode
>> 11) & 0x3FF;
16825 tcg_gen_movi_tl(t0
, imm
);
16826 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
16829 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16830 tcg_gen_movi_tl(t0
, imm
);
16831 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
16835 #ifdef TARGET_MIPS64
16836 case OPC_DEXTR_W_DSP
:
16840 tcg_gen_movi_tl(t0
, ret
);
16841 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
16845 int shift
= (ctx
->opcode
>> 19) & 0x7F;
16846 int ac
= (ctx
->opcode
>> 11) & 0x03;
16847 tcg_gen_movi_tl(t0
, shift
);
16848 tcg_gen_movi_tl(t1
, ac
);
16849 gen_helper_dshilo(t0
, t1
, cpu_env
);
16854 int ac
= (ctx
->opcode
>> 11) & 0x03;
16855 tcg_gen_movi_tl(t0
, ac
);
16856 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
16860 tcg_gen_movi_tl(t0
, v2
);
16861 tcg_gen_movi_tl(t1
, v1
);
16863 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16866 tcg_gen_movi_tl(t0
, v2
);
16867 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16870 tcg_gen_movi_tl(t0
, v2
);
16871 tcg_gen_movi_tl(t1
, v1
);
16872 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16875 tcg_gen_movi_tl(t0
, v2
);
16876 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16879 tcg_gen_movi_tl(t0
, v2
);
16880 tcg_gen_movi_tl(t1
, v1
);
16881 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16883 case OPC_DEXTR_R_L
:
16884 tcg_gen_movi_tl(t0
, v2
);
16885 tcg_gen_movi_tl(t1
, v1
);
16886 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16888 case OPC_DEXTR_RS_L
:
16889 tcg_gen_movi_tl(t0
, v2
);
16890 tcg_gen_movi_tl(t1
, v1
);
16891 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16894 tcg_gen_movi_tl(t0
, v2
);
16895 tcg_gen_movi_tl(t1
, v1
);
16896 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16898 case OPC_DEXTR_R_W
:
16899 tcg_gen_movi_tl(t0
, v2
);
16900 tcg_gen_movi_tl(t1
, v1
);
16901 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16903 case OPC_DEXTR_RS_W
:
16904 tcg_gen_movi_tl(t0
, v2
);
16905 tcg_gen_movi_tl(t1
, v1
);
16906 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16908 case OPC_DEXTR_S_H
:
16909 tcg_gen_movi_tl(t0
, v2
);
16910 tcg_gen_movi_tl(t1
, v1
);
16911 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16913 case OPC_DEXTRV_S_H
:
16914 tcg_gen_movi_tl(t0
, v2
);
16915 tcg_gen_movi_tl(t1
, v1
);
16916 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16919 tcg_gen_movi_tl(t0
, v2
);
16920 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16922 case OPC_DEXTRV_R_L
:
16923 tcg_gen_movi_tl(t0
, v2
);
16924 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16926 case OPC_DEXTRV_RS_L
:
16927 tcg_gen_movi_tl(t0
, v2
);
16928 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16931 tcg_gen_movi_tl(t0
, v2
);
16932 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16934 case OPC_DEXTRV_R_W
:
16935 tcg_gen_movi_tl(t0
, v2
);
16936 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16938 case OPC_DEXTRV_RS_W
:
16939 tcg_gen_movi_tl(t0
, v2
);
16940 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16949 tcg_temp_free(v1_t
);
16950 tcg_temp_free(v2_t
);
16953 /* End MIPSDSP functions. */
16955 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
16957 int rs
, rt
, rd
, sa
;
16960 rs
= (ctx
->opcode
>> 21) & 0x1f;
16961 rt
= (ctx
->opcode
>> 16) & 0x1f;
16962 rd
= (ctx
->opcode
>> 11) & 0x1f;
16963 sa
= (ctx
->opcode
>> 6) & 0x1f;
16965 op1
= MASK_SPECIAL(ctx
->opcode
);
16968 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
16970 case OPC_MULT
... OPC_DIVU
:
16971 op2
= MASK_R6_MULDIV(ctx
->opcode
);
16981 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
16984 MIPS_INVAL("special_r6 muldiv");
16985 generate_exception_end(ctx
, EXCP_RI
);
16991 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
16995 if (rt
== 0 && sa
== 1) {
16996 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16997 We need additionally to check other fields */
16998 gen_cl(ctx
, op1
, rd
, rs
);
17000 generate_exception_end(ctx
, EXCP_RI
);
17004 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
17005 gen_helper_do_semihosting(cpu_env
);
17007 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
17008 generate_exception_end(ctx
, EXCP_RI
);
17010 generate_exception_end(ctx
, EXCP_DBp
);
17014 #if defined(TARGET_MIPS64)
17016 check_mips_64(ctx
);
17017 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
17021 if (rt
== 0 && sa
== 1) {
17022 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17023 We need additionally to check other fields */
17024 check_mips_64(ctx
);
17025 gen_cl(ctx
, op1
, rd
, rs
);
17027 generate_exception_end(ctx
, EXCP_RI
);
17030 case OPC_DMULT
... OPC_DDIVU
:
17031 op2
= MASK_R6_MULDIV(ctx
->opcode
);
17041 check_mips_64(ctx
);
17042 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
17045 MIPS_INVAL("special_r6 muldiv");
17046 generate_exception_end(ctx
, EXCP_RI
);
17051 default: /* Invalid */
17052 MIPS_INVAL("special_r6");
17053 generate_exception_end(ctx
, EXCP_RI
);
17058 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17060 int rs
, rt
, rd
, sa
;
17063 rs
= (ctx
->opcode
>> 21) & 0x1f;
17064 rt
= (ctx
->opcode
>> 16) & 0x1f;
17065 rd
= (ctx
->opcode
>> 11) & 0x1f;
17066 sa
= (ctx
->opcode
>> 6) & 0x1f;
17068 op1
= MASK_SPECIAL(ctx
->opcode
);
17070 case OPC_MOVN
: /* Conditional move */
17072 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
17073 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
17074 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
17076 case OPC_MFHI
: /* Move from HI/LO */
17078 gen_HILO(ctx
, op1
, rs
& 3, rd
);
17081 case OPC_MTLO
: /* Move to HI/LO */
17082 gen_HILO(ctx
, op1
, rd
& 3, rs
);
17085 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
17086 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17087 check_cp1_enabled(ctx
);
17088 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
17089 (ctx
->opcode
>> 16) & 1);
17091 generate_exception_err(ctx
, EXCP_CpU
, 1);
17097 check_insn(ctx
, INSN_VR54XX
);
17098 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
17099 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
17101 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
17106 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
17108 #if defined(TARGET_MIPS64)
17109 case OPC_DMULT
... OPC_DDIVU
:
17110 check_insn(ctx
, ISA_MIPS3
);
17111 check_mips_64(ctx
);
17112 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
17116 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
17119 #ifdef MIPS_STRICT_STANDARD
17120 MIPS_INVAL("SPIM");
17121 generate_exception_end(ctx
, EXCP_RI
);
17123 /* Implemented as RI exception for now. */
17124 MIPS_INVAL("spim (unofficial)");
17125 generate_exception_end(ctx
, EXCP_RI
);
17128 default: /* Invalid */
17129 MIPS_INVAL("special_legacy");
17130 generate_exception_end(ctx
, EXCP_RI
);
17135 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
17137 int rs
, rt
, rd
, sa
;
17140 rs
= (ctx
->opcode
>> 21) & 0x1f;
17141 rt
= (ctx
->opcode
>> 16) & 0x1f;
17142 rd
= (ctx
->opcode
>> 11) & 0x1f;
17143 sa
= (ctx
->opcode
>> 6) & 0x1f;
17145 op1
= MASK_SPECIAL(ctx
->opcode
);
17147 case OPC_SLL
: /* Shift with immediate */
17148 if (sa
== 5 && rd
== 0 &&
17149 rs
== 0 && rt
== 0) { /* PAUSE */
17150 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
17151 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
17152 generate_exception_end(ctx
, EXCP_RI
);
17158 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17161 switch ((ctx
->opcode
>> 21) & 0x1f) {
17163 /* rotr is decoded as srl on non-R2 CPUs */
17164 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17169 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17172 generate_exception_end(ctx
, EXCP_RI
);
17176 case OPC_ADD
... OPC_SUBU
:
17177 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17179 case OPC_SLLV
: /* Shifts */
17181 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17184 switch ((ctx
->opcode
>> 6) & 0x1f) {
17186 /* rotrv is decoded as srlv on non-R2 CPUs */
17187 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17192 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17195 generate_exception_end(ctx
, EXCP_RI
);
17199 case OPC_SLT
: /* Set on less than */
17201 gen_slt(ctx
, op1
, rd
, rs
, rt
);
17203 case OPC_AND
: /* Logic*/
17207 gen_logic(ctx
, op1
, rd
, rs
, rt
);
17210 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
17212 case OPC_TGE
... OPC_TEQ
: /* Traps */
17214 check_insn(ctx
, ISA_MIPS2
);
17215 gen_trap(ctx
, op1
, rs
, rt
, -1);
17217 case OPC_LSA
: /* OPC_PMON */
17218 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
17219 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
17220 decode_opc_special_r6(env
, ctx
);
17222 /* Pmon entry point, also R4010 selsl */
17223 #ifdef MIPS_STRICT_STANDARD
17224 MIPS_INVAL("PMON / selsl");
17225 generate_exception_end(ctx
, EXCP_RI
);
17227 gen_helper_0e0i(pmon
, sa
);
17232 generate_exception_end(ctx
, EXCP_SYSCALL
);
17235 generate_exception_end(ctx
, EXCP_BREAK
);
17238 check_insn(ctx
, ISA_MIPS2
);
17239 gen_sync(extract32(ctx
->opcode
, 6, 5));
17242 #if defined(TARGET_MIPS64)
17243 /* MIPS64 specific opcodes */
17248 check_insn(ctx
, ISA_MIPS3
);
17249 check_mips_64(ctx
);
17250 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17253 switch ((ctx
->opcode
>> 21) & 0x1f) {
17255 /* drotr is decoded as dsrl on non-R2 CPUs */
17256 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17261 check_insn(ctx
, ISA_MIPS3
);
17262 check_mips_64(ctx
);
17263 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17266 generate_exception_end(ctx
, EXCP_RI
);
17271 switch ((ctx
->opcode
>> 21) & 0x1f) {
17273 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17274 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17279 check_insn(ctx
, ISA_MIPS3
);
17280 check_mips_64(ctx
);
17281 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17284 generate_exception_end(ctx
, EXCP_RI
);
17288 case OPC_DADD
... OPC_DSUBU
:
17289 check_insn(ctx
, ISA_MIPS3
);
17290 check_mips_64(ctx
);
17291 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17295 check_insn(ctx
, ISA_MIPS3
);
17296 check_mips_64(ctx
);
17297 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17300 switch ((ctx
->opcode
>> 6) & 0x1f) {
17302 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17303 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17308 check_insn(ctx
, ISA_MIPS3
);
17309 check_mips_64(ctx
);
17310 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17313 generate_exception_end(ctx
, EXCP_RI
);
17318 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
17319 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
17320 decode_opc_special_r6(env
, ctx
);
17325 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17326 decode_opc_special_r6(env
, ctx
);
17328 decode_opc_special_legacy(env
, ctx
);
17333 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17338 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17340 rs
= (ctx
->opcode
>> 21) & 0x1f;
17341 rt
= (ctx
->opcode
>> 16) & 0x1f;
17342 rd
= (ctx
->opcode
>> 11) & 0x1f;
17344 op1
= MASK_SPECIAL2(ctx
->opcode
);
17346 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
17347 case OPC_MSUB
... OPC_MSUBU
:
17348 check_insn(ctx
, ISA_MIPS32
);
17349 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
17352 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17355 case OPC_DIVU_G_2F
:
17356 case OPC_MULT_G_2F
:
17357 case OPC_MULTU_G_2F
:
17359 case OPC_MODU_G_2F
:
17360 check_insn(ctx
, INSN_LOONGSON2F
);
17361 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17365 check_insn(ctx
, ISA_MIPS32
);
17366 gen_cl(ctx
, op1
, rd
, rs
);
17369 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
17370 gen_helper_do_semihosting(cpu_env
);
17372 /* XXX: not clear which exception should be raised
17373 * when in debug mode...
17375 check_insn(ctx
, ISA_MIPS32
);
17376 generate_exception_end(ctx
, EXCP_DBp
);
17379 #if defined(TARGET_MIPS64)
17382 check_insn(ctx
, ISA_MIPS64
);
17383 check_mips_64(ctx
);
17384 gen_cl(ctx
, op1
, rd
, rs
);
17386 case OPC_DMULT_G_2F
:
17387 case OPC_DMULTU_G_2F
:
17388 case OPC_DDIV_G_2F
:
17389 case OPC_DDIVU_G_2F
:
17390 case OPC_DMOD_G_2F
:
17391 case OPC_DMODU_G_2F
:
17392 check_insn(ctx
, INSN_LOONGSON2F
);
17393 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17396 default: /* Invalid */
17397 MIPS_INVAL("special2_legacy");
17398 generate_exception_end(ctx
, EXCP_RI
);
17403 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
17405 int rs
, rt
, rd
, sa
;
17409 rs
= (ctx
->opcode
>> 21) & 0x1f;
17410 rt
= (ctx
->opcode
>> 16) & 0x1f;
17411 rd
= (ctx
->opcode
>> 11) & 0x1f;
17412 sa
= (ctx
->opcode
>> 6) & 0x1f;
17413 imm
= (int16_t)ctx
->opcode
>> 7;
17415 op1
= MASK_SPECIAL3(ctx
->opcode
);
17419 /* hint codes 24-31 are reserved and signal RI */
17420 generate_exception_end(ctx
, EXCP_RI
);
17422 /* Treat as NOP. */
17425 check_cp0_enabled(ctx
);
17426 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17427 gen_cache_operation(ctx
, rt
, rs
, imm
);
17431 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
17434 gen_ld(ctx
, op1
, rt
, rs
, imm
);
17439 /* Treat as NOP. */
17442 op2
= MASK_BSHFL(ctx
->opcode
);
17444 case OPC_ALIGN
... OPC_ALIGN_END
:
17445 gen_align(ctx
, OPC_ALIGN
, rd
, rs
, rt
, sa
& 3);
17448 gen_bitswap(ctx
, op2
, rd
, rt
);
17453 #if defined(TARGET_MIPS64)
17455 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
17458 gen_ld(ctx
, op1
, rt
, rs
, imm
);
17461 check_mips_64(ctx
);
17464 /* Treat as NOP. */
17467 op2
= MASK_DBSHFL(ctx
->opcode
);
17469 case OPC_DALIGN
... OPC_DALIGN_END
:
17470 gen_align(ctx
, OPC_DALIGN
, rd
, rs
, rt
, sa
& 7);
17473 gen_bitswap(ctx
, op2
, rd
, rt
);
17480 default: /* Invalid */
17481 MIPS_INVAL("special3_r6");
17482 generate_exception_end(ctx
, EXCP_RI
);
17487 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17492 rs
= (ctx
->opcode
>> 21) & 0x1f;
17493 rt
= (ctx
->opcode
>> 16) & 0x1f;
17494 rd
= (ctx
->opcode
>> 11) & 0x1f;
17496 op1
= MASK_SPECIAL3(ctx
->opcode
);
17498 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
17499 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
17500 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
17501 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17502 * the same mask and op1. */
17503 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
17504 op2
= MASK_ADDUH_QB(ctx
->opcode
);
17507 case OPC_ADDUH_R_QB
:
17509 case OPC_ADDQH_R_PH
:
17511 case OPC_ADDQH_R_W
:
17513 case OPC_SUBUH_R_QB
:
17515 case OPC_SUBQH_R_PH
:
17517 case OPC_SUBQH_R_W
:
17518 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17523 case OPC_MULQ_RS_W
:
17524 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17527 MIPS_INVAL("MASK ADDUH.QB");
17528 generate_exception_end(ctx
, EXCP_RI
);
17531 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
17532 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17534 generate_exception_end(ctx
, EXCP_RI
);
17538 op2
= MASK_LX(ctx
->opcode
);
17540 #if defined(TARGET_MIPS64)
17546 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
17548 default: /* Invalid */
17549 MIPS_INVAL("MASK LX");
17550 generate_exception_end(ctx
, EXCP_RI
);
17554 case OPC_ABSQ_S_PH_DSP
:
17555 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
17557 case OPC_ABSQ_S_QB
:
17558 case OPC_ABSQ_S_PH
:
17560 case OPC_PRECEQ_W_PHL
:
17561 case OPC_PRECEQ_W_PHR
:
17562 case OPC_PRECEQU_PH_QBL
:
17563 case OPC_PRECEQU_PH_QBR
:
17564 case OPC_PRECEQU_PH_QBLA
:
17565 case OPC_PRECEQU_PH_QBRA
:
17566 case OPC_PRECEU_PH_QBL
:
17567 case OPC_PRECEU_PH_QBR
:
17568 case OPC_PRECEU_PH_QBLA
:
17569 case OPC_PRECEU_PH_QBRA
:
17570 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17577 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
17580 MIPS_INVAL("MASK ABSQ_S.PH");
17581 generate_exception_end(ctx
, EXCP_RI
);
17585 case OPC_ADDU_QB_DSP
:
17586 op2
= MASK_ADDU_QB(ctx
->opcode
);
17589 case OPC_ADDQ_S_PH
:
17592 case OPC_ADDU_S_QB
:
17594 case OPC_ADDU_S_PH
:
17596 case OPC_SUBQ_S_PH
:
17599 case OPC_SUBU_S_QB
:
17601 case OPC_SUBU_S_PH
:
17605 case OPC_RADDU_W_QB
:
17606 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17608 case OPC_MULEU_S_PH_QBL
:
17609 case OPC_MULEU_S_PH_QBR
:
17610 case OPC_MULQ_RS_PH
:
17611 case OPC_MULEQ_S_W_PHL
:
17612 case OPC_MULEQ_S_W_PHR
:
17613 case OPC_MULQ_S_PH
:
17614 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17616 default: /* Invalid */
17617 MIPS_INVAL("MASK ADDU.QB");
17618 generate_exception_end(ctx
, EXCP_RI
);
17623 case OPC_CMPU_EQ_QB_DSP
:
17624 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
17626 case OPC_PRECR_SRA_PH_W
:
17627 case OPC_PRECR_SRA_R_PH_W
:
17628 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
17630 case OPC_PRECR_QB_PH
:
17631 case OPC_PRECRQ_QB_PH
:
17632 case OPC_PRECRQ_PH_W
:
17633 case OPC_PRECRQ_RS_PH_W
:
17634 case OPC_PRECRQU_S_QB_PH
:
17635 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17637 case OPC_CMPU_EQ_QB
:
17638 case OPC_CMPU_LT_QB
:
17639 case OPC_CMPU_LE_QB
:
17640 case OPC_CMP_EQ_PH
:
17641 case OPC_CMP_LT_PH
:
17642 case OPC_CMP_LE_PH
:
17643 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17645 case OPC_CMPGU_EQ_QB
:
17646 case OPC_CMPGU_LT_QB
:
17647 case OPC_CMPGU_LE_QB
:
17648 case OPC_CMPGDU_EQ_QB
:
17649 case OPC_CMPGDU_LT_QB
:
17650 case OPC_CMPGDU_LE_QB
:
17653 case OPC_PACKRL_PH
:
17654 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17656 default: /* Invalid */
17657 MIPS_INVAL("MASK CMPU.EQ.QB");
17658 generate_exception_end(ctx
, EXCP_RI
);
17662 case OPC_SHLL_QB_DSP
:
17663 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
17665 case OPC_DPA_W_PH_DSP
:
17666 op2
= MASK_DPA_W_PH(ctx
->opcode
);
17668 case OPC_DPAU_H_QBL
:
17669 case OPC_DPAU_H_QBR
:
17670 case OPC_DPSU_H_QBL
:
17671 case OPC_DPSU_H_QBR
:
17673 case OPC_DPAX_W_PH
:
17674 case OPC_DPAQ_S_W_PH
:
17675 case OPC_DPAQX_S_W_PH
:
17676 case OPC_DPAQX_SA_W_PH
:
17678 case OPC_DPSX_W_PH
:
17679 case OPC_DPSQ_S_W_PH
:
17680 case OPC_DPSQX_S_W_PH
:
17681 case OPC_DPSQX_SA_W_PH
:
17682 case OPC_MULSAQ_S_W_PH
:
17683 case OPC_DPAQ_SA_L_W
:
17684 case OPC_DPSQ_SA_L_W
:
17685 case OPC_MAQ_S_W_PHL
:
17686 case OPC_MAQ_S_W_PHR
:
17687 case OPC_MAQ_SA_W_PHL
:
17688 case OPC_MAQ_SA_W_PHR
:
17689 case OPC_MULSA_W_PH
:
17690 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17692 default: /* Invalid */
17693 MIPS_INVAL("MASK DPAW.PH");
17694 generate_exception_end(ctx
, EXCP_RI
);
17699 op2
= MASK_INSV(ctx
->opcode
);
17710 t0
= tcg_temp_new();
17711 t1
= tcg_temp_new();
17713 gen_load_gpr(t0
, rt
);
17714 gen_load_gpr(t1
, rs
);
17716 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
17722 default: /* Invalid */
17723 MIPS_INVAL("MASK INSV");
17724 generate_exception_end(ctx
, EXCP_RI
);
17728 case OPC_APPEND_DSP
:
17729 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
17731 case OPC_EXTR_W_DSP
:
17732 op2
= MASK_EXTR_W(ctx
->opcode
);
17736 case OPC_EXTR_RS_W
:
17738 case OPC_EXTRV_S_H
:
17740 case OPC_EXTRV_R_W
:
17741 case OPC_EXTRV_RS_W
:
17746 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
17749 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17755 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17757 default: /* Invalid */
17758 MIPS_INVAL("MASK EXTR.W");
17759 generate_exception_end(ctx
, EXCP_RI
);
17763 #if defined(TARGET_MIPS64)
17764 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
17765 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
17766 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
17767 check_insn(ctx
, INSN_LOONGSON2E
);
17768 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17770 case OPC_ABSQ_S_QH_DSP
:
17771 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
17773 case OPC_PRECEQ_L_PWL
:
17774 case OPC_PRECEQ_L_PWR
:
17775 case OPC_PRECEQ_PW_QHL
:
17776 case OPC_PRECEQ_PW_QHR
:
17777 case OPC_PRECEQ_PW_QHLA
:
17778 case OPC_PRECEQ_PW_QHRA
:
17779 case OPC_PRECEQU_QH_OBL
:
17780 case OPC_PRECEQU_QH_OBR
:
17781 case OPC_PRECEQU_QH_OBLA
:
17782 case OPC_PRECEQU_QH_OBRA
:
17783 case OPC_PRECEU_QH_OBL
:
17784 case OPC_PRECEU_QH_OBR
:
17785 case OPC_PRECEU_QH_OBLA
:
17786 case OPC_PRECEU_QH_OBRA
:
17787 case OPC_ABSQ_S_OB
:
17788 case OPC_ABSQ_S_PW
:
17789 case OPC_ABSQ_S_QH
:
17790 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17798 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
17800 default: /* Invalid */
17801 MIPS_INVAL("MASK ABSQ_S.QH");
17802 generate_exception_end(ctx
, EXCP_RI
);
17806 case OPC_ADDU_OB_DSP
:
17807 op2
= MASK_ADDU_OB(ctx
->opcode
);
17809 case OPC_RADDU_L_OB
:
17811 case OPC_SUBQ_S_PW
:
17813 case OPC_SUBQ_S_QH
:
17815 case OPC_SUBU_S_OB
:
17817 case OPC_SUBU_S_QH
:
17819 case OPC_SUBUH_R_OB
:
17821 case OPC_ADDQ_S_PW
:
17823 case OPC_ADDQ_S_QH
:
17825 case OPC_ADDU_S_OB
:
17827 case OPC_ADDU_S_QH
:
17829 case OPC_ADDUH_R_OB
:
17830 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17832 case OPC_MULEQ_S_PW_QHL
:
17833 case OPC_MULEQ_S_PW_QHR
:
17834 case OPC_MULEU_S_QH_OBL
:
17835 case OPC_MULEU_S_QH_OBR
:
17836 case OPC_MULQ_RS_QH
:
17837 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17839 default: /* Invalid */
17840 MIPS_INVAL("MASK ADDU.OB");
17841 generate_exception_end(ctx
, EXCP_RI
);
17845 case OPC_CMPU_EQ_OB_DSP
:
17846 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
17848 case OPC_PRECR_SRA_QH_PW
:
17849 case OPC_PRECR_SRA_R_QH_PW
:
17850 /* Return value is rt. */
17851 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
17853 case OPC_PRECR_OB_QH
:
17854 case OPC_PRECRQ_OB_QH
:
17855 case OPC_PRECRQ_PW_L
:
17856 case OPC_PRECRQ_QH_PW
:
17857 case OPC_PRECRQ_RS_QH_PW
:
17858 case OPC_PRECRQU_S_OB_QH
:
17859 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17861 case OPC_CMPU_EQ_OB
:
17862 case OPC_CMPU_LT_OB
:
17863 case OPC_CMPU_LE_OB
:
17864 case OPC_CMP_EQ_QH
:
17865 case OPC_CMP_LT_QH
:
17866 case OPC_CMP_LE_QH
:
17867 case OPC_CMP_EQ_PW
:
17868 case OPC_CMP_LT_PW
:
17869 case OPC_CMP_LE_PW
:
17870 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17872 case OPC_CMPGDU_EQ_OB
:
17873 case OPC_CMPGDU_LT_OB
:
17874 case OPC_CMPGDU_LE_OB
:
17875 case OPC_CMPGU_EQ_OB
:
17876 case OPC_CMPGU_LT_OB
:
17877 case OPC_CMPGU_LE_OB
:
17878 case OPC_PACKRL_PW
:
17882 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17884 default: /* Invalid */
17885 MIPS_INVAL("MASK CMPU_EQ.OB");
17886 generate_exception_end(ctx
, EXCP_RI
);
17890 case OPC_DAPPEND_DSP
:
17891 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
17893 case OPC_DEXTR_W_DSP
:
17894 op2
= MASK_DEXTR_W(ctx
->opcode
);
17901 case OPC_DEXTR_R_L
:
17902 case OPC_DEXTR_RS_L
:
17904 case OPC_DEXTR_R_W
:
17905 case OPC_DEXTR_RS_W
:
17906 case OPC_DEXTR_S_H
:
17908 case OPC_DEXTRV_R_L
:
17909 case OPC_DEXTRV_RS_L
:
17910 case OPC_DEXTRV_S_H
:
17912 case OPC_DEXTRV_R_W
:
17913 case OPC_DEXTRV_RS_W
:
17914 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
17919 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17921 default: /* Invalid */
17922 MIPS_INVAL("MASK EXTR.W");
17923 generate_exception_end(ctx
, EXCP_RI
);
17927 case OPC_DPAQ_W_QH_DSP
:
17928 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
17930 case OPC_DPAU_H_OBL
:
17931 case OPC_DPAU_H_OBR
:
17932 case OPC_DPSU_H_OBL
:
17933 case OPC_DPSU_H_OBR
:
17935 case OPC_DPAQ_S_W_QH
:
17937 case OPC_DPSQ_S_W_QH
:
17938 case OPC_MULSAQ_S_W_QH
:
17939 case OPC_DPAQ_SA_L_PW
:
17940 case OPC_DPSQ_SA_L_PW
:
17941 case OPC_MULSAQ_S_L_PW
:
17942 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17944 case OPC_MAQ_S_W_QHLL
:
17945 case OPC_MAQ_S_W_QHLR
:
17946 case OPC_MAQ_S_W_QHRL
:
17947 case OPC_MAQ_S_W_QHRR
:
17948 case OPC_MAQ_SA_W_QHLL
:
17949 case OPC_MAQ_SA_W_QHLR
:
17950 case OPC_MAQ_SA_W_QHRL
:
17951 case OPC_MAQ_SA_W_QHRR
:
17952 case OPC_MAQ_S_L_PWL
:
17953 case OPC_MAQ_S_L_PWR
:
17958 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17960 default: /* Invalid */
17961 MIPS_INVAL("MASK DPAQ.W.QH");
17962 generate_exception_end(ctx
, EXCP_RI
);
17966 case OPC_DINSV_DSP
:
17967 op2
= MASK_INSV(ctx
->opcode
);
17978 t0
= tcg_temp_new();
17979 t1
= tcg_temp_new();
17981 gen_load_gpr(t0
, rt
);
17982 gen_load_gpr(t1
, rs
);
17984 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
17990 default: /* Invalid */
17991 MIPS_INVAL("MASK DINSV");
17992 generate_exception_end(ctx
, EXCP_RI
);
17996 case OPC_SHLL_OB_DSP
:
17997 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
18000 default: /* Invalid */
18001 MIPS_INVAL("special3_legacy");
18002 generate_exception_end(ctx
, EXCP_RI
);
18007 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
18009 int rs
, rt
, rd
, sa
;
18012 rs
= (ctx
->opcode
>> 21) & 0x1f;
18013 rt
= (ctx
->opcode
>> 16) & 0x1f;
18014 rd
= (ctx
->opcode
>> 11) & 0x1f;
18015 sa
= (ctx
->opcode
>> 6) & 0x1f;
18017 op1
= MASK_SPECIAL3(ctx
->opcode
);
18021 check_insn(ctx
, ISA_MIPS32R2
);
18022 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
18025 op2
= MASK_BSHFL(ctx
->opcode
);
18027 case OPC_ALIGN
... OPC_ALIGN_END
:
18029 check_insn(ctx
, ISA_MIPS32R6
);
18030 decode_opc_special3_r6(env
, ctx
);
18033 check_insn(ctx
, ISA_MIPS32R2
);
18034 gen_bshfl(ctx
, op2
, rt
, rd
);
18038 #if defined(TARGET_MIPS64)
18039 case OPC_DEXTM
... OPC_DEXT
:
18040 case OPC_DINSM
... OPC_DINS
:
18041 check_insn(ctx
, ISA_MIPS64R2
);
18042 check_mips_64(ctx
);
18043 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
18046 op2
= MASK_DBSHFL(ctx
->opcode
);
18048 case OPC_DALIGN
... OPC_DALIGN_END
:
18050 check_insn(ctx
, ISA_MIPS32R6
);
18051 decode_opc_special3_r6(env
, ctx
);
18054 check_insn(ctx
, ISA_MIPS64R2
);
18055 check_mips_64(ctx
);
18056 op2
= MASK_DBSHFL(ctx
->opcode
);
18057 gen_bshfl(ctx
, op2
, rt
, rd
);
18063 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
18066 check_insn(ctx
, ASE_MT
);
18068 TCGv t0
= tcg_temp_new();
18069 TCGv t1
= tcg_temp_new();
18071 gen_load_gpr(t0
, rt
);
18072 gen_load_gpr(t1
, rs
);
18073 gen_helper_fork(t0
, t1
);
18079 check_insn(ctx
, ASE_MT
);
18081 TCGv t0
= tcg_temp_new();
18083 gen_load_gpr(t0
, rs
);
18084 gen_helper_yield(t0
, cpu_env
, t0
);
18085 gen_store_gpr(t0
, rd
);
18090 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18091 decode_opc_special3_r6(env
, ctx
);
18093 decode_opc_special3_legacy(env
, ctx
);
18098 /* MIPS SIMD Architecture (MSA) */
18099 static inline int check_msa_access(DisasContext
*ctx
)
18101 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
18102 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
18103 generate_exception_end(ctx
, EXCP_RI
);
18107 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
18108 if (ctx
->insn_flags
& ASE_MSA
) {
18109 generate_exception_end(ctx
, EXCP_MSADIS
);
18112 generate_exception_end(ctx
, EXCP_RI
);
18119 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
18121 /* generates tcg ops to check if any element is 0 */
18122 /* Note this function only works with MSA_WRLEN = 128 */
18123 uint64_t eval_zero_or_big
= 0;
18124 uint64_t eval_big
= 0;
18125 TCGv_i64 t0
= tcg_temp_new_i64();
18126 TCGv_i64 t1
= tcg_temp_new_i64();
18129 eval_zero_or_big
= 0x0101010101010101ULL
;
18130 eval_big
= 0x8080808080808080ULL
;
18133 eval_zero_or_big
= 0x0001000100010001ULL
;
18134 eval_big
= 0x8000800080008000ULL
;
18137 eval_zero_or_big
= 0x0000000100000001ULL
;
18138 eval_big
= 0x8000000080000000ULL
;
18141 eval_zero_or_big
= 0x0000000000000001ULL
;
18142 eval_big
= 0x8000000000000000ULL
;
18145 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<<1], eval_zero_or_big
);
18146 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<<1]);
18147 tcg_gen_andi_i64(t0
, t0
, eval_big
);
18148 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<<1)+1], eval_zero_or_big
);
18149 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<<1)+1]);
18150 tcg_gen_andi_i64(t1
, t1
, eval_big
);
18151 tcg_gen_or_i64(t0
, t0
, t1
);
18152 /* if all bits are zero then all elements are not zero */
18153 /* if some bit is non-zero then some element is zero */
18154 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
18155 tcg_gen_trunc_i64_tl(tresult
, t0
);
18156 tcg_temp_free_i64(t0
);
18157 tcg_temp_free_i64(t1
);
18160 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
18162 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18163 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18164 int64_t s16
= (int16_t)ctx
->opcode
;
18166 check_msa_access(ctx
);
18168 if (ctx
->insn_flags
& ISA_MIPS32R6
&& ctx
->hflags
& MIPS_HFLAG_BMASK
) {
18169 generate_exception_end(ctx
, EXCP_RI
);
18176 TCGv_i64 t0
= tcg_temp_new_i64();
18177 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<<1], msa_wr_d
[(wt
<<1)+1]);
18178 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
18179 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
18180 tcg_gen_trunc_i64_tl(bcond
, t0
);
18181 tcg_temp_free_i64(t0
);
18188 gen_check_zero_element(bcond
, df
, wt
);
18194 gen_check_zero_element(bcond
, df
, wt
);
18195 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
18199 ctx
->btarget
= ctx
->pc
+ (s16
<< 2) + 4;
18201 ctx
->hflags
|= MIPS_HFLAG_BC
;
18202 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
18205 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
18207 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18208 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
18209 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18210 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18212 TCGv_i32 twd
= tcg_const_i32(wd
);
18213 TCGv_i32 tws
= tcg_const_i32(ws
);
18214 TCGv_i32 ti8
= tcg_const_i32(i8
);
18216 switch (MASK_MSA_I8(ctx
->opcode
)) {
18218 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
18221 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
18224 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
18227 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
18230 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
18233 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
18236 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
18242 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
18243 if (df
== DF_DOUBLE
) {
18244 generate_exception_end(ctx
, EXCP_RI
);
18246 TCGv_i32 tdf
= tcg_const_i32(df
);
18247 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
18248 tcg_temp_free_i32(tdf
);
18253 MIPS_INVAL("MSA instruction");
18254 generate_exception_end(ctx
, EXCP_RI
);
18258 tcg_temp_free_i32(twd
);
18259 tcg_temp_free_i32(tws
);
18260 tcg_temp_free_i32(ti8
);
18263 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
18265 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18266 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18267 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
18268 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
18269 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18270 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18272 TCGv_i32 tdf
= tcg_const_i32(df
);
18273 TCGv_i32 twd
= tcg_const_i32(wd
);
18274 TCGv_i32 tws
= tcg_const_i32(ws
);
18275 TCGv_i32 timm
= tcg_temp_new_i32();
18276 tcg_gen_movi_i32(timm
, u5
);
18278 switch (MASK_MSA_I5(ctx
->opcode
)) {
18280 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18283 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18285 case OPC_MAXI_S_df
:
18286 tcg_gen_movi_i32(timm
, s5
);
18287 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18289 case OPC_MAXI_U_df
:
18290 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18292 case OPC_MINI_S_df
:
18293 tcg_gen_movi_i32(timm
, s5
);
18294 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18296 case OPC_MINI_U_df
:
18297 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18300 tcg_gen_movi_i32(timm
, s5
);
18301 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18303 case OPC_CLTI_S_df
:
18304 tcg_gen_movi_i32(timm
, s5
);
18305 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18307 case OPC_CLTI_U_df
:
18308 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18310 case OPC_CLEI_S_df
:
18311 tcg_gen_movi_i32(timm
, s5
);
18312 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18314 case OPC_CLEI_U_df
:
18315 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18319 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
18320 tcg_gen_movi_i32(timm
, s10
);
18321 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
18325 MIPS_INVAL("MSA instruction");
18326 generate_exception_end(ctx
, EXCP_RI
);
18330 tcg_temp_free_i32(tdf
);
18331 tcg_temp_free_i32(twd
);
18332 tcg_temp_free_i32(tws
);
18333 tcg_temp_free_i32(timm
);
18336 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
18338 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18339 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
18340 uint32_t df
= 0, m
= 0;
18341 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18342 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18349 if ((dfm
& 0x40) == 0x00) {
18352 } else if ((dfm
& 0x60) == 0x40) {
18355 } else if ((dfm
& 0x70) == 0x60) {
18358 } else if ((dfm
& 0x78) == 0x70) {
18362 generate_exception_end(ctx
, EXCP_RI
);
18366 tdf
= tcg_const_i32(df
);
18367 tm
= tcg_const_i32(m
);
18368 twd
= tcg_const_i32(wd
);
18369 tws
= tcg_const_i32(ws
);
18371 switch (MASK_MSA_BIT(ctx
->opcode
)) {
18373 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18376 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
18379 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18382 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18385 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
18388 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
18390 case OPC_BINSLI_df
:
18391 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18393 case OPC_BINSRI_df
:
18394 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18397 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
18400 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
18403 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
18406 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18409 MIPS_INVAL("MSA instruction");
18410 generate_exception_end(ctx
, EXCP_RI
);
18414 tcg_temp_free_i32(tdf
);
18415 tcg_temp_free_i32(tm
);
18416 tcg_temp_free_i32(twd
);
18417 tcg_temp_free_i32(tws
);
18420 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
18422 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18423 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18424 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18425 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18426 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18428 TCGv_i32 tdf
= tcg_const_i32(df
);
18429 TCGv_i32 twd
= tcg_const_i32(wd
);
18430 TCGv_i32 tws
= tcg_const_i32(ws
);
18431 TCGv_i32 twt
= tcg_const_i32(wt
);
18433 switch (MASK_MSA_3R(ctx
->opcode
)) {
18435 gen_helper_msa_sll_df(cpu_env
, tdf
, twd
, tws
, twt
);
18438 gen_helper_msa_addv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18441 gen_helper_msa_ceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18444 gen_helper_msa_add_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18446 case OPC_SUBS_S_df
:
18447 gen_helper_msa_subs_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18450 gen_helper_msa_mulv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18453 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
18456 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18459 gen_helper_msa_sra_df(cpu_env
, tdf
, twd
, tws
, twt
);
18462 gen_helper_msa_subv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18464 case OPC_ADDS_A_df
:
18465 gen_helper_msa_adds_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18467 case OPC_SUBS_U_df
:
18468 gen_helper_msa_subs_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18471 gen_helper_msa_maddv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18474 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
18477 gen_helper_msa_srar_df(cpu_env
, tdf
, twd
, tws
, twt
);
18480 gen_helper_msa_srl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18483 gen_helper_msa_max_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18486 gen_helper_msa_clt_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18488 case OPC_ADDS_S_df
:
18489 gen_helper_msa_adds_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18491 case OPC_SUBSUS_U_df
:
18492 gen_helper_msa_subsus_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18495 gen_helper_msa_msubv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18498 gen_helper_msa_pckev_df(cpu_env
, tdf
, twd
, tws
, twt
);
18501 gen_helper_msa_srlr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18504 gen_helper_msa_bclr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18507 gen_helper_msa_max_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18510 gen_helper_msa_clt_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18512 case OPC_ADDS_U_df
:
18513 gen_helper_msa_adds_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18515 case OPC_SUBSUU_S_df
:
18516 gen_helper_msa_subsuu_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18519 gen_helper_msa_pckod_df(cpu_env
, tdf
, twd
, tws
, twt
);
18522 gen_helper_msa_bset_df(cpu_env
, tdf
, twd
, tws
, twt
);
18525 gen_helper_msa_min_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18528 gen_helper_msa_cle_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18531 gen_helper_msa_ave_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18533 case OPC_ASUB_S_df
:
18534 gen_helper_msa_asub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18537 gen_helper_msa_div_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18540 gen_helper_msa_ilvl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18543 gen_helper_msa_bneg_df(cpu_env
, tdf
, twd
, tws
, twt
);
18546 gen_helper_msa_min_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18549 gen_helper_msa_cle_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18552 gen_helper_msa_ave_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18554 case OPC_ASUB_U_df
:
18555 gen_helper_msa_asub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18558 gen_helper_msa_div_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18561 gen_helper_msa_ilvr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18564 gen_helper_msa_binsl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18567 gen_helper_msa_max_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18569 case OPC_AVER_S_df
:
18570 gen_helper_msa_aver_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18573 gen_helper_msa_mod_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18576 gen_helper_msa_ilvev_df(cpu_env
, tdf
, twd
, tws
, twt
);
18579 gen_helper_msa_binsr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18582 gen_helper_msa_min_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18584 case OPC_AVER_U_df
:
18585 gen_helper_msa_aver_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18588 gen_helper_msa_mod_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18591 gen_helper_msa_ilvod_df(cpu_env
, tdf
, twd
, tws
, twt
);
18594 case OPC_DOTP_S_df
:
18595 case OPC_DOTP_U_df
:
18596 case OPC_DPADD_S_df
:
18597 case OPC_DPADD_U_df
:
18598 case OPC_DPSUB_S_df
:
18599 case OPC_HADD_S_df
:
18600 case OPC_DPSUB_U_df
:
18601 case OPC_HADD_U_df
:
18602 case OPC_HSUB_S_df
:
18603 case OPC_HSUB_U_df
:
18604 if (df
== DF_BYTE
) {
18605 generate_exception_end(ctx
, EXCP_RI
);
18608 switch (MASK_MSA_3R(ctx
->opcode
)) {
18609 case OPC_DOTP_S_df
:
18610 gen_helper_msa_dotp_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18612 case OPC_DOTP_U_df
:
18613 gen_helper_msa_dotp_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18615 case OPC_DPADD_S_df
:
18616 gen_helper_msa_dpadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18618 case OPC_DPADD_U_df
:
18619 gen_helper_msa_dpadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18621 case OPC_DPSUB_S_df
:
18622 gen_helper_msa_dpsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18624 case OPC_HADD_S_df
:
18625 gen_helper_msa_hadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18627 case OPC_DPSUB_U_df
:
18628 gen_helper_msa_dpsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18630 case OPC_HADD_U_df
:
18631 gen_helper_msa_hadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18633 case OPC_HSUB_S_df
:
18634 gen_helper_msa_hsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18636 case OPC_HSUB_U_df
:
18637 gen_helper_msa_hsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18642 MIPS_INVAL("MSA instruction");
18643 generate_exception_end(ctx
, EXCP_RI
);
18646 tcg_temp_free_i32(twd
);
18647 tcg_temp_free_i32(tws
);
18648 tcg_temp_free_i32(twt
);
18649 tcg_temp_free_i32(tdf
);
18652 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
18654 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18655 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
18656 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
18657 TCGv telm
= tcg_temp_new();
18658 TCGv_i32 tsr
= tcg_const_i32(source
);
18659 TCGv_i32 tdt
= tcg_const_i32(dest
);
18661 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
18663 gen_load_gpr(telm
, source
);
18664 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
18667 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
18668 gen_store_gpr(telm
, dest
);
18671 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
18674 MIPS_INVAL("MSA instruction");
18675 generate_exception_end(ctx
, EXCP_RI
);
18679 tcg_temp_free(telm
);
18680 tcg_temp_free_i32(tdt
);
18681 tcg_temp_free_i32(tsr
);
18684 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
18687 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18688 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18689 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18691 TCGv_i32 tws
= tcg_const_i32(ws
);
18692 TCGv_i32 twd
= tcg_const_i32(wd
);
18693 TCGv_i32 tn
= tcg_const_i32(n
);
18694 TCGv_i32 tdf
= tcg_const_i32(df
);
18696 switch (MASK_MSA_ELM(ctx
->opcode
)) {
18698 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
18700 case OPC_SPLATI_df
:
18701 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
18704 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
18706 case OPC_COPY_S_df
:
18707 case OPC_COPY_U_df
:
18708 case OPC_INSERT_df
:
18709 #if !defined(TARGET_MIPS64)
18710 /* Double format valid only for MIPS64 */
18711 if (df
== DF_DOUBLE
) {
18712 generate_exception_end(ctx
, EXCP_RI
);
18716 switch (MASK_MSA_ELM(ctx
->opcode
)) {
18717 case OPC_COPY_S_df
:
18718 gen_helper_msa_copy_s_df(cpu_env
, tdf
, twd
, tws
, tn
);
18720 case OPC_COPY_U_df
:
18721 gen_helper_msa_copy_u_df(cpu_env
, tdf
, twd
, tws
, tn
);
18723 case OPC_INSERT_df
:
18724 gen_helper_msa_insert_df(cpu_env
, tdf
, twd
, tws
, tn
);
18729 MIPS_INVAL("MSA instruction");
18730 generate_exception_end(ctx
, EXCP_RI
);
18732 tcg_temp_free_i32(twd
);
18733 tcg_temp_free_i32(tws
);
18734 tcg_temp_free_i32(tn
);
18735 tcg_temp_free_i32(tdf
);
18738 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
18740 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
18741 uint32_t df
= 0, n
= 0;
18743 if ((dfn
& 0x30) == 0x00) {
18746 } else if ((dfn
& 0x38) == 0x20) {
18749 } else if ((dfn
& 0x3c) == 0x30) {
18752 } else if ((dfn
& 0x3e) == 0x38) {
18755 } else if (dfn
== 0x3E) {
18756 /* CTCMSA, CFCMSA, MOVE.V */
18757 gen_msa_elm_3e(env
, ctx
);
18760 generate_exception_end(ctx
, EXCP_RI
);
18764 gen_msa_elm_df(env
, ctx
, df
, n
);
18767 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
18769 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18770 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
18771 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18772 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18773 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18775 TCGv_i32 twd
= tcg_const_i32(wd
);
18776 TCGv_i32 tws
= tcg_const_i32(ws
);
18777 TCGv_i32 twt
= tcg_const_i32(wt
);
18778 TCGv_i32 tdf
= tcg_temp_new_i32();
18780 /* adjust df value for floating-point instruction */
18781 tcg_gen_movi_i32(tdf
, df
+ 2);
18783 switch (MASK_MSA_3RF(ctx
->opcode
)) {
18785 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18788 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
18791 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
18794 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
18797 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
18800 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18803 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
18806 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
18809 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18812 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18815 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
18818 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
18821 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
18824 tcg_gen_movi_i32(tdf
, df
+ 1);
18825 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18828 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
18831 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
18833 case OPC_MADD_Q_df
:
18834 tcg_gen_movi_i32(tdf
, df
+ 1);
18835 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18838 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
18840 case OPC_MSUB_Q_df
:
18841 tcg_gen_movi_i32(tdf
, df
+ 1);
18842 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18845 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
18848 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
18851 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18854 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
18857 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
18860 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
18863 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18866 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18869 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
18872 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18875 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
18878 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
18881 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
18883 case OPC_MULR_Q_df
:
18884 tcg_gen_movi_i32(tdf
, df
+ 1);
18885 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18888 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
18890 case OPC_FMIN_A_df
:
18891 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18893 case OPC_MADDR_Q_df
:
18894 tcg_gen_movi_i32(tdf
, df
+ 1);
18895 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18898 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
18901 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
18903 case OPC_MSUBR_Q_df
:
18904 tcg_gen_movi_i32(tdf
, df
+ 1);
18905 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18908 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
18910 case OPC_FMAX_A_df
:
18911 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18914 MIPS_INVAL("MSA instruction");
18915 generate_exception_end(ctx
, EXCP_RI
);
18919 tcg_temp_free_i32(twd
);
18920 tcg_temp_free_i32(tws
);
18921 tcg_temp_free_i32(twt
);
18922 tcg_temp_free_i32(tdf
);
18925 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
18927 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18928 (op & (0x7 << 18)))
18929 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18930 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18931 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18932 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
18933 TCGv_i32 twd
= tcg_const_i32(wd
);
18934 TCGv_i32 tws
= tcg_const_i32(ws
);
18935 TCGv_i32 twt
= tcg_const_i32(wt
);
18936 TCGv_i32 tdf
= tcg_const_i32(df
);
18938 switch (MASK_MSA_2R(ctx
->opcode
)) {
18940 #if !defined(TARGET_MIPS64)
18941 /* Double format valid only for MIPS64 */
18942 if (df
== DF_DOUBLE
) {
18943 generate_exception_end(ctx
, EXCP_RI
);
18947 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
18950 gen_helper_msa_pcnt_df(cpu_env
, tdf
, twd
, tws
);
18953 gen_helper_msa_nloc_df(cpu_env
, tdf
, twd
, tws
);
18956 gen_helper_msa_nlzc_df(cpu_env
, tdf
, twd
, tws
);
18959 MIPS_INVAL("MSA instruction");
18960 generate_exception_end(ctx
, EXCP_RI
);
18964 tcg_temp_free_i32(twd
);
18965 tcg_temp_free_i32(tws
);
18966 tcg_temp_free_i32(twt
);
18967 tcg_temp_free_i32(tdf
);
18970 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
18972 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18973 (op & (0xf << 17)))
18974 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18975 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18976 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18977 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
18978 TCGv_i32 twd
= tcg_const_i32(wd
);
18979 TCGv_i32 tws
= tcg_const_i32(ws
);
18980 TCGv_i32 twt
= tcg_const_i32(wt
);
18981 /* adjust df value for floating-point instruction */
18982 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
18984 switch (MASK_MSA_2RF(ctx
->opcode
)) {
18985 case OPC_FCLASS_df
:
18986 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
18988 case OPC_FTRUNC_S_df
:
18989 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
18991 case OPC_FTRUNC_U_df
:
18992 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
18995 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
18997 case OPC_FRSQRT_df
:
18998 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
19001 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
19004 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
19007 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
19009 case OPC_FEXUPL_df
:
19010 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
19012 case OPC_FEXUPR_df
:
19013 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
19016 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
19019 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
19021 case OPC_FTINT_S_df
:
19022 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
19024 case OPC_FTINT_U_df
:
19025 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
19027 case OPC_FFINT_S_df
:
19028 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
19030 case OPC_FFINT_U_df
:
19031 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
19035 tcg_temp_free_i32(twd
);
19036 tcg_temp_free_i32(tws
);
19037 tcg_temp_free_i32(twt
);
19038 tcg_temp_free_i32(tdf
);
19041 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
19043 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19044 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19045 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19046 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19047 TCGv_i32 twd
= tcg_const_i32(wd
);
19048 TCGv_i32 tws
= tcg_const_i32(ws
);
19049 TCGv_i32 twt
= tcg_const_i32(wt
);
19051 switch (MASK_MSA_VEC(ctx
->opcode
)) {
19053 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
19056 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
19059 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
19062 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
19065 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
19068 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
19071 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
19074 MIPS_INVAL("MSA instruction");
19075 generate_exception_end(ctx
, EXCP_RI
);
19079 tcg_temp_free_i32(twd
);
19080 tcg_temp_free_i32(tws
);
19081 tcg_temp_free_i32(twt
);
19084 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
19086 switch (MASK_MSA_VEC(ctx
->opcode
)) {
19094 gen_msa_vec_v(env
, ctx
);
19097 gen_msa_2r(env
, ctx
);
19100 gen_msa_2rf(env
, ctx
);
19103 MIPS_INVAL("MSA instruction");
19104 generate_exception_end(ctx
, EXCP_RI
);
19109 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
19111 uint32_t opcode
= ctx
->opcode
;
19112 check_insn(ctx
, ASE_MSA
);
19113 check_msa_access(ctx
);
19115 switch (MASK_MSA_MINOR(opcode
)) {
19116 case OPC_MSA_I8_00
:
19117 case OPC_MSA_I8_01
:
19118 case OPC_MSA_I8_02
:
19119 gen_msa_i8(env
, ctx
);
19121 case OPC_MSA_I5_06
:
19122 case OPC_MSA_I5_07
:
19123 gen_msa_i5(env
, ctx
);
19125 case OPC_MSA_BIT_09
:
19126 case OPC_MSA_BIT_0A
:
19127 gen_msa_bit(env
, ctx
);
19129 case OPC_MSA_3R_0D
:
19130 case OPC_MSA_3R_0E
:
19131 case OPC_MSA_3R_0F
:
19132 case OPC_MSA_3R_10
:
19133 case OPC_MSA_3R_11
:
19134 case OPC_MSA_3R_12
:
19135 case OPC_MSA_3R_13
:
19136 case OPC_MSA_3R_14
:
19137 case OPC_MSA_3R_15
:
19138 gen_msa_3r(env
, ctx
);
19141 gen_msa_elm(env
, ctx
);
19143 case OPC_MSA_3RF_1A
:
19144 case OPC_MSA_3RF_1B
:
19145 case OPC_MSA_3RF_1C
:
19146 gen_msa_3rf(env
, ctx
);
19149 gen_msa_vec(env
, ctx
);
19160 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
19161 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
19162 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19163 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
19165 TCGv_i32 twd
= tcg_const_i32(wd
);
19166 TCGv taddr
= tcg_temp_new();
19167 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
19169 switch (MASK_MSA_MINOR(opcode
)) {
19171 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
19174 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
19177 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
19180 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
19183 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
19186 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
19189 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
19192 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
19196 tcg_temp_free_i32(twd
);
19197 tcg_temp_free(taddr
);
19201 MIPS_INVAL("MSA instruction");
19202 generate_exception_end(ctx
, EXCP_RI
);
19208 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
19211 int rs
, rt
, rd
, sa
;
19215 /* make sure instructions are on a word boundary */
19216 if (ctx
->pc
& 0x3) {
19217 env
->CP0_BadVAddr
= ctx
->pc
;
19218 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
19222 /* Handle blikely not taken case */
19223 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
19224 TCGLabel
*l1
= gen_new_label();
19226 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
19227 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
19228 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
19232 op
= MASK_OP_MAJOR(ctx
->opcode
);
19233 rs
= (ctx
->opcode
>> 21) & 0x1f;
19234 rt
= (ctx
->opcode
>> 16) & 0x1f;
19235 rd
= (ctx
->opcode
>> 11) & 0x1f;
19236 sa
= (ctx
->opcode
>> 6) & 0x1f;
19237 imm
= (int16_t)ctx
->opcode
;
19240 decode_opc_special(env
, ctx
);
19243 decode_opc_special2_legacy(env
, ctx
);
19246 decode_opc_special3(env
, ctx
);
19249 op1
= MASK_REGIMM(ctx
->opcode
);
19251 case OPC_BLTZL
: /* REGIMM branches */
19255 check_insn(ctx
, ISA_MIPS2
);
19256 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19260 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
19264 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19266 /* OPC_NAL, OPC_BAL */
19267 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
19269 generate_exception_end(ctx
, EXCP_RI
);
19272 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
19275 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
19277 check_insn(ctx
, ISA_MIPS2
);
19278 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19279 gen_trap(ctx
, op1
, rs
, -1, imm
);
19282 check_insn(ctx
, ISA_MIPS32R6
);
19283 generate_exception_end(ctx
, EXCP_RI
);
19286 check_insn(ctx
, ISA_MIPS32R2
);
19287 /* Break the TB to be able to sync copied instructions
19289 ctx
->bstate
= BS_STOP
;
19291 case OPC_BPOSGE32
: /* MIPS DSP branch */
19292 #if defined(TARGET_MIPS64)
19296 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
19298 #if defined(TARGET_MIPS64)
19300 check_insn(ctx
, ISA_MIPS32R6
);
19301 check_mips_64(ctx
);
19303 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
19307 check_insn(ctx
, ISA_MIPS32R6
);
19308 check_mips_64(ctx
);
19310 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
19314 default: /* Invalid */
19315 MIPS_INVAL("regimm");
19316 generate_exception_end(ctx
, EXCP_RI
);
19321 check_cp0_enabled(ctx
);
19322 op1
= MASK_CP0(ctx
->opcode
);
19330 #if defined(TARGET_MIPS64)
19334 #ifndef CONFIG_USER_ONLY
19335 gen_cp0(env
, ctx
, op1
, rt
, rd
);
19336 #endif /* !CONFIG_USER_ONLY */
19338 case OPC_C0_FIRST
... OPC_C0_LAST
:
19339 #ifndef CONFIG_USER_ONLY
19340 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
19341 #endif /* !CONFIG_USER_ONLY */
19344 #ifndef CONFIG_USER_ONLY
19347 TCGv t0
= tcg_temp_new();
19349 op2
= MASK_MFMC0(ctx
->opcode
);
19352 check_insn(ctx
, ASE_MT
);
19353 gen_helper_dmt(t0
);
19354 gen_store_gpr(t0
, rt
);
19357 check_insn(ctx
, ASE_MT
);
19358 gen_helper_emt(t0
);
19359 gen_store_gpr(t0
, rt
);
19362 check_insn(ctx
, ASE_MT
);
19363 gen_helper_dvpe(t0
, cpu_env
);
19364 gen_store_gpr(t0
, rt
);
19367 check_insn(ctx
, ASE_MT
);
19368 gen_helper_evpe(t0
, cpu_env
);
19369 gen_store_gpr(t0
, rt
);
19372 check_insn(ctx
, ISA_MIPS32R6
);
19374 gen_helper_dvp(t0
, cpu_env
);
19375 gen_store_gpr(t0
, rt
);
19379 check_insn(ctx
, ISA_MIPS32R6
);
19381 gen_helper_evp(t0
, cpu_env
);
19382 gen_store_gpr(t0
, rt
);
19386 check_insn(ctx
, ISA_MIPS32R2
);
19387 save_cpu_state(ctx
, 1);
19388 gen_helper_di(t0
, cpu_env
);
19389 gen_store_gpr(t0
, rt
);
19390 /* Stop translation as we may have switched
19391 the execution mode. */
19392 ctx
->bstate
= BS_STOP
;
19395 check_insn(ctx
, ISA_MIPS32R2
);
19396 save_cpu_state(ctx
, 1);
19397 gen_helper_ei(t0
, cpu_env
);
19398 gen_store_gpr(t0
, rt
);
19399 /* Stop translation as we may have switched
19400 the execution mode. */
19401 ctx
->bstate
= BS_STOP
;
19403 default: /* Invalid */
19404 MIPS_INVAL("mfmc0");
19405 generate_exception_end(ctx
, EXCP_RI
);
19410 #endif /* !CONFIG_USER_ONLY */
19413 check_insn(ctx
, ISA_MIPS32R2
);
19414 gen_load_srsgpr(rt
, rd
);
19417 check_insn(ctx
, ISA_MIPS32R2
);
19418 gen_store_srsgpr(rt
, rd
);
19422 generate_exception_end(ctx
, EXCP_RI
);
19426 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19427 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19428 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19429 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19432 /* Arithmetic with immediate opcode */
19433 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19437 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19439 case OPC_SLTI
: /* Set on less than with immediate opcode */
19441 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
19443 case OPC_ANDI
: /* Arithmetic with immediate opcode */
19444 case OPC_LUI
: /* OPC_AUI */
19447 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
19449 case OPC_J
... OPC_JAL
: /* Jump */
19450 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
19451 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
19454 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19455 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19457 generate_exception_end(ctx
, EXCP_RI
);
19460 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19461 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19464 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19467 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19468 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19470 generate_exception_end(ctx
, EXCP_RI
);
19473 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19474 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19477 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19480 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19483 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19485 check_insn(ctx
, ISA_MIPS32R6
);
19486 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19487 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19490 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19493 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19495 check_insn(ctx
, ISA_MIPS32R6
);
19496 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19497 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19502 check_insn(ctx
, ISA_MIPS2
);
19503 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19507 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19509 case OPC_LL
: /* Load and stores */
19510 check_insn(ctx
, ISA_MIPS2
);
19514 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19516 case OPC_LB
... OPC_LH
:
19517 case OPC_LW
... OPC_LHU
:
19518 gen_ld(ctx
, op
, rt
, rs
, imm
);
19522 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19524 case OPC_SB
... OPC_SH
:
19526 gen_st(ctx
, op
, rt
, rs
, imm
);
19529 check_insn(ctx
, ISA_MIPS2
);
19530 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19531 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
19534 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19535 check_cp0_enabled(ctx
);
19536 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
19537 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
19538 gen_cache_operation(ctx
, rt
, rs
, imm
);
19540 /* Treat as NOP. */
19543 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19544 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
19545 /* Treat as NOP. */
19548 /* Floating point (COP1). */
19553 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
19557 op1
= MASK_CP1(ctx
->opcode
);
19562 check_cp1_enabled(ctx
);
19563 check_insn(ctx
, ISA_MIPS32R2
);
19568 check_cp1_enabled(ctx
);
19569 gen_cp1(ctx
, op1
, rt
, rd
);
19571 #if defined(TARGET_MIPS64)
19574 check_cp1_enabled(ctx
);
19575 check_insn(ctx
, ISA_MIPS3
);
19576 check_mips_64(ctx
);
19577 gen_cp1(ctx
, op1
, rt
, rd
);
19580 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
19581 check_cp1_enabled(ctx
);
19582 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19584 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
19589 check_insn(ctx
, ASE_MIPS3D
);
19590 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
19591 (rt
>> 2) & 0x7, imm
<< 2);
19595 check_cp1_enabled(ctx
);
19596 check_insn(ctx
, ISA_MIPS32R6
);
19597 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
19601 check_cp1_enabled(ctx
);
19602 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19604 check_insn(ctx
, ASE_MIPS3D
);
19607 check_cp1_enabled(ctx
);
19608 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19609 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
19610 (rt
>> 2) & 0x7, imm
<< 2);
19617 check_cp1_enabled(ctx
);
19618 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
19624 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
19625 check_cp1_enabled(ctx
);
19626 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19628 case R6_OPC_CMP_AF_S
:
19629 case R6_OPC_CMP_UN_S
:
19630 case R6_OPC_CMP_EQ_S
:
19631 case R6_OPC_CMP_UEQ_S
:
19632 case R6_OPC_CMP_LT_S
:
19633 case R6_OPC_CMP_ULT_S
:
19634 case R6_OPC_CMP_LE_S
:
19635 case R6_OPC_CMP_ULE_S
:
19636 case R6_OPC_CMP_SAF_S
:
19637 case R6_OPC_CMP_SUN_S
:
19638 case R6_OPC_CMP_SEQ_S
:
19639 case R6_OPC_CMP_SEUQ_S
:
19640 case R6_OPC_CMP_SLT_S
:
19641 case R6_OPC_CMP_SULT_S
:
19642 case R6_OPC_CMP_SLE_S
:
19643 case R6_OPC_CMP_SULE_S
:
19644 case R6_OPC_CMP_OR_S
:
19645 case R6_OPC_CMP_UNE_S
:
19646 case R6_OPC_CMP_NE_S
:
19647 case R6_OPC_CMP_SOR_S
:
19648 case R6_OPC_CMP_SUNE_S
:
19649 case R6_OPC_CMP_SNE_S
:
19650 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
19652 case R6_OPC_CMP_AF_D
:
19653 case R6_OPC_CMP_UN_D
:
19654 case R6_OPC_CMP_EQ_D
:
19655 case R6_OPC_CMP_UEQ_D
:
19656 case R6_OPC_CMP_LT_D
:
19657 case R6_OPC_CMP_ULT_D
:
19658 case R6_OPC_CMP_LE_D
:
19659 case R6_OPC_CMP_ULE_D
:
19660 case R6_OPC_CMP_SAF_D
:
19661 case R6_OPC_CMP_SUN_D
:
19662 case R6_OPC_CMP_SEQ_D
:
19663 case R6_OPC_CMP_SEUQ_D
:
19664 case R6_OPC_CMP_SLT_D
:
19665 case R6_OPC_CMP_SULT_D
:
19666 case R6_OPC_CMP_SLE_D
:
19667 case R6_OPC_CMP_SULE_D
:
19668 case R6_OPC_CMP_OR_D
:
19669 case R6_OPC_CMP_UNE_D
:
19670 case R6_OPC_CMP_NE_D
:
19671 case R6_OPC_CMP_SOR_D
:
19672 case R6_OPC_CMP_SUNE_D
:
19673 case R6_OPC_CMP_SNE_D
:
19674 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
19677 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
19678 rt
, rd
, sa
, (imm
>> 8) & 0x7);
19683 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
19698 check_insn(ctx
, ASE_MSA
);
19699 gen_msa_branch(env
, ctx
, op1
);
19703 generate_exception_end(ctx
, EXCP_RI
);
19708 /* Compact branches [R6] and COP2 [non-R6] */
19709 case OPC_BC
: /* OPC_LWC2 */
19710 case OPC_BALC
: /* OPC_SWC2 */
19711 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19712 /* OPC_BC, OPC_BALC */
19713 gen_compute_compact_branch(ctx
, op
, 0, 0,
19714 sextract32(ctx
->opcode
<< 2, 0, 28));
19716 /* OPC_LWC2, OPC_SWC2 */
19717 /* COP2: Not implemented. */
19718 generate_exception_err(ctx
, EXCP_CpU
, 2);
19721 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
19722 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
19723 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19725 /* OPC_BEQZC, OPC_BNEZC */
19726 gen_compute_compact_branch(ctx
, op
, rs
, 0,
19727 sextract32(ctx
->opcode
<< 2, 0, 23));
19729 /* OPC_JIC, OPC_JIALC */
19730 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
19733 /* OPC_LWC2, OPC_SWC2 */
19734 /* COP2: Not implemented. */
19735 generate_exception_err(ctx
, EXCP_CpU
, 2);
19739 check_insn(ctx
, INSN_LOONGSON2F
);
19740 /* Note that these instructions use different fields. */
19741 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
19745 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19746 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
19747 check_cp1_enabled(ctx
);
19748 op1
= MASK_CP3(ctx
->opcode
);
19752 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
19758 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
19759 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
19762 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
19763 /* Treat as NOP. */
19766 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
19780 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
19781 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
19785 generate_exception_end(ctx
, EXCP_RI
);
19789 generate_exception_err(ctx
, EXCP_CpU
, 1);
19793 #if defined(TARGET_MIPS64)
19794 /* MIPS64 opcodes */
19795 case OPC_LDL
... OPC_LDR
:
19797 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19801 check_insn(ctx
, ISA_MIPS3
);
19802 check_mips_64(ctx
);
19803 gen_ld(ctx
, op
, rt
, rs
, imm
);
19805 case OPC_SDL
... OPC_SDR
:
19806 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19809 check_insn(ctx
, ISA_MIPS3
);
19810 check_mips_64(ctx
);
19811 gen_st(ctx
, op
, rt
, rs
, imm
);
19814 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19815 check_insn(ctx
, ISA_MIPS3
);
19816 check_mips_64(ctx
);
19817 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
19819 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19820 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19821 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19822 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19825 check_insn(ctx
, ISA_MIPS3
);
19826 check_mips_64(ctx
);
19827 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19831 check_insn(ctx
, ISA_MIPS3
);
19832 check_mips_64(ctx
);
19833 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19836 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
19837 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19838 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19840 MIPS_INVAL("major opcode");
19841 generate_exception_end(ctx
, EXCP_RI
);
19845 case OPC_DAUI
: /* OPC_JALX */
19846 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19847 #if defined(TARGET_MIPS64)
19849 check_mips_64(ctx
);
19851 generate_exception(ctx
, EXCP_RI
);
19852 } else if (rt
!= 0) {
19853 TCGv t0
= tcg_temp_new();
19854 gen_load_gpr(t0
, rs
);
19855 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
19859 generate_exception_end(ctx
, EXCP_RI
);
19860 MIPS_INVAL("major opcode");
19864 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
19865 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
19866 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
19869 case OPC_MSA
: /* OPC_MDMX */
19870 /* MDMX: Not implemented. */
19874 check_insn(ctx
, ISA_MIPS32R6
);
19875 gen_pcrel(ctx
, ctx
->opcode
, ctx
->pc
, rs
);
19877 default: /* Invalid */
19878 MIPS_INVAL("major opcode");
19879 generate_exception_end(ctx
, EXCP_RI
);
19884 void gen_intermediate_code(CPUMIPSState
*env
, struct TranslationBlock
*tb
)
19886 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
19887 CPUState
*cs
= CPU(cpu
);
19889 target_ulong pc_start
;
19890 target_ulong next_page_start
;
19897 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
19900 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
19901 ctx
.insn_flags
= env
->insn_flags
;
19902 ctx
.CP0_Config1
= env
->CP0_Config1
;
19904 ctx
.bstate
= BS_NONE
;
19906 ctx
.kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
19907 ctx
.rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
19908 ctx
.ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
19909 ctx
.bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
19910 ctx
.bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
19911 ctx
.PAMask
= env
->PAMask
;
19912 ctx
.mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
19913 ctx
.CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
19914 ctx
.cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
19915 /* Restore delay slot state from the tb context. */
19916 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
19917 ctx
.ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
19918 ctx
.ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
19919 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
19920 ctx
.vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
19921 ctx
.mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
19922 ctx
.nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
19923 ctx
.abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
19924 restore_cpu_state(env
, &ctx
);
19925 #ifdef CONFIG_USER_ONLY
19926 ctx
.mem_idx
= MIPS_HFLAG_UM
;
19928 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
19930 ctx
.default_tcg_memop_mask
= (ctx
.insn_flags
& ISA_MIPS32R6
) ?
19931 MO_UNALN
: MO_ALIGN
;
19933 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
19934 if (max_insns
== 0) {
19935 max_insns
= CF_COUNT_MASK
;
19937 if (max_insns
> TCG_MAX_INSNS
) {
19938 max_insns
= TCG_MAX_INSNS
;
19941 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
19943 while (ctx
.bstate
== BS_NONE
) {
19944 tcg_gen_insn_start(ctx
.pc
, ctx
.hflags
& MIPS_HFLAG_BMASK
, ctx
.btarget
);
19947 if (unlikely(cpu_breakpoint_test(cs
, ctx
.pc
, BP_ANY
))) {
19948 save_cpu_state(&ctx
, 1);
19949 ctx
.bstate
= BS_BRANCH
;
19950 gen_helper_raise_exception_debug(cpu_env
);
19951 /* The address covered by the breakpoint must be included in
19952 [tb->pc, tb->pc + tb->size) in order to for it to be
19953 properly cleared -- thus we increment the PC here so that
19954 the logic setting tb->size below does the right thing. */
19956 goto done_generating
;
19959 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
19963 is_slot
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
19964 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
19965 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
19967 decode_opc(env
, &ctx
);
19968 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
19969 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
19970 insn_bytes
= decode_micromips_opc(env
, &ctx
);
19971 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
19972 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
19973 insn_bytes
= decode_mips16_opc(env
, &ctx
);
19975 generate_exception_end(&ctx
, EXCP_RI
);
19979 if (ctx
.hflags
& MIPS_HFLAG_BMASK
) {
19980 if (!(ctx
.hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
19981 MIPS_HFLAG_FBNSLOT
))) {
19982 /* force to generate branch as there is neither delay nor
19986 if ((ctx
.hflags
& MIPS_HFLAG_M16
) &&
19987 (ctx
.hflags
& MIPS_HFLAG_FBNSLOT
)) {
19988 /* Force to generate branch as microMIPS R6 doesn't restrict
19989 branches in the forbidden slot. */
19994 gen_branch(&ctx
, insn_bytes
);
19996 ctx
.pc
+= insn_bytes
;
19998 /* Execute a branch and its delay slot as a single instruction.
19999 This is what GDB expects and is consistent with what the
20000 hardware does (e.g. if a delay slot instruction faults, the
20001 reported PC is the PC of the branch). */
20002 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
20006 if (ctx
.pc
>= next_page_start
) {
20010 if (tcg_op_buf_full()) {
20014 if (num_insns
>= max_insns
)
20020 if (tb
->cflags
& CF_LAST_IO
) {
20023 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
20024 save_cpu_state(&ctx
, ctx
.bstate
!= BS_EXCP
);
20025 gen_helper_raise_exception_debug(cpu_env
);
20027 switch (ctx
.bstate
) {
20029 gen_goto_tb(&ctx
, 0, ctx
.pc
);
20032 save_cpu_state(&ctx
, 0);
20033 gen_goto_tb(&ctx
, 0, ctx
.pc
);
20036 tcg_gen_exit_tb(0);
20044 gen_tb_end(tb
, num_insns
);
20046 tb
->size
= ctx
.pc
- pc_start
;
20047 tb
->icount
= num_insns
;
20051 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)
20052 && qemu_log_in_addr_range(pc_start
)) {
20054 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
20055 log_target_disas(cs
, pc_start
, ctx
.pc
- pc_start
, 0);
20062 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
20066 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
20068 #define printfpr(fp) \
20071 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20072 " fd:%13g fs:%13g psu: %13g\n", \
20073 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20074 (double)(fp)->fd, \
20075 (double)(fp)->fs[FP_ENDIAN_IDX], \
20076 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20079 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20080 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20081 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20082 " fd:%13g fs:%13g psu:%13g\n", \
20083 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20085 (double)tmp.fs[FP_ENDIAN_IDX], \
20086 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20091 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20092 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
20093 get_float_exception_flags(&env
->active_fpu
.fp_status
));
20094 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
20095 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
20096 printfpr(&env
->active_fpu
.fpr
[i
]);
20102 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
20105 MIPSCPU
*cpu
= MIPS_CPU(cs
);
20106 CPUMIPSState
*env
= &cpu
->env
;
20109 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
20110 " LO=0x" TARGET_FMT_lx
" ds %04x "
20111 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
20112 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
20113 env
->hflags
, env
->btarget
, env
->bcond
);
20114 for (i
= 0; i
< 32; i
++) {
20116 cpu_fprintf(f
, "GPR%02d:", i
);
20117 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
20119 cpu_fprintf(f
, "\n");
20122 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
20123 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
20124 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20126 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
20127 cpu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
20128 env
->CP0_Config2
, env
->CP0_Config3
);
20129 cpu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
20130 env
->CP0_Config4
, env
->CP0_Config5
);
20131 if (env
->hflags
& MIPS_HFLAG_FPU
)
20132 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
20135 void mips_tcg_init(void)
20140 /* Initialize various static tables. */
20144 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
20145 tcg_ctx
.tcg_env
= cpu_env
;
20147 TCGV_UNUSED(cpu_gpr
[0]);
20148 for (i
= 1; i
< 32; i
++)
20149 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
20150 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
20153 for (i
= 0; i
< 32; i
++) {
20154 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
20156 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
20157 /* The scalar floating-point unit (FPU) registers are mapped on
20158 * the MSA vector registers. */
20159 fpu_f64
[i
] = msa_wr_d
[i
* 2];
20160 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
20161 msa_wr_d
[i
* 2 + 1] =
20162 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
20165 cpu_PC
= tcg_global_mem_new(cpu_env
,
20166 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
20167 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
20168 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
20169 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
20171 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
20172 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
20175 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
20176 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
20178 bcond
= tcg_global_mem_new(cpu_env
,
20179 offsetof(CPUMIPSState
, bcond
), "bcond");
20180 btarget
= tcg_global_mem_new(cpu_env
,
20181 offsetof(CPUMIPSState
, btarget
), "btarget");
20182 hflags
= tcg_global_mem_new_i32(cpu_env
,
20183 offsetof(CPUMIPSState
, hflags
), "hflags");
20185 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
20186 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
20188 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
20189 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
20195 #include "translate_init.c"
20197 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
20201 const mips_def_t
*def
;
20203 def
= cpu_mips_find_by_name(cpu_model
);
20206 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
20208 env
->cpu_model
= def
;
20209 env
->exception_base
= (int32_t)0xBFC00000;
20211 #ifndef CONFIG_USER_ONLY
20212 mmu_init(env
, def
);
20214 fpu_init(env
, def
);
20215 mvp_init(env
, def
);
20217 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
20222 bool cpu_supports_cps_smp(const char *cpu_model
)
20224 const mips_def_t
*def
= cpu_mips_find_by_name(cpu_model
);
20229 return (def
->CP0_Config3
& (1 << CP0C3_CMGCR
)) != 0;
20232 bool cpu_supports_isa(const char *cpu_model
, unsigned int isa
)
20234 const mips_def_t
*def
= cpu_mips_find_by_name(cpu_model
);
20239 return (def
->insn_flags
& isa
) != 0;
20242 void cpu_set_exception_base(int vp_index
, target_ulong address
)
20244 MIPSCPU
*vp
= MIPS_CPU(qemu_get_cpu(vp_index
));
20245 vp
->env
.exception_base
= address
;
20248 void cpu_state_reset(CPUMIPSState
*env
)
20250 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
20251 CPUState
*cs
= CPU(cpu
);
20253 /* Reset registers to their default values */
20254 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
20255 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
20256 #ifdef TARGET_WORDS_BIGENDIAN
20257 env
->CP0_Config0
|= (1 << CP0C0_BE
);
20259 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
20260 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
20261 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
20262 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
20263 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
20264 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
20265 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
20266 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
20267 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
20268 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
20269 << env
->cpu_model
->CP0_LLAddr_shift
;
20270 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
20271 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
20272 env
->CCRes
= env
->cpu_model
->CCRes
;
20273 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
20274 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
20275 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
20276 env
->current_tc
= 0;
20277 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
20278 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
20279 #if defined(TARGET_MIPS64)
20280 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
20281 env
->SEGMask
|= 3ULL << 62;
20284 env
->PABITS
= env
->cpu_model
->PABITS
;
20285 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
20286 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
20287 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
20288 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
20289 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
20290 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
20291 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
20292 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
20293 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
20294 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
20295 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
20296 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
20297 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
20298 env
->active_fpu
.fcr31_rw_bitmask
= env
->cpu_model
->CP1_fcr31_rw_bitmask
;
20299 env
->active_fpu
.fcr31
= env
->cpu_model
->CP1_fcr31
;
20300 env
->msair
= env
->cpu_model
->MSAIR
;
20301 env
->insn_flags
= env
->cpu_model
->insn_flags
;
20303 #if defined(CONFIG_USER_ONLY)
20304 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
20305 # ifdef TARGET_MIPS64
20306 /* Enable 64-bit register mode. */
20307 env
->CP0_Status
|= (1 << CP0St_PX
);
20309 # ifdef TARGET_ABI_MIPSN64
20310 /* Enable 64-bit address mode. */
20311 env
->CP0_Status
|= (1 << CP0St_UX
);
20313 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20314 hardware registers. */
20315 env
->CP0_HWREna
|= 0x0000000F;
20316 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
20317 env
->CP0_Status
|= (1 << CP0St_CU1
);
20319 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
20320 env
->CP0_Status
|= (1 << CP0St_MX
);
20322 # if defined(TARGET_MIPS64)
20323 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20324 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
20325 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
20326 env
->CP0_Status
|= (1 << CP0St_FR
);
20330 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
20331 /* If the exception was raised from a delay slot,
20332 come back to the jump. */
20333 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
20334 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
20336 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
20338 env
->active_tc
.PC
= env
->exception_base
;
20339 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
20340 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
20341 env
->CP0_Wired
= 0;
20342 env
->CP0_GlobalNumber
= (cs
->cpu_index
& 0xFF) << CP0GN_VPId
;
20343 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
20344 if (kvm_enabled()) {
20345 env
->CP0_EBase
|= 0x40000000;
20347 env
->CP0_EBase
|= 0x80000000;
20349 if (env
->CP0_Config3
& (1 << CP0C3_CMGCR
)) {
20350 env
->CP0_CMGCRBase
= 0x1fbf8000 >> 4;
20352 env
->CP0_EntryHi_ASID_mask
= (env
->CP0_Config4
& (1 << CP0C4_AE
)) ?
20354 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
20355 /* vectored interrupts not implemented, timer on int 7,
20356 no performance counters. */
20357 env
->CP0_IntCtl
= 0xe0000000;
20361 for (i
= 0; i
< 7; i
++) {
20362 env
->CP0_WatchLo
[i
] = 0;
20363 env
->CP0_WatchHi
[i
] = 0x80000000;
20365 env
->CP0_WatchLo
[7] = 0;
20366 env
->CP0_WatchHi
[7] = 0;
20368 /* Count register increments in debug mode, EJTAG version 1 */
20369 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
20371 cpu_mips_store_count(env
, 1);
20373 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
20376 /* Only TC0 on VPE 0 starts as active. */
20377 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
20378 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
20379 env
->tcs
[i
].CP0_TCHalt
= 1;
20381 env
->active_tc
.CP0_TCHalt
= 1;
20384 if (cs
->cpu_index
== 0) {
20385 /* VPE0 starts up enabled. */
20386 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
20387 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
20389 /* TC0 starts up unhalted. */
20391 env
->active_tc
.CP0_TCHalt
= 0;
20392 env
->tcs
[0].CP0_TCHalt
= 0;
20393 /* With thread 0 active. */
20394 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
20395 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
20399 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
20400 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
20401 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20402 env
->CP0_Status
|= (1 << CP0St_FR
);
20406 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
20410 compute_hflags(env
);
20411 restore_fp_status(env
);
20412 restore_pamask(env
);
20413 cs
->exception_index
= EXCP_NONE
;
20415 if (semihosting_get_argc()) {
20416 /* UHI interface can be used to obtain argc and argv */
20417 env
->active_tc
.gpr
[4] = -1;
20421 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
20422 target_ulong
*data
)
20424 env
->active_tc
.PC
= data
[0];
20425 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
20426 env
->hflags
|= data
[1];
20427 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
20428 case MIPS_HFLAG_BR
:
20430 case MIPS_HFLAG_BC
:
20431 case MIPS_HFLAG_BL
:
20433 env
->btarget
= data
[2];