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
,
3629 t0
= tcg_temp_new();
3630 gen_load_gpr(t0
, rs
);
3634 gen_helper_clo(cpu_gpr
[rd
], t0
);
3638 gen_helper_clz(cpu_gpr
[rd
], t0
);
3640 #if defined(TARGET_MIPS64)
3643 gen_helper_dclo(cpu_gpr
[rd
], t0
);
3647 gen_helper_dclz(cpu_gpr
[rd
], t0
);
3654 /* Godson integer instructions */
3655 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3656 int rd
, int rs
, int rt
)
3668 case OPC_MULTU_G_2E
:
3669 case OPC_MULTU_G_2F
:
3670 #if defined(TARGET_MIPS64)
3671 case OPC_DMULT_G_2E
:
3672 case OPC_DMULT_G_2F
:
3673 case OPC_DMULTU_G_2E
:
3674 case OPC_DMULTU_G_2F
:
3676 t0
= tcg_temp_new();
3677 t1
= tcg_temp_new();
3680 t0
= tcg_temp_local_new();
3681 t1
= tcg_temp_local_new();
3685 gen_load_gpr(t0
, rs
);
3686 gen_load_gpr(t1
, rt
);
3691 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3692 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3694 case OPC_MULTU_G_2E
:
3695 case OPC_MULTU_G_2F
:
3696 tcg_gen_ext32u_tl(t0
, t0
);
3697 tcg_gen_ext32u_tl(t1
, t1
);
3698 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3699 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3704 TCGLabel
*l1
= gen_new_label();
3705 TCGLabel
*l2
= gen_new_label();
3706 TCGLabel
*l3
= gen_new_label();
3707 tcg_gen_ext32s_tl(t0
, t0
);
3708 tcg_gen_ext32s_tl(t1
, t1
);
3709 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3710 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3713 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3714 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3715 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3718 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3719 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3726 TCGLabel
*l1
= gen_new_label();
3727 TCGLabel
*l2
= gen_new_label();
3728 tcg_gen_ext32u_tl(t0
, t0
);
3729 tcg_gen_ext32u_tl(t1
, t1
);
3730 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3731 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3734 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3735 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3742 TCGLabel
*l1
= gen_new_label();
3743 TCGLabel
*l2
= gen_new_label();
3744 TCGLabel
*l3
= gen_new_label();
3745 tcg_gen_ext32u_tl(t0
, t0
);
3746 tcg_gen_ext32u_tl(t1
, t1
);
3747 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3748 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3749 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3751 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3754 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3755 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3762 TCGLabel
*l1
= gen_new_label();
3763 TCGLabel
*l2
= gen_new_label();
3764 tcg_gen_ext32u_tl(t0
, t0
);
3765 tcg_gen_ext32u_tl(t1
, t1
);
3766 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3767 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3770 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3771 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3775 #if defined(TARGET_MIPS64)
3776 case OPC_DMULT_G_2E
:
3777 case OPC_DMULT_G_2F
:
3778 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3780 case OPC_DMULTU_G_2E
:
3781 case OPC_DMULTU_G_2F
:
3782 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3787 TCGLabel
*l1
= gen_new_label();
3788 TCGLabel
*l2
= gen_new_label();
3789 TCGLabel
*l3
= gen_new_label();
3790 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3791 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3794 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3795 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3796 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3799 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3803 case OPC_DDIVU_G_2E
:
3804 case OPC_DDIVU_G_2F
:
3806 TCGLabel
*l1
= gen_new_label();
3807 TCGLabel
*l2
= gen_new_label();
3808 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3809 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3812 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3819 TCGLabel
*l1
= gen_new_label();
3820 TCGLabel
*l2
= gen_new_label();
3821 TCGLabel
*l3
= gen_new_label();
3822 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3823 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3824 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3826 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3829 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3833 case OPC_DMODU_G_2E
:
3834 case OPC_DMODU_G_2F
:
3836 TCGLabel
*l1
= gen_new_label();
3837 TCGLabel
*l2
= gen_new_label();
3838 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3839 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3842 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3853 /* Loongson multimedia instructions */
3854 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3856 uint32_t opc
, shift_max
;
3859 opc
= MASK_LMI(ctx
->opcode
);
3865 t0
= tcg_temp_local_new_i64();
3866 t1
= tcg_temp_local_new_i64();
3869 t0
= tcg_temp_new_i64();
3870 t1
= tcg_temp_new_i64();
3874 check_cp1_enabled(ctx
);
3875 gen_load_fpr64(ctx
, t0
, rs
);
3876 gen_load_fpr64(ctx
, t1
, rt
);
3878 #define LMI_HELPER(UP, LO) \
3879 case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
3880 #define LMI_HELPER_1(UP, LO) \
3881 case OPC_##UP: gen_helper_##LO(t0, t0); break
3882 #define LMI_DIRECT(UP, LO, OP) \
3883 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
3886 LMI_HELPER(PADDSH
, paddsh
);
3887 LMI_HELPER(PADDUSH
, paddush
);
3888 LMI_HELPER(PADDH
, paddh
);
3889 LMI_HELPER(PADDW
, paddw
);
3890 LMI_HELPER(PADDSB
, paddsb
);
3891 LMI_HELPER(PADDUSB
, paddusb
);
3892 LMI_HELPER(PADDB
, paddb
);
3894 LMI_HELPER(PSUBSH
, psubsh
);
3895 LMI_HELPER(PSUBUSH
, psubush
);
3896 LMI_HELPER(PSUBH
, psubh
);
3897 LMI_HELPER(PSUBW
, psubw
);
3898 LMI_HELPER(PSUBSB
, psubsb
);
3899 LMI_HELPER(PSUBUSB
, psubusb
);
3900 LMI_HELPER(PSUBB
, psubb
);
3902 LMI_HELPER(PSHUFH
, pshufh
);
3903 LMI_HELPER(PACKSSWH
, packsswh
);
3904 LMI_HELPER(PACKSSHB
, packsshb
);
3905 LMI_HELPER(PACKUSHB
, packushb
);
3907 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3908 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3909 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3910 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3911 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3912 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3914 LMI_HELPER(PAVGH
, pavgh
);
3915 LMI_HELPER(PAVGB
, pavgb
);
3916 LMI_HELPER(PMAXSH
, pmaxsh
);
3917 LMI_HELPER(PMINSH
, pminsh
);
3918 LMI_HELPER(PMAXUB
, pmaxub
);
3919 LMI_HELPER(PMINUB
, pminub
);
3921 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3922 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3923 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3924 LMI_HELPER(PCMPGTH
, pcmpgth
);
3925 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3926 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3928 LMI_HELPER(PSLLW
, psllw
);
3929 LMI_HELPER(PSLLH
, psllh
);
3930 LMI_HELPER(PSRLW
, psrlw
);
3931 LMI_HELPER(PSRLH
, psrlh
);
3932 LMI_HELPER(PSRAW
, psraw
);
3933 LMI_HELPER(PSRAH
, psrah
);
3935 LMI_HELPER(PMULLH
, pmullh
);
3936 LMI_HELPER(PMULHH
, pmulhh
);
3937 LMI_HELPER(PMULHUH
, pmulhuh
);
3938 LMI_HELPER(PMADDHW
, pmaddhw
);
3940 LMI_HELPER(PASUBUB
, pasubub
);
3941 LMI_HELPER_1(BIADD
, biadd
);
3942 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3944 LMI_DIRECT(PADDD
, paddd
, add
);
3945 LMI_DIRECT(PSUBD
, psubd
, sub
);
3946 LMI_DIRECT(XOR_CP2
, xor, xor);
3947 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3948 LMI_DIRECT(AND_CP2
, and, and);
3949 LMI_DIRECT(OR_CP2
, or, or);
3952 tcg_gen_andc_i64(t0
, t1
, t0
);
3956 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3959 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3962 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3965 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3969 tcg_gen_andi_i64(t1
, t1
, 3);
3970 tcg_gen_shli_i64(t1
, t1
, 4);
3971 tcg_gen_shr_i64(t0
, t0
, t1
);
3972 tcg_gen_ext16u_i64(t0
, t0
);
3976 tcg_gen_add_i64(t0
, t0
, t1
);
3977 tcg_gen_ext32s_i64(t0
, t0
);
3980 tcg_gen_sub_i64(t0
, t0
, t1
);
3981 tcg_gen_ext32s_i64(t0
, t0
);
4003 /* Make sure shift count isn't TCG undefined behaviour. */
4004 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
4009 tcg_gen_shl_i64(t0
, t0
, t1
);
4013 /* Since SRA is UndefinedResult without sign-extended inputs,
4014 we can treat SRA and DSRA the same. */
4015 tcg_gen_sar_i64(t0
, t0
, t1
);
4018 /* We want to shift in zeros for SRL; zero-extend first. */
4019 tcg_gen_ext32u_i64(t0
, t0
);
4022 tcg_gen_shr_i64(t0
, t0
, t1
);
4026 if (shift_max
== 32) {
4027 tcg_gen_ext32s_i64(t0
, t0
);
4030 /* Shifts larger than MAX produce zero. */
4031 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
4032 tcg_gen_neg_i64(t1
, t1
);
4033 tcg_gen_and_i64(t0
, t0
, t1
);
4039 TCGv_i64 t2
= tcg_temp_new_i64();
4040 TCGLabel
*lab
= gen_new_label();
4042 tcg_gen_mov_i64(t2
, t0
);
4043 tcg_gen_add_i64(t0
, t1
, t2
);
4044 if (opc
== OPC_ADD_CP2
) {
4045 tcg_gen_ext32s_i64(t0
, t0
);
4047 tcg_gen_xor_i64(t1
, t1
, t2
);
4048 tcg_gen_xor_i64(t2
, t2
, t0
);
4049 tcg_gen_andc_i64(t1
, t2
, t1
);
4050 tcg_temp_free_i64(t2
);
4051 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4052 generate_exception(ctx
, EXCP_OVERFLOW
);
4060 TCGv_i64 t2
= tcg_temp_new_i64();
4061 TCGLabel
*lab
= gen_new_label();
4063 tcg_gen_mov_i64(t2
, t0
);
4064 tcg_gen_sub_i64(t0
, t1
, t2
);
4065 if (opc
== OPC_SUB_CP2
) {
4066 tcg_gen_ext32s_i64(t0
, t0
);
4068 tcg_gen_xor_i64(t1
, t1
, t2
);
4069 tcg_gen_xor_i64(t2
, t2
, t0
);
4070 tcg_gen_and_i64(t1
, t1
, t2
);
4071 tcg_temp_free_i64(t2
);
4072 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
4073 generate_exception(ctx
, EXCP_OVERFLOW
);
4079 tcg_gen_ext32u_i64(t0
, t0
);
4080 tcg_gen_ext32u_i64(t1
, t1
);
4081 tcg_gen_mul_i64(t0
, t0
, t1
);
4090 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4091 FD field is the CC field? */
4093 MIPS_INVAL("loongson_cp2");
4094 generate_exception_end(ctx
, EXCP_RI
);
4101 gen_store_fpr64(ctx
, t0
, rd
);
4103 tcg_temp_free_i64(t0
);
4104 tcg_temp_free_i64(t1
);
4108 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
4109 int rs
, int rt
, int16_t imm
)
4112 TCGv t0
= tcg_temp_new();
4113 TCGv t1
= tcg_temp_new();
4116 /* Load needed operands */
4124 /* Compare two registers */
4126 gen_load_gpr(t0
, rs
);
4127 gen_load_gpr(t1
, rt
);
4137 /* Compare register to immediate */
4138 if (rs
!= 0 || imm
!= 0) {
4139 gen_load_gpr(t0
, rs
);
4140 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4147 case OPC_TEQ
: /* rs == rs */
4148 case OPC_TEQI
: /* r0 == 0 */
4149 case OPC_TGE
: /* rs >= rs */
4150 case OPC_TGEI
: /* r0 >= 0 */
4151 case OPC_TGEU
: /* rs >= rs unsigned */
4152 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4154 generate_exception_end(ctx
, EXCP_TRAP
);
4156 case OPC_TLT
: /* rs < rs */
4157 case OPC_TLTI
: /* r0 < 0 */
4158 case OPC_TLTU
: /* rs < rs unsigned */
4159 case OPC_TLTIU
: /* r0 < 0 unsigned */
4160 case OPC_TNE
: /* rs != rs */
4161 case OPC_TNEI
: /* r0 != 0 */
4162 /* Never trap: treat as NOP. */
4166 TCGLabel
*l1
= gen_new_label();
4171 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4175 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4179 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
4183 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
4187 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
4191 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
4194 generate_exception(ctx
, EXCP_TRAP
);
4201 static inline bool use_goto_tb(DisasContext
*ctx
, target_ulong dest
)
4203 if (unlikely(ctx
->singlestep_enabled
)) {
4207 #ifndef CONFIG_USER_ONLY
4208 return (ctx
->tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
4214 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
4216 if (use_goto_tb(ctx
, dest
)) {
4219 tcg_gen_exit_tb((uintptr_t)ctx
->tb
+ n
);
4222 if (ctx
->singlestep_enabled
) {
4223 save_cpu_state(ctx
, 0);
4224 gen_helper_raise_exception_debug(cpu_env
);
4230 /* Branches (before delay slot) */
4231 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
4233 int rs
, int rt
, int32_t offset
,
4236 target_ulong btgt
= -1;
4238 int bcond_compute
= 0;
4239 TCGv t0
= tcg_temp_new();
4240 TCGv t1
= tcg_temp_new();
4242 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
4243 #ifdef MIPS_DEBUG_DISAS
4244 LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4245 TARGET_FMT_lx
"\n", ctx
->pc
);
4247 generate_exception_end(ctx
, EXCP_RI
);
4251 /* Load needed operands */
4257 /* Compare two registers */
4259 gen_load_gpr(t0
, rs
);
4260 gen_load_gpr(t1
, rt
);
4263 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4277 /* Compare to zero */
4279 gen_load_gpr(t0
, rs
);
4282 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4285 #if defined(TARGET_MIPS64)
4287 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
4289 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
4292 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4297 /* Jump to immediate */
4298 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
4302 /* Jump to register */
4303 if (offset
!= 0 && offset
!= 16) {
4304 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4305 others are reserved. */
4306 MIPS_INVAL("jump hint");
4307 generate_exception_end(ctx
, EXCP_RI
);
4310 gen_load_gpr(btarget
, rs
);
4313 MIPS_INVAL("branch/jump");
4314 generate_exception_end(ctx
, EXCP_RI
);
4317 if (bcond_compute
== 0) {
4318 /* No condition to be computed */
4320 case OPC_BEQ
: /* rx == rx */
4321 case OPC_BEQL
: /* rx == rx likely */
4322 case OPC_BGEZ
: /* 0 >= 0 */
4323 case OPC_BGEZL
: /* 0 >= 0 likely */
4324 case OPC_BLEZ
: /* 0 <= 0 */
4325 case OPC_BLEZL
: /* 0 <= 0 likely */
4327 ctx
->hflags
|= MIPS_HFLAG_B
;
4329 case OPC_BGEZAL
: /* 0 >= 0 */
4330 case OPC_BGEZALL
: /* 0 >= 0 likely */
4331 /* Always take and link */
4333 ctx
->hflags
|= MIPS_HFLAG_B
;
4335 case OPC_BNE
: /* rx != rx */
4336 case OPC_BGTZ
: /* 0 > 0 */
4337 case OPC_BLTZ
: /* 0 < 0 */
4340 case OPC_BLTZAL
: /* 0 < 0 */
4341 /* Handle as an unconditional branch to get correct delay
4344 btgt
= ctx
->pc
+ insn_bytes
+ delayslot_size
;
4345 ctx
->hflags
|= MIPS_HFLAG_B
;
4347 case OPC_BLTZALL
: /* 0 < 0 likely */
4348 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
4349 /* Skip the instruction in the delay slot */
4352 case OPC_BNEL
: /* rx != rx likely */
4353 case OPC_BGTZL
: /* 0 > 0 likely */
4354 case OPC_BLTZL
: /* 0 < 0 likely */
4355 /* Skip the instruction in the delay slot */
4359 ctx
->hflags
|= MIPS_HFLAG_B
;
4362 ctx
->hflags
|= MIPS_HFLAG_BX
;
4366 ctx
->hflags
|= MIPS_HFLAG_B
;
4369 ctx
->hflags
|= MIPS_HFLAG_BR
;
4373 ctx
->hflags
|= MIPS_HFLAG_BR
;
4376 MIPS_INVAL("branch/jump");
4377 generate_exception_end(ctx
, EXCP_RI
);
4383 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4386 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4389 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4392 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4395 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4398 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4401 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4405 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4409 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4412 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4415 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4418 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4421 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4424 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4427 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
4429 #if defined(TARGET_MIPS64)
4431 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
4435 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4438 ctx
->hflags
|= MIPS_HFLAG_BC
;
4441 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4444 ctx
->hflags
|= MIPS_HFLAG_BL
;
4447 MIPS_INVAL("conditional branch/jump");
4448 generate_exception_end(ctx
, EXCP_RI
);
4453 ctx
->btarget
= btgt
;
4455 switch (delayslot_size
) {
4457 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
4460 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
4465 int post_delay
= insn_bytes
+ delayslot_size
;
4466 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
4468 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
4472 if (insn_bytes
== 2)
4473 ctx
->hflags
|= MIPS_HFLAG_B16
;
4478 /* special3 bitfield operations */
4479 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
4480 int rs
, int lsb
, int msb
)
4482 TCGv t0
= tcg_temp_new();
4483 TCGv t1
= tcg_temp_new();
4485 gen_load_gpr(t1
, rs
);
4488 if (lsb
+ msb
> 31) {
4491 tcg_gen_shri_tl(t0
, t1
, lsb
);
4493 tcg_gen_andi_tl(t0
, t0
, (1U << (msb
+ 1)) - 1);
4495 tcg_gen_ext32s_tl(t0
, t0
);
4498 #if defined(TARGET_MIPS64)
4507 if (lsb
+ msb
> 63) {
4510 tcg_gen_shri_tl(t0
, t1
, lsb
);
4512 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4520 gen_load_gpr(t0
, rt
);
4521 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4522 tcg_gen_ext32s_tl(t0
, t0
);
4524 #if defined(TARGET_MIPS64)
4535 gen_load_gpr(t0
, rt
);
4536 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4541 MIPS_INVAL("bitops");
4542 generate_exception_end(ctx
, EXCP_RI
);
4547 gen_store_gpr(t0
, rt
);
4552 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4557 /* If no destination, treat it as a NOP. */
4561 t0
= tcg_temp_new();
4562 gen_load_gpr(t0
, rt
);
4566 TCGv t1
= tcg_temp_new();
4568 tcg_gen_shri_tl(t1
, t0
, 8);
4569 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4570 tcg_gen_shli_tl(t0
, t0
, 8);
4571 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4572 tcg_gen_or_tl(t0
, t0
, t1
);
4574 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4578 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4581 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4583 #if defined(TARGET_MIPS64)
4586 TCGv t1
= tcg_temp_new();
4588 tcg_gen_shri_tl(t1
, t0
, 8);
4589 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4590 tcg_gen_shli_tl(t0
, t0
, 8);
4591 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4592 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4598 TCGv t1
= tcg_temp_new();
4600 tcg_gen_shri_tl(t1
, t0
, 16);
4601 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4602 tcg_gen_shli_tl(t0
, t0
, 16);
4603 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4604 tcg_gen_or_tl(t0
, t0
, t1
);
4605 tcg_gen_shri_tl(t1
, t0
, 32);
4606 tcg_gen_shli_tl(t0
, t0
, 32);
4607 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4613 MIPS_INVAL("bsfhl");
4614 generate_exception_end(ctx
, EXCP_RI
);
4621 static void gen_lsa(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
4630 t0
= tcg_temp_new();
4631 t1
= tcg_temp_new();
4632 gen_load_gpr(t0
, rs
);
4633 gen_load_gpr(t1
, rt
);
4634 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
4635 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
4636 if (opc
== OPC_LSA
) {
4637 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
4646 static void gen_align(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
,
4654 t0
= tcg_temp_new();
4655 gen_load_gpr(t0
, rt
);
4659 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4661 #if defined(TARGET_MIPS64)
4663 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
4668 TCGv t1
= tcg_temp_new();
4669 gen_load_gpr(t1
, rs
);
4673 TCGv_i64 t2
= tcg_temp_new_i64();
4674 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
4675 tcg_gen_shri_i64(t2
, t2
, 8 * (4 - bp
));
4676 gen_move_low32(cpu_gpr
[rd
], t2
);
4677 tcg_temp_free_i64(t2
);
4680 #if defined(TARGET_MIPS64)
4682 tcg_gen_shli_tl(t0
, t0
, 8 * bp
);
4683 tcg_gen_shri_tl(t1
, t1
, 8 * (8 - bp
));
4684 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
4694 static void gen_bitswap(DisasContext
*ctx
, int opc
, int rd
, int rt
)
4701 t0
= tcg_temp_new();
4702 gen_load_gpr(t0
, rt
);
4705 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
4707 #if defined(TARGET_MIPS64)
4709 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
4716 #ifndef CONFIG_USER_ONLY
4717 /* CP0 (MMU and control) */
4718 static inline void gen_mthc0_entrylo(TCGv arg
, target_ulong off
)
4720 TCGv_i64 t0
= tcg_temp_new_i64();
4721 TCGv_i64 t1
= tcg_temp_new_i64();
4723 tcg_gen_ext_tl_i64(t0
, arg
);
4724 tcg_gen_ld_i64(t1
, cpu_env
, off
);
4725 #if defined(TARGET_MIPS64)
4726 tcg_gen_deposit_i64(t1
, t1
, t0
, 30, 32);
4728 tcg_gen_concat32_i64(t1
, t1
, t0
);
4730 tcg_gen_st_i64(t1
, cpu_env
, off
);
4731 tcg_temp_free_i64(t1
);
4732 tcg_temp_free_i64(t0
);
4735 static inline void gen_mthc0_store64(TCGv arg
, target_ulong off
)
4737 TCGv_i64 t0
= tcg_temp_new_i64();
4738 TCGv_i64 t1
= tcg_temp_new_i64();
4740 tcg_gen_ext_tl_i64(t0
, arg
);
4741 tcg_gen_ld_i64(t1
, cpu_env
, off
);
4742 tcg_gen_concat32_i64(t1
, t1
, t0
);
4743 tcg_gen_st_i64(t1
, cpu_env
, off
);
4744 tcg_temp_free_i64(t1
);
4745 tcg_temp_free_i64(t0
);
4748 static inline void gen_mfhc0_entrylo(TCGv arg
, target_ulong off
)
4750 TCGv_i64 t0
= tcg_temp_new_i64();
4752 tcg_gen_ld_i64(t0
, cpu_env
, off
);
4753 #if defined(TARGET_MIPS64)
4754 tcg_gen_shri_i64(t0
, t0
, 30);
4756 tcg_gen_shri_i64(t0
, t0
, 32);
4758 gen_move_low32(arg
, t0
);
4759 tcg_temp_free_i64(t0
);
4762 static inline void gen_mfhc0_load64(TCGv arg
, target_ulong off
, int shift
)
4764 TCGv_i64 t0
= tcg_temp_new_i64();
4766 tcg_gen_ld_i64(t0
, cpu_env
, off
);
4767 tcg_gen_shri_i64(t0
, t0
, 32 + shift
);
4768 gen_move_low32(arg
, t0
);
4769 tcg_temp_free_i64(t0
);
4772 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4774 TCGv_i32 t0
= tcg_temp_new_i32();
4776 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4777 tcg_gen_ext_i32_tl(arg
, t0
);
4778 tcg_temp_free_i32(t0
);
4781 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4783 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4784 tcg_gen_ext32s_tl(arg
, arg
);
4787 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4789 TCGv_i32 t0
= tcg_temp_new_i32();
4791 tcg_gen_trunc_tl_i32(t0
, arg
);
4792 tcg_gen_st_i32(t0
, cpu_env
, off
);
4793 tcg_temp_free_i32(t0
);
4796 #define CP0_CHECK(c) \
4799 goto cp0_unimplemented; \
4803 static void gen_mfhc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4805 const char *rn
= "invalid";
4807 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
4813 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4817 goto cp0_unimplemented
;
4823 gen_mfhc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4827 goto cp0_unimplemented
;
4833 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, lladdr
),
4834 ctx
->CP0_LLAddr_shift
);
4838 CP0_CHECK(ctx
->mrp
);
4839 gen_helper_mfhc0_maar(arg
, cpu_env
);
4843 goto cp0_unimplemented
;
4852 gen_mfhc0_load64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
), 0);
4856 goto cp0_unimplemented
;
4860 goto cp0_unimplemented
;
4863 (void)rn
; /* avoid a compiler warning */
4864 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4868 LOG_DISAS("mfhc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4869 tcg_gen_movi_tl(arg
, 0);
4872 static void gen_mthc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4874 const char *rn
= "invalid";
4875 uint64_t mask
= ctx
->PAMask
>> 36;
4877 CP0_CHECK(ctx
->hflags
& MIPS_HFLAG_ELPA
);
4883 tcg_gen_andi_tl(arg
, arg
, mask
);
4884 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4888 goto cp0_unimplemented
;
4894 tcg_gen_andi_tl(arg
, arg
, mask
);
4895 gen_mthc0_entrylo(arg
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4899 goto cp0_unimplemented
;
4905 /* LLAddr is read-only (the only exception is bit 0 if LLB is
4906 supported); the CP0_LLAddr_rw_bitmask does not seem to be
4907 relevant for modern MIPS cores supporting MTHC0, therefore
4908 treating MTHC0 to LLAddr as NOP. */
4912 CP0_CHECK(ctx
->mrp
);
4913 gen_helper_mthc0_maar(cpu_env
, arg
);
4917 goto cp0_unimplemented
;
4926 tcg_gen_andi_tl(arg
, arg
, mask
);
4927 gen_mthc0_store64(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4931 goto cp0_unimplemented
;
4935 goto cp0_unimplemented
;
4938 (void)rn
; /* avoid a compiler warning */
4940 LOG_DISAS("mthc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4943 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
4945 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
4946 tcg_gen_movi_tl(arg
, 0);
4948 tcg_gen_movi_tl(arg
, ~0);
4952 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4954 const char *rn
= "invalid";
4957 check_insn(ctx
, ISA_MIPS32
);
4963 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4967 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4968 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4972 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4973 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4977 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4978 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4983 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
4987 goto cp0_unimplemented
;
4993 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
4994 gen_helper_mfc0_random(arg
, cpu_env
);
4998 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
4999 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5003 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5004 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5008 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5009 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5013 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5014 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
5018 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5019 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5023 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5024 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5025 rn
= "VPEScheFBack";
5028 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5029 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5033 goto cp0_unimplemented
;
5040 TCGv_i64 tmp
= tcg_temp_new_i64();
5041 tcg_gen_ld_i64(tmp
, cpu_env
,
5042 offsetof(CPUMIPSState
, CP0_EntryLo0
));
5043 #if defined(TARGET_MIPS64)
5045 /* Move RI/XI fields to bits 31:30 */
5046 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
5047 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
5050 gen_move_low32(arg
, tmp
);
5051 tcg_temp_free_i64(tmp
);
5056 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5057 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5061 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5062 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5066 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5067 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
5071 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5072 gen_helper_mfc0_tchalt(arg
, cpu_env
);
5076 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5077 gen_helper_mfc0_tccontext(arg
, cpu_env
);
5081 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5082 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
5086 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5087 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
5091 goto cp0_unimplemented
;
5098 TCGv_i64 tmp
= tcg_temp_new_i64();
5099 tcg_gen_ld_i64(tmp
, cpu_env
,
5100 offsetof(CPUMIPSState
, CP0_EntryLo1
));
5101 #if defined(TARGET_MIPS64)
5103 /* Move RI/XI fields to bits 31:30 */
5104 tcg_gen_shri_tl(arg
, tmp
, CP0EnLo_XI
);
5105 tcg_gen_deposit_tl(tmp
, tmp
, arg
, 30, 2);
5108 gen_move_low32(arg
, tmp
);
5109 tcg_temp_free_i64(tmp
);
5115 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
5116 rn
= "GlobalNumber";
5119 goto cp0_unimplemented
;
5125 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5126 tcg_gen_ext32s_tl(arg
, arg
);
5130 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
5131 rn
= "ContextConfig";
5132 goto cp0_unimplemented
;
5135 CP0_CHECK(ctx
->ulri
);
5136 tcg_gen_ld32s_tl(arg
, cpu_env
,
5137 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5141 goto cp0_unimplemented
;
5147 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5151 check_insn(ctx
, ISA_MIPS32R2
);
5152 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5156 goto cp0_unimplemented
;
5162 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5166 check_insn(ctx
, ISA_MIPS32R2
);
5167 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5171 check_insn(ctx
, ISA_MIPS32R2
);
5172 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5176 check_insn(ctx
, ISA_MIPS32R2
);
5177 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5181 check_insn(ctx
, ISA_MIPS32R2
);
5182 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5186 check_insn(ctx
, ISA_MIPS32R2
);
5187 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5191 goto cp0_unimplemented
;
5197 check_insn(ctx
, ISA_MIPS32R2
);
5198 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5202 goto cp0_unimplemented
;
5208 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5209 tcg_gen_ext32s_tl(arg
, arg
);
5214 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
5219 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
5223 goto cp0_unimplemented
;
5229 /* Mark as an IO operation because we read the time. */
5230 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5233 gen_helper_mfc0_count(arg
, cpu_env
);
5234 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5237 /* Break the TB to be able to take timer interrupts immediately
5238 after reading count. */
5239 ctx
->bstate
= BS_STOP
;
5242 /* 6,7 are implementation dependent */
5244 goto cp0_unimplemented
;
5250 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5251 tcg_gen_ext32s_tl(arg
, arg
);
5255 goto cp0_unimplemented
;
5261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5264 /* 6,7 are implementation dependent */
5266 goto cp0_unimplemented
;
5272 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5276 check_insn(ctx
, ISA_MIPS32R2
);
5277 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5281 check_insn(ctx
, ISA_MIPS32R2
);
5282 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5286 check_insn(ctx
, ISA_MIPS32R2
);
5287 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5291 goto cp0_unimplemented
;
5297 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5301 goto cp0_unimplemented
;
5307 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5308 tcg_gen_ext32s_tl(arg
, arg
);
5312 goto cp0_unimplemented
;
5318 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5322 check_insn(ctx
, ISA_MIPS32R2
);
5323 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5327 check_insn(ctx
, ISA_MIPS32R2
);
5328 CP0_CHECK(ctx
->cmgcr
);
5329 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
5330 tcg_gen_ext32s_tl(arg
, arg
);
5334 goto cp0_unimplemented
;
5340 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5344 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5348 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5352 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5356 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
5360 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
5363 /* 6,7 are implementation dependent */
5365 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5369 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5373 goto cp0_unimplemented
;
5379 gen_helper_mfc0_lladdr(arg
, cpu_env
);
5383 CP0_CHECK(ctx
->mrp
);
5384 gen_helper_mfc0_maar(arg
, cpu_env
);
5388 CP0_CHECK(ctx
->mrp
);
5389 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
5393 goto cp0_unimplemented
;
5399 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
5403 goto cp0_unimplemented
;
5409 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5413 goto cp0_unimplemented
;
5419 #if defined(TARGET_MIPS64)
5420 check_insn(ctx
, ISA_MIPS3
);
5421 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5422 tcg_gen_ext32s_tl(arg
, arg
);
5427 goto cp0_unimplemented
;
5431 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5432 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
5435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5439 goto cp0_unimplemented
;
5443 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5444 rn
= "'Diagnostic"; /* implementation dependent */
5449 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5453 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5454 rn
= "TraceControl";
5457 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5458 rn
= "TraceControl2";
5461 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5462 rn
= "UserTraceData";
5465 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5469 goto cp0_unimplemented
;
5476 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5477 tcg_gen_ext32s_tl(arg
, arg
);
5481 goto cp0_unimplemented
;
5487 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5488 rn
= "Performance0";
5491 // gen_helper_mfc0_performance1(arg);
5492 rn
= "Performance1";
5495 // gen_helper_mfc0_performance2(arg);
5496 rn
= "Performance2";
5499 // gen_helper_mfc0_performance3(arg);
5500 rn
= "Performance3";
5503 // gen_helper_mfc0_performance4(arg);
5504 rn
= "Performance4";
5507 // gen_helper_mfc0_performance5(arg);
5508 rn
= "Performance5";
5511 // gen_helper_mfc0_performance6(arg);
5512 rn
= "Performance6";
5515 // gen_helper_mfc0_performance7(arg);
5516 rn
= "Performance7";
5519 goto cp0_unimplemented
;
5525 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
5529 goto cp0_unimplemented
;
5535 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5539 goto cp0_unimplemented
;
5549 TCGv_i64 tmp
= tcg_temp_new_i64();
5550 tcg_gen_ld_i64(tmp
, cpu_env
, offsetof(CPUMIPSState
, CP0_TagLo
));
5551 gen_move_low32(arg
, tmp
);
5552 tcg_temp_free_i64(tmp
);
5560 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5564 goto cp0_unimplemented
;
5573 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5580 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5584 goto cp0_unimplemented
;
5590 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5591 tcg_gen_ext32s_tl(arg
, arg
);
5595 goto cp0_unimplemented
;
5602 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5606 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
5607 tcg_gen_ld_tl(arg
, cpu_env
,
5608 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
5609 tcg_gen_ext32s_tl(arg
, arg
);
5613 goto cp0_unimplemented
;
5617 goto cp0_unimplemented
;
5619 (void)rn
; /* avoid a compiler warning */
5620 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5624 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5625 gen_mfc0_unimplemented(ctx
, arg
);
5628 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5630 const char *rn
= "invalid";
5633 check_insn(ctx
, ISA_MIPS32
);
5635 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
5643 gen_helper_mtc0_index(cpu_env
, arg
);
5647 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5648 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5652 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5657 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5667 goto cp0_unimplemented
;
5677 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5678 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5682 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5683 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5687 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5688 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5692 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5693 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5697 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5698 tcg_gen_st_tl(arg
, cpu_env
,
5699 offsetof(CPUMIPSState
, CP0_VPESchedule
));
5703 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5704 tcg_gen_st_tl(arg
, cpu_env
,
5705 offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5706 rn
= "VPEScheFBack";
5709 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5710 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5714 goto cp0_unimplemented
;
5720 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5724 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5725 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5729 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5730 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5734 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5735 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5739 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5740 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5744 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5745 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5749 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5750 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5754 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
5755 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5759 goto cp0_unimplemented
;
5765 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5771 rn
= "GlobalNumber";
5774 goto cp0_unimplemented
;
5780 gen_helper_mtc0_context(cpu_env
, arg
);
5784 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5785 rn
= "ContextConfig";
5786 goto cp0_unimplemented
;
5789 CP0_CHECK(ctx
->ulri
);
5790 tcg_gen_st_tl(arg
, cpu_env
,
5791 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5795 goto cp0_unimplemented
;
5801 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5805 check_insn(ctx
, ISA_MIPS32R2
);
5806 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5808 ctx
->bstate
= BS_STOP
;
5811 goto cp0_unimplemented
;
5817 gen_helper_mtc0_wired(cpu_env
, arg
);
5821 check_insn(ctx
, ISA_MIPS32R2
);
5822 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5826 check_insn(ctx
, ISA_MIPS32R2
);
5827 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
5831 check_insn(ctx
, ISA_MIPS32R2
);
5832 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
5836 check_insn(ctx
, ISA_MIPS32R2
);
5837 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
5841 check_insn(ctx
, ISA_MIPS32R2
);
5842 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
5846 goto cp0_unimplemented
;
5852 check_insn(ctx
, ISA_MIPS32R2
);
5853 gen_helper_mtc0_hwrena(cpu_env
, arg
);
5854 ctx
->bstate
= BS_STOP
;
5858 goto cp0_unimplemented
;
5876 goto cp0_unimplemented
;
5882 gen_helper_mtc0_count(cpu_env
, arg
);
5885 /* 6,7 are implementation dependent */
5887 goto cp0_unimplemented
;
5893 gen_helper_mtc0_entryhi(cpu_env
, arg
);
5897 goto cp0_unimplemented
;
5903 gen_helper_mtc0_compare(cpu_env
, arg
);
5906 /* 6,7 are implementation dependent */
5908 goto cp0_unimplemented
;
5914 save_cpu_state(ctx
, 1);
5915 gen_helper_mtc0_status(cpu_env
, arg
);
5916 /* BS_STOP isn't good enough here, hflags may have changed. */
5917 gen_save_pc(ctx
->pc
+ 4);
5918 ctx
->bstate
= BS_EXCP
;
5922 check_insn(ctx
, ISA_MIPS32R2
);
5923 gen_helper_mtc0_intctl(cpu_env
, arg
);
5924 /* Stop translation as we may have switched the execution mode */
5925 ctx
->bstate
= BS_STOP
;
5929 check_insn(ctx
, ISA_MIPS32R2
);
5930 gen_helper_mtc0_srsctl(cpu_env
, arg
);
5931 /* Stop translation as we may have switched the execution mode */
5932 ctx
->bstate
= BS_STOP
;
5936 check_insn(ctx
, ISA_MIPS32R2
);
5937 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5938 /* Stop translation as we may have switched the execution mode */
5939 ctx
->bstate
= BS_STOP
;
5943 goto cp0_unimplemented
;
5949 save_cpu_state(ctx
, 1);
5950 gen_helper_mtc0_cause(cpu_env
, arg
);
5954 goto cp0_unimplemented
;
5960 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5964 goto cp0_unimplemented
;
5974 check_insn(ctx
, ISA_MIPS32R2
);
5975 gen_helper_mtc0_ebase(cpu_env
, arg
);
5979 goto cp0_unimplemented
;
5985 gen_helper_mtc0_config0(cpu_env
, arg
);
5987 /* Stop translation as we may have switched the execution mode */
5988 ctx
->bstate
= BS_STOP
;
5991 /* ignored, read only */
5995 gen_helper_mtc0_config2(cpu_env
, arg
);
5997 /* Stop translation as we may have switched the execution mode */
5998 ctx
->bstate
= BS_STOP
;
6001 gen_helper_mtc0_config3(cpu_env
, arg
);
6003 /* Stop translation as we may have switched the execution mode */
6004 ctx
->bstate
= BS_STOP
;
6007 gen_helper_mtc0_config4(cpu_env
, arg
);
6009 ctx
->bstate
= BS_STOP
;
6012 gen_helper_mtc0_config5(cpu_env
, arg
);
6014 /* Stop translation as we may have switched the execution mode */
6015 ctx
->bstate
= BS_STOP
;
6017 /* 6,7 are implementation dependent */
6027 rn
= "Invalid config selector";
6028 goto cp0_unimplemented
;
6034 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6038 CP0_CHECK(ctx
->mrp
);
6039 gen_helper_mtc0_maar(cpu_env
, arg
);
6043 CP0_CHECK(ctx
->mrp
);
6044 gen_helper_mtc0_maari(cpu_env
, arg
);
6048 goto cp0_unimplemented
;
6054 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6058 goto cp0_unimplemented
;
6064 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6068 goto cp0_unimplemented
;
6074 #if defined(TARGET_MIPS64)
6075 check_insn(ctx
, ISA_MIPS3
);
6076 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6081 goto cp0_unimplemented
;
6085 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6086 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6089 gen_helper_mtc0_framemask(cpu_env
, arg
);
6093 goto cp0_unimplemented
;
6098 rn
= "Diagnostic"; /* implementation dependent */
6103 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6104 /* BS_STOP isn't good enough here, hflags may have changed. */
6105 gen_save_pc(ctx
->pc
+ 4);
6106 ctx
->bstate
= BS_EXCP
;
6110 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6111 rn
= "TraceControl";
6112 /* Stop translation as we may have switched the execution mode */
6113 ctx
->bstate
= BS_STOP
;
6116 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6117 rn
= "TraceControl2";
6118 /* Stop translation as we may have switched the execution mode */
6119 ctx
->bstate
= BS_STOP
;
6122 /* Stop translation as we may have switched the execution mode */
6123 ctx
->bstate
= BS_STOP
;
6124 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6125 rn
= "UserTraceData";
6126 /* Stop translation as we may have switched the execution mode */
6127 ctx
->bstate
= BS_STOP
;
6130 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6131 /* Stop translation as we may have switched the execution mode */
6132 ctx
->bstate
= BS_STOP
;
6136 goto cp0_unimplemented
;
6143 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6147 goto cp0_unimplemented
;
6153 gen_helper_mtc0_performance0(cpu_env
, arg
);
6154 rn
= "Performance0";
6157 // gen_helper_mtc0_performance1(arg);
6158 rn
= "Performance1";
6161 // gen_helper_mtc0_performance2(arg);
6162 rn
= "Performance2";
6165 // gen_helper_mtc0_performance3(arg);
6166 rn
= "Performance3";
6169 // gen_helper_mtc0_performance4(arg);
6170 rn
= "Performance4";
6173 // gen_helper_mtc0_performance5(arg);
6174 rn
= "Performance5";
6177 // gen_helper_mtc0_performance6(arg);
6178 rn
= "Performance6";
6181 // gen_helper_mtc0_performance7(arg);
6182 rn
= "Performance7";
6185 goto cp0_unimplemented
;
6191 gen_helper_mtc0_errctl(cpu_env
, arg
);
6192 ctx
->bstate
= BS_STOP
;
6196 goto cp0_unimplemented
;
6206 goto cp0_unimplemented
;
6215 gen_helper_mtc0_taglo(cpu_env
, arg
);
6222 gen_helper_mtc0_datalo(cpu_env
, arg
);
6226 goto cp0_unimplemented
;
6235 gen_helper_mtc0_taghi(cpu_env
, arg
);
6242 gen_helper_mtc0_datahi(cpu_env
, arg
);
6247 goto cp0_unimplemented
;
6253 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6257 goto cp0_unimplemented
;
6264 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6268 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6269 tcg_gen_st_tl(arg
, cpu_env
,
6270 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6274 goto cp0_unimplemented
;
6276 /* Stop translation as we may have switched the execution mode */
6277 ctx
->bstate
= BS_STOP
;
6280 goto cp0_unimplemented
;
6282 (void)rn
; /* avoid a compiler warning */
6283 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6284 /* For simplicity assume that all writes can cause interrupts. */
6285 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6287 ctx
->bstate
= BS_STOP
;
6292 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6295 #if defined(TARGET_MIPS64)
6296 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6298 const char *rn
= "invalid";
6301 check_insn(ctx
, ISA_MIPS64
);
6307 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
6311 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6312 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
6316 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6317 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
6321 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6322 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
6327 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPControl
));
6331 goto cp0_unimplemented
;
6337 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6338 gen_helper_mfc0_random(arg
, cpu_env
);
6342 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6343 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
6347 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6348 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
6352 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6353 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
6357 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6358 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
6362 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6363 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6367 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6368 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6369 rn
= "VPEScheFBack";
6372 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6373 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
6377 goto cp0_unimplemented
;
6383 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
6387 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6388 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
6392 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6393 gen_helper_mfc0_tcbind(arg
, cpu_env
);
6397 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6398 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
6402 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6403 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
6407 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6408 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
6412 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6413 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
6417 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6418 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
6422 goto cp0_unimplemented
;
6428 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
6433 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_GlobalNumber
));
6434 rn
= "GlobalNumber";
6437 goto cp0_unimplemented
;
6443 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
6447 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
6448 rn
= "ContextConfig";
6449 goto cp0_unimplemented
;
6452 CP0_CHECK(ctx
->ulri
);
6453 tcg_gen_ld_tl(arg
, cpu_env
,
6454 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6458 goto cp0_unimplemented
;
6464 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
6468 check_insn(ctx
, ISA_MIPS32R2
);
6469 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6473 goto cp0_unimplemented
;
6479 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6483 check_insn(ctx
, ISA_MIPS32R2
);
6484 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6488 check_insn(ctx
, ISA_MIPS32R2
);
6489 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6493 check_insn(ctx
, ISA_MIPS32R2
);
6494 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6498 check_insn(ctx
, ISA_MIPS32R2
);
6499 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6503 check_insn(ctx
, ISA_MIPS32R2
);
6504 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6508 goto cp0_unimplemented
;
6514 check_insn(ctx
, ISA_MIPS32R2
);
6515 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6519 goto cp0_unimplemented
;
6525 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6530 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstr
));
6535 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_BadInstrP
));
6539 goto cp0_unimplemented
;
6545 /* Mark as an IO operation because we read the time. */
6546 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6549 gen_helper_mfc0_count(arg
, cpu_env
);
6550 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6553 /* Break the TB to be able to take timer interrupts immediately
6554 after reading count. */
6555 ctx
->bstate
= BS_STOP
;
6558 /* 6,7 are implementation dependent */
6560 goto cp0_unimplemented
;
6566 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6570 goto cp0_unimplemented
;
6576 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6579 /* 6,7 are implementation dependent */
6581 goto cp0_unimplemented
;
6587 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6591 check_insn(ctx
, ISA_MIPS32R2
);
6592 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6596 check_insn(ctx
, ISA_MIPS32R2
);
6597 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6601 check_insn(ctx
, ISA_MIPS32R2
);
6602 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6606 goto cp0_unimplemented
;
6612 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6616 goto cp0_unimplemented
;
6622 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6626 goto cp0_unimplemented
;
6632 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6636 check_insn(ctx
, ISA_MIPS32R2
);
6637 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
6641 check_insn(ctx
, ISA_MIPS32R2
);
6642 CP0_CHECK(ctx
->cmgcr
);
6643 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_CMGCRBase
));
6647 goto cp0_unimplemented
;
6653 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6657 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6661 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6665 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6669 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
6673 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
6676 /* 6,7 are implementation dependent */
6678 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6682 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6686 goto cp0_unimplemented
;
6692 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
6696 CP0_CHECK(ctx
->mrp
);
6697 gen_helper_dmfc0_maar(arg
, cpu_env
);
6701 CP0_CHECK(ctx
->mrp
);
6702 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_MAARI
));
6706 goto cp0_unimplemented
;
6712 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
6716 goto cp0_unimplemented
;
6722 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6726 goto cp0_unimplemented
;
6732 check_insn(ctx
, ISA_MIPS3
);
6733 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6737 goto cp0_unimplemented
;
6741 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6742 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
6745 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6749 goto cp0_unimplemented
;
6753 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6754 rn
= "'Diagnostic"; /* implementation dependent */
6759 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6763 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6764 rn
= "TraceControl";
6767 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6768 rn
= "TraceControl2";
6771 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6772 rn
= "UserTraceData";
6775 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6779 goto cp0_unimplemented
;
6786 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6790 goto cp0_unimplemented
;
6796 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6797 rn
= "Performance0";
6800 // gen_helper_dmfc0_performance1(arg);
6801 rn
= "Performance1";
6804 // gen_helper_dmfc0_performance2(arg);
6805 rn
= "Performance2";
6808 // gen_helper_dmfc0_performance3(arg);
6809 rn
= "Performance3";
6812 // gen_helper_dmfc0_performance4(arg);
6813 rn
= "Performance4";
6816 // gen_helper_dmfc0_performance5(arg);
6817 rn
= "Performance5";
6820 // gen_helper_dmfc0_performance6(arg);
6821 rn
= "Performance6";
6824 // gen_helper_dmfc0_performance7(arg);
6825 rn
= "Performance7";
6828 goto cp0_unimplemented
;
6834 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_ErrCtl
));
6838 goto cp0_unimplemented
;
6845 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6849 goto cp0_unimplemented
;
6858 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6865 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6869 goto cp0_unimplemented
;
6878 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6885 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6889 goto cp0_unimplemented
;
6895 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6899 goto cp0_unimplemented
;
6906 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6910 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
6911 tcg_gen_ld_tl(arg
, cpu_env
,
6912 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6916 goto cp0_unimplemented
;
6920 goto cp0_unimplemented
;
6922 (void)rn
; /* avoid a compiler warning */
6923 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6927 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6928 gen_mfc0_unimplemented(ctx
, arg
);
6931 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6933 const char *rn
= "invalid";
6936 check_insn(ctx
, ISA_MIPS64
);
6938 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
6946 gen_helper_mtc0_index(cpu_env
, arg
);
6950 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6951 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6955 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6960 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6970 goto cp0_unimplemented
;
6980 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6981 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6985 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6986 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6990 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6991 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6995 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
6996 gen_helper_mtc0_yqmask(cpu_env
, arg
);
7000 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7001 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
7005 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7006 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
7007 rn
= "VPEScheFBack";
7010 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7011 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
7015 goto cp0_unimplemented
;
7021 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
7025 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7026 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
7030 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7031 gen_helper_mtc0_tcbind(cpu_env
, arg
);
7035 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7036 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
7040 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7041 gen_helper_mtc0_tchalt(cpu_env
, arg
);
7045 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7046 gen_helper_mtc0_tccontext(cpu_env
, arg
);
7050 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7051 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
7055 CP0_CHECK(ctx
->insn_flags
& ASE_MT
);
7056 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
7060 goto cp0_unimplemented
;
7066 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
7072 rn
= "GlobalNumber";
7075 goto cp0_unimplemented
;
7081 gen_helper_mtc0_context(cpu_env
, arg
);
7085 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7086 rn
= "ContextConfig";
7087 goto cp0_unimplemented
;
7090 CP0_CHECK(ctx
->ulri
);
7091 tcg_gen_st_tl(arg
, cpu_env
,
7092 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
7096 goto cp0_unimplemented
;
7102 gen_helper_mtc0_pagemask(cpu_env
, arg
);
7106 check_insn(ctx
, ISA_MIPS32R2
);
7107 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
7111 goto cp0_unimplemented
;
7117 gen_helper_mtc0_wired(cpu_env
, arg
);
7121 check_insn(ctx
, ISA_MIPS32R2
);
7122 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
7126 check_insn(ctx
, ISA_MIPS32R2
);
7127 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
7131 check_insn(ctx
, ISA_MIPS32R2
);
7132 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
7136 check_insn(ctx
, ISA_MIPS32R2
);
7137 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
7141 check_insn(ctx
, ISA_MIPS32R2
);
7142 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
7146 goto cp0_unimplemented
;
7152 check_insn(ctx
, ISA_MIPS32R2
);
7153 gen_helper_mtc0_hwrena(cpu_env
, arg
);
7154 ctx
->bstate
= BS_STOP
;
7158 goto cp0_unimplemented
;
7176 goto cp0_unimplemented
;
7182 gen_helper_mtc0_count(cpu_env
, arg
);
7185 /* 6,7 are implementation dependent */
7187 goto cp0_unimplemented
;
7189 /* Stop translation as we may have switched the execution mode */
7190 ctx
->bstate
= BS_STOP
;
7195 gen_helper_mtc0_entryhi(cpu_env
, arg
);
7199 goto cp0_unimplemented
;
7205 gen_helper_mtc0_compare(cpu_env
, arg
);
7208 /* 6,7 are implementation dependent */
7210 goto cp0_unimplemented
;
7212 /* Stop translation as we may have switched the execution mode */
7213 ctx
->bstate
= BS_STOP
;
7218 save_cpu_state(ctx
, 1);
7219 gen_helper_mtc0_status(cpu_env
, arg
);
7220 /* BS_STOP isn't good enough here, hflags may have changed. */
7221 gen_save_pc(ctx
->pc
+ 4);
7222 ctx
->bstate
= BS_EXCP
;
7226 check_insn(ctx
, ISA_MIPS32R2
);
7227 gen_helper_mtc0_intctl(cpu_env
, arg
);
7228 /* Stop translation as we may have switched the execution mode */
7229 ctx
->bstate
= BS_STOP
;
7233 check_insn(ctx
, ISA_MIPS32R2
);
7234 gen_helper_mtc0_srsctl(cpu_env
, arg
);
7235 /* Stop translation as we may have switched the execution mode */
7236 ctx
->bstate
= BS_STOP
;
7240 check_insn(ctx
, ISA_MIPS32R2
);
7241 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
7242 /* Stop translation as we may have switched the execution mode */
7243 ctx
->bstate
= BS_STOP
;
7247 goto cp0_unimplemented
;
7253 save_cpu_state(ctx
, 1);
7254 /* Mark as an IO operation because we may trigger a software
7256 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7259 gen_helper_mtc0_cause(cpu_env
, arg
);
7260 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7263 /* Stop translation as we may have triggered an intetrupt */
7264 ctx
->bstate
= BS_STOP
;
7268 goto cp0_unimplemented
;
7274 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
7278 goto cp0_unimplemented
;
7288 check_insn(ctx
, ISA_MIPS32R2
);
7289 gen_helper_mtc0_ebase(cpu_env
, arg
);
7293 goto cp0_unimplemented
;
7299 gen_helper_mtc0_config0(cpu_env
, arg
);
7301 /* Stop translation as we may have switched the execution mode */
7302 ctx
->bstate
= BS_STOP
;
7305 /* ignored, read only */
7309 gen_helper_mtc0_config2(cpu_env
, arg
);
7311 /* Stop translation as we may have switched the execution mode */
7312 ctx
->bstate
= BS_STOP
;
7315 gen_helper_mtc0_config3(cpu_env
, arg
);
7317 /* Stop translation as we may have switched the execution mode */
7318 ctx
->bstate
= BS_STOP
;
7321 /* currently ignored */
7325 gen_helper_mtc0_config5(cpu_env
, arg
);
7327 /* Stop translation as we may have switched the execution mode */
7328 ctx
->bstate
= BS_STOP
;
7330 /* 6,7 are implementation dependent */
7332 rn
= "Invalid config selector";
7333 goto cp0_unimplemented
;
7339 gen_helper_mtc0_lladdr(cpu_env
, arg
);
7343 CP0_CHECK(ctx
->mrp
);
7344 gen_helper_mtc0_maar(cpu_env
, arg
);
7348 CP0_CHECK(ctx
->mrp
);
7349 gen_helper_mtc0_maari(cpu_env
, arg
);
7353 goto cp0_unimplemented
;
7359 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
7363 goto cp0_unimplemented
;
7369 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
7373 goto cp0_unimplemented
;
7379 check_insn(ctx
, ISA_MIPS3
);
7380 gen_helper_mtc0_xcontext(cpu_env
, arg
);
7384 goto cp0_unimplemented
;
7388 /* Officially reserved, but sel 0 is used for R1x000 framemask */
7389 CP0_CHECK(!(ctx
->insn_flags
& ISA_MIPS32R6
));
7392 gen_helper_mtc0_framemask(cpu_env
, arg
);
7396 goto cp0_unimplemented
;
7401 rn
= "Diagnostic"; /* implementation dependent */
7406 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
7407 /* BS_STOP isn't good enough here, hflags may have changed. */
7408 gen_save_pc(ctx
->pc
+ 4);
7409 ctx
->bstate
= BS_EXCP
;
7413 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7414 /* Stop translation as we may have switched the execution mode */
7415 ctx
->bstate
= BS_STOP
;
7416 rn
= "TraceControl";
7419 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7420 /* Stop translation as we may have switched the execution mode */
7421 ctx
->bstate
= BS_STOP
;
7422 rn
= "TraceControl2";
7425 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7426 /* Stop translation as we may have switched the execution mode */
7427 ctx
->bstate
= BS_STOP
;
7428 rn
= "UserTraceData";
7431 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7432 /* Stop translation as we may have switched the execution mode */
7433 ctx
->bstate
= BS_STOP
;
7437 goto cp0_unimplemented
;
7444 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
7448 goto cp0_unimplemented
;
7454 gen_helper_mtc0_performance0(cpu_env
, arg
);
7455 rn
= "Performance0";
7458 // gen_helper_mtc0_performance1(cpu_env, arg);
7459 rn
= "Performance1";
7462 // gen_helper_mtc0_performance2(cpu_env, arg);
7463 rn
= "Performance2";
7466 // gen_helper_mtc0_performance3(cpu_env, arg);
7467 rn
= "Performance3";
7470 // gen_helper_mtc0_performance4(cpu_env, arg);
7471 rn
= "Performance4";
7474 // gen_helper_mtc0_performance5(cpu_env, arg);
7475 rn
= "Performance5";
7478 // gen_helper_mtc0_performance6(cpu_env, arg);
7479 rn
= "Performance6";
7482 // gen_helper_mtc0_performance7(cpu_env, arg);
7483 rn
= "Performance7";
7486 goto cp0_unimplemented
;
7492 gen_helper_mtc0_errctl(cpu_env
, arg
);
7493 ctx
->bstate
= BS_STOP
;
7497 goto cp0_unimplemented
;
7507 goto cp0_unimplemented
;
7516 gen_helper_mtc0_taglo(cpu_env
, arg
);
7523 gen_helper_mtc0_datalo(cpu_env
, arg
);
7527 goto cp0_unimplemented
;
7536 gen_helper_mtc0_taghi(cpu_env
, arg
);
7543 gen_helper_mtc0_datahi(cpu_env
, arg
);
7548 goto cp0_unimplemented
;
7554 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7558 goto cp0_unimplemented
;
7565 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7569 CP0_CHECK(ctx
->kscrexist
& (1 << sel
));
7570 tcg_gen_st_tl(arg
, cpu_env
,
7571 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7575 goto cp0_unimplemented
;
7577 /* Stop translation as we may have switched the execution mode */
7578 ctx
->bstate
= BS_STOP
;
7581 goto cp0_unimplemented
;
7583 (void)rn
; /* avoid a compiler warning */
7584 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7585 /* For simplicity assume that all writes can cause interrupts. */
7586 if (ctx
->tb
->cflags
& CF_USE_ICOUNT
) {
7588 ctx
->bstate
= BS_STOP
;
7593 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7595 #endif /* TARGET_MIPS64 */
7597 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
7598 int u
, int sel
, int h
)
7600 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7601 TCGv t0
= tcg_temp_local_new();
7603 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7604 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7605 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7606 tcg_gen_movi_tl(t0
, -1);
7607 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7608 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7609 tcg_gen_movi_tl(t0
, -1);
7615 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
7618 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
7628 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
7631 gen_helper_mftc0_tcbind(t0
, cpu_env
);
7634 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
7637 gen_helper_mftc0_tchalt(t0
, cpu_env
);
7640 gen_helper_mftc0_tccontext(t0
, cpu_env
);
7643 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
7646 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
7649 gen_mfc0(ctx
, t0
, rt
, sel
);
7656 gen_helper_mftc0_entryhi(t0
, cpu_env
);
7659 gen_mfc0(ctx
, t0
, rt
, sel
);
7665 gen_helper_mftc0_status(t0
, cpu_env
);
7668 gen_mfc0(ctx
, t0
, rt
, sel
);
7674 gen_helper_mftc0_cause(t0
, cpu_env
);
7684 gen_helper_mftc0_epc(t0
, cpu_env
);
7694 gen_helper_mftc0_ebase(t0
, cpu_env
);
7704 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
7714 gen_helper_mftc0_debug(t0
, cpu_env
);
7717 gen_mfc0(ctx
, t0
, rt
, sel
);
7722 gen_mfc0(ctx
, t0
, rt
, sel
);
7724 } else switch (sel
) {
7725 /* GPR registers. */
7727 gen_helper_1e0i(mftgpr
, t0
, rt
);
7729 /* Auxiliary CPU registers */
7733 gen_helper_1e0i(mftlo
, t0
, 0);
7736 gen_helper_1e0i(mfthi
, t0
, 0);
7739 gen_helper_1e0i(mftacx
, t0
, 0);
7742 gen_helper_1e0i(mftlo
, t0
, 1);
7745 gen_helper_1e0i(mfthi
, t0
, 1);
7748 gen_helper_1e0i(mftacx
, t0
, 1);
7751 gen_helper_1e0i(mftlo
, t0
, 2);
7754 gen_helper_1e0i(mfthi
, t0
, 2);
7757 gen_helper_1e0i(mftacx
, t0
, 2);
7760 gen_helper_1e0i(mftlo
, t0
, 3);
7763 gen_helper_1e0i(mfthi
, t0
, 3);
7766 gen_helper_1e0i(mftacx
, t0
, 3);
7769 gen_helper_mftdsp(t0
, cpu_env
);
7775 /* Floating point (COP1). */
7777 /* XXX: For now we support only a single FPU context. */
7779 TCGv_i32 fp0
= tcg_temp_new_i32();
7781 gen_load_fpr32(ctx
, fp0
, rt
);
7782 tcg_gen_ext_i32_tl(t0
, fp0
);
7783 tcg_temp_free_i32(fp0
);
7785 TCGv_i32 fp0
= tcg_temp_new_i32();
7787 gen_load_fpr32h(ctx
, fp0
, rt
);
7788 tcg_gen_ext_i32_tl(t0
, fp0
);
7789 tcg_temp_free_i32(fp0
);
7793 /* XXX: For now we support only a single FPU context. */
7794 gen_helper_1e0i(cfc1
, t0
, rt
);
7796 /* COP2: Not implemented. */
7803 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7804 gen_store_gpr(t0
, rd
);
7810 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7811 generate_exception_end(ctx
, EXCP_RI
);
7814 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
7815 int u
, int sel
, int h
)
7817 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7818 TCGv t0
= tcg_temp_local_new();
7820 gen_load_gpr(t0
, rt
);
7821 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7822 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7823 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7825 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7826 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7833 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
7836 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
7846 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
7849 gen_helper_mttc0_tcbind(cpu_env
, t0
);
7852 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
7855 gen_helper_mttc0_tchalt(cpu_env
, t0
);
7858 gen_helper_mttc0_tccontext(cpu_env
, t0
);
7861 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
7864 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
7867 gen_mtc0(ctx
, t0
, rd
, sel
);
7874 gen_helper_mttc0_entryhi(cpu_env
, t0
);
7877 gen_mtc0(ctx
, t0
, rd
, sel
);
7883 gen_helper_mttc0_status(cpu_env
, t0
);
7886 gen_mtc0(ctx
, t0
, rd
, sel
);
7892 gen_helper_mttc0_cause(cpu_env
, t0
);
7902 gen_helper_mttc0_ebase(cpu_env
, t0
);
7912 gen_helper_mttc0_debug(cpu_env
, t0
);
7915 gen_mtc0(ctx
, t0
, rd
, sel
);
7920 gen_mtc0(ctx
, t0
, rd
, sel
);
7922 } else switch (sel
) {
7923 /* GPR registers. */
7925 gen_helper_0e1i(mttgpr
, t0
, rd
);
7927 /* Auxiliary CPU registers */
7931 gen_helper_0e1i(mttlo
, t0
, 0);
7934 gen_helper_0e1i(mtthi
, t0
, 0);
7937 gen_helper_0e1i(mttacx
, t0
, 0);
7940 gen_helper_0e1i(mttlo
, t0
, 1);
7943 gen_helper_0e1i(mtthi
, t0
, 1);
7946 gen_helper_0e1i(mttacx
, t0
, 1);
7949 gen_helper_0e1i(mttlo
, t0
, 2);
7952 gen_helper_0e1i(mtthi
, t0
, 2);
7955 gen_helper_0e1i(mttacx
, t0
, 2);
7958 gen_helper_0e1i(mttlo
, t0
, 3);
7961 gen_helper_0e1i(mtthi
, t0
, 3);
7964 gen_helper_0e1i(mttacx
, t0
, 3);
7967 gen_helper_mttdsp(cpu_env
, t0
);
7973 /* Floating point (COP1). */
7975 /* XXX: For now we support only a single FPU context. */
7977 TCGv_i32 fp0
= tcg_temp_new_i32();
7979 tcg_gen_trunc_tl_i32(fp0
, t0
);
7980 gen_store_fpr32(ctx
, fp0
, rd
);
7981 tcg_temp_free_i32(fp0
);
7983 TCGv_i32 fp0
= tcg_temp_new_i32();
7985 tcg_gen_trunc_tl_i32(fp0
, t0
);
7986 gen_store_fpr32h(ctx
, fp0
, rd
);
7987 tcg_temp_free_i32(fp0
);
7991 /* XXX: For now we support only a single FPU context. */
7993 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
7995 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7996 tcg_temp_free_i32(fs_tmp
);
7998 /* Stop translation as we may have changed hflags */
7999 ctx
->bstate
= BS_STOP
;
8001 /* COP2: Not implemented. */
8008 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
8014 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
8015 generate_exception_end(ctx
, EXCP_RI
);
8018 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
8020 const char *opn
= "ldst";
8022 check_cp0_enabled(ctx
);
8029 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8034 TCGv t0
= tcg_temp_new();
8036 gen_load_gpr(t0
, rt
);
8037 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8042 #if defined(TARGET_MIPS64)
8044 check_insn(ctx
, ISA_MIPS3
);
8049 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8053 check_insn(ctx
, ISA_MIPS3
);
8055 TCGv t0
= tcg_temp_new();
8057 gen_load_gpr(t0
, rt
);
8058 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8070 gen_mfhc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
8076 TCGv t0
= tcg_temp_new();
8077 gen_load_gpr(t0
, rt
);
8078 gen_mthc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
8084 check_insn(ctx
, ASE_MT
);
8089 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
8090 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
8094 check_insn(ctx
, ASE_MT
);
8095 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
8096 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
8101 if (!env
->tlb
->helper_tlbwi
)
8103 gen_helper_tlbwi(cpu_env
);
8108 if (!env
->tlb
->helper_tlbinv
) {
8111 gen_helper_tlbinv(cpu_env
);
8112 } /* treat as nop if TLBINV not supported */
8117 if (!env
->tlb
->helper_tlbinvf
) {
8120 gen_helper_tlbinvf(cpu_env
);
8121 } /* treat as nop if TLBINV not supported */
8125 if (!env
->tlb
->helper_tlbwr
)
8127 gen_helper_tlbwr(cpu_env
);
8131 if (!env
->tlb
->helper_tlbp
)
8133 gen_helper_tlbp(cpu_env
);
8137 if (!env
->tlb
->helper_tlbr
)
8139 gen_helper_tlbr(cpu_env
);
8141 case OPC_ERET
: /* OPC_ERETNC */
8142 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8143 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8146 int bit_shift
= (ctx
->hflags
& MIPS_HFLAG_M16
) ? 16 : 6;
8147 if (ctx
->opcode
& (1 << bit_shift
)) {
8150 check_insn(ctx
, ISA_MIPS32R5
);
8151 gen_helper_eretnc(cpu_env
);
8155 check_insn(ctx
, ISA_MIPS2
);
8156 gen_helper_eret(cpu_env
);
8158 ctx
->bstate
= BS_EXCP
;
8163 check_insn(ctx
, ISA_MIPS32
);
8164 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8165 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8168 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
8170 generate_exception_end(ctx
, EXCP_RI
);
8172 gen_helper_deret(cpu_env
);
8173 ctx
->bstate
= BS_EXCP
;
8178 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
8179 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
8180 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8183 /* If we get an exception, we want to restart at next instruction */
8185 save_cpu_state(ctx
, 1);
8187 gen_helper_wait(cpu_env
);
8188 ctx
->bstate
= BS_EXCP
;
8193 generate_exception_end(ctx
, EXCP_RI
);
8196 (void)opn
; /* avoid a compiler warning */
8198 #endif /* !CONFIG_USER_ONLY */
8200 /* CP1 Branches (before delay slot) */
8201 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
8202 int32_t cc
, int32_t offset
)
8204 target_ulong btarget
;
8205 TCGv_i32 t0
= tcg_temp_new_i32();
8207 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
8208 generate_exception_end(ctx
, EXCP_RI
);
8213 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
8215 btarget
= ctx
->pc
+ 4 + offset
;
8219 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8220 tcg_gen_not_i32(t0
, t0
);
8221 tcg_gen_andi_i32(t0
, t0
, 1);
8222 tcg_gen_extu_i32_tl(bcond
, t0
);
8225 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8226 tcg_gen_not_i32(t0
, t0
);
8227 tcg_gen_andi_i32(t0
, t0
, 1);
8228 tcg_gen_extu_i32_tl(bcond
, t0
);
8231 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8232 tcg_gen_andi_i32(t0
, t0
, 1);
8233 tcg_gen_extu_i32_tl(bcond
, t0
);
8236 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8237 tcg_gen_andi_i32(t0
, t0
, 1);
8238 tcg_gen_extu_i32_tl(bcond
, t0
);
8240 ctx
->hflags
|= MIPS_HFLAG_BL
;
8244 TCGv_i32 t1
= tcg_temp_new_i32();
8245 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8246 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8247 tcg_gen_nand_i32(t0
, t0
, t1
);
8248 tcg_temp_free_i32(t1
);
8249 tcg_gen_andi_i32(t0
, t0
, 1);
8250 tcg_gen_extu_i32_tl(bcond
, t0
);
8255 TCGv_i32 t1
= tcg_temp_new_i32();
8256 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8257 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8258 tcg_gen_or_i32(t0
, t0
, t1
);
8259 tcg_temp_free_i32(t1
);
8260 tcg_gen_andi_i32(t0
, t0
, 1);
8261 tcg_gen_extu_i32_tl(bcond
, t0
);
8266 TCGv_i32 t1
= tcg_temp_new_i32();
8267 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8268 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8269 tcg_gen_and_i32(t0
, t0
, t1
);
8270 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8271 tcg_gen_and_i32(t0
, t0
, t1
);
8272 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8273 tcg_gen_nand_i32(t0
, t0
, t1
);
8274 tcg_temp_free_i32(t1
);
8275 tcg_gen_andi_i32(t0
, t0
, 1);
8276 tcg_gen_extu_i32_tl(bcond
, t0
);
8281 TCGv_i32 t1
= tcg_temp_new_i32();
8282 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
8283 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
8284 tcg_gen_or_i32(t0
, t0
, t1
);
8285 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
8286 tcg_gen_or_i32(t0
, t0
, t1
);
8287 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
8288 tcg_gen_or_i32(t0
, t0
, t1
);
8289 tcg_temp_free_i32(t1
);
8290 tcg_gen_andi_i32(t0
, t0
, 1);
8291 tcg_gen_extu_i32_tl(bcond
, t0
);
8294 ctx
->hflags
|= MIPS_HFLAG_BC
;
8297 MIPS_INVAL("cp1 cond branch");
8298 generate_exception_end(ctx
, EXCP_RI
);
8301 ctx
->btarget
= btarget
;
8302 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8304 tcg_temp_free_i32(t0
);
8307 /* R6 CP1 Branches */
8308 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
8309 int32_t ft
, int32_t offset
,
8312 target_ulong btarget
;
8313 TCGv_i64 t0
= tcg_temp_new_i64();
8315 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
8316 #ifdef MIPS_DEBUG_DISAS
8317 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
8320 generate_exception_end(ctx
, EXCP_RI
);
8324 gen_load_fpr64(ctx
, t0
, ft
);
8325 tcg_gen_andi_i64(t0
, t0
, 1);
8327 btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
8331 tcg_gen_xori_i64(t0
, t0
, 1);
8332 ctx
->hflags
|= MIPS_HFLAG_BC
;
8335 /* t0 already set */
8336 ctx
->hflags
|= MIPS_HFLAG_BC
;
8339 MIPS_INVAL("cp1 cond branch");
8340 generate_exception_end(ctx
, EXCP_RI
);
8344 tcg_gen_trunc_i64_tl(bcond
, t0
);
8346 ctx
->btarget
= btarget
;
8348 switch (delayslot_size
) {
8350 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
8353 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
8358 tcg_temp_free_i64(t0
);
8361 /* Coprocessor 1 (FPU) */
8363 #define FOP(func, fmt) (((fmt) << 21) | (func))
8366 OPC_ADD_S
= FOP(0, FMT_S
),
8367 OPC_SUB_S
= FOP(1, FMT_S
),
8368 OPC_MUL_S
= FOP(2, FMT_S
),
8369 OPC_DIV_S
= FOP(3, FMT_S
),
8370 OPC_SQRT_S
= FOP(4, FMT_S
),
8371 OPC_ABS_S
= FOP(5, FMT_S
),
8372 OPC_MOV_S
= FOP(6, FMT_S
),
8373 OPC_NEG_S
= FOP(7, FMT_S
),
8374 OPC_ROUND_L_S
= FOP(8, FMT_S
),
8375 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
8376 OPC_CEIL_L_S
= FOP(10, FMT_S
),
8377 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
8378 OPC_ROUND_W_S
= FOP(12, FMT_S
),
8379 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
8380 OPC_CEIL_W_S
= FOP(14, FMT_S
),
8381 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
8382 OPC_SEL_S
= FOP(16, FMT_S
),
8383 OPC_MOVCF_S
= FOP(17, FMT_S
),
8384 OPC_MOVZ_S
= FOP(18, FMT_S
),
8385 OPC_MOVN_S
= FOP(19, FMT_S
),
8386 OPC_SELEQZ_S
= FOP(20, FMT_S
),
8387 OPC_RECIP_S
= FOP(21, FMT_S
),
8388 OPC_RSQRT_S
= FOP(22, FMT_S
),
8389 OPC_SELNEZ_S
= FOP(23, FMT_S
),
8390 OPC_MADDF_S
= FOP(24, FMT_S
),
8391 OPC_MSUBF_S
= FOP(25, FMT_S
),
8392 OPC_RINT_S
= FOP(26, FMT_S
),
8393 OPC_CLASS_S
= FOP(27, FMT_S
),
8394 OPC_MIN_S
= FOP(28, FMT_S
),
8395 OPC_RECIP2_S
= FOP(28, FMT_S
),
8396 OPC_MINA_S
= FOP(29, FMT_S
),
8397 OPC_RECIP1_S
= FOP(29, FMT_S
),
8398 OPC_MAX_S
= FOP(30, FMT_S
),
8399 OPC_RSQRT1_S
= FOP(30, FMT_S
),
8400 OPC_MAXA_S
= FOP(31, FMT_S
),
8401 OPC_RSQRT2_S
= FOP(31, FMT_S
),
8402 OPC_CVT_D_S
= FOP(33, FMT_S
),
8403 OPC_CVT_W_S
= FOP(36, FMT_S
),
8404 OPC_CVT_L_S
= FOP(37, FMT_S
),
8405 OPC_CVT_PS_S
= FOP(38, FMT_S
),
8406 OPC_CMP_F_S
= FOP (48, FMT_S
),
8407 OPC_CMP_UN_S
= FOP (49, FMT_S
),
8408 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
8409 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
8410 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
8411 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
8412 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
8413 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
8414 OPC_CMP_SF_S
= FOP (56, FMT_S
),
8415 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
8416 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
8417 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
8418 OPC_CMP_LT_S
= FOP (60, FMT_S
),
8419 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
8420 OPC_CMP_LE_S
= FOP (62, FMT_S
),
8421 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
8423 OPC_ADD_D
= FOP(0, FMT_D
),
8424 OPC_SUB_D
= FOP(1, FMT_D
),
8425 OPC_MUL_D
= FOP(2, FMT_D
),
8426 OPC_DIV_D
= FOP(3, FMT_D
),
8427 OPC_SQRT_D
= FOP(4, FMT_D
),
8428 OPC_ABS_D
= FOP(5, FMT_D
),
8429 OPC_MOV_D
= FOP(6, FMT_D
),
8430 OPC_NEG_D
= FOP(7, FMT_D
),
8431 OPC_ROUND_L_D
= FOP(8, FMT_D
),
8432 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
8433 OPC_CEIL_L_D
= FOP(10, FMT_D
),
8434 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
8435 OPC_ROUND_W_D
= FOP(12, FMT_D
),
8436 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
8437 OPC_CEIL_W_D
= FOP(14, FMT_D
),
8438 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
8439 OPC_SEL_D
= FOP(16, FMT_D
),
8440 OPC_MOVCF_D
= FOP(17, FMT_D
),
8441 OPC_MOVZ_D
= FOP(18, FMT_D
),
8442 OPC_MOVN_D
= FOP(19, FMT_D
),
8443 OPC_SELEQZ_D
= FOP(20, FMT_D
),
8444 OPC_RECIP_D
= FOP(21, FMT_D
),
8445 OPC_RSQRT_D
= FOP(22, FMT_D
),
8446 OPC_SELNEZ_D
= FOP(23, FMT_D
),
8447 OPC_MADDF_D
= FOP(24, FMT_D
),
8448 OPC_MSUBF_D
= FOP(25, FMT_D
),
8449 OPC_RINT_D
= FOP(26, FMT_D
),
8450 OPC_CLASS_D
= FOP(27, FMT_D
),
8451 OPC_MIN_D
= FOP(28, FMT_D
),
8452 OPC_RECIP2_D
= FOP(28, FMT_D
),
8453 OPC_MINA_D
= FOP(29, FMT_D
),
8454 OPC_RECIP1_D
= FOP(29, FMT_D
),
8455 OPC_MAX_D
= FOP(30, FMT_D
),
8456 OPC_RSQRT1_D
= FOP(30, FMT_D
),
8457 OPC_MAXA_D
= FOP(31, FMT_D
),
8458 OPC_RSQRT2_D
= FOP(31, FMT_D
),
8459 OPC_CVT_S_D
= FOP(32, FMT_D
),
8460 OPC_CVT_W_D
= FOP(36, FMT_D
),
8461 OPC_CVT_L_D
= FOP(37, FMT_D
),
8462 OPC_CMP_F_D
= FOP (48, FMT_D
),
8463 OPC_CMP_UN_D
= FOP (49, FMT_D
),
8464 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
8465 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
8466 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
8467 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
8468 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
8469 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
8470 OPC_CMP_SF_D
= FOP (56, FMT_D
),
8471 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
8472 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
8473 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
8474 OPC_CMP_LT_D
= FOP (60, FMT_D
),
8475 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
8476 OPC_CMP_LE_D
= FOP (62, FMT_D
),
8477 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
8479 OPC_CVT_S_W
= FOP(32, FMT_W
),
8480 OPC_CVT_D_W
= FOP(33, FMT_W
),
8481 OPC_CVT_S_L
= FOP(32, FMT_L
),
8482 OPC_CVT_D_L
= FOP(33, FMT_L
),
8483 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
8485 OPC_ADD_PS
= FOP(0, FMT_PS
),
8486 OPC_SUB_PS
= FOP(1, FMT_PS
),
8487 OPC_MUL_PS
= FOP(2, FMT_PS
),
8488 OPC_DIV_PS
= FOP(3, FMT_PS
),
8489 OPC_ABS_PS
= FOP(5, FMT_PS
),
8490 OPC_MOV_PS
= FOP(6, FMT_PS
),
8491 OPC_NEG_PS
= FOP(7, FMT_PS
),
8492 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
8493 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
8494 OPC_MOVN_PS
= FOP(19, FMT_PS
),
8495 OPC_ADDR_PS
= FOP(24, FMT_PS
),
8496 OPC_MULR_PS
= FOP(26, FMT_PS
),
8497 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
8498 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
8499 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
8500 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
8502 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
8503 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
8504 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
8505 OPC_PLL_PS
= FOP(44, FMT_PS
),
8506 OPC_PLU_PS
= FOP(45, FMT_PS
),
8507 OPC_PUL_PS
= FOP(46, FMT_PS
),
8508 OPC_PUU_PS
= FOP(47, FMT_PS
),
8509 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
8510 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
8511 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
8512 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
8513 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
8514 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
8515 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
8516 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
8517 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
8518 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
8519 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
8520 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
8521 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
8522 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
8523 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
8524 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
8528 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
8529 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
8530 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
8531 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
8532 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
8533 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
8534 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
8535 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
8536 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
8537 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
8538 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
8539 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
8540 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
8541 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
8542 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
8543 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
8544 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
8545 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
8546 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
8547 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
8548 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
8549 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
8551 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
8552 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
8553 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
8554 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
8555 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
8556 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
8557 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
8558 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
8559 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
8560 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
8561 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
8562 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
8563 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
8564 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
8565 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
8566 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
8567 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
8568 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
8569 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
8570 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
8571 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
8572 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
8574 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
8576 TCGv t0
= tcg_temp_new();
8581 TCGv_i32 fp0
= tcg_temp_new_i32();
8583 gen_load_fpr32(ctx
, fp0
, fs
);
8584 tcg_gen_ext_i32_tl(t0
, fp0
);
8585 tcg_temp_free_i32(fp0
);
8587 gen_store_gpr(t0
, rt
);
8590 gen_load_gpr(t0
, rt
);
8592 TCGv_i32 fp0
= tcg_temp_new_i32();
8594 tcg_gen_trunc_tl_i32(fp0
, t0
);
8595 gen_store_fpr32(ctx
, fp0
, fs
);
8596 tcg_temp_free_i32(fp0
);
8600 gen_helper_1e0i(cfc1
, t0
, fs
);
8601 gen_store_gpr(t0
, rt
);
8604 gen_load_gpr(t0
, rt
);
8605 save_cpu_state(ctx
, 0);
8607 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
8609 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8610 tcg_temp_free_i32(fs_tmp
);
8612 /* Stop translation as we may have changed hflags */
8613 ctx
->bstate
= BS_STOP
;
8615 #if defined(TARGET_MIPS64)
8617 gen_load_fpr64(ctx
, t0
, fs
);
8618 gen_store_gpr(t0
, rt
);
8621 gen_load_gpr(t0
, rt
);
8622 gen_store_fpr64(ctx
, t0
, fs
);
8627 TCGv_i32 fp0
= tcg_temp_new_i32();
8629 gen_load_fpr32h(ctx
, fp0
, fs
);
8630 tcg_gen_ext_i32_tl(t0
, fp0
);
8631 tcg_temp_free_i32(fp0
);
8633 gen_store_gpr(t0
, rt
);
8636 gen_load_gpr(t0
, rt
);
8638 TCGv_i32 fp0
= tcg_temp_new_i32();
8640 tcg_gen_trunc_tl_i32(fp0
, t0
);
8641 gen_store_fpr32h(ctx
, fp0
, fs
);
8642 tcg_temp_free_i32(fp0
);
8646 MIPS_INVAL("cp1 move");
8647 generate_exception_end(ctx
, EXCP_RI
);
8655 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
8671 l1
= gen_new_label();
8672 t0
= tcg_temp_new_i32();
8673 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8674 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8675 tcg_temp_free_i32(t0
);
8677 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
8679 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
8684 static inline void gen_movcf_s(DisasContext
*ctx
, int fs
, int fd
, int cc
,
8688 TCGv_i32 t0
= tcg_temp_new_i32();
8689 TCGLabel
*l1
= gen_new_label();
8696 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8697 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8698 gen_load_fpr32(ctx
, t0
, fs
);
8699 gen_store_fpr32(ctx
, t0
, fd
);
8701 tcg_temp_free_i32(t0
);
8704 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
8707 TCGv_i32 t0
= tcg_temp_new_i32();
8709 TCGLabel
*l1
= gen_new_label();
8716 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8717 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8718 tcg_temp_free_i32(t0
);
8719 fp0
= tcg_temp_new_i64();
8720 gen_load_fpr64(ctx
, fp0
, fs
);
8721 gen_store_fpr64(ctx
, fp0
, fd
);
8722 tcg_temp_free_i64(fp0
);
8726 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
8730 TCGv_i32 t0
= tcg_temp_new_i32();
8731 TCGLabel
*l1
= gen_new_label();
8732 TCGLabel
*l2
= gen_new_label();
8739 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8740 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8741 gen_load_fpr32(ctx
, t0
, fs
);
8742 gen_store_fpr32(ctx
, t0
, fd
);
8745 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
8746 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
8747 gen_load_fpr32h(ctx
, t0
, fs
);
8748 gen_store_fpr32h(ctx
, t0
, fd
);
8749 tcg_temp_free_i32(t0
);
8753 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8756 TCGv_i32 t1
= tcg_const_i32(0);
8757 TCGv_i32 fp0
= tcg_temp_new_i32();
8758 TCGv_i32 fp1
= tcg_temp_new_i32();
8759 TCGv_i32 fp2
= tcg_temp_new_i32();
8760 gen_load_fpr32(ctx
, fp0
, fd
);
8761 gen_load_fpr32(ctx
, fp1
, ft
);
8762 gen_load_fpr32(ctx
, fp2
, fs
);
8766 tcg_gen_andi_i32(fp0
, fp0
, 1);
8767 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8770 tcg_gen_andi_i32(fp1
, fp1
, 1);
8771 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8774 tcg_gen_andi_i32(fp1
, fp1
, 1);
8775 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8778 MIPS_INVAL("gen_sel_s");
8779 generate_exception_end(ctx
, EXCP_RI
);
8783 gen_store_fpr32(ctx
, fp0
, fd
);
8784 tcg_temp_free_i32(fp2
);
8785 tcg_temp_free_i32(fp1
);
8786 tcg_temp_free_i32(fp0
);
8787 tcg_temp_free_i32(t1
);
8790 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8793 TCGv_i64 t1
= tcg_const_i64(0);
8794 TCGv_i64 fp0
= tcg_temp_new_i64();
8795 TCGv_i64 fp1
= tcg_temp_new_i64();
8796 TCGv_i64 fp2
= tcg_temp_new_i64();
8797 gen_load_fpr64(ctx
, fp0
, fd
);
8798 gen_load_fpr64(ctx
, fp1
, ft
);
8799 gen_load_fpr64(ctx
, fp2
, fs
);
8803 tcg_gen_andi_i64(fp0
, fp0
, 1);
8804 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8807 tcg_gen_andi_i64(fp1
, fp1
, 1);
8808 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8811 tcg_gen_andi_i64(fp1
, fp1
, 1);
8812 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8815 MIPS_INVAL("gen_sel_d");
8816 generate_exception_end(ctx
, EXCP_RI
);
8820 gen_store_fpr64(ctx
, fp0
, fd
);
8821 tcg_temp_free_i64(fp2
);
8822 tcg_temp_free_i64(fp1
);
8823 tcg_temp_free_i64(fp0
);
8824 tcg_temp_free_i64(t1
);
8827 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
8828 int ft
, int fs
, int fd
, int cc
)
8830 uint32_t func
= ctx
->opcode
& 0x3f;
8834 TCGv_i32 fp0
= tcg_temp_new_i32();
8835 TCGv_i32 fp1
= tcg_temp_new_i32();
8837 gen_load_fpr32(ctx
, fp0
, fs
);
8838 gen_load_fpr32(ctx
, fp1
, ft
);
8839 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
8840 tcg_temp_free_i32(fp1
);
8841 gen_store_fpr32(ctx
, fp0
, fd
);
8842 tcg_temp_free_i32(fp0
);
8847 TCGv_i32 fp0
= tcg_temp_new_i32();
8848 TCGv_i32 fp1
= tcg_temp_new_i32();
8850 gen_load_fpr32(ctx
, fp0
, fs
);
8851 gen_load_fpr32(ctx
, fp1
, ft
);
8852 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
8853 tcg_temp_free_i32(fp1
);
8854 gen_store_fpr32(ctx
, fp0
, fd
);
8855 tcg_temp_free_i32(fp0
);
8860 TCGv_i32 fp0
= tcg_temp_new_i32();
8861 TCGv_i32 fp1
= tcg_temp_new_i32();
8863 gen_load_fpr32(ctx
, fp0
, fs
);
8864 gen_load_fpr32(ctx
, fp1
, ft
);
8865 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
8866 tcg_temp_free_i32(fp1
);
8867 gen_store_fpr32(ctx
, fp0
, fd
);
8868 tcg_temp_free_i32(fp0
);
8873 TCGv_i32 fp0
= tcg_temp_new_i32();
8874 TCGv_i32 fp1
= tcg_temp_new_i32();
8876 gen_load_fpr32(ctx
, fp0
, fs
);
8877 gen_load_fpr32(ctx
, fp1
, ft
);
8878 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
8879 tcg_temp_free_i32(fp1
);
8880 gen_store_fpr32(ctx
, fp0
, fd
);
8881 tcg_temp_free_i32(fp0
);
8886 TCGv_i32 fp0
= tcg_temp_new_i32();
8888 gen_load_fpr32(ctx
, fp0
, fs
);
8889 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
8890 gen_store_fpr32(ctx
, fp0
, fd
);
8891 tcg_temp_free_i32(fp0
);
8896 TCGv_i32 fp0
= tcg_temp_new_i32();
8898 gen_load_fpr32(ctx
, fp0
, fs
);
8900 tcg_gen_andi_i32(fp0
, fp0
, 0x7fffffffUL
);
8902 gen_helper_float_abs_s(fp0
, fp0
);
8904 gen_store_fpr32(ctx
, fp0
, fd
);
8905 tcg_temp_free_i32(fp0
);
8910 TCGv_i32 fp0
= tcg_temp_new_i32();
8912 gen_load_fpr32(ctx
, fp0
, fs
);
8913 gen_store_fpr32(ctx
, fp0
, fd
);
8914 tcg_temp_free_i32(fp0
);
8919 TCGv_i32 fp0
= tcg_temp_new_i32();
8921 gen_load_fpr32(ctx
, fp0
, fs
);
8923 tcg_gen_xori_i32(fp0
, fp0
, 1UL << 31);
8925 gen_helper_float_chs_s(fp0
, fp0
);
8927 gen_store_fpr32(ctx
, fp0
, fd
);
8928 tcg_temp_free_i32(fp0
);
8932 check_cp1_64bitmode(ctx
);
8934 TCGv_i32 fp32
= tcg_temp_new_i32();
8935 TCGv_i64 fp64
= tcg_temp_new_i64();
8937 gen_load_fpr32(ctx
, fp32
, fs
);
8939 gen_helper_float_round_2008_l_s(fp64
, cpu_env
, fp32
);
8941 gen_helper_float_round_l_s(fp64
, cpu_env
, fp32
);
8943 tcg_temp_free_i32(fp32
);
8944 gen_store_fpr64(ctx
, fp64
, fd
);
8945 tcg_temp_free_i64(fp64
);
8949 check_cp1_64bitmode(ctx
);
8951 TCGv_i32 fp32
= tcg_temp_new_i32();
8952 TCGv_i64 fp64
= tcg_temp_new_i64();
8954 gen_load_fpr32(ctx
, fp32
, fs
);
8956 gen_helper_float_trunc_2008_l_s(fp64
, cpu_env
, fp32
);
8958 gen_helper_float_trunc_l_s(fp64
, cpu_env
, fp32
);
8960 tcg_temp_free_i32(fp32
);
8961 gen_store_fpr64(ctx
, fp64
, fd
);
8962 tcg_temp_free_i64(fp64
);
8966 check_cp1_64bitmode(ctx
);
8968 TCGv_i32 fp32
= tcg_temp_new_i32();
8969 TCGv_i64 fp64
= tcg_temp_new_i64();
8971 gen_load_fpr32(ctx
, fp32
, fs
);
8973 gen_helper_float_ceil_2008_l_s(fp64
, cpu_env
, fp32
);
8975 gen_helper_float_ceil_l_s(fp64
, cpu_env
, fp32
);
8977 tcg_temp_free_i32(fp32
);
8978 gen_store_fpr64(ctx
, fp64
, fd
);
8979 tcg_temp_free_i64(fp64
);
8983 check_cp1_64bitmode(ctx
);
8985 TCGv_i32 fp32
= tcg_temp_new_i32();
8986 TCGv_i64 fp64
= tcg_temp_new_i64();
8988 gen_load_fpr32(ctx
, fp32
, fs
);
8990 gen_helper_float_floor_2008_l_s(fp64
, cpu_env
, fp32
);
8992 gen_helper_float_floor_l_s(fp64
, cpu_env
, fp32
);
8994 tcg_temp_free_i32(fp32
);
8995 gen_store_fpr64(ctx
, fp64
, fd
);
8996 tcg_temp_free_i64(fp64
);
9001 TCGv_i32 fp0
= tcg_temp_new_i32();
9003 gen_load_fpr32(ctx
, fp0
, fs
);
9005 gen_helper_float_round_2008_w_s(fp0
, cpu_env
, fp0
);
9007 gen_helper_float_round_w_s(fp0
, cpu_env
, fp0
);
9009 gen_store_fpr32(ctx
, fp0
, fd
);
9010 tcg_temp_free_i32(fp0
);
9015 TCGv_i32 fp0
= tcg_temp_new_i32();
9017 gen_load_fpr32(ctx
, fp0
, fs
);
9019 gen_helper_float_trunc_2008_w_s(fp0
, cpu_env
, fp0
);
9021 gen_helper_float_trunc_w_s(fp0
, cpu_env
, fp0
);
9023 gen_store_fpr32(ctx
, fp0
, fd
);
9024 tcg_temp_free_i32(fp0
);
9029 TCGv_i32 fp0
= tcg_temp_new_i32();
9031 gen_load_fpr32(ctx
, fp0
, fs
);
9033 gen_helper_float_ceil_2008_w_s(fp0
, cpu_env
, fp0
);
9035 gen_helper_float_ceil_w_s(fp0
, cpu_env
, fp0
);
9037 gen_store_fpr32(ctx
, fp0
, fd
);
9038 tcg_temp_free_i32(fp0
);
9043 TCGv_i32 fp0
= tcg_temp_new_i32();
9045 gen_load_fpr32(ctx
, fp0
, fs
);
9047 gen_helper_float_floor_2008_w_s(fp0
, cpu_env
, fp0
);
9049 gen_helper_float_floor_w_s(fp0
, cpu_env
, fp0
);
9051 gen_store_fpr32(ctx
, fp0
, fd
);
9052 tcg_temp_free_i32(fp0
);
9056 check_insn(ctx
, ISA_MIPS32R6
);
9057 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9060 check_insn(ctx
, ISA_MIPS32R6
);
9061 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9064 check_insn(ctx
, ISA_MIPS32R6
);
9065 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
9068 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9069 gen_movcf_s(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9072 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9074 TCGLabel
*l1
= gen_new_label();
9078 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9080 fp0
= tcg_temp_new_i32();
9081 gen_load_fpr32(ctx
, fp0
, fs
);
9082 gen_store_fpr32(ctx
, fp0
, fd
);
9083 tcg_temp_free_i32(fp0
);
9088 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9090 TCGLabel
*l1
= gen_new_label();
9094 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9095 fp0
= tcg_temp_new_i32();
9096 gen_load_fpr32(ctx
, fp0
, fs
);
9097 gen_store_fpr32(ctx
, fp0
, fd
);
9098 tcg_temp_free_i32(fp0
);
9105 TCGv_i32 fp0
= tcg_temp_new_i32();
9107 gen_load_fpr32(ctx
, fp0
, fs
);
9108 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
9109 gen_store_fpr32(ctx
, fp0
, fd
);
9110 tcg_temp_free_i32(fp0
);
9115 TCGv_i32 fp0
= tcg_temp_new_i32();
9117 gen_load_fpr32(ctx
, fp0
, fs
);
9118 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
9119 gen_store_fpr32(ctx
, fp0
, fd
);
9120 tcg_temp_free_i32(fp0
);
9124 check_insn(ctx
, ISA_MIPS32R6
);
9126 TCGv_i32 fp0
= tcg_temp_new_i32();
9127 TCGv_i32 fp1
= tcg_temp_new_i32();
9128 TCGv_i32 fp2
= tcg_temp_new_i32();
9129 gen_load_fpr32(ctx
, fp0
, fs
);
9130 gen_load_fpr32(ctx
, fp1
, ft
);
9131 gen_load_fpr32(ctx
, fp2
, fd
);
9132 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9133 gen_store_fpr32(ctx
, fp2
, fd
);
9134 tcg_temp_free_i32(fp2
);
9135 tcg_temp_free_i32(fp1
);
9136 tcg_temp_free_i32(fp0
);
9140 check_insn(ctx
, ISA_MIPS32R6
);
9142 TCGv_i32 fp0
= tcg_temp_new_i32();
9143 TCGv_i32 fp1
= tcg_temp_new_i32();
9144 TCGv_i32 fp2
= tcg_temp_new_i32();
9145 gen_load_fpr32(ctx
, fp0
, fs
);
9146 gen_load_fpr32(ctx
, fp1
, ft
);
9147 gen_load_fpr32(ctx
, fp2
, fd
);
9148 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9149 gen_store_fpr32(ctx
, fp2
, fd
);
9150 tcg_temp_free_i32(fp2
);
9151 tcg_temp_free_i32(fp1
);
9152 tcg_temp_free_i32(fp0
);
9156 check_insn(ctx
, ISA_MIPS32R6
);
9158 TCGv_i32 fp0
= tcg_temp_new_i32();
9159 gen_load_fpr32(ctx
, fp0
, fs
);
9160 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
9161 gen_store_fpr32(ctx
, fp0
, fd
);
9162 tcg_temp_free_i32(fp0
);
9166 check_insn(ctx
, ISA_MIPS32R6
);
9168 TCGv_i32 fp0
= tcg_temp_new_i32();
9169 gen_load_fpr32(ctx
, fp0
, fs
);
9170 gen_helper_float_class_s(fp0
, cpu_env
, fp0
);
9171 gen_store_fpr32(ctx
, fp0
, fd
);
9172 tcg_temp_free_i32(fp0
);
9175 case OPC_MIN_S
: /* OPC_RECIP2_S */
9176 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9178 TCGv_i32 fp0
= tcg_temp_new_i32();
9179 TCGv_i32 fp1
= tcg_temp_new_i32();
9180 TCGv_i32 fp2
= tcg_temp_new_i32();
9181 gen_load_fpr32(ctx
, fp0
, fs
);
9182 gen_load_fpr32(ctx
, fp1
, ft
);
9183 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
9184 gen_store_fpr32(ctx
, fp2
, fd
);
9185 tcg_temp_free_i32(fp2
);
9186 tcg_temp_free_i32(fp1
);
9187 tcg_temp_free_i32(fp0
);
9190 check_cp1_64bitmode(ctx
);
9192 TCGv_i32 fp0
= tcg_temp_new_i32();
9193 TCGv_i32 fp1
= tcg_temp_new_i32();
9195 gen_load_fpr32(ctx
, fp0
, fs
);
9196 gen_load_fpr32(ctx
, fp1
, ft
);
9197 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
9198 tcg_temp_free_i32(fp1
);
9199 gen_store_fpr32(ctx
, fp0
, fd
);
9200 tcg_temp_free_i32(fp0
);
9204 case OPC_MINA_S
: /* OPC_RECIP1_S */
9205 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9207 TCGv_i32 fp0
= tcg_temp_new_i32();
9208 TCGv_i32 fp1
= tcg_temp_new_i32();
9209 TCGv_i32 fp2
= tcg_temp_new_i32();
9210 gen_load_fpr32(ctx
, fp0
, fs
);
9211 gen_load_fpr32(ctx
, fp1
, ft
);
9212 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
9213 gen_store_fpr32(ctx
, fp2
, fd
);
9214 tcg_temp_free_i32(fp2
);
9215 tcg_temp_free_i32(fp1
);
9216 tcg_temp_free_i32(fp0
);
9219 check_cp1_64bitmode(ctx
);
9221 TCGv_i32 fp0
= tcg_temp_new_i32();
9223 gen_load_fpr32(ctx
, fp0
, fs
);
9224 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
9225 gen_store_fpr32(ctx
, fp0
, fd
);
9226 tcg_temp_free_i32(fp0
);
9230 case OPC_MAX_S
: /* OPC_RSQRT1_S */
9231 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9233 TCGv_i32 fp0
= tcg_temp_new_i32();
9234 TCGv_i32 fp1
= tcg_temp_new_i32();
9235 gen_load_fpr32(ctx
, fp0
, fs
);
9236 gen_load_fpr32(ctx
, fp1
, ft
);
9237 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
9238 gen_store_fpr32(ctx
, fp1
, fd
);
9239 tcg_temp_free_i32(fp1
);
9240 tcg_temp_free_i32(fp0
);
9243 check_cp1_64bitmode(ctx
);
9245 TCGv_i32 fp0
= tcg_temp_new_i32();
9247 gen_load_fpr32(ctx
, fp0
, fs
);
9248 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
9249 gen_store_fpr32(ctx
, fp0
, fd
);
9250 tcg_temp_free_i32(fp0
);
9254 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
9255 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9257 TCGv_i32 fp0
= tcg_temp_new_i32();
9258 TCGv_i32 fp1
= tcg_temp_new_i32();
9259 gen_load_fpr32(ctx
, fp0
, fs
);
9260 gen_load_fpr32(ctx
, fp1
, ft
);
9261 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
9262 gen_store_fpr32(ctx
, fp1
, fd
);
9263 tcg_temp_free_i32(fp1
);
9264 tcg_temp_free_i32(fp0
);
9267 check_cp1_64bitmode(ctx
);
9269 TCGv_i32 fp0
= tcg_temp_new_i32();
9270 TCGv_i32 fp1
= tcg_temp_new_i32();
9272 gen_load_fpr32(ctx
, fp0
, fs
);
9273 gen_load_fpr32(ctx
, fp1
, ft
);
9274 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
9275 tcg_temp_free_i32(fp1
);
9276 gen_store_fpr32(ctx
, fp0
, fd
);
9277 tcg_temp_free_i32(fp0
);
9282 check_cp1_registers(ctx
, fd
);
9284 TCGv_i32 fp32
= tcg_temp_new_i32();
9285 TCGv_i64 fp64
= tcg_temp_new_i64();
9287 gen_load_fpr32(ctx
, fp32
, fs
);
9288 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
9289 tcg_temp_free_i32(fp32
);
9290 gen_store_fpr64(ctx
, fp64
, fd
);
9291 tcg_temp_free_i64(fp64
);
9296 TCGv_i32 fp0
= tcg_temp_new_i32();
9298 gen_load_fpr32(ctx
, fp0
, fs
);
9300 gen_helper_float_cvt_2008_w_s(fp0
, cpu_env
, fp0
);
9302 gen_helper_float_cvt_w_s(fp0
, cpu_env
, fp0
);
9304 gen_store_fpr32(ctx
, fp0
, fd
);
9305 tcg_temp_free_i32(fp0
);
9309 check_cp1_64bitmode(ctx
);
9311 TCGv_i32 fp32
= tcg_temp_new_i32();
9312 TCGv_i64 fp64
= tcg_temp_new_i64();
9314 gen_load_fpr32(ctx
, fp32
, fs
);
9316 gen_helper_float_cvt_2008_l_s(fp64
, cpu_env
, fp32
);
9318 gen_helper_float_cvt_l_s(fp64
, cpu_env
, fp32
);
9320 tcg_temp_free_i32(fp32
);
9321 gen_store_fpr64(ctx
, fp64
, fd
);
9322 tcg_temp_free_i64(fp64
);
9328 TCGv_i64 fp64
= tcg_temp_new_i64();
9329 TCGv_i32 fp32_0
= tcg_temp_new_i32();
9330 TCGv_i32 fp32_1
= tcg_temp_new_i32();
9332 gen_load_fpr32(ctx
, fp32_0
, fs
);
9333 gen_load_fpr32(ctx
, fp32_1
, ft
);
9334 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
9335 tcg_temp_free_i32(fp32_1
);
9336 tcg_temp_free_i32(fp32_0
);
9337 gen_store_fpr64(ctx
, fp64
, fd
);
9338 tcg_temp_free_i64(fp64
);
9350 case OPC_CMP_NGLE_S
:
9357 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9358 if (ctx
->opcode
& (1 << 6)) {
9359 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
9361 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
9365 check_cp1_registers(ctx
, fs
| ft
| fd
);
9367 TCGv_i64 fp0
= tcg_temp_new_i64();
9368 TCGv_i64 fp1
= tcg_temp_new_i64();
9370 gen_load_fpr64(ctx
, fp0
, fs
);
9371 gen_load_fpr64(ctx
, fp1
, ft
);
9372 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
9373 tcg_temp_free_i64(fp1
);
9374 gen_store_fpr64(ctx
, fp0
, fd
);
9375 tcg_temp_free_i64(fp0
);
9379 check_cp1_registers(ctx
, fs
| ft
| fd
);
9381 TCGv_i64 fp0
= tcg_temp_new_i64();
9382 TCGv_i64 fp1
= tcg_temp_new_i64();
9384 gen_load_fpr64(ctx
, fp0
, fs
);
9385 gen_load_fpr64(ctx
, fp1
, ft
);
9386 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
9387 tcg_temp_free_i64(fp1
);
9388 gen_store_fpr64(ctx
, fp0
, fd
);
9389 tcg_temp_free_i64(fp0
);
9393 check_cp1_registers(ctx
, fs
| ft
| fd
);
9395 TCGv_i64 fp0
= tcg_temp_new_i64();
9396 TCGv_i64 fp1
= tcg_temp_new_i64();
9398 gen_load_fpr64(ctx
, fp0
, fs
);
9399 gen_load_fpr64(ctx
, fp1
, ft
);
9400 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
9401 tcg_temp_free_i64(fp1
);
9402 gen_store_fpr64(ctx
, fp0
, fd
);
9403 tcg_temp_free_i64(fp0
);
9407 check_cp1_registers(ctx
, fs
| ft
| fd
);
9409 TCGv_i64 fp0
= tcg_temp_new_i64();
9410 TCGv_i64 fp1
= tcg_temp_new_i64();
9412 gen_load_fpr64(ctx
, fp0
, fs
);
9413 gen_load_fpr64(ctx
, fp1
, ft
);
9414 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
9415 tcg_temp_free_i64(fp1
);
9416 gen_store_fpr64(ctx
, fp0
, fd
);
9417 tcg_temp_free_i64(fp0
);
9421 check_cp1_registers(ctx
, fs
| fd
);
9423 TCGv_i64 fp0
= tcg_temp_new_i64();
9425 gen_load_fpr64(ctx
, fp0
, fs
);
9426 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
9427 gen_store_fpr64(ctx
, fp0
, fd
);
9428 tcg_temp_free_i64(fp0
);
9432 check_cp1_registers(ctx
, fs
| fd
);
9434 TCGv_i64 fp0
= tcg_temp_new_i64();
9436 gen_load_fpr64(ctx
, fp0
, fs
);
9438 tcg_gen_andi_i64(fp0
, fp0
, 0x7fffffffffffffffULL
);
9440 gen_helper_float_abs_d(fp0
, fp0
);
9442 gen_store_fpr64(ctx
, fp0
, fd
);
9443 tcg_temp_free_i64(fp0
);
9447 check_cp1_registers(ctx
, fs
| fd
);
9449 TCGv_i64 fp0
= tcg_temp_new_i64();
9451 gen_load_fpr64(ctx
, fp0
, fs
);
9452 gen_store_fpr64(ctx
, fp0
, fd
);
9453 tcg_temp_free_i64(fp0
);
9457 check_cp1_registers(ctx
, fs
| fd
);
9459 TCGv_i64 fp0
= tcg_temp_new_i64();
9461 gen_load_fpr64(ctx
, fp0
, fs
);
9463 tcg_gen_xori_i64(fp0
, fp0
, 1ULL << 63);
9465 gen_helper_float_chs_d(fp0
, fp0
);
9467 gen_store_fpr64(ctx
, fp0
, fd
);
9468 tcg_temp_free_i64(fp0
);
9472 check_cp1_64bitmode(ctx
);
9474 TCGv_i64 fp0
= tcg_temp_new_i64();
9476 gen_load_fpr64(ctx
, fp0
, fs
);
9478 gen_helper_float_round_2008_l_d(fp0
, cpu_env
, fp0
);
9480 gen_helper_float_round_l_d(fp0
, cpu_env
, fp0
);
9482 gen_store_fpr64(ctx
, fp0
, fd
);
9483 tcg_temp_free_i64(fp0
);
9487 check_cp1_64bitmode(ctx
);
9489 TCGv_i64 fp0
= tcg_temp_new_i64();
9491 gen_load_fpr64(ctx
, fp0
, fs
);
9493 gen_helper_float_trunc_2008_l_d(fp0
, cpu_env
, fp0
);
9495 gen_helper_float_trunc_l_d(fp0
, cpu_env
, fp0
);
9497 gen_store_fpr64(ctx
, fp0
, fd
);
9498 tcg_temp_free_i64(fp0
);
9502 check_cp1_64bitmode(ctx
);
9504 TCGv_i64 fp0
= tcg_temp_new_i64();
9506 gen_load_fpr64(ctx
, fp0
, fs
);
9508 gen_helper_float_ceil_2008_l_d(fp0
, cpu_env
, fp0
);
9510 gen_helper_float_ceil_l_d(fp0
, cpu_env
, fp0
);
9512 gen_store_fpr64(ctx
, fp0
, fd
);
9513 tcg_temp_free_i64(fp0
);
9517 check_cp1_64bitmode(ctx
);
9519 TCGv_i64 fp0
= tcg_temp_new_i64();
9521 gen_load_fpr64(ctx
, fp0
, fs
);
9523 gen_helper_float_floor_2008_l_d(fp0
, cpu_env
, fp0
);
9525 gen_helper_float_floor_l_d(fp0
, cpu_env
, fp0
);
9527 gen_store_fpr64(ctx
, fp0
, fd
);
9528 tcg_temp_free_i64(fp0
);
9532 check_cp1_registers(ctx
, fs
);
9534 TCGv_i32 fp32
= tcg_temp_new_i32();
9535 TCGv_i64 fp64
= tcg_temp_new_i64();
9537 gen_load_fpr64(ctx
, fp64
, fs
);
9539 gen_helper_float_round_2008_w_d(fp32
, cpu_env
, fp64
);
9541 gen_helper_float_round_w_d(fp32
, cpu_env
, fp64
);
9543 tcg_temp_free_i64(fp64
);
9544 gen_store_fpr32(ctx
, fp32
, fd
);
9545 tcg_temp_free_i32(fp32
);
9549 check_cp1_registers(ctx
, fs
);
9551 TCGv_i32 fp32
= tcg_temp_new_i32();
9552 TCGv_i64 fp64
= tcg_temp_new_i64();
9554 gen_load_fpr64(ctx
, fp64
, fs
);
9556 gen_helper_float_trunc_2008_w_d(fp32
, cpu_env
, fp64
);
9558 gen_helper_float_trunc_w_d(fp32
, cpu_env
, fp64
);
9560 tcg_temp_free_i64(fp64
);
9561 gen_store_fpr32(ctx
, fp32
, fd
);
9562 tcg_temp_free_i32(fp32
);
9566 check_cp1_registers(ctx
, fs
);
9568 TCGv_i32 fp32
= tcg_temp_new_i32();
9569 TCGv_i64 fp64
= tcg_temp_new_i64();
9571 gen_load_fpr64(ctx
, fp64
, fs
);
9573 gen_helper_float_ceil_2008_w_d(fp32
, cpu_env
, fp64
);
9575 gen_helper_float_ceil_w_d(fp32
, cpu_env
, fp64
);
9577 tcg_temp_free_i64(fp64
);
9578 gen_store_fpr32(ctx
, fp32
, fd
);
9579 tcg_temp_free_i32(fp32
);
9583 check_cp1_registers(ctx
, fs
);
9585 TCGv_i32 fp32
= tcg_temp_new_i32();
9586 TCGv_i64 fp64
= tcg_temp_new_i64();
9588 gen_load_fpr64(ctx
, fp64
, fs
);
9590 gen_helper_float_floor_2008_w_d(fp32
, cpu_env
, fp64
);
9592 gen_helper_float_floor_w_d(fp32
, cpu_env
, fp64
);
9594 tcg_temp_free_i64(fp64
);
9595 gen_store_fpr32(ctx
, fp32
, fd
);
9596 tcg_temp_free_i32(fp32
);
9600 check_insn(ctx
, ISA_MIPS32R6
);
9601 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9604 check_insn(ctx
, ISA_MIPS32R6
);
9605 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9608 check_insn(ctx
, ISA_MIPS32R6
);
9609 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9612 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9613 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9616 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9618 TCGLabel
*l1
= gen_new_label();
9622 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9624 fp0
= tcg_temp_new_i64();
9625 gen_load_fpr64(ctx
, fp0
, fs
);
9626 gen_store_fpr64(ctx
, fp0
, fd
);
9627 tcg_temp_free_i64(fp0
);
9632 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9634 TCGLabel
*l1
= gen_new_label();
9638 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9639 fp0
= tcg_temp_new_i64();
9640 gen_load_fpr64(ctx
, fp0
, fs
);
9641 gen_store_fpr64(ctx
, fp0
, fd
);
9642 tcg_temp_free_i64(fp0
);
9648 check_cp1_registers(ctx
, fs
| fd
);
9650 TCGv_i64 fp0
= tcg_temp_new_i64();
9652 gen_load_fpr64(ctx
, fp0
, fs
);
9653 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
9654 gen_store_fpr64(ctx
, fp0
, fd
);
9655 tcg_temp_free_i64(fp0
);
9659 check_cp1_registers(ctx
, fs
| fd
);
9661 TCGv_i64 fp0
= tcg_temp_new_i64();
9663 gen_load_fpr64(ctx
, fp0
, fs
);
9664 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
9665 gen_store_fpr64(ctx
, fp0
, fd
);
9666 tcg_temp_free_i64(fp0
);
9670 check_insn(ctx
, ISA_MIPS32R6
);
9672 TCGv_i64 fp0
= tcg_temp_new_i64();
9673 TCGv_i64 fp1
= tcg_temp_new_i64();
9674 TCGv_i64 fp2
= tcg_temp_new_i64();
9675 gen_load_fpr64(ctx
, fp0
, fs
);
9676 gen_load_fpr64(ctx
, fp1
, ft
);
9677 gen_load_fpr64(ctx
, fp2
, fd
);
9678 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9679 gen_store_fpr64(ctx
, fp2
, fd
);
9680 tcg_temp_free_i64(fp2
);
9681 tcg_temp_free_i64(fp1
);
9682 tcg_temp_free_i64(fp0
);
9686 check_insn(ctx
, ISA_MIPS32R6
);
9688 TCGv_i64 fp0
= tcg_temp_new_i64();
9689 TCGv_i64 fp1
= tcg_temp_new_i64();
9690 TCGv_i64 fp2
= tcg_temp_new_i64();
9691 gen_load_fpr64(ctx
, fp0
, fs
);
9692 gen_load_fpr64(ctx
, fp1
, ft
);
9693 gen_load_fpr64(ctx
, fp2
, fd
);
9694 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9695 gen_store_fpr64(ctx
, fp2
, fd
);
9696 tcg_temp_free_i64(fp2
);
9697 tcg_temp_free_i64(fp1
);
9698 tcg_temp_free_i64(fp0
);
9702 check_insn(ctx
, ISA_MIPS32R6
);
9704 TCGv_i64 fp0
= tcg_temp_new_i64();
9705 gen_load_fpr64(ctx
, fp0
, fs
);
9706 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
9707 gen_store_fpr64(ctx
, fp0
, fd
);
9708 tcg_temp_free_i64(fp0
);
9712 check_insn(ctx
, ISA_MIPS32R6
);
9714 TCGv_i64 fp0
= tcg_temp_new_i64();
9715 gen_load_fpr64(ctx
, fp0
, fs
);
9716 gen_helper_float_class_d(fp0
, cpu_env
, fp0
);
9717 gen_store_fpr64(ctx
, fp0
, fd
);
9718 tcg_temp_free_i64(fp0
);
9721 case OPC_MIN_D
: /* OPC_RECIP2_D */
9722 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9724 TCGv_i64 fp0
= tcg_temp_new_i64();
9725 TCGv_i64 fp1
= tcg_temp_new_i64();
9726 gen_load_fpr64(ctx
, fp0
, fs
);
9727 gen_load_fpr64(ctx
, fp1
, ft
);
9728 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
9729 gen_store_fpr64(ctx
, fp1
, fd
);
9730 tcg_temp_free_i64(fp1
);
9731 tcg_temp_free_i64(fp0
);
9734 check_cp1_64bitmode(ctx
);
9736 TCGv_i64 fp0
= tcg_temp_new_i64();
9737 TCGv_i64 fp1
= tcg_temp_new_i64();
9739 gen_load_fpr64(ctx
, fp0
, fs
);
9740 gen_load_fpr64(ctx
, fp1
, ft
);
9741 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
9742 tcg_temp_free_i64(fp1
);
9743 gen_store_fpr64(ctx
, fp0
, fd
);
9744 tcg_temp_free_i64(fp0
);
9748 case OPC_MINA_D
: /* OPC_RECIP1_D */
9749 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9751 TCGv_i64 fp0
= tcg_temp_new_i64();
9752 TCGv_i64 fp1
= tcg_temp_new_i64();
9753 gen_load_fpr64(ctx
, fp0
, fs
);
9754 gen_load_fpr64(ctx
, fp1
, ft
);
9755 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
9756 gen_store_fpr64(ctx
, fp1
, fd
);
9757 tcg_temp_free_i64(fp1
);
9758 tcg_temp_free_i64(fp0
);
9761 check_cp1_64bitmode(ctx
);
9763 TCGv_i64 fp0
= tcg_temp_new_i64();
9765 gen_load_fpr64(ctx
, fp0
, fs
);
9766 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
9767 gen_store_fpr64(ctx
, fp0
, fd
);
9768 tcg_temp_free_i64(fp0
);
9772 case OPC_MAX_D
: /* OPC_RSQRT1_D */
9773 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9775 TCGv_i64 fp0
= tcg_temp_new_i64();
9776 TCGv_i64 fp1
= tcg_temp_new_i64();
9777 gen_load_fpr64(ctx
, fp0
, fs
);
9778 gen_load_fpr64(ctx
, fp1
, ft
);
9779 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
9780 gen_store_fpr64(ctx
, fp1
, fd
);
9781 tcg_temp_free_i64(fp1
);
9782 tcg_temp_free_i64(fp0
);
9785 check_cp1_64bitmode(ctx
);
9787 TCGv_i64 fp0
= tcg_temp_new_i64();
9789 gen_load_fpr64(ctx
, fp0
, fs
);
9790 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
9791 gen_store_fpr64(ctx
, fp0
, fd
);
9792 tcg_temp_free_i64(fp0
);
9796 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
9797 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9799 TCGv_i64 fp0
= tcg_temp_new_i64();
9800 TCGv_i64 fp1
= tcg_temp_new_i64();
9801 gen_load_fpr64(ctx
, fp0
, fs
);
9802 gen_load_fpr64(ctx
, fp1
, ft
);
9803 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
9804 gen_store_fpr64(ctx
, fp1
, fd
);
9805 tcg_temp_free_i64(fp1
);
9806 tcg_temp_free_i64(fp0
);
9809 check_cp1_64bitmode(ctx
);
9811 TCGv_i64 fp0
= tcg_temp_new_i64();
9812 TCGv_i64 fp1
= tcg_temp_new_i64();
9814 gen_load_fpr64(ctx
, fp0
, fs
);
9815 gen_load_fpr64(ctx
, fp1
, ft
);
9816 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
9817 tcg_temp_free_i64(fp1
);
9818 gen_store_fpr64(ctx
, fp0
, fd
);
9819 tcg_temp_free_i64(fp0
);
9832 case OPC_CMP_NGLE_D
:
9839 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9840 if (ctx
->opcode
& (1 << 6)) {
9841 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
9843 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
9847 check_cp1_registers(ctx
, fs
);
9849 TCGv_i32 fp32
= tcg_temp_new_i32();
9850 TCGv_i64 fp64
= tcg_temp_new_i64();
9852 gen_load_fpr64(ctx
, fp64
, fs
);
9853 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
9854 tcg_temp_free_i64(fp64
);
9855 gen_store_fpr32(ctx
, fp32
, fd
);
9856 tcg_temp_free_i32(fp32
);
9860 check_cp1_registers(ctx
, fs
);
9862 TCGv_i32 fp32
= tcg_temp_new_i32();
9863 TCGv_i64 fp64
= tcg_temp_new_i64();
9865 gen_load_fpr64(ctx
, fp64
, fs
);
9867 gen_helper_float_cvt_2008_w_d(fp32
, cpu_env
, fp64
);
9869 gen_helper_float_cvt_w_d(fp32
, cpu_env
, fp64
);
9871 tcg_temp_free_i64(fp64
);
9872 gen_store_fpr32(ctx
, fp32
, fd
);
9873 tcg_temp_free_i32(fp32
);
9877 check_cp1_64bitmode(ctx
);
9879 TCGv_i64 fp0
= tcg_temp_new_i64();
9881 gen_load_fpr64(ctx
, fp0
, fs
);
9883 gen_helper_float_cvt_2008_l_d(fp0
, cpu_env
, fp0
);
9885 gen_helper_float_cvt_l_d(fp0
, cpu_env
, fp0
);
9887 gen_store_fpr64(ctx
, fp0
, fd
);
9888 tcg_temp_free_i64(fp0
);
9893 TCGv_i32 fp0
= tcg_temp_new_i32();
9895 gen_load_fpr32(ctx
, fp0
, fs
);
9896 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
9897 gen_store_fpr32(ctx
, fp0
, fd
);
9898 tcg_temp_free_i32(fp0
);
9902 check_cp1_registers(ctx
, fd
);
9904 TCGv_i32 fp32
= tcg_temp_new_i32();
9905 TCGv_i64 fp64
= tcg_temp_new_i64();
9907 gen_load_fpr32(ctx
, fp32
, fs
);
9908 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
9909 tcg_temp_free_i32(fp32
);
9910 gen_store_fpr64(ctx
, fp64
, fd
);
9911 tcg_temp_free_i64(fp64
);
9915 check_cp1_64bitmode(ctx
);
9917 TCGv_i32 fp32
= tcg_temp_new_i32();
9918 TCGv_i64 fp64
= tcg_temp_new_i64();
9920 gen_load_fpr64(ctx
, fp64
, fs
);
9921 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
9922 tcg_temp_free_i64(fp64
);
9923 gen_store_fpr32(ctx
, fp32
, fd
);
9924 tcg_temp_free_i32(fp32
);
9928 check_cp1_64bitmode(ctx
);
9930 TCGv_i64 fp0
= tcg_temp_new_i64();
9932 gen_load_fpr64(ctx
, fp0
, fs
);
9933 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
9934 gen_store_fpr64(ctx
, fp0
, fd
);
9935 tcg_temp_free_i64(fp0
);
9941 TCGv_i64 fp0
= tcg_temp_new_i64();
9943 gen_load_fpr64(ctx
, fp0
, fs
);
9944 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
9945 gen_store_fpr64(ctx
, fp0
, fd
);
9946 tcg_temp_free_i64(fp0
);
9952 TCGv_i64 fp0
= tcg_temp_new_i64();
9953 TCGv_i64 fp1
= tcg_temp_new_i64();
9955 gen_load_fpr64(ctx
, fp0
, fs
);
9956 gen_load_fpr64(ctx
, fp1
, ft
);
9957 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
9958 tcg_temp_free_i64(fp1
);
9959 gen_store_fpr64(ctx
, fp0
, fd
);
9960 tcg_temp_free_i64(fp0
);
9966 TCGv_i64 fp0
= tcg_temp_new_i64();
9967 TCGv_i64 fp1
= tcg_temp_new_i64();
9969 gen_load_fpr64(ctx
, fp0
, fs
);
9970 gen_load_fpr64(ctx
, fp1
, ft
);
9971 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
9972 tcg_temp_free_i64(fp1
);
9973 gen_store_fpr64(ctx
, fp0
, fd
);
9974 tcg_temp_free_i64(fp0
);
9980 TCGv_i64 fp0
= tcg_temp_new_i64();
9981 TCGv_i64 fp1
= tcg_temp_new_i64();
9983 gen_load_fpr64(ctx
, fp0
, fs
);
9984 gen_load_fpr64(ctx
, fp1
, ft
);
9985 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
9986 tcg_temp_free_i64(fp1
);
9987 gen_store_fpr64(ctx
, fp0
, fd
);
9988 tcg_temp_free_i64(fp0
);
9994 TCGv_i64 fp0
= tcg_temp_new_i64();
9996 gen_load_fpr64(ctx
, fp0
, fs
);
9997 gen_helper_float_abs_ps(fp0
, fp0
);
9998 gen_store_fpr64(ctx
, fp0
, fd
);
9999 tcg_temp_free_i64(fp0
);
10005 TCGv_i64 fp0
= tcg_temp_new_i64();
10007 gen_load_fpr64(ctx
, fp0
, fs
);
10008 gen_store_fpr64(ctx
, fp0
, fd
);
10009 tcg_temp_free_i64(fp0
);
10015 TCGv_i64 fp0
= tcg_temp_new_i64();
10017 gen_load_fpr64(ctx
, fp0
, fs
);
10018 gen_helper_float_chs_ps(fp0
, fp0
);
10019 gen_store_fpr64(ctx
, fp0
, fd
);
10020 tcg_temp_free_i64(fp0
);
10025 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
10030 TCGLabel
*l1
= gen_new_label();
10034 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
10035 fp0
= tcg_temp_new_i64();
10036 gen_load_fpr64(ctx
, fp0
, fs
);
10037 gen_store_fpr64(ctx
, fp0
, fd
);
10038 tcg_temp_free_i64(fp0
);
10045 TCGLabel
*l1
= gen_new_label();
10049 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
10050 fp0
= tcg_temp_new_i64();
10051 gen_load_fpr64(ctx
, fp0
, fs
);
10052 gen_store_fpr64(ctx
, fp0
, fd
);
10053 tcg_temp_free_i64(fp0
);
10061 TCGv_i64 fp0
= tcg_temp_new_i64();
10062 TCGv_i64 fp1
= tcg_temp_new_i64();
10064 gen_load_fpr64(ctx
, fp0
, ft
);
10065 gen_load_fpr64(ctx
, fp1
, fs
);
10066 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
10067 tcg_temp_free_i64(fp1
);
10068 gen_store_fpr64(ctx
, fp0
, fd
);
10069 tcg_temp_free_i64(fp0
);
10075 TCGv_i64 fp0
= tcg_temp_new_i64();
10076 TCGv_i64 fp1
= tcg_temp_new_i64();
10078 gen_load_fpr64(ctx
, fp0
, ft
);
10079 gen_load_fpr64(ctx
, fp1
, fs
);
10080 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
10081 tcg_temp_free_i64(fp1
);
10082 gen_store_fpr64(ctx
, fp0
, fd
);
10083 tcg_temp_free_i64(fp0
);
10086 case OPC_RECIP2_PS
:
10089 TCGv_i64 fp0
= tcg_temp_new_i64();
10090 TCGv_i64 fp1
= tcg_temp_new_i64();
10092 gen_load_fpr64(ctx
, fp0
, fs
);
10093 gen_load_fpr64(ctx
, fp1
, ft
);
10094 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
10095 tcg_temp_free_i64(fp1
);
10096 gen_store_fpr64(ctx
, fp0
, fd
);
10097 tcg_temp_free_i64(fp0
);
10100 case OPC_RECIP1_PS
:
10103 TCGv_i64 fp0
= tcg_temp_new_i64();
10105 gen_load_fpr64(ctx
, fp0
, fs
);
10106 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
10107 gen_store_fpr64(ctx
, fp0
, fd
);
10108 tcg_temp_free_i64(fp0
);
10111 case OPC_RSQRT1_PS
:
10114 TCGv_i64 fp0
= tcg_temp_new_i64();
10116 gen_load_fpr64(ctx
, fp0
, fs
);
10117 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
10118 gen_store_fpr64(ctx
, fp0
, fd
);
10119 tcg_temp_free_i64(fp0
);
10122 case OPC_RSQRT2_PS
:
10125 TCGv_i64 fp0
= tcg_temp_new_i64();
10126 TCGv_i64 fp1
= tcg_temp_new_i64();
10128 gen_load_fpr64(ctx
, fp0
, fs
);
10129 gen_load_fpr64(ctx
, fp1
, ft
);
10130 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
10131 tcg_temp_free_i64(fp1
);
10132 gen_store_fpr64(ctx
, fp0
, fd
);
10133 tcg_temp_free_i64(fp0
);
10137 check_cp1_64bitmode(ctx
);
10139 TCGv_i32 fp0
= tcg_temp_new_i32();
10141 gen_load_fpr32h(ctx
, fp0
, fs
);
10142 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
10143 gen_store_fpr32(ctx
, fp0
, fd
);
10144 tcg_temp_free_i32(fp0
);
10147 case OPC_CVT_PW_PS
:
10150 TCGv_i64 fp0
= tcg_temp_new_i64();
10152 gen_load_fpr64(ctx
, fp0
, fs
);
10153 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
10154 gen_store_fpr64(ctx
, fp0
, fd
);
10155 tcg_temp_free_i64(fp0
);
10159 check_cp1_64bitmode(ctx
);
10161 TCGv_i32 fp0
= tcg_temp_new_i32();
10163 gen_load_fpr32(ctx
, fp0
, fs
);
10164 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
10165 gen_store_fpr32(ctx
, fp0
, fd
);
10166 tcg_temp_free_i32(fp0
);
10172 TCGv_i32 fp0
= tcg_temp_new_i32();
10173 TCGv_i32 fp1
= tcg_temp_new_i32();
10175 gen_load_fpr32(ctx
, fp0
, fs
);
10176 gen_load_fpr32(ctx
, fp1
, ft
);
10177 gen_store_fpr32h(ctx
, fp0
, fd
);
10178 gen_store_fpr32(ctx
, fp1
, fd
);
10179 tcg_temp_free_i32(fp0
);
10180 tcg_temp_free_i32(fp1
);
10186 TCGv_i32 fp0
= tcg_temp_new_i32();
10187 TCGv_i32 fp1
= tcg_temp_new_i32();
10189 gen_load_fpr32(ctx
, fp0
, fs
);
10190 gen_load_fpr32h(ctx
, fp1
, ft
);
10191 gen_store_fpr32(ctx
, fp1
, fd
);
10192 gen_store_fpr32h(ctx
, fp0
, fd
);
10193 tcg_temp_free_i32(fp0
);
10194 tcg_temp_free_i32(fp1
);
10200 TCGv_i32 fp0
= tcg_temp_new_i32();
10201 TCGv_i32 fp1
= tcg_temp_new_i32();
10203 gen_load_fpr32h(ctx
, fp0
, fs
);
10204 gen_load_fpr32(ctx
, fp1
, ft
);
10205 gen_store_fpr32(ctx
, fp1
, fd
);
10206 gen_store_fpr32h(ctx
, fp0
, fd
);
10207 tcg_temp_free_i32(fp0
);
10208 tcg_temp_free_i32(fp1
);
10214 TCGv_i32 fp0
= tcg_temp_new_i32();
10215 TCGv_i32 fp1
= tcg_temp_new_i32();
10217 gen_load_fpr32h(ctx
, fp0
, fs
);
10218 gen_load_fpr32h(ctx
, fp1
, ft
);
10219 gen_store_fpr32(ctx
, fp1
, fd
);
10220 gen_store_fpr32h(ctx
, fp0
, fd
);
10221 tcg_temp_free_i32(fp0
);
10222 tcg_temp_free_i32(fp1
);
10226 case OPC_CMP_UN_PS
:
10227 case OPC_CMP_EQ_PS
:
10228 case OPC_CMP_UEQ_PS
:
10229 case OPC_CMP_OLT_PS
:
10230 case OPC_CMP_ULT_PS
:
10231 case OPC_CMP_OLE_PS
:
10232 case OPC_CMP_ULE_PS
:
10233 case OPC_CMP_SF_PS
:
10234 case OPC_CMP_NGLE_PS
:
10235 case OPC_CMP_SEQ_PS
:
10236 case OPC_CMP_NGL_PS
:
10237 case OPC_CMP_LT_PS
:
10238 case OPC_CMP_NGE_PS
:
10239 case OPC_CMP_LE_PS
:
10240 case OPC_CMP_NGT_PS
:
10241 if (ctx
->opcode
& (1 << 6)) {
10242 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
10244 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
10248 MIPS_INVAL("farith");
10249 generate_exception_end(ctx
, EXCP_RI
);
10254 /* Coprocessor 3 (FPU) */
10255 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
10256 int fd
, int fs
, int base
, int index
)
10258 TCGv t0
= tcg_temp_new();
10261 gen_load_gpr(t0
, index
);
10262 } else if (index
== 0) {
10263 gen_load_gpr(t0
, base
);
10265 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
10267 /* Don't do NOP if destination is zero: we must perform the actual
10273 TCGv_i32 fp0
= tcg_temp_new_i32();
10275 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
10276 tcg_gen_trunc_tl_i32(fp0
, t0
);
10277 gen_store_fpr32(ctx
, fp0
, fd
);
10278 tcg_temp_free_i32(fp0
);
10283 check_cp1_registers(ctx
, fd
);
10285 TCGv_i64 fp0
= tcg_temp_new_i64();
10286 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10287 gen_store_fpr64(ctx
, fp0
, fd
);
10288 tcg_temp_free_i64(fp0
);
10292 check_cp1_64bitmode(ctx
);
10293 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10295 TCGv_i64 fp0
= tcg_temp_new_i64();
10297 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10298 gen_store_fpr64(ctx
, fp0
, fd
);
10299 tcg_temp_free_i64(fp0
);
10305 TCGv_i32 fp0
= tcg_temp_new_i32();
10306 gen_load_fpr32(ctx
, fp0
, fs
);
10307 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
10308 tcg_temp_free_i32(fp0
);
10313 check_cp1_registers(ctx
, fs
);
10315 TCGv_i64 fp0
= tcg_temp_new_i64();
10316 gen_load_fpr64(ctx
, fp0
, fs
);
10317 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10318 tcg_temp_free_i64(fp0
);
10322 check_cp1_64bitmode(ctx
);
10323 tcg_gen_andi_tl(t0
, t0
, ~0x7);
10325 TCGv_i64 fp0
= tcg_temp_new_i64();
10326 gen_load_fpr64(ctx
, fp0
, fs
);
10327 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
10328 tcg_temp_free_i64(fp0
);
10335 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
10336 int fd
, int fr
, int fs
, int ft
)
10342 TCGv t0
= tcg_temp_local_new();
10343 TCGv_i32 fp
= tcg_temp_new_i32();
10344 TCGv_i32 fph
= tcg_temp_new_i32();
10345 TCGLabel
*l1
= gen_new_label();
10346 TCGLabel
*l2
= gen_new_label();
10348 gen_load_gpr(t0
, fr
);
10349 tcg_gen_andi_tl(t0
, t0
, 0x7);
10351 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
10352 gen_load_fpr32(ctx
, fp
, fs
);
10353 gen_load_fpr32h(ctx
, fph
, fs
);
10354 gen_store_fpr32(ctx
, fp
, fd
);
10355 gen_store_fpr32h(ctx
, fph
, fd
);
10358 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
10360 #ifdef TARGET_WORDS_BIGENDIAN
10361 gen_load_fpr32(ctx
, fp
, fs
);
10362 gen_load_fpr32h(ctx
, fph
, ft
);
10363 gen_store_fpr32h(ctx
, fp
, fd
);
10364 gen_store_fpr32(ctx
, fph
, fd
);
10366 gen_load_fpr32h(ctx
, fph
, fs
);
10367 gen_load_fpr32(ctx
, fp
, ft
);
10368 gen_store_fpr32(ctx
, fph
, fd
);
10369 gen_store_fpr32h(ctx
, fp
, fd
);
10372 tcg_temp_free_i32(fp
);
10373 tcg_temp_free_i32(fph
);
10379 TCGv_i32 fp0
= tcg_temp_new_i32();
10380 TCGv_i32 fp1
= tcg_temp_new_i32();
10381 TCGv_i32 fp2
= tcg_temp_new_i32();
10383 gen_load_fpr32(ctx
, fp0
, fs
);
10384 gen_load_fpr32(ctx
, fp1
, ft
);
10385 gen_load_fpr32(ctx
, fp2
, fr
);
10386 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10387 tcg_temp_free_i32(fp0
);
10388 tcg_temp_free_i32(fp1
);
10389 gen_store_fpr32(ctx
, fp2
, fd
);
10390 tcg_temp_free_i32(fp2
);
10395 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10397 TCGv_i64 fp0
= tcg_temp_new_i64();
10398 TCGv_i64 fp1
= tcg_temp_new_i64();
10399 TCGv_i64 fp2
= tcg_temp_new_i64();
10401 gen_load_fpr64(ctx
, fp0
, fs
);
10402 gen_load_fpr64(ctx
, fp1
, ft
);
10403 gen_load_fpr64(ctx
, fp2
, fr
);
10404 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10405 tcg_temp_free_i64(fp0
);
10406 tcg_temp_free_i64(fp1
);
10407 gen_store_fpr64(ctx
, fp2
, fd
);
10408 tcg_temp_free_i64(fp2
);
10414 TCGv_i64 fp0
= tcg_temp_new_i64();
10415 TCGv_i64 fp1
= tcg_temp_new_i64();
10416 TCGv_i64 fp2
= tcg_temp_new_i64();
10418 gen_load_fpr64(ctx
, fp0
, fs
);
10419 gen_load_fpr64(ctx
, fp1
, ft
);
10420 gen_load_fpr64(ctx
, fp2
, fr
);
10421 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10422 tcg_temp_free_i64(fp0
);
10423 tcg_temp_free_i64(fp1
);
10424 gen_store_fpr64(ctx
, fp2
, fd
);
10425 tcg_temp_free_i64(fp2
);
10431 TCGv_i32 fp0
= tcg_temp_new_i32();
10432 TCGv_i32 fp1
= tcg_temp_new_i32();
10433 TCGv_i32 fp2
= tcg_temp_new_i32();
10435 gen_load_fpr32(ctx
, fp0
, fs
);
10436 gen_load_fpr32(ctx
, fp1
, ft
);
10437 gen_load_fpr32(ctx
, fp2
, fr
);
10438 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10439 tcg_temp_free_i32(fp0
);
10440 tcg_temp_free_i32(fp1
);
10441 gen_store_fpr32(ctx
, fp2
, fd
);
10442 tcg_temp_free_i32(fp2
);
10447 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10449 TCGv_i64 fp0
= tcg_temp_new_i64();
10450 TCGv_i64 fp1
= tcg_temp_new_i64();
10451 TCGv_i64 fp2
= tcg_temp_new_i64();
10453 gen_load_fpr64(ctx
, fp0
, fs
);
10454 gen_load_fpr64(ctx
, fp1
, ft
);
10455 gen_load_fpr64(ctx
, fp2
, fr
);
10456 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10457 tcg_temp_free_i64(fp0
);
10458 tcg_temp_free_i64(fp1
);
10459 gen_store_fpr64(ctx
, fp2
, fd
);
10460 tcg_temp_free_i64(fp2
);
10466 TCGv_i64 fp0
= tcg_temp_new_i64();
10467 TCGv_i64 fp1
= tcg_temp_new_i64();
10468 TCGv_i64 fp2
= tcg_temp_new_i64();
10470 gen_load_fpr64(ctx
, fp0
, fs
);
10471 gen_load_fpr64(ctx
, fp1
, ft
);
10472 gen_load_fpr64(ctx
, fp2
, fr
);
10473 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10474 tcg_temp_free_i64(fp0
);
10475 tcg_temp_free_i64(fp1
);
10476 gen_store_fpr64(ctx
, fp2
, fd
);
10477 tcg_temp_free_i64(fp2
);
10483 TCGv_i32 fp0
= tcg_temp_new_i32();
10484 TCGv_i32 fp1
= tcg_temp_new_i32();
10485 TCGv_i32 fp2
= tcg_temp_new_i32();
10487 gen_load_fpr32(ctx
, fp0
, fs
);
10488 gen_load_fpr32(ctx
, fp1
, ft
);
10489 gen_load_fpr32(ctx
, fp2
, fr
);
10490 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10491 tcg_temp_free_i32(fp0
);
10492 tcg_temp_free_i32(fp1
);
10493 gen_store_fpr32(ctx
, fp2
, fd
);
10494 tcg_temp_free_i32(fp2
);
10499 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10501 TCGv_i64 fp0
= tcg_temp_new_i64();
10502 TCGv_i64 fp1
= tcg_temp_new_i64();
10503 TCGv_i64 fp2
= tcg_temp_new_i64();
10505 gen_load_fpr64(ctx
, fp0
, fs
);
10506 gen_load_fpr64(ctx
, fp1
, ft
);
10507 gen_load_fpr64(ctx
, fp2
, fr
);
10508 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10509 tcg_temp_free_i64(fp0
);
10510 tcg_temp_free_i64(fp1
);
10511 gen_store_fpr64(ctx
, fp2
, fd
);
10512 tcg_temp_free_i64(fp2
);
10518 TCGv_i64 fp0
= tcg_temp_new_i64();
10519 TCGv_i64 fp1
= tcg_temp_new_i64();
10520 TCGv_i64 fp2
= tcg_temp_new_i64();
10522 gen_load_fpr64(ctx
, fp0
, fs
);
10523 gen_load_fpr64(ctx
, fp1
, ft
);
10524 gen_load_fpr64(ctx
, fp2
, fr
);
10525 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10526 tcg_temp_free_i64(fp0
);
10527 tcg_temp_free_i64(fp1
);
10528 gen_store_fpr64(ctx
, fp2
, fd
);
10529 tcg_temp_free_i64(fp2
);
10535 TCGv_i32 fp0
= tcg_temp_new_i32();
10536 TCGv_i32 fp1
= tcg_temp_new_i32();
10537 TCGv_i32 fp2
= tcg_temp_new_i32();
10539 gen_load_fpr32(ctx
, fp0
, fs
);
10540 gen_load_fpr32(ctx
, fp1
, ft
);
10541 gen_load_fpr32(ctx
, fp2
, fr
);
10542 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10543 tcg_temp_free_i32(fp0
);
10544 tcg_temp_free_i32(fp1
);
10545 gen_store_fpr32(ctx
, fp2
, fd
);
10546 tcg_temp_free_i32(fp2
);
10551 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10553 TCGv_i64 fp0
= tcg_temp_new_i64();
10554 TCGv_i64 fp1
= tcg_temp_new_i64();
10555 TCGv_i64 fp2
= tcg_temp_new_i64();
10557 gen_load_fpr64(ctx
, fp0
, fs
);
10558 gen_load_fpr64(ctx
, fp1
, ft
);
10559 gen_load_fpr64(ctx
, fp2
, fr
);
10560 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10561 tcg_temp_free_i64(fp0
);
10562 tcg_temp_free_i64(fp1
);
10563 gen_store_fpr64(ctx
, fp2
, fd
);
10564 tcg_temp_free_i64(fp2
);
10570 TCGv_i64 fp0
= tcg_temp_new_i64();
10571 TCGv_i64 fp1
= tcg_temp_new_i64();
10572 TCGv_i64 fp2
= tcg_temp_new_i64();
10574 gen_load_fpr64(ctx
, fp0
, fs
);
10575 gen_load_fpr64(ctx
, fp1
, ft
);
10576 gen_load_fpr64(ctx
, fp2
, fr
);
10577 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10578 tcg_temp_free_i64(fp0
);
10579 tcg_temp_free_i64(fp1
);
10580 gen_store_fpr64(ctx
, fp2
, fd
);
10581 tcg_temp_free_i64(fp2
);
10585 MIPS_INVAL("flt3_arith");
10586 generate_exception_end(ctx
, EXCP_RI
);
10591 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
, int sel
)
10595 #if !defined(CONFIG_USER_ONLY)
10596 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10597 Therefore only check the ISA in system mode. */
10598 check_insn(ctx
, ISA_MIPS32R2
);
10600 t0
= tcg_temp_new();
10604 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
10605 gen_store_gpr(t0
, rt
);
10608 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
10609 gen_store_gpr(t0
, rt
);
10612 gen_helper_rdhwr_cc(t0
, cpu_env
);
10613 gen_store_gpr(t0
, rt
);
10616 gen_helper_rdhwr_ccres(t0
, cpu_env
);
10617 gen_store_gpr(t0
, rt
);
10620 check_insn(ctx
, ISA_MIPS32R6
);
10622 /* Performance counter registers are not implemented other than
10623 * control register 0.
10625 generate_exception(ctx
, EXCP_RI
);
10627 gen_helper_rdhwr_performance(t0
, cpu_env
);
10628 gen_store_gpr(t0
, rt
);
10631 check_insn(ctx
, ISA_MIPS32R6
);
10632 gen_helper_rdhwr_xnp(t0
, cpu_env
);
10633 gen_store_gpr(t0
, rt
);
10636 #if defined(CONFIG_USER_ONLY)
10637 tcg_gen_ld_tl(t0
, cpu_env
,
10638 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10639 gen_store_gpr(t0
, rt
);
10642 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
10643 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
10644 tcg_gen_ld_tl(t0
, cpu_env
,
10645 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10646 gen_store_gpr(t0
, rt
);
10648 generate_exception_end(ctx
, EXCP_RI
);
10652 default: /* Invalid */
10653 MIPS_INVAL("rdhwr");
10654 generate_exception_end(ctx
, EXCP_RI
);
10660 static inline void clear_branch_hflags(DisasContext
*ctx
)
10662 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
10663 if (ctx
->bstate
== BS_NONE
) {
10664 save_cpu_state(ctx
, 0);
10666 /* it is not safe to save ctx->hflags as hflags may be changed
10667 in execution time by the instruction in delay / forbidden slot. */
10668 tcg_gen_andi_i32(hflags
, hflags
, ~MIPS_HFLAG_BMASK
);
10672 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
10674 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10675 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
10676 /* Branches completion */
10677 clear_branch_hflags(ctx
);
10678 ctx
->bstate
= BS_BRANCH
;
10679 /* FIXME: Need to clear can_do_io. */
10680 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
10681 case MIPS_HFLAG_FBNSLOT
:
10682 gen_goto_tb(ctx
, 0, ctx
->pc
+ insn_bytes
);
10685 /* unconditional branch */
10686 if (proc_hflags
& MIPS_HFLAG_BX
) {
10687 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
10689 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10691 case MIPS_HFLAG_BL
:
10692 /* blikely taken case */
10693 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10695 case MIPS_HFLAG_BC
:
10696 /* Conditional branch */
10698 TCGLabel
*l1
= gen_new_label();
10700 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
10701 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
10703 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10706 case MIPS_HFLAG_BR
:
10707 /* unconditional branch to register */
10708 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
10709 TCGv t0
= tcg_temp_new();
10710 TCGv_i32 t1
= tcg_temp_new_i32();
10712 tcg_gen_andi_tl(t0
, btarget
, 0x1);
10713 tcg_gen_trunc_tl_i32(t1
, t0
);
10715 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
10716 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
10717 tcg_gen_or_i32(hflags
, hflags
, t1
);
10718 tcg_temp_free_i32(t1
);
10720 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
10722 tcg_gen_mov_tl(cpu_PC
, btarget
);
10724 if (ctx
->singlestep_enabled
) {
10725 save_cpu_state(ctx
, 0);
10726 gen_helper_raise_exception_debug(cpu_env
);
10728 tcg_gen_exit_tb(0);
10731 fprintf(stderr
, "unknown branch 0x%x\n", proc_hflags
);
10737 /* Compact Branches */
10738 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
10739 int rs
, int rt
, int32_t offset
)
10741 int bcond_compute
= 0;
10742 TCGv t0
= tcg_temp_new();
10743 TCGv t1
= tcg_temp_new();
10744 int m16_lowbit
= (ctx
->hflags
& MIPS_HFLAG_M16
) != 0;
10746 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10747 #ifdef MIPS_DEBUG_DISAS
10748 LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10751 generate_exception_end(ctx
, EXCP_RI
);
10755 /* Load needed operands and calculate btarget */
10757 /* compact branch */
10758 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
10759 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
10760 gen_load_gpr(t0
, rs
);
10761 gen_load_gpr(t1
, rt
);
10763 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
10764 if (rs
<= rt
&& rs
== 0) {
10765 /* OPC_BEQZALC, OPC_BNEZALC */
10766 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
10769 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
10770 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
10771 gen_load_gpr(t0
, rs
);
10772 gen_load_gpr(t1
, rt
);
10774 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
10776 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
10777 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
10778 if (rs
== 0 || rs
== rt
) {
10779 /* OPC_BLEZALC, OPC_BGEZALC */
10780 /* OPC_BGTZALC, OPC_BLTZALC */
10781 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
10783 gen_load_gpr(t0
, rs
);
10784 gen_load_gpr(t1
, rt
);
10786 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
10790 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
10795 /* OPC_BEQZC, OPC_BNEZC */
10796 gen_load_gpr(t0
, rs
);
10798 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
10800 /* OPC_JIC, OPC_JIALC */
10801 TCGv tbase
= tcg_temp_new();
10802 TCGv toffset
= tcg_temp_new();
10804 gen_load_gpr(tbase
, rt
);
10805 tcg_gen_movi_tl(toffset
, offset
);
10806 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
10807 tcg_temp_free(tbase
);
10808 tcg_temp_free(toffset
);
10812 MIPS_INVAL("Compact branch/jump");
10813 generate_exception_end(ctx
, EXCP_RI
);
10817 if (bcond_compute
== 0) {
10818 /* Uncoditional compact branch */
10821 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
10824 ctx
->hflags
|= MIPS_HFLAG_BR
;
10827 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4 + m16_lowbit
);
10830 ctx
->hflags
|= MIPS_HFLAG_B
;
10833 MIPS_INVAL("Compact branch/jump");
10834 generate_exception_end(ctx
, EXCP_RI
);
10838 /* Generating branch here as compact branches don't have delay slot */
10839 gen_branch(ctx
, 4);
10841 /* Conditional compact branch */
10842 TCGLabel
*fs
= gen_new_label();
10843 save_cpu_state(ctx
, 0);
10846 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
10847 if (rs
== 0 && rt
!= 0) {
10849 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
10850 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
10852 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
10855 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU
), t0
, t1
, fs
);
10858 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
10859 if (rs
== 0 && rt
!= 0) {
10861 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
10862 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
10864 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
10867 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU
), t0
, t1
, fs
);
10870 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
10871 if (rs
== 0 && rt
!= 0) {
10873 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE
), t1
, 0, fs
);
10874 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
10876 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE
), t1
, 0, fs
);
10879 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE
), t0
, t1
, fs
);
10882 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
10883 if (rs
== 0 && rt
!= 0) {
10885 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT
), t1
, 0, fs
);
10886 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
10888 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT
), t1
, 0, fs
);
10891 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT
), t0
, t1
, fs
);
10894 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
10895 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
10897 /* OPC_BOVC, OPC_BNVC */
10898 TCGv t2
= tcg_temp_new();
10899 TCGv t3
= tcg_temp_new();
10900 TCGv t4
= tcg_temp_new();
10901 TCGv input_overflow
= tcg_temp_new();
10903 gen_load_gpr(t0
, rs
);
10904 gen_load_gpr(t1
, rt
);
10905 tcg_gen_ext32s_tl(t2
, t0
);
10906 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
10907 tcg_gen_ext32s_tl(t3
, t1
);
10908 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
10909 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
10911 tcg_gen_add_tl(t4
, t2
, t3
);
10912 tcg_gen_ext32s_tl(t4
, t4
);
10913 tcg_gen_xor_tl(t2
, t2
, t3
);
10914 tcg_gen_xor_tl(t3
, t4
, t3
);
10915 tcg_gen_andc_tl(t2
, t3
, t2
);
10916 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
10917 tcg_gen_or_tl(t4
, t4
, input_overflow
);
10918 if (opc
== OPC_BOVC
) {
10920 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t4
, 0, fs
);
10923 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t4
, 0, fs
);
10925 tcg_temp_free(input_overflow
);
10929 } else if (rs
< rt
&& rs
== 0) {
10930 /* OPC_BEQZALC, OPC_BNEZALC */
10931 if (opc
== OPC_BEQZALC
) {
10933 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t1
, 0, fs
);
10936 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t1
, 0, fs
);
10939 /* OPC_BEQC, OPC_BNEC */
10940 if (opc
== OPC_BEQC
) {
10942 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, t1
, fs
);
10945 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE
), t0
, t1
, fs
);
10950 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ
), t0
, 0, fs
);
10953 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE
), t0
, 0, fs
);
10956 MIPS_INVAL("Compact conditional branch/jump");
10957 generate_exception_end(ctx
, EXCP_RI
);
10961 /* Generating branch here as compact branches don't have delay slot */
10962 gen_goto_tb(ctx
, 1, ctx
->btarget
);
10965 ctx
->hflags
|= MIPS_HFLAG_FBNSLOT
;
10973 /* ISA extensions (ASEs) */
10974 /* MIPS16 extension to MIPS32 */
10976 /* MIPS16 major opcodes */
10978 M16_OPC_ADDIUSP
= 0x00,
10979 M16_OPC_ADDIUPC
= 0x01,
10981 M16_OPC_JAL
= 0x03,
10982 M16_OPC_BEQZ
= 0x04,
10983 M16_OPC_BNEQZ
= 0x05,
10984 M16_OPC_SHIFT
= 0x06,
10986 M16_OPC_RRIA
= 0x08,
10987 M16_OPC_ADDIU8
= 0x09,
10988 M16_OPC_SLTI
= 0x0a,
10989 M16_OPC_SLTIU
= 0x0b,
10992 M16_OPC_CMPI
= 0x0e,
10996 M16_OPC_LWSP
= 0x12,
10998 M16_OPC_LBU
= 0x14,
10999 M16_OPC_LHU
= 0x15,
11000 M16_OPC_LWPC
= 0x16,
11001 M16_OPC_LWU
= 0x17,
11004 M16_OPC_SWSP
= 0x1a,
11006 M16_OPC_RRR
= 0x1c,
11008 M16_OPC_EXTEND
= 0x1e,
11012 /* I8 funct field */
11031 /* RR funct field */
11065 /* I64 funct field */
11073 I64_DADDIUPC
= 0x6,
11077 /* RR ry field for CNVT */
11079 RR_RY_CNVT_ZEB
= 0x0,
11080 RR_RY_CNVT_ZEH
= 0x1,
11081 RR_RY_CNVT_ZEW
= 0x2,
11082 RR_RY_CNVT_SEB
= 0x4,
11083 RR_RY_CNVT_SEH
= 0x5,
11084 RR_RY_CNVT_SEW
= 0x6,
11087 static int xlat (int r
)
11089 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11094 static void gen_mips16_save (DisasContext
*ctx
,
11095 int xsregs
, int aregs
,
11096 int do_ra
, int do_s0
, int do_s1
,
11099 TCGv t0
= tcg_temp_new();
11100 TCGv t1
= tcg_temp_new();
11101 TCGv t2
= tcg_temp_new();
11131 generate_exception_end(ctx
, EXCP_RI
);
11137 gen_base_offset_addr(ctx
, t0
, 29, 12);
11138 gen_load_gpr(t1
, 7);
11139 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11142 gen_base_offset_addr(ctx
, t0
, 29, 8);
11143 gen_load_gpr(t1
, 6);
11144 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11147 gen_base_offset_addr(ctx
, t0
, 29, 4);
11148 gen_load_gpr(t1
, 5);
11149 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11152 gen_base_offset_addr(ctx
, t0
, 29, 0);
11153 gen_load_gpr(t1
, 4);
11154 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11157 gen_load_gpr(t0
, 29);
11159 #define DECR_AND_STORE(reg) do { \
11160 tcg_gen_movi_tl(t2, -4); \
11161 gen_op_addr_add(ctx, t0, t0, t2); \
11162 gen_load_gpr(t1, reg); \
11163 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
11167 DECR_AND_STORE(31);
11172 DECR_AND_STORE(30);
11175 DECR_AND_STORE(23);
11178 DECR_AND_STORE(22);
11181 DECR_AND_STORE(21);
11184 DECR_AND_STORE(20);
11187 DECR_AND_STORE(19);
11190 DECR_AND_STORE(18);
11194 DECR_AND_STORE(17);
11197 DECR_AND_STORE(16);
11227 generate_exception_end(ctx
, EXCP_RI
);
11243 #undef DECR_AND_STORE
11245 tcg_gen_movi_tl(t2
, -framesize
);
11246 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11252 static void gen_mips16_restore (DisasContext
*ctx
,
11253 int xsregs
, int aregs
,
11254 int do_ra
, int do_s0
, int do_s1
,
11258 TCGv t0
= tcg_temp_new();
11259 TCGv t1
= tcg_temp_new();
11260 TCGv t2
= tcg_temp_new();
11262 tcg_gen_movi_tl(t2
, framesize
);
11263 gen_op_addr_add(ctx
, t0
, cpu_gpr
[29], t2
);
11265 #define DECR_AND_LOAD(reg) do { \
11266 tcg_gen_movi_tl(t2, -4); \
11267 gen_op_addr_add(ctx, t0, t0, t2); \
11268 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
11269 gen_store_gpr(t1, reg); \
11333 generate_exception_end(ctx
, EXCP_RI
);
11349 #undef DECR_AND_LOAD
11351 tcg_gen_movi_tl(t2
, framesize
);
11352 gen_op_addr_add(ctx
, cpu_gpr
[29], cpu_gpr
[29], t2
);
11358 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
11359 int is_64_bit
, int extended
)
11363 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11364 generate_exception_end(ctx
, EXCP_RI
);
11368 t0
= tcg_temp_new();
11370 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
11371 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
11373 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11379 static void gen_cache_operation(DisasContext
*ctx
, uint32_t op
, int base
,
11382 TCGv_i32 t0
= tcg_const_i32(op
);
11383 TCGv t1
= tcg_temp_new();
11384 gen_base_offset_addr(ctx
, t1
, base
, offset
);
11385 gen_helper_cache(cpu_env
, t1
, t0
);
11388 #if defined(TARGET_MIPS64)
11389 static void decode_i64_mips16 (DisasContext
*ctx
,
11390 int ry
, int funct
, int16_t offset
,
11395 check_insn(ctx
, ISA_MIPS3
);
11396 check_mips_64(ctx
);
11397 offset
= extended
? offset
: offset
<< 3;
11398 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
11401 check_insn(ctx
, ISA_MIPS3
);
11402 check_mips_64(ctx
);
11403 offset
= extended
? offset
: offset
<< 3;
11404 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
11407 check_insn(ctx
, ISA_MIPS3
);
11408 check_mips_64(ctx
);
11409 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
11410 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
11413 check_insn(ctx
, ISA_MIPS3
);
11414 check_mips_64(ctx
);
11415 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
11416 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
11419 check_insn(ctx
, ISA_MIPS3
);
11420 check_mips_64(ctx
);
11421 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
11422 generate_exception_end(ctx
, EXCP_RI
);
11424 offset
= extended
? offset
: offset
<< 3;
11425 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
11429 check_insn(ctx
, ISA_MIPS3
);
11430 check_mips_64(ctx
);
11431 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
11432 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
11435 check_insn(ctx
, ISA_MIPS3
);
11436 check_mips_64(ctx
);
11437 offset
= extended
? offset
: offset
<< 2;
11438 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
11441 check_insn(ctx
, ISA_MIPS3
);
11442 check_mips_64(ctx
);
11443 offset
= extended
? offset
: offset
<< 2;
11444 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
11450 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11452 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11453 int op
, rx
, ry
, funct
, sa
;
11454 int16_t imm
, offset
;
11456 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
11457 op
= (ctx
->opcode
>> 11) & 0x1f;
11458 sa
= (ctx
->opcode
>> 22) & 0x1f;
11459 funct
= (ctx
->opcode
>> 8) & 0x7;
11460 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11461 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11462 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
11463 | ((ctx
->opcode
>> 21) & 0x3f) << 5
11464 | (ctx
->opcode
& 0x1f));
11466 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
11469 case M16_OPC_ADDIUSP
:
11470 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11472 case M16_OPC_ADDIUPC
:
11473 gen_addiupc(ctx
, rx
, imm
, 0, 1);
11476 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
11477 /* No delay slot, so just process as a normal instruction */
11480 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
11481 /* No delay slot, so just process as a normal instruction */
11483 case M16_OPC_BNEQZ
:
11484 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
11485 /* No delay slot, so just process as a normal instruction */
11487 case M16_OPC_SHIFT
:
11488 switch (ctx
->opcode
& 0x3) {
11490 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11493 #if defined(TARGET_MIPS64)
11494 check_mips_64(ctx
);
11495 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11497 generate_exception_end(ctx
, EXCP_RI
);
11501 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11504 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11508 #if defined(TARGET_MIPS64)
11510 check_insn(ctx
, ISA_MIPS3
);
11511 check_mips_64(ctx
);
11512 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
11516 imm
= ctx
->opcode
& 0xf;
11517 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
11518 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
11519 imm
= (int16_t) (imm
<< 1) >> 1;
11520 if ((ctx
->opcode
>> 4) & 0x1) {
11521 #if defined(TARGET_MIPS64)
11522 check_mips_64(ctx
);
11523 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11525 generate_exception_end(ctx
, EXCP_RI
);
11528 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11531 case M16_OPC_ADDIU8
:
11532 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11535 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11537 case M16_OPC_SLTIU
:
11538 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11543 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
11546 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
11549 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
11552 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
11555 check_insn(ctx
, ISA_MIPS32
);
11557 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
11558 int aregs
= (ctx
->opcode
>> 16) & 0xf;
11559 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
11560 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
11561 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
11562 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
11563 | (ctx
->opcode
& 0xf)) << 3;
11565 if (ctx
->opcode
& (1 << 7)) {
11566 gen_mips16_save(ctx
, xsregs
, aregs
,
11567 do_ra
, do_s0
, do_s1
,
11570 gen_mips16_restore(ctx
, xsregs
, aregs
,
11571 do_ra
, do_s0
, do_s1
,
11577 generate_exception_end(ctx
, EXCP_RI
);
11582 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
11585 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
11587 #if defined(TARGET_MIPS64)
11589 check_insn(ctx
, ISA_MIPS3
);
11590 check_mips_64(ctx
);
11591 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
11595 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11598 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
11601 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
11604 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
11607 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11610 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
11613 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
11615 #if defined(TARGET_MIPS64)
11617 check_insn(ctx
, ISA_MIPS3
);
11618 check_mips_64(ctx
);
11619 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
11623 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11626 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
11629 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
11632 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
11634 #if defined(TARGET_MIPS64)
11636 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
11640 generate_exception_end(ctx
, EXCP_RI
);
11647 static inline bool is_uhi(int sdbbp_code
)
11649 #ifdef CONFIG_USER_ONLY
11652 return semihosting_enabled() && sdbbp_code
== 1;
11656 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
11660 int op
, cnvt_op
, op1
, offset
;
11664 op
= (ctx
->opcode
>> 11) & 0x1f;
11665 sa
= (ctx
->opcode
>> 2) & 0x7;
11666 sa
= sa
== 0 ? 8 : sa
;
11667 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
11668 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
11669 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
11670 op1
= offset
= ctx
->opcode
& 0x1f;
11675 case M16_OPC_ADDIUSP
:
11677 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
11679 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
11682 case M16_OPC_ADDIUPC
:
11683 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
11686 offset
= (ctx
->opcode
& 0x7ff) << 1;
11687 offset
= (int16_t)(offset
<< 4) >> 4;
11688 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
11689 /* No delay slot, so just process as a normal instruction */
11692 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11693 offset
= (((ctx
->opcode
& 0x1f) << 21)
11694 | ((ctx
->opcode
>> 5) & 0x1f) << 16
11696 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
11697 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
11701 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
11702 ((int8_t)ctx
->opcode
) << 1, 0);
11703 /* No delay slot, so just process as a normal instruction */
11705 case M16_OPC_BNEQZ
:
11706 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
11707 ((int8_t)ctx
->opcode
) << 1, 0);
11708 /* No delay slot, so just process as a normal instruction */
11710 case M16_OPC_SHIFT
:
11711 switch (ctx
->opcode
& 0x3) {
11713 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
11716 #if defined(TARGET_MIPS64)
11717 check_insn(ctx
, ISA_MIPS3
);
11718 check_mips_64(ctx
);
11719 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
11721 generate_exception_end(ctx
, EXCP_RI
);
11725 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
11728 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
11732 #if defined(TARGET_MIPS64)
11734 check_insn(ctx
, ISA_MIPS3
);
11735 check_mips_64(ctx
);
11736 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
11741 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
11743 if ((ctx
->opcode
>> 4) & 1) {
11744 #if defined(TARGET_MIPS64)
11745 check_insn(ctx
, ISA_MIPS3
);
11746 check_mips_64(ctx
);
11747 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
11749 generate_exception_end(ctx
, EXCP_RI
);
11752 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
11756 case M16_OPC_ADDIU8
:
11758 int16_t imm
= (int8_t) ctx
->opcode
;
11760 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
11765 int16_t imm
= (uint8_t) ctx
->opcode
;
11766 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
11769 case M16_OPC_SLTIU
:
11771 int16_t imm
= (uint8_t) ctx
->opcode
;
11772 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
11779 funct
= (ctx
->opcode
>> 8) & 0x7;
11782 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
11783 ((int8_t)ctx
->opcode
) << 1, 0);
11786 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
11787 ((int8_t)ctx
->opcode
) << 1, 0);
11790 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
11793 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
11794 ((int8_t)ctx
->opcode
) << 3);
11797 check_insn(ctx
, ISA_MIPS32
);
11799 int do_ra
= ctx
->opcode
& (1 << 6);
11800 int do_s0
= ctx
->opcode
& (1 << 5);
11801 int do_s1
= ctx
->opcode
& (1 << 4);
11802 int framesize
= ctx
->opcode
& 0xf;
11804 if (framesize
== 0) {
11807 framesize
= framesize
<< 3;
11810 if (ctx
->opcode
& (1 << 7)) {
11811 gen_mips16_save(ctx
, 0, 0,
11812 do_ra
, do_s0
, do_s1
, framesize
);
11814 gen_mips16_restore(ctx
, 0, 0,
11815 do_ra
, do_s0
, do_s1
, framesize
);
11821 int rz
= xlat(ctx
->opcode
& 0x7);
11823 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
11824 ((ctx
->opcode
>> 5) & 0x7);
11825 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
11829 reg32
= ctx
->opcode
& 0x1f;
11830 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
11833 generate_exception_end(ctx
, EXCP_RI
);
11840 int16_t imm
= (uint8_t) ctx
->opcode
;
11842 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
11847 int16_t imm
= (uint8_t) ctx
->opcode
;
11848 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
11851 #if defined(TARGET_MIPS64)
11853 check_insn(ctx
, ISA_MIPS3
);
11854 check_mips_64(ctx
);
11855 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
11859 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11862 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
11865 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11868 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
11871 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11874 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
11877 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
11879 #if defined (TARGET_MIPS64)
11881 check_insn(ctx
, ISA_MIPS3
);
11882 check_mips_64(ctx
);
11883 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
11887 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11890 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
11893 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11896 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
11900 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
11903 switch (ctx
->opcode
& 0x3) {
11905 mips32_op
= OPC_ADDU
;
11908 mips32_op
= OPC_SUBU
;
11910 #if defined(TARGET_MIPS64)
11912 mips32_op
= OPC_DADDU
;
11913 check_insn(ctx
, ISA_MIPS3
);
11914 check_mips_64(ctx
);
11917 mips32_op
= OPC_DSUBU
;
11918 check_insn(ctx
, ISA_MIPS3
);
11919 check_mips_64(ctx
);
11923 generate_exception_end(ctx
, EXCP_RI
);
11927 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
11936 int nd
= (ctx
->opcode
>> 7) & 0x1;
11937 int link
= (ctx
->opcode
>> 6) & 0x1;
11938 int ra
= (ctx
->opcode
>> 5) & 0x1;
11941 check_insn(ctx
, ISA_MIPS32
);
11950 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
11955 if (is_uhi(extract32(ctx
->opcode
, 5, 6))) {
11956 gen_helper_do_semihosting(cpu_env
);
11958 /* XXX: not clear which exception should be raised
11959 * when in debug mode...
11961 check_insn(ctx
, ISA_MIPS32
);
11962 generate_exception_end(ctx
, EXCP_DBp
);
11966 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
11969 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
11972 generate_exception_end(ctx
, EXCP_BREAK
);
11975 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
11978 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
11981 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
11983 #if defined (TARGET_MIPS64)
11985 check_insn(ctx
, ISA_MIPS3
);
11986 check_mips_64(ctx
);
11987 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
11991 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
11994 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
11997 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
12000 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
12003 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
12006 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
12009 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
12012 check_insn(ctx
, ISA_MIPS32
);
12014 case RR_RY_CNVT_ZEB
:
12015 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12017 case RR_RY_CNVT_ZEH
:
12018 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12020 case RR_RY_CNVT_SEB
:
12021 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12023 case RR_RY_CNVT_SEH
:
12024 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12026 #if defined (TARGET_MIPS64)
12027 case RR_RY_CNVT_ZEW
:
12028 check_insn(ctx
, ISA_MIPS64
);
12029 check_mips_64(ctx
);
12030 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12032 case RR_RY_CNVT_SEW
:
12033 check_insn(ctx
, ISA_MIPS64
);
12034 check_mips_64(ctx
);
12035 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
12039 generate_exception_end(ctx
, EXCP_RI
);
12044 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
12046 #if defined (TARGET_MIPS64)
12048 check_insn(ctx
, ISA_MIPS3
);
12049 check_mips_64(ctx
);
12050 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
12053 check_insn(ctx
, ISA_MIPS3
);
12054 check_mips_64(ctx
);
12055 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
12058 check_insn(ctx
, ISA_MIPS3
);
12059 check_mips_64(ctx
);
12060 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
12063 check_insn(ctx
, ISA_MIPS3
);
12064 check_mips_64(ctx
);
12065 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
12069 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
12072 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
12075 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
12078 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
12080 #if defined (TARGET_MIPS64)
12082 check_insn(ctx
, ISA_MIPS3
);
12083 check_mips_64(ctx
);
12084 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
12087 check_insn(ctx
, ISA_MIPS3
);
12088 check_mips_64(ctx
);
12089 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
12092 check_insn(ctx
, ISA_MIPS3
);
12093 check_mips_64(ctx
);
12094 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
12097 check_insn(ctx
, ISA_MIPS3
);
12098 check_mips_64(ctx
);
12099 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
12103 generate_exception_end(ctx
, EXCP_RI
);
12107 case M16_OPC_EXTEND
:
12108 decode_extended_mips16_opc(env
, ctx
);
12111 #if defined(TARGET_MIPS64)
12113 funct
= (ctx
->opcode
>> 8) & 0x7;
12114 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
12118 generate_exception_end(ctx
, EXCP_RI
);
12125 /* microMIPS extension to MIPS32/MIPS64 */
12128 * microMIPS32/microMIPS64 major opcodes
12130 * 1. MIPS Architecture for Programmers Volume II-B:
12131 * The microMIPS32 Instruction Set (Revision 3.05)
12133 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
12135 * 2. MIPS Architecture For Programmers Volume II-A:
12136 * The MIPS64 Instruction Set (Revision 3.51)
12166 POOL32S
= 0x16, /* MIPS64 */
12167 DADDIU32
= 0x17, /* MIPS64 */
12196 /* 0x29 is reserved */
12209 /* 0x31 is reserved */
12222 SD32
= 0x36, /* MIPS64 */
12223 LD32
= 0x37, /* MIPS64 */
12225 /* 0x39 is reserved */
12241 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
12251 /* POOL32A encoding of minor opcode field */
12254 /* These opcodes are distinguished only by bits 9..6; those bits are
12255 * what are recorded below. */
12292 /* The following can be distinguished by their lower 6 bits. */
12302 /* POOL32AXF encoding of minor opcode field extension */
12305 * 1. MIPS Architecture for Programmers Volume II-B:
12306 * The microMIPS32 Instruction Set (Revision 3.05)
12308 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
12310 * 2. MIPS Architecture for Programmers VolumeIV-e:
12311 * The MIPS DSP Application-Specific Extension
12312 * to the microMIPS32 Architecture (Revision 2.34)
12314 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
12329 /* begin of microMIPS32 DSP */
12331 /* bits 13..12 for 0x01 */
12337 /* bits 13..12 for 0x2a */
12343 /* bits 13..12 for 0x32 */
12347 /* end of microMIPS32 DSP */
12349 /* bits 15..12 for 0x2c */
12366 /* bits 15..12 for 0x34 */
12374 /* bits 15..12 for 0x3c */
12376 JR
= 0x0, /* alias */
12384 /* bits 15..12 for 0x05 */
12388 /* bits 15..12 for 0x0d */
12400 /* bits 15..12 for 0x15 */
12406 /* bits 15..12 for 0x1d */
12410 /* bits 15..12 for 0x2d */
12415 /* bits 15..12 for 0x35 */
12422 /* POOL32B encoding of minor opcode field (bits 15..12) */
12438 /* POOL32C encoding of minor opcode field (bits 15..12) */
12446 /* 0xa is reserved */
12453 /* 0x6 is reserved */
12459 /* POOL32F encoding of minor opcode field (bits 5..0) */
12462 /* These are the bit 7..6 values */
12471 /* These are the bit 8..6 values */
12496 MOVZ_FMT_05
= 0x05,
12530 CABS_COND_FMT
= 0x1c, /* MIPS3D */
12537 /* POOL32Fxf encoding of minor opcode extension field */
12575 /* POOL32I encoding of minor opcode field (bits 25..21) */
12605 /* These overlap and are distinguished by bit16 of the instruction */
12614 /* POOL16A encoding of minor opcode field */
12621 /* POOL16B encoding of minor opcode field */
12628 /* POOL16C encoding of minor opcode field */
12648 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
12668 /* POOL16D encoding of minor opcode field */
12675 /* POOL16E encoding of minor opcode field */
12682 static int mmreg (int r
)
12684 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12689 /* Used for 16-bit store instructions. */
12690 static int mmreg2 (int r
)
12692 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
12697 #define uMIPS_RD(op) ((op >> 7) & 0x7)
12698 #define uMIPS_RS(op) ((op >> 4) & 0x7)
12699 #define uMIPS_RS2(op) uMIPS_RS(op)
12700 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
12701 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
12702 #define uMIPS_RS5(op) (op & 0x1f)
12704 /* Signed immediate */
12705 #define SIMM(op, start, width) \
12706 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
12709 /* Zero-extended immediate */
12710 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
12712 static void gen_addiur1sp(DisasContext
*ctx
)
12714 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12716 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
12719 static void gen_addiur2(DisasContext
*ctx
)
12721 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
12722 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12723 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12725 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
12728 static void gen_addiusp(DisasContext
*ctx
)
12730 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
12733 if (encoded
<= 1) {
12734 decoded
= 256 + encoded
;
12735 } else if (encoded
<= 255) {
12737 } else if (encoded
<= 509) {
12738 decoded
= encoded
- 512;
12740 decoded
= encoded
- 768;
12743 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
12746 static void gen_addius5(DisasContext
*ctx
)
12748 int imm
= SIMM(ctx
->opcode
, 1, 4);
12749 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12751 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
12754 static void gen_andi16(DisasContext
*ctx
)
12756 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
12757 31, 32, 63, 64, 255, 32768, 65535 };
12758 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12759 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12760 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
12762 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
12765 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
12766 int base
, int16_t offset
)
12771 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12772 generate_exception_end(ctx
, EXCP_RI
);
12776 t0
= tcg_temp_new();
12778 gen_base_offset_addr(ctx
, t0
, base
, offset
);
12780 t1
= tcg_const_tl(reglist
);
12781 t2
= tcg_const_i32(ctx
->mem_idx
);
12783 save_cpu_state(ctx
, 1);
12786 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
12789 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
12791 #ifdef TARGET_MIPS64
12793 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
12796 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
12802 tcg_temp_free_i32(t2
);
12806 static void gen_pool16c_insn(DisasContext
*ctx
)
12808 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
12809 int rs
= mmreg(ctx
->opcode
& 0x7);
12811 switch (((ctx
->opcode
) >> 4) & 0x3f) {
12816 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
12822 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
12828 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
12834 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
12841 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
12842 int offset
= ZIMM(ctx
->opcode
, 0, 4);
12844 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
12853 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
12854 int offset
= ZIMM(ctx
->opcode
, 0, 4);
12856 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
12863 int reg
= ctx
->opcode
& 0x1f;
12865 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
12871 int reg
= ctx
->opcode
& 0x1f;
12872 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
12873 /* Let normal delay slot handling in our caller take us
12874 to the branch target. */
12879 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
12880 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12884 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
12885 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12889 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
12893 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
12896 generate_exception_end(ctx
, EXCP_BREAK
);
12899 if (is_uhi(extract32(ctx
->opcode
, 0, 4))) {
12900 gen_helper_do_semihosting(cpu_env
);
12902 /* XXX: not clear which exception should be raised
12903 * when in debug mode...
12905 check_insn(ctx
, ISA_MIPS32
);
12906 generate_exception_end(ctx
, EXCP_DBp
);
12909 case JRADDIUSP
+ 0:
12910 case JRADDIUSP
+ 1:
12912 int imm
= ZIMM(ctx
->opcode
, 0, 5);
12913 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
12914 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
12915 /* Let normal delay slot handling in our caller take us
12916 to the branch target. */
12920 generate_exception_end(ctx
, EXCP_RI
);
12925 static inline void gen_movep(DisasContext
*ctx
, int enc_dest
, int enc_rt
,
12928 int rd
, rs
, re
, rt
;
12929 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12930 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12931 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12932 rd
= rd_enc
[enc_dest
];
12933 re
= re_enc
[enc_dest
];
12934 rs
= rs_rt_enc
[enc_rs
];
12935 rt
= rs_rt_enc
[enc_rt
];
12937 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
12939 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
12942 tcg_gen_mov_tl(cpu_gpr
[re
], cpu_gpr
[rt
]);
12944 tcg_gen_movi_tl(cpu_gpr
[re
], 0);
12948 static void gen_pool16c_r6_insn(DisasContext
*ctx
)
12950 int rt
= mmreg((ctx
->opcode
>> 7) & 0x7);
12951 int rs
= mmreg((ctx
->opcode
>> 4) & 0x7);
12953 switch (ctx
->opcode
& 0xf) {
12955 gen_logic(ctx
, OPC_NOR
, rt
, rs
, 0);
12958 gen_logic(ctx
, OPC_AND
, rt
, rt
, rs
);
12962 int lwm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
12963 int offset
= extract32(ctx
->opcode
, 4, 4);
12964 gen_ldst_multiple(ctx
, LWM32
, lwm_converted
, 29, offset
<< 2);
12967 case R6_JRC16
: /* JRCADDIUSP */
12968 if ((ctx
->opcode
>> 4) & 1) {
12970 int imm
= extract32(ctx
->opcode
, 5, 5);
12971 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
12972 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
12975 int rs
= extract32(ctx
->opcode
, 5, 5);
12976 gen_compute_branch(ctx
, OPC_JR
, 2, rs
, 0, 0, 0);
12979 case MOVEP
... MOVEP_07
:
12980 case MOVEP_0C
... MOVEP_0F
:
12982 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12983 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12984 int enc_rs
= (ctx
->opcode
& 3) | ((ctx
->opcode
>> 1) & 4);
12985 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
12989 gen_logic(ctx
, OPC_XOR
, rt
, rt
, rs
);
12992 gen_logic(ctx
, OPC_OR
, rt
, rt
, rs
);
12996 int swm_converted
= 0x11 + extract32(ctx
->opcode
, 8, 2);
12997 int offset
= extract32(ctx
->opcode
, 4, 4);
12998 gen_ldst_multiple(ctx
, SWM32
, swm_converted
, 29, offset
<< 2);
13001 case JALRC16
: /* BREAK16, SDBBP16 */
13002 switch (ctx
->opcode
& 0x3f) {
13004 case JALRC16
+ 0x20:
13006 gen_compute_branch(ctx
, OPC_JALR
, 2, (ctx
->opcode
>> 5) & 0x1f,
13011 generate_exception(ctx
, EXCP_BREAK
);
13015 if (is_uhi(extract32(ctx
->opcode
, 6, 4))) {
13016 gen_helper_do_semihosting(cpu_env
);
13018 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
13019 generate_exception(ctx
, EXCP_RI
);
13021 generate_exception(ctx
, EXCP_DBp
);
13028 generate_exception(ctx
, EXCP_RI
);
13033 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
13035 TCGv t0
= tcg_temp_new();
13036 TCGv t1
= tcg_temp_new();
13038 gen_load_gpr(t0
, base
);
13041 gen_load_gpr(t1
, index
);
13042 tcg_gen_shli_tl(t1
, t1
, 2);
13043 gen_op_addr_add(ctx
, t0
, t1
, t0
);
13046 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13047 gen_store_gpr(t1
, rd
);
13053 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
13054 int base
, int16_t offset
)
13058 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
13059 generate_exception_end(ctx
, EXCP_RI
);
13063 t0
= tcg_temp_new();
13064 t1
= tcg_temp_new();
13066 gen_base_offset_addr(ctx
, t0
, base
, offset
);
13071 generate_exception_end(ctx
, EXCP_RI
);
13074 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13075 gen_store_gpr(t1
, rd
);
13076 tcg_gen_movi_tl(t1
, 4);
13077 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13078 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
13079 gen_store_gpr(t1
, rd
+1);
13082 gen_load_gpr(t1
, rd
);
13083 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13084 tcg_gen_movi_tl(t1
, 4);
13085 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13086 gen_load_gpr(t1
, rd
+1);
13087 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
13089 #ifdef TARGET_MIPS64
13092 generate_exception_end(ctx
, EXCP_RI
);
13095 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13096 gen_store_gpr(t1
, rd
);
13097 tcg_gen_movi_tl(t1
, 8);
13098 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13099 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13100 gen_store_gpr(t1
, rd
+1);
13103 gen_load_gpr(t1
, rd
);
13104 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13105 tcg_gen_movi_tl(t1
, 8);
13106 gen_op_addr_add(ctx
, t0
, t0
, t1
);
13107 gen_load_gpr(t1
, rd
+1);
13108 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
13116 static void gen_sync(int stype
)
13118 TCGBar tcg_mo
= TCG_BAR_SC
;
13121 case 0x4: /* SYNC_WMB */
13122 tcg_mo
|= TCG_MO_ST_ST
;
13124 case 0x10: /* SYNC_MB */
13125 tcg_mo
|= TCG_MO_ALL
;
13127 case 0x11: /* SYNC_ACQUIRE */
13128 tcg_mo
|= TCG_MO_LD_LD
| TCG_MO_LD_ST
;
13130 case 0x12: /* SYNC_RELEASE */
13131 tcg_mo
|= TCG_MO_ST_ST
| TCG_MO_LD_ST
;
13133 case 0x13: /* SYNC_RMB */
13134 tcg_mo
|= TCG_MO_LD_LD
;
13137 tcg_mo
|= TCG_MO_ALL
;
13141 tcg_gen_mb(tcg_mo
);
13144 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
13146 int extension
= (ctx
->opcode
>> 6) & 0x3f;
13147 int minor
= (ctx
->opcode
>> 12) & 0xf;
13148 uint32_t mips32_op
;
13150 switch (extension
) {
13152 mips32_op
= OPC_TEQ
;
13155 mips32_op
= OPC_TGE
;
13158 mips32_op
= OPC_TGEU
;
13161 mips32_op
= OPC_TLT
;
13164 mips32_op
= OPC_TLTU
;
13167 mips32_op
= OPC_TNE
;
13169 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
13171 #ifndef CONFIG_USER_ONLY
13174 check_cp0_enabled(ctx
);
13176 /* Treat as NOP. */
13179 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
13183 check_cp0_enabled(ctx
);
13185 TCGv t0
= tcg_temp_new();
13187 gen_load_gpr(t0
, rt
);
13188 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
13194 switch (minor
& 3) {
13196 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13199 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13202 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13205 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13208 goto pool32axf_invalid
;
13212 switch (minor
& 3) {
13214 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13217 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
13220 goto pool32axf_invalid
;
13226 check_insn(ctx
, ISA_MIPS32R6
);
13227 gen_bitswap(ctx
, OPC_BITSWAP
, rs
, rt
);
13230 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
13233 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
13236 mips32_op
= OPC_CLO
;
13239 mips32_op
= OPC_CLZ
;
13241 check_insn(ctx
, ISA_MIPS32
);
13242 gen_cl(ctx
, mips32_op
, rt
, rs
);
13245 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13246 gen_rdhwr(ctx
, rt
, rs
, 0);
13249 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
13252 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13253 mips32_op
= OPC_MULT
;
13256 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13257 mips32_op
= OPC_MULTU
;
13260 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13261 mips32_op
= OPC_DIV
;
13264 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13265 mips32_op
= OPC_DIVU
;
13268 check_insn(ctx
, ISA_MIPS32
);
13269 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
13272 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13273 mips32_op
= OPC_MADD
;
13276 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13277 mips32_op
= OPC_MADDU
;
13280 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13281 mips32_op
= OPC_MSUB
;
13284 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13285 mips32_op
= OPC_MSUBU
;
13287 check_insn(ctx
, ISA_MIPS32
);
13288 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
13291 goto pool32axf_invalid
;
13302 generate_exception_err(ctx
, EXCP_CpU
, 2);
13305 goto pool32axf_invalid
;
13310 case JALR
: /* JALRC */
13311 case JALR_HB
: /* JALRC_HB */
13312 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13313 /* JALRC, JALRC_HB */
13314 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 0);
13316 /* JALR, JALR_HB */
13317 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
13318 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13323 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13324 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
13325 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13328 goto pool32axf_invalid
;
13334 check_cp0_enabled(ctx
);
13335 check_insn(ctx
, ISA_MIPS32R2
);
13336 gen_load_srsgpr(rs
, rt
);
13339 check_cp0_enabled(ctx
);
13340 check_insn(ctx
, ISA_MIPS32R2
);
13341 gen_store_srsgpr(rs
, rt
);
13344 goto pool32axf_invalid
;
13347 #ifndef CONFIG_USER_ONLY
13351 mips32_op
= OPC_TLBP
;
13354 mips32_op
= OPC_TLBR
;
13357 mips32_op
= OPC_TLBWI
;
13360 mips32_op
= OPC_TLBWR
;
13363 mips32_op
= OPC_TLBINV
;
13366 mips32_op
= OPC_TLBINVF
;
13369 mips32_op
= OPC_WAIT
;
13372 mips32_op
= OPC_DERET
;
13375 mips32_op
= OPC_ERET
;
13377 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
13380 goto pool32axf_invalid
;
13386 check_cp0_enabled(ctx
);
13388 TCGv t0
= tcg_temp_new();
13390 save_cpu_state(ctx
, 1);
13391 gen_helper_di(t0
, cpu_env
);
13392 gen_store_gpr(t0
, rs
);
13393 /* Stop translation as we may have switched the execution mode */
13394 ctx
->bstate
= BS_STOP
;
13399 check_cp0_enabled(ctx
);
13401 TCGv t0
= tcg_temp_new();
13403 save_cpu_state(ctx
, 1);
13404 gen_helper_ei(t0
, cpu_env
);
13405 gen_store_gpr(t0
, rs
);
13406 /* Stop translation as we may have switched the execution mode */
13407 ctx
->bstate
= BS_STOP
;
13412 goto pool32axf_invalid
;
13419 gen_sync(extract32(ctx
->opcode
, 16, 5));
13422 generate_exception_end(ctx
, EXCP_SYSCALL
);
13425 if (is_uhi(extract32(ctx
->opcode
, 16, 10))) {
13426 gen_helper_do_semihosting(cpu_env
);
13428 check_insn(ctx
, ISA_MIPS32
);
13429 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
13430 generate_exception_end(ctx
, EXCP_RI
);
13432 generate_exception_end(ctx
, EXCP_DBp
);
13437 goto pool32axf_invalid
;
13441 switch (minor
& 3) {
13443 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
13446 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
13449 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
13452 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
13455 goto pool32axf_invalid
;
13459 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13462 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
13465 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
13468 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
13471 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
13474 goto pool32axf_invalid
;
13479 MIPS_INVAL("pool32axf");
13480 generate_exception_end(ctx
, EXCP_RI
);
13485 /* Values for microMIPS fmt field. Variable-width, depending on which
13486 formats the instruction supports. */
13505 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
13507 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
13508 uint32_t mips32_op
;
13510 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
13511 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
13512 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
13514 switch (extension
) {
13515 case FLOAT_1BIT_FMT(CFC1
, 0):
13516 mips32_op
= OPC_CFC1
;
13518 case FLOAT_1BIT_FMT(CTC1
, 0):
13519 mips32_op
= OPC_CTC1
;
13521 case FLOAT_1BIT_FMT(MFC1
, 0):
13522 mips32_op
= OPC_MFC1
;
13524 case FLOAT_1BIT_FMT(MTC1
, 0):
13525 mips32_op
= OPC_MTC1
;
13527 case FLOAT_1BIT_FMT(MFHC1
, 0):
13528 mips32_op
= OPC_MFHC1
;
13530 case FLOAT_1BIT_FMT(MTHC1
, 0):
13531 mips32_op
= OPC_MTHC1
;
13533 gen_cp1(ctx
, mips32_op
, rt
, rs
);
13536 /* Reciprocal square root */
13537 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
13538 mips32_op
= OPC_RSQRT_S
;
13540 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
13541 mips32_op
= OPC_RSQRT_D
;
13545 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
13546 mips32_op
= OPC_SQRT_S
;
13548 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
13549 mips32_op
= OPC_SQRT_D
;
13553 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
13554 mips32_op
= OPC_RECIP_S
;
13556 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
13557 mips32_op
= OPC_RECIP_D
;
13561 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
13562 mips32_op
= OPC_FLOOR_L_S
;
13564 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
13565 mips32_op
= OPC_FLOOR_L_D
;
13567 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
13568 mips32_op
= OPC_FLOOR_W_S
;
13570 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
13571 mips32_op
= OPC_FLOOR_W_D
;
13575 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
13576 mips32_op
= OPC_CEIL_L_S
;
13578 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
13579 mips32_op
= OPC_CEIL_L_D
;
13581 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
13582 mips32_op
= OPC_CEIL_W_S
;
13584 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
13585 mips32_op
= OPC_CEIL_W_D
;
13589 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
13590 mips32_op
= OPC_TRUNC_L_S
;
13592 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
13593 mips32_op
= OPC_TRUNC_L_D
;
13595 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
13596 mips32_op
= OPC_TRUNC_W_S
;
13598 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
13599 mips32_op
= OPC_TRUNC_W_D
;
13603 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
13604 mips32_op
= OPC_ROUND_L_S
;
13606 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
13607 mips32_op
= OPC_ROUND_L_D
;
13609 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
13610 mips32_op
= OPC_ROUND_W_S
;
13612 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
13613 mips32_op
= OPC_ROUND_W_D
;
13616 /* Integer to floating-point conversion */
13617 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
13618 mips32_op
= OPC_CVT_L_S
;
13620 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
13621 mips32_op
= OPC_CVT_L_D
;
13623 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
13624 mips32_op
= OPC_CVT_W_S
;
13626 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
13627 mips32_op
= OPC_CVT_W_D
;
13630 /* Paired-foo conversions */
13631 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
13632 mips32_op
= OPC_CVT_S_PL
;
13634 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
13635 mips32_op
= OPC_CVT_S_PU
;
13637 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
13638 mips32_op
= OPC_CVT_PW_PS
;
13640 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
13641 mips32_op
= OPC_CVT_PS_PW
;
13644 /* Floating-point moves */
13645 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
13646 mips32_op
= OPC_MOV_S
;
13648 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
13649 mips32_op
= OPC_MOV_D
;
13651 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
13652 mips32_op
= OPC_MOV_PS
;
13655 /* Absolute value */
13656 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
13657 mips32_op
= OPC_ABS_S
;
13659 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
13660 mips32_op
= OPC_ABS_D
;
13662 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
13663 mips32_op
= OPC_ABS_PS
;
13667 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
13668 mips32_op
= OPC_NEG_S
;
13670 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
13671 mips32_op
= OPC_NEG_D
;
13673 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
13674 mips32_op
= OPC_NEG_PS
;
13677 /* Reciprocal square root step */
13678 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
13679 mips32_op
= OPC_RSQRT1_S
;
13681 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
13682 mips32_op
= OPC_RSQRT1_D
;
13684 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
13685 mips32_op
= OPC_RSQRT1_PS
;
13688 /* Reciprocal step */
13689 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
13690 mips32_op
= OPC_RECIP1_S
;
13692 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
13693 mips32_op
= OPC_RECIP1_S
;
13695 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
13696 mips32_op
= OPC_RECIP1_PS
;
13699 /* Conversions from double */
13700 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
13701 mips32_op
= OPC_CVT_D_S
;
13703 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
13704 mips32_op
= OPC_CVT_D_W
;
13706 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
13707 mips32_op
= OPC_CVT_D_L
;
13710 /* Conversions from single */
13711 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
13712 mips32_op
= OPC_CVT_S_D
;
13714 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
13715 mips32_op
= OPC_CVT_S_W
;
13717 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
13718 mips32_op
= OPC_CVT_S_L
;
13720 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
13723 /* Conditional moves on floating-point codes */
13724 case COND_FLOAT_MOV(MOVT
, 0):
13725 case COND_FLOAT_MOV(MOVT
, 1):
13726 case COND_FLOAT_MOV(MOVT
, 2):
13727 case COND_FLOAT_MOV(MOVT
, 3):
13728 case COND_FLOAT_MOV(MOVT
, 4):
13729 case COND_FLOAT_MOV(MOVT
, 5):
13730 case COND_FLOAT_MOV(MOVT
, 6):
13731 case COND_FLOAT_MOV(MOVT
, 7):
13732 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13733 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
13735 case COND_FLOAT_MOV(MOVF
, 0):
13736 case COND_FLOAT_MOV(MOVF
, 1):
13737 case COND_FLOAT_MOV(MOVF
, 2):
13738 case COND_FLOAT_MOV(MOVF
, 3):
13739 case COND_FLOAT_MOV(MOVF
, 4):
13740 case COND_FLOAT_MOV(MOVF
, 5):
13741 case COND_FLOAT_MOV(MOVF
, 6):
13742 case COND_FLOAT_MOV(MOVF
, 7):
13743 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13744 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
13747 MIPS_INVAL("pool32fxf");
13748 generate_exception_end(ctx
, EXCP_RI
);
13753 static void decode_micromips32_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
13757 int rt
, rs
, rd
, rr
;
13759 uint32_t op
, minor
, mips32_op
;
13760 uint32_t cond
, fmt
, cc
;
13762 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
13763 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
13765 rt
= (ctx
->opcode
>> 21) & 0x1f;
13766 rs
= (ctx
->opcode
>> 16) & 0x1f;
13767 rd
= (ctx
->opcode
>> 11) & 0x1f;
13768 rr
= (ctx
->opcode
>> 6) & 0x1f;
13769 imm
= (int16_t) ctx
->opcode
;
13771 op
= (ctx
->opcode
>> 26) & 0x3f;
13774 minor
= ctx
->opcode
& 0x3f;
13777 minor
= (ctx
->opcode
>> 6) & 0xf;
13780 mips32_op
= OPC_SLL
;
13783 mips32_op
= OPC_SRA
;
13786 mips32_op
= OPC_SRL
;
13789 mips32_op
= OPC_ROTR
;
13791 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
13794 check_insn(ctx
, ISA_MIPS32R6
);
13795 gen_cond_move(ctx
, OPC_SELEQZ
, rd
, rs
, rt
);
13798 check_insn(ctx
, ISA_MIPS32R6
);
13799 gen_cond_move(ctx
, OPC_SELNEZ
, rd
, rs
, rt
);
13802 check_insn(ctx
, ISA_MIPS32R6
);
13803 gen_rdhwr(ctx
, rt
, rs
, extract32(ctx
->opcode
, 11, 3));
13806 goto pool32a_invalid
;
13810 minor
= (ctx
->opcode
>> 6) & 0xf;
13814 mips32_op
= OPC_ADD
;
13817 mips32_op
= OPC_ADDU
;
13820 mips32_op
= OPC_SUB
;
13823 mips32_op
= OPC_SUBU
;
13826 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
13827 mips32_op
= OPC_MUL
;
13829 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
13833 mips32_op
= OPC_SLLV
;
13836 mips32_op
= OPC_SRLV
;
13839 mips32_op
= OPC_SRAV
;
13842 mips32_op
= OPC_ROTRV
;
13844 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
13846 /* Logical operations */
13848 mips32_op
= OPC_AND
;
13851 mips32_op
= OPC_OR
;
13854 mips32_op
= OPC_NOR
;
13857 mips32_op
= OPC_XOR
;
13859 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
13861 /* Set less than */
13863 mips32_op
= OPC_SLT
;
13866 mips32_op
= OPC_SLTU
;
13868 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
13871 goto pool32a_invalid
;
13875 minor
= (ctx
->opcode
>> 6) & 0xf;
13877 /* Conditional moves */
13878 case MOVN
: /* MUL */
13879 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13881 gen_r6_muldiv(ctx
, R6_OPC_MUL
, rd
, rs
, rt
);
13884 gen_cond_move(ctx
, OPC_MOVN
, rd
, rs
, rt
);
13887 case MOVZ
: /* MUH */
13888 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13890 gen_r6_muldiv(ctx
, R6_OPC_MUH
, rd
, rs
, rt
);
13893 gen_cond_move(ctx
, OPC_MOVZ
, rd
, rs
, rt
);
13897 check_insn(ctx
, ISA_MIPS32R6
);
13898 gen_r6_muldiv(ctx
, R6_OPC_MULU
, rd
, rs
, rt
);
13901 check_insn(ctx
, ISA_MIPS32R6
);
13902 gen_r6_muldiv(ctx
, R6_OPC_MUHU
, rd
, rs
, rt
);
13904 case LWXS
: /* DIV */
13905 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
13907 gen_r6_muldiv(ctx
, R6_OPC_DIV
, rd
, rs
, rt
);
13910 gen_ldxs(ctx
, rs
, rt
, rd
);
13914 check_insn(ctx
, ISA_MIPS32R6
);
13915 gen_r6_muldiv(ctx
, R6_OPC_MOD
, rd
, rs
, rt
);
13918 check_insn(ctx
, ISA_MIPS32R6
);
13919 gen_r6_muldiv(ctx
, R6_OPC_DIVU
, rd
, rs
, rt
);
13922 check_insn(ctx
, ISA_MIPS32R6
);
13923 gen_r6_muldiv(ctx
, R6_OPC_MODU
, rd
, rs
, rt
);
13926 goto pool32a_invalid
;
13930 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
13933 check_insn(ctx
, ISA_MIPS32R6
);
13934 gen_lsa(ctx
, OPC_LSA
, rd
, rs
, rt
,
13935 extract32(ctx
->opcode
, 9, 2));
13938 check_insn(ctx
, ISA_MIPS32R6
);
13939 gen_align(ctx
, OPC_ALIGN
, rd
, rs
, rt
,
13940 extract32(ctx
->opcode
, 9, 2));
13943 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
13946 gen_pool32axf(env
, ctx
, rt
, rs
);
13949 generate_exception_end(ctx
, EXCP_BREAK
);
13952 check_insn(ctx
, ISA_MIPS32R6
);
13953 generate_exception_end(ctx
, EXCP_RI
);
13957 MIPS_INVAL("pool32a");
13958 generate_exception_end(ctx
, EXCP_RI
);
13963 minor
= (ctx
->opcode
>> 12) & 0xf;
13966 check_cp0_enabled(ctx
);
13967 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
13968 gen_cache_operation(ctx
, rt
, rs
, imm
);
13973 /* COP2: Not implemented. */
13974 generate_exception_err(ctx
, EXCP_CpU
, 2);
13976 #ifdef TARGET_MIPS64
13979 check_insn(ctx
, ISA_MIPS3
);
13980 check_mips_64(ctx
);
13985 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13987 #ifdef TARGET_MIPS64
13990 check_insn(ctx
, ISA_MIPS3
);
13991 check_mips_64(ctx
);
13996 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13999 MIPS_INVAL("pool32b");
14000 generate_exception_end(ctx
, EXCP_RI
);
14005 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
14006 minor
= ctx
->opcode
& 0x3f;
14007 check_cp1_enabled(ctx
);
14010 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14011 mips32_op
= OPC_ALNV_PS
;
14014 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14015 mips32_op
= OPC_MADD_S
;
14018 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14019 mips32_op
= OPC_MADD_D
;
14022 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14023 mips32_op
= OPC_MADD_PS
;
14026 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14027 mips32_op
= OPC_MSUB_S
;
14030 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14031 mips32_op
= OPC_MSUB_D
;
14034 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14035 mips32_op
= OPC_MSUB_PS
;
14038 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14039 mips32_op
= OPC_NMADD_S
;
14042 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14043 mips32_op
= OPC_NMADD_D
;
14046 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14047 mips32_op
= OPC_NMADD_PS
;
14050 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14051 mips32_op
= OPC_NMSUB_S
;
14054 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14055 mips32_op
= OPC_NMSUB_D
;
14058 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14059 mips32_op
= OPC_NMSUB_PS
;
14061 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
14063 case CABS_COND_FMT
:
14064 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14065 cond
= (ctx
->opcode
>> 6) & 0xf;
14066 cc
= (ctx
->opcode
>> 13) & 0x7;
14067 fmt
= (ctx
->opcode
>> 10) & 0x3;
14070 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
14073 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
14076 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
14079 goto pool32f_invalid
;
14083 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14084 cond
= (ctx
->opcode
>> 6) & 0xf;
14085 cc
= (ctx
->opcode
>> 13) & 0x7;
14086 fmt
= (ctx
->opcode
>> 10) & 0x3;
14089 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
14092 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
14095 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
14098 goto pool32f_invalid
;
14102 check_insn(ctx
, ISA_MIPS32R6
);
14103 gen_r6_cmp_s(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
14106 check_insn(ctx
, ISA_MIPS32R6
);
14107 gen_r6_cmp_d(ctx
, (ctx
->opcode
>> 6) & 0x1f, rt
, rs
, rd
);
14110 gen_pool32fxf(ctx
, rt
, rs
);
14114 switch ((ctx
->opcode
>> 6) & 0x7) {
14116 mips32_op
= OPC_PLL_PS
;
14119 mips32_op
= OPC_PLU_PS
;
14122 mips32_op
= OPC_PUL_PS
;
14125 mips32_op
= OPC_PUU_PS
;
14128 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14129 mips32_op
= OPC_CVT_PS_S
;
14131 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14134 goto pool32f_invalid
;
14138 check_insn(ctx
, ISA_MIPS32R6
);
14139 switch ((ctx
->opcode
>> 9) & 0x3) {
14141 gen_farith(ctx
, OPC_MIN_S
, rt
, rs
, rd
, 0);
14144 gen_farith(ctx
, OPC_MIN_D
, rt
, rs
, rd
, 0);
14147 goto pool32f_invalid
;
14152 switch ((ctx
->opcode
>> 6) & 0x7) {
14154 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14155 mips32_op
= OPC_LWXC1
;
14158 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14159 mips32_op
= OPC_SWXC1
;
14162 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14163 mips32_op
= OPC_LDXC1
;
14166 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14167 mips32_op
= OPC_SDXC1
;
14170 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14171 mips32_op
= OPC_LUXC1
;
14174 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14175 mips32_op
= OPC_SUXC1
;
14177 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
14180 goto pool32f_invalid
;
14184 check_insn(ctx
, ISA_MIPS32R6
);
14185 switch ((ctx
->opcode
>> 9) & 0x3) {
14187 gen_farith(ctx
, OPC_MAX_S
, rt
, rs
, rd
, 0);
14190 gen_farith(ctx
, OPC_MAX_D
, rt
, rs
, rd
, 0);
14193 goto pool32f_invalid
;
14198 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14199 fmt
= (ctx
->opcode
>> 9) & 0x3;
14200 switch ((ctx
->opcode
>> 6) & 0x7) {
14204 mips32_op
= OPC_RSQRT2_S
;
14207 mips32_op
= OPC_RSQRT2_D
;
14210 mips32_op
= OPC_RSQRT2_PS
;
14213 goto pool32f_invalid
;
14219 mips32_op
= OPC_RECIP2_S
;
14222 mips32_op
= OPC_RECIP2_D
;
14225 mips32_op
= OPC_RECIP2_PS
;
14228 goto pool32f_invalid
;
14232 mips32_op
= OPC_ADDR_PS
;
14235 mips32_op
= OPC_MULR_PS
;
14237 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14240 goto pool32f_invalid
;
14244 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
14245 cc
= (ctx
->opcode
>> 13) & 0x7;
14246 fmt
= (ctx
->opcode
>> 9) & 0x3;
14247 switch ((ctx
->opcode
>> 6) & 0x7) {
14248 case MOVF_FMT
: /* RINT_FMT */
14249 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14253 gen_farith(ctx
, OPC_RINT_S
, 0, rt
, rs
, 0);
14256 gen_farith(ctx
, OPC_RINT_D
, 0, rt
, rs
, 0);
14259 goto pool32f_invalid
;
14265 gen_movcf_s(ctx
, rs
, rt
, cc
, 0);
14268 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
14272 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
14275 goto pool32f_invalid
;
14279 case MOVT_FMT
: /* CLASS_FMT */
14280 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14284 gen_farith(ctx
, OPC_CLASS_S
, 0, rt
, rs
, 0);
14287 gen_farith(ctx
, OPC_CLASS_D
, 0, rt
, rs
, 0);
14290 goto pool32f_invalid
;
14296 gen_movcf_s(ctx
, rs
, rt
, cc
, 1);
14299 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
14303 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
14306 goto pool32f_invalid
;
14311 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14314 goto pool32f_invalid
;
14317 #define FINSN_3ARG_SDPS(prfx) \
14318 switch ((ctx->opcode >> 8) & 0x3) { \
14320 mips32_op = OPC_##prfx##_S; \
14323 mips32_op = OPC_##prfx##_D; \
14325 case FMT_SDPS_PS: \
14327 mips32_op = OPC_##prfx##_PS; \
14330 goto pool32f_invalid; \
14333 check_insn(ctx
, ISA_MIPS32R6
);
14334 switch ((ctx
->opcode
>> 9) & 0x3) {
14336 gen_farith(ctx
, OPC_MINA_S
, rt
, rs
, rd
, 0);
14339 gen_farith(ctx
, OPC_MINA_D
, rt
, rs
, rd
, 0);
14342 goto pool32f_invalid
;
14346 check_insn(ctx
, ISA_MIPS32R6
);
14347 switch ((ctx
->opcode
>> 9) & 0x3) {
14349 gen_farith(ctx
, OPC_MAXA_S
, rt
, rs
, rd
, 0);
14352 gen_farith(ctx
, OPC_MAXA_D
, rt
, rs
, rd
, 0);
14355 goto pool32f_invalid
;
14359 /* regular FP ops */
14360 switch ((ctx
->opcode
>> 6) & 0x3) {
14362 FINSN_3ARG_SDPS(ADD
);
14365 FINSN_3ARG_SDPS(SUB
);
14368 FINSN_3ARG_SDPS(MUL
);
14371 fmt
= (ctx
->opcode
>> 8) & 0x3;
14373 mips32_op
= OPC_DIV_D
;
14374 } else if (fmt
== 0) {
14375 mips32_op
= OPC_DIV_S
;
14377 goto pool32f_invalid
;
14381 goto pool32f_invalid
;
14386 switch ((ctx
->opcode
>> 6) & 0x7) {
14387 case MOVN_FMT
: /* SELNEZ_FMT */
14388 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14390 switch ((ctx
->opcode
>> 9) & 0x3) {
14392 gen_sel_s(ctx
, OPC_SELNEZ_S
, rd
, rt
, rs
);
14395 gen_sel_d(ctx
, OPC_SELNEZ_D
, rd
, rt
, rs
);
14398 goto pool32f_invalid
;
14402 FINSN_3ARG_SDPS(MOVN
);
14406 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14407 FINSN_3ARG_SDPS(MOVN
);
14409 case MOVZ_FMT
: /* SELEQZ_FMT */
14410 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14412 switch ((ctx
->opcode
>> 9) & 0x3) {
14414 gen_sel_s(ctx
, OPC_SELEQZ_S
, rd
, rt
, rs
);
14417 gen_sel_d(ctx
, OPC_SELEQZ_D
, rd
, rt
, rs
);
14420 goto pool32f_invalid
;
14424 FINSN_3ARG_SDPS(MOVZ
);
14428 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14429 FINSN_3ARG_SDPS(MOVZ
);
14432 check_insn(ctx
, ISA_MIPS32R6
);
14433 switch ((ctx
->opcode
>> 9) & 0x3) {
14435 gen_sel_s(ctx
, OPC_SEL_S
, rd
, rt
, rs
);
14438 gen_sel_d(ctx
, OPC_SEL_D
, rd
, rt
, rs
);
14441 goto pool32f_invalid
;
14445 check_insn(ctx
, ISA_MIPS32R6
);
14446 switch ((ctx
->opcode
>> 9) & 0x3) {
14448 mips32_op
= OPC_MADDF_S
;
14451 mips32_op
= OPC_MADDF_D
;
14454 goto pool32f_invalid
;
14458 check_insn(ctx
, ISA_MIPS32R6
);
14459 switch ((ctx
->opcode
>> 9) & 0x3) {
14461 mips32_op
= OPC_MSUBF_S
;
14464 mips32_op
= OPC_MSUBF_D
;
14467 goto pool32f_invalid
;
14471 goto pool32f_invalid
;
14475 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
14479 MIPS_INVAL("pool32f");
14480 generate_exception_end(ctx
, EXCP_RI
);
14484 generate_exception_err(ctx
, EXCP_CpU
, 1);
14488 minor
= (ctx
->opcode
>> 21) & 0x1f;
14491 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14492 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
14495 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14496 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
14497 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14500 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14501 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
14502 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14505 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14506 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
14509 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14510 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
14511 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14514 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14515 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
14516 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14519 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14520 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
14523 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14524 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
14528 case TLTI
: /* BC1EQZC */
14529 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14531 check_cp1_enabled(ctx
);
14532 gen_compute_branch1_r6(ctx
, OPC_BC1EQZ
, rs
, imm
<< 1, 0);
14535 mips32_op
= OPC_TLTI
;
14539 case TGEI
: /* BC1NEZC */
14540 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14542 check_cp1_enabled(ctx
);
14543 gen_compute_branch1_r6(ctx
, OPC_BC1NEZ
, rs
, imm
<< 1, 0);
14546 mips32_op
= OPC_TGEI
;
14551 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14552 mips32_op
= OPC_TLTIU
;
14555 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14556 mips32_op
= OPC_TGEIU
;
14558 case TNEI
: /* SYNCI */
14559 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14561 /* Break the TB to be able to sync copied instructions
14563 ctx
->bstate
= BS_STOP
;
14566 mips32_op
= OPC_TNEI
;
14571 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14572 mips32_op
= OPC_TEQI
;
14574 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
14579 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14580 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
14581 4, rs
, 0, imm
<< 1, 0);
14582 /* Compact branches don't have a delay slot, so just let
14583 the normal delay slot handling take us to the branch
14587 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14588 gen_logic_imm(ctx
, OPC_LUI
, rs
, 0, imm
);
14591 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14592 /* Break the TB to be able to sync copied instructions
14594 ctx
->bstate
= BS_STOP
;
14598 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14599 /* COP2: Not implemented. */
14600 generate_exception_err(ctx
, EXCP_CpU
, 2);
14603 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14604 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
14607 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14608 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
14611 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14612 mips32_op
= OPC_BC1FANY4
;
14615 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14616 mips32_op
= OPC_BC1TANY4
;
14619 check_insn(ctx
, ASE_MIPS3D
);
14622 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14623 check_cp1_enabled(ctx
);
14624 gen_compute_branch1(ctx
, mips32_op
,
14625 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
14627 generate_exception_err(ctx
, EXCP_CpU
, 1);
14632 /* MIPS DSP: not implemented */
14635 MIPS_INVAL("pool32i");
14636 generate_exception_end(ctx
, EXCP_RI
);
14641 minor
= (ctx
->opcode
>> 12) & 0xf;
14642 offset
= sextract32(ctx
->opcode
, 0,
14643 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 9 : 12);
14646 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14647 mips32_op
= OPC_LWL
;
14650 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14651 mips32_op
= OPC_SWL
;
14654 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14655 mips32_op
= OPC_LWR
;
14658 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14659 mips32_op
= OPC_SWR
;
14661 #if defined(TARGET_MIPS64)
14663 check_insn(ctx
, ISA_MIPS3
);
14664 check_mips_64(ctx
);
14665 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14666 mips32_op
= OPC_LDL
;
14669 check_insn(ctx
, ISA_MIPS3
);
14670 check_mips_64(ctx
);
14671 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14672 mips32_op
= OPC_SDL
;
14675 check_insn(ctx
, ISA_MIPS3
);
14676 check_mips_64(ctx
);
14677 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14678 mips32_op
= OPC_LDR
;
14681 check_insn(ctx
, ISA_MIPS3
);
14682 check_mips_64(ctx
);
14683 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14684 mips32_op
= OPC_SDR
;
14687 check_insn(ctx
, ISA_MIPS3
);
14688 check_mips_64(ctx
);
14689 mips32_op
= OPC_LWU
;
14692 check_insn(ctx
, ISA_MIPS3
);
14693 check_mips_64(ctx
);
14694 mips32_op
= OPC_LLD
;
14698 mips32_op
= OPC_LL
;
14701 gen_ld(ctx
, mips32_op
, rt
, rs
, offset
);
14704 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
14707 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, offset
);
14709 #if defined(TARGET_MIPS64)
14711 check_insn(ctx
, ISA_MIPS3
);
14712 check_mips_64(ctx
);
14713 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, offset
);
14717 /* Treat as no-op */
14718 if ((ctx
->insn_flags
& ISA_MIPS32R6
) && (rt
>= 24)) {
14719 /* hint codes 24-31 are reserved and signal RI */
14720 generate_exception(ctx
, EXCP_RI
);
14724 MIPS_INVAL("pool32c");
14725 generate_exception_end(ctx
, EXCP_RI
);
14729 case ADDI32
: /* AUI, LUI */
14730 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14732 gen_logic_imm(ctx
, OPC_LUI
, rt
, rs
, imm
);
14735 mips32_op
= OPC_ADDI
;
14740 mips32_op
= OPC_ADDIU
;
14742 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14745 /* Logical operations */
14747 mips32_op
= OPC_ORI
;
14750 mips32_op
= OPC_XORI
;
14753 mips32_op
= OPC_ANDI
;
14755 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14758 /* Set less than immediate */
14760 mips32_op
= OPC_SLTI
;
14763 mips32_op
= OPC_SLTIU
;
14765 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
14768 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
14769 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
14770 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
14771 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14773 case JALS32
: /* BOVC, BEQC, BEQZALC */
14774 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14777 mips32_op
= OPC_BOVC
;
14778 } else if (rs
< rt
&& rs
== 0) {
14780 mips32_op
= OPC_BEQZALC
;
14783 mips32_op
= OPC_BEQC
;
14785 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14788 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
14789 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
14790 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14793 case BEQ32
: /* BC */
14794 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14796 gen_compute_compact_branch(ctx
, OPC_BC
, 0, 0,
14797 sextract32(ctx
->opcode
<< 1, 0, 27));
14800 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
14803 case BNE32
: /* BALC */
14804 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14806 gen_compute_compact_branch(ctx
, OPC_BALC
, 0, 0,
14807 sextract32(ctx
->opcode
<< 1, 0, 27));
14810 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
14813 case J32
: /* BGTZC, BLTZC, BLTC */
14814 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14815 if (rs
== 0 && rt
!= 0) {
14817 mips32_op
= OPC_BGTZC
;
14818 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
14820 mips32_op
= OPC_BLTZC
;
14823 mips32_op
= OPC_BLTC
;
14825 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14828 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
14829 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
14832 case JAL32
: /* BLEZC, BGEZC, BGEC */
14833 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14834 if (rs
== 0 && rt
!= 0) {
14836 mips32_op
= OPC_BLEZC
;
14837 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
14839 mips32_op
= OPC_BGEZC
;
14842 mips32_op
= OPC_BGEC
;
14844 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14847 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
14848 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
14849 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
14852 /* Floating point (COP1) */
14854 mips32_op
= OPC_LWC1
;
14857 mips32_op
= OPC_LDC1
;
14860 mips32_op
= OPC_SWC1
;
14863 mips32_op
= OPC_SDC1
;
14865 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
14867 case ADDIUPC
: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14868 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
14869 /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
14870 switch ((ctx
->opcode
>> 16) & 0x1f) {
14871 case ADDIUPC_00
... ADDIUPC_07
:
14872 gen_pcrel(ctx
, OPC_ADDIUPC
, ctx
->pc
& ~0x3, rt
);
14875 gen_pcrel(ctx
, OPC_AUIPC
, ctx
->pc
, rt
);
14878 gen_pcrel(ctx
, OPC_ALUIPC
, ctx
->pc
, rt
);
14880 case LWPC_08
... LWPC_0F
:
14881 gen_pcrel(ctx
, R6_OPC_LWPC
, ctx
->pc
& ~0x3, rt
);
14884 generate_exception(ctx
, EXCP_RI
);
14889 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
14890 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
14892 gen_addiupc(ctx
, reg
, offset
, 0, 0);
14895 case BNVC
: /* BNEC, BNEZALC */
14896 check_insn(ctx
, ISA_MIPS32R6
);
14899 mips32_op
= OPC_BNVC
;
14900 } else if (rs
< rt
&& rs
== 0) {
14902 mips32_op
= OPC_BNEZALC
;
14905 mips32_op
= OPC_BNEC
;
14907 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14909 case R6_BNEZC
: /* JIALC */
14910 check_insn(ctx
, ISA_MIPS32R6
);
14913 gen_compute_compact_branch(ctx
, OPC_BNEZC
, rt
, 0,
14914 sextract32(ctx
->opcode
<< 1, 0, 22));
14917 gen_compute_compact_branch(ctx
, OPC_JIALC
, 0, rs
, imm
);
14920 case R6_BEQZC
: /* JIC */
14921 check_insn(ctx
, ISA_MIPS32R6
);
14924 gen_compute_compact_branch(ctx
, OPC_BEQZC
, rt
, 0,
14925 sextract32(ctx
->opcode
<< 1, 0, 22));
14928 gen_compute_compact_branch(ctx
, OPC_JIC
, 0, rs
, imm
);
14931 case BLEZALC
: /* BGEZALC, BGEUC */
14932 check_insn(ctx
, ISA_MIPS32R6
);
14933 if (rs
== 0 && rt
!= 0) {
14935 mips32_op
= OPC_BLEZALC
;
14936 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
14938 mips32_op
= OPC_BGEZALC
;
14941 mips32_op
= OPC_BGEUC
;
14943 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14945 case BGTZALC
: /* BLTZALC, BLTUC */
14946 check_insn(ctx
, ISA_MIPS32R6
);
14947 if (rs
== 0 && rt
!= 0) {
14949 mips32_op
= OPC_BGTZALC
;
14950 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
14952 mips32_op
= OPC_BLTZALC
;
14955 mips32_op
= OPC_BLTUC
;
14957 gen_compute_compact_branch(ctx
, mips32_op
, rs
, rt
, imm
<< 1);
14959 /* Loads and stores */
14961 mips32_op
= OPC_LB
;
14964 mips32_op
= OPC_LBU
;
14967 mips32_op
= OPC_LH
;
14970 mips32_op
= OPC_LHU
;
14973 mips32_op
= OPC_LW
;
14975 #ifdef TARGET_MIPS64
14977 check_insn(ctx
, ISA_MIPS3
);
14978 check_mips_64(ctx
);
14979 mips32_op
= OPC_LD
;
14982 check_insn(ctx
, ISA_MIPS3
);
14983 check_mips_64(ctx
);
14984 mips32_op
= OPC_SD
;
14988 mips32_op
= OPC_SB
;
14991 mips32_op
= OPC_SH
;
14994 mips32_op
= OPC_SW
;
14997 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
15000 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
15003 generate_exception_end(ctx
, EXCP_RI
);
15008 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
15012 /* make sure instructions are on a halfword boundary */
15013 if (ctx
->pc
& 0x1) {
15014 env
->CP0_BadVAddr
= ctx
->pc
;
15015 generate_exception_end(ctx
, EXCP_AdEL
);
15019 op
= (ctx
->opcode
>> 10) & 0x3f;
15020 /* Enforce properly-sized instructions in a delay slot */
15021 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
15022 switch (op
& 0x7) { /* MSB-3..MSB-5 */
15024 /* POOL32A, POOL32B, POOL32I, POOL32C */
15026 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
15028 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
15030 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
15032 /* LB32, LH32, LWC132, LDC132, LW32 */
15033 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
15034 generate_exception_end(ctx
, EXCP_RI
);
15039 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
15041 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
15043 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
15044 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
15045 generate_exception_end(ctx
, EXCP_RI
);
15055 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15056 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
15057 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
15060 switch (ctx
->opcode
& 0x1) {
15068 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15069 /* In the Release 6 the register number location in
15070 * the instruction encoding has changed.
15072 gen_arith(ctx
, opc
, rs1
, rd
, rs2
);
15074 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
15080 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15081 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
15082 int amount
= (ctx
->opcode
>> 1) & 0x7;
15084 amount
= amount
== 0 ? 8 : amount
;
15086 switch (ctx
->opcode
& 0x1) {
15095 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
15099 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15100 gen_pool16c_r6_insn(ctx
);
15102 gen_pool16c_insn(ctx
);
15107 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15108 int rb
= 28; /* GP */
15109 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
15111 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15115 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15116 if (ctx
->opcode
& 1) {
15117 generate_exception_end(ctx
, EXCP_RI
);
15120 int enc_dest
= uMIPS_RD(ctx
->opcode
);
15121 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
15122 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
15123 gen_movep(ctx
, enc_dest
, enc_rt
, enc_rs
);
15128 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15129 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15130 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
15131 offset
= (offset
== 0xf ? -1 : offset
);
15133 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
15138 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15139 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15140 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
15142 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
15147 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15148 int rb
= 29; /* SP */
15149 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
15151 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15156 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
15157 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15158 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
15160 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
15165 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15166 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15167 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
15169 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
15174 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15175 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15176 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
15178 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
15183 int rd
= (ctx
->opcode
>> 5) & 0x1f;
15184 int rb
= 29; /* SP */
15185 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
15187 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
15192 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
15193 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
15194 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
15196 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
15201 int rd
= uMIPS_RD5(ctx
->opcode
);
15202 int rs
= uMIPS_RS5(ctx
->opcode
);
15204 gen_arith(ctx
, OPC_ADDU
, rd
, rs
, 0);
15211 switch (ctx
->opcode
& 0x1) {
15221 switch (ctx
->opcode
& 0x1) {
15226 gen_addiur1sp(ctx
);
15230 case B16
: /* BC16 */
15231 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
15232 sextract32(ctx
->opcode
, 0, 10) << 1,
15233 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
15235 case BNEZ16
: /* BNEZC16 */
15236 case BEQZ16
: /* BEQZC16 */
15237 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
15238 mmreg(uMIPS_RD(ctx
->opcode
)),
15239 0, sextract32(ctx
->opcode
, 0, 7) << 1,
15240 (ctx
->insn_flags
& ISA_MIPS32R6
) ? 0 : 4);
15245 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
15246 int imm
= ZIMM(ctx
->opcode
, 0, 7);
15248 imm
= (imm
== 0x7f ? -1 : imm
);
15249 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
15255 generate_exception_end(ctx
, EXCP_RI
);
15258 decode_micromips32_opc(env
, ctx
);
15265 /* SmartMIPS extension to MIPS32 */
15267 #if defined(TARGET_MIPS64)
15269 /* MDMX extension to MIPS64 */
15273 /* MIPSDSP functions. */
15274 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
15275 int rd
, int base
, int offset
)
15280 t0
= tcg_temp_new();
15283 gen_load_gpr(t0
, offset
);
15284 } else if (offset
== 0) {
15285 gen_load_gpr(t0
, base
);
15287 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
15292 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
15293 gen_store_gpr(t0
, rd
);
15296 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
15297 gen_store_gpr(t0
, rd
);
15300 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
15301 gen_store_gpr(t0
, rd
);
15303 #if defined(TARGET_MIPS64)
15305 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
15306 gen_store_gpr(t0
, rd
);
15313 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15314 int ret
, int v1
, int v2
)
15320 /* Treat as NOP. */
15324 v1_t
= tcg_temp_new();
15325 v2_t
= tcg_temp_new();
15327 gen_load_gpr(v1_t
, v1
);
15328 gen_load_gpr(v2_t
, v2
);
15331 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
15332 case OPC_MULT_G_2E
:
15336 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15338 case OPC_ADDUH_R_QB
:
15339 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15342 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15344 case OPC_ADDQH_R_PH
:
15345 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15348 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15350 case OPC_ADDQH_R_W
:
15351 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15354 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15356 case OPC_SUBUH_R_QB
:
15357 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15360 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15362 case OPC_SUBQH_R_PH
:
15363 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15366 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15368 case OPC_SUBQH_R_W
:
15369 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15373 case OPC_ABSQ_S_PH_DSP
:
15375 case OPC_ABSQ_S_QB
:
15377 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
15379 case OPC_ABSQ_S_PH
:
15381 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
15385 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
15387 case OPC_PRECEQ_W_PHL
:
15389 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
15390 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15392 case OPC_PRECEQ_W_PHR
:
15394 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
15395 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
15396 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
15398 case OPC_PRECEQU_PH_QBL
:
15400 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
15402 case OPC_PRECEQU_PH_QBR
:
15404 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
15406 case OPC_PRECEQU_PH_QBLA
:
15408 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
15410 case OPC_PRECEQU_PH_QBRA
:
15412 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
15414 case OPC_PRECEU_PH_QBL
:
15416 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
15418 case OPC_PRECEU_PH_QBR
:
15420 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
15422 case OPC_PRECEU_PH_QBLA
:
15424 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
15426 case OPC_PRECEU_PH_QBRA
:
15428 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
15432 case OPC_ADDU_QB_DSP
:
15436 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15438 case OPC_ADDQ_S_PH
:
15440 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15444 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15448 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15450 case OPC_ADDU_S_QB
:
15452 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15456 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15458 case OPC_ADDU_S_PH
:
15460 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15464 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15466 case OPC_SUBQ_S_PH
:
15468 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15472 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15476 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15478 case OPC_SUBU_S_QB
:
15480 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15484 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15486 case OPC_SUBU_S_PH
:
15488 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15492 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15496 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15500 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
15502 case OPC_RADDU_W_QB
:
15504 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
15508 case OPC_CMPU_EQ_QB_DSP
:
15510 case OPC_PRECR_QB_PH
:
15512 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15514 case OPC_PRECRQ_QB_PH
:
15516 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15518 case OPC_PRECR_SRA_PH_W
:
15521 TCGv_i32 sa_t
= tcg_const_i32(v2
);
15522 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
15524 tcg_temp_free_i32(sa_t
);
15527 case OPC_PRECR_SRA_R_PH_W
:
15530 TCGv_i32 sa_t
= tcg_const_i32(v2
);
15531 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
15533 tcg_temp_free_i32(sa_t
);
15536 case OPC_PRECRQ_PH_W
:
15538 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15540 case OPC_PRECRQ_RS_PH_W
:
15542 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15544 case OPC_PRECRQU_S_QB_PH
:
15546 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15550 #ifdef TARGET_MIPS64
15551 case OPC_ABSQ_S_QH_DSP
:
15553 case OPC_PRECEQ_L_PWL
:
15555 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
15557 case OPC_PRECEQ_L_PWR
:
15559 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
15561 case OPC_PRECEQ_PW_QHL
:
15563 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
15565 case OPC_PRECEQ_PW_QHR
:
15567 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
15569 case OPC_PRECEQ_PW_QHLA
:
15571 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
15573 case OPC_PRECEQ_PW_QHRA
:
15575 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
15577 case OPC_PRECEQU_QH_OBL
:
15579 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
15581 case OPC_PRECEQU_QH_OBR
:
15583 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
15585 case OPC_PRECEQU_QH_OBLA
:
15587 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
15589 case OPC_PRECEQU_QH_OBRA
:
15591 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
15593 case OPC_PRECEU_QH_OBL
:
15595 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
15597 case OPC_PRECEU_QH_OBR
:
15599 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
15601 case OPC_PRECEU_QH_OBLA
:
15603 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
15605 case OPC_PRECEU_QH_OBRA
:
15607 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
15609 case OPC_ABSQ_S_OB
:
15611 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
15613 case OPC_ABSQ_S_PW
:
15615 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
15617 case OPC_ABSQ_S_QH
:
15619 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
15623 case OPC_ADDU_OB_DSP
:
15625 case OPC_RADDU_L_OB
:
15627 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
15631 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15633 case OPC_SUBQ_S_PW
:
15635 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15639 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15641 case OPC_SUBQ_S_QH
:
15643 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15647 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15649 case OPC_SUBU_S_OB
:
15651 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15655 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15657 case OPC_SUBU_S_QH
:
15659 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15663 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15665 case OPC_SUBUH_R_OB
:
15667 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15671 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15673 case OPC_ADDQ_S_PW
:
15675 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15679 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15681 case OPC_ADDQ_S_QH
:
15683 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15687 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15689 case OPC_ADDU_S_OB
:
15691 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15695 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15697 case OPC_ADDU_S_QH
:
15699 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15703 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15705 case OPC_ADDUH_R_OB
:
15707 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15711 case OPC_CMPU_EQ_OB_DSP
:
15713 case OPC_PRECR_OB_QH
:
15715 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
15717 case OPC_PRECR_SRA_QH_PW
:
15720 TCGv_i32 ret_t
= tcg_const_i32(ret
);
15721 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
15722 tcg_temp_free_i32(ret_t
);
15725 case OPC_PRECR_SRA_R_QH_PW
:
15728 TCGv_i32 sa_v
= tcg_const_i32(ret
);
15729 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
15730 tcg_temp_free_i32(sa_v
);
15733 case OPC_PRECRQ_OB_QH
:
15735 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
15737 case OPC_PRECRQ_PW_L
:
15739 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
15741 case OPC_PRECRQ_QH_PW
:
15743 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
15745 case OPC_PRECRQ_RS_QH_PW
:
15747 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15749 case OPC_PRECRQU_S_OB_QH
:
15751 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15758 tcg_temp_free(v1_t
);
15759 tcg_temp_free(v2_t
);
15762 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
15763 int ret
, int v1
, int v2
)
15771 /* Treat as NOP. */
15775 t0
= tcg_temp_new();
15776 v1_t
= tcg_temp_new();
15777 v2_t
= tcg_temp_new();
15779 tcg_gen_movi_tl(t0
, v1
);
15780 gen_load_gpr(v1_t
, v1
);
15781 gen_load_gpr(v2_t
, v2
);
15784 case OPC_SHLL_QB_DSP
:
15786 op2
= MASK_SHLL_QB(ctx
->opcode
);
15790 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
15794 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15798 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
15802 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15804 case OPC_SHLL_S_PH
:
15806 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
15808 case OPC_SHLLV_S_PH
:
15810 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15814 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
15816 case OPC_SHLLV_S_W
:
15818 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15822 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
15826 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15830 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
15834 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15838 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
15840 case OPC_SHRA_R_QB
:
15842 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
15846 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15848 case OPC_SHRAV_R_QB
:
15850 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
15854 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
15856 case OPC_SHRA_R_PH
:
15858 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
15862 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15864 case OPC_SHRAV_R_PH
:
15866 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15870 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
15872 case OPC_SHRAV_R_W
:
15874 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
15876 default: /* Invalid */
15877 MIPS_INVAL("MASK SHLL.QB");
15878 generate_exception_end(ctx
, EXCP_RI
);
15883 #ifdef TARGET_MIPS64
15884 case OPC_SHLL_OB_DSP
:
15885 op2
= MASK_SHLL_OB(ctx
->opcode
);
15889 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
15893 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
15895 case OPC_SHLL_S_PW
:
15897 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
15899 case OPC_SHLLV_S_PW
:
15901 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
15905 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
15909 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
15913 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
15917 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
15919 case OPC_SHLL_S_QH
:
15921 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
15923 case OPC_SHLLV_S_QH
:
15925 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
15929 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
15933 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
15935 case OPC_SHRA_R_OB
:
15937 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
15939 case OPC_SHRAV_R_OB
:
15941 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
15945 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
15949 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
15951 case OPC_SHRA_R_PW
:
15953 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
15955 case OPC_SHRAV_R_PW
:
15957 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
15961 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
15965 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
15967 case OPC_SHRA_R_QH
:
15969 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
15971 case OPC_SHRAV_R_QH
:
15973 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
15977 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
15981 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
15985 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
15989 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
15991 default: /* Invalid */
15992 MIPS_INVAL("MASK SHLL.OB");
15993 generate_exception_end(ctx
, EXCP_RI
);
16001 tcg_temp_free(v1_t
);
16002 tcg_temp_free(v2_t
);
16005 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16006 int ret
, int v1
, int v2
, int check_ret
)
16012 if ((ret
== 0) && (check_ret
== 1)) {
16013 /* Treat as NOP. */
16017 t0
= tcg_temp_new_i32();
16018 v1_t
= tcg_temp_new();
16019 v2_t
= tcg_temp_new();
16021 tcg_gen_movi_i32(t0
, ret
);
16022 gen_load_gpr(v1_t
, v1
);
16023 gen_load_gpr(v2_t
, v2
);
16026 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16027 * the same mask and op1. */
16028 case OPC_MULT_G_2E
:
16032 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16035 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16038 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16040 case OPC_MULQ_RS_W
:
16041 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16045 case OPC_DPA_W_PH_DSP
:
16047 case OPC_DPAU_H_QBL
:
16049 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
16051 case OPC_DPAU_H_QBR
:
16053 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
16055 case OPC_DPSU_H_QBL
:
16057 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
16059 case OPC_DPSU_H_QBR
:
16061 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
16065 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16067 case OPC_DPAX_W_PH
:
16069 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16071 case OPC_DPAQ_S_W_PH
:
16073 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16075 case OPC_DPAQX_S_W_PH
:
16077 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16079 case OPC_DPAQX_SA_W_PH
:
16081 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16085 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16087 case OPC_DPSX_W_PH
:
16089 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16091 case OPC_DPSQ_S_W_PH
:
16093 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16095 case OPC_DPSQX_S_W_PH
:
16097 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16099 case OPC_DPSQX_SA_W_PH
:
16101 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16103 case OPC_MULSAQ_S_W_PH
:
16105 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16107 case OPC_DPAQ_SA_L_W
:
16109 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
16111 case OPC_DPSQ_SA_L_W
:
16113 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
16115 case OPC_MAQ_S_W_PHL
:
16117 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
16119 case OPC_MAQ_S_W_PHR
:
16121 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
16123 case OPC_MAQ_SA_W_PHL
:
16125 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
16127 case OPC_MAQ_SA_W_PHR
:
16129 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
16131 case OPC_MULSA_W_PH
:
16133 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
16137 #ifdef TARGET_MIPS64
16138 case OPC_DPAQ_W_QH_DSP
:
16140 int ac
= ret
& 0x03;
16141 tcg_gen_movi_i32(t0
, ac
);
16146 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
16150 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
16154 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
16158 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
16162 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16164 case OPC_DPAQ_S_W_QH
:
16166 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16168 case OPC_DPAQ_SA_L_PW
:
16170 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16172 case OPC_DPAU_H_OBL
:
16174 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
16176 case OPC_DPAU_H_OBR
:
16178 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
16182 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16184 case OPC_DPSQ_S_W_QH
:
16186 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16188 case OPC_DPSQ_SA_L_PW
:
16190 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16192 case OPC_DPSU_H_OBL
:
16194 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
16196 case OPC_DPSU_H_OBR
:
16198 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
16200 case OPC_MAQ_S_L_PWL
:
16202 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
16204 case OPC_MAQ_S_L_PWR
:
16206 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
16208 case OPC_MAQ_S_W_QHLL
:
16210 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
16212 case OPC_MAQ_SA_W_QHLL
:
16214 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
16216 case OPC_MAQ_S_W_QHLR
:
16218 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
16220 case OPC_MAQ_SA_W_QHLR
:
16222 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
16224 case OPC_MAQ_S_W_QHRL
:
16226 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
16228 case OPC_MAQ_SA_W_QHRL
:
16230 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
16232 case OPC_MAQ_S_W_QHRR
:
16234 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
16236 case OPC_MAQ_SA_W_QHRR
:
16238 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
16240 case OPC_MULSAQ_S_L_PW
:
16242 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
16244 case OPC_MULSAQ_S_W_QH
:
16246 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
16252 case OPC_ADDU_QB_DSP
:
16254 case OPC_MULEU_S_PH_QBL
:
16256 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16258 case OPC_MULEU_S_PH_QBR
:
16260 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16262 case OPC_MULQ_RS_PH
:
16264 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16266 case OPC_MULEQ_S_W_PHL
:
16268 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16270 case OPC_MULEQ_S_W_PHR
:
16272 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16274 case OPC_MULQ_S_PH
:
16276 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16280 #ifdef TARGET_MIPS64
16281 case OPC_ADDU_OB_DSP
:
16283 case OPC_MULEQ_S_PW_QHL
:
16285 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16287 case OPC_MULEQ_S_PW_QHR
:
16289 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16291 case OPC_MULEU_S_QH_OBL
:
16293 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16295 case OPC_MULEU_S_QH_OBR
:
16297 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16299 case OPC_MULQ_RS_QH
:
16301 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16308 tcg_temp_free_i32(t0
);
16309 tcg_temp_free(v1_t
);
16310 tcg_temp_free(v2_t
);
16313 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16321 /* Treat as NOP. */
16325 t0
= tcg_temp_new();
16326 val_t
= tcg_temp_new();
16327 gen_load_gpr(val_t
, val
);
16330 case OPC_ABSQ_S_PH_DSP
:
16334 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
16339 target_long result
;
16340 imm
= (ctx
->opcode
>> 16) & 0xFF;
16341 result
= (uint32_t)imm
<< 24 |
16342 (uint32_t)imm
<< 16 |
16343 (uint32_t)imm
<< 8 |
16345 result
= (int32_t)result
;
16346 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
16351 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
16352 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
16353 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16354 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16355 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16356 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
16361 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16362 imm
= (int16_t)(imm
<< 6) >> 6;
16363 tcg_gen_movi_tl(cpu_gpr
[ret
], \
16364 (target_long
)((int32_t)imm
<< 16 | \
16370 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
16371 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16372 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16373 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
16377 #ifdef TARGET_MIPS64
16378 case OPC_ABSQ_S_QH_DSP
:
16385 imm
= (ctx
->opcode
>> 16) & 0xFF;
16386 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
16387 temp
= (temp
<< 16) | temp
;
16388 temp
= (temp
<< 32) | temp
;
16389 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16397 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16398 imm
= (int16_t)(imm
<< 6) >> 6;
16399 temp
= ((target_long
)imm
<< 32) \
16400 | ((target_long
)imm
& 0xFFFFFFFF);
16401 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16409 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16410 imm
= (int16_t)(imm
<< 6) >> 6;
16412 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
16413 ((uint64_t)(uint16_t)imm
<< 32) |
16414 ((uint64_t)(uint16_t)imm
<< 16) |
16415 (uint64_t)(uint16_t)imm
;
16416 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
16421 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
16422 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
16423 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16424 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16425 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16426 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16427 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16431 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
16432 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16433 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16437 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
16438 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
16439 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16440 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
16441 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
16448 tcg_temp_free(val_t
);
16451 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
16452 uint32_t op1
, uint32_t op2
,
16453 int ret
, int v1
, int v2
, int check_ret
)
16459 if ((ret
== 0) && (check_ret
== 1)) {
16460 /* Treat as NOP. */
16464 t1
= tcg_temp_new();
16465 v1_t
= tcg_temp_new();
16466 v2_t
= tcg_temp_new();
16468 gen_load_gpr(v1_t
, v1
);
16469 gen_load_gpr(v2_t
, v2
);
16472 case OPC_CMPU_EQ_QB_DSP
:
16474 case OPC_CMPU_EQ_QB
:
16476 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
16478 case OPC_CMPU_LT_QB
:
16480 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
16482 case OPC_CMPU_LE_QB
:
16484 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
16486 case OPC_CMPGU_EQ_QB
:
16488 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16490 case OPC_CMPGU_LT_QB
:
16492 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16494 case OPC_CMPGU_LE_QB
:
16496 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
16498 case OPC_CMPGDU_EQ_QB
:
16500 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
16501 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16502 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16503 tcg_gen_shli_tl(t1
, t1
, 24);
16504 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16506 case OPC_CMPGDU_LT_QB
:
16508 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
16509 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16510 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16511 tcg_gen_shli_tl(t1
, t1
, 24);
16512 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16514 case OPC_CMPGDU_LE_QB
:
16516 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
16517 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
16518 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
16519 tcg_gen_shli_tl(t1
, t1
, 24);
16520 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
16522 case OPC_CMP_EQ_PH
:
16524 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
16526 case OPC_CMP_LT_PH
:
16528 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
16530 case OPC_CMP_LE_PH
:
16532 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
16536 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16540 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16542 case OPC_PACKRL_PH
:
16544 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
16548 #ifdef TARGET_MIPS64
16549 case OPC_CMPU_EQ_OB_DSP
:
16551 case OPC_CMP_EQ_PW
:
16553 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
16555 case OPC_CMP_LT_PW
:
16557 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
16559 case OPC_CMP_LE_PW
:
16561 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
16563 case OPC_CMP_EQ_QH
:
16565 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
16567 case OPC_CMP_LT_QH
:
16569 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
16571 case OPC_CMP_LE_QH
:
16573 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
16575 case OPC_CMPGDU_EQ_OB
:
16577 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16579 case OPC_CMPGDU_LT_OB
:
16581 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16583 case OPC_CMPGDU_LE_OB
:
16585 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16587 case OPC_CMPGU_EQ_OB
:
16589 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16591 case OPC_CMPGU_LT_OB
:
16593 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16595 case OPC_CMPGU_LE_OB
:
16597 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
16599 case OPC_CMPU_EQ_OB
:
16601 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
16603 case OPC_CMPU_LT_OB
:
16605 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
16607 case OPC_CMPU_LE_OB
:
16609 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
16611 case OPC_PACKRL_PW
:
16613 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
16617 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16621 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16625 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
16633 tcg_temp_free(v1_t
);
16634 tcg_temp_free(v2_t
);
16637 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
16638 uint32_t op1
, int rt
, int rs
, int sa
)
16645 /* Treat as NOP. */
16649 t0
= tcg_temp_new();
16650 gen_load_gpr(t0
, rs
);
16653 case OPC_APPEND_DSP
:
16654 switch (MASK_APPEND(ctx
->opcode
)) {
16657 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
16659 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16663 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16664 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
16665 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
16666 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16668 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16672 if (sa
!= 0 && sa
!= 2) {
16673 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
16674 tcg_gen_ext32u_tl(t0
, t0
);
16675 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
16676 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16678 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
16680 default: /* Invalid */
16681 MIPS_INVAL("MASK APPEND");
16682 generate_exception_end(ctx
, EXCP_RI
);
16686 #ifdef TARGET_MIPS64
16687 case OPC_DAPPEND_DSP
:
16688 switch (MASK_DAPPEND(ctx
->opcode
)) {
16691 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
16695 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
16696 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
16697 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
16701 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
16702 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
16703 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16708 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
16709 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
16710 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
16711 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
16714 default: /* Invalid */
16715 MIPS_INVAL("MASK DAPPEND");
16716 generate_exception_end(ctx
, EXCP_RI
);
16725 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
16726 int ret
, int v1
, int v2
, int check_ret
)
16735 if ((ret
== 0) && (check_ret
== 1)) {
16736 /* Treat as NOP. */
16740 t0
= tcg_temp_new();
16741 t1
= tcg_temp_new();
16742 v1_t
= tcg_temp_new();
16743 v2_t
= tcg_temp_new();
16745 gen_load_gpr(v1_t
, v1
);
16746 gen_load_gpr(v2_t
, v2
);
16749 case OPC_EXTR_W_DSP
:
16753 tcg_gen_movi_tl(t0
, v2
);
16754 tcg_gen_movi_tl(t1
, v1
);
16755 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16758 tcg_gen_movi_tl(t0
, v2
);
16759 tcg_gen_movi_tl(t1
, v1
);
16760 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16762 case OPC_EXTR_RS_W
:
16763 tcg_gen_movi_tl(t0
, v2
);
16764 tcg_gen_movi_tl(t1
, v1
);
16765 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16768 tcg_gen_movi_tl(t0
, v2
);
16769 tcg_gen_movi_tl(t1
, v1
);
16770 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16772 case OPC_EXTRV_S_H
:
16773 tcg_gen_movi_tl(t0
, v2
);
16774 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16777 tcg_gen_movi_tl(t0
, v2
);
16778 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16780 case OPC_EXTRV_R_W
:
16781 tcg_gen_movi_tl(t0
, v2
);
16782 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16784 case OPC_EXTRV_RS_W
:
16785 tcg_gen_movi_tl(t0
, v2
);
16786 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16789 tcg_gen_movi_tl(t0
, v2
);
16790 tcg_gen_movi_tl(t1
, v1
);
16791 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16794 tcg_gen_movi_tl(t0
, v2
);
16795 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16798 tcg_gen_movi_tl(t0
, v2
);
16799 tcg_gen_movi_tl(t1
, v1
);
16800 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16803 tcg_gen_movi_tl(t0
, v2
);
16804 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16807 imm
= (ctx
->opcode
>> 20) & 0x3F;
16808 tcg_gen_movi_tl(t0
, ret
);
16809 tcg_gen_movi_tl(t1
, imm
);
16810 gen_helper_shilo(t0
, t1
, cpu_env
);
16813 tcg_gen_movi_tl(t0
, ret
);
16814 gen_helper_shilo(t0
, v1_t
, cpu_env
);
16817 tcg_gen_movi_tl(t0
, ret
);
16818 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
16821 imm
= (ctx
->opcode
>> 11) & 0x3FF;
16822 tcg_gen_movi_tl(t0
, imm
);
16823 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
16826 imm
= (ctx
->opcode
>> 16) & 0x03FF;
16827 tcg_gen_movi_tl(t0
, imm
);
16828 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
16832 #ifdef TARGET_MIPS64
16833 case OPC_DEXTR_W_DSP
:
16837 tcg_gen_movi_tl(t0
, ret
);
16838 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
16842 int shift
= (ctx
->opcode
>> 19) & 0x7F;
16843 int ac
= (ctx
->opcode
>> 11) & 0x03;
16844 tcg_gen_movi_tl(t0
, shift
);
16845 tcg_gen_movi_tl(t1
, ac
);
16846 gen_helper_dshilo(t0
, t1
, cpu_env
);
16851 int ac
= (ctx
->opcode
>> 11) & 0x03;
16852 tcg_gen_movi_tl(t0
, ac
);
16853 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
16857 tcg_gen_movi_tl(t0
, v2
);
16858 tcg_gen_movi_tl(t1
, v1
);
16860 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16863 tcg_gen_movi_tl(t0
, v2
);
16864 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16867 tcg_gen_movi_tl(t0
, v2
);
16868 tcg_gen_movi_tl(t1
, v1
);
16869 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16872 tcg_gen_movi_tl(t0
, v2
);
16873 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16876 tcg_gen_movi_tl(t0
, v2
);
16877 tcg_gen_movi_tl(t1
, v1
);
16878 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16880 case OPC_DEXTR_R_L
:
16881 tcg_gen_movi_tl(t0
, v2
);
16882 tcg_gen_movi_tl(t1
, v1
);
16883 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16885 case OPC_DEXTR_RS_L
:
16886 tcg_gen_movi_tl(t0
, v2
);
16887 tcg_gen_movi_tl(t1
, v1
);
16888 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16891 tcg_gen_movi_tl(t0
, v2
);
16892 tcg_gen_movi_tl(t1
, v1
);
16893 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16895 case OPC_DEXTR_R_W
:
16896 tcg_gen_movi_tl(t0
, v2
);
16897 tcg_gen_movi_tl(t1
, v1
);
16898 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16900 case OPC_DEXTR_RS_W
:
16901 tcg_gen_movi_tl(t0
, v2
);
16902 tcg_gen_movi_tl(t1
, v1
);
16903 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16905 case OPC_DEXTR_S_H
:
16906 tcg_gen_movi_tl(t0
, v2
);
16907 tcg_gen_movi_tl(t1
, v1
);
16908 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16910 case OPC_DEXTRV_S_H
:
16911 tcg_gen_movi_tl(t0
, v2
);
16912 tcg_gen_movi_tl(t1
, v1
);
16913 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
16916 tcg_gen_movi_tl(t0
, v2
);
16917 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16919 case OPC_DEXTRV_R_L
:
16920 tcg_gen_movi_tl(t0
, v2
);
16921 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16923 case OPC_DEXTRV_RS_L
:
16924 tcg_gen_movi_tl(t0
, v2
);
16925 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16928 tcg_gen_movi_tl(t0
, v2
);
16929 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16931 case OPC_DEXTRV_R_W
:
16932 tcg_gen_movi_tl(t0
, v2
);
16933 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16935 case OPC_DEXTRV_RS_W
:
16936 tcg_gen_movi_tl(t0
, v2
);
16937 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
16946 tcg_temp_free(v1_t
);
16947 tcg_temp_free(v2_t
);
16950 /* End MIPSDSP functions. */
16952 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
16954 int rs
, rt
, rd
, sa
;
16957 rs
= (ctx
->opcode
>> 21) & 0x1f;
16958 rt
= (ctx
->opcode
>> 16) & 0x1f;
16959 rd
= (ctx
->opcode
>> 11) & 0x1f;
16960 sa
= (ctx
->opcode
>> 6) & 0x1f;
16962 op1
= MASK_SPECIAL(ctx
->opcode
);
16965 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
16967 case OPC_MULT
... OPC_DIVU
:
16968 op2
= MASK_R6_MULDIV(ctx
->opcode
);
16978 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
16981 MIPS_INVAL("special_r6 muldiv");
16982 generate_exception_end(ctx
, EXCP_RI
);
16988 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
16992 if (rt
== 0 && sa
== 1) {
16993 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
16994 We need additionally to check other fields */
16995 gen_cl(ctx
, op1
, rd
, rs
);
16997 generate_exception_end(ctx
, EXCP_RI
);
17001 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
17002 gen_helper_do_semihosting(cpu_env
);
17004 if (ctx
->hflags
& MIPS_HFLAG_SBRI
) {
17005 generate_exception_end(ctx
, EXCP_RI
);
17007 generate_exception_end(ctx
, EXCP_DBp
);
17011 #if defined(TARGET_MIPS64)
17013 check_mips_64(ctx
);
17014 gen_lsa(ctx
, op1
, rd
, rs
, rt
, extract32(ctx
->opcode
, 6, 2));
17018 if (rt
== 0 && sa
== 1) {
17019 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
17020 We need additionally to check other fields */
17021 check_mips_64(ctx
);
17022 gen_cl(ctx
, op1
, rd
, rs
);
17024 generate_exception_end(ctx
, EXCP_RI
);
17027 case OPC_DMULT
... OPC_DDIVU
:
17028 op2
= MASK_R6_MULDIV(ctx
->opcode
);
17038 check_mips_64(ctx
);
17039 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
17042 MIPS_INVAL("special_r6 muldiv");
17043 generate_exception_end(ctx
, EXCP_RI
);
17048 default: /* Invalid */
17049 MIPS_INVAL("special_r6");
17050 generate_exception_end(ctx
, EXCP_RI
);
17055 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17057 int rs
, rt
, rd
, sa
;
17060 rs
= (ctx
->opcode
>> 21) & 0x1f;
17061 rt
= (ctx
->opcode
>> 16) & 0x1f;
17062 rd
= (ctx
->opcode
>> 11) & 0x1f;
17063 sa
= (ctx
->opcode
>> 6) & 0x1f;
17065 op1
= MASK_SPECIAL(ctx
->opcode
);
17067 case OPC_MOVN
: /* Conditional move */
17069 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
17070 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
17071 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
17073 case OPC_MFHI
: /* Move from HI/LO */
17075 gen_HILO(ctx
, op1
, rs
& 3, rd
);
17078 case OPC_MTLO
: /* Move to HI/LO */
17079 gen_HILO(ctx
, op1
, rd
& 3, rs
);
17082 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
17083 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17084 check_cp1_enabled(ctx
);
17085 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
17086 (ctx
->opcode
>> 16) & 1);
17088 generate_exception_err(ctx
, EXCP_CpU
, 1);
17094 check_insn(ctx
, INSN_VR54XX
);
17095 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
17096 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
17098 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
17103 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
17105 #if defined(TARGET_MIPS64)
17106 case OPC_DMULT
... OPC_DDIVU
:
17107 check_insn(ctx
, ISA_MIPS3
);
17108 check_mips_64(ctx
);
17109 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
17113 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
17116 #ifdef MIPS_STRICT_STANDARD
17117 MIPS_INVAL("SPIM");
17118 generate_exception_end(ctx
, EXCP_RI
);
17120 /* Implemented as RI exception for now. */
17121 MIPS_INVAL("spim (unofficial)");
17122 generate_exception_end(ctx
, EXCP_RI
);
17125 default: /* Invalid */
17126 MIPS_INVAL("special_legacy");
17127 generate_exception_end(ctx
, EXCP_RI
);
17132 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
17134 int rs
, rt
, rd
, sa
;
17137 rs
= (ctx
->opcode
>> 21) & 0x1f;
17138 rt
= (ctx
->opcode
>> 16) & 0x1f;
17139 rd
= (ctx
->opcode
>> 11) & 0x1f;
17140 sa
= (ctx
->opcode
>> 6) & 0x1f;
17142 op1
= MASK_SPECIAL(ctx
->opcode
);
17144 case OPC_SLL
: /* Shift with immediate */
17145 if (sa
== 5 && rd
== 0 &&
17146 rs
== 0 && rt
== 0) { /* PAUSE */
17147 if ((ctx
->insn_flags
& ISA_MIPS32R6
) &&
17148 (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
17149 generate_exception_end(ctx
, EXCP_RI
);
17155 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17158 switch ((ctx
->opcode
>> 21) & 0x1f) {
17160 /* rotr is decoded as srl on non-R2 CPUs */
17161 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17166 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17169 generate_exception_end(ctx
, EXCP_RI
);
17173 case OPC_ADD
... OPC_SUBU
:
17174 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17176 case OPC_SLLV
: /* Shifts */
17178 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17181 switch ((ctx
->opcode
>> 6) & 0x1f) {
17183 /* rotrv is decoded as srlv on non-R2 CPUs */
17184 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17189 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17192 generate_exception_end(ctx
, EXCP_RI
);
17196 case OPC_SLT
: /* Set on less than */
17198 gen_slt(ctx
, op1
, rd
, rs
, rt
);
17200 case OPC_AND
: /* Logic*/
17204 gen_logic(ctx
, op1
, rd
, rs
, rt
);
17207 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
17209 case OPC_TGE
... OPC_TEQ
: /* Traps */
17211 check_insn(ctx
, ISA_MIPS2
);
17212 gen_trap(ctx
, op1
, rs
, rt
, -1);
17214 case OPC_LSA
: /* OPC_PMON */
17215 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
17216 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
17217 decode_opc_special_r6(env
, ctx
);
17219 /* Pmon entry point, also R4010 selsl */
17220 #ifdef MIPS_STRICT_STANDARD
17221 MIPS_INVAL("PMON / selsl");
17222 generate_exception_end(ctx
, EXCP_RI
);
17224 gen_helper_0e0i(pmon
, sa
);
17229 generate_exception_end(ctx
, EXCP_SYSCALL
);
17232 generate_exception_end(ctx
, EXCP_BREAK
);
17235 check_insn(ctx
, ISA_MIPS2
);
17236 gen_sync(extract32(ctx
->opcode
, 6, 5));
17239 #if defined(TARGET_MIPS64)
17240 /* MIPS64 specific opcodes */
17245 check_insn(ctx
, ISA_MIPS3
);
17246 check_mips_64(ctx
);
17247 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17250 switch ((ctx
->opcode
>> 21) & 0x1f) {
17252 /* drotr is decoded as dsrl on non-R2 CPUs */
17253 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17258 check_insn(ctx
, ISA_MIPS3
);
17259 check_mips_64(ctx
);
17260 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17263 generate_exception_end(ctx
, EXCP_RI
);
17268 switch ((ctx
->opcode
>> 21) & 0x1f) {
17270 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
17271 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17276 check_insn(ctx
, ISA_MIPS3
);
17277 check_mips_64(ctx
);
17278 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
17281 generate_exception_end(ctx
, EXCP_RI
);
17285 case OPC_DADD
... OPC_DSUBU
:
17286 check_insn(ctx
, ISA_MIPS3
);
17287 check_mips_64(ctx
);
17288 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17292 check_insn(ctx
, ISA_MIPS3
);
17293 check_mips_64(ctx
);
17294 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17297 switch ((ctx
->opcode
>> 6) & 0x1f) {
17299 /* drotrv is decoded as dsrlv on non-R2 CPUs */
17300 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
17305 check_insn(ctx
, ISA_MIPS3
);
17306 check_mips_64(ctx
);
17307 gen_shift(ctx
, op1
, rd
, rs
, rt
);
17310 generate_exception_end(ctx
, EXCP_RI
);
17315 if ((ctx
->insn_flags
& ISA_MIPS32R6
) ||
17316 (env
->CP0_Config3
& (1 << CP0C3_MSAP
))) {
17317 decode_opc_special_r6(env
, ctx
);
17322 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17323 decode_opc_special_r6(env
, ctx
);
17325 decode_opc_special_legacy(env
, ctx
);
17330 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17335 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17337 rs
= (ctx
->opcode
>> 21) & 0x1f;
17338 rt
= (ctx
->opcode
>> 16) & 0x1f;
17339 rd
= (ctx
->opcode
>> 11) & 0x1f;
17341 op1
= MASK_SPECIAL2(ctx
->opcode
);
17343 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
17344 case OPC_MSUB
... OPC_MSUBU
:
17345 check_insn(ctx
, ISA_MIPS32
);
17346 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
17349 gen_arith(ctx
, op1
, rd
, rs
, rt
);
17352 case OPC_DIVU_G_2F
:
17353 case OPC_MULT_G_2F
:
17354 case OPC_MULTU_G_2F
:
17356 case OPC_MODU_G_2F
:
17357 check_insn(ctx
, INSN_LOONGSON2F
);
17358 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17362 check_insn(ctx
, ISA_MIPS32
);
17363 gen_cl(ctx
, op1
, rd
, rs
);
17366 if (is_uhi(extract32(ctx
->opcode
, 6, 20))) {
17367 gen_helper_do_semihosting(cpu_env
);
17369 /* XXX: not clear which exception should be raised
17370 * when in debug mode...
17372 check_insn(ctx
, ISA_MIPS32
);
17373 generate_exception_end(ctx
, EXCP_DBp
);
17376 #if defined(TARGET_MIPS64)
17379 check_insn(ctx
, ISA_MIPS64
);
17380 check_mips_64(ctx
);
17381 gen_cl(ctx
, op1
, rd
, rs
);
17383 case OPC_DMULT_G_2F
:
17384 case OPC_DMULTU_G_2F
:
17385 case OPC_DDIV_G_2F
:
17386 case OPC_DDIVU_G_2F
:
17387 case OPC_DMOD_G_2F
:
17388 case OPC_DMODU_G_2F
:
17389 check_insn(ctx
, INSN_LOONGSON2F
);
17390 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17393 default: /* Invalid */
17394 MIPS_INVAL("special2_legacy");
17395 generate_exception_end(ctx
, EXCP_RI
);
17400 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
17402 int rs
, rt
, rd
, sa
;
17406 rs
= (ctx
->opcode
>> 21) & 0x1f;
17407 rt
= (ctx
->opcode
>> 16) & 0x1f;
17408 rd
= (ctx
->opcode
>> 11) & 0x1f;
17409 sa
= (ctx
->opcode
>> 6) & 0x1f;
17410 imm
= (int16_t)ctx
->opcode
>> 7;
17412 op1
= MASK_SPECIAL3(ctx
->opcode
);
17416 /* hint codes 24-31 are reserved and signal RI */
17417 generate_exception_end(ctx
, EXCP_RI
);
17419 /* Treat as NOP. */
17422 check_cp0_enabled(ctx
);
17423 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
17424 gen_cache_operation(ctx
, rt
, rs
, imm
);
17428 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
17431 gen_ld(ctx
, op1
, rt
, rs
, imm
);
17436 /* Treat as NOP. */
17439 op2
= MASK_BSHFL(ctx
->opcode
);
17441 case OPC_ALIGN
... OPC_ALIGN_END
:
17442 gen_align(ctx
, OPC_ALIGN
, rd
, rs
, rt
, sa
& 3);
17445 gen_bitswap(ctx
, op2
, rd
, rt
);
17450 #if defined(TARGET_MIPS64)
17452 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
17455 gen_ld(ctx
, op1
, rt
, rs
, imm
);
17458 check_mips_64(ctx
);
17461 /* Treat as NOP. */
17464 op2
= MASK_DBSHFL(ctx
->opcode
);
17466 case OPC_DALIGN
... OPC_DALIGN_END
:
17467 gen_align(ctx
, OPC_DALIGN
, rd
, rs
, rt
, sa
& 7);
17470 gen_bitswap(ctx
, op2
, rd
, rt
);
17477 default: /* Invalid */
17478 MIPS_INVAL("special3_r6");
17479 generate_exception_end(ctx
, EXCP_RI
);
17484 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
17489 rs
= (ctx
->opcode
>> 21) & 0x1f;
17490 rt
= (ctx
->opcode
>> 16) & 0x1f;
17491 rd
= (ctx
->opcode
>> 11) & 0x1f;
17493 op1
= MASK_SPECIAL3(ctx
->opcode
);
17495 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
17496 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
17497 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
17498 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
17499 * the same mask and op1. */
17500 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
17501 op2
= MASK_ADDUH_QB(ctx
->opcode
);
17504 case OPC_ADDUH_R_QB
:
17506 case OPC_ADDQH_R_PH
:
17508 case OPC_ADDQH_R_W
:
17510 case OPC_SUBUH_R_QB
:
17512 case OPC_SUBQH_R_PH
:
17514 case OPC_SUBQH_R_W
:
17515 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17520 case OPC_MULQ_RS_W
:
17521 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17524 MIPS_INVAL("MASK ADDUH.QB");
17525 generate_exception_end(ctx
, EXCP_RI
);
17528 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
17529 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17531 generate_exception_end(ctx
, EXCP_RI
);
17535 op2
= MASK_LX(ctx
->opcode
);
17537 #if defined(TARGET_MIPS64)
17543 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
17545 default: /* Invalid */
17546 MIPS_INVAL("MASK LX");
17547 generate_exception_end(ctx
, EXCP_RI
);
17551 case OPC_ABSQ_S_PH_DSP
:
17552 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
17554 case OPC_ABSQ_S_QB
:
17555 case OPC_ABSQ_S_PH
:
17557 case OPC_PRECEQ_W_PHL
:
17558 case OPC_PRECEQ_W_PHR
:
17559 case OPC_PRECEQU_PH_QBL
:
17560 case OPC_PRECEQU_PH_QBR
:
17561 case OPC_PRECEQU_PH_QBLA
:
17562 case OPC_PRECEQU_PH_QBRA
:
17563 case OPC_PRECEU_PH_QBL
:
17564 case OPC_PRECEU_PH_QBR
:
17565 case OPC_PRECEU_PH_QBLA
:
17566 case OPC_PRECEU_PH_QBRA
:
17567 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17574 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
17577 MIPS_INVAL("MASK ABSQ_S.PH");
17578 generate_exception_end(ctx
, EXCP_RI
);
17582 case OPC_ADDU_QB_DSP
:
17583 op2
= MASK_ADDU_QB(ctx
->opcode
);
17586 case OPC_ADDQ_S_PH
:
17589 case OPC_ADDU_S_QB
:
17591 case OPC_ADDU_S_PH
:
17593 case OPC_SUBQ_S_PH
:
17596 case OPC_SUBU_S_QB
:
17598 case OPC_SUBU_S_PH
:
17602 case OPC_RADDU_W_QB
:
17603 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17605 case OPC_MULEU_S_PH_QBL
:
17606 case OPC_MULEU_S_PH_QBR
:
17607 case OPC_MULQ_RS_PH
:
17608 case OPC_MULEQ_S_W_PHL
:
17609 case OPC_MULEQ_S_W_PHR
:
17610 case OPC_MULQ_S_PH
:
17611 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17613 default: /* Invalid */
17614 MIPS_INVAL("MASK ADDU.QB");
17615 generate_exception_end(ctx
, EXCP_RI
);
17620 case OPC_CMPU_EQ_QB_DSP
:
17621 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
17623 case OPC_PRECR_SRA_PH_W
:
17624 case OPC_PRECR_SRA_R_PH_W
:
17625 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
17627 case OPC_PRECR_QB_PH
:
17628 case OPC_PRECRQ_QB_PH
:
17629 case OPC_PRECRQ_PH_W
:
17630 case OPC_PRECRQ_RS_PH_W
:
17631 case OPC_PRECRQU_S_QB_PH
:
17632 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17634 case OPC_CMPU_EQ_QB
:
17635 case OPC_CMPU_LT_QB
:
17636 case OPC_CMPU_LE_QB
:
17637 case OPC_CMP_EQ_PH
:
17638 case OPC_CMP_LT_PH
:
17639 case OPC_CMP_LE_PH
:
17640 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17642 case OPC_CMPGU_EQ_QB
:
17643 case OPC_CMPGU_LT_QB
:
17644 case OPC_CMPGU_LE_QB
:
17645 case OPC_CMPGDU_EQ_QB
:
17646 case OPC_CMPGDU_LT_QB
:
17647 case OPC_CMPGDU_LE_QB
:
17650 case OPC_PACKRL_PH
:
17651 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17653 default: /* Invalid */
17654 MIPS_INVAL("MASK CMPU.EQ.QB");
17655 generate_exception_end(ctx
, EXCP_RI
);
17659 case OPC_SHLL_QB_DSP
:
17660 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
17662 case OPC_DPA_W_PH_DSP
:
17663 op2
= MASK_DPA_W_PH(ctx
->opcode
);
17665 case OPC_DPAU_H_QBL
:
17666 case OPC_DPAU_H_QBR
:
17667 case OPC_DPSU_H_QBL
:
17668 case OPC_DPSU_H_QBR
:
17670 case OPC_DPAX_W_PH
:
17671 case OPC_DPAQ_S_W_PH
:
17672 case OPC_DPAQX_S_W_PH
:
17673 case OPC_DPAQX_SA_W_PH
:
17675 case OPC_DPSX_W_PH
:
17676 case OPC_DPSQ_S_W_PH
:
17677 case OPC_DPSQX_S_W_PH
:
17678 case OPC_DPSQX_SA_W_PH
:
17679 case OPC_MULSAQ_S_W_PH
:
17680 case OPC_DPAQ_SA_L_W
:
17681 case OPC_DPSQ_SA_L_W
:
17682 case OPC_MAQ_S_W_PHL
:
17683 case OPC_MAQ_S_W_PHR
:
17684 case OPC_MAQ_SA_W_PHL
:
17685 case OPC_MAQ_SA_W_PHR
:
17686 case OPC_MULSA_W_PH
:
17687 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17689 default: /* Invalid */
17690 MIPS_INVAL("MASK DPAW.PH");
17691 generate_exception_end(ctx
, EXCP_RI
);
17696 op2
= MASK_INSV(ctx
->opcode
);
17707 t0
= tcg_temp_new();
17708 t1
= tcg_temp_new();
17710 gen_load_gpr(t0
, rt
);
17711 gen_load_gpr(t1
, rs
);
17713 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
17719 default: /* Invalid */
17720 MIPS_INVAL("MASK INSV");
17721 generate_exception_end(ctx
, EXCP_RI
);
17725 case OPC_APPEND_DSP
:
17726 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
17728 case OPC_EXTR_W_DSP
:
17729 op2
= MASK_EXTR_W(ctx
->opcode
);
17733 case OPC_EXTR_RS_W
:
17735 case OPC_EXTRV_S_H
:
17737 case OPC_EXTRV_R_W
:
17738 case OPC_EXTRV_RS_W
:
17743 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
17746 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17752 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17754 default: /* Invalid */
17755 MIPS_INVAL("MASK EXTR.W");
17756 generate_exception_end(ctx
, EXCP_RI
);
17760 #if defined(TARGET_MIPS64)
17761 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
17762 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
17763 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
17764 check_insn(ctx
, INSN_LOONGSON2E
);
17765 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
17767 case OPC_ABSQ_S_QH_DSP
:
17768 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
17770 case OPC_PRECEQ_L_PWL
:
17771 case OPC_PRECEQ_L_PWR
:
17772 case OPC_PRECEQ_PW_QHL
:
17773 case OPC_PRECEQ_PW_QHR
:
17774 case OPC_PRECEQ_PW_QHLA
:
17775 case OPC_PRECEQ_PW_QHRA
:
17776 case OPC_PRECEQU_QH_OBL
:
17777 case OPC_PRECEQU_QH_OBR
:
17778 case OPC_PRECEQU_QH_OBLA
:
17779 case OPC_PRECEQU_QH_OBRA
:
17780 case OPC_PRECEU_QH_OBL
:
17781 case OPC_PRECEU_QH_OBR
:
17782 case OPC_PRECEU_QH_OBLA
:
17783 case OPC_PRECEU_QH_OBRA
:
17784 case OPC_ABSQ_S_OB
:
17785 case OPC_ABSQ_S_PW
:
17786 case OPC_ABSQ_S_QH
:
17787 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17795 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
17797 default: /* Invalid */
17798 MIPS_INVAL("MASK ABSQ_S.QH");
17799 generate_exception_end(ctx
, EXCP_RI
);
17803 case OPC_ADDU_OB_DSP
:
17804 op2
= MASK_ADDU_OB(ctx
->opcode
);
17806 case OPC_RADDU_L_OB
:
17808 case OPC_SUBQ_S_PW
:
17810 case OPC_SUBQ_S_QH
:
17812 case OPC_SUBU_S_OB
:
17814 case OPC_SUBU_S_QH
:
17816 case OPC_SUBUH_R_OB
:
17818 case OPC_ADDQ_S_PW
:
17820 case OPC_ADDQ_S_QH
:
17822 case OPC_ADDU_S_OB
:
17824 case OPC_ADDU_S_QH
:
17826 case OPC_ADDUH_R_OB
:
17827 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17829 case OPC_MULEQ_S_PW_QHL
:
17830 case OPC_MULEQ_S_PW_QHR
:
17831 case OPC_MULEU_S_QH_OBL
:
17832 case OPC_MULEU_S_QH_OBR
:
17833 case OPC_MULQ_RS_QH
:
17834 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17836 default: /* Invalid */
17837 MIPS_INVAL("MASK ADDU.OB");
17838 generate_exception_end(ctx
, EXCP_RI
);
17842 case OPC_CMPU_EQ_OB_DSP
:
17843 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
17845 case OPC_PRECR_SRA_QH_PW
:
17846 case OPC_PRECR_SRA_R_QH_PW
:
17847 /* Return value is rt. */
17848 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
17850 case OPC_PRECR_OB_QH
:
17851 case OPC_PRECRQ_OB_QH
:
17852 case OPC_PRECRQ_PW_L
:
17853 case OPC_PRECRQ_QH_PW
:
17854 case OPC_PRECRQ_RS_QH_PW
:
17855 case OPC_PRECRQU_S_OB_QH
:
17856 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
17858 case OPC_CMPU_EQ_OB
:
17859 case OPC_CMPU_LT_OB
:
17860 case OPC_CMPU_LE_OB
:
17861 case OPC_CMP_EQ_QH
:
17862 case OPC_CMP_LT_QH
:
17863 case OPC_CMP_LE_QH
:
17864 case OPC_CMP_EQ_PW
:
17865 case OPC_CMP_LT_PW
:
17866 case OPC_CMP_LE_PW
:
17867 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17869 case OPC_CMPGDU_EQ_OB
:
17870 case OPC_CMPGDU_LT_OB
:
17871 case OPC_CMPGDU_LE_OB
:
17872 case OPC_CMPGU_EQ_OB
:
17873 case OPC_CMPGU_LT_OB
:
17874 case OPC_CMPGU_LE_OB
:
17875 case OPC_PACKRL_PW
:
17879 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
17881 default: /* Invalid */
17882 MIPS_INVAL("MASK CMPU_EQ.OB");
17883 generate_exception_end(ctx
, EXCP_RI
);
17887 case OPC_DAPPEND_DSP
:
17888 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
17890 case OPC_DEXTR_W_DSP
:
17891 op2
= MASK_DEXTR_W(ctx
->opcode
);
17898 case OPC_DEXTR_R_L
:
17899 case OPC_DEXTR_RS_L
:
17901 case OPC_DEXTR_R_W
:
17902 case OPC_DEXTR_RS_W
:
17903 case OPC_DEXTR_S_H
:
17905 case OPC_DEXTRV_R_L
:
17906 case OPC_DEXTRV_RS_L
:
17907 case OPC_DEXTRV_S_H
:
17909 case OPC_DEXTRV_R_W
:
17910 case OPC_DEXTRV_RS_W
:
17911 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
17916 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17918 default: /* Invalid */
17919 MIPS_INVAL("MASK EXTR.W");
17920 generate_exception_end(ctx
, EXCP_RI
);
17924 case OPC_DPAQ_W_QH_DSP
:
17925 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
17927 case OPC_DPAU_H_OBL
:
17928 case OPC_DPAU_H_OBR
:
17929 case OPC_DPSU_H_OBL
:
17930 case OPC_DPSU_H_OBR
:
17932 case OPC_DPAQ_S_W_QH
:
17934 case OPC_DPSQ_S_W_QH
:
17935 case OPC_MULSAQ_S_W_QH
:
17936 case OPC_DPAQ_SA_L_PW
:
17937 case OPC_DPSQ_SA_L_PW
:
17938 case OPC_MULSAQ_S_L_PW
:
17939 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17941 case OPC_MAQ_S_W_QHLL
:
17942 case OPC_MAQ_S_W_QHLR
:
17943 case OPC_MAQ_S_W_QHRL
:
17944 case OPC_MAQ_S_W_QHRR
:
17945 case OPC_MAQ_SA_W_QHLL
:
17946 case OPC_MAQ_SA_W_QHLR
:
17947 case OPC_MAQ_SA_W_QHRL
:
17948 case OPC_MAQ_SA_W_QHRR
:
17949 case OPC_MAQ_S_L_PWL
:
17950 case OPC_MAQ_S_L_PWR
:
17955 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
17957 default: /* Invalid */
17958 MIPS_INVAL("MASK DPAQ.W.QH");
17959 generate_exception_end(ctx
, EXCP_RI
);
17963 case OPC_DINSV_DSP
:
17964 op2
= MASK_INSV(ctx
->opcode
);
17975 t0
= tcg_temp_new();
17976 t1
= tcg_temp_new();
17978 gen_load_gpr(t0
, rt
);
17979 gen_load_gpr(t1
, rs
);
17981 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
17987 default: /* Invalid */
17988 MIPS_INVAL("MASK DINSV");
17989 generate_exception_end(ctx
, EXCP_RI
);
17993 case OPC_SHLL_OB_DSP
:
17994 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
17997 default: /* Invalid */
17998 MIPS_INVAL("special3_legacy");
17999 generate_exception_end(ctx
, EXCP_RI
);
18004 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
18006 int rs
, rt
, rd
, sa
;
18009 rs
= (ctx
->opcode
>> 21) & 0x1f;
18010 rt
= (ctx
->opcode
>> 16) & 0x1f;
18011 rd
= (ctx
->opcode
>> 11) & 0x1f;
18012 sa
= (ctx
->opcode
>> 6) & 0x1f;
18014 op1
= MASK_SPECIAL3(ctx
->opcode
);
18018 check_insn(ctx
, ISA_MIPS32R2
);
18019 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
18022 op2
= MASK_BSHFL(ctx
->opcode
);
18024 case OPC_ALIGN
... OPC_ALIGN_END
:
18026 check_insn(ctx
, ISA_MIPS32R6
);
18027 decode_opc_special3_r6(env
, ctx
);
18030 check_insn(ctx
, ISA_MIPS32R2
);
18031 gen_bshfl(ctx
, op2
, rt
, rd
);
18035 #if defined(TARGET_MIPS64)
18036 case OPC_DEXTM
... OPC_DEXT
:
18037 case OPC_DINSM
... OPC_DINS
:
18038 check_insn(ctx
, ISA_MIPS64R2
);
18039 check_mips_64(ctx
);
18040 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
18043 op2
= MASK_DBSHFL(ctx
->opcode
);
18045 case OPC_DALIGN
... OPC_DALIGN_END
:
18047 check_insn(ctx
, ISA_MIPS32R6
);
18048 decode_opc_special3_r6(env
, ctx
);
18051 check_insn(ctx
, ISA_MIPS64R2
);
18052 check_mips_64(ctx
);
18053 op2
= MASK_DBSHFL(ctx
->opcode
);
18054 gen_bshfl(ctx
, op2
, rt
, rd
);
18060 gen_rdhwr(ctx
, rt
, rd
, extract32(ctx
->opcode
, 6, 3));
18063 check_insn(ctx
, ASE_MT
);
18065 TCGv t0
= tcg_temp_new();
18066 TCGv t1
= tcg_temp_new();
18068 gen_load_gpr(t0
, rt
);
18069 gen_load_gpr(t1
, rs
);
18070 gen_helper_fork(t0
, t1
);
18076 check_insn(ctx
, ASE_MT
);
18078 TCGv t0
= tcg_temp_new();
18080 gen_load_gpr(t0
, rs
);
18081 gen_helper_yield(t0
, cpu_env
, t0
);
18082 gen_store_gpr(t0
, rd
);
18087 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
18088 decode_opc_special3_r6(env
, ctx
);
18090 decode_opc_special3_legacy(env
, ctx
);
18095 /* MIPS SIMD Architecture (MSA) */
18096 static inline int check_msa_access(DisasContext
*ctx
)
18098 if (unlikely((ctx
->hflags
& MIPS_HFLAG_FPU
) &&
18099 !(ctx
->hflags
& MIPS_HFLAG_F64
))) {
18100 generate_exception_end(ctx
, EXCP_RI
);
18104 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_MSA
))) {
18105 if (ctx
->insn_flags
& ASE_MSA
) {
18106 generate_exception_end(ctx
, EXCP_MSADIS
);
18109 generate_exception_end(ctx
, EXCP_RI
);
18116 static void gen_check_zero_element(TCGv tresult
, uint8_t df
, uint8_t wt
)
18118 /* generates tcg ops to check if any element is 0 */
18119 /* Note this function only works with MSA_WRLEN = 128 */
18120 uint64_t eval_zero_or_big
= 0;
18121 uint64_t eval_big
= 0;
18122 TCGv_i64 t0
= tcg_temp_new_i64();
18123 TCGv_i64 t1
= tcg_temp_new_i64();
18126 eval_zero_or_big
= 0x0101010101010101ULL
;
18127 eval_big
= 0x8080808080808080ULL
;
18130 eval_zero_or_big
= 0x0001000100010001ULL
;
18131 eval_big
= 0x8000800080008000ULL
;
18134 eval_zero_or_big
= 0x0000000100000001ULL
;
18135 eval_big
= 0x8000000080000000ULL
;
18138 eval_zero_or_big
= 0x0000000000000001ULL
;
18139 eval_big
= 0x8000000000000000ULL
;
18142 tcg_gen_subi_i64(t0
, msa_wr_d
[wt
<<1], eval_zero_or_big
);
18143 tcg_gen_andc_i64(t0
, t0
, msa_wr_d
[wt
<<1]);
18144 tcg_gen_andi_i64(t0
, t0
, eval_big
);
18145 tcg_gen_subi_i64(t1
, msa_wr_d
[(wt
<<1)+1], eval_zero_or_big
);
18146 tcg_gen_andc_i64(t1
, t1
, msa_wr_d
[(wt
<<1)+1]);
18147 tcg_gen_andi_i64(t1
, t1
, eval_big
);
18148 tcg_gen_or_i64(t0
, t0
, t1
);
18149 /* if all bits are zero then all elements are not zero */
18150 /* if some bit is non-zero then some element is zero */
18151 tcg_gen_setcondi_i64(TCG_COND_NE
, t0
, t0
, 0);
18152 tcg_gen_trunc_i64_tl(tresult
, t0
);
18153 tcg_temp_free_i64(t0
);
18154 tcg_temp_free_i64(t1
);
18157 static void gen_msa_branch(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t op1
)
18159 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18160 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18161 int64_t s16
= (int16_t)ctx
->opcode
;
18163 check_msa_access(ctx
);
18165 if (ctx
->insn_flags
& ISA_MIPS32R6
&& ctx
->hflags
& MIPS_HFLAG_BMASK
) {
18166 generate_exception_end(ctx
, EXCP_RI
);
18173 TCGv_i64 t0
= tcg_temp_new_i64();
18174 tcg_gen_or_i64(t0
, msa_wr_d
[wt
<<1], msa_wr_d
[(wt
<<1)+1]);
18175 tcg_gen_setcondi_i64((op1
== OPC_BZ_V
) ?
18176 TCG_COND_EQ
: TCG_COND_NE
, t0
, t0
, 0);
18177 tcg_gen_trunc_i64_tl(bcond
, t0
);
18178 tcg_temp_free_i64(t0
);
18185 gen_check_zero_element(bcond
, df
, wt
);
18191 gen_check_zero_element(bcond
, df
, wt
);
18192 tcg_gen_setcondi_tl(TCG_COND_EQ
, bcond
, bcond
, 0);
18196 ctx
->btarget
= ctx
->pc
+ (s16
<< 2) + 4;
18198 ctx
->hflags
|= MIPS_HFLAG_BC
;
18199 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
18202 static void gen_msa_i8(CPUMIPSState
*env
, DisasContext
*ctx
)
18204 #define MASK_MSA_I8(op) (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
18205 uint8_t i8
= (ctx
->opcode
>> 16) & 0xff;
18206 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18207 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18209 TCGv_i32 twd
= tcg_const_i32(wd
);
18210 TCGv_i32 tws
= tcg_const_i32(ws
);
18211 TCGv_i32 ti8
= tcg_const_i32(i8
);
18213 switch (MASK_MSA_I8(ctx
->opcode
)) {
18215 gen_helper_msa_andi_b(cpu_env
, twd
, tws
, ti8
);
18218 gen_helper_msa_ori_b(cpu_env
, twd
, tws
, ti8
);
18221 gen_helper_msa_nori_b(cpu_env
, twd
, tws
, ti8
);
18224 gen_helper_msa_xori_b(cpu_env
, twd
, tws
, ti8
);
18227 gen_helper_msa_bmnzi_b(cpu_env
, twd
, tws
, ti8
);
18230 gen_helper_msa_bmzi_b(cpu_env
, twd
, tws
, ti8
);
18233 gen_helper_msa_bseli_b(cpu_env
, twd
, tws
, ti8
);
18239 uint8_t df
= (ctx
->opcode
>> 24) & 0x3;
18240 if (df
== DF_DOUBLE
) {
18241 generate_exception_end(ctx
, EXCP_RI
);
18243 TCGv_i32 tdf
= tcg_const_i32(df
);
18244 gen_helper_msa_shf_df(cpu_env
, tdf
, twd
, tws
, ti8
);
18245 tcg_temp_free_i32(tdf
);
18250 MIPS_INVAL("MSA instruction");
18251 generate_exception_end(ctx
, EXCP_RI
);
18255 tcg_temp_free_i32(twd
);
18256 tcg_temp_free_i32(tws
);
18257 tcg_temp_free_i32(ti8
);
18260 static void gen_msa_i5(CPUMIPSState
*env
, DisasContext
*ctx
)
18262 #define MASK_MSA_I5(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18263 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18264 int8_t s5
= (int8_t) sextract32(ctx
->opcode
, 16, 5);
18265 uint8_t u5
= (ctx
->opcode
>> 16) & 0x1f;
18266 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18267 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18269 TCGv_i32 tdf
= tcg_const_i32(df
);
18270 TCGv_i32 twd
= tcg_const_i32(wd
);
18271 TCGv_i32 tws
= tcg_const_i32(ws
);
18272 TCGv_i32 timm
= tcg_temp_new_i32();
18273 tcg_gen_movi_i32(timm
, u5
);
18275 switch (MASK_MSA_I5(ctx
->opcode
)) {
18277 gen_helper_msa_addvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18280 gen_helper_msa_subvi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18282 case OPC_MAXI_S_df
:
18283 tcg_gen_movi_i32(timm
, s5
);
18284 gen_helper_msa_maxi_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18286 case OPC_MAXI_U_df
:
18287 gen_helper_msa_maxi_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18289 case OPC_MINI_S_df
:
18290 tcg_gen_movi_i32(timm
, s5
);
18291 gen_helper_msa_mini_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18293 case OPC_MINI_U_df
:
18294 gen_helper_msa_mini_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18297 tcg_gen_movi_i32(timm
, s5
);
18298 gen_helper_msa_ceqi_df(cpu_env
, tdf
, twd
, tws
, timm
);
18300 case OPC_CLTI_S_df
:
18301 tcg_gen_movi_i32(timm
, s5
);
18302 gen_helper_msa_clti_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18304 case OPC_CLTI_U_df
:
18305 gen_helper_msa_clti_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18307 case OPC_CLEI_S_df
:
18308 tcg_gen_movi_i32(timm
, s5
);
18309 gen_helper_msa_clei_s_df(cpu_env
, tdf
, twd
, tws
, timm
);
18311 case OPC_CLEI_U_df
:
18312 gen_helper_msa_clei_u_df(cpu_env
, tdf
, twd
, tws
, timm
);
18316 int32_t s10
= sextract32(ctx
->opcode
, 11, 10);
18317 tcg_gen_movi_i32(timm
, s10
);
18318 gen_helper_msa_ldi_df(cpu_env
, tdf
, twd
, timm
);
18322 MIPS_INVAL("MSA instruction");
18323 generate_exception_end(ctx
, EXCP_RI
);
18327 tcg_temp_free_i32(tdf
);
18328 tcg_temp_free_i32(twd
);
18329 tcg_temp_free_i32(tws
);
18330 tcg_temp_free_i32(timm
);
18333 static void gen_msa_bit(CPUMIPSState
*env
, DisasContext
*ctx
)
18335 #define MASK_MSA_BIT(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18336 uint8_t dfm
= (ctx
->opcode
>> 16) & 0x7f;
18337 uint32_t df
= 0, m
= 0;
18338 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18339 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18346 if ((dfm
& 0x40) == 0x00) {
18349 } else if ((dfm
& 0x60) == 0x40) {
18352 } else if ((dfm
& 0x70) == 0x60) {
18355 } else if ((dfm
& 0x78) == 0x70) {
18359 generate_exception_end(ctx
, EXCP_RI
);
18363 tdf
= tcg_const_i32(df
);
18364 tm
= tcg_const_i32(m
);
18365 twd
= tcg_const_i32(wd
);
18366 tws
= tcg_const_i32(ws
);
18368 switch (MASK_MSA_BIT(ctx
->opcode
)) {
18370 gen_helper_msa_slli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18373 gen_helper_msa_srai_df(cpu_env
, tdf
, twd
, tws
, tm
);
18376 gen_helper_msa_srli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18379 gen_helper_msa_bclri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18382 gen_helper_msa_bseti_df(cpu_env
, tdf
, twd
, tws
, tm
);
18385 gen_helper_msa_bnegi_df(cpu_env
, tdf
, twd
, tws
, tm
);
18387 case OPC_BINSLI_df
:
18388 gen_helper_msa_binsli_df(cpu_env
, tdf
, twd
, tws
, tm
);
18390 case OPC_BINSRI_df
:
18391 gen_helper_msa_binsri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18394 gen_helper_msa_sat_s_df(cpu_env
, tdf
, twd
, tws
, tm
);
18397 gen_helper_msa_sat_u_df(cpu_env
, tdf
, twd
, tws
, tm
);
18400 gen_helper_msa_srari_df(cpu_env
, tdf
, twd
, tws
, tm
);
18403 gen_helper_msa_srlri_df(cpu_env
, tdf
, twd
, tws
, tm
);
18406 MIPS_INVAL("MSA instruction");
18407 generate_exception_end(ctx
, EXCP_RI
);
18411 tcg_temp_free_i32(tdf
);
18412 tcg_temp_free_i32(tm
);
18413 tcg_temp_free_i32(twd
);
18414 tcg_temp_free_i32(tws
);
18417 static void gen_msa_3r(CPUMIPSState
*env
, DisasContext
*ctx
)
18419 #define MASK_MSA_3R(op) (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
18420 uint8_t df
= (ctx
->opcode
>> 21) & 0x3;
18421 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18422 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18423 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18425 TCGv_i32 tdf
= tcg_const_i32(df
);
18426 TCGv_i32 twd
= tcg_const_i32(wd
);
18427 TCGv_i32 tws
= tcg_const_i32(ws
);
18428 TCGv_i32 twt
= tcg_const_i32(wt
);
18430 switch (MASK_MSA_3R(ctx
->opcode
)) {
18432 gen_helper_msa_sll_df(cpu_env
, tdf
, twd
, tws
, twt
);
18435 gen_helper_msa_addv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18438 gen_helper_msa_ceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18441 gen_helper_msa_add_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18443 case OPC_SUBS_S_df
:
18444 gen_helper_msa_subs_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18447 gen_helper_msa_mulv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18450 gen_helper_msa_sld_df(cpu_env
, tdf
, twd
, tws
, twt
);
18453 gen_helper_msa_vshf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18456 gen_helper_msa_sra_df(cpu_env
, tdf
, twd
, tws
, twt
);
18459 gen_helper_msa_subv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18461 case OPC_ADDS_A_df
:
18462 gen_helper_msa_adds_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18464 case OPC_SUBS_U_df
:
18465 gen_helper_msa_subs_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18468 gen_helper_msa_maddv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18471 gen_helper_msa_splat_df(cpu_env
, tdf
, twd
, tws
, twt
);
18474 gen_helper_msa_srar_df(cpu_env
, tdf
, twd
, tws
, twt
);
18477 gen_helper_msa_srl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18480 gen_helper_msa_max_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18483 gen_helper_msa_clt_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18485 case OPC_ADDS_S_df
:
18486 gen_helper_msa_adds_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18488 case OPC_SUBSUS_U_df
:
18489 gen_helper_msa_subsus_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18492 gen_helper_msa_msubv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18495 gen_helper_msa_pckev_df(cpu_env
, tdf
, twd
, tws
, twt
);
18498 gen_helper_msa_srlr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18501 gen_helper_msa_bclr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18504 gen_helper_msa_max_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18507 gen_helper_msa_clt_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18509 case OPC_ADDS_U_df
:
18510 gen_helper_msa_adds_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18512 case OPC_SUBSUU_S_df
:
18513 gen_helper_msa_subsuu_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18516 gen_helper_msa_pckod_df(cpu_env
, tdf
, twd
, tws
, twt
);
18519 gen_helper_msa_bset_df(cpu_env
, tdf
, twd
, tws
, twt
);
18522 gen_helper_msa_min_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18525 gen_helper_msa_cle_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18528 gen_helper_msa_ave_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18530 case OPC_ASUB_S_df
:
18531 gen_helper_msa_asub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18534 gen_helper_msa_div_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18537 gen_helper_msa_ilvl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18540 gen_helper_msa_bneg_df(cpu_env
, tdf
, twd
, tws
, twt
);
18543 gen_helper_msa_min_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18546 gen_helper_msa_cle_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18549 gen_helper_msa_ave_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18551 case OPC_ASUB_U_df
:
18552 gen_helper_msa_asub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18555 gen_helper_msa_div_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18558 gen_helper_msa_ilvr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18561 gen_helper_msa_binsl_df(cpu_env
, tdf
, twd
, tws
, twt
);
18564 gen_helper_msa_max_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18566 case OPC_AVER_S_df
:
18567 gen_helper_msa_aver_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18570 gen_helper_msa_mod_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18573 gen_helper_msa_ilvev_df(cpu_env
, tdf
, twd
, tws
, twt
);
18576 gen_helper_msa_binsr_df(cpu_env
, tdf
, twd
, tws
, twt
);
18579 gen_helper_msa_min_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18581 case OPC_AVER_U_df
:
18582 gen_helper_msa_aver_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18585 gen_helper_msa_mod_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18588 gen_helper_msa_ilvod_df(cpu_env
, tdf
, twd
, tws
, twt
);
18591 case OPC_DOTP_S_df
:
18592 case OPC_DOTP_U_df
:
18593 case OPC_DPADD_S_df
:
18594 case OPC_DPADD_U_df
:
18595 case OPC_DPSUB_S_df
:
18596 case OPC_HADD_S_df
:
18597 case OPC_DPSUB_U_df
:
18598 case OPC_HADD_U_df
:
18599 case OPC_HSUB_S_df
:
18600 case OPC_HSUB_U_df
:
18601 if (df
== DF_BYTE
) {
18602 generate_exception_end(ctx
, EXCP_RI
);
18605 switch (MASK_MSA_3R(ctx
->opcode
)) {
18606 case OPC_DOTP_S_df
:
18607 gen_helper_msa_dotp_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18609 case OPC_DOTP_U_df
:
18610 gen_helper_msa_dotp_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18612 case OPC_DPADD_S_df
:
18613 gen_helper_msa_dpadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18615 case OPC_DPADD_U_df
:
18616 gen_helper_msa_dpadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18618 case OPC_DPSUB_S_df
:
18619 gen_helper_msa_dpsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18621 case OPC_HADD_S_df
:
18622 gen_helper_msa_hadd_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18624 case OPC_DPSUB_U_df
:
18625 gen_helper_msa_dpsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18627 case OPC_HADD_U_df
:
18628 gen_helper_msa_hadd_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18630 case OPC_HSUB_S_df
:
18631 gen_helper_msa_hsub_s_df(cpu_env
, tdf
, twd
, tws
, twt
);
18633 case OPC_HSUB_U_df
:
18634 gen_helper_msa_hsub_u_df(cpu_env
, tdf
, twd
, tws
, twt
);
18639 MIPS_INVAL("MSA instruction");
18640 generate_exception_end(ctx
, EXCP_RI
);
18643 tcg_temp_free_i32(twd
);
18644 tcg_temp_free_i32(tws
);
18645 tcg_temp_free_i32(twt
);
18646 tcg_temp_free_i32(tdf
);
18649 static void gen_msa_elm_3e(CPUMIPSState
*env
, DisasContext
*ctx
)
18651 #define MASK_MSA_ELM_DF3E(op) (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
18652 uint8_t source
= (ctx
->opcode
>> 11) & 0x1f;
18653 uint8_t dest
= (ctx
->opcode
>> 6) & 0x1f;
18654 TCGv telm
= tcg_temp_new();
18655 TCGv_i32 tsr
= tcg_const_i32(source
);
18656 TCGv_i32 tdt
= tcg_const_i32(dest
);
18658 switch (MASK_MSA_ELM_DF3E(ctx
->opcode
)) {
18660 gen_load_gpr(telm
, source
);
18661 gen_helper_msa_ctcmsa(cpu_env
, telm
, tdt
);
18664 gen_helper_msa_cfcmsa(telm
, cpu_env
, tsr
);
18665 gen_store_gpr(telm
, dest
);
18668 gen_helper_msa_move_v(cpu_env
, tdt
, tsr
);
18671 MIPS_INVAL("MSA instruction");
18672 generate_exception_end(ctx
, EXCP_RI
);
18676 tcg_temp_free(telm
);
18677 tcg_temp_free_i32(tdt
);
18678 tcg_temp_free_i32(tsr
);
18681 static void gen_msa_elm_df(CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t df
,
18684 #define MASK_MSA_ELM(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18685 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18686 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18688 TCGv_i32 tws
= tcg_const_i32(ws
);
18689 TCGv_i32 twd
= tcg_const_i32(wd
);
18690 TCGv_i32 tn
= tcg_const_i32(n
);
18691 TCGv_i32 tdf
= tcg_const_i32(df
);
18693 switch (MASK_MSA_ELM(ctx
->opcode
)) {
18695 gen_helper_msa_sldi_df(cpu_env
, tdf
, twd
, tws
, tn
);
18697 case OPC_SPLATI_df
:
18698 gen_helper_msa_splati_df(cpu_env
, tdf
, twd
, tws
, tn
);
18701 gen_helper_msa_insve_df(cpu_env
, tdf
, twd
, tws
, tn
);
18703 case OPC_COPY_S_df
:
18704 case OPC_COPY_U_df
:
18705 case OPC_INSERT_df
:
18706 #if !defined(TARGET_MIPS64)
18707 /* Double format valid only for MIPS64 */
18708 if (df
== DF_DOUBLE
) {
18709 generate_exception_end(ctx
, EXCP_RI
);
18713 switch (MASK_MSA_ELM(ctx
->opcode
)) {
18714 case OPC_COPY_S_df
:
18715 gen_helper_msa_copy_s_df(cpu_env
, tdf
, twd
, tws
, tn
);
18717 case OPC_COPY_U_df
:
18718 gen_helper_msa_copy_u_df(cpu_env
, tdf
, twd
, tws
, tn
);
18720 case OPC_INSERT_df
:
18721 gen_helper_msa_insert_df(cpu_env
, tdf
, twd
, tws
, tn
);
18726 MIPS_INVAL("MSA instruction");
18727 generate_exception_end(ctx
, EXCP_RI
);
18729 tcg_temp_free_i32(twd
);
18730 tcg_temp_free_i32(tws
);
18731 tcg_temp_free_i32(tn
);
18732 tcg_temp_free_i32(tdf
);
18735 static void gen_msa_elm(CPUMIPSState
*env
, DisasContext
*ctx
)
18737 uint8_t dfn
= (ctx
->opcode
>> 16) & 0x3f;
18738 uint32_t df
= 0, n
= 0;
18740 if ((dfn
& 0x30) == 0x00) {
18743 } else if ((dfn
& 0x38) == 0x20) {
18746 } else if ((dfn
& 0x3c) == 0x30) {
18749 } else if ((dfn
& 0x3e) == 0x38) {
18752 } else if (dfn
== 0x3E) {
18753 /* CTCMSA, CFCMSA, MOVE.V */
18754 gen_msa_elm_3e(env
, ctx
);
18757 generate_exception_end(ctx
, EXCP_RI
);
18761 gen_msa_elm_df(env
, ctx
, df
, n
);
18764 static void gen_msa_3rf(CPUMIPSState
*env
, DisasContext
*ctx
)
18766 #define MASK_MSA_3RF(op) (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
18767 uint8_t df
= (ctx
->opcode
>> 21) & 0x1;
18768 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18769 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18770 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18772 TCGv_i32 twd
= tcg_const_i32(wd
);
18773 TCGv_i32 tws
= tcg_const_i32(ws
);
18774 TCGv_i32 twt
= tcg_const_i32(wt
);
18775 TCGv_i32 tdf
= tcg_temp_new_i32();
18777 /* adjust df value for floating-point instruction */
18778 tcg_gen_movi_i32(tdf
, df
+ 2);
18780 switch (MASK_MSA_3RF(ctx
->opcode
)) {
18782 gen_helper_msa_fcaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18785 gen_helper_msa_fadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
18788 gen_helper_msa_fcun_df(cpu_env
, tdf
, twd
, tws
, twt
);
18791 gen_helper_msa_fsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
18794 gen_helper_msa_fcor_df(cpu_env
, tdf
, twd
, tws
, twt
);
18797 gen_helper_msa_fceq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18800 gen_helper_msa_fmul_df(cpu_env
, tdf
, twd
, tws
, twt
);
18803 gen_helper_msa_fcune_df(cpu_env
, tdf
, twd
, tws
, twt
);
18806 gen_helper_msa_fcueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18809 gen_helper_msa_fdiv_df(cpu_env
, tdf
, twd
, tws
, twt
);
18812 gen_helper_msa_fcne_df(cpu_env
, tdf
, twd
, tws
, twt
);
18815 gen_helper_msa_fclt_df(cpu_env
, tdf
, twd
, tws
, twt
);
18818 gen_helper_msa_fmadd_df(cpu_env
, tdf
, twd
, tws
, twt
);
18821 tcg_gen_movi_i32(tdf
, df
+ 1);
18822 gen_helper_msa_mul_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18825 gen_helper_msa_fcult_df(cpu_env
, tdf
, twd
, tws
, twt
);
18828 gen_helper_msa_fmsub_df(cpu_env
, tdf
, twd
, tws
, twt
);
18830 case OPC_MADD_Q_df
:
18831 tcg_gen_movi_i32(tdf
, df
+ 1);
18832 gen_helper_msa_madd_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18835 gen_helper_msa_fcle_df(cpu_env
, tdf
, twd
, tws
, twt
);
18837 case OPC_MSUB_Q_df
:
18838 tcg_gen_movi_i32(tdf
, df
+ 1);
18839 gen_helper_msa_msub_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18842 gen_helper_msa_fcule_df(cpu_env
, tdf
, twd
, tws
, twt
);
18845 gen_helper_msa_fexp2_df(cpu_env
, tdf
, twd
, tws
, twt
);
18848 gen_helper_msa_fsaf_df(cpu_env
, tdf
, twd
, tws
, twt
);
18851 gen_helper_msa_fexdo_df(cpu_env
, tdf
, twd
, tws
, twt
);
18854 gen_helper_msa_fsun_df(cpu_env
, tdf
, twd
, tws
, twt
);
18857 gen_helper_msa_fsor_df(cpu_env
, tdf
, twd
, tws
, twt
);
18860 gen_helper_msa_fseq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18863 gen_helper_msa_ftq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18866 gen_helper_msa_fsune_df(cpu_env
, tdf
, twd
, tws
, twt
);
18869 gen_helper_msa_fsueq_df(cpu_env
, tdf
, twd
, tws
, twt
);
18872 gen_helper_msa_fsne_df(cpu_env
, tdf
, twd
, tws
, twt
);
18875 gen_helper_msa_fslt_df(cpu_env
, tdf
, twd
, tws
, twt
);
18878 gen_helper_msa_fmin_df(cpu_env
, tdf
, twd
, tws
, twt
);
18880 case OPC_MULR_Q_df
:
18881 tcg_gen_movi_i32(tdf
, df
+ 1);
18882 gen_helper_msa_mulr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18885 gen_helper_msa_fsult_df(cpu_env
, tdf
, twd
, tws
, twt
);
18887 case OPC_FMIN_A_df
:
18888 gen_helper_msa_fmin_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18890 case OPC_MADDR_Q_df
:
18891 tcg_gen_movi_i32(tdf
, df
+ 1);
18892 gen_helper_msa_maddr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18895 gen_helper_msa_fsle_df(cpu_env
, tdf
, twd
, tws
, twt
);
18898 gen_helper_msa_fmax_df(cpu_env
, tdf
, twd
, tws
, twt
);
18900 case OPC_MSUBR_Q_df
:
18901 tcg_gen_movi_i32(tdf
, df
+ 1);
18902 gen_helper_msa_msubr_q_df(cpu_env
, tdf
, twd
, tws
, twt
);
18905 gen_helper_msa_fsule_df(cpu_env
, tdf
, twd
, tws
, twt
);
18907 case OPC_FMAX_A_df
:
18908 gen_helper_msa_fmax_a_df(cpu_env
, tdf
, twd
, tws
, twt
);
18911 MIPS_INVAL("MSA instruction");
18912 generate_exception_end(ctx
, EXCP_RI
);
18916 tcg_temp_free_i32(twd
);
18917 tcg_temp_free_i32(tws
);
18918 tcg_temp_free_i32(twt
);
18919 tcg_temp_free_i32(tdf
);
18922 static void gen_msa_2r(CPUMIPSState
*env
, DisasContext
*ctx
)
18924 #define MASK_MSA_2R(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18925 (op & (0x7 << 18)))
18926 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18927 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18928 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18929 uint8_t df
= (ctx
->opcode
>> 16) & 0x3;
18930 TCGv_i32 twd
= tcg_const_i32(wd
);
18931 TCGv_i32 tws
= tcg_const_i32(ws
);
18932 TCGv_i32 twt
= tcg_const_i32(wt
);
18933 TCGv_i32 tdf
= tcg_const_i32(df
);
18935 switch (MASK_MSA_2R(ctx
->opcode
)) {
18937 #if !defined(TARGET_MIPS64)
18938 /* Double format valid only for MIPS64 */
18939 if (df
== DF_DOUBLE
) {
18940 generate_exception_end(ctx
, EXCP_RI
);
18944 gen_helper_msa_fill_df(cpu_env
, tdf
, twd
, tws
); /* trs */
18947 gen_helper_msa_pcnt_df(cpu_env
, tdf
, twd
, tws
);
18950 gen_helper_msa_nloc_df(cpu_env
, tdf
, twd
, tws
);
18953 gen_helper_msa_nlzc_df(cpu_env
, tdf
, twd
, tws
);
18956 MIPS_INVAL("MSA instruction");
18957 generate_exception_end(ctx
, EXCP_RI
);
18961 tcg_temp_free_i32(twd
);
18962 tcg_temp_free_i32(tws
);
18963 tcg_temp_free_i32(twt
);
18964 tcg_temp_free_i32(tdf
);
18967 static void gen_msa_2rf(CPUMIPSState
*env
, DisasContext
*ctx
)
18969 #define MASK_MSA_2RF(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
18970 (op & (0xf << 17)))
18971 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
18972 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
18973 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
18974 uint8_t df
= (ctx
->opcode
>> 16) & 0x1;
18975 TCGv_i32 twd
= tcg_const_i32(wd
);
18976 TCGv_i32 tws
= tcg_const_i32(ws
);
18977 TCGv_i32 twt
= tcg_const_i32(wt
);
18978 /* adjust df value for floating-point instruction */
18979 TCGv_i32 tdf
= tcg_const_i32(df
+ 2);
18981 switch (MASK_MSA_2RF(ctx
->opcode
)) {
18982 case OPC_FCLASS_df
:
18983 gen_helper_msa_fclass_df(cpu_env
, tdf
, twd
, tws
);
18985 case OPC_FTRUNC_S_df
:
18986 gen_helper_msa_ftrunc_s_df(cpu_env
, tdf
, twd
, tws
);
18988 case OPC_FTRUNC_U_df
:
18989 gen_helper_msa_ftrunc_u_df(cpu_env
, tdf
, twd
, tws
);
18992 gen_helper_msa_fsqrt_df(cpu_env
, tdf
, twd
, tws
);
18994 case OPC_FRSQRT_df
:
18995 gen_helper_msa_frsqrt_df(cpu_env
, tdf
, twd
, tws
);
18998 gen_helper_msa_frcp_df(cpu_env
, tdf
, twd
, tws
);
19001 gen_helper_msa_frint_df(cpu_env
, tdf
, twd
, tws
);
19004 gen_helper_msa_flog2_df(cpu_env
, tdf
, twd
, tws
);
19006 case OPC_FEXUPL_df
:
19007 gen_helper_msa_fexupl_df(cpu_env
, tdf
, twd
, tws
);
19009 case OPC_FEXUPR_df
:
19010 gen_helper_msa_fexupr_df(cpu_env
, tdf
, twd
, tws
);
19013 gen_helper_msa_ffql_df(cpu_env
, tdf
, twd
, tws
);
19016 gen_helper_msa_ffqr_df(cpu_env
, tdf
, twd
, tws
);
19018 case OPC_FTINT_S_df
:
19019 gen_helper_msa_ftint_s_df(cpu_env
, tdf
, twd
, tws
);
19021 case OPC_FTINT_U_df
:
19022 gen_helper_msa_ftint_u_df(cpu_env
, tdf
, twd
, tws
);
19024 case OPC_FFINT_S_df
:
19025 gen_helper_msa_ffint_s_df(cpu_env
, tdf
, twd
, tws
);
19027 case OPC_FFINT_U_df
:
19028 gen_helper_msa_ffint_u_df(cpu_env
, tdf
, twd
, tws
);
19032 tcg_temp_free_i32(twd
);
19033 tcg_temp_free_i32(tws
);
19034 tcg_temp_free_i32(twt
);
19035 tcg_temp_free_i32(tdf
);
19038 static void gen_msa_vec_v(CPUMIPSState
*env
, DisasContext
*ctx
)
19040 #define MASK_MSA_VEC(op) (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
19041 uint8_t wt
= (ctx
->opcode
>> 16) & 0x1f;
19042 uint8_t ws
= (ctx
->opcode
>> 11) & 0x1f;
19043 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19044 TCGv_i32 twd
= tcg_const_i32(wd
);
19045 TCGv_i32 tws
= tcg_const_i32(ws
);
19046 TCGv_i32 twt
= tcg_const_i32(wt
);
19048 switch (MASK_MSA_VEC(ctx
->opcode
)) {
19050 gen_helper_msa_and_v(cpu_env
, twd
, tws
, twt
);
19053 gen_helper_msa_or_v(cpu_env
, twd
, tws
, twt
);
19056 gen_helper_msa_nor_v(cpu_env
, twd
, tws
, twt
);
19059 gen_helper_msa_xor_v(cpu_env
, twd
, tws
, twt
);
19062 gen_helper_msa_bmnz_v(cpu_env
, twd
, tws
, twt
);
19065 gen_helper_msa_bmz_v(cpu_env
, twd
, tws
, twt
);
19068 gen_helper_msa_bsel_v(cpu_env
, twd
, tws
, twt
);
19071 MIPS_INVAL("MSA instruction");
19072 generate_exception_end(ctx
, EXCP_RI
);
19076 tcg_temp_free_i32(twd
);
19077 tcg_temp_free_i32(tws
);
19078 tcg_temp_free_i32(twt
);
19081 static void gen_msa_vec(CPUMIPSState
*env
, DisasContext
*ctx
)
19083 switch (MASK_MSA_VEC(ctx
->opcode
)) {
19091 gen_msa_vec_v(env
, ctx
);
19094 gen_msa_2r(env
, ctx
);
19097 gen_msa_2rf(env
, ctx
);
19100 MIPS_INVAL("MSA instruction");
19101 generate_exception_end(ctx
, EXCP_RI
);
19106 static void gen_msa(CPUMIPSState
*env
, DisasContext
*ctx
)
19108 uint32_t opcode
= ctx
->opcode
;
19109 check_insn(ctx
, ASE_MSA
);
19110 check_msa_access(ctx
);
19112 switch (MASK_MSA_MINOR(opcode
)) {
19113 case OPC_MSA_I8_00
:
19114 case OPC_MSA_I8_01
:
19115 case OPC_MSA_I8_02
:
19116 gen_msa_i8(env
, ctx
);
19118 case OPC_MSA_I5_06
:
19119 case OPC_MSA_I5_07
:
19120 gen_msa_i5(env
, ctx
);
19122 case OPC_MSA_BIT_09
:
19123 case OPC_MSA_BIT_0A
:
19124 gen_msa_bit(env
, ctx
);
19126 case OPC_MSA_3R_0D
:
19127 case OPC_MSA_3R_0E
:
19128 case OPC_MSA_3R_0F
:
19129 case OPC_MSA_3R_10
:
19130 case OPC_MSA_3R_11
:
19131 case OPC_MSA_3R_12
:
19132 case OPC_MSA_3R_13
:
19133 case OPC_MSA_3R_14
:
19134 case OPC_MSA_3R_15
:
19135 gen_msa_3r(env
, ctx
);
19138 gen_msa_elm(env
, ctx
);
19140 case OPC_MSA_3RF_1A
:
19141 case OPC_MSA_3RF_1B
:
19142 case OPC_MSA_3RF_1C
:
19143 gen_msa_3rf(env
, ctx
);
19146 gen_msa_vec(env
, ctx
);
19157 int32_t s10
= sextract32(ctx
->opcode
, 16, 10);
19158 uint8_t rs
= (ctx
->opcode
>> 11) & 0x1f;
19159 uint8_t wd
= (ctx
->opcode
>> 6) & 0x1f;
19160 uint8_t df
= (ctx
->opcode
>> 0) & 0x3;
19162 TCGv_i32 twd
= tcg_const_i32(wd
);
19163 TCGv taddr
= tcg_temp_new();
19164 gen_base_offset_addr(ctx
, taddr
, rs
, s10
<< df
);
19166 switch (MASK_MSA_MINOR(opcode
)) {
19168 gen_helper_msa_ld_b(cpu_env
, twd
, taddr
);
19171 gen_helper_msa_ld_h(cpu_env
, twd
, taddr
);
19174 gen_helper_msa_ld_w(cpu_env
, twd
, taddr
);
19177 gen_helper_msa_ld_d(cpu_env
, twd
, taddr
);
19180 gen_helper_msa_st_b(cpu_env
, twd
, taddr
);
19183 gen_helper_msa_st_h(cpu_env
, twd
, taddr
);
19186 gen_helper_msa_st_w(cpu_env
, twd
, taddr
);
19189 gen_helper_msa_st_d(cpu_env
, twd
, taddr
);
19193 tcg_temp_free_i32(twd
);
19194 tcg_temp_free(taddr
);
19198 MIPS_INVAL("MSA instruction");
19199 generate_exception_end(ctx
, EXCP_RI
);
19205 static void decode_opc(CPUMIPSState
*env
, DisasContext
*ctx
)
19208 int rs
, rt
, rd
, sa
;
19212 /* make sure instructions are on a word boundary */
19213 if (ctx
->pc
& 0x3) {
19214 env
->CP0_BadVAddr
= ctx
->pc
;
19215 generate_exception_err(ctx
, EXCP_AdEL
, EXCP_INST_NOTAVAIL
);
19219 /* Handle blikely not taken case */
19220 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
19221 TCGLabel
*l1
= gen_new_label();
19223 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
19224 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
19225 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
19229 op
= MASK_OP_MAJOR(ctx
->opcode
);
19230 rs
= (ctx
->opcode
>> 21) & 0x1f;
19231 rt
= (ctx
->opcode
>> 16) & 0x1f;
19232 rd
= (ctx
->opcode
>> 11) & 0x1f;
19233 sa
= (ctx
->opcode
>> 6) & 0x1f;
19234 imm
= (int16_t)ctx
->opcode
;
19237 decode_opc_special(env
, ctx
);
19240 decode_opc_special2_legacy(env
, ctx
);
19243 decode_opc_special3(env
, ctx
);
19246 op1
= MASK_REGIMM(ctx
->opcode
);
19248 case OPC_BLTZL
: /* REGIMM branches */
19252 check_insn(ctx
, ISA_MIPS2
);
19253 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19257 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
19261 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19263 /* OPC_NAL, OPC_BAL */
19264 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
19266 generate_exception_end(ctx
, EXCP_RI
);
19269 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
19272 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
19274 check_insn(ctx
, ISA_MIPS2
);
19275 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19276 gen_trap(ctx
, op1
, rs
, -1, imm
);
19279 check_insn(ctx
, ISA_MIPS32R6
);
19280 generate_exception_end(ctx
, EXCP_RI
);
19283 check_insn(ctx
, ISA_MIPS32R2
);
19284 /* Break the TB to be able to sync copied instructions
19286 ctx
->bstate
= BS_STOP
;
19288 case OPC_BPOSGE32
: /* MIPS DSP branch */
19289 #if defined(TARGET_MIPS64)
19293 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
19295 #if defined(TARGET_MIPS64)
19297 check_insn(ctx
, ISA_MIPS32R6
);
19298 check_mips_64(ctx
);
19300 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
19304 check_insn(ctx
, ISA_MIPS32R6
);
19305 check_mips_64(ctx
);
19307 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
19311 default: /* Invalid */
19312 MIPS_INVAL("regimm");
19313 generate_exception_end(ctx
, EXCP_RI
);
19318 check_cp0_enabled(ctx
);
19319 op1
= MASK_CP0(ctx
->opcode
);
19327 #if defined(TARGET_MIPS64)
19331 #ifndef CONFIG_USER_ONLY
19332 gen_cp0(env
, ctx
, op1
, rt
, rd
);
19333 #endif /* !CONFIG_USER_ONLY */
19335 case OPC_C0_FIRST
... OPC_C0_LAST
:
19336 #ifndef CONFIG_USER_ONLY
19337 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
19338 #endif /* !CONFIG_USER_ONLY */
19341 #ifndef CONFIG_USER_ONLY
19344 TCGv t0
= tcg_temp_new();
19346 op2
= MASK_MFMC0(ctx
->opcode
);
19349 check_insn(ctx
, ASE_MT
);
19350 gen_helper_dmt(t0
);
19351 gen_store_gpr(t0
, rt
);
19354 check_insn(ctx
, ASE_MT
);
19355 gen_helper_emt(t0
);
19356 gen_store_gpr(t0
, rt
);
19359 check_insn(ctx
, ASE_MT
);
19360 gen_helper_dvpe(t0
, cpu_env
);
19361 gen_store_gpr(t0
, rt
);
19364 check_insn(ctx
, ASE_MT
);
19365 gen_helper_evpe(t0
, cpu_env
);
19366 gen_store_gpr(t0
, rt
);
19369 check_insn(ctx
, ISA_MIPS32R6
);
19371 gen_helper_dvp(t0
, cpu_env
);
19372 gen_store_gpr(t0
, rt
);
19376 check_insn(ctx
, ISA_MIPS32R6
);
19378 gen_helper_evp(t0
, cpu_env
);
19379 gen_store_gpr(t0
, rt
);
19383 check_insn(ctx
, ISA_MIPS32R2
);
19384 save_cpu_state(ctx
, 1);
19385 gen_helper_di(t0
, cpu_env
);
19386 gen_store_gpr(t0
, rt
);
19387 /* Stop translation as we may have switched
19388 the execution mode. */
19389 ctx
->bstate
= BS_STOP
;
19392 check_insn(ctx
, ISA_MIPS32R2
);
19393 save_cpu_state(ctx
, 1);
19394 gen_helper_ei(t0
, cpu_env
);
19395 gen_store_gpr(t0
, rt
);
19396 /* Stop translation as we may have switched
19397 the execution mode. */
19398 ctx
->bstate
= BS_STOP
;
19400 default: /* Invalid */
19401 MIPS_INVAL("mfmc0");
19402 generate_exception_end(ctx
, EXCP_RI
);
19407 #endif /* !CONFIG_USER_ONLY */
19410 check_insn(ctx
, ISA_MIPS32R2
);
19411 gen_load_srsgpr(rt
, rd
);
19414 check_insn(ctx
, ISA_MIPS32R2
);
19415 gen_store_srsgpr(rt
, rd
);
19419 generate_exception_end(ctx
, EXCP_RI
);
19423 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
19424 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19425 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
19426 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19429 /* Arithmetic with immediate opcode */
19430 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19434 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19436 case OPC_SLTI
: /* Set on less than with immediate opcode */
19438 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
19440 case OPC_ANDI
: /* Arithmetic with immediate opcode */
19441 case OPC_LUI
: /* OPC_AUI */
19444 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
19446 case OPC_J
... OPC_JAL
: /* Jump */
19447 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
19448 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
19451 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
19452 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19454 generate_exception_end(ctx
, EXCP_RI
);
19457 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
19458 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19461 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19464 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
19465 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19467 generate_exception_end(ctx
, EXCP_RI
);
19470 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
19471 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19474 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19477 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
19480 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19482 check_insn(ctx
, ISA_MIPS32R6
);
19483 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
19484 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19487 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
19490 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19492 check_insn(ctx
, ISA_MIPS32R6
);
19493 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
19494 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19499 check_insn(ctx
, ISA_MIPS2
);
19500 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19504 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
19506 case OPC_LL
: /* Load and stores */
19507 check_insn(ctx
, ISA_MIPS2
);
19511 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19513 case OPC_LB
... OPC_LH
:
19514 case OPC_LW
... OPC_LHU
:
19515 gen_ld(ctx
, op
, rt
, rs
, imm
);
19519 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19521 case OPC_SB
... OPC_SH
:
19523 gen_st(ctx
, op
, rt
, rs
, imm
);
19526 check_insn(ctx
, ISA_MIPS2
);
19527 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19528 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
19531 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19532 check_cp0_enabled(ctx
);
19533 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
19534 if (ctx
->hflags
& MIPS_HFLAG_ITC_CACHE
) {
19535 gen_cache_operation(ctx
, rt
, rs
, imm
);
19537 /* Treat as NOP. */
19540 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19541 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
19542 /* Treat as NOP. */
19545 /* Floating point (COP1). */
19550 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
19554 op1
= MASK_CP1(ctx
->opcode
);
19559 check_cp1_enabled(ctx
);
19560 check_insn(ctx
, ISA_MIPS32R2
);
19565 check_cp1_enabled(ctx
);
19566 gen_cp1(ctx
, op1
, rt
, rd
);
19568 #if defined(TARGET_MIPS64)
19571 check_cp1_enabled(ctx
);
19572 check_insn(ctx
, ISA_MIPS3
);
19573 check_mips_64(ctx
);
19574 gen_cp1(ctx
, op1
, rt
, rd
);
19577 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
19578 check_cp1_enabled(ctx
);
19579 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19581 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
19586 check_insn(ctx
, ASE_MIPS3D
);
19587 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
19588 (rt
>> 2) & 0x7, imm
<< 2);
19592 check_cp1_enabled(ctx
);
19593 check_insn(ctx
, ISA_MIPS32R6
);
19594 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
19598 check_cp1_enabled(ctx
);
19599 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19601 check_insn(ctx
, ASE_MIPS3D
);
19604 check_cp1_enabled(ctx
);
19605 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19606 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
19607 (rt
>> 2) & 0x7, imm
<< 2);
19614 check_cp1_enabled(ctx
);
19615 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
19621 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
19622 check_cp1_enabled(ctx
);
19623 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19625 case R6_OPC_CMP_AF_S
:
19626 case R6_OPC_CMP_UN_S
:
19627 case R6_OPC_CMP_EQ_S
:
19628 case R6_OPC_CMP_UEQ_S
:
19629 case R6_OPC_CMP_LT_S
:
19630 case R6_OPC_CMP_ULT_S
:
19631 case R6_OPC_CMP_LE_S
:
19632 case R6_OPC_CMP_ULE_S
:
19633 case R6_OPC_CMP_SAF_S
:
19634 case R6_OPC_CMP_SUN_S
:
19635 case R6_OPC_CMP_SEQ_S
:
19636 case R6_OPC_CMP_SEUQ_S
:
19637 case R6_OPC_CMP_SLT_S
:
19638 case R6_OPC_CMP_SULT_S
:
19639 case R6_OPC_CMP_SLE_S
:
19640 case R6_OPC_CMP_SULE_S
:
19641 case R6_OPC_CMP_OR_S
:
19642 case R6_OPC_CMP_UNE_S
:
19643 case R6_OPC_CMP_NE_S
:
19644 case R6_OPC_CMP_SOR_S
:
19645 case R6_OPC_CMP_SUNE_S
:
19646 case R6_OPC_CMP_SNE_S
:
19647 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
19649 case R6_OPC_CMP_AF_D
:
19650 case R6_OPC_CMP_UN_D
:
19651 case R6_OPC_CMP_EQ_D
:
19652 case R6_OPC_CMP_UEQ_D
:
19653 case R6_OPC_CMP_LT_D
:
19654 case R6_OPC_CMP_ULT_D
:
19655 case R6_OPC_CMP_LE_D
:
19656 case R6_OPC_CMP_ULE_D
:
19657 case R6_OPC_CMP_SAF_D
:
19658 case R6_OPC_CMP_SUN_D
:
19659 case R6_OPC_CMP_SEQ_D
:
19660 case R6_OPC_CMP_SEUQ_D
:
19661 case R6_OPC_CMP_SLT_D
:
19662 case R6_OPC_CMP_SULT_D
:
19663 case R6_OPC_CMP_SLE_D
:
19664 case R6_OPC_CMP_SULE_D
:
19665 case R6_OPC_CMP_OR_D
:
19666 case R6_OPC_CMP_UNE_D
:
19667 case R6_OPC_CMP_NE_D
:
19668 case R6_OPC_CMP_SOR_D
:
19669 case R6_OPC_CMP_SUNE_D
:
19670 case R6_OPC_CMP_SNE_D
:
19671 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
19674 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f),
19675 rt
, rd
, sa
, (imm
>> 8) & 0x7);
19680 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
19695 check_insn(ctx
, ASE_MSA
);
19696 gen_msa_branch(env
, ctx
, op1
);
19700 generate_exception_end(ctx
, EXCP_RI
);
19705 /* Compact branches [R6] and COP2 [non-R6] */
19706 case OPC_BC
: /* OPC_LWC2 */
19707 case OPC_BALC
: /* OPC_SWC2 */
19708 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19709 /* OPC_BC, OPC_BALC */
19710 gen_compute_compact_branch(ctx
, op
, 0, 0,
19711 sextract32(ctx
->opcode
<< 2, 0, 28));
19713 /* OPC_LWC2, OPC_SWC2 */
19714 /* COP2: Not implemented. */
19715 generate_exception_err(ctx
, EXCP_CpU
, 2);
19718 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
19719 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
19720 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19722 /* OPC_BEQZC, OPC_BNEZC */
19723 gen_compute_compact_branch(ctx
, op
, rs
, 0,
19724 sextract32(ctx
->opcode
<< 2, 0, 23));
19726 /* OPC_JIC, OPC_JIALC */
19727 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
19730 /* OPC_LWC2, OPC_SWC2 */
19731 /* COP2: Not implemented. */
19732 generate_exception_err(ctx
, EXCP_CpU
, 2);
19736 check_insn(ctx
, INSN_LOONGSON2F
);
19737 /* Note that these instructions use different fields. */
19738 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
19742 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19743 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
19744 check_cp1_enabled(ctx
);
19745 op1
= MASK_CP3(ctx
->opcode
);
19749 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
19755 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
19756 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
19759 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
19760 /* Treat as NOP. */
19763 check_insn(ctx
, ISA_MIPS5
| ISA_MIPS32R2
);
19777 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32R2
);
19778 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
19782 generate_exception_end(ctx
, EXCP_RI
);
19786 generate_exception_err(ctx
, EXCP_CpU
, 1);
19790 #if defined(TARGET_MIPS64)
19791 /* MIPS64 opcodes */
19792 case OPC_LDL
... OPC_LDR
:
19794 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19798 check_insn(ctx
, ISA_MIPS3
);
19799 check_mips_64(ctx
);
19800 gen_ld(ctx
, op
, rt
, rs
, imm
);
19802 case OPC_SDL
... OPC_SDR
:
19803 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19806 check_insn(ctx
, ISA_MIPS3
);
19807 check_mips_64(ctx
);
19808 gen_st(ctx
, op
, rt
, rs
, imm
);
19811 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
19812 check_insn(ctx
, ISA_MIPS3
);
19813 check_mips_64(ctx
);
19814 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
19816 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
19817 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19818 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
19819 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19822 check_insn(ctx
, ISA_MIPS3
);
19823 check_mips_64(ctx
);
19824 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19828 check_insn(ctx
, ISA_MIPS3
);
19829 check_mips_64(ctx
);
19830 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
19833 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
19834 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19835 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
19837 MIPS_INVAL("major opcode");
19838 generate_exception_end(ctx
, EXCP_RI
);
19842 case OPC_DAUI
: /* OPC_JALX */
19843 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
19844 #if defined(TARGET_MIPS64)
19846 check_mips_64(ctx
);
19848 generate_exception(ctx
, EXCP_RI
);
19849 } else if (rt
!= 0) {
19850 TCGv t0
= tcg_temp_new();
19851 gen_load_gpr(t0
, rs
);
19852 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
19856 generate_exception_end(ctx
, EXCP_RI
);
19857 MIPS_INVAL("major opcode");
19861 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
19862 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
19863 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
19866 case OPC_MSA
: /* OPC_MDMX */
19867 /* MDMX: Not implemented. */
19871 check_insn(ctx
, ISA_MIPS32R6
);
19872 gen_pcrel(ctx
, ctx
->opcode
, ctx
->pc
, rs
);
19874 default: /* Invalid */
19875 MIPS_INVAL("major opcode");
19876 generate_exception_end(ctx
, EXCP_RI
);
19881 void gen_intermediate_code(CPUMIPSState
*env
, struct TranslationBlock
*tb
)
19883 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
19884 CPUState
*cs
= CPU(cpu
);
19886 target_ulong pc_start
;
19887 target_ulong next_page_start
;
19894 next_page_start
= (pc_start
& TARGET_PAGE_MASK
) + TARGET_PAGE_SIZE
;
19897 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
19898 ctx
.insn_flags
= env
->insn_flags
;
19899 ctx
.CP0_Config1
= env
->CP0_Config1
;
19901 ctx
.bstate
= BS_NONE
;
19903 ctx
.kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
19904 ctx
.rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
19905 ctx
.ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
19906 ctx
.bi
= (env
->CP0_Config3
>> CP0C3_BI
) & 1;
19907 ctx
.bp
= (env
->CP0_Config3
>> CP0C3_BP
) & 1;
19908 ctx
.PAMask
= env
->PAMask
;
19909 ctx
.mvh
= (env
->CP0_Config5
>> CP0C5_MVH
) & 1;
19910 ctx
.CP0_LLAddr_shift
= env
->CP0_LLAddr_shift
;
19911 ctx
.cmgcr
= (env
->CP0_Config3
>> CP0C3_CMGCR
) & 1;
19912 /* Restore delay slot state from the tb context. */
19913 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
19914 ctx
.ulri
= (env
->CP0_Config3
>> CP0C3_ULRI
) & 1;
19915 ctx
.ps
= ((env
->active_fpu
.fcr0
>> FCR0_PS
) & 1) ||
19916 (env
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
));
19917 ctx
.vp
= (env
->CP0_Config5
>> CP0C5_VP
) & 1;
19918 ctx
.mrp
= (env
->CP0_Config5
>> CP0C5_MRP
) & 1;
19919 ctx
.nan2008
= (env
->active_fpu
.fcr31
>> FCR31_NAN2008
) & 1;
19920 ctx
.abs2008
= (env
->active_fpu
.fcr31
>> FCR31_ABS2008
) & 1;
19921 restore_cpu_state(env
, &ctx
);
19922 #ifdef CONFIG_USER_ONLY
19923 ctx
.mem_idx
= MIPS_HFLAG_UM
;
19925 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
19927 ctx
.default_tcg_memop_mask
= (ctx
.insn_flags
& ISA_MIPS32R6
) ?
19928 MO_UNALN
: MO_ALIGN
;
19930 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
19931 if (max_insns
== 0) {
19932 max_insns
= CF_COUNT_MASK
;
19934 if (max_insns
> TCG_MAX_INSNS
) {
19935 max_insns
= TCG_MAX_INSNS
;
19938 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
19940 while (ctx
.bstate
== BS_NONE
) {
19941 tcg_gen_insn_start(ctx
.pc
, ctx
.hflags
& MIPS_HFLAG_BMASK
, ctx
.btarget
);
19944 if (unlikely(cpu_breakpoint_test(cs
, ctx
.pc
, BP_ANY
))) {
19945 save_cpu_state(&ctx
, 1);
19946 ctx
.bstate
= BS_BRANCH
;
19947 gen_helper_raise_exception_debug(cpu_env
);
19948 /* The address covered by the breakpoint must be included in
19949 [tb->pc, tb->pc + tb->size) in order to for it to be
19950 properly cleared -- thus we increment the PC here so that
19951 the logic setting tb->size below does the right thing. */
19953 goto done_generating
;
19956 if (num_insns
== max_insns
&& (tb
->cflags
& CF_LAST_IO
)) {
19960 is_slot
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
19961 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
19962 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
19964 decode_opc(env
, &ctx
);
19965 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
19966 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
19967 insn_bytes
= decode_micromips_opc(env
, &ctx
);
19968 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
19969 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
19970 insn_bytes
= decode_mips16_opc(env
, &ctx
);
19972 generate_exception_end(&ctx
, EXCP_RI
);
19976 if (ctx
.hflags
& MIPS_HFLAG_BMASK
) {
19977 if (!(ctx
.hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
|
19978 MIPS_HFLAG_FBNSLOT
))) {
19979 /* force to generate branch as there is neither delay nor
19983 if ((ctx
.hflags
& MIPS_HFLAG_M16
) &&
19984 (ctx
.hflags
& MIPS_HFLAG_FBNSLOT
)) {
19985 /* Force to generate branch as microMIPS R6 doesn't restrict
19986 branches in the forbidden slot. */
19991 gen_branch(&ctx
, insn_bytes
);
19993 ctx
.pc
+= insn_bytes
;
19995 /* Execute a branch and its delay slot as a single instruction.
19996 This is what GDB expects and is consistent with what the
19997 hardware does (e.g. if a delay slot instruction faults, the
19998 reported PC is the PC of the branch). */
19999 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
20003 if (ctx
.pc
>= next_page_start
) {
20007 if (tcg_op_buf_full()) {
20011 if (num_insns
>= max_insns
)
20017 if (tb
->cflags
& CF_LAST_IO
) {
20020 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
20021 save_cpu_state(&ctx
, ctx
.bstate
!= BS_EXCP
);
20022 gen_helper_raise_exception_debug(cpu_env
);
20024 switch (ctx
.bstate
) {
20026 gen_goto_tb(&ctx
, 0, ctx
.pc
);
20029 save_cpu_state(&ctx
, 0);
20030 gen_goto_tb(&ctx
, 0, ctx
.pc
);
20033 tcg_gen_exit_tb(0);
20041 gen_tb_end(tb
, num_insns
);
20043 tb
->size
= ctx
.pc
- pc_start
;
20044 tb
->icount
= num_insns
;
20048 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)
20049 && qemu_log_in_addr_range(pc_start
)) {
20051 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
20052 log_target_disas(cs
, pc_start
, ctx
.pc
- pc_start
, 0);
20059 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
20063 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
20065 #define printfpr(fp) \
20068 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20069 " fd:%13g fs:%13g psu: %13g\n", \
20070 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
20071 (double)(fp)->fd, \
20072 (double)(fp)->fs[FP_ENDIAN_IDX], \
20073 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
20076 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
20077 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
20078 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
20079 " fd:%13g fs:%13g psu:%13g\n", \
20080 tmp.w[FP_ENDIAN_IDX], tmp.d, \
20082 (double)tmp.fs[FP_ENDIAN_IDX], \
20083 (double)tmp.fs[!FP_ENDIAN_IDX]); \
20088 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
20089 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
20090 get_float_exception_flags(&env
->active_fpu
.fp_status
));
20091 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
20092 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
20093 printfpr(&env
->active_fpu
.fpr
[i
]);
20099 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
20102 MIPSCPU
*cpu
= MIPS_CPU(cs
);
20103 CPUMIPSState
*env
= &cpu
->env
;
20106 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
20107 " LO=0x" TARGET_FMT_lx
" ds %04x "
20108 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
20109 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
20110 env
->hflags
, env
->btarget
, env
->bcond
);
20111 for (i
= 0; i
< 32; i
++) {
20113 cpu_fprintf(f
, "GPR%02d:", i
);
20114 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
20116 cpu_fprintf(f
, "\n");
20119 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
20120 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
20121 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
20123 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
20124 cpu_fprintf(f
, " Config2 0x%08x Config3 0x%08x\n",
20125 env
->CP0_Config2
, env
->CP0_Config3
);
20126 cpu_fprintf(f
, " Config4 0x%08x Config5 0x%08x\n",
20127 env
->CP0_Config4
, env
->CP0_Config5
);
20128 if (env
->hflags
& MIPS_HFLAG_FPU
)
20129 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
20132 void mips_tcg_init(void)
20137 /* Initialize various static tables. */
20141 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
20142 tcg_ctx
.tcg_env
= cpu_env
;
20144 TCGV_UNUSED(cpu_gpr
[0]);
20145 for (i
= 1; i
< 32; i
++)
20146 cpu_gpr
[i
] = tcg_global_mem_new(cpu_env
,
20147 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
20150 for (i
= 0; i
< 32; i
++) {
20151 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[0]);
20153 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2]);
20154 /* The scalar floating-point unit (FPU) registers are mapped on
20155 * the MSA vector registers. */
20156 fpu_f64
[i
] = msa_wr_d
[i
* 2];
20157 off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
].wr
.d
[1]);
20158 msa_wr_d
[i
* 2 + 1] =
20159 tcg_global_mem_new_i64(cpu_env
, off
, msaregnames
[i
* 2 + 1]);
20162 cpu_PC
= tcg_global_mem_new(cpu_env
,
20163 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
20164 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
20165 cpu_HI
[i
] = tcg_global_mem_new(cpu_env
,
20166 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
20168 cpu_LO
[i
] = tcg_global_mem_new(cpu_env
,
20169 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
20172 cpu_dspctrl
= tcg_global_mem_new(cpu_env
,
20173 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
20175 bcond
= tcg_global_mem_new(cpu_env
,
20176 offsetof(CPUMIPSState
, bcond
), "bcond");
20177 btarget
= tcg_global_mem_new(cpu_env
,
20178 offsetof(CPUMIPSState
, btarget
), "btarget");
20179 hflags
= tcg_global_mem_new_i32(cpu_env
,
20180 offsetof(CPUMIPSState
, hflags
), "hflags");
20182 fpu_fcr0
= tcg_global_mem_new_i32(cpu_env
,
20183 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
20185 fpu_fcr31
= tcg_global_mem_new_i32(cpu_env
,
20186 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
20192 #include "translate_init.c"
20194 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
20198 const mips_def_t
*def
;
20200 def
= cpu_mips_find_by_name(cpu_model
);
20203 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
20205 env
->cpu_model
= def
;
20206 env
->exception_base
= (int32_t)0xBFC00000;
20208 #ifndef CONFIG_USER_ONLY
20209 mmu_init(env
, def
);
20211 fpu_init(env
, def
);
20212 mvp_init(env
, def
);
20214 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
20219 bool cpu_supports_cps_smp(const char *cpu_model
)
20221 const mips_def_t
*def
= cpu_mips_find_by_name(cpu_model
);
20226 return (def
->CP0_Config3
& (1 << CP0C3_CMGCR
)) != 0;
20229 void cpu_set_exception_base(int vp_index
, target_ulong address
)
20231 MIPSCPU
*vp
= MIPS_CPU(qemu_get_cpu(vp_index
));
20232 vp
->env
.exception_base
= address
;
20235 void cpu_state_reset(CPUMIPSState
*env
)
20237 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
20238 CPUState
*cs
= CPU(cpu
);
20240 /* Reset registers to their default values */
20241 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
20242 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
20243 #ifdef TARGET_WORDS_BIGENDIAN
20244 env
->CP0_Config0
|= (1 << CP0C0_BE
);
20246 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
20247 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
20248 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
20249 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
20250 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
20251 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
20252 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
20253 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
20254 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
20255 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
20256 << env
->cpu_model
->CP0_LLAddr_shift
;
20257 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
20258 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
20259 env
->CCRes
= env
->cpu_model
->CCRes
;
20260 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
20261 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
20262 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
20263 env
->current_tc
= 0;
20264 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
20265 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
20266 #if defined(TARGET_MIPS64)
20267 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
20268 env
->SEGMask
|= 3ULL << 62;
20271 env
->PABITS
= env
->cpu_model
->PABITS
;
20272 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
20273 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
20274 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
20275 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
20276 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
20277 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
20278 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
20279 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
20280 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
20281 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
20282 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
20283 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
20284 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
20285 env
->active_fpu
.fcr31_rw_bitmask
= env
->cpu_model
->CP1_fcr31_rw_bitmask
;
20286 env
->active_fpu
.fcr31
= env
->cpu_model
->CP1_fcr31
;
20287 env
->msair
= env
->cpu_model
->MSAIR
;
20288 env
->insn_flags
= env
->cpu_model
->insn_flags
;
20290 #if defined(CONFIG_USER_ONLY)
20291 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
20292 # ifdef TARGET_MIPS64
20293 /* Enable 64-bit register mode. */
20294 env
->CP0_Status
|= (1 << CP0St_PX
);
20296 # ifdef TARGET_ABI_MIPSN64
20297 /* Enable 64-bit address mode. */
20298 env
->CP0_Status
|= (1 << CP0St_UX
);
20300 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
20301 hardware registers. */
20302 env
->CP0_HWREna
|= 0x0000000F;
20303 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
20304 env
->CP0_Status
|= (1 << CP0St_CU1
);
20306 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
20307 env
->CP0_Status
|= (1 << CP0St_MX
);
20309 # if defined(TARGET_MIPS64)
20310 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
20311 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
20312 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
20313 env
->CP0_Status
|= (1 << CP0St_FR
);
20317 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
20318 /* If the exception was raised from a delay slot,
20319 come back to the jump. */
20320 env
->CP0_ErrorEPC
= (env
->active_tc
.PC
20321 - (env
->hflags
& MIPS_HFLAG_B16
? 2 : 4));
20323 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
20325 env
->active_tc
.PC
= env
->exception_base
;
20326 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
20327 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
20328 env
->CP0_Wired
= 0;
20329 env
->CP0_GlobalNumber
= (cs
->cpu_index
& 0xFF) << CP0GN_VPId
;
20330 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
20331 if (kvm_enabled()) {
20332 env
->CP0_EBase
|= 0x40000000;
20334 env
->CP0_EBase
|= 0x80000000;
20336 if (env
->CP0_Config3
& (1 << CP0C3_CMGCR
)) {
20337 env
->CP0_CMGCRBase
= 0x1fbf8000 >> 4;
20339 env
->CP0_EntryHi_ASID_mask
= (env
->CP0_Config4
& (1 << CP0C4_AE
)) ?
20341 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
20342 /* vectored interrupts not implemented, timer on int 7,
20343 no performance counters. */
20344 env
->CP0_IntCtl
= 0xe0000000;
20348 for (i
= 0; i
< 7; i
++) {
20349 env
->CP0_WatchLo
[i
] = 0;
20350 env
->CP0_WatchHi
[i
] = 0x80000000;
20352 env
->CP0_WatchLo
[7] = 0;
20353 env
->CP0_WatchHi
[7] = 0;
20355 /* Count register increments in debug mode, EJTAG version 1 */
20356 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
20358 cpu_mips_store_count(env
, 1);
20360 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
20363 /* Only TC0 on VPE 0 starts as active. */
20364 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
20365 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
20366 env
->tcs
[i
].CP0_TCHalt
= 1;
20368 env
->active_tc
.CP0_TCHalt
= 1;
20371 if (cs
->cpu_index
== 0) {
20372 /* VPE0 starts up enabled. */
20373 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
20374 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
20376 /* TC0 starts up unhalted. */
20378 env
->active_tc
.CP0_TCHalt
= 0;
20379 env
->tcs
[0].CP0_TCHalt
= 0;
20380 /* With thread 0 active. */
20381 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
20382 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
20386 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
20387 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
20388 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
20389 env
->CP0_Status
|= (1 << CP0St_FR
);
20393 if (env
->CP0_Config3
& (1 << CP0C3_MSAP
)) {
20397 compute_hflags(env
);
20398 restore_fp_status(env
);
20399 restore_pamask(env
);
20400 cs
->exception_index
= EXCP_NONE
;
20402 if (semihosting_get_argc()) {
20403 /* UHI interface can be used to obtain argc and argv */
20404 env
->active_tc
.gpr
[4] = -1;
20408 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
,
20409 target_ulong
*data
)
20411 env
->active_tc
.PC
= data
[0];
20412 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
20413 env
->hflags
|= data
[1];
20414 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
20415 case MIPS_HFLAG_BR
:
20417 case MIPS_HFLAG_BC
:
20418 case MIPS_HFLAG_BL
:
20420 env
->btarget
= data
[2];