2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "disas/disas.h"
27 #include "exec/cpu_ldst.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 #include "sysemu/kvm.h"
33 #include "trace-tcg.h"
36 #define MIPS_DEBUG_DISAS 0
37 //#define MIPS_DEBUG_SIGN_EXTENSIONS
39 /* MIPS major opcodes */
40 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
43 /* indirect opcode tables */
44 OPC_SPECIAL
= (0x00 << 26),
45 OPC_REGIMM
= (0x01 << 26),
46 OPC_CP0
= (0x10 << 26),
47 OPC_CP1
= (0x11 << 26),
48 OPC_CP2
= (0x12 << 26),
49 OPC_CP3
= (0x13 << 26),
50 OPC_SPECIAL2
= (0x1C << 26),
51 OPC_SPECIAL3
= (0x1F << 26),
52 /* arithmetic with immediate */
53 OPC_ADDI
= (0x08 << 26),
54 OPC_ADDIU
= (0x09 << 26),
55 OPC_SLTI
= (0x0A << 26),
56 OPC_SLTIU
= (0x0B << 26),
57 /* logic with immediate */
58 OPC_ANDI
= (0x0C << 26),
59 OPC_ORI
= (0x0D << 26),
60 OPC_XORI
= (0x0E << 26),
61 OPC_LUI
= (0x0F << 26),
62 /* arithmetic with immediate */
63 OPC_DADDI
= (0x18 << 26),
64 OPC_DADDIU
= (0x19 << 26),
65 /* Jump and branches */
67 OPC_JAL
= (0x03 << 26),
68 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
69 OPC_BEQL
= (0x14 << 26),
70 OPC_BNE
= (0x05 << 26),
71 OPC_BNEL
= (0x15 << 26),
72 OPC_BLEZ
= (0x06 << 26),
73 OPC_BLEZL
= (0x16 << 26),
74 OPC_BGTZ
= (0x07 << 26),
75 OPC_BGTZL
= (0x17 << 26),
76 OPC_JALX
= (0x1D << 26),
77 OPC_DAUI
= (0x1D << 26),
79 OPC_LDL
= (0x1A << 26),
80 OPC_LDR
= (0x1B << 26),
81 OPC_LB
= (0x20 << 26),
82 OPC_LH
= (0x21 << 26),
83 OPC_LWL
= (0x22 << 26),
84 OPC_LW
= (0x23 << 26),
85 OPC_LWPC
= OPC_LW
| 0x5,
86 OPC_LBU
= (0x24 << 26),
87 OPC_LHU
= (0x25 << 26),
88 OPC_LWR
= (0x26 << 26),
89 OPC_LWU
= (0x27 << 26),
90 OPC_SB
= (0x28 << 26),
91 OPC_SH
= (0x29 << 26),
92 OPC_SWL
= (0x2A << 26),
93 OPC_SW
= (0x2B << 26),
94 OPC_SDL
= (0x2C << 26),
95 OPC_SDR
= (0x2D << 26),
96 OPC_SWR
= (0x2E << 26),
97 OPC_LL
= (0x30 << 26),
98 OPC_LLD
= (0x34 << 26),
99 OPC_LD
= (0x37 << 26),
100 OPC_LDPC
= OPC_LD
| 0x5,
101 OPC_SC
= (0x38 << 26),
102 OPC_SCD
= (0x3C << 26),
103 OPC_SD
= (0x3F << 26),
104 /* Floating point load/store */
105 OPC_LWC1
= (0x31 << 26),
106 OPC_LWC2
= (0x32 << 26),
107 OPC_LDC1
= (0x35 << 26),
108 OPC_LDC2
= (0x36 << 26),
109 OPC_SWC1
= (0x39 << 26),
110 OPC_SWC2
= (0x3A << 26),
111 OPC_SDC1
= (0x3D << 26),
112 OPC_SDC2
= (0x3E << 26),
113 /* Compact Branches */
114 OPC_BLEZALC
= (0x06 << 26),
115 OPC_BGEZALC
= (0x06 << 26),
116 OPC_BGEUC
= (0x06 << 26),
117 OPC_BGTZALC
= (0x07 << 26),
118 OPC_BLTZALC
= (0x07 << 26),
119 OPC_BLTUC
= (0x07 << 26),
120 OPC_BOVC
= (0x08 << 26),
121 OPC_BEQZALC
= (0x08 << 26),
122 OPC_BEQC
= (0x08 << 26),
123 OPC_BLEZC
= (0x16 << 26),
124 OPC_BGEZC
= (0x16 << 26),
125 OPC_BGEC
= (0x16 << 26),
126 OPC_BGTZC
= (0x17 << 26),
127 OPC_BLTZC
= (0x17 << 26),
128 OPC_BLTC
= (0x17 << 26),
129 OPC_BNVC
= (0x18 << 26),
130 OPC_BNEZALC
= (0x18 << 26),
131 OPC_BNEC
= (0x18 << 26),
132 OPC_BC
= (0x32 << 26),
133 OPC_BEQZC
= (0x36 << 26),
134 OPC_JIC
= (0x36 << 26),
135 OPC_BALC
= (0x3A << 26),
136 OPC_BNEZC
= (0x3E << 26),
137 OPC_JIALC
= (0x3E << 26),
138 /* MDMX ASE specific */
139 OPC_MDMX
= (0x1E << 26),
140 /* Cache and prefetch */
141 OPC_CACHE
= (0x2F << 26),
142 OPC_PREF
= (0x33 << 26),
143 /* PC-relative address computation / loads */
144 OPC_PCREL
= (0x3B << 26),
147 /* PC-relative address computation / loads */
148 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
149 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
151 /* Instructions determined by bits 19 and 20 */
152 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
153 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
154 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
156 /* Instructions determined by bits 16 ... 20 */
157 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
158 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
161 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
164 /* MIPS special opcodes */
165 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
169 OPC_SLL
= 0x00 | OPC_SPECIAL
,
170 /* NOP is SLL r0, r0, 0 */
171 /* SSNOP is SLL r0, r0, 1 */
172 /* EHB is SLL r0, r0, 3 */
173 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
174 OPC_ROTR
= OPC_SRL
| (1 << 21),
175 OPC_SRA
= 0x03 | OPC_SPECIAL
,
176 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
177 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
178 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
179 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
180 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
181 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
182 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
183 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
184 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
185 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
186 OPC_DROTR
= OPC_DSRL
| (1 << 21),
187 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
188 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
189 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
190 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
191 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
192 /* Multiplication / division */
193 OPC_MULT
= 0x18 | OPC_SPECIAL
,
194 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
195 OPC_DIV
= 0x1A | OPC_SPECIAL
,
196 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
197 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
198 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
199 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
200 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
202 /* 2 registers arithmetic / logic */
203 OPC_ADD
= 0x20 | OPC_SPECIAL
,
204 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
205 OPC_SUB
= 0x22 | OPC_SPECIAL
,
206 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
207 OPC_AND
= 0x24 | OPC_SPECIAL
,
208 OPC_OR
= 0x25 | OPC_SPECIAL
,
209 OPC_XOR
= 0x26 | OPC_SPECIAL
,
210 OPC_NOR
= 0x27 | OPC_SPECIAL
,
211 OPC_SLT
= 0x2A | OPC_SPECIAL
,
212 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
213 OPC_DADD
= 0x2C | OPC_SPECIAL
,
214 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
215 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
216 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
218 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
219 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
221 OPC_TGE
= 0x30 | OPC_SPECIAL
,
222 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
223 OPC_TLT
= 0x32 | OPC_SPECIAL
,
224 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
225 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
226 OPC_TNE
= 0x36 | OPC_SPECIAL
,
227 /* HI / LO registers load & stores */
228 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
229 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
230 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
231 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
232 /* Conditional moves */
233 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
234 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
236 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
237 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
239 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
242 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
243 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
244 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
245 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
246 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
248 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
249 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
250 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
251 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
254 /* R6 Multiply and Divide instructions have the same Opcode
255 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
256 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
259 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
260 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
261 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
262 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
263 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
264 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
265 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
266 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
268 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
269 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
270 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
271 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
272 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
273 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
274 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
275 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
277 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
278 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
279 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
280 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
281 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
283 OPC_LSA
= 0x05 | OPC_SPECIAL
,
284 OPC_DLSA
= 0x15 | OPC_SPECIAL
,
287 /* Multiplication variants of the vr54xx. */
288 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
291 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
292 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
293 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
294 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
295 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
296 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
297 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
298 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
299 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
300 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
301 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
302 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
303 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
304 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
307 /* REGIMM (rt field) opcodes */
308 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
311 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
312 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
313 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
314 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
315 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
316 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
317 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
318 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
319 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
320 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
321 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
322 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
323 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
324 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
325 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
327 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
328 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
331 /* Special2 opcodes */
332 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
335 /* Multiply & xxx operations */
336 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
337 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
338 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
339 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
340 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
342 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
343 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
344 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
345 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
346 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
347 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
348 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
349 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
350 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
351 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
352 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
353 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
355 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
356 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
357 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
358 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
360 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
363 /* Special3 opcodes */
364 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
367 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
368 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
369 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
370 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
371 OPC_INS
= 0x04 | OPC_SPECIAL3
,
372 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
373 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
374 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
375 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
376 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
377 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
378 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
379 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
382 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
383 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
384 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
385 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
386 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
387 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
388 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
389 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
390 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
391 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
392 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
393 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
396 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
397 /* MIPS DSP Arithmetic */
398 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
399 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
400 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
401 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
402 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
403 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
404 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
405 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
406 /* MIPS DSP GPR-Based Shift Sub-class */
407 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
408 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
409 /* MIPS DSP Multiply Sub-class insns */
410 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
411 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
412 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
413 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
414 /* DSP Bit/Manipulation Sub-class */
415 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
416 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
417 /* MIPS DSP Append Sub-class */
418 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
419 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
420 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
421 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
422 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
425 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
426 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
427 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
428 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
429 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
430 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
434 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
437 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
438 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
439 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
440 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp */
441 OPC_ALIGN_END
= (0x0B << 6) | OPC_BSHFL
, /* 010.00 to 010.11 */
442 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
446 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
449 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
450 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
451 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp */
452 OPC_DALIGN_END
= (0x0F << 6) | OPC_DBSHFL
, /* 01.000 to 01.111 */
453 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
456 /* MIPS DSP REGIMM opcodes */
458 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
459 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
462 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
465 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
466 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
467 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
468 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
471 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
473 /* MIPS DSP Arithmetic Sub-class */
474 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
475 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
476 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
477 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
478 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
479 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
480 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
481 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
482 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
483 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
484 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
485 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
486 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
487 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
488 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
489 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
490 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
491 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
492 /* MIPS DSP Multiply Sub-class insns */
493 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
494 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
495 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
496 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
497 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
498 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
501 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
502 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
504 /* MIPS DSP Arithmetic Sub-class */
505 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
506 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
507 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
508 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
509 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
510 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
511 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
512 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
513 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
514 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
515 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
516 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
517 /* MIPS DSP Multiply Sub-class insns */
518 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
519 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
520 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
521 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
524 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
526 /* MIPS DSP Arithmetic Sub-class */
527 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
528 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
529 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
530 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
531 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
532 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
533 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
534 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
535 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
536 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
537 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
538 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
539 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
542 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
543 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
544 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
545 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
548 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
550 /* MIPS DSP Arithmetic Sub-class */
551 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
552 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
553 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
554 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
555 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
556 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
557 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
558 /* DSP Compare-Pick Sub-class */
559 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
560 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
561 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
562 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
563 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
564 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
565 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
566 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
567 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
568 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
569 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
570 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
571 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
572 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
573 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
576 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
578 /* MIPS DSP GPR-Based Shift Sub-class */
579 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
580 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
581 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
582 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
583 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
584 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
585 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
586 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
587 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
588 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
589 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
590 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
591 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
592 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
593 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
594 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
595 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
596 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
597 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
598 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
599 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
600 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
603 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
607 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
608 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
609 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
610 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
611 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
612 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
613 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
614 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
615 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
616 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
617 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
618 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
619 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
620 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
621 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
622 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
623 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
624 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
625 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
626 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
627 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
630 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
632 /* DSP Bit/Manipulation Sub-class */
633 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
636 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
638 /* MIPS DSP Append Sub-class */
639 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
640 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
641 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
644 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
646 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
647 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
648 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
649 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
650 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
651 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
652 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
653 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
654 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
655 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
656 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
657 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
658 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
659 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
660 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
661 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
662 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
663 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
666 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
668 /* MIPS DSP Arithmetic Sub-class */
669 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
670 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
671 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
672 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
673 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
674 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
675 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
676 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
677 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
678 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
679 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
680 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
681 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
682 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
683 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
684 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
685 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
686 /* DSP Bit/Manipulation Sub-class */
687 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
688 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
689 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
690 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
691 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
692 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
695 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
697 /* MIPS DSP Multiply Sub-class insns */
698 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
699 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
700 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
701 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
702 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
703 /* MIPS DSP Arithmetic Sub-class */
704 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
705 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
706 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
707 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
708 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
709 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
710 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
711 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
712 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
713 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
714 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
715 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
716 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
717 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
718 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
719 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
720 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
721 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
722 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
723 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
724 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
727 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
729 /* DSP Compare-Pick Sub-class */
730 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
731 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
732 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
733 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
734 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
735 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
736 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
737 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
738 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
739 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
740 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
741 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
742 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
743 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
744 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
745 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
746 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
747 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
748 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
749 /* MIPS DSP Arithmetic Sub-class */
750 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
751 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
752 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
753 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
754 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
755 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
756 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
757 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
760 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
762 /* DSP Append Sub-class */
763 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
764 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
765 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
766 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
769 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
771 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
772 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
773 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
774 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
775 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
776 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
777 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
778 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
779 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
780 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
781 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
782 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
783 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
784 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
785 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
786 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
787 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
788 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
789 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
790 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
791 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
792 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
795 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
797 /* DSP Bit/Manipulation Sub-class */
798 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
801 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
803 /* MIPS DSP Multiply Sub-class insns */
804 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
805 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
806 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
807 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
808 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
809 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
810 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
811 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
812 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
813 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
814 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
815 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
816 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
817 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
818 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
819 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
820 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
821 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
822 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
823 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
824 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
825 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
826 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
827 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
828 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
829 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
832 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
834 /* MIPS DSP GPR-Based Shift Sub-class */
835 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
836 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
837 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
838 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
839 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
840 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
841 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
842 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
843 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
844 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
845 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
846 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
847 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
848 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
849 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
850 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
851 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
852 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
853 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
854 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
855 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
856 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
857 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
858 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
859 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
860 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
863 /* Coprocessor 0 (rs field) */
864 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
867 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
868 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
869 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
870 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
871 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
872 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
873 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
874 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
875 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
876 OPC_C0
= (0x10 << 21) | OPC_CP0
,
877 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
878 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
882 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
885 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
886 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
887 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
888 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
889 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
890 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
893 /* Coprocessor 0 (with rs == C0) */
894 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
897 OPC_TLBR
= 0x01 | OPC_C0
,
898 OPC_TLBWI
= 0x02 | OPC_C0
,
899 OPC_TLBWR
= 0x06 | OPC_C0
,
900 OPC_TLBP
= 0x08 | OPC_C0
,
901 OPC_RFE
= 0x10 | OPC_C0
,
902 OPC_ERET
= 0x18 | OPC_C0
,
903 OPC_DERET
= 0x1F | OPC_C0
,
904 OPC_WAIT
= 0x20 | OPC_C0
,
907 /* Coprocessor 1 (rs field) */
908 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
910 /* Values for the fmt field in FP instructions */
912 /* 0 - 15 are reserved */
913 FMT_S
= 16, /* single fp */
914 FMT_D
= 17, /* double fp */
915 FMT_E
= 18, /* extended fp */
916 FMT_Q
= 19, /* quad fp */
917 FMT_W
= 20, /* 32-bit fixed */
918 FMT_L
= 21, /* 64-bit fixed */
919 FMT_PS
= 22, /* paired single fp */
920 /* 23 - 31 are reserved */
924 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
925 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
926 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
927 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
928 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
929 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
930 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
931 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
932 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
933 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
934 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
935 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
936 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
937 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
938 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
939 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
940 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
941 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
942 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
943 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
946 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
947 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
950 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
951 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
952 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
953 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
957 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
958 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
962 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
963 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
966 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
969 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
970 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
971 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
972 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
973 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
974 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
975 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
976 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
977 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
978 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
979 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
982 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
985 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
986 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
987 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
988 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
989 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
990 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
991 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
992 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
994 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
995 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
996 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
997 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
998 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
999 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1000 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1001 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1003 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1004 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1005 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1006 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1007 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1008 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1009 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1010 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1012 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1013 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1014 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1015 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1016 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1017 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1018 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1019 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1021 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1022 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1023 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1024 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1025 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1026 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1028 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1029 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1030 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1031 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1032 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1033 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1035 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1036 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1037 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1038 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1039 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1040 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1042 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1043 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1044 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1045 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1046 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1047 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1049 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1050 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1051 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1052 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1053 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1054 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1056 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1057 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1058 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1059 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1060 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1061 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1063 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1064 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1065 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1066 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1067 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1068 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1070 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1071 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1072 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1073 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1074 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1075 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1079 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1082 OPC_LWXC1
= 0x00 | OPC_CP3
,
1083 OPC_LDXC1
= 0x01 | OPC_CP3
,
1084 OPC_LUXC1
= 0x05 | OPC_CP3
,
1085 OPC_SWXC1
= 0x08 | OPC_CP3
,
1086 OPC_SDXC1
= 0x09 | OPC_CP3
,
1087 OPC_SUXC1
= 0x0D | OPC_CP3
,
1088 OPC_PREFX
= 0x0F | OPC_CP3
,
1089 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1090 OPC_MADD_S
= 0x20 | OPC_CP3
,
1091 OPC_MADD_D
= 0x21 | OPC_CP3
,
1092 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1093 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1094 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1095 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1096 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1097 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1098 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1099 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1100 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1101 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1104 /* global register indices */
1105 static TCGv_ptr cpu_env
;
1106 static TCGv cpu_gpr
[32], cpu_PC
;
1107 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1108 static TCGv cpu_dspctrl
, btarget
, bcond
;
1109 static TCGv_i32 hflags
;
1110 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1111 static TCGv_i64 fpu_f64
[32];
1113 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1114 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1116 #include "exec/gen-icount.h"
1118 #define gen_helper_0e0i(name, arg) do { \
1119 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1120 gen_helper_##name(cpu_env, helper_tmp); \
1121 tcg_temp_free_i32(helper_tmp); \
1124 #define gen_helper_0e1i(name, arg1, arg2) do { \
1125 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1126 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1127 tcg_temp_free_i32(helper_tmp); \
1130 #define gen_helper_1e0i(name, ret, arg1) do { \
1131 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1132 gen_helper_##name(ret, cpu_env, helper_tmp); \
1133 tcg_temp_free_i32(helper_tmp); \
1136 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1137 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1138 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1139 tcg_temp_free_i32(helper_tmp); \
1142 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1143 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1144 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1145 tcg_temp_free_i32(helper_tmp); \
1148 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1149 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1150 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1151 tcg_temp_free_i32(helper_tmp); \
1154 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1155 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1156 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1157 tcg_temp_free_i32(helper_tmp); \
1160 typedef struct DisasContext
{
1161 struct TranslationBlock
*tb
;
1162 target_ulong pc
, saved_pc
;
1164 int singlestep_enabled
;
1166 int32_t CP0_Config1
;
1167 /* Routine used to access memory */
1169 uint32_t hflags
, saved_hflags
;
1171 target_ulong btarget
;
1176 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1177 * exception condition */
1178 BS_STOP
= 1, /* We want to stop translation for any reason */
1179 BS_BRANCH
= 2, /* We reached a branch condition */
1180 BS_EXCP
= 3, /* We reached an exception condition */
1183 static const char * const regnames
[] = {
1184 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1185 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1186 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1187 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1190 static const char * const regnames_HI
[] = {
1191 "HI0", "HI1", "HI2", "HI3",
1194 static const char * const regnames_LO
[] = {
1195 "LO0", "LO1", "LO2", "LO3",
1198 static const char * const fregnames
[] = {
1199 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1200 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1201 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1202 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1205 #define MIPS_DEBUG(fmt, ...) \
1207 if (MIPS_DEBUG_DISAS) { \
1208 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1209 TARGET_FMT_lx ": %08x " fmt "\n", \
1210 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1214 #define LOG_DISAS(...) \
1216 if (MIPS_DEBUG_DISAS) { \
1217 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1221 #define MIPS_INVAL(op) \
1222 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1223 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1225 /* General purpose registers moves. */
1226 static inline void gen_load_gpr (TCGv t
, int reg
)
1229 tcg_gen_movi_tl(t
, 0);
1231 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1234 static inline void gen_store_gpr (TCGv t
, int reg
)
1237 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1240 /* Moves to/from shadow registers. */
1241 static inline void gen_load_srsgpr (int from
, int to
)
1243 TCGv t0
= tcg_temp_new();
1246 tcg_gen_movi_tl(t0
, 0);
1248 TCGv_i32 t2
= tcg_temp_new_i32();
1249 TCGv_ptr addr
= tcg_temp_new_ptr();
1251 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1252 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1253 tcg_gen_andi_i32(t2
, t2
, 0xf);
1254 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1255 tcg_gen_ext_i32_ptr(addr
, t2
);
1256 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1258 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1259 tcg_temp_free_ptr(addr
);
1260 tcg_temp_free_i32(t2
);
1262 gen_store_gpr(t0
, to
);
1266 static inline void gen_store_srsgpr (int from
, int to
)
1269 TCGv t0
= tcg_temp_new();
1270 TCGv_i32 t2
= tcg_temp_new_i32();
1271 TCGv_ptr addr
= tcg_temp_new_ptr();
1273 gen_load_gpr(t0
, from
);
1274 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1275 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1276 tcg_gen_andi_i32(t2
, t2
, 0xf);
1277 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1278 tcg_gen_ext_i32_ptr(addr
, t2
);
1279 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1281 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1282 tcg_temp_free_ptr(addr
);
1283 tcg_temp_free_i32(t2
);
1288 /* Floating point register moves. */
1289 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1291 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1294 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1296 TCGv_i64 t64
= tcg_temp_new_i64();
1297 tcg_gen_extu_i32_i64(t64
, t
);
1298 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1299 tcg_temp_free_i64(t64
);
1302 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1304 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1305 TCGv_i64 t64
= tcg_temp_new_i64();
1306 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1307 tcg_gen_trunc_i64_i32(t
, t64
);
1308 tcg_temp_free_i64(t64
);
1310 gen_load_fpr32(t
, reg
| 1);
1314 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1316 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1317 TCGv_i64 t64
= tcg_temp_new_i64();
1318 tcg_gen_extu_i32_i64(t64
, t
);
1319 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1320 tcg_temp_free_i64(t64
);
1322 gen_store_fpr32(t
, reg
| 1);
1326 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1328 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1329 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1331 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1335 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1337 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1338 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1341 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1342 t0
= tcg_temp_new_i64();
1343 tcg_gen_shri_i64(t0
, t
, 32);
1344 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1345 tcg_temp_free_i64(t0
);
1349 static inline int get_fp_bit (int cc
)
1358 static inline void gen_save_pc(target_ulong pc
)
1360 tcg_gen_movi_tl(cpu_PC
, pc
);
1363 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1365 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1366 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1367 gen_save_pc(ctx
->pc
);
1368 ctx
->saved_pc
= ctx
->pc
;
1370 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1371 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1372 ctx
->saved_hflags
= ctx
->hflags
;
1373 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1379 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1385 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1387 ctx
->saved_hflags
= ctx
->hflags
;
1388 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1394 ctx
->btarget
= env
->btarget
;
1400 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1402 TCGv_i32 texcp
= tcg_const_i32(excp
);
1403 TCGv_i32 terr
= tcg_const_i32(err
);
1404 save_cpu_state(ctx
, 1);
1405 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1406 tcg_temp_free_i32(terr
);
1407 tcg_temp_free_i32(texcp
);
1411 generate_exception (DisasContext
*ctx
, int excp
)
1413 save_cpu_state(ctx
, 1);
1414 gen_helper_0e0i(raise_exception
, excp
);
1417 /* Addresses computation */
1418 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1420 tcg_gen_add_tl(ret
, arg0
, arg1
);
1422 #if defined(TARGET_MIPS64)
1423 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1424 tcg_gen_ext32s_i64(ret
, ret
);
1429 /* Addresses computation (translation time) */
1430 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1433 target_long sum
= base
+ offset
;
1435 #if defined(TARGET_MIPS64)
1436 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1443 static inline void check_cp0_enabled(DisasContext
*ctx
)
1445 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1446 generate_exception_err(ctx
, EXCP_CpU
, 0);
1449 static inline void check_cp1_enabled(DisasContext
*ctx
)
1451 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1452 generate_exception_err(ctx
, EXCP_CpU
, 1);
1455 /* Verify that the processor is running with COP1X instructions enabled.
1456 This is associated with the nabla symbol in the MIPS32 and MIPS64
1459 static inline void check_cop1x(DisasContext
*ctx
)
1461 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1462 generate_exception(ctx
, EXCP_RI
);
1465 /* Verify that the processor is running with 64-bit floating-point
1466 operations enabled. */
1468 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1470 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1471 generate_exception(ctx
, EXCP_RI
);
1475 * Verify if floating point register is valid; an operation is not defined
1476 * if bit 0 of any register specification is set and the FR bit in the
1477 * Status register equals zero, since the register numbers specify an
1478 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1479 * in the Status register equals one, both even and odd register numbers
1480 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1482 * Multiple 64 bit wide registers can be checked by calling
1483 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1485 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1487 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1488 generate_exception(ctx
, EXCP_RI
);
1491 /* Verify that the processor is running with DSP instructions enabled.
1492 This is enabled by CP0 Status register MX(24) bit.
1495 static inline void check_dsp(DisasContext
*ctx
)
1497 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1498 if (ctx
->insn_flags
& ASE_DSP
) {
1499 generate_exception(ctx
, EXCP_DSPDIS
);
1501 generate_exception(ctx
, EXCP_RI
);
1506 static inline void check_dspr2(DisasContext
*ctx
)
1508 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1509 if (ctx
->insn_flags
& ASE_DSP
) {
1510 generate_exception(ctx
, EXCP_DSPDIS
);
1512 generate_exception(ctx
, EXCP_RI
);
1517 /* This code generates a "reserved instruction" exception if the
1518 CPU does not support the instruction set corresponding to flags. */
1519 static inline void check_insn(DisasContext
*ctx
, int flags
)
1521 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1522 generate_exception(ctx
, EXCP_RI
);
1526 /* This code generates a "reserved instruction" exception if the
1527 CPU has corresponding flag set which indicates that the instruction
1528 has been removed. */
1529 static inline void check_insn_opc_removed(DisasContext
*ctx
, int flags
)
1531 if (unlikely(ctx
->insn_flags
& flags
)) {
1532 generate_exception(ctx
, EXCP_RI
);
1536 #ifdef TARGET_MIPS64
1537 /* This code generates a "reserved instruction" exception if 64-bit
1538 instructions are not enabled. */
1539 static inline void check_mips_64(DisasContext
*ctx
)
1541 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1542 generate_exception(ctx
, EXCP_RI
);
1546 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1547 calling interface for 32 and 64-bit FPRs. No sense in changing
1548 all callers for gen_load_fpr32 when we need the CTX parameter for
1550 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1551 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1552 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1553 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1554 int ft, int fs, int cc) \
1556 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1557 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1560 check_cp1_64bitmode(ctx); \
1566 check_cp1_registers(ctx, fs | ft); \
1574 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1575 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1577 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1578 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1579 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1580 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1581 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1582 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1583 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1584 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1585 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1586 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1587 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1588 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1589 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1590 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1591 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1592 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1595 tcg_temp_free_i##bits (fp0); \
1596 tcg_temp_free_i##bits (fp1); \
1599 FOP_CONDS(, 0, d
, FMT_D
, 64)
1600 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1601 FOP_CONDS(, 0, s
, FMT_S
, 32)
1602 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1603 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1604 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1607 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1608 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1609 int ft, int fs, int fd) \
1611 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1612 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1615 check_cp1_registers(ctx, fs | ft | fd); \
1618 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1619 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1622 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1625 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1628 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1631 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1634 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1637 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1640 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1643 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1646 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1649 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1652 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1655 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1658 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1661 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1664 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1667 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1670 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1673 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1676 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1679 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1682 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1685 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1691 tcg_temp_free_i ## bits (fp0); \
1692 tcg_temp_free_i ## bits (fp1); \
1695 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
1696 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(fp0
, fd
))
1698 #undef gen_ldcmp_fpr32
1699 #undef gen_ldcmp_fpr64
1701 /* load/store instructions. */
1702 #ifdef CONFIG_USER_ONLY
1703 #define OP_LD_ATOMIC(insn,fname) \
1704 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1706 TCGv t0 = tcg_temp_new(); \
1707 tcg_gen_mov_tl(t0, arg1); \
1708 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1709 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1710 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1711 tcg_temp_free(t0); \
1714 #define OP_LD_ATOMIC(insn,fname) \
1715 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1717 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1720 OP_LD_ATOMIC(ll
,ld32s
);
1721 #if defined(TARGET_MIPS64)
1722 OP_LD_ATOMIC(lld
,ld64
);
1726 #ifdef CONFIG_USER_ONLY
1727 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1728 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1730 TCGv t0 = tcg_temp_new(); \
1731 int l1 = gen_new_label(); \
1732 int l2 = gen_new_label(); \
1734 tcg_gen_andi_tl(t0, arg2, almask); \
1735 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1736 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1737 generate_exception(ctx, EXCP_AdES); \
1738 gen_set_label(l1); \
1739 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1740 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1741 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1742 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1743 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1744 gen_helper_0e0i(raise_exception, EXCP_SC); \
1745 gen_set_label(l2); \
1746 tcg_gen_movi_tl(t0, 0); \
1747 gen_store_gpr(t0, rt); \
1748 tcg_temp_free(t0); \
1751 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1752 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1754 TCGv t0 = tcg_temp_new(); \
1755 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1756 gen_store_gpr(t0, rt); \
1757 tcg_temp_free(t0); \
1760 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1761 #if defined(TARGET_MIPS64)
1762 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1766 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1767 int base
, int16_t offset
)
1770 tcg_gen_movi_tl(addr
, offset
);
1771 } else if (offset
== 0) {
1772 gen_load_gpr(addr
, base
);
1774 tcg_gen_movi_tl(addr
, offset
);
1775 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1779 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1781 target_ulong pc
= ctx
->pc
;
1783 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1784 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1789 pc
&= ~(target_ulong
)3;
1794 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1795 int rt
, int base
, int16_t offset
)
1797 const char *opn
= "ld";
1800 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1801 /* Loongson CPU uses a load to zero register for prefetch.
1802 We emulate it as a NOP. On other CPU we must perform the
1803 actual memory access. */
1808 t0
= tcg_temp_new();
1809 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1812 #if defined(TARGET_MIPS64)
1814 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1815 gen_store_gpr(t0
, rt
);
1819 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1820 gen_store_gpr(t0
, rt
);
1825 save_cpu_state(ctx
, 1);
1826 op_ld_lld(t0
, t0
, ctx
);
1827 gen_store_gpr(t0
, rt
);
1831 t1
= tcg_temp_new();
1832 tcg_gen_andi_tl(t1
, t0
, 7);
1833 #ifndef TARGET_WORDS_BIGENDIAN
1834 tcg_gen_xori_tl(t1
, t1
, 7);
1836 tcg_gen_shli_tl(t1
, t1
, 3);
1837 tcg_gen_andi_tl(t0
, t0
, ~7);
1838 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1839 tcg_gen_shl_tl(t0
, t0
, t1
);
1840 tcg_gen_xori_tl(t1
, t1
, 63);
1841 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1842 tcg_gen_shr_tl(t2
, t2
, t1
);
1843 gen_load_gpr(t1
, rt
);
1844 tcg_gen_and_tl(t1
, t1
, t2
);
1846 tcg_gen_or_tl(t0
, t0
, t1
);
1848 gen_store_gpr(t0
, rt
);
1852 t1
= tcg_temp_new();
1853 tcg_gen_andi_tl(t1
, t0
, 7);
1854 #ifdef TARGET_WORDS_BIGENDIAN
1855 tcg_gen_xori_tl(t1
, t1
, 7);
1857 tcg_gen_shli_tl(t1
, t1
, 3);
1858 tcg_gen_andi_tl(t0
, t0
, ~7);
1859 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1860 tcg_gen_shr_tl(t0
, t0
, t1
);
1861 tcg_gen_xori_tl(t1
, t1
, 63);
1862 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1863 tcg_gen_shl_tl(t2
, t2
, t1
);
1864 gen_load_gpr(t1
, rt
);
1865 tcg_gen_and_tl(t1
, t1
, t2
);
1867 tcg_gen_or_tl(t0
, t0
, t1
);
1869 gen_store_gpr(t0
, rt
);
1873 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1874 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1876 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1877 gen_store_gpr(t0
, rt
);
1882 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1883 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1885 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1886 gen_store_gpr(t0
, rt
);
1890 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1891 gen_store_gpr(t0
, rt
);
1895 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
1896 gen_store_gpr(t0
, rt
);
1900 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
1901 gen_store_gpr(t0
, rt
);
1905 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
1906 gen_store_gpr(t0
, rt
);
1910 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
1911 gen_store_gpr(t0
, rt
);
1915 t1
= tcg_temp_new();
1916 tcg_gen_andi_tl(t1
, t0
, 3);
1917 #ifndef TARGET_WORDS_BIGENDIAN
1918 tcg_gen_xori_tl(t1
, t1
, 3);
1920 tcg_gen_shli_tl(t1
, t1
, 3);
1921 tcg_gen_andi_tl(t0
, t0
, ~3);
1922 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1923 tcg_gen_shl_tl(t0
, t0
, t1
);
1924 tcg_gen_xori_tl(t1
, t1
, 31);
1925 t2
= tcg_const_tl(0x7fffffffull
);
1926 tcg_gen_shr_tl(t2
, t2
, t1
);
1927 gen_load_gpr(t1
, rt
);
1928 tcg_gen_and_tl(t1
, t1
, t2
);
1930 tcg_gen_or_tl(t0
, t0
, t1
);
1932 tcg_gen_ext32s_tl(t0
, t0
);
1933 gen_store_gpr(t0
, rt
);
1937 t1
= tcg_temp_new();
1938 tcg_gen_andi_tl(t1
, t0
, 3);
1939 #ifdef TARGET_WORDS_BIGENDIAN
1940 tcg_gen_xori_tl(t1
, t1
, 3);
1942 tcg_gen_shli_tl(t1
, t1
, 3);
1943 tcg_gen_andi_tl(t0
, t0
, ~3);
1944 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1945 tcg_gen_shr_tl(t0
, t0
, t1
);
1946 tcg_gen_xori_tl(t1
, t1
, 31);
1947 t2
= tcg_const_tl(0xfffffffeull
);
1948 tcg_gen_shl_tl(t2
, t2
, t1
);
1949 gen_load_gpr(t1
, rt
);
1950 tcg_gen_and_tl(t1
, t1
, t2
);
1952 tcg_gen_or_tl(t0
, t0
, t1
);
1954 tcg_gen_ext32s_tl(t0
, t0
);
1955 gen_store_gpr(t0
, rt
);
1960 save_cpu_state(ctx
, 1);
1961 op_ld_ll(t0
, t0
, ctx
);
1962 gen_store_gpr(t0
, rt
);
1966 (void)opn
; /* avoid a compiler warning */
1967 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1972 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1973 int base
, int16_t offset
)
1975 const char *opn
= "st";
1976 TCGv t0
= tcg_temp_new();
1977 TCGv t1
= tcg_temp_new();
1979 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1980 gen_load_gpr(t1
, rt
);
1982 #if defined(TARGET_MIPS64)
1984 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
1988 save_cpu_state(ctx
, 1);
1989 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1993 save_cpu_state(ctx
, 1);
1994 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
1999 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
2003 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
2007 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
2011 save_cpu_state(ctx
, 1);
2012 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
2016 save_cpu_state(ctx
, 1);
2017 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
2021 (void)opn
; /* avoid a compiler warning */
2022 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2028 /* Store conditional */
2029 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
2030 int base
, int16_t offset
)
2032 const char *opn
= "st_cond";
2035 #ifdef CONFIG_USER_ONLY
2036 t0
= tcg_temp_local_new();
2037 t1
= tcg_temp_local_new();
2039 t0
= tcg_temp_new();
2040 t1
= tcg_temp_new();
2042 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2043 gen_load_gpr(t1
, rt
);
2045 #if defined(TARGET_MIPS64)
2048 save_cpu_state(ctx
, 1);
2049 op_st_scd(t1
, t0
, rt
, ctx
);
2055 save_cpu_state(ctx
, 1);
2056 op_st_sc(t1
, t0
, rt
, ctx
);
2060 (void)opn
; /* avoid a compiler warning */
2061 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2066 /* Load and store */
2067 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
2068 int base
, int16_t offset
)
2070 const char *opn
= "flt_ldst";
2071 TCGv t0
= tcg_temp_new();
2073 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2074 /* Don't do NOP if destination is zero: we must perform the actual
2079 TCGv_i32 fp0
= tcg_temp_new_i32();
2080 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
2081 gen_store_fpr32(fp0
, ft
);
2082 tcg_temp_free_i32(fp0
);
2088 TCGv_i32 fp0
= tcg_temp_new_i32();
2089 gen_load_fpr32(fp0
, ft
);
2090 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2091 tcg_temp_free_i32(fp0
);
2097 TCGv_i64 fp0
= tcg_temp_new_i64();
2098 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2099 gen_store_fpr64(ctx
, fp0
, ft
);
2100 tcg_temp_free_i64(fp0
);
2106 TCGv_i64 fp0
= tcg_temp_new_i64();
2107 gen_load_fpr64(ctx
, fp0
, ft
);
2108 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2109 tcg_temp_free_i64(fp0
);
2115 generate_exception(ctx
, EXCP_RI
);
2118 (void)opn
; /* avoid a compiler warning */
2119 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
2124 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2125 int rs
, int16_t imm
)
2127 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2128 check_cp1_enabled(ctx
);
2129 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
2131 generate_exception_err(ctx
, EXCP_CpU
, 1);
2135 /* Arithmetic with immediate operand */
2136 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2137 int rt
, int rs
, int16_t imm
)
2139 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2140 const char *opn
= "imm arith";
2142 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2143 /* If no destination, treat it as a NOP.
2144 For addi, we must generate the overflow exception when needed. */
2151 TCGv t0
= tcg_temp_local_new();
2152 TCGv t1
= tcg_temp_new();
2153 TCGv t2
= tcg_temp_new();
2154 int l1
= gen_new_label();
2156 gen_load_gpr(t1
, rs
);
2157 tcg_gen_addi_tl(t0
, t1
, uimm
);
2158 tcg_gen_ext32s_tl(t0
, t0
);
2160 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2161 tcg_gen_xori_tl(t2
, t0
, uimm
);
2162 tcg_gen_and_tl(t1
, t1
, t2
);
2164 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2166 /* operands of same sign, result different sign */
2167 generate_exception(ctx
, EXCP_OVERFLOW
);
2169 tcg_gen_ext32s_tl(t0
, t0
);
2170 gen_store_gpr(t0
, rt
);
2177 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2178 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2180 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2184 #if defined(TARGET_MIPS64)
2187 TCGv t0
= tcg_temp_local_new();
2188 TCGv t1
= tcg_temp_new();
2189 TCGv t2
= tcg_temp_new();
2190 int l1
= gen_new_label();
2192 gen_load_gpr(t1
, rs
);
2193 tcg_gen_addi_tl(t0
, t1
, uimm
);
2195 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2196 tcg_gen_xori_tl(t2
, t0
, uimm
);
2197 tcg_gen_and_tl(t1
, t1
, t2
);
2199 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2201 /* operands of same sign, result different sign */
2202 generate_exception(ctx
, EXCP_OVERFLOW
);
2204 gen_store_gpr(t0
, rt
);
2211 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2213 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2219 (void)opn
; /* avoid a compiler warning */
2220 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2223 /* Logic with immediate operand */
2224 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2225 int rt
, int rs
, int16_t imm
)
2230 /* If no destination, treat it as a NOP. */
2234 uimm
= (uint16_t)imm
;
2237 if (likely(rs
!= 0))
2238 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2240 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2241 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2242 regnames
[rs
], uimm
);
2246 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2248 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2249 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2250 regnames
[rs
], uimm
);
2253 if (likely(rs
!= 0))
2254 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2256 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2257 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2258 regnames
[rs
], uimm
);
2261 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
2263 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2264 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2265 MIPS_DEBUG("aui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
2267 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2268 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2273 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2278 /* Set on less than with immediate operand */
2279 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2280 int rt
, int rs
, int16_t imm
)
2282 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2283 const char *opn
= "imm arith";
2287 /* If no destination, treat it as a NOP. */
2291 t0
= tcg_temp_new();
2292 gen_load_gpr(t0
, rs
);
2295 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2299 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2303 (void)opn
; /* avoid a compiler warning */
2304 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2308 /* Shifts with immediate operand */
2309 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2310 int rt
, int rs
, int16_t imm
)
2312 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2313 const char *opn
= "imm shift";
2317 /* If no destination, treat it as a NOP. */
2322 t0
= tcg_temp_new();
2323 gen_load_gpr(t0
, rs
);
2326 tcg_gen_shli_tl(t0
, t0
, uimm
);
2327 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2331 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2336 tcg_gen_ext32u_tl(t0
, t0
);
2337 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2339 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2345 TCGv_i32 t1
= tcg_temp_new_i32();
2347 tcg_gen_trunc_tl_i32(t1
, t0
);
2348 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2349 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2350 tcg_temp_free_i32(t1
);
2352 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2356 #if defined(TARGET_MIPS64)
2358 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2362 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2366 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2371 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2373 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2378 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2382 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2386 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2390 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2395 (void)opn
; /* avoid a compiler warning */
2396 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2401 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2402 int rd
, int rs
, int rt
)
2404 const char *opn
= "arith";
2406 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2407 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2408 /* If no destination, treat it as a NOP.
2409 For add & sub, we must generate the overflow exception when needed. */
2417 TCGv t0
= tcg_temp_local_new();
2418 TCGv t1
= tcg_temp_new();
2419 TCGv t2
= tcg_temp_new();
2420 int l1
= gen_new_label();
2422 gen_load_gpr(t1
, rs
);
2423 gen_load_gpr(t2
, rt
);
2424 tcg_gen_add_tl(t0
, t1
, t2
);
2425 tcg_gen_ext32s_tl(t0
, t0
);
2426 tcg_gen_xor_tl(t1
, t1
, t2
);
2427 tcg_gen_xor_tl(t2
, t0
, t2
);
2428 tcg_gen_andc_tl(t1
, t2
, t1
);
2430 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2432 /* operands of same sign, result different sign */
2433 generate_exception(ctx
, EXCP_OVERFLOW
);
2435 gen_store_gpr(t0
, rd
);
2441 if (rs
!= 0 && rt
!= 0) {
2442 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2443 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2444 } else if (rs
== 0 && rt
!= 0) {
2445 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2446 } else if (rs
!= 0 && rt
== 0) {
2447 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2449 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2455 TCGv t0
= tcg_temp_local_new();
2456 TCGv t1
= tcg_temp_new();
2457 TCGv t2
= tcg_temp_new();
2458 int l1
= gen_new_label();
2460 gen_load_gpr(t1
, rs
);
2461 gen_load_gpr(t2
, rt
);
2462 tcg_gen_sub_tl(t0
, t1
, t2
);
2463 tcg_gen_ext32s_tl(t0
, t0
);
2464 tcg_gen_xor_tl(t2
, t1
, t2
);
2465 tcg_gen_xor_tl(t1
, t0
, t1
);
2466 tcg_gen_and_tl(t1
, t1
, t2
);
2468 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2470 /* operands of different sign, first operand and result different sign */
2471 generate_exception(ctx
, EXCP_OVERFLOW
);
2473 gen_store_gpr(t0
, rd
);
2479 if (rs
!= 0 && rt
!= 0) {
2480 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2481 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2482 } else if (rs
== 0 && rt
!= 0) {
2483 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2484 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2485 } else if (rs
!= 0 && rt
== 0) {
2486 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2488 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2492 #if defined(TARGET_MIPS64)
2495 TCGv t0
= tcg_temp_local_new();
2496 TCGv t1
= tcg_temp_new();
2497 TCGv t2
= tcg_temp_new();
2498 int l1
= gen_new_label();
2500 gen_load_gpr(t1
, rs
);
2501 gen_load_gpr(t2
, rt
);
2502 tcg_gen_add_tl(t0
, t1
, t2
);
2503 tcg_gen_xor_tl(t1
, t1
, t2
);
2504 tcg_gen_xor_tl(t2
, t0
, t2
);
2505 tcg_gen_andc_tl(t1
, t2
, t1
);
2507 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2509 /* operands of same sign, result different sign */
2510 generate_exception(ctx
, EXCP_OVERFLOW
);
2512 gen_store_gpr(t0
, rd
);
2518 if (rs
!= 0 && rt
!= 0) {
2519 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2520 } else if (rs
== 0 && rt
!= 0) {
2521 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2522 } else if (rs
!= 0 && rt
== 0) {
2523 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2525 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2531 TCGv t0
= tcg_temp_local_new();
2532 TCGv t1
= tcg_temp_new();
2533 TCGv t2
= tcg_temp_new();
2534 int l1
= gen_new_label();
2536 gen_load_gpr(t1
, rs
);
2537 gen_load_gpr(t2
, rt
);
2538 tcg_gen_sub_tl(t0
, t1
, t2
);
2539 tcg_gen_xor_tl(t2
, t1
, t2
);
2540 tcg_gen_xor_tl(t1
, t0
, t1
);
2541 tcg_gen_and_tl(t1
, t1
, t2
);
2543 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2545 /* operands of different sign, first operand and result different sign */
2546 generate_exception(ctx
, EXCP_OVERFLOW
);
2548 gen_store_gpr(t0
, rd
);
2554 if (rs
!= 0 && rt
!= 0) {
2555 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2556 } else if (rs
== 0 && rt
!= 0) {
2557 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2558 } else if (rs
!= 0 && rt
== 0) {
2559 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2561 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2567 if (likely(rs
!= 0 && rt
!= 0)) {
2568 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2569 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2571 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2576 (void)opn
; /* avoid a compiler warning */
2577 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2580 /* Conditional move */
2581 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2582 int rd
, int rs
, int rt
)
2584 const char *opn
= "cond move";
2588 /* If no destination, treat it as a NOP. */
2593 t0
= tcg_temp_new();
2594 gen_load_gpr(t0
, rt
);
2595 t1
= tcg_const_tl(0);
2596 t2
= tcg_temp_new();
2597 gen_load_gpr(t2
, rs
);
2600 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2604 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2608 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2612 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2620 (void)opn
; /* avoid a compiler warning */
2621 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2625 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2626 int rd
, int rs
, int rt
)
2628 const char *opn
= "logic";
2631 /* If no destination, treat it as a NOP. */
2638 if (likely(rs
!= 0 && rt
!= 0)) {
2639 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2641 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2646 if (rs
!= 0 && rt
!= 0) {
2647 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2648 } else if (rs
== 0 && rt
!= 0) {
2649 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2650 } else if (rs
!= 0 && rt
== 0) {
2651 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2653 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2658 if (likely(rs
!= 0 && rt
!= 0)) {
2659 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2660 } else if (rs
== 0 && rt
!= 0) {
2661 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2662 } else if (rs
!= 0 && rt
== 0) {
2663 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2665 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2670 if (likely(rs
!= 0 && rt
!= 0)) {
2671 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2672 } else if (rs
== 0 && rt
!= 0) {
2673 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2674 } else if (rs
!= 0 && rt
== 0) {
2675 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2677 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2682 (void)opn
; /* avoid a compiler warning */
2683 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2686 /* Set on lower than */
2687 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2688 int rd
, int rs
, int rt
)
2690 const char *opn
= "slt";
2694 /* If no destination, treat it as a NOP. */
2699 t0
= tcg_temp_new();
2700 t1
= tcg_temp_new();
2701 gen_load_gpr(t0
, rs
);
2702 gen_load_gpr(t1
, rt
);
2705 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2709 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2713 (void)opn
; /* avoid a compiler warning */
2714 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2720 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2721 int rd
, int rs
, int rt
)
2723 const char *opn
= "shifts";
2727 /* If no destination, treat it as a NOP.
2728 For add & sub, we must generate the overflow exception when needed. */
2733 t0
= tcg_temp_new();
2734 t1
= tcg_temp_new();
2735 gen_load_gpr(t0
, rs
);
2736 gen_load_gpr(t1
, rt
);
2739 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2740 tcg_gen_shl_tl(t0
, t1
, t0
);
2741 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2745 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2746 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2750 tcg_gen_ext32u_tl(t1
, t1
);
2751 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2752 tcg_gen_shr_tl(t0
, t1
, t0
);
2753 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2758 TCGv_i32 t2
= tcg_temp_new_i32();
2759 TCGv_i32 t3
= tcg_temp_new_i32();
2761 tcg_gen_trunc_tl_i32(t2
, t0
);
2762 tcg_gen_trunc_tl_i32(t3
, t1
);
2763 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2764 tcg_gen_rotr_i32(t2
, t3
, t2
);
2765 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2766 tcg_temp_free_i32(t2
);
2767 tcg_temp_free_i32(t3
);
2771 #if defined(TARGET_MIPS64)
2773 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2774 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2778 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2779 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2783 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2784 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2788 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2789 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2794 (void)opn
; /* avoid a compiler warning */
2795 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2800 /* Arithmetic on HI/LO registers */
2801 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2803 const char *opn
= "hilo";
2805 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2817 #if defined(TARGET_MIPS64)
2819 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2823 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2828 #if defined(TARGET_MIPS64)
2830 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2834 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2840 #if defined(TARGET_MIPS64)
2842 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2846 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2849 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2855 #if defined(TARGET_MIPS64)
2857 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2861 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2864 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2869 (void)opn
; /* avoid a compiler warning */
2870 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2873 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
2876 TCGv t0
= tcg_const_tl(addr
);
2877 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
2878 gen_store_gpr(t0
, reg
);
2882 static inline void gen_pcrel(DisasContext
*ctx
, int rs
, int16_t imm
)
2887 switch (MASK_OPC_PCREL_TOP2BITS(ctx
->opcode
)) {
2890 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
2891 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2892 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
2896 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
2897 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2898 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
2900 #if defined(TARGET_MIPS64)
2903 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
2904 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2905 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
2909 switch (MASK_OPC_PCREL_TOP5BITS(ctx
->opcode
)) {
2913 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2914 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
2920 addr
= ~0xFFFF & addr_add(ctx
, ctx
->pc
, offset
);
2921 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
2924 #if defined(TARGET_MIPS64)
2925 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
2926 case R6_OPC_LDPC
+ (1 << 16):
2927 case R6_OPC_LDPC
+ (2 << 16):
2928 case R6_OPC_LDPC
+ (3 << 16):
2930 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
2931 addr
= addr_add(ctx
, (ctx
->pc
& ~0x7), offset
);
2932 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
2936 MIPS_INVAL("OPC_PCREL");
2937 generate_exception(ctx
, EXCP_RI
);
2944 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
2946 const char *opn
= "r6 mul/div";
2955 t0
= tcg_temp_new();
2956 t1
= tcg_temp_new();
2958 gen_load_gpr(t0
, rs
);
2959 gen_load_gpr(t1
, rt
);
2964 TCGv t2
= tcg_temp_new();
2965 TCGv t3
= tcg_temp_new();
2966 tcg_gen_ext32s_tl(t0
, t0
);
2967 tcg_gen_ext32s_tl(t1
, t1
);
2968 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2969 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2970 tcg_gen_and_tl(t2
, t2
, t3
);
2971 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2972 tcg_gen_or_tl(t2
, t2
, t3
);
2973 tcg_gen_movi_tl(t3
, 0);
2974 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2975 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
2976 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2984 TCGv t2
= tcg_temp_new();
2985 TCGv t3
= tcg_temp_new();
2986 tcg_gen_ext32s_tl(t0
, t0
);
2987 tcg_gen_ext32s_tl(t1
, t1
);
2988 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2989 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2990 tcg_gen_and_tl(t2
, t2
, t3
);
2991 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2992 tcg_gen_or_tl(t2
, t2
, t3
);
2993 tcg_gen_movi_tl(t3
, 0);
2994 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2995 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
2996 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3004 TCGv t2
= tcg_const_tl(0);
3005 TCGv t3
= tcg_const_tl(1);
3006 tcg_gen_ext32u_tl(t0
, t0
);
3007 tcg_gen_ext32u_tl(t1
, t1
);
3008 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3009 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3010 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3018 TCGv t2
= tcg_const_tl(0);
3019 TCGv t3
= tcg_const_tl(1);
3020 tcg_gen_ext32u_tl(t0
, t0
);
3021 tcg_gen_ext32u_tl(t1
, t1
);
3022 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3023 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3024 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3032 TCGv_i32 t2
= tcg_temp_new_i32();
3033 TCGv_i32 t3
= tcg_temp_new_i32();
3034 tcg_gen_trunc_tl_i32(t2
, t0
);
3035 tcg_gen_trunc_tl_i32(t3
, t1
);
3036 tcg_gen_mul_i32(t2
, t2
, t3
);
3037 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3038 tcg_temp_free_i32(t2
);
3039 tcg_temp_free_i32(t3
);
3045 TCGv_i32 t2
= tcg_temp_new_i32();
3046 TCGv_i32 t3
= tcg_temp_new_i32();
3047 tcg_gen_trunc_tl_i32(t2
, t0
);
3048 tcg_gen_trunc_tl_i32(t3
, t1
);
3049 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3050 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3051 tcg_temp_free_i32(t2
);
3052 tcg_temp_free_i32(t3
);
3058 TCGv_i32 t2
= tcg_temp_new_i32();
3059 TCGv_i32 t3
= tcg_temp_new_i32();
3060 tcg_gen_trunc_tl_i32(t2
, t0
);
3061 tcg_gen_trunc_tl_i32(t3
, t1
);
3062 tcg_gen_mul_i32(t2
, t2
, t3
);
3063 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3064 tcg_temp_free_i32(t2
);
3065 tcg_temp_free_i32(t3
);
3071 TCGv_i32 t2
= tcg_temp_new_i32();
3072 TCGv_i32 t3
= tcg_temp_new_i32();
3073 tcg_gen_trunc_tl_i32(t2
, t0
);
3074 tcg_gen_trunc_tl_i32(t3
, t1
);
3075 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3076 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3077 tcg_temp_free_i32(t2
);
3078 tcg_temp_free_i32(t3
);
3082 #if defined(TARGET_MIPS64)
3085 TCGv t2
= tcg_temp_new();
3086 TCGv t3
= tcg_temp_new();
3087 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3088 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3089 tcg_gen_and_tl(t2
, t2
, t3
);
3090 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3091 tcg_gen_or_tl(t2
, t2
, t3
);
3092 tcg_gen_movi_tl(t3
, 0);
3093 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3094 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3102 TCGv t2
= tcg_temp_new();
3103 TCGv t3
= tcg_temp_new();
3104 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3105 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3106 tcg_gen_and_tl(t2
, t2
, t3
);
3107 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3108 tcg_gen_or_tl(t2
, t2
, t3
);
3109 tcg_gen_movi_tl(t3
, 0);
3110 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3111 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3119 TCGv t2
= tcg_const_tl(0);
3120 TCGv t3
= tcg_const_tl(1);
3121 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3122 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3130 TCGv t2
= tcg_const_tl(0);
3131 TCGv t3
= tcg_const_tl(1);
3132 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3133 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3140 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3145 TCGv t2
= tcg_temp_new();
3146 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3152 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3157 TCGv t2
= tcg_temp_new();
3158 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3166 generate_exception(ctx
, EXCP_RI
);
3169 (void)opn
; /* avoid a compiler warning */
3170 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3176 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3177 int acc
, int rs
, int rt
)
3179 const char *opn
= "mul/div";
3182 t0
= tcg_temp_new();
3183 t1
= tcg_temp_new();
3185 gen_load_gpr(t0
, rs
);
3186 gen_load_gpr(t1
, rt
);
3195 TCGv t2
= tcg_temp_new();
3196 TCGv t3
= tcg_temp_new();
3197 tcg_gen_ext32s_tl(t0
, t0
);
3198 tcg_gen_ext32s_tl(t1
, t1
);
3199 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3200 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3201 tcg_gen_and_tl(t2
, t2
, t3
);
3202 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3203 tcg_gen_or_tl(t2
, t2
, t3
);
3204 tcg_gen_movi_tl(t3
, 0);
3205 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3206 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3207 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3208 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3209 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3217 TCGv t2
= tcg_const_tl(0);
3218 TCGv t3
= tcg_const_tl(1);
3219 tcg_gen_ext32u_tl(t0
, t0
);
3220 tcg_gen_ext32u_tl(t1
, t1
);
3221 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3222 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3223 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3224 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3225 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3233 TCGv_i32 t2
= tcg_temp_new_i32();
3234 TCGv_i32 t3
= tcg_temp_new_i32();
3235 tcg_gen_trunc_tl_i32(t2
, t0
);
3236 tcg_gen_trunc_tl_i32(t3
, t1
);
3237 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3238 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3239 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3240 tcg_temp_free_i32(t2
);
3241 tcg_temp_free_i32(t3
);
3247 TCGv_i32 t2
= tcg_temp_new_i32();
3248 TCGv_i32 t3
= tcg_temp_new_i32();
3249 tcg_gen_trunc_tl_i32(t2
, t0
);
3250 tcg_gen_trunc_tl_i32(t3
, t1
);
3251 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3252 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3253 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3254 tcg_temp_free_i32(t2
);
3255 tcg_temp_free_i32(t3
);
3259 #if defined(TARGET_MIPS64)
3262 TCGv t2
= tcg_temp_new();
3263 TCGv t3
= tcg_temp_new();
3264 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3265 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3266 tcg_gen_and_tl(t2
, t2
, t3
);
3267 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3268 tcg_gen_or_tl(t2
, t2
, t3
);
3269 tcg_gen_movi_tl(t3
, 0);
3270 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3271 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3272 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3280 TCGv t2
= tcg_const_tl(0);
3281 TCGv t3
= tcg_const_tl(1);
3282 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3283 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3284 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3291 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3295 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3301 TCGv_i64 t2
= tcg_temp_new_i64();
3302 TCGv_i64 t3
= tcg_temp_new_i64();
3304 tcg_gen_ext_tl_i64(t2
, t0
);
3305 tcg_gen_ext_tl_i64(t3
, t1
);
3306 tcg_gen_mul_i64(t2
, t2
, t3
);
3307 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3308 tcg_gen_add_i64(t2
, t2
, t3
);
3309 tcg_temp_free_i64(t3
);
3310 tcg_gen_trunc_i64_tl(t0
, t2
);
3311 tcg_gen_shri_i64(t2
, t2
, 32);
3312 tcg_gen_trunc_i64_tl(t1
, t2
);
3313 tcg_temp_free_i64(t2
);
3314 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3315 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3321 TCGv_i64 t2
= tcg_temp_new_i64();
3322 TCGv_i64 t3
= tcg_temp_new_i64();
3324 tcg_gen_ext32u_tl(t0
, t0
);
3325 tcg_gen_ext32u_tl(t1
, t1
);
3326 tcg_gen_extu_tl_i64(t2
, t0
);
3327 tcg_gen_extu_tl_i64(t3
, t1
);
3328 tcg_gen_mul_i64(t2
, t2
, t3
);
3329 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3330 tcg_gen_add_i64(t2
, t2
, t3
);
3331 tcg_temp_free_i64(t3
);
3332 tcg_gen_trunc_i64_tl(t0
, t2
);
3333 tcg_gen_shri_i64(t2
, t2
, 32);
3334 tcg_gen_trunc_i64_tl(t1
, t2
);
3335 tcg_temp_free_i64(t2
);
3336 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3337 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3343 TCGv_i64 t2
= tcg_temp_new_i64();
3344 TCGv_i64 t3
= tcg_temp_new_i64();
3346 tcg_gen_ext_tl_i64(t2
, t0
);
3347 tcg_gen_ext_tl_i64(t3
, t1
);
3348 tcg_gen_mul_i64(t2
, t2
, t3
);
3349 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3350 tcg_gen_sub_i64(t2
, t3
, t2
);
3351 tcg_temp_free_i64(t3
);
3352 tcg_gen_trunc_i64_tl(t0
, t2
);
3353 tcg_gen_shri_i64(t2
, t2
, 32);
3354 tcg_gen_trunc_i64_tl(t1
, t2
);
3355 tcg_temp_free_i64(t2
);
3356 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3357 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3363 TCGv_i64 t2
= tcg_temp_new_i64();
3364 TCGv_i64 t3
= tcg_temp_new_i64();
3366 tcg_gen_ext32u_tl(t0
, t0
);
3367 tcg_gen_ext32u_tl(t1
, t1
);
3368 tcg_gen_extu_tl_i64(t2
, t0
);
3369 tcg_gen_extu_tl_i64(t3
, t1
);
3370 tcg_gen_mul_i64(t2
, t2
, t3
);
3371 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3372 tcg_gen_sub_i64(t2
, t3
, t2
);
3373 tcg_temp_free_i64(t3
);
3374 tcg_gen_trunc_i64_tl(t0
, t2
);
3375 tcg_gen_shri_i64(t2
, t2
, 32);
3376 tcg_gen_trunc_i64_tl(t1
, t2
);
3377 tcg_temp_free_i64(t2
);
3378 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3379 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3385 generate_exception(ctx
, EXCP_RI
);
3388 (void)opn
; /* avoid a compiler warning */
3389 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3395 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
3396 int rd
, int rs
, int rt
)
3398 const char *opn
= "mul vr54xx";
3399 TCGv t0
= tcg_temp_new();
3400 TCGv t1
= tcg_temp_new();
3402 gen_load_gpr(t0
, rs
);
3403 gen_load_gpr(t1
, rt
);
3406 case OPC_VR54XX_MULS
:
3407 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3410 case OPC_VR54XX_MULSU
:
3411 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3414 case OPC_VR54XX_MACC
:
3415 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3418 case OPC_VR54XX_MACCU
:
3419 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3422 case OPC_VR54XX_MSAC
:
3423 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3426 case OPC_VR54XX_MSACU
:
3427 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3430 case OPC_VR54XX_MULHI
:
3431 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3434 case OPC_VR54XX_MULHIU
:
3435 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3438 case OPC_VR54XX_MULSHI
:
3439 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3442 case OPC_VR54XX_MULSHIU
:
3443 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3446 case OPC_VR54XX_MACCHI
:
3447 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3450 case OPC_VR54XX_MACCHIU
:
3451 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3454 case OPC_VR54XX_MSACHI
:
3455 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3458 case OPC_VR54XX_MSACHIU
:
3459 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3463 MIPS_INVAL("mul vr54xx");
3464 generate_exception(ctx
, EXCP_RI
);
3467 gen_store_gpr(t0
, rd
);
3468 (void)opn
; /* avoid a compiler warning */
3469 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3476 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
3479 const char *opn
= "CLx";
3487 t0
= tcg_temp_new();
3488 gen_load_gpr(t0
, rs
);
3492 gen_helper_clo(cpu_gpr
[rd
], t0
);
3497 gen_helper_clz(cpu_gpr
[rd
], t0
);
3500 #if defined(TARGET_MIPS64)
3503 gen_helper_dclo(cpu_gpr
[rd
], t0
);
3508 gen_helper_dclz(cpu_gpr
[rd
], t0
);
3513 (void)opn
; /* avoid a compiler warning */
3514 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3518 /* Godson integer instructions */
3519 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3520 int rd
, int rs
, int rt
)
3522 const char *opn
= "loongson";
3534 case OPC_MULTU_G_2E
:
3535 case OPC_MULTU_G_2F
:
3536 #if defined(TARGET_MIPS64)
3537 case OPC_DMULT_G_2E
:
3538 case OPC_DMULT_G_2F
:
3539 case OPC_DMULTU_G_2E
:
3540 case OPC_DMULTU_G_2F
:
3542 t0
= tcg_temp_new();
3543 t1
= tcg_temp_new();
3546 t0
= tcg_temp_local_new();
3547 t1
= tcg_temp_local_new();
3551 gen_load_gpr(t0
, rs
);
3552 gen_load_gpr(t1
, rt
);
3557 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3558 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3561 case OPC_MULTU_G_2E
:
3562 case OPC_MULTU_G_2F
:
3563 tcg_gen_ext32u_tl(t0
, t0
);
3564 tcg_gen_ext32u_tl(t1
, t1
);
3565 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3566 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3572 int l1
= gen_new_label();
3573 int l2
= gen_new_label();
3574 int l3
= gen_new_label();
3575 tcg_gen_ext32s_tl(t0
, t0
);
3576 tcg_gen_ext32s_tl(t1
, t1
);
3577 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3578 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3581 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3582 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3583 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3586 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3587 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3595 int l1
= gen_new_label();
3596 int l2
= gen_new_label();
3597 tcg_gen_ext32u_tl(t0
, t0
);
3598 tcg_gen_ext32u_tl(t1
, t1
);
3599 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3600 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3603 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3604 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3612 int l1
= gen_new_label();
3613 int l2
= gen_new_label();
3614 int l3
= gen_new_label();
3615 tcg_gen_ext32u_tl(t0
, t0
);
3616 tcg_gen_ext32u_tl(t1
, t1
);
3617 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3618 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3619 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3621 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3624 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3625 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3633 int l1
= gen_new_label();
3634 int l2
= gen_new_label();
3635 tcg_gen_ext32u_tl(t0
, t0
);
3636 tcg_gen_ext32u_tl(t1
, t1
);
3637 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3638 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3641 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3642 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3647 #if defined(TARGET_MIPS64)
3648 case OPC_DMULT_G_2E
:
3649 case OPC_DMULT_G_2F
:
3650 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3653 case OPC_DMULTU_G_2E
:
3654 case OPC_DMULTU_G_2F
:
3655 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3661 int l1
= gen_new_label();
3662 int l2
= gen_new_label();
3663 int l3
= gen_new_label();
3664 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3665 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3668 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3669 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3670 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3673 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3678 case OPC_DDIVU_G_2E
:
3679 case OPC_DDIVU_G_2F
:
3681 int l1
= gen_new_label();
3682 int l2
= gen_new_label();
3683 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3684 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3687 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3695 int l1
= gen_new_label();
3696 int l2
= gen_new_label();
3697 int l3
= gen_new_label();
3698 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3699 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3700 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3702 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3705 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3710 case OPC_DMODU_G_2E
:
3711 case OPC_DMODU_G_2F
:
3713 int l1
= gen_new_label();
3714 int l2
= gen_new_label();
3715 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3716 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3719 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3727 (void)opn
; /* avoid a compiler warning */
3728 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3733 /* Loongson multimedia instructions */
3734 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3736 const char *opn
= "loongson_cp2";
3737 uint32_t opc
, shift_max
;
3740 opc
= MASK_LMI(ctx
->opcode
);
3746 t0
= tcg_temp_local_new_i64();
3747 t1
= tcg_temp_local_new_i64();
3750 t0
= tcg_temp_new_i64();
3751 t1
= tcg_temp_new_i64();
3755 gen_load_fpr64(ctx
, t0
, rs
);
3756 gen_load_fpr64(ctx
, t1
, rt
);
3758 #define LMI_HELPER(UP, LO) \
3759 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3760 #define LMI_HELPER_1(UP, LO) \
3761 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3762 #define LMI_DIRECT(UP, LO, OP) \
3763 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3766 LMI_HELPER(PADDSH
, paddsh
);
3767 LMI_HELPER(PADDUSH
, paddush
);
3768 LMI_HELPER(PADDH
, paddh
);
3769 LMI_HELPER(PADDW
, paddw
);
3770 LMI_HELPER(PADDSB
, paddsb
);
3771 LMI_HELPER(PADDUSB
, paddusb
);
3772 LMI_HELPER(PADDB
, paddb
);
3774 LMI_HELPER(PSUBSH
, psubsh
);
3775 LMI_HELPER(PSUBUSH
, psubush
);
3776 LMI_HELPER(PSUBH
, psubh
);
3777 LMI_HELPER(PSUBW
, psubw
);
3778 LMI_HELPER(PSUBSB
, psubsb
);
3779 LMI_HELPER(PSUBUSB
, psubusb
);
3780 LMI_HELPER(PSUBB
, psubb
);
3782 LMI_HELPER(PSHUFH
, pshufh
);
3783 LMI_HELPER(PACKSSWH
, packsswh
);
3784 LMI_HELPER(PACKSSHB
, packsshb
);
3785 LMI_HELPER(PACKUSHB
, packushb
);
3787 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3788 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3789 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3790 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3791 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3792 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3794 LMI_HELPER(PAVGH
, pavgh
);
3795 LMI_HELPER(PAVGB
, pavgb
);
3796 LMI_HELPER(PMAXSH
, pmaxsh
);
3797 LMI_HELPER(PMINSH
, pminsh
);
3798 LMI_HELPER(PMAXUB
, pmaxub
);
3799 LMI_HELPER(PMINUB
, pminub
);
3801 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3802 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3803 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3804 LMI_HELPER(PCMPGTH
, pcmpgth
);
3805 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3806 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3808 LMI_HELPER(PSLLW
, psllw
);
3809 LMI_HELPER(PSLLH
, psllh
);
3810 LMI_HELPER(PSRLW
, psrlw
);
3811 LMI_HELPER(PSRLH
, psrlh
);
3812 LMI_HELPER(PSRAW
, psraw
);
3813 LMI_HELPER(PSRAH
, psrah
);
3815 LMI_HELPER(PMULLH
, pmullh
);
3816 LMI_HELPER(PMULHH
, pmulhh
);
3817 LMI_HELPER(PMULHUH
, pmulhuh
);
3818 LMI_HELPER(PMADDHW
, pmaddhw
);
3820 LMI_HELPER(PASUBUB
, pasubub
);
3821 LMI_HELPER_1(BIADD
, biadd
);
3822 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3824 LMI_DIRECT(PADDD
, paddd
, add
);
3825 LMI_DIRECT(PSUBD
, psubd
, sub
);
3826 LMI_DIRECT(XOR_CP2
, xor, xor);
3827 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3828 LMI_DIRECT(AND_CP2
, and, and);
3829 LMI_DIRECT(PANDN
, pandn
, andc
);
3830 LMI_DIRECT(OR
, or, or);
3833 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3837 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3841 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3845 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3850 tcg_gen_andi_i64(t1
, t1
, 3);
3851 tcg_gen_shli_i64(t1
, t1
, 4);
3852 tcg_gen_shr_i64(t0
, t0
, t1
);
3853 tcg_gen_ext16u_i64(t0
, t0
);
3858 tcg_gen_add_i64(t0
, t0
, t1
);
3859 tcg_gen_ext32s_i64(t0
, t0
);
3863 tcg_gen_sub_i64(t0
, t0
, t1
);
3864 tcg_gen_ext32s_i64(t0
, t0
);
3893 /* Make sure shift count isn't TCG undefined behaviour. */
3894 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3899 tcg_gen_shl_i64(t0
, t0
, t1
);
3903 /* Since SRA is UndefinedResult without sign-extended inputs,
3904 we can treat SRA and DSRA the same. */
3905 tcg_gen_sar_i64(t0
, t0
, t1
);
3908 /* We want to shift in zeros for SRL; zero-extend first. */
3909 tcg_gen_ext32u_i64(t0
, t0
);
3912 tcg_gen_shr_i64(t0
, t0
, t1
);
3916 if (shift_max
== 32) {
3917 tcg_gen_ext32s_i64(t0
, t0
);
3920 /* Shifts larger than MAX produce zero. */
3921 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3922 tcg_gen_neg_i64(t1
, t1
);
3923 tcg_gen_and_i64(t0
, t0
, t1
);
3929 TCGv_i64 t2
= tcg_temp_new_i64();
3930 int lab
= gen_new_label();
3932 tcg_gen_mov_i64(t2
, t0
);
3933 tcg_gen_add_i64(t0
, t1
, t2
);
3934 if (opc
== OPC_ADD_CP2
) {
3935 tcg_gen_ext32s_i64(t0
, t0
);
3937 tcg_gen_xor_i64(t1
, t1
, t2
);
3938 tcg_gen_xor_i64(t2
, t2
, t0
);
3939 tcg_gen_andc_i64(t1
, t2
, t1
);
3940 tcg_temp_free_i64(t2
);
3941 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3942 generate_exception(ctx
, EXCP_OVERFLOW
);
3945 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3952 TCGv_i64 t2
= tcg_temp_new_i64();
3953 int lab
= gen_new_label();
3955 tcg_gen_mov_i64(t2
, t0
);
3956 tcg_gen_sub_i64(t0
, t1
, t2
);
3957 if (opc
== OPC_SUB_CP2
) {
3958 tcg_gen_ext32s_i64(t0
, t0
);
3960 tcg_gen_xor_i64(t1
, t1
, t2
);
3961 tcg_gen_xor_i64(t2
, t2
, t0
);
3962 tcg_gen_and_i64(t1
, t1
, t2
);
3963 tcg_temp_free_i64(t2
);
3964 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3965 generate_exception(ctx
, EXCP_OVERFLOW
);
3968 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3973 tcg_gen_ext32u_i64(t0
, t0
);
3974 tcg_gen_ext32u_i64(t1
, t1
);
3975 tcg_gen_mul_i64(t0
, t0
, t1
);
3985 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3986 FD field is the CC field? */
3989 generate_exception(ctx
, EXCP_RI
);
3996 gen_store_fpr64(ctx
, t0
, rd
);
3998 (void)opn
; /* avoid a compiler warning */
3999 MIPS_DEBUG("%s %s, %s, %s", opn
,
4000 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
4001 tcg_temp_free_i64(t0
);
4002 tcg_temp_free_i64(t1
);
4006 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
4007 int rs
, int rt
, int16_t imm
)
4010 TCGv t0
= tcg_temp_new();
4011 TCGv t1
= tcg_temp_new();
4014 /* Load needed operands */
4022 /* Compare two registers */
4024 gen_load_gpr(t0
, rs
);
4025 gen_load_gpr(t1
, rt
);
4035 /* Compare register to immediate */
4036 if (rs
!= 0 || imm
!= 0) {
4037 gen_load_gpr(t0
, rs
);
4038 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4045 case OPC_TEQ
: /* rs == rs */
4046 case OPC_TEQI
: /* r0 == 0 */
4047 case OPC_TGE
: /* rs >= rs */
4048 case OPC_TGEI
: /* r0 >= 0 */
4049 case OPC_TGEU
: /* rs >= rs unsigned */
4050 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4052 generate_exception(ctx
, EXCP_TRAP
);
4054 case OPC_TLT
: /* rs < rs */
4055 case OPC_TLTI
: /* r0 < 0 */
4056 case OPC_TLTU
: /* rs < rs unsigned */
4057 case OPC_TLTIU
: /* r0 < 0 unsigned */
4058 case OPC_TNE
: /* rs != rs */
4059 case OPC_TNEI
: /* r0 != 0 */
4060 /* Never trap: treat as NOP. */
4064 int l1
= gen_new_label();
4069 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4073 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4077 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
4081 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
4085 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
4089 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
4092 generate_exception(ctx
, EXCP_TRAP
);
4099 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
4101 TranslationBlock
*tb
;
4103 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
4104 likely(!ctx
->singlestep_enabled
)) {
4107 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
4110 if (ctx
->singlestep_enabled
) {
4111 save_cpu_state(ctx
, 0);
4112 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
4118 /* Branches (before delay slot) */
4119 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
4121 int rs
, int rt
, int32_t offset
,
4124 target_ulong btgt
= -1;
4126 int bcond_compute
= 0;
4127 TCGv t0
= tcg_temp_new();
4128 TCGv t1
= tcg_temp_new();
4130 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
4131 #ifdef MIPS_DEBUG_DISAS
4132 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
4134 generate_exception(ctx
, EXCP_RI
);
4138 /* Load needed operands */
4144 /* Compare two registers */
4146 gen_load_gpr(t0
, rs
);
4147 gen_load_gpr(t1
, rt
);
4150 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4164 /* Compare to zero */
4166 gen_load_gpr(t0
, rs
);
4169 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4172 #if defined(TARGET_MIPS64)
4174 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
4176 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
4179 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4184 /* Jump to immediate */
4185 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
4189 /* Jump to register */
4190 if (offset
!= 0 && offset
!= 16) {
4191 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4192 others are reserved. */
4193 MIPS_INVAL("jump hint");
4194 generate_exception(ctx
, EXCP_RI
);
4197 gen_load_gpr(btarget
, rs
);
4200 MIPS_INVAL("branch/jump");
4201 generate_exception(ctx
, EXCP_RI
);
4204 if (bcond_compute
== 0) {
4205 /* No condition to be computed */
4207 case OPC_BEQ
: /* rx == rx */
4208 case OPC_BEQL
: /* rx == rx likely */
4209 case OPC_BGEZ
: /* 0 >= 0 */
4210 case OPC_BGEZL
: /* 0 >= 0 likely */
4211 case OPC_BLEZ
: /* 0 <= 0 */
4212 case OPC_BLEZL
: /* 0 <= 0 likely */
4214 ctx
->hflags
|= MIPS_HFLAG_B
;
4215 MIPS_DEBUG("balways");
4217 case OPC_BGEZAL
: /* 0 >= 0 */
4218 case OPC_BGEZALL
: /* 0 >= 0 likely */
4219 /* Always take and link */
4221 ctx
->hflags
|= MIPS_HFLAG_B
;
4222 MIPS_DEBUG("balways and link");
4224 case OPC_BNE
: /* rx != rx */
4225 case OPC_BGTZ
: /* 0 > 0 */
4226 case OPC_BLTZ
: /* 0 < 0 */
4228 MIPS_DEBUG("bnever (NOP)");
4230 case OPC_BLTZAL
: /* 0 < 0 */
4231 /* Handle as an unconditional branch to get correct delay
4234 btgt
= ctx
->pc
+ insn_bytes
+ delayslot_size
;
4235 ctx
->hflags
|= MIPS_HFLAG_B
;
4236 MIPS_DEBUG("bnever and link");
4238 case OPC_BLTZALL
: /* 0 < 0 likely */
4239 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
4240 /* Skip the instruction in the delay slot */
4241 MIPS_DEBUG("bnever, link and skip");
4244 case OPC_BNEL
: /* rx != rx likely */
4245 case OPC_BGTZL
: /* 0 > 0 likely */
4246 case OPC_BLTZL
: /* 0 < 0 likely */
4247 /* Skip the instruction in the delay slot */
4248 MIPS_DEBUG("bnever and skip");
4252 ctx
->hflags
|= MIPS_HFLAG_B
;
4253 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
4256 ctx
->hflags
|= MIPS_HFLAG_BX
;
4260 ctx
->hflags
|= MIPS_HFLAG_B
;
4261 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
4264 ctx
->hflags
|= MIPS_HFLAG_BR
;
4265 MIPS_DEBUG("jr %s", regnames
[rs
]);
4269 ctx
->hflags
|= MIPS_HFLAG_BR
;
4270 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
4273 MIPS_INVAL("branch/jump");
4274 generate_exception(ctx
, EXCP_RI
);
4280 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4281 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
4282 regnames
[rs
], regnames
[rt
], btgt
);
4285 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4286 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
4287 regnames
[rs
], regnames
[rt
], btgt
);
4290 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4291 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
4292 regnames
[rs
], regnames
[rt
], btgt
);
4295 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4296 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
4297 regnames
[rs
], regnames
[rt
], btgt
);
4300 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4301 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4304 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4305 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4308 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4309 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4313 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4315 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4318 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4319 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4322 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4323 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4326 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4327 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4330 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4331 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4334 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4335 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4338 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4339 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4342 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
4343 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
4345 #if defined(TARGET_MIPS64)
4347 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
4348 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
4352 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4354 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4356 ctx
->hflags
|= MIPS_HFLAG_BC
;
4359 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4361 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4363 ctx
->hflags
|= MIPS_HFLAG_BL
;
4366 MIPS_INVAL("conditional branch/jump");
4367 generate_exception(ctx
, EXCP_RI
);
4371 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
4372 blink
, ctx
->hflags
, btgt
);
4374 ctx
->btarget
= btgt
;
4376 switch (delayslot_size
) {
4378 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
4381 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
4386 int post_delay
= insn_bytes
+ delayslot_size
;
4387 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
4389 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
4393 if (insn_bytes
== 2)
4394 ctx
->hflags
|= MIPS_HFLAG_B16
;
4399 /* special3 bitfield operations */
4400 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
4401 int rs
, int lsb
, int msb
)
4403 TCGv t0
= tcg_temp_new();
4404 TCGv t1
= tcg_temp_new();
4406 gen_load_gpr(t1
, rs
);
4411 tcg_gen_shri_tl(t0
, t1
, lsb
);
4413 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
4415 tcg_gen_ext32s_tl(t0
, t0
);
4418 #if defined(TARGET_MIPS64)
4420 tcg_gen_shri_tl(t0
, t1
, lsb
);
4422 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
4426 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
4427 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4430 tcg_gen_shri_tl(t0
, t1
, lsb
);
4431 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4437 gen_load_gpr(t0
, rt
);
4438 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4439 tcg_gen_ext32s_tl(t0
, t0
);
4441 #if defined(TARGET_MIPS64)
4443 gen_load_gpr(t0
, rt
);
4444 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
4447 gen_load_gpr(t0
, rt
);
4448 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
4451 gen_load_gpr(t0
, rt
);
4452 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4457 MIPS_INVAL("bitops");
4458 generate_exception(ctx
, EXCP_RI
);
4463 gen_store_gpr(t0
, rt
);
4468 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4473 /* If no destination, treat it as a NOP. */
4478 t0
= tcg_temp_new();
4479 gen_load_gpr(t0
, rt
);
4483 TCGv t1
= tcg_temp_new();
4485 tcg_gen_shri_tl(t1
, t0
, 8);
4486 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4487 tcg_gen_shli_tl(t0
, t0
, 8);
4488 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4489 tcg_gen_or_tl(t0
, t0
, t1
);
4491 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4495 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4498 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4500 #if defined(TARGET_MIPS64)
4503 TCGv t1
= tcg_temp_new();
4505 tcg_gen_shri_tl(t1
, t0
, 8);
4506 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4507 tcg_gen_shli_tl(t0
, t0
, 8);
4508 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4509 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4515 TCGv t1
= tcg_temp_new();
4517 tcg_gen_shri_tl(t1
, t0
, 16);
4518 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4519 tcg_gen_shli_tl(t0
, t0
, 16);
4520 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4521 tcg_gen_or_tl(t0
, t0
, t1
);
4522 tcg_gen_shri_tl(t1
, t0
, 32);
4523 tcg_gen_shli_tl(t0
, t0
, 32);
4524 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4530 MIPS_INVAL("bsfhl");
4531 generate_exception(ctx
, EXCP_RI
);
4538 #ifndef CONFIG_USER_ONLY
4539 /* CP0 (MMU and control) */
4540 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4542 TCGv_i32 t0
= tcg_temp_new_i32();
4544 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4545 tcg_gen_ext_i32_tl(arg
, t0
);
4546 tcg_temp_free_i32(t0
);
4549 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4551 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4552 tcg_gen_ext32s_tl(arg
, arg
);
4555 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4557 TCGv_i32 t0
= tcg_temp_new_i32();
4559 tcg_gen_trunc_tl_i32(t0
, arg
);
4560 tcg_gen_st_i32(t0
, cpu_env
, off
);
4561 tcg_temp_free_i32(t0
);
4564 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4566 tcg_gen_ext32s_tl(arg
, arg
);
4567 tcg_gen_st_tl(arg
, cpu_env
, off
);
4570 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4572 const char *rn
= "invalid";
4575 check_insn(ctx
, ISA_MIPS32
);
4581 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4585 check_insn(ctx
, ASE_MT
);
4586 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4590 check_insn(ctx
, ASE_MT
);
4591 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4595 check_insn(ctx
, ASE_MT
);
4596 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4606 gen_helper_mfc0_random(arg
, cpu_env
);
4610 check_insn(ctx
, ASE_MT
);
4611 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4615 check_insn(ctx
, ASE_MT
);
4616 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4620 check_insn(ctx
, ASE_MT
);
4621 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4625 check_insn(ctx
, ASE_MT
);
4626 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4630 check_insn(ctx
, ASE_MT
);
4631 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4635 check_insn(ctx
, ASE_MT
);
4636 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4637 rn
= "VPEScheFBack";
4640 check_insn(ctx
, ASE_MT
);
4641 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4651 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4652 tcg_gen_ext32s_tl(arg
, arg
);
4656 check_insn(ctx
, ASE_MT
);
4657 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4661 check_insn(ctx
, ASE_MT
);
4662 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4666 check_insn(ctx
, ASE_MT
);
4667 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4671 check_insn(ctx
, ASE_MT
);
4672 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4676 check_insn(ctx
, ASE_MT
);
4677 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4681 check_insn(ctx
, ASE_MT
);
4682 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4686 check_insn(ctx
, ASE_MT
);
4687 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4697 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4698 tcg_gen_ext32s_tl(arg
, arg
);
4708 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4709 tcg_gen_ext32s_tl(arg
, arg
);
4713 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4714 rn
= "ContextConfig";
4719 tcg_gen_ld32s_tl(arg
, cpu_env
,
4720 offsetof(CPUMIPSState
,
4721 active_tc
.CP0_UserLocal
));
4724 tcg_gen_movi_tl(arg
, 0);
4734 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4738 check_insn(ctx
, ISA_MIPS32R2
);
4739 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4749 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4753 check_insn(ctx
, ISA_MIPS32R2
);
4754 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4758 check_insn(ctx
, ISA_MIPS32R2
);
4759 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4763 check_insn(ctx
, ISA_MIPS32R2
);
4764 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4768 check_insn(ctx
, ISA_MIPS32R2
);
4769 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4773 check_insn(ctx
, ISA_MIPS32R2
);
4774 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4784 check_insn(ctx
, ISA_MIPS32R2
);
4785 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4795 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4796 tcg_gen_ext32s_tl(arg
, arg
);
4806 /* Mark as an IO operation because we read the time. */
4809 gen_helper_mfc0_count(arg
, cpu_env
);
4813 /* Break the TB to be able to take timer interrupts immediately
4814 after reading count. */
4815 ctx
->bstate
= BS_STOP
;
4818 /* 6,7 are implementation dependent */
4826 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4827 tcg_gen_ext32s_tl(arg
, arg
);
4837 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4840 /* 6,7 are implementation dependent */
4848 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4852 check_insn(ctx
, ISA_MIPS32R2
);
4853 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4857 check_insn(ctx
, ISA_MIPS32R2
);
4858 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4862 check_insn(ctx
, ISA_MIPS32R2
);
4863 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4873 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4883 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4884 tcg_gen_ext32s_tl(arg
, arg
);
4894 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4898 check_insn(ctx
, ISA_MIPS32R2
);
4899 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4909 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4913 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4917 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4921 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4925 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
4929 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
4932 /* 6,7 are implementation dependent */
4934 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4938 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4948 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4958 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4968 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4978 #if defined(TARGET_MIPS64)
4979 check_insn(ctx
, ISA_MIPS3
);
4980 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4981 tcg_gen_ext32s_tl(arg
, arg
);
4990 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4993 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5001 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5002 rn
= "'Diagnostic"; /* implementation dependent */
5007 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5011 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5012 rn
= "TraceControl";
5015 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5016 rn
= "TraceControl2";
5019 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5020 rn
= "UserTraceData";
5023 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5034 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5035 tcg_gen_ext32s_tl(arg
, arg
);
5045 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5046 rn
= "Performance0";
5049 // gen_helper_mfc0_performance1(arg);
5050 rn
= "Performance1";
5053 // gen_helper_mfc0_performance2(arg);
5054 rn
= "Performance2";
5057 // gen_helper_mfc0_performance3(arg);
5058 rn
= "Performance3";
5061 // gen_helper_mfc0_performance4(arg);
5062 rn
= "Performance4";
5065 // gen_helper_mfc0_performance5(arg);
5066 rn
= "Performance5";
5069 // gen_helper_mfc0_performance6(arg);
5070 rn
= "Performance6";
5073 // gen_helper_mfc0_performance7(arg);
5074 rn
= "Performance7";
5081 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5087 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5100 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5107 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5120 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5127 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5137 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5138 tcg_gen_ext32s_tl(arg
, arg
);
5149 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5159 (void)rn
; /* avoid a compiler warning */
5160 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5164 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5165 generate_exception(ctx
, EXCP_RI
);
5168 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5170 const char *rn
= "invalid";
5173 check_insn(ctx
, ISA_MIPS32
);
5182 gen_helper_mtc0_index(cpu_env
, arg
);
5186 check_insn(ctx
, ASE_MT
);
5187 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5191 check_insn(ctx
, ASE_MT
);
5196 check_insn(ctx
, ASE_MT
);
5211 check_insn(ctx
, ASE_MT
);
5212 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5216 check_insn(ctx
, ASE_MT
);
5217 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5221 check_insn(ctx
, ASE_MT
);
5222 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5226 check_insn(ctx
, ASE_MT
);
5227 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5231 check_insn(ctx
, ASE_MT
);
5232 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5236 check_insn(ctx
, ASE_MT
);
5237 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5238 rn
= "VPEScheFBack";
5241 check_insn(ctx
, ASE_MT
);
5242 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5252 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5256 check_insn(ctx
, ASE_MT
);
5257 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5261 check_insn(ctx
, ASE_MT
);
5262 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5266 check_insn(ctx
, ASE_MT
);
5267 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5271 check_insn(ctx
, ASE_MT
);
5272 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5276 check_insn(ctx
, ASE_MT
);
5277 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5281 check_insn(ctx
, ASE_MT
);
5282 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5286 check_insn(ctx
, ASE_MT
);
5287 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5297 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5307 gen_helper_mtc0_context(cpu_env
, arg
);
5311 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5312 rn
= "ContextConfig";
5317 tcg_gen_st_tl(arg
, cpu_env
,
5318 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5329 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5333 check_insn(ctx
, ISA_MIPS32R2
);
5334 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5344 gen_helper_mtc0_wired(cpu_env
, arg
);
5348 check_insn(ctx
, ISA_MIPS32R2
);
5349 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5353 check_insn(ctx
, ISA_MIPS32R2
);
5354 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
5358 check_insn(ctx
, ISA_MIPS32R2
);
5359 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
5363 check_insn(ctx
, ISA_MIPS32R2
);
5364 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
5368 check_insn(ctx
, ISA_MIPS32R2
);
5369 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
5379 check_insn(ctx
, ISA_MIPS32R2
);
5380 gen_helper_mtc0_hwrena(cpu_env
, arg
);
5381 ctx
->bstate
= BS_STOP
;
5395 gen_helper_mtc0_count(cpu_env
, arg
);
5398 /* 6,7 are implementation dependent */
5406 gen_helper_mtc0_entryhi(cpu_env
, arg
);
5416 gen_helper_mtc0_compare(cpu_env
, arg
);
5419 /* 6,7 are implementation dependent */
5427 save_cpu_state(ctx
, 1);
5428 gen_helper_mtc0_status(cpu_env
, arg
);
5429 /* BS_STOP isn't good enough here, hflags may have changed. */
5430 gen_save_pc(ctx
->pc
+ 4);
5431 ctx
->bstate
= BS_EXCP
;
5435 check_insn(ctx
, ISA_MIPS32R2
);
5436 gen_helper_mtc0_intctl(cpu_env
, arg
);
5437 /* Stop translation as we may have switched the execution mode */
5438 ctx
->bstate
= BS_STOP
;
5442 check_insn(ctx
, ISA_MIPS32R2
);
5443 gen_helper_mtc0_srsctl(cpu_env
, arg
);
5444 /* Stop translation as we may have switched the execution mode */
5445 ctx
->bstate
= BS_STOP
;
5449 check_insn(ctx
, ISA_MIPS32R2
);
5450 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5451 /* Stop translation as we may have switched the execution mode */
5452 ctx
->bstate
= BS_STOP
;
5462 save_cpu_state(ctx
, 1);
5463 gen_helper_mtc0_cause(cpu_env
, arg
);
5473 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
5487 check_insn(ctx
, ISA_MIPS32R2
);
5488 gen_helper_mtc0_ebase(cpu_env
, arg
);
5498 gen_helper_mtc0_config0(cpu_env
, arg
);
5500 /* Stop translation as we may have switched the execution mode */
5501 ctx
->bstate
= BS_STOP
;
5504 /* ignored, read only */
5508 gen_helper_mtc0_config2(cpu_env
, arg
);
5510 /* Stop translation as we may have switched the execution mode */
5511 ctx
->bstate
= BS_STOP
;
5514 /* ignored, read only */
5518 gen_helper_mtc0_config4(cpu_env
, arg
);
5520 ctx
->bstate
= BS_STOP
;
5523 gen_helper_mtc0_config5(cpu_env
, arg
);
5525 /* Stop translation as we may have switched the execution mode */
5526 ctx
->bstate
= BS_STOP
;
5528 /* 6,7 are implementation dependent */
5538 rn
= "Invalid config selector";
5545 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5555 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5565 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5575 #if defined(TARGET_MIPS64)
5576 check_insn(ctx
, ISA_MIPS3
);
5577 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5586 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5589 gen_helper_mtc0_framemask(cpu_env
, arg
);
5598 rn
= "Diagnostic"; /* implementation dependent */
5603 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5604 /* BS_STOP isn't good enough here, hflags may have changed. */
5605 gen_save_pc(ctx
->pc
+ 4);
5606 ctx
->bstate
= BS_EXCP
;
5610 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5611 rn
= "TraceControl";
5612 /* Stop translation as we may have switched the execution mode */
5613 ctx
->bstate
= BS_STOP
;
5616 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5617 rn
= "TraceControl2";
5618 /* Stop translation as we may have switched the execution mode */
5619 ctx
->bstate
= BS_STOP
;
5622 /* Stop translation as we may have switched the execution mode */
5623 ctx
->bstate
= BS_STOP
;
5624 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5625 rn
= "UserTraceData";
5626 /* Stop translation as we may have switched the execution mode */
5627 ctx
->bstate
= BS_STOP
;
5630 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5631 /* Stop translation as we may have switched the execution mode */
5632 ctx
->bstate
= BS_STOP
;
5643 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5653 gen_helper_mtc0_performance0(cpu_env
, arg
);
5654 rn
= "Performance0";
5657 // gen_helper_mtc0_performance1(arg);
5658 rn
= "Performance1";
5661 // gen_helper_mtc0_performance2(arg);
5662 rn
= "Performance2";
5665 // gen_helper_mtc0_performance3(arg);
5666 rn
= "Performance3";
5669 // gen_helper_mtc0_performance4(arg);
5670 rn
= "Performance4";
5673 // gen_helper_mtc0_performance5(arg);
5674 rn
= "Performance5";
5677 // gen_helper_mtc0_performance6(arg);
5678 rn
= "Performance6";
5681 // gen_helper_mtc0_performance7(arg);
5682 rn
= "Performance7";
5708 gen_helper_mtc0_taglo(cpu_env
, arg
);
5715 gen_helper_mtc0_datalo(cpu_env
, arg
);
5728 gen_helper_mtc0_taghi(cpu_env
, arg
);
5735 gen_helper_mtc0_datahi(cpu_env
, arg
);
5746 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5757 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5763 /* Stop translation as we may have switched the execution mode */
5764 ctx
->bstate
= BS_STOP
;
5769 (void)rn
; /* avoid a compiler warning */
5770 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5771 /* For simplicity assume that all writes can cause interrupts. */
5774 ctx
->bstate
= BS_STOP
;
5779 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5780 generate_exception(ctx
, EXCP_RI
);
5783 #if defined(TARGET_MIPS64)
5784 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5786 const char *rn
= "invalid";
5789 check_insn(ctx
, ISA_MIPS64
);
5795 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5799 check_insn(ctx
, ASE_MT
);
5800 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5804 check_insn(ctx
, ASE_MT
);
5805 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5809 check_insn(ctx
, ASE_MT
);
5810 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5820 gen_helper_mfc0_random(arg
, cpu_env
);
5824 check_insn(ctx
, ASE_MT
);
5825 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5829 check_insn(ctx
, ASE_MT
);
5830 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5834 check_insn(ctx
, ASE_MT
);
5835 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5839 check_insn(ctx
, ASE_MT
);
5840 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5844 check_insn(ctx
, ASE_MT
);
5845 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5849 check_insn(ctx
, ASE_MT
);
5850 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5851 rn
= "VPEScheFBack";
5854 check_insn(ctx
, ASE_MT
);
5855 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5865 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5869 check_insn(ctx
, ASE_MT
);
5870 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5874 check_insn(ctx
, ASE_MT
);
5875 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5879 check_insn(ctx
, ASE_MT
);
5880 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5884 check_insn(ctx
, ASE_MT
);
5885 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5889 check_insn(ctx
, ASE_MT
);
5890 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5894 check_insn(ctx
, ASE_MT
);
5895 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5899 check_insn(ctx
, ASE_MT
);
5900 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5910 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5920 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5924 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5925 rn
= "ContextConfig";
5930 tcg_gen_ld_tl(arg
, cpu_env
,
5931 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5934 tcg_gen_movi_tl(arg
, 0);
5944 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5948 check_insn(ctx
, ISA_MIPS32R2
);
5949 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5959 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5963 check_insn(ctx
, ISA_MIPS32R2
);
5964 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5968 check_insn(ctx
, ISA_MIPS32R2
);
5969 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5973 check_insn(ctx
, ISA_MIPS32R2
);
5974 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5978 check_insn(ctx
, ISA_MIPS32R2
);
5979 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5983 check_insn(ctx
, ISA_MIPS32R2
);
5984 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5994 check_insn(ctx
, ISA_MIPS32R2
);
5995 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6005 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6015 /* Mark as an IO operation because we read the time. */
6018 gen_helper_mfc0_count(arg
, cpu_env
);
6022 /* Break the TB to be able to take timer interrupts immediately
6023 after reading count. */
6024 ctx
->bstate
= BS_STOP
;
6027 /* 6,7 are implementation dependent */
6035 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6045 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6048 /* 6,7 are implementation dependent */
6056 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6060 check_insn(ctx
, ISA_MIPS32R2
);
6061 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6065 check_insn(ctx
, ISA_MIPS32R2
);
6066 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6070 check_insn(ctx
, ISA_MIPS32R2
);
6071 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6081 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6091 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6101 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6105 check_insn(ctx
, ISA_MIPS32R2
);
6106 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
6116 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6120 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6124 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6128 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6131 /* 6,7 are implementation dependent */
6133 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6137 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6147 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
6157 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
6167 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6177 check_insn(ctx
, ISA_MIPS3
);
6178 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6186 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6189 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6197 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6198 rn
= "'Diagnostic"; /* implementation dependent */
6203 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6207 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6208 rn
= "TraceControl";
6211 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6212 rn
= "TraceControl2";
6215 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6216 rn
= "UserTraceData";
6219 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6230 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6240 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6241 rn
= "Performance0";
6244 // gen_helper_dmfc0_performance1(arg);
6245 rn
= "Performance1";
6248 // gen_helper_dmfc0_performance2(arg);
6249 rn
= "Performance2";
6252 // gen_helper_dmfc0_performance3(arg);
6253 rn
= "Performance3";
6256 // gen_helper_dmfc0_performance4(arg);
6257 rn
= "Performance4";
6260 // gen_helper_dmfc0_performance5(arg);
6261 rn
= "Performance5";
6264 // gen_helper_dmfc0_performance6(arg);
6265 rn
= "Performance6";
6268 // gen_helper_dmfc0_performance7(arg);
6269 rn
= "Performance7";
6276 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6283 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6296 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6303 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6316 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6323 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6333 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6344 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6354 (void)rn
; /* avoid a compiler warning */
6355 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6359 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6360 generate_exception(ctx
, EXCP_RI
);
6363 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6365 const char *rn
= "invalid";
6368 check_insn(ctx
, ISA_MIPS64
);
6377 gen_helper_mtc0_index(cpu_env
, arg
);
6381 check_insn(ctx
, ASE_MT
);
6382 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6386 check_insn(ctx
, ASE_MT
);
6391 check_insn(ctx
, ASE_MT
);
6406 check_insn(ctx
, ASE_MT
);
6407 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6411 check_insn(ctx
, ASE_MT
);
6412 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6416 check_insn(ctx
, ASE_MT
);
6417 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6421 check_insn(ctx
, ASE_MT
);
6422 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6426 check_insn(ctx
, ASE_MT
);
6427 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6431 check_insn(ctx
, ASE_MT
);
6432 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6433 rn
= "VPEScheFBack";
6436 check_insn(ctx
, ASE_MT
);
6437 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6447 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
6451 check_insn(ctx
, ASE_MT
);
6452 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6456 check_insn(ctx
, ASE_MT
);
6457 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6461 check_insn(ctx
, ASE_MT
);
6462 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
6466 check_insn(ctx
, ASE_MT
);
6467 gen_helper_mtc0_tchalt(cpu_env
, arg
);
6471 check_insn(ctx
, ASE_MT
);
6472 gen_helper_mtc0_tccontext(cpu_env
, arg
);
6476 check_insn(ctx
, ASE_MT
);
6477 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
6481 check_insn(ctx
, ASE_MT
);
6482 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6492 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
6502 gen_helper_mtc0_context(cpu_env
, arg
);
6506 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6507 rn
= "ContextConfig";
6512 tcg_gen_st_tl(arg
, cpu_env
,
6513 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6524 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6528 check_insn(ctx
, ISA_MIPS32R2
);
6529 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6539 gen_helper_mtc0_wired(cpu_env
, arg
);
6543 check_insn(ctx
, ISA_MIPS32R2
);
6544 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6548 check_insn(ctx
, ISA_MIPS32R2
);
6549 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6553 check_insn(ctx
, ISA_MIPS32R2
);
6554 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6558 check_insn(ctx
, ISA_MIPS32R2
);
6559 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6563 check_insn(ctx
, ISA_MIPS32R2
);
6564 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6574 check_insn(ctx
, ISA_MIPS32R2
);
6575 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6576 ctx
->bstate
= BS_STOP
;
6590 gen_helper_mtc0_count(cpu_env
, arg
);
6593 /* 6,7 are implementation dependent */
6597 /* Stop translation as we may have switched the execution mode */
6598 ctx
->bstate
= BS_STOP
;
6603 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6613 gen_helper_mtc0_compare(cpu_env
, arg
);
6616 /* 6,7 are implementation dependent */
6620 /* Stop translation as we may have switched the execution mode */
6621 ctx
->bstate
= BS_STOP
;
6626 save_cpu_state(ctx
, 1);
6627 gen_helper_mtc0_status(cpu_env
, arg
);
6628 /* BS_STOP isn't good enough here, hflags may have changed. */
6629 gen_save_pc(ctx
->pc
+ 4);
6630 ctx
->bstate
= BS_EXCP
;
6634 check_insn(ctx
, ISA_MIPS32R2
);
6635 gen_helper_mtc0_intctl(cpu_env
, arg
);
6636 /* Stop translation as we may have switched the execution mode */
6637 ctx
->bstate
= BS_STOP
;
6641 check_insn(ctx
, ISA_MIPS32R2
);
6642 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6643 /* Stop translation as we may have switched the execution mode */
6644 ctx
->bstate
= BS_STOP
;
6648 check_insn(ctx
, ISA_MIPS32R2
);
6649 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6650 /* Stop translation as we may have switched the execution mode */
6651 ctx
->bstate
= BS_STOP
;
6661 save_cpu_state(ctx
, 1);
6662 /* Mark as an IO operation because we may trigger a software
6667 gen_helper_mtc0_cause(cpu_env
, arg
);
6671 /* Stop translation as we may have triggered an intetrupt */
6672 ctx
->bstate
= BS_STOP
;
6682 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6696 check_insn(ctx
, ISA_MIPS32R2
);
6697 gen_helper_mtc0_ebase(cpu_env
, arg
);
6707 gen_helper_mtc0_config0(cpu_env
, arg
);
6709 /* Stop translation as we may have switched the execution mode */
6710 ctx
->bstate
= BS_STOP
;
6713 /* ignored, read only */
6717 gen_helper_mtc0_config2(cpu_env
, arg
);
6719 /* Stop translation as we may have switched the execution mode */
6720 ctx
->bstate
= BS_STOP
;
6726 /* 6,7 are implementation dependent */
6728 rn
= "Invalid config selector";
6735 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6745 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6755 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6765 check_insn(ctx
, ISA_MIPS3
);
6766 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6774 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6777 gen_helper_mtc0_framemask(cpu_env
, arg
);
6786 rn
= "Diagnostic"; /* implementation dependent */
6791 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6792 /* BS_STOP isn't good enough here, hflags may have changed. */
6793 gen_save_pc(ctx
->pc
+ 4);
6794 ctx
->bstate
= BS_EXCP
;
6798 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6799 /* Stop translation as we may have switched the execution mode */
6800 ctx
->bstate
= BS_STOP
;
6801 rn
= "TraceControl";
6804 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6805 /* Stop translation as we may have switched the execution mode */
6806 ctx
->bstate
= BS_STOP
;
6807 rn
= "TraceControl2";
6810 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6811 /* Stop translation as we may have switched the execution mode */
6812 ctx
->bstate
= BS_STOP
;
6813 rn
= "UserTraceData";
6816 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6817 /* Stop translation as we may have switched the execution mode */
6818 ctx
->bstate
= BS_STOP
;
6829 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6839 gen_helper_mtc0_performance0(cpu_env
, arg
);
6840 rn
= "Performance0";
6843 // gen_helper_mtc0_performance1(cpu_env, arg);
6844 rn
= "Performance1";
6847 // gen_helper_mtc0_performance2(cpu_env, arg);
6848 rn
= "Performance2";
6851 // gen_helper_mtc0_performance3(cpu_env, arg);
6852 rn
= "Performance3";
6855 // gen_helper_mtc0_performance4(cpu_env, arg);
6856 rn
= "Performance4";
6859 // gen_helper_mtc0_performance5(cpu_env, arg);
6860 rn
= "Performance5";
6863 // gen_helper_mtc0_performance6(cpu_env, arg);
6864 rn
= "Performance6";
6867 // gen_helper_mtc0_performance7(cpu_env, arg);
6868 rn
= "Performance7";
6894 gen_helper_mtc0_taglo(cpu_env
, arg
);
6901 gen_helper_mtc0_datalo(cpu_env
, arg
);
6914 gen_helper_mtc0_taghi(cpu_env
, arg
);
6921 gen_helper_mtc0_datahi(cpu_env
, arg
);
6932 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6943 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6949 /* Stop translation as we may have switched the execution mode */
6950 ctx
->bstate
= BS_STOP
;
6955 (void)rn
; /* avoid a compiler warning */
6956 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6957 /* For simplicity assume that all writes can cause interrupts. */
6960 ctx
->bstate
= BS_STOP
;
6965 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6966 generate_exception(ctx
, EXCP_RI
);
6968 #endif /* TARGET_MIPS64 */
6970 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6971 int u
, int sel
, int h
)
6973 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6974 TCGv t0
= tcg_temp_local_new();
6976 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6977 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6978 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6979 tcg_gen_movi_tl(t0
, -1);
6980 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6981 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6982 tcg_gen_movi_tl(t0
, -1);
6988 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6991 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
7001 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
7004 gen_helper_mftc0_tcbind(t0
, cpu_env
);
7007 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
7010 gen_helper_mftc0_tchalt(t0
, cpu_env
);
7013 gen_helper_mftc0_tccontext(t0
, cpu_env
);
7016 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
7019 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
7022 gen_mfc0(ctx
, t0
, rt
, sel
);
7029 gen_helper_mftc0_entryhi(t0
, cpu_env
);
7032 gen_mfc0(ctx
, t0
, rt
, sel
);
7038 gen_helper_mftc0_status(t0
, cpu_env
);
7041 gen_mfc0(ctx
, t0
, rt
, sel
);
7047 gen_helper_mftc0_cause(t0
, cpu_env
);
7057 gen_helper_mftc0_epc(t0
, cpu_env
);
7067 gen_helper_mftc0_ebase(t0
, cpu_env
);
7077 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
7087 gen_helper_mftc0_debug(t0
, cpu_env
);
7090 gen_mfc0(ctx
, t0
, rt
, sel
);
7095 gen_mfc0(ctx
, t0
, rt
, sel
);
7097 } else switch (sel
) {
7098 /* GPR registers. */
7100 gen_helper_1e0i(mftgpr
, t0
, rt
);
7102 /* Auxiliary CPU registers */
7106 gen_helper_1e0i(mftlo
, t0
, 0);
7109 gen_helper_1e0i(mfthi
, t0
, 0);
7112 gen_helper_1e0i(mftacx
, t0
, 0);
7115 gen_helper_1e0i(mftlo
, t0
, 1);
7118 gen_helper_1e0i(mfthi
, t0
, 1);
7121 gen_helper_1e0i(mftacx
, t0
, 1);
7124 gen_helper_1e0i(mftlo
, t0
, 2);
7127 gen_helper_1e0i(mfthi
, t0
, 2);
7130 gen_helper_1e0i(mftacx
, t0
, 2);
7133 gen_helper_1e0i(mftlo
, t0
, 3);
7136 gen_helper_1e0i(mfthi
, t0
, 3);
7139 gen_helper_1e0i(mftacx
, t0
, 3);
7142 gen_helper_mftdsp(t0
, cpu_env
);
7148 /* Floating point (COP1). */
7150 /* XXX: For now we support only a single FPU context. */
7152 TCGv_i32 fp0
= tcg_temp_new_i32();
7154 gen_load_fpr32(fp0
, rt
);
7155 tcg_gen_ext_i32_tl(t0
, fp0
);
7156 tcg_temp_free_i32(fp0
);
7158 TCGv_i32 fp0
= tcg_temp_new_i32();
7160 gen_load_fpr32h(ctx
, fp0
, rt
);
7161 tcg_gen_ext_i32_tl(t0
, fp0
);
7162 tcg_temp_free_i32(fp0
);
7166 /* XXX: For now we support only a single FPU context. */
7167 gen_helper_1e0i(cfc1
, t0
, rt
);
7169 /* COP2: Not implemented. */
7176 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7177 gen_store_gpr(t0
, rd
);
7183 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7184 generate_exception(ctx
, EXCP_RI
);
7187 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
7188 int u
, int sel
, int h
)
7190 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7191 TCGv t0
= tcg_temp_local_new();
7193 gen_load_gpr(t0
, rt
);
7194 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7195 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7196 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7198 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7199 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7206 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
7209 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
7219 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
7222 gen_helper_mttc0_tcbind(cpu_env
, t0
);
7225 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
7228 gen_helper_mttc0_tchalt(cpu_env
, t0
);
7231 gen_helper_mttc0_tccontext(cpu_env
, t0
);
7234 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
7237 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
7240 gen_mtc0(ctx
, t0
, rd
, sel
);
7247 gen_helper_mttc0_entryhi(cpu_env
, t0
);
7250 gen_mtc0(ctx
, t0
, rd
, sel
);
7256 gen_helper_mttc0_status(cpu_env
, t0
);
7259 gen_mtc0(ctx
, t0
, rd
, sel
);
7265 gen_helper_mttc0_cause(cpu_env
, t0
);
7275 gen_helper_mttc0_ebase(cpu_env
, t0
);
7285 gen_helper_mttc0_debug(cpu_env
, t0
);
7288 gen_mtc0(ctx
, t0
, rd
, sel
);
7293 gen_mtc0(ctx
, t0
, rd
, sel
);
7295 } else switch (sel
) {
7296 /* GPR registers. */
7298 gen_helper_0e1i(mttgpr
, t0
, rd
);
7300 /* Auxiliary CPU registers */
7304 gen_helper_0e1i(mttlo
, t0
, 0);
7307 gen_helper_0e1i(mtthi
, t0
, 0);
7310 gen_helper_0e1i(mttacx
, t0
, 0);
7313 gen_helper_0e1i(mttlo
, t0
, 1);
7316 gen_helper_0e1i(mtthi
, t0
, 1);
7319 gen_helper_0e1i(mttacx
, t0
, 1);
7322 gen_helper_0e1i(mttlo
, t0
, 2);
7325 gen_helper_0e1i(mtthi
, t0
, 2);
7328 gen_helper_0e1i(mttacx
, t0
, 2);
7331 gen_helper_0e1i(mttlo
, t0
, 3);
7334 gen_helper_0e1i(mtthi
, t0
, 3);
7337 gen_helper_0e1i(mttacx
, t0
, 3);
7340 gen_helper_mttdsp(cpu_env
, t0
);
7346 /* Floating point (COP1). */
7348 /* XXX: For now we support only a single FPU context. */
7350 TCGv_i32 fp0
= tcg_temp_new_i32();
7352 tcg_gen_trunc_tl_i32(fp0
, t0
);
7353 gen_store_fpr32(fp0
, rd
);
7354 tcg_temp_free_i32(fp0
);
7356 TCGv_i32 fp0
= tcg_temp_new_i32();
7358 tcg_gen_trunc_tl_i32(fp0
, t0
);
7359 gen_store_fpr32h(ctx
, fp0
, rd
);
7360 tcg_temp_free_i32(fp0
);
7364 /* XXX: For now we support only a single FPU context. */
7366 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
7368 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7369 tcg_temp_free_i32(fs_tmp
);
7372 /* COP2: Not implemented. */
7379 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
7385 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
7386 generate_exception(ctx
, EXCP_RI
);
7389 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
7391 const char *opn
= "ldst";
7393 check_cp0_enabled(ctx
);
7400 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
7405 TCGv t0
= tcg_temp_new();
7407 gen_load_gpr(t0
, rt
);
7408 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
7413 #if defined(TARGET_MIPS64)
7415 check_insn(ctx
, ISA_MIPS3
);
7420 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
7424 check_insn(ctx
, ISA_MIPS3
);
7426 TCGv t0
= tcg_temp_new();
7428 gen_load_gpr(t0
, rt
);
7429 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
7436 check_insn(ctx
, ASE_MT
);
7441 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
7442 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
7446 check_insn(ctx
, ASE_MT
);
7447 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
7448 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
7453 if (!env
->tlb
->helper_tlbwi
)
7455 gen_helper_tlbwi(cpu_env
);
7459 if (!env
->tlb
->helper_tlbwr
)
7461 gen_helper_tlbwr(cpu_env
);
7465 if (!env
->tlb
->helper_tlbp
)
7467 gen_helper_tlbp(cpu_env
);
7471 if (!env
->tlb
->helper_tlbr
)
7473 gen_helper_tlbr(cpu_env
);
7477 check_insn(ctx
, ISA_MIPS2
);
7478 gen_helper_eret(cpu_env
);
7479 ctx
->bstate
= BS_EXCP
;
7483 check_insn(ctx
, ISA_MIPS32
);
7484 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
7486 generate_exception(ctx
, EXCP_RI
);
7488 gen_helper_deret(cpu_env
);
7489 ctx
->bstate
= BS_EXCP
;
7494 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
7495 /* If we get an exception, we want to restart at next instruction */
7497 save_cpu_state(ctx
, 1);
7499 gen_helper_wait(cpu_env
);
7500 ctx
->bstate
= BS_EXCP
;
7505 generate_exception(ctx
, EXCP_RI
);
7508 (void)opn
; /* avoid a compiler warning */
7509 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
7511 #endif /* !CONFIG_USER_ONLY */
7513 /* CP1 Branches (before delay slot) */
7514 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
7515 int32_t cc
, int32_t offset
)
7517 target_ulong btarget
;
7518 const char *opn
= "cp1 cond branch";
7519 TCGv_i32 t0
= tcg_temp_new_i32();
7522 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
7524 btarget
= ctx
->pc
+ 4 + offset
;
7528 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7529 tcg_gen_not_i32(t0
, t0
);
7530 tcg_gen_andi_i32(t0
, t0
, 1);
7531 tcg_gen_extu_i32_tl(bcond
, t0
);
7535 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7536 tcg_gen_not_i32(t0
, t0
);
7537 tcg_gen_andi_i32(t0
, t0
, 1);
7538 tcg_gen_extu_i32_tl(bcond
, t0
);
7542 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7543 tcg_gen_andi_i32(t0
, t0
, 1);
7544 tcg_gen_extu_i32_tl(bcond
, t0
);
7548 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7549 tcg_gen_andi_i32(t0
, t0
, 1);
7550 tcg_gen_extu_i32_tl(bcond
, t0
);
7553 ctx
->hflags
|= MIPS_HFLAG_BL
;
7557 TCGv_i32 t1
= tcg_temp_new_i32();
7558 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7559 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7560 tcg_gen_nand_i32(t0
, t0
, t1
);
7561 tcg_temp_free_i32(t1
);
7562 tcg_gen_andi_i32(t0
, t0
, 1);
7563 tcg_gen_extu_i32_tl(bcond
, t0
);
7569 TCGv_i32 t1
= tcg_temp_new_i32();
7570 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7571 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7572 tcg_gen_or_i32(t0
, t0
, t1
);
7573 tcg_temp_free_i32(t1
);
7574 tcg_gen_andi_i32(t0
, t0
, 1);
7575 tcg_gen_extu_i32_tl(bcond
, t0
);
7581 TCGv_i32 t1
= tcg_temp_new_i32();
7582 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7583 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7584 tcg_gen_and_i32(t0
, t0
, t1
);
7585 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7586 tcg_gen_and_i32(t0
, t0
, t1
);
7587 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7588 tcg_gen_nand_i32(t0
, t0
, t1
);
7589 tcg_temp_free_i32(t1
);
7590 tcg_gen_andi_i32(t0
, t0
, 1);
7591 tcg_gen_extu_i32_tl(bcond
, t0
);
7597 TCGv_i32 t1
= tcg_temp_new_i32();
7598 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7599 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7600 tcg_gen_or_i32(t0
, t0
, t1
);
7601 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7602 tcg_gen_or_i32(t0
, t0
, t1
);
7603 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7604 tcg_gen_or_i32(t0
, t0
, t1
);
7605 tcg_temp_free_i32(t1
);
7606 tcg_gen_andi_i32(t0
, t0
, 1);
7607 tcg_gen_extu_i32_tl(bcond
, t0
);
7611 ctx
->hflags
|= MIPS_HFLAG_BC
;
7615 generate_exception (ctx
, EXCP_RI
);
7618 (void)opn
; /* avoid a compiler warning */
7619 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7620 ctx
->hflags
, btarget
);
7621 ctx
->btarget
= btarget
;
7622 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
7624 tcg_temp_free_i32(t0
);
7627 /* R6 CP1 Branches */
7628 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
7629 int32_t ft
, int32_t offset
)
7631 target_ulong btarget
;
7632 const char *opn
= "cp1 cond branch";
7633 TCGv_i64 t0
= tcg_temp_new_i64();
7635 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
7636 #ifdef MIPS_DEBUG_DISAS
7637 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
7639 generate_exception(ctx
, EXCP_RI
);
7643 gen_load_fpr64(ctx
, t0
, ft
);
7644 tcg_gen_andi_i64(t0
, t0
, 1);
7646 btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
7650 tcg_gen_xori_i64(t0
, t0
, 1);
7652 ctx
->hflags
|= MIPS_HFLAG_BC
;
7655 /* t0 already set */
7657 ctx
->hflags
|= MIPS_HFLAG_BC
;
7661 generate_exception(ctx
, EXCP_RI
);
7665 tcg_gen_trunc_i64_tl(bcond
, t0
);
7667 (void)opn
; /* avoid a compiler warning */
7668 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7669 ctx
->hflags
, btarget
);
7670 ctx
->btarget
= btarget
;
7673 tcg_temp_free_i64(t0
);
7676 /* Coprocessor 1 (FPU) */
7678 #define FOP(func, fmt) (((fmt) << 21) | (func))
7681 OPC_ADD_S
= FOP(0, FMT_S
),
7682 OPC_SUB_S
= FOP(1, FMT_S
),
7683 OPC_MUL_S
= FOP(2, FMT_S
),
7684 OPC_DIV_S
= FOP(3, FMT_S
),
7685 OPC_SQRT_S
= FOP(4, FMT_S
),
7686 OPC_ABS_S
= FOP(5, FMT_S
),
7687 OPC_MOV_S
= FOP(6, FMT_S
),
7688 OPC_NEG_S
= FOP(7, FMT_S
),
7689 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7690 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7691 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7692 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7693 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7694 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7695 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7696 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7697 OPC_SEL_S
= FOP(16, FMT_S
),
7698 OPC_MOVCF_S
= FOP(17, FMT_S
),
7699 OPC_MOVZ_S
= FOP(18, FMT_S
),
7700 OPC_MOVN_S
= FOP(19, FMT_S
),
7701 OPC_SELEQZ_S
= FOP(20, FMT_S
),
7702 OPC_RECIP_S
= FOP(21, FMT_S
),
7703 OPC_RSQRT_S
= FOP(22, FMT_S
),
7704 OPC_SELNEZ_S
= FOP(23, FMT_S
),
7705 OPC_MADDF_S
= FOP(24, FMT_S
),
7706 OPC_MSUBF_S
= FOP(25, FMT_S
),
7707 OPC_RINT_S
= FOP(26, FMT_S
),
7708 OPC_CLASS_S
= FOP(27, FMT_S
),
7709 OPC_MIN_S
= FOP(28, FMT_S
),
7710 OPC_RECIP2_S
= FOP(28, FMT_S
),
7711 OPC_MINA_S
= FOP(29, FMT_S
),
7712 OPC_RECIP1_S
= FOP(29, FMT_S
),
7713 OPC_MAX_S
= FOP(30, FMT_S
),
7714 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7715 OPC_MAXA_S
= FOP(31, FMT_S
),
7716 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7717 OPC_CVT_D_S
= FOP(33, FMT_S
),
7718 OPC_CVT_W_S
= FOP(36, FMT_S
),
7719 OPC_CVT_L_S
= FOP(37, FMT_S
),
7720 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7721 OPC_CMP_F_S
= FOP (48, FMT_S
),
7722 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7723 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7724 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7725 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7726 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7727 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7728 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7729 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7730 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7731 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7732 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7733 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7734 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7735 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7736 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7738 OPC_ADD_D
= FOP(0, FMT_D
),
7739 OPC_SUB_D
= FOP(1, FMT_D
),
7740 OPC_MUL_D
= FOP(2, FMT_D
),
7741 OPC_DIV_D
= FOP(3, FMT_D
),
7742 OPC_SQRT_D
= FOP(4, FMT_D
),
7743 OPC_ABS_D
= FOP(5, FMT_D
),
7744 OPC_MOV_D
= FOP(6, FMT_D
),
7745 OPC_NEG_D
= FOP(7, FMT_D
),
7746 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7747 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7748 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7749 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7750 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7751 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7752 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7753 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7754 OPC_SEL_D
= FOP(16, FMT_D
),
7755 OPC_MOVCF_D
= FOP(17, FMT_D
),
7756 OPC_MOVZ_D
= FOP(18, FMT_D
),
7757 OPC_MOVN_D
= FOP(19, FMT_D
),
7758 OPC_SELEQZ_D
= FOP(20, FMT_D
),
7759 OPC_RECIP_D
= FOP(21, FMT_D
),
7760 OPC_RSQRT_D
= FOP(22, FMT_D
),
7761 OPC_SELNEZ_D
= FOP(23, FMT_D
),
7762 OPC_MADDF_D
= FOP(24, FMT_D
),
7763 OPC_MSUBF_D
= FOP(25, FMT_D
),
7764 OPC_RINT_D
= FOP(26, FMT_D
),
7765 OPC_CLASS_D
= FOP(27, FMT_D
),
7766 OPC_MIN_D
= FOP(28, FMT_D
),
7767 OPC_RECIP2_D
= FOP(28, FMT_D
),
7768 OPC_MINA_D
= FOP(29, FMT_D
),
7769 OPC_RECIP1_D
= FOP(29, FMT_D
),
7770 OPC_MAX_D
= FOP(30, FMT_D
),
7771 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7772 OPC_MAXA_D
= FOP(31, FMT_D
),
7773 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7774 OPC_CVT_S_D
= FOP(32, FMT_D
),
7775 OPC_CVT_W_D
= FOP(36, FMT_D
),
7776 OPC_CVT_L_D
= FOP(37, FMT_D
),
7777 OPC_CMP_F_D
= FOP (48, FMT_D
),
7778 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7779 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7780 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7781 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7782 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7783 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7784 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7785 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7786 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7787 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7788 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7789 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7790 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7791 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7792 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7794 OPC_CVT_S_W
= FOP(32, FMT_W
),
7795 OPC_CVT_D_W
= FOP(33, FMT_W
),
7796 OPC_CVT_S_L
= FOP(32, FMT_L
),
7797 OPC_CVT_D_L
= FOP(33, FMT_L
),
7798 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7800 OPC_ADD_PS
= FOP(0, FMT_PS
),
7801 OPC_SUB_PS
= FOP(1, FMT_PS
),
7802 OPC_MUL_PS
= FOP(2, FMT_PS
),
7803 OPC_DIV_PS
= FOP(3, FMT_PS
),
7804 OPC_ABS_PS
= FOP(5, FMT_PS
),
7805 OPC_MOV_PS
= FOP(6, FMT_PS
),
7806 OPC_NEG_PS
= FOP(7, FMT_PS
),
7807 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7808 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7809 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7810 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7811 OPC_MULR_PS
= FOP(26, FMT_PS
),
7812 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7813 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7814 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7815 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7817 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7818 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7819 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7820 OPC_PLL_PS
= FOP(44, FMT_PS
),
7821 OPC_PLU_PS
= FOP(45, FMT_PS
),
7822 OPC_PUL_PS
= FOP(46, FMT_PS
),
7823 OPC_PUU_PS
= FOP(47, FMT_PS
),
7824 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7825 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7826 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7827 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7828 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7829 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7830 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7831 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7832 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7833 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7834 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7835 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7836 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7837 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7838 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7839 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7843 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
7844 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
7845 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
7846 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
7847 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
7848 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
7849 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
7850 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
7851 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
7852 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
7853 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
7854 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
7855 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
7856 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
7857 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
7858 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
7859 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
7860 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
7861 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
7862 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
7863 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
7864 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
7866 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
7867 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
7868 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
7869 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
7870 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
7871 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
7872 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
7873 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
7874 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
7875 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
7876 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
7877 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
7878 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
7879 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
7880 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
7881 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
7882 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
7883 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
7884 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
7885 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
7886 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
7887 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
7889 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7891 const char *opn
= "cp1 move";
7892 TCGv t0
= tcg_temp_new();
7897 TCGv_i32 fp0
= tcg_temp_new_i32();
7899 gen_load_fpr32(fp0
, fs
);
7900 tcg_gen_ext_i32_tl(t0
, fp0
);
7901 tcg_temp_free_i32(fp0
);
7903 gen_store_gpr(t0
, rt
);
7907 gen_load_gpr(t0
, rt
);
7909 TCGv_i32 fp0
= tcg_temp_new_i32();
7911 tcg_gen_trunc_tl_i32(fp0
, t0
);
7912 gen_store_fpr32(fp0
, fs
);
7913 tcg_temp_free_i32(fp0
);
7918 gen_helper_1e0i(cfc1
, t0
, fs
);
7919 gen_store_gpr(t0
, rt
);
7923 gen_load_gpr(t0
, rt
);
7925 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
7927 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7928 tcg_temp_free_i32(fs_tmp
);
7932 #if defined(TARGET_MIPS64)
7934 gen_load_fpr64(ctx
, t0
, fs
);
7935 gen_store_gpr(t0
, rt
);
7939 gen_load_gpr(t0
, rt
);
7940 gen_store_fpr64(ctx
, t0
, fs
);
7946 TCGv_i32 fp0
= tcg_temp_new_i32();
7948 gen_load_fpr32h(ctx
, fp0
, fs
);
7949 tcg_gen_ext_i32_tl(t0
, fp0
);
7950 tcg_temp_free_i32(fp0
);
7952 gen_store_gpr(t0
, rt
);
7956 gen_load_gpr(t0
, rt
);
7958 TCGv_i32 fp0
= tcg_temp_new_i32();
7960 tcg_gen_trunc_tl_i32(fp0
, t0
);
7961 gen_store_fpr32h(ctx
, fp0
, fs
);
7962 tcg_temp_free_i32(fp0
);
7968 generate_exception (ctx
, EXCP_RI
);
7971 (void)opn
; /* avoid a compiler warning */
7972 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7978 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7994 l1
= gen_new_label();
7995 t0
= tcg_temp_new_i32();
7996 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7997 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7998 tcg_temp_free_i32(t0
);
8000 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
8002 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
8007 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
8010 TCGv_i32 t0
= tcg_temp_new_i32();
8011 int l1
= gen_new_label();
8018 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8019 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8020 gen_load_fpr32(t0
, fs
);
8021 gen_store_fpr32(t0
, fd
);
8023 tcg_temp_free_i32(t0
);
8026 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
8029 TCGv_i32 t0
= tcg_temp_new_i32();
8031 int l1
= gen_new_label();
8038 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8039 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8040 tcg_temp_free_i32(t0
);
8041 fp0
= tcg_temp_new_i64();
8042 gen_load_fpr64(ctx
, fp0
, fs
);
8043 gen_store_fpr64(ctx
, fp0
, fd
);
8044 tcg_temp_free_i64(fp0
);
8048 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
8052 TCGv_i32 t0
= tcg_temp_new_i32();
8053 int l1
= gen_new_label();
8054 int l2
= gen_new_label();
8061 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8062 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8063 gen_load_fpr32(t0
, fs
);
8064 gen_store_fpr32(t0
, fd
);
8067 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
8068 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
8069 gen_load_fpr32h(ctx
, t0
, fs
);
8070 gen_store_fpr32h(ctx
, t0
, fd
);
8071 tcg_temp_free_i32(t0
);
8075 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8078 TCGv_i32 t1
= tcg_const_i32(0);
8079 TCGv_i32 fp0
= tcg_temp_new_i32();
8080 TCGv_i32 fp1
= tcg_temp_new_i32();
8081 TCGv_i32 fp2
= tcg_temp_new_i32();
8082 gen_load_fpr32(fp0
, fd
);
8083 gen_load_fpr32(fp1
, ft
);
8084 gen_load_fpr32(fp2
, fs
);
8088 tcg_gen_andi_i32(fp0
, fp0
, 1);
8089 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8092 tcg_gen_andi_i32(fp1
, fp1
, 1);
8093 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8096 tcg_gen_andi_i32(fp1
, fp1
, 1);
8097 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8100 MIPS_INVAL("gen_sel_s");
8101 generate_exception (ctx
, EXCP_RI
);
8105 gen_store_fpr32(fp0
, fd
);
8106 tcg_temp_free_i32(fp2
);
8107 tcg_temp_free_i32(fp1
);
8108 tcg_temp_free_i32(fp0
);
8109 tcg_temp_free_i32(t1
);
8112 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8115 TCGv_i64 t1
= tcg_const_i64(0);
8116 TCGv_i64 fp0
= tcg_temp_new_i64();
8117 TCGv_i64 fp1
= tcg_temp_new_i64();
8118 TCGv_i64 fp2
= tcg_temp_new_i64();
8119 gen_load_fpr64(ctx
, fp0
, fd
);
8120 gen_load_fpr64(ctx
, fp1
, ft
);
8121 gen_load_fpr64(ctx
, fp2
, fs
);
8125 tcg_gen_andi_i64(fp0
, fp0
, 1);
8126 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8129 tcg_gen_andi_i64(fp1
, fp1
, 1);
8130 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8133 tcg_gen_andi_i64(fp1
, fp1
, 1);
8134 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8137 MIPS_INVAL("gen_sel_d");
8138 generate_exception (ctx
, EXCP_RI
);
8142 gen_store_fpr64(ctx
, fp0
, fd
);
8143 tcg_temp_free_i64(fp2
);
8144 tcg_temp_free_i64(fp1
);
8145 tcg_temp_free_i64(fp0
);
8146 tcg_temp_free_i64(t1
);
8149 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
8150 int ft
, int fs
, int fd
, int cc
)
8152 const char *opn
= "farith";
8153 const char *condnames
[] = {
8171 const char *condnames_abs
[] = {
8189 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
8190 uint32_t func
= ctx
->opcode
& 0x3f;
8195 TCGv_i32 fp0
= tcg_temp_new_i32();
8196 TCGv_i32 fp1
= tcg_temp_new_i32();
8198 gen_load_fpr32(fp0
, fs
);
8199 gen_load_fpr32(fp1
, ft
);
8200 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
8201 tcg_temp_free_i32(fp1
);
8202 gen_store_fpr32(fp0
, fd
);
8203 tcg_temp_free_i32(fp0
);
8210 TCGv_i32 fp0
= tcg_temp_new_i32();
8211 TCGv_i32 fp1
= tcg_temp_new_i32();
8213 gen_load_fpr32(fp0
, fs
);
8214 gen_load_fpr32(fp1
, ft
);
8215 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
8216 tcg_temp_free_i32(fp1
);
8217 gen_store_fpr32(fp0
, fd
);
8218 tcg_temp_free_i32(fp0
);
8225 TCGv_i32 fp0
= tcg_temp_new_i32();
8226 TCGv_i32 fp1
= tcg_temp_new_i32();
8228 gen_load_fpr32(fp0
, fs
);
8229 gen_load_fpr32(fp1
, ft
);
8230 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
8231 tcg_temp_free_i32(fp1
);
8232 gen_store_fpr32(fp0
, fd
);
8233 tcg_temp_free_i32(fp0
);
8240 TCGv_i32 fp0
= tcg_temp_new_i32();
8241 TCGv_i32 fp1
= tcg_temp_new_i32();
8243 gen_load_fpr32(fp0
, fs
);
8244 gen_load_fpr32(fp1
, ft
);
8245 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
8246 tcg_temp_free_i32(fp1
);
8247 gen_store_fpr32(fp0
, fd
);
8248 tcg_temp_free_i32(fp0
);
8255 TCGv_i32 fp0
= tcg_temp_new_i32();
8257 gen_load_fpr32(fp0
, fs
);
8258 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
8259 gen_store_fpr32(fp0
, fd
);
8260 tcg_temp_free_i32(fp0
);
8266 TCGv_i32 fp0
= tcg_temp_new_i32();
8268 gen_load_fpr32(fp0
, fs
);
8269 gen_helper_float_abs_s(fp0
, fp0
);
8270 gen_store_fpr32(fp0
, fd
);
8271 tcg_temp_free_i32(fp0
);
8277 TCGv_i32 fp0
= tcg_temp_new_i32();
8279 gen_load_fpr32(fp0
, fs
);
8280 gen_store_fpr32(fp0
, fd
);
8281 tcg_temp_free_i32(fp0
);
8287 TCGv_i32 fp0
= tcg_temp_new_i32();
8289 gen_load_fpr32(fp0
, fs
);
8290 gen_helper_float_chs_s(fp0
, fp0
);
8291 gen_store_fpr32(fp0
, fd
);
8292 tcg_temp_free_i32(fp0
);
8297 check_cp1_64bitmode(ctx
);
8299 TCGv_i32 fp32
= tcg_temp_new_i32();
8300 TCGv_i64 fp64
= tcg_temp_new_i64();
8302 gen_load_fpr32(fp32
, fs
);
8303 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
8304 tcg_temp_free_i32(fp32
);
8305 gen_store_fpr64(ctx
, fp64
, fd
);
8306 tcg_temp_free_i64(fp64
);
8311 check_cp1_64bitmode(ctx
);
8313 TCGv_i32 fp32
= tcg_temp_new_i32();
8314 TCGv_i64 fp64
= tcg_temp_new_i64();
8316 gen_load_fpr32(fp32
, fs
);
8317 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
8318 tcg_temp_free_i32(fp32
);
8319 gen_store_fpr64(ctx
, fp64
, fd
);
8320 tcg_temp_free_i64(fp64
);
8325 check_cp1_64bitmode(ctx
);
8327 TCGv_i32 fp32
= tcg_temp_new_i32();
8328 TCGv_i64 fp64
= tcg_temp_new_i64();
8330 gen_load_fpr32(fp32
, fs
);
8331 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
8332 tcg_temp_free_i32(fp32
);
8333 gen_store_fpr64(ctx
, fp64
, fd
);
8334 tcg_temp_free_i64(fp64
);
8339 check_cp1_64bitmode(ctx
);
8341 TCGv_i32 fp32
= tcg_temp_new_i32();
8342 TCGv_i64 fp64
= tcg_temp_new_i64();
8344 gen_load_fpr32(fp32
, fs
);
8345 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
8346 tcg_temp_free_i32(fp32
);
8347 gen_store_fpr64(ctx
, fp64
, fd
);
8348 tcg_temp_free_i64(fp64
);
8354 TCGv_i32 fp0
= tcg_temp_new_i32();
8356 gen_load_fpr32(fp0
, fs
);
8357 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
8358 gen_store_fpr32(fp0
, fd
);
8359 tcg_temp_free_i32(fp0
);
8365 TCGv_i32 fp0
= tcg_temp_new_i32();
8367 gen_load_fpr32(fp0
, fs
);
8368 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
8369 gen_store_fpr32(fp0
, fd
);
8370 tcg_temp_free_i32(fp0
);
8376 TCGv_i32 fp0
= tcg_temp_new_i32();
8378 gen_load_fpr32(fp0
, fs
);
8379 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
8380 gen_store_fpr32(fp0
, fd
);
8381 tcg_temp_free_i32(fp0
);
8387 TCGv_i32 fp0
= tcg_temp_new_i32();
8389 gen_load_fpr32(fp0
, fs
);
8390 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
8391 gen_store_fpr32(fp0
, fd
);
8392 tcg_temp_free_i32(fp0
);
8397 check_insn(ctx
, ISA_MIPS32R6
);
8398 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8402 check_insn(ctx
, ISA_MIPS32R6
);
8403 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8407 check_insn(ctx
, ISA_MIPS32R6
);
8408 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8412 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8413 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8417 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8419 int l1
= gen_new_label();
8423 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8425 fp0
= tcg_temp_new_i32();
8426 gen_load_fpr32(fp0
, fs
);
8427 gen_store_fpr32(fp0
, fd
);
8428 tcg_temp_free_i32(fp0
);
8434 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8436 int l1
= gen_new_label();
8440 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8441 fp0
= tcg_temp_new_i32();
8442 gen_load_fpr32(fp0
, fs
);
8443 gen_store_fpr32(fp0
, fd
);
8444 tcg_temp_free_i32(fp0
);
8453 TCGv_i32 fp0
= tcg_temp_new_i32();
8455 gen_load_fpr32(fp0
, fs
);
8456 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
8457 gen_store_fpr32(fp0
, fd
);
8458 tcg_temp_free_i32(fp0
);
8465 TCGv_i32 fp0
= tcg_temp_new_i32();
8467 gen_load_fpr32(fp0
, fs
);
8468 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
8469 gen_store_fpr32(fp0
, fd
);
8470 tcg_temp_free_i32(fp0
);
8475 check_insn(ctx
, ISA_MIPS32R6
);
8477 TCGv_i32 fp0
= tcg_temp_new_i32();
8478 TCGv_i32 fp1
= tcg_temp_new_i32();
8479 TCGv_i32 fp2
= tcg_temp_new_i32();
8480 gen_load_fpr32(fp0
, fs
);
8481 gen_load_fpr32(fp1
, ft
);
8482 gen_load_fpr32(fp2
, fd
);
8483 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8484 gen_store_fpr32(fp2
, fd
);
8485 tcg_temp_free_i32(fp2
);
8486 tcg_temp_free_i32(fp1
);
8487 tcg_temp_free_i32(fp0
);
8492 check_insn(ctx
, ISA_MIPS32R6
);
8494 TCGv_i32 fp0
= tcg_temp_new_i32();
8495 TCGv_i32 fp1
= tcg_temp_new_i32();
8496 TCGv_i32 fp2
= tcg_temp_new_i32();
8497 gen_load_fpr32(fp0
, fs
);
8498 gen_load_fpr32(fp1
, ft
);
8499 gen_load_fpr32(fp2
, fd
);
8500 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8501 gen_store_fpr32(fp2
, fd
);
8502 tcg_temp_free_i32(fp2
);
8503 tcg_temp_free_i32(fp1
);
8504 tcg_temp_free_i32(fp0
);
8509 check_insn(ctx
, ISA_MIPS32R6
);
8511 TCGv_i32 fp0
= tcg_temp_new_i32();
8512 gen_load_fpr32(fp0
, fs
);
8513 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
8514 gen_store_fpr32(fp0
, fd
);
8515 tcg_temp_free_i32(fp0
);
8520 check_insn(ctx
, ISA_MIPS32R6
);
8522 TCGv_i32 fp0
= tcg_temp_new_i32();
8523 gen_load_fpr32(fp0
, fs
);
8524 gen_helper_float_class_s(fp0
, fp0
);
8525 gen_store_fpr32(fp0
, fd
);
8526 tcg_temp_free_i32(fp0
);
8530 case OPC_MIN_S
: /* OPC_RECIP2_S */
8531 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8533 TCGv_i32 fp0
= tcg_temp_new_i32();
8534 TCGv_i32 fp1
= tcg_temp_new_i32();
8535 TCGv_i32 fp2
= tcg_temp_new_i32();
8536 gen_load_fpr32(fp0
, fs
);
8537 gen_load_fpr32(fp1
, ft
);
8538 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
8539 gen_store_fpr32(fp2
, fd
);
8540 tcg_temp_free_i32(fp2
);
8541 tcg_temp_free_i32(fp1
);
8542 tcg_temp_free_i32(fp0
);
8546 check_cp1_64bitmode(ctx
);
8548 TCGv_i32 fp0
= tcg_temp_new_i32();
8549 TCGv_i32 fp1
= tcg_temp_new_i32();
8551 gen_load_fpr32(fp0
, fs
);
8552 gen_load_fpr32(fp1
, ft
);
8553 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
8554 tcg_temp_free_i32(fp1
);
8555 gen_store_fpr32(fp0
, fd
);
8556 tcg_temp_free_i32(fp0
);
8561 case OPC_MINA_S
: /* OPC_RECIP1_S */
8562 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8564 TCGv_i32 fp0
= tcg_temp_new_i32();
8565 TCGv_i32 fp1
= tcg_temp_new_i32();
8566 TCGv_i32 fp2
= tcg_temp_new_i32();
8567 gen_load_fpr32(fp0
, fs
);
8568 gen_load_fpr32(fp1
, ft
);
8569 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
8570 gen_store_fpr32(fp2
, fd
);
8571 tcg_temp_free_i32(fp2
);
8572 tcg_temp_free_i32(fp1
);
8573 tcg_temp_free_i32(fp0
);
8577 check_cp1_64bitmode(ctx
);
8579 TCGv_i32 fp0
= tcg_temp_new_i32();
8581 gen_load_fpr32(fp0
, fs
);
8582 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
8583 gen_store_fpr32(fp0
, fd
);
8584 tcg_temp_free_i32(fp0
);
8589 case OPC_MAX_S
: /* OPC_RSQRT1_S */
8590 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8592 TCGv_i32 fp0
= tcg_temp_new_i32();
8593 TCGv_i32 fp1
= tcg_temp_new_i32();
8594 gen_load_fpr32(fp0
, fs
);
8595 gen_load_fpr32(fp1
, ft
);
8596 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
8597 gen_store_fpr32(fp1
, fd
);
8598 tcg_temp_free_i32(fp1
);
8599 tcg_temp_free_i32(fp0
);
8603 check_cp1_64bitmode(ctx
);
8605 TCGv_i32 fp0
= tcg_temp_new_i32();
8607 gen_load_fpr32(fp0
, fs
);
8608 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
8609 gen_store_fpr32(fp0
, fd
);
8610 tcg_temp_free_i32(fp0
);
8615 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
8616 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8618 TCGv_i32 fp0
= tcg_temp_new_i32();
8619 TCGv_i32 fp1
= tcg_temp_new_i32();
8620 gen_load_fpr32(fp0
, fs
);
8621 gen_load_fpr32(fp1
, ft
);
8622 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
8623 gen_store_fpr32(fp1
, fd
);
8624 tcg_temp_free_i32(fp1
);
8625 tcg_temp_free_i32(fp0
);
8629 check_cp1_64bitmode(ctx
);
8631 TCGv_i32 fp0
= tcg_temp_new_i32();
8632 TCGv_i32 fp1
= tcg_temp_new_i32();
8634 gen_load_fpr32(fp0
, fs
);
8635 gen_load_fpr32(fp1
, ft
);
8636 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
8637 tcg_temp_free_i32(fp1
);
8638 gen_store_fpr32(fp0
, fd
);
8639 tcg_temp_free_i32(fp0
);
8645 check_cp1_registers(ctx
, fd
);
8647 TCGv_i32 fp32
= tcg_temp_new_i32();
8648 TCGv_i64 fp64
= tcg_temp_new_i64();
8650 gen_load_fpr32(fp32
, fs
);
8651 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
8652 tcg_temp_free_i32(fp32
);
8653 gen_store_fpr64(ctx
, fp64
, fd
);
8654 tcg_temp_free_i64(fp64
);
8660 TCGv_i32 fp0
= tcg_temp_new_i32();
8662 gen_load_fpr32(fp0
, fs
);
8663 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
8664 gen_store_fpr32(fp0
, fd
);
8665 tcg_temp_free_i32(fp0
);
8670 check_cp1_64bitmode(ctx
);
8672 TCGv_i32 fp32
= tcg_temp_new_i32();
8673 TCGv_i64 fp64
= tcg_temp_new_i64();
8675 gen_load_fpr32(fp32
, fs
);
8676 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
8677 tcg_temp_free_i32(fp32
);
8678 gen_store_fpr64(ctx
, fp64
, fd
);
8679 tcg_temp_free_i64(fp64
);
8684 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8685 check_cp1_64bitmode(ctx
);
8687 TCGv_i64 fp64
= tcg_temp_new_i64();
8688 TCGv_i32 fp32_0
= tcg_temp_new_i32();
8689 TCGv_i32 fp32_1
= tcg_temp_new_i32();
8691 gen_load_fpr32(fp32_0
, fs
);
8692 gen_load_fpr32(fp32_1
, ft
);
8693 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
8694 tcg_temp_free_i32(fp32_1
);
8695 tcg_temp_free_i32(fp32_0
);
8696 gen_store_fpr64(ctx
, fp64
, fd
);
8697 tcg_temp_free_i64(fp64
);
8710 case OPC_CMP_NGLE_S
:
8717 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8718 if (ctx
->opcode
& (1 << 6)) {
8719 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
8720 opn
= condnames_abs
[func
-48];
8722 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
8723 opn
= condnames
[func
-48];
8727 check_cp1_registers(ctx
, fs
| ft
| fd
);
8729 TCGv_i64 fp0
= tcg_temp_new_i64();
8730 TCGv_i64 fp1
= tcg_temp_new_i64();
8732 gen_load_fpr64(ctx
, fp0
, fs
);
8733 gen_load_fpr64(ctx
, fp1
, ft
);
8734 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
8735 tcg_temp_free_i64(fp1
);
8736 gen_store_fpr64(ctx
, fp0
, fd
);
8737 tcg_temp_free_i64(fp0
);
8743 check_cp1_registers(ctx
, fs
| ft
| fd
);
8745 TCGv_i64 fp0
= tcg_temp_new_i64();
8746 TCGv_i64 fp1
= tcg_temp_new_i64();
8748 gen_load_fpr64(ctx
, fp0
, fs
);
8749 gen_load_fpr64(ctx
, fp1
, ft
);
8750 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
8751 tcg_temp_free_i64(fp1
);
8752 gen_store_fpr64(ctx
, fp0
, fd
);
8753 tcg_temp_free_i64(fp0
);
8759 check_cp1_registers(ctx
, fs
| ft
| fd
);
8761 TCGv_i64 fp0
= tcg_temp_new_i64();
8762 TCGv_i64 fp1
= tcg_temp_new_i64();
8764 gen_load_fpr64(ctx
, fp0
, fs
);
8765 gen_load_fpr64(ctx
, fp1
, ft
);
8766 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
8767 tcg_temp_free_i64(fp1
);
8768 gen_store_fpr64(ctx
, fp0
, fd
);
8769 tcg_temp_free_i64(fp0
);
8775 check_cp1_registers(ctx
, fs
| ft
| fd
);
8777 TCGv_i64 fp0
= tcg_temp_new_i64();
8778 TCGv_i64 fp1
= tcg_temp_new_i64();
8780 gen_load_fpr64(ctx
, fp0
, fs
);
8781 gen_load_fpr64(ctx
, fp1
, ft
);
8782 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
8783 tcg_temp_free_i64(fp1
);
8784 gen_store_fpr64(ctx
, fp0
, fd
);
8785 tcg_temp_free_i64(fp0
);
8791 check_cp1_registers(ctx
, fs
| fd
);
8793 TCGv_i64 fp0
= tcg_temp_new_i64();
8795 gen_load_fpr64(ctx
, fp0
, fs
);
8796 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
8797 gen_store_fpr64(ctx
, fp0
, fd
);
8798 tcg_temp_free_i64(fp0
);
8803 check_cp1_registers(ctx
, fs
| fd
);
8805 TCGv_i64 fp0
= tcg_temp_new_i64();
8807 gen_load_fpr64(ctx
, fp0
, fs
);
8808 gen_helper_float_abs_d(fp0
, fp0
);
8809 gen_store_fpr64(ctx
, fp0
, fd
);
8810 tcg_temp_free_i64(fp0
);
8815 check_cp1_registers(ctx
, fs
| fd
);
8817 TCGv_i64 fp0
= tcg_temp_new_i64();
8819 gen_load_fpr64(ctx
, fp0
, fs
);
8820 gen_store_fpr64(ctx
, fp0
, fd
);
8821 tcg_temp_free_i64(fp0
);
8826 check_cp1_registers(ctx
, fs
| fd
);
8828 TCGv_i64 fp0
= tcg_temp_new_i64();
8830 gen_load_fpr64(ctx
, fp0
, fs
);
8831 gen_helper_float_chs_d(fp0
, fp0
);
8832 gen_store_fpr64(ctx
, fp0
, fd
);
8833 tcg_temp_free_i64(fp0
);
8838 check_cp1_64bitmode(ctx
);
8840 TCGv_i64 fp0
= tcg_temp_new_i64();
8842 gen_load_fpr64(ctx
, fp0
, fs
);
8843 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
8844 gen_store_fpr64(ctx
, fp0
, fd
);
8845 tcg_temp_free_i64(fp0
);
8850 check_cp1_64bitmode(ctx
);
8852 TCGv_i64 fp0
= tcg_temp_new_i64();
8854 gen_load_fpr64(ctx
, fp0
, fs
);
8855 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
8856 gen_store_fpr64(ctx
, fp0
, fd
);
8857 tcg_temp_free_i64(fp0
);
8862 check_cp1_64bitmode(ctx
);
8864 TCGv_i64 fp0
= tcg_temp_new_i64();
8866 gen_load_fpr64(ctx
, fp0
, fs
);
8867 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
8868 gen_store_fpr64(ctx
, fp0
, fd
);
8869 tcg_temp_free_i64(fp0
);
8874 check_cp1_64bitmode(ctx
);
8876 TCGv_i64 fp0
= tcg_temp_new_i64();
8878 gen_load_fpr64(ctx
, fp0
, fs
);
8879 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8880 gen_store_fpr64(ctx
, fp0
, fd
);
8881 tcg_temp_free_i64(fp0
);
8886 check_cp1_registers(ctx
, fs
);
8888 TCGv_i32 fp32
= tcg_temp_new_i32();
8889 TCGv_i64 fp64
= tcg_temp_new_i64();
8891 gen_load_fpr64(ctx
, fp64
, fs
);
8892 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8893 tcg_temp_free_i64(fp64
);
8894 gen_store_fpr32(fp32
, fd
);
8895 tcg_temp_free_i32(fp32
);
8900 check_cp1_registers(ctx
, fs
);
8902 TCGv_i32 fp32
= tcg_temp_new_i32();
8903 TCGv_i64 fp64
= tcg_temp_new_i64();
8905 gen_load_fpr64(ctx
, fp64
, fs
);
8906 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8907 tcg_temp_free_i64(fp64
);
8908 gen_store_fpr32(fp32
, fd
);
8909 tcg_temp_free_i32(fp32
);
8914 check_cp1_registers(ctx
, fs
);
8916 TCGv_i32 fp32
= tcg_temp_new_i32();
8917 TCGv_i64 fp64
= tcg_temp_new_i64();
8919 gen_load_fpr64(ctx
, fp64
, fs
);
8920 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8921 tcg_temp_free_i64(fp64
);
8922 gen_store_fpr32(fp32
, fd
);
8923 tcg_temp_free_i32(fp32
);
8928 check_cp1_registers(ctx
, fs
);
8930 TCGv_i32 fp32
= tcg_temp_new_i32();
8931 TCGv_i64 fp64
= tcg_temp_new_i64();
8933 gen_load_fpr64(ctx
, fp64
, fs
);
8934 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8935 tcg_temp_free_i64(fp64
);
8936 gen_store_fpr32(fp32
, fd
);
8937 tcg_temp_free_i32(fp32
);
8942 check_insn(ctx
, ISA_MIPS32R6
);
8943 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
8947 check_insn(ctx
, ISA_MIPS32R6
);
8948 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
8952 check_insn(ctx
, ISA_MIPS32R6
);
8953 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
8957 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8958 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8962 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8964 int l1
= gen_new_label();
8968 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8970 fp0
= tcg_temp_new_i64();
8971 gen_load_fpr64(ctx
, fp0
, fs
);
8972 gen_store_fpr64(ctx
, fp0
, fd
);
8973 tcg_temp_free_i64(fp0
);
8979 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8981 int l1
= gen_new_label();
8985 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8986 fp0
= tcg_temp_new_i64();
8987 gen_load_fpr64(ctx
, fp0
, fs
);
8988 gen_store_fpr64(ctx
, fp0
, fd
);
8989 tcg_temp_free_i64(fp0
);
8996 check_cp1_64bitmode(ctx
);
8998 TCGv_i64 fp0
= tcg_temp_new_i64();
9000 gen_load_fpr64(ctx
, fp0
, fs
);
9001 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
9002 gen_store_fpr64(ctx
, fp0
, fd
);
9003 tcg_temp_free_i64(fp0
);
9008 check_cp1_64bitmode(ctx
);
9010 TCGv_i64 fp0
= tcg_temp_new_i64();
9012 gen_load_fpr64(ctx
, fp0
, fs
);
9013 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
9014 gen_store_fpr64(ctx
, fp0
, fd
);
9015 tcg_temp_free_i64(fp0
);
9020 check_insn(ctx
, ISA_MIPS32R6
);
9022 TCGv_i64 fp0
= tcg_temp_new_i64();
9023 TCGv_i64 fp1
= tcg_temp_new_i64();
9024 TCGv_i64 fp2
= tcg_temp_new_i64();
9025 gen_load_fpr64(ctx
, fp0
, fs
);
9026 gen_load_fpr64(ctx
, fp1
, ft
);
9027 gen_load_fpr64(ctx
, fp2
, fd
);
9028 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9029 gen_store_fpr64(ctx
, fp2
, fd
);
9030 tcg_temp_free_i64(fp2
);
9031 tcg_temp_free_i64(fp1
);
9032 tcg_temp_free_i64(fp0
);
9037 check_insn(ctx
, ISA_MIPS32R6
);
9039 TCGv_i64 fp0
= tcg_temp_new_i64();
9040 TCGv_i64 fp1
= tcg_temp_new_i64();
9041 TCGv_i64 fp2
= tcg_temp_new_i64();
9042 gen_load_fpr64(ctx
, fp0
, fs
);
9043 gen_load_fpr64(ctx
, fp1
, ft
);
9044 gen_load_fpr64(ctx
, fp2
, fd
);
9045 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9046 gen_store_fpr64(ctx
, fp2
, fd
);
9047 tcg_temp_free_i64(fp2
);
9048 tcg_temp_free_i64(fp1
);
9049 tcg_temp_free_i64(fp0
);
9054 check_insn(ctx
, ISA_MIPS32R6
);
9056 TCGv_i64 fp0
= tcg_temp_new_i64();
9057 gen_load_fpr64(ctx
, fp0
, fs
);
9058 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
9059 gen_store_fpr64(ctx
, fp0
, fd
);
9060 tcg_temp_free_i64(fp0
);
9065 check_insn(ctx
, ISA_MIPS32R6
);
9067 TCGv_i64 fp0
= tcg_temp_new_i64();
9068 gen_load_fpr64(ctx
, fp0
, fs
);
9069 gen_helper_float_class_d(fp0
, fp0
);
9070 gen_store_fpr64(ctx
, fp0
, fd
);
9071 tcg_temp_free_i64(fp0
);
9075 case OPC_MIN_D
: /* OPC_RECIP2_D */
9076 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9078 TCGv_i64 fp0
= tcg_temp_new_i64();
9079 TCGv_i64 fp1
= tcg_temp_new_i64();
9080 gen_load_fpr64(ctx
, fp0
, fs
);
9081 gen_load_fpr64(ctx
, fp1
, ft
);
9082 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
9083 gen_store_fpr64(ctx
, fp1
, fd
);
9084 tcg_temp_free_i64(fp1
);
9085 tcg_temp_free_i64(fp0
);
9089 check_cp1_64bitmode(ctx
);
9091 TCGv_i64 fp0
= tcg_temp_new_i64();
9092 TCGv_i64 fp1
= tcg_temp_new_i64();
9094 gen_load_fpr64(ctx
, fp0
, fs
);
9095 gen_load_fpr64(ctx
, fp1
, ft
);
9096 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
9097 tcg_temp_free_i64(fp1
);
9098 gen_store_fpr64(ctx
, fp0
, fd
);
9099 tcg_temp_free_i64(fp0
);
9104 case OPC_MINA_D
: /* OPC_RECIP1_D */
9105 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9107 TCGv_i64 fp0
= tcg_temp_new_i64();
9108 TCGv_i64 fp1
= tcg_temp_new_i64();
9109 gen_load_fpr64(ctx
, fp0
, fs
);
9110 gen_load_fpr64(ctx
, fp1
, ft
);
9111 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
9112 gen_store_fpr64(ctx
, fp1
, fd
);
9113 tcg_temp_free_i64(fp1
);
9114 tcg_temp_free_i64(fp0
);
9118 check_cp1_64bitmode(ctx
);
9120 TCGv_i64 fp0
= tcg_temp_new_i64();
9122 gen_load_fpr64(ctx
, fp0
, fs
);
9123 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
9124 gen_store_fpr64(ctx
, fp0
, fd
);
9125 tcg_temp_free_i64(fp0
);
9130 case OPC_MAX_D
: /* OPC_RSQRT1_D */
9131 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9133 TCGv_i64 fp0
= tcg_temp_new_i64();
9134 TCGv_i64 fp1
= tcg_temp_new_i64();
9135 gen_load_fpr64(ctx
, fp0
, fs
);
9136 gen_load_fpr64(ctx
, fp1
, ft
);
9137 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
9138 gen_store_fpr64(ctx
, fp1
, fd
);
9139 tcg_temp_free_i64(fp1
);
9140 tcg_temp_free_i64(fp0
);
9144 check_cp1_64bitmode(ctx
);
9146 TCGv_i64 fp0
= tcg_temp_new_i64();
9148 gen_load_fpr64(ctx
, fp0
, fs
);
9149 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
9150 gen_store_fpr64(ctx
, fp0
, fd
);
9151 tcg_temp_free_i64(fp0
);
9156 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
9157 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9159 TCGv_i64 fp0
= tcg_temp_new_i64();
9160 TCGv_i64 fp1
= tcg_temp_new_i64();
9161 gen_load_fpr64(ctx
, fp0
, fs
);
9162 gen_load_fpr64(ctx
, fp1
, ft
);
9163 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
9164 gen_store_fpr64(ctx
, fp1
, fd
);
9165 tcg_temp_free_i64(fp1
);
9166 tcg_temp_free_i64(fp0
);
9170 check_cp1_64bitmode(ctx
);
9172 TCGv_i64 fp0
= tcg_temp_new_i64();
9173 TCGv_i64 fp1
= tcg_temp_new_i64();
9175 gen_load_fpr64(ctx
, fp0
, fs
);
9176 gen_load_fpr64(ctx
, fp1
, ft
);
9177 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
9178 tcg_temp_free_i64(fp1
);
9179 gen_store_fpr64(ctx
, fp0
, fd
);
9180 tcg_temp_free_i64(fp0
);
9194 case OPC_CMP_NGLE_D
:
9201 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9202 if (ctx
->opcode
& (1 << 6)) {
9203 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
9204 opn
= condnames_abs
[func
-48];
9206 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
9207 opn
= condnames
[func
-48];
9211 check_cp1_registers(ctx
, fs
);
9213 TCGv_i32 fp32
= tcg_temp_new_i32();
9214 TCGv_i64 fp64
= tcg_temp_new_i64();
9216 gen_load_fpr64(ctx
, fp64
, fs
);
9217 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
9218 tcg_temp_free_i64(fp64
);
9219 gen_store_fpr32(fp32
, fd
);
9220 tcg_temp_free_i32(fp32
);
9225 check_cp1_registers(ctx
, fs
);
9227 TCGv_i32 fp32
= tcg_temp_new_i32();
9228 TCGv_i64 fp64
= tcg_temp_new_i64();
9230 gen_load_fpr64(ctx
, fp64
, fs
);
9231 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
9232 tcg_temp_free_i64(fp64
);
9233 gen_store_fpr32(fp32
, fd
);
9234 tcg_temp_free_i32(fp32
);
9239 check_cp1_64bitmode(ctx
);
9241 TCGv_i64 fp0
= tcg_temp_new_i64();
9243 gen_load_fpr64(ctx
, fp0
, fs
);
9244 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
9245 gen_store_fpr64(ctx
, fp0
, fd
);
9246 tcg_temp_free_i64(fp0
);
9252 TCGv_i32 fp0
= tcg_temp_new_i32();
9254 gen_load_fpr32(fp0
, fs
);
9255 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
9256 gen_store_fpr32(fp0
, fd
);
9257 tcg_temp_free_i32(fp0
);
9262 check_cp1_registers(ctx
, fd
);
9264 TCGv_i32 fp32
= tcg_temp_new_i32();
9265 TCGv_i64 fp64
= tcg_temp_new_i64();
9267 gen_load_fpr32(fp32
, fs
);
9268 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
9269 tcg_temp_free_i32(fp32
);
9270 gen_store_fpr64(ctx
, fp64
, fd
);
9271 tcg_temp_free_i64(fp64
);
9276 check_cp1_64bitmode(ctx
);
9278 TCGv_i32 fp32
= tcg_temp_new_i32();
9279 TCGv_i64 fp64
= tcg_temp_new_i64();
9281 gen_load_fpr64(ctx
, fp64
, fs
);
9282 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
9283 tcg_temp_free_i64(fp64
);
9284 gen_store_fpr32(fp32
, fd
);
9285 tcg_temp_free_i32(fp32
);
9290 check_cp1_64bitmode(ctx
);
9292 TCGv_i64 fp0
= tcg_temp_new_i64();
9294 gen_load_fpr64(ctx
, fp0
, fs
);
9295 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
9296 gen_store_fpr64(ctx
, fp0
, fd
);
9297 tcg_temp_free_i64(fp0
);
9302 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9303 check_cp1_64bitmode(ctx
);
9305 TCGv_i64 fp0
= tcg_temp_new_i64();
9307 gen_load_fpr64(ctx
, fp0
, fs
);
9308 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
9309 gen_store_fpr64(ctx
, fp0
, fd
);
9310 tcg_temp_free_i64(fp0
);
9315 check_cp1_64bitmode(ctx
);
9317 TCGv_i64 fp0
= tcg_temp_new_i64();
9318 TCGv_i64 fp1
= tcg_temp_new_i64();
9320 gen_load_fpr64(ctx
, fp0
, fs
);
9321 gen_load_fpr64(ctx
, fp1
, ft
);
9322 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
9323 tcg_temp_free_i64(fp1
);
9324 gen_store_fpr64(ctx
, fp0
, fd
);
9325 tcg_temp_free_i64(fp0
);
9330 check_cp1_64bitmode(ctx
);
9332 TCGv_i64 fp0
= tcg_temp_new_i64();
9333 TCGv_i64 fp1
= tcg_temp_new_i64();
9335 gen_load_fpr64(ctx
, fp0
, fs
);
9336 gen_load_fpr64(ctx
, fp1
, ft
);
9337 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
9338 tcg_temp_free_i64(fp1
);
9339 gen_store_fpr64(ctx
, fp0
, fd
);
9340 tcg_temp_free_i64(fp0
);
9345 check_cp1_64bitmode(ctx
);
9347 TCGv_i64 fp0
= tcg_temp_new_i64();
9348 TCGv_i64 fp1
= tcg_temp_new_i64();
9350 gen_load_fpr64(ctx
, fp0
, fs
);
9351 gen_load_fpr64(ctx
, fp1
, ft
);
9352 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
9353 tcg_temp_free_i64(fp1
);
9354 gen_store_fpr64(ctx
, fp0
, fd
);
9355 tcg_temp_free_i64(fp0
);
9360 check_cp1_64bitmode(ctx
);
9362 TCGv_i64 fp0
= tcg_temp_new_i64();
9364 gen_load_fpr64(ctx
, fp0
, fs
);
9365 gen_helper_float_abs_ps(fp0
, fp0
);
9366 gen_store_fpr64(ctx
, fp0
, fd
);
9367 tcg_temp_free_i64(fp0
);
9372 check_cp1_64bitmode(ctx
);
9374 TCGv_i64 fp0
= tcg_temp_new_i64();
9376 gen_load_fpr64(ctx
, fp0
, fs
);
9377 gen_store_fpr64(ctx
, fp0
, fd
);
9378 tcg_temp_free_i64(fp0
);
9383 check_cp1_64bitmode(ctx
);
9385 TCGv_i64 fp0
= tcg_temp_new_i64();
9387 gen_load_fpr64(ctx
, fp0
, fs
);
9388 gen_helper_float_chs_ps(fp0
, fp0
);
9389 gen_store_fpr64(ctx
, fp0
, fd
);
9390 tcg_temp_free_i64(fp0
);
9395 check_cp1_64bitmode(ctx
);
9396 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9400 check_cp1_64bitmode(ctx
);
9402 int l1
= gen_new_label();
9406 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9407 fp0
= tcg_temp_new_i64();
9408 gen_load_fpr64(ctx
, fp0
, fs
);
9409 gen_store_fpr64(ctx
, fp0
, fd
);
9410 tcg_temp_free_i64(fp0
);
9416 check_cp1_64bitmode(ctx
);
9418 int l1
= gen_new_label();
9422 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9423 fp0
= tcg_temp_new_i64();
9424 gen_load_fpr64(ctx
, fp0
, fs
);
9425 gen_store_fpr64(ctx
, fp0
, fd
);
9426 tcg_temp_free_i64(fp0
);
9433 check_cp1_64bitmode(ctx
);
9435 TCGv_i64 fp0
= tcg_temp_new_i64();
9436 TCGv_i64 fp1
= tcg_temp_new_i64();
9438 gen_load_fpr64(ctx
, fp0
, ft
);
9439 gen_load_fpr64(ctx
, fp1
, fs
);
9440 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
9441 tcg_temp_free_i64(fp1
);
9442 gen_store_fpr64(ctx
, fp0
, fd
);
9443 tcg_temp_free_i64(fp0
);
9448 check_cp1_64bitmode(ctx
);
9450 TCGv_i64 fp0
= tcg_temp_new_i64();
9451 TCGv_i64 fp1
= tcg_temp_new_i64();
9453 gen_load_fpr64(ctx
, fp0
, ft
);
9454 gen_load_fpr64(ctx
, fp1
, fs
);
9455 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
9456 tcg_temp_free_i64(fp1
);
9457 gen_store_fpr64(ctx
, fp0
, fd
);
9458 tcg_temp_free_i64(fp0
);
9463 check_cp1_64bitmode(ctx
);
9465 TCGv_i64 fp0
= tcg_temp_new_i64();
9466 TCGv_i64 fp1
= tcg_temp_new_i64();
9468 gen_load_fpr64(ctx
, fp0
, fs
);
9469 gen_load_fpr64(ctx
, fp1
, ft
);
9470 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
9471 tcg_temp_free_i64(fp1
);
9472 gen_store_fpr64(ctx
, fp0
, fd
);
9473 tcg_temp_free_i64(fp0
);
9478 check_cp1_64bitmode(ctx
);
9480 TCGv_i64 fp0
= tcg_temp_new_i64();
9482 gen_load_fpr64(ctx
, fp0
, fs
);
9483 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
9484 gen_store_fpr64(ctx
, fp0
, fd
);
9485 tcg_temp_free_i64(fp0
);
9490 check_cp1_64bitmode(ctx
);
9492 TCGv_i64 fp0
= tcg_temp_new_i64();
9494 gen_load_fpr64(ctx
, fp0
, fs
);
9495 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
9496 gen_store_fpr64(ctx
, fp0
, fd
);
9497 tcg_temp_free_i64(fp0
);
9502 check_cp1_64bitmode(ctx
);
9504 TCGv_i64 fp0
= tcg_temp_new_i64();
9505 TCGv_i64 fp1
= tcg_temp_new_i64();
9507 gen_load_fpr64(ctx
, fp0
, fs
);
9508 gen_load_fpr64(ctx
, fp1
, ft
);
9509 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
9510 tcg_temp_free_i64(fp1
);
9511 gen_store_fpr64(ctx
, fp0
, fd
);
9512 tcg_temp_free_i64(fp0
);
9517 check_cp1_64bitmode(ctx
);
9519 TCGv_i32 fp0
= tcg_temp_new_i32();
9521 gen_load_fpr32h(ctx
, fp0
, fs
);
9522 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
9523 gen_store_fpr32(fp0
, fd
);
9524 tcg_temp_free_i32(fp0
);
9529 check_cp1_64bitmode(ctx
);
9531 TCGv_i64 fp0
= tcg_temp_new_i64();
9533 gen_load_fpr64(ctx
, fp0
, fs
);
9534 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
9535 gen_store_fpr64(ctx
, fp0
, fd
);
9536 tcg_temp_free_i64(fp0
);
9541 check_cp1_64bitmode(ctx
);
9543 TCGv_i32 fp0
= tcg_temp_new_i32();
9545 gen_load_fpr32(fp0
, fs
);
9546 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
9547 gen_store_fpr32(fp0
, fd
);
9548 tcg_temp_free_i32(fp0
);
9553 check_cp1_64bitmode(ctx
);
9555 TCGv_i32 fp0
= tcg_temp_new_i32();
9556 TCGv_i32 fp1
= tcg_temp_new_i32();
9558 gen_load_fpr32(fp0
, fs
);
9559 gen_load_fpr32(fp1
, ft
);
9560 gen_store_fpr32h(ctx
, fp0
, fd
);
9561 gen_store_fpr32(fp1
, fd
);
9562 tcg_temp_free_i32(fp0
);
9563 tcg_temp_free_i32(fp1
);
9568 check_cp1_64bitmode(ctx
);
9570 TCGv_i32 fp0
= tcg_temp_new_i32();
9571 TCGv_i32 fp1
= tcg_temp_new_i32();
9573 gen_load_fpr32(fp0
, fs
);
9574 gen_load_fpr32h(ctx
, fp1
, ft
);
9575 gen_store_fpr32(fp1
, fd
);
9576 gen_store_fpr32h(ctx
, fp0
, fd
);
9577 tcg_temp_free_i32(fp0
);
9578 tcg_temp_free_i32(fp1
);
9583 check_cp1_64bitmode(ctx
);
9585 TCGv_i32 fp0
= tcg_temp_new_i32();
9586 TCGv_i32 fp1
= tcg_temp_new_i32();
9588 gen_load_fpr32h(ctx
, fp0
, fs
);
9589 gen_load_fpr32(fp1
, ft
);
9590 gen_store_fpr32(fp1
, fd
);
9591 gen_store_fpr32h(ctx
, fp0
, fd
);
9592 tcg_temp_free_i32(fp0
);
9593 tcg_temp_free_i32(fp1
);
9598 check_cp1_64bitmode(ctx
);
9600 TCGv_i32 fp0
= tcg_temp_new_i32();
9601 TCGv_i32 fp1
= tcg_temp_new_i32();
9603 gen_load_fpr32h(ctx
, fp0
, fs
);
9604 gen_load_fpr32h(ctx
, fp1
, ft
);
9605 gen_store_fpr32(fp1
, fd
);
9606 gen_store_fpr32h(ctx
, fp0
, fd
);
9607 tcg_temp_free_i32(fp0
);
9608 tcg_temp_free_i32(fp1
);
9615 case OPC_CMP_UEQ_PS
:
9616 case OPC_CMP_OLT_PS
:
9617 case OPC_CMP_ULT_PS
:
9618 case OPC_CMP_OLE_PS
:
9619 case OPC_CMP_ULE_PS
:
9621 case OPC_CMP_NGLE_PS
:
9622 case OPC_CMP_SEQ_PS
:
9623 case OPC_CMP_NGL_PS
:
9625 case OPC_CMP_NGE_PS
:
9627 case OPC_CMP_NGT_PS
:
9628 if (ctx
->opcode
& (1 << 6)) {
9629 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
9630 opn
= condnames_abs
[func
-48];
9632 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
9633 opn
= condnames
[func
-48];
9638 generate_exception (ctx
, EXCP_RI
);
9641 (void)opn
; /* avoid a compiler warning */
9644 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
9647 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
9650 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
9655 /* Coprocessor 3 (FPU) */
9656 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
9657 int fd
, int fs
, int base
, int index
)
9659 const char *opn
= "extended float load/store";
9661 TCGv t0
= tcg_temp_new();
9664 gen_load_gpr(t0
, index
);
9665 } else if (index
== 0) {
9666 gen_load_gpr(t0
, base
);
9668 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
9670 /* Don't do NOP if destination is zero: we must perform the actual
9676 TCGv_i32 fp0
= tcg_temp_new_i32();
9678 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
9679 tcg_gen_trunc_tl_i32(fp0
, t0
);
9680 gen_store_fpr32(fp0
, fd
);
9681 tcg_temp_free_i32(fp0
);
9687 check_cp1_registers(ctx
, fd
);
9689 TCGv_i64 fp0
= tcg_temp_new_i64();
9690 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9691 gen_store_fpr64(ctx
, fp0
, fd
);
9692 tcg_temp_free_i64(fp0
);
9697 check_cp1_64bitmode(ctx
);
9698 tcg_gen_andi_tl(t0
, t0
, ~0x7);
9700 TCGv_i64 fp0
= tcg_temp_new_i64();
9702 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9703 gen_store_fpr64(ctx
, fp0
, fd
);
9704 tcg_temp_free_i64(fp0
);
9711 TCGv_i32 fp0
= tcg_temp_new_i32();
9712 gen_load_fpr32(fp0
, fs
);
9713 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
9714 tcg_temp_free_i32(fp0
);
9721 check_cp1_registers(ctx
, fs
);
9723 TCGv_i64 fp0
= tcg_temp_new_i64();
9724 gen_load_fpr64(ctx
, fp0
, fs
);
9725 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9726 tcg_temp_free_i64(fp0
);
9732 check_cp1_64bitmode(ctx
);
9733 tcg_gen_andi_tl(t0
, t0
, ~0x7);
9735 TCGv_i64 fp0
= tcg_temp_new_i64();
9736 gen_load_fpr64(ctx
, fp0
, fs
);
9737 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9738 tcg_temp_free_i64(fp0
);
9745 (void)opn
; (void)store
; /* avoid compiler warnings */
9746 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
9747 regnames
[index
], regnames
[base
]);
9750 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
9751 int fd
, int fr
, int fs
, int ft
)
9753 const char *opn
= "flt3_arith";
9757 check_cp1_64bitmode(ctx
);
9759 TCGv t0
= tcg_temp_local_new();
9760 TCGv_i32 fp
= tcg_temp_new_i32();
9761 TCGv_i32 fph
= tcg_temp_new_i32();
9762 int l1
= gen_new_label();
9763 int l2
= gen_new_label();
9765 gen_load_gpr(t0
, fr
);
9766 tcg_gen_andi_tl(t0
, t0
, 0x7);
9768 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
9769 gen_load_fpr32(fp
, fs
);
9770 gen_load_fpr32h(ctx
, fph
, fs
);
9771 gen_store_fpr32(fp
, fd
);
9772 gen_store_fpr32h(ctx
, fph
, fd
);
9775 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
9777 #ifdef TARGET_WORDS_BIGENDIAN
9778 gen_load_fpr32(fp
, fs
);
9779 gen_load_fpr32h(ctx
, fph
, ft
);
9780 gen_store_fpr32h(ctx
, fp
, fd
);
9781 gen_store_fpr32(fph
, fd
);
9783 gen_load_fpr32h(ctx
, fph
, fs
);
9784 gen_load_fpr32(fp
, ft
);
9785 gen_store_fpr32(fph
, fd
);
9786 gen_store_fpr32h(ctx
, fp
, fd
);
9789 tcg_temp_free_i32(fp
);
9790 tcg_temp_free_i32(fph
);
9797 TCGv_i32 fp0
= tcg_temp_new_i32();
9798 TCGv_i32 fp1
= tcg_temp_new_i32();
9799 TCGv_i32 fp2
= tcg_temp_new_i32();
9801 gen_load_fpr32(fp0
, fs
);
9802 gen_load_fpr32(fp1
, ft
);
9803 gen_load_fpr32(fp2
, fr
);
9804 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9805 tcg_temp_free_i32(fp0
);
9806 tcg_temp_free_i32(fp1
);
9807 gen_store_fpr32(fp2
, fd
);
9808 tcg_temp_free_i32(fp2
);
9814 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9816 TCGv_i64 fp0
= tcg_temp_new_i64();
9817 TCGv_i64 fp1
= tcg_temp_new_i64();
9818 TCGv_i64 fp2
= tcg_temp_new_i64();
9820 gen_load_fpr64(ctx
, fp0
, fs
);
9821 gen_load_fpr64(ctx
, fp1
, ft
);
9822 gen_load_fpr64(ctx
, fp2
, fr
);
9823 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9824 tcg_temp_free_i64(fp0
);
9825 tcg_temp_free_i64(fp1
);
9826 gen_store_fpr64(ctx
, fp2
, fd
);
9827 tcg_temp_free_i64(fp2
);
9832 check_cp1_64bitmode(ctx
);
9834 TCGv_i64 fp0
= tcg_temp_new_i64();
9835 TCGv_i64 fp1
= tcg_temp_new_i64();
9836 TCGv_i64 fp2
= tcg_temp_new_i64();
9838 gen_load_fpr64(ctx
, fp0
, fs
);
9839 gen_load_fpr64(ctx
, fp1
, ft
);
9840 gen_load_fpr64(ctx
, fp2
, fr
);
9841 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9842 tcg_temp_free_i64(fp0
);
9843 tcg_temp_free_i64(fp1
);
9844 gen_store_fpr64(ctx
, fp2
, fd
);
9845 tcg_temp_free_i64(fp2
);
9852 TCGv_i32 fp0
= tcg_temp_new_i32();
9853 TCGv_i32 fp1
= tcg_temp_new_i32();
9854 TCGv_i32 fp2
= tcg_temp_new_i32();
9856 gen_load_fpr32(fp0
, fs
);
9857 gen_load_fpr32(fp1
, ft
);
9858 gen_load_fpr32(fp2
, fr
);
9859 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9860 tcg_temp_free_i32(fp0
);
9861 tcg_temp_free_i32(fp1
);
9862 gen_store_fpr32(fp2
, fd
);
9863 tcg_temp_free_i32(fp2
);
9869 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9871 TCGv_i64 fp0
= tcg_temp_new_i64();
9872 TCGv_i64 fp1
= tcg_temp_new_i64();
9873 TCGv_i64 fp2
= tcg_temp_new_i64();
9875 gen_load_fpr64(ctx
, fp0
, fs
);
9876 gen_load_fpr64(ctx
, fp1
, ft
);
9877 gen_load_fpr64(ctx
, fp2
, fr
);
9878 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9879 tcg_temp_free_i64(fp0
);
9880 tcg_temp_free_i64(fp1
);
9881 gen_store_fpr64(ctx
, fp2
, fd
);
9882 tcg_temp_free_i64(fp2
);
9887 check_cp1_64bitmode(ctx
);
9889 TCGv_i64 fp0
= tcg_temp_new_i64();
9890 TCGv_i64 fp1
= tcg_temp_new_i64();
9891 TCGv_i64 fp2
= tcg_temp_new_i64();
9893 gen_load_fpr64(ctx
, fp0
, fs
);
9894 gen_load_fpr64(ctx
, fp1
, ft
);
9895 gen_load_fpr64(ctx
, fp2
, fr
);
9896 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9897 tcg_temp_free_i64(fp0
);
9898 tcg_temp_free_i64(fp1
);
9899 gen_store_fpr64(ctx
, fp2
, fd
);
9900 tcg_temp_free_i64(fp2
);
9907 TCGv_i32 fp0
= tcg_temp_new_i32();
9908 TCGv_i32 fp1
= tcg_temp_new_i32();
9909 TCGv_i32 fp2
= tcg_temp_new_i32();
9911 gen_load_fpr32(fp0
, fs
);
9912 gen_load_fpr32(fp1
, ft
);
9913 gen_load_fpr32(fp2
, fr
);
9914 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9915 tcg_temp_free_i32(fp0
);
9916 tcg_temp_free_i32(fp1
);
9917 gen_store_fpr32(fp2
, fd
);
9918 tcg_temp_free_i32(fp2
);
9924 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9926 TCGv_i64 fp0
= tcg_temp_new_i64();
9927 TCGv_i64 fp1
= tcg_temp_new_i64();
9928 TCGv_i64 fp2
= tcg_temp_new_i64();
9930 gen_load_fpr64(ctx
, fp0
, fs
);
9931 gen_load_fpr64(ctx
, fp1
, ft
);
9932 gen_load_fpr64(ctx
, fp2
, fr
);
9933 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9934 tcg_temp_free_i64(fp0
);
9935 tcg_temp_free_i64(fp1
);
9936 gen_store_fpr64(ctx
, fp2
, fd
);
9937 tcg_temp_free_i64(fp2
);
9942 check_cp1_64bitmode(ctx
);
9944 TCGv_i64 fp0
= tcg_temp_new_i64();
9945 TCGv_i64 fp1
= tcg_temp_new_i64();
9946 TCGv_i64 fp2
= tcg_temp_new_i64();
9948 gen_load_fpr64(ctx
, fp0
, fs
);
9949 gen_load_fpr64(ctx
, fp1
, ft
);
9950 gen_load_fpr64(ctx
, fp2
, fr
);
9951 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9952 tcg_temp_free_i64(fp0
);
9953 tcg_temp_free_i64(fp1
);
9954 gen_store_fpr64(ctx
, fp2
, fd
);
9955 tcg_temp_free_i64(fp2
);
9962 TCGv_i32 fp0
= tcg_temp_new_i32();
9963 TCGv_i32 fp1
= tcg_temp_new_i32();
9964 TCGv_i32 fp2
= tcg_temp_new_i32();
9966 gen_load_fpr32(fp0
, fs
);
9967 gen_load_fpr32(fp1
, ft
);
9968 gen_load_fpr32(fp2
, fr
);
9969 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9970 tcg_temp_free_i32(fp0
);
9971 tcg_temp_free_i32(fp1
);
9972 gen_store_fpr32(fp2
, fd
);
9973 tcg_temp_free_i32(fp2
);
9979 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9981 TCGv_i64 fp0
= tcg_temp_new_i64();
9982 TCGv_i64 fp1
= tcg_temp_new_i64();
9983 TCGv_i64 fp2
= tcg_temp_new_i64();
9985 gen_load_fpr64(ctx
, fp0
, fs
);
9986 gen_load_fpr64(ctx
, fp1
, ft
);
9987 gen_load_fpr64(ctx
, fp2
, fr
);
9988 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9989 tcg_temp_free_i64(fp0
);
9990 tcg_temp_free_i64(fp1
);
9991 gen_store_fpr64(ctx
, fp2
, fd
);
9992 tcg_temp_free_i64(fp2
);
9997 check_cp1_64bitmode(ctx
);
9999 TCGv_i64 fp0
= tcg_temp_new_i64();
10000 TCGv_i64 fp1
= tcg_temp_new_i64();
10001 TCGv_i64 fp2
= tcg_temp_new_i64();
10003 gen_load_fpr64(ctx
, fp0
, fs
);
10004 gen_load_fpr64(ctx
, fp1
, ft
);
10005 gen_load_fpr64(ctx
, fp2
, fr
);
10006 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10007 tcg_temp_free_i64(fp0
);
10008 tcg_temp_free_i64(fp1
);
10009 gen_store_fpr64(ctx
, fp2
, fd
);
10010 tcg_temp_free_i64(fp2
);
10016 generate_exception (ctx
, EXCP_RI
);
10019 (void)opn
; /* avoid a compiler warning */
10020 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
10021 fregnames
[fs
], fregnames
[ft
]);
10024 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
10028 #if !defined(CONFIG_USER_ONLY)
10029 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10030 Therefore only check the ISA in system mode. */
10031 check_insn(ctx
, ISA_MIPS32R2
);
10033 t0
= tcg_temp_new();
10037 save_cpu_state(ctx
, 1);
10038 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
10039 gen_store_gpr(t0
, rt
);
10042 save_cpu_state(ctx
, 1);
10043 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
10044 gen_store_gpr(t0
, rt
);
10047 save_cpu_state(ctx
, 1);
10048 gen_helper_rdhwr_cc(t0
, cpu_env
);
10049 gen_store_gpr(t0
, rt
);
10052 save_cpu_state(ctx
, 1);
10053 gen_helper_rdhwr_ccres(t0
, cpu_env
);
10054 gen_store_gpr(t0
, rt
);
10057 #if defined(CONFIG_USER_ONLY)
10058 tcg_gen_ld_tl(t0
, cpu_env
,
10059 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10060 gen_store_gpr(t0
, rt
);
10063 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
10064 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
10065 tcg_gen_ld_tl(t0
, cpu_env
,
10066 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10067 gen_store_gpr(t0
, rt
);
10069 generate_exception(ctx
, EXCP_RI
);
10073 default: /* Invalid */
10074 MIPS_INVAL("rdhwr");
10075 generate_exception(ctx
, EXCP_RI
);
10081 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
10083 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10084 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
10085 /* Branches completion */
10086 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
10087 ctx
->bstate
= BS_BRANCH
;
10088 save_cpu_state(ctx
, 0);
10089 /* FIXME: Need to clear can_do_io. */
10090 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
10092 /* unconditional branch */
10093 MIPS_DEBUG("unconditional branch");
10094 if (proc_hflags
& MIPS_HFLAG_BX
) {
10095 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
10097 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10099 case MIPS_HFLAG_BL
:
10100 /* blikely taken case */
10101 MIPS_DEBUG("blikely branch taken");
10102 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10104 case MIPS_HFLAG_BC
:
10105 /* Conditional branch */
10106 MIPS_DEBUG("conditional branch");
10108 int l1
= gen_new_label();
10110 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
10111 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
10113 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10116 case MIPS_HFLAG_BR
:
10117 /* unconditional branch to register */
10118 MIPS_DEBUG("branch to register");
10119 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
10120 TCGv t0
= tcg_temp_new();
10121 TCGv_i32 t1
= tcg_temp_new_i32();
10123 tcg_gen_andi_tl(t0
, btarget
, 0x1);
10124 tcg_gen_trunc_tl_i32(t1
, t0
);
10126 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
10127 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
10128 tcg_gen_or_i32(hflags
, hflags
, t1
);
10129 tcg_temp_free_i32(t1
);
10131 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
10133 tcg_gen_mov_tl(cpu_PC
, btarget
);
10135 if (ctx
->singlestep_enabled
) {
10136 save_cpu_state(ctx
, 0);
10137 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
10139 tcg_gen_exit_tb(0);
10142 MIPS_DEBUG("unknown branch");
10148 /* ISA extensions (ASEs) */
10149 /* MIPS16 extension to MIPS32 */
10151 /* MIPS16 major opcodes */
10153 M16_OPC_ADDIUSP
= 0x00,
10154 M16_OPC_ADDIUPC
= 0x01,
10156 M16_OPC_JAL
= 0x03,
10157 M16_OPC_BEQZ
= 0x04,
10158 M16_OPC_BNEQZ
= 0x05,
10159 M16_OPC_SHIFT
= 0x06,
10161 M16_OPC_RRIA
= 0x08,
10162 M16_OPC_ADDIU8
= 0x09,
10163 M16_OPC_SLTI
= 0x0a,
10164 M16_OPC_SLTIU
= 0x0b,
10167 M16_OPC_CMPI
= 0x0e,
10171 M16_OPC_LWSP
= 0x12,
10173 M16_OPC_LBU
= 0x14,
10174 M16_OPC_LHU
= 0x15,
10175 M16_OPC_LWPC
= 0x16,
10176 M16_OPC_LWU
= 0x17,
10179 M16_OPC_SWSP
= 0x1a,
10181 M16_OPC_RRR
= 0x1c,
10183 M16_OPC_EXTEND
= 0x1e,
10187 /* I8 funct field */
10206 /* RR funct field */
10240 /* I64 funct field */
10248 I64_DADDIUPC
= 0x6,
10252 /* RR ry field for CNVT */
10254 RR_RY_CNVT_ZEB
= 0x0,
10255 RR_RY_CNVT_ZEH
= 0x1,
10256 RR_RY_CNVT_ZEW
= 0x2,
10257 RR_RY_CNVT_SEB
= 0x4,
10258 RR_RY_CNVT_SEH
= 0x5,
10259 RR_RY_CNVT_SEW
= 0x6,
10262 static int xlat (int r
)
10264 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10269 static void gen_mips16_save (DisasContext
*ctx
,
10270 int xsregs
, int aregs
,
10271 int do_ra
, int do_s0
, int do_s1
,
10274 TCGv t0
= tcg_temp_new();
10275 TCGv t1
= tcg_temp_new();
10305 generate_exception(ctx
, EXCP_RI
);
10311 gen_base_offset_addr(ctx
, t0
, 29, 12);
10312 gen_load_gpr(t1
, 7);
10313 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10316 gen_base_offset_addr(ctx
, t0
, 29, 8);
10317 gen_load_gpr(t1
, 6);
10318 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10321 gen_base_offset_addr(ctx
, t0
, 29, 4);
10322 gen_load_gpr(t1
, 5);
10323 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10326 gen_base_offset_addr(ctx
, t0
, 29, 0);
10327 gen_load_gpr(t1
, 4);
10328 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10331 gen_load_gpr(t0
, 29);
10333 #define DECR_AND_STORE(reg) do { \
10334 tcg_gen_subi_tl(t0, t0, 4); \
10335 gen_load_gpr(t1, reg); \
10336 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
10340 DECR_AND_STORE(31);
10345 DECR_AND_STORE(30);
10348 DECR_AND_STORE(23);
10351 DECR_AND_STORE(22);
10354 DECR_AND_STORE(21);
10357 DECR_AND_STORE(20);
10360 DECR_AND_STORE(19);
10363 DECR_AND_STORE(18);
10367 DECR_AND_STORE(17);
10370 DECR_AND_STORE(16);
10400 generate_exception(ctx
, EXCP_RI
);
10416 #undef DECR_AND_STORE
10418 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
10423 static void gen_mips16_restore (DisasContext
*ctx
,
10424 int xsregs
, int aregs
,
10425 int do_ra
, int do_s0
, int do_s1
,
10429 TCGv t0
= tcg_temp_new();
10430 TCGv t1
= tcg_temp_new();
10432 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
10434 #define DECR_AND_LOAD(reg) do { \
10435 tcg_gen_subi_tl(t0, t0, 4); \
10436 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10437 gen_store_gpr(t1, reg); \
10501 generate_exception(ctx
, EXCP_RI
);
10517 #undef DECR_AND_LOAD
10519 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
10524 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
10525 int is_64_bit
, int extended
)
10529 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10530 generate_exception(ctx
, EXCP_RI
);
10534 t0
= tcg_temp_new();
10536 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
10537 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
10539 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10545 #if defined(TARGET_MIPS64)
10546 static void decode_i64_mips16 (DisasContext
*ctx
,
10547 int ry
, int funct
, int16_t offset
,
10552 check_mips_64(ctx
);
10553 offset
= extended
? offset
: offset
<< 3;
10554 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
10557 check_mips_64(ctx
);
10558 offset
= extended
? offset
: offset
<< 3;
10559 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
10562 check_mips_64(ctx
);
10563 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
10564 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
10567 check_mips_64(ctx
);
10568 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
10569 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
10572 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10573 generate_exception(ctx
, EXCP_RI
);
10575 offset
= extended
? offset
: offset
<< 3;
10576 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
10580 check_mips_64(ctx
);
10581 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
10582 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
10585 check_mips_64(ctx
);
10586 offset
= extended
? offset
: offset
<< 2;
10587 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
10590 check_mips_64(ctx
);
10591 offset
= extended
? offset
: offset
<< 2;
10592 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
10598 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
10600 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
10601 int op
, rx
, ry
, funct
, sa
;
10602 int16_t imm
, offset
;
10604 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
10605 op
= (ctx
->opcode
>> 11) & 0x1f;
10606 sa
= (ctx
->opcode
>> 22) & 0x1f;
10607 funct
= (ctx
->opcode
>> 8) & 0x7;
10608 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
10609 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
10610 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
10611 | ((ctx
->opcode
>> 21) & 0x3f) << 5
10612 | (ctx
->opcode
& 0x1f));
10614 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
10617 case M16_OPC_ADDIUSP
:
10618 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
10620 case M16_OPC_ADDIUPC
:
10621 gen_addiupc(ctx
, rx
, imm
, 0, 1);
10624 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
10625 /* No delay slot, so just process as a normal instruction */
10628 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
10629 /* No delay slot, so just process as a normal instruction */
10631 case M16_OPC_BNEQZ
:
10632 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
10633 /* No delay slot, so just process as a normal instruction */
10635 case M16_OPC_SHIFT
:
10636 switch (ctx
->opcode
& 0x3) {
10638 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
10641 #if defined(TARGET_MIPS64)
10642 check_mips_64(ctx
);
10643 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
10645 generate_exception(ctx
, EXCP_RI
);
10649 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
10652 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
10656 #if defined(TARGET_MIPS64)
10658 check_mips_64(ctx
);
10659 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
10663 imm
= ctx
->opcode
& 0xf;
10664 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
10665 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
10666 imm
= (int16_t) (imm
<< 1) >> 1;
10667 if ((ctx
->opcode
>> 4) & 0x1) {
10668 #if defined(TARGET_MIPS64)
10669 check_mips_64(ctx
);
10670 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
10672 generate_exception(ctx
, EXCP_RI
);
10675 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
10678 case M16_OPC_ADDIU8
:
10679 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
10682 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
10684 case M16_OPC_SLTIU
:
10685 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
10690 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
10693 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
10696 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
10699 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
10703 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
10704 int aregs
= (ctx
->opcode
>> 16) & 0xf;
10705 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
10706 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
10707 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
10708 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
10709 | (ctx
->opcode
& 0xf)) << 3;
10711 if (ctx
->opcode
& (1 << 7)) {
10712 gen_mips16_save(ctx
, xsregs
, aregs
,
10713 do_ra
, do_s0
, do_s1
,
10716 gen_mips16_restore(ctx
, xsregs
, aregs
,
10717 do_ra
, do_s0
, do_s1
,
10723 generate_exception(ctx
, EXCP_RI
);
10728 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
10731 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
10733 #if defined(TARGET_MIPS64)
10735 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
10739 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
10742 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
10745 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
10748 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
10751 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
10754 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
10757 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
10759 #if defined(TARGET_MIPS64)
10761 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
10765 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10768 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
10771 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
10774 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
10776 #if defined(TARGET_MIPS64)
10778 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
10782 generate_exception(ctx
, EXCP_RI
);
10789 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
10793 int op
, cnvt_op
, op1
, offset
;
10797 op
= (ctx
->opcode
>> 11) & 0x1f;
10798 sa
= (ctx
->opcode
>> 2) & 0x7;
10799 sa
= sa
== 0 ? 8 : sa
;
10800 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
10801 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
10802 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
10803 op1
= offset
= ctx
->opcode
& 0x1f;
10808 case M16_OPC_ADDIUSP
:
10810 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
10812 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
10815 case M16_OPC_ADDIUPC
:
10816 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
10819 offset
= (ctx
->opcode
& 0x7ff) << 1;
10820 offset
= (int16_t)(offset
<< 4) >> 4;
10821 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
10822 /* No delay slot, so just process as a normal instruction */
10825 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
10826 offset
= (((ctx
->opcode
& 0x1f) << 21)
10827 | ((ctx
->opcode
>> 5) & 0x1f) << 16
10829 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
10830 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
10834 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
10835 ((int8_t)ctx
->opcode
) << 1, 0);
10836 /* No delay slot, so just process as a normal instruction */
10838 case M16_OPC_BNEQZ
:
10839 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
10840 ((int8_t)ctx
->opcode
) << 1, 0);
10841 /* No delay slot, so just process as a normal instruction */
10843 case M16_OPC_SHIFT
:
10844 switch (ctx
->opcode
& 0x3) {
10846 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
10849 #if defined(TARGET_MIPS64)
10850 check_mips_64(ctx
);
10851 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
10853 generate_exception(ctx
, EXCP_RI
);
10857 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
10860 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
10864 #if defined(TARGET_MIPS64)
10866 check_mips_64(ctx
);
10867 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
10872 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
10874 if ((ctx
->opcode
>> 4) & 1) {
10875 #if defined(TARGET_MIPS64)
10876 check_mips_64(ctx
);
10877 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
10879 generate_exception(ctx
, EXCP_RI
);
10882 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
10886 case M16_OPC_ADDIU8
:
10888 int16_t imm
= (int8_t) ctx
->opcode
;
10890 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
10895 int16_t imm
= (uint8_t) ctx
->opcode
;
10896 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
10899 case M16_OPC_SLTIU
:
10901 int16_t imm
= (uint8_t) ctx
->opcode
;
10902 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
10909 funct
= (ctx
->opcode
>> 8) & 0x7;
10912 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
10913 ((int8_t)ctx
->opcode
) << 1, 0);
10916 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
10917 ((int8_t)ctx
->opcode
) << 1, 0);
10920 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
10923 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
10924 ((int8_t)ctx
->opcode
) << 3);
10928 int do_ra
= ctx
->opcode
& (1 << 6);
10929 int do_s0
= ctx
->opcode
& (1 << 5);
10930 int do_s1
= ctx
->opcode
& (1 << 4);
10931 int framesize
= ctx
->opcode
& 0xf;
10933 if (framesize
== 0) {
10936 framesize
= framesize
<< 3;
10939 if (ctx
->opcode
& (1 << 7)) {
10940 gen_mips16_save(ctx
, 0, 0,
10941 do_ra
, do_s0
, do_s1
, framesize
);
10943 gen_mips16_restore(ctx
, 0, 0,
10944 do_ra
, do_s0
, do_s1
, framesize
);
10950 int rz
= xlat(ctx
->opcode
& 0x7);
10952 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
10953 ((ctx
->opcode
>> 5) & 0x7);
10954 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
10958 reg32
= ctx
->opcode
& 0x1f;
10959 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
10962 generate_exception(ctx
, EXCP_RI
);
10969 int16_t imm
= (uint8_t) ctx
->opcode
;
10971 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
10976 int16_t imm
= (uint8_t) ctx
->opcode
;
10977 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
10980 #if defined(TARGET_MIPS64)
10982 check_mips_64(ctx
);
10983 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
10987 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
10990 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
10993 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10996 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
10999 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11002 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
11005 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
11007 #if defined (TARGET_MIPS64)
11009 check_mips_64(ctx
);
11010 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
11014 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11017 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
11020 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11023 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
11027 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
11030 switch (ctx
->opcode
& 0x3) {
11032 mips32_op
= OPC_ADDU
;
11035 mips32_op
= OPC_SUBU
;
11037 #if defined(TARGET_MIPS64)
11039 mips32_op
= OPC_DADDU
;
11040 check_mips_64(ctx
);
11043 mips32_op
= OPC_DSUBU
;
11044 check_mips_64(ctx
);
11048 generate_exception(ctx
, EXCP_RI
);
11052 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
11061 int nd
= (ctx
->opcode
>> 7) & 0x1;
11062 int link
= (ctx
->opcode
>> 6) & 0x1;
11063 int ra
= (ctx
->opcode
>> 5) & 0x1;
11071 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
11076 /* XXX: not clear which exception should be raised
11077 * when in debug mode...
11079 check_insn(ctx
, ISA_MIPS32
);
11080 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11081 generate_exception(ctx
, EXCP_DBp
);
11083 generate_exception(ctx
, EXCP_DBp
);
11087 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
11090 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
11093 generate_exception(ctx
, EXCP_BREAK
);
11096 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
11099 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
11102 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
11104 #if defined (TARGET_MIPS64)
11106 check_mips_64(ctx
);
11107 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
11111 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
11114 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
11117 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
11120 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
11123 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
11126 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
11129 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
11133 case RR_RY_CNVT_ZEB
:
11134 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11136 case RR_RY_CNVT_ZEH
:
11137 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11139 case RR_RY_CNVT_SEB
:
11140 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11142 case RR_RY_CNVT_SEH
:
11143 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11145 #if defined (TARGET_MIPS64)
11146 case RR_RY_CNVT_ZEW
:
11147 check_mips_64(ctx
);
11148 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11150 case RR_RY_CNVT_SEW
:
11151 check_mips_64(ctx
);
11152 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11156 generate_exception(ctx
, EXCP_RI
);
11161 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
11163 #if defined (TARGET_MIPS64)
11165 check_mips_64(ctx
);
11166 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
11169 check_mips_64(ctx
);
11170 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
11173 check_mips_64(ctx
);
11174 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
11177 check_mips_64(ctx
);
11178 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
11182 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
11185 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
11188 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
11191 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
11193 #if defined (TARGET_MIPS64)
11195 check_mips_64(ctx
);
11196 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
11199 check_mips_64(ctx
);
11200 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
11203 check_mips_64(ctx
);
11204 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
11207 check_mips_64(ctx
);
11208 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
11212 generate_exception(ctx
, EXCP_RI
);
11216 case M16_OPC_EXTEND
:
11217 decode_extended_mips16_opc(env
, ctx
);
11220 #if defined(TARGET_MIPS64)
11222 funct
= (ctx
->opcode
>> 8) & 0x7;
11223 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
11227 generate_exception(ctx
, EXCP_RI
);
11234 /* microMIPS extension to MIPS32/MIPS64 */
11237 * microMIPS32/microMIPS64 major opcodes
11239 * 1. MIPS Architecture for Programmers Volume II-B:
11240 * The microMIPS32 Instruction Set (Revision 3.05)
11242 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11244 * 2. MIPS Architecture For Programmers Volume II-A:
11245 * The MIPS64 Instruction Set (Revision 3.51)
11273 POOL32S
= 0x16, /* MIPS64 */
11274 DADDIU32
= 0x17, /* MIPS64 */
11276 /* 0x1f is reserved */
11285 /* 0x20 is reserved */
11295 /* 0x28 and 0x29 are reserved */
11305 /* 0x30 and 0x31 are reserved */
11312 SD32
= 0x36, /* MIPS64 */
11313 LD32
= 0x37, /* MIPS64 */
11315 /* 0x38 and 0x39 are reserved */
11326 /* POOL32A encoding of minor opcode field */
11329 /* These opcodes are distinguished only by bits 9..6; those bits are
11330 * what are recorded below. */
11356 /* The following can be distinguished by their lower 6 bits. */
11362 /* POOL32AXF encoding of minor opcode field extension */
11365 * 1. MIPS Architecture for Programmers Volume II-B:
11366 * The microMIPS32 Instruction Set (Revision 3.05)
11368 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11370 * 2. MIPS Architecture for Programmers VolumeIV-e:
11371 * The MIPS DSP Application-Specific Extension
11372 * to the microMIPS32 Architecture (Revision 2.34)
11374 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11389 /* begin of microMIPS32 DSP */
11391 /* bits 13..12 for 0x01 */
11397 /* bits 13..12 for 0x2a */
11403 /* bits 13..12 for 0x32 */
11407 /* end of microMIPS32 DSP */
11409 /* bits 15..12 for 0x2c */
11425 /* bits 15..12 for 0x34 */
11433 /* bits 15..12 for 0x3c */
11435 JR
= 0x0, /* alias */
11440 /* bits 15..12 for 0x05 */
11444 /* bits 15..12 for 0x0d */
11454 /* bits 15..12 for 0x15 */
11460 /* bits 15..12 for 0x1d */
11464 /* bits 15..12 for 0x2d */
11469 /* bits 15..12 for 0x35 */
11476 /* POOL32B encoding of minor opcode field (bits 15..12) */
11492 /* POOL32C encoding of minor opcode field (bits 15..12) */
11500 /* 0xa is reserved */
11507 /* 0x6 is reserved */
11513 /* POOL32F encoding of minor opcode field (bits 5..0) */
11516 /* These are the bit 7..6 values */
11527 /* These are the bit 8..6 values */
11571 CABS_COND_FMT
= 0x1c, /* MIPS3D */
11575 /* POOL32Fxf encoding of minor opcode extension field */
11613 /* POOL32I encoding of minor opcode field (bits 25..21) */
11638 /* These overlap and are distinguished by bit16 of the instruction */
11647 /* POOL16A encoding of minor opcode field */
11654 /* POOL16B encoding of minor opcode field */
11661 /* POOL16C encoding of minor opcode field */
11681 /* POOL16D encoding of minor opcode field */
11688 /* POOL16E encoding of minor opcode field */
11695 static int mmreg (int r
)
11697 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11702 /* Used for 16-bit store instructions. */
11703 static int mmreg2 (int r
)
11705 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
11710 #define uMIPS_RD(op) ((op >> 7) & 0x7)
11711 #define uMIPS_RS(op) ((op >> 4) & 0x7)
11712 #define uMIPS_RS2(op) uMIPS_RS(op)
11713 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
11714 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
11715 #define uMIPS_RS5(op) (op & 0x1f)
11717 /* Signed immediate */
11718 #define SIMM(op, start, width) \
11719 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
11722 /* Zero-extended immediate */
11723 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
11725 static void gen_addiur1sp(DisasContext
*ctx
)
11727 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
11729 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
11732 static void gen_addiur2(DisasContext
*ctx
)
11734 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
11735 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
11736 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
11738 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
11741 static void gen_addiusp(DisasContext
*ctx
)
11743 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
11746 if (encoded
<= 1) {
11747 decoded
= 256 + encoded
;
11748 } else if (encoded
<= 255) {
11750 } else if (encoded
<= 509) {
11751 decoded
= encoded
- 512;
11753 decoded
= encoded
- 768;
11756 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
11759 static void gen_addius5(DisasContext
*ctx
)
11761 int imm
= SIMM(ctx
->opcode
, 1, 4);
11762 int rd
= (ctx
->opcode
>> 5) & 0x1f;
11764 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
11767 static void gen_andi16(DisasContext
*ctx
)
11769 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
11770 31, 32, 63, 64, 255, 32768, 65535 };
11771 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
11772 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
11773 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
11775 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
11778 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
11779 int base
, int16_t offset
)
11781 const char *opn
= "ldst_multiple";
11785 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11786 generate_exception(ctx
, EXCP_RI
);
11790 t0
= tcg_temp_new();
11792 gen_base_offset_addr(ctx
, t0
, base
, offset
);
11794 t1
= tcg_const_tl(reglist
);
11795 t2
= tcg_const_i32(ctx
->mem_idx
);
11797 save_cpu_state(ctx
, 1);
11800 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
11804 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
11807 #ifdef TARGET_MIPS64
11809 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
11813 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
11819 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
11822 tcg_temp_free_i32(t2
);
11826 static void gen_pool16c_insn(DisasContext
*ctx
)
11828 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
11829 int rs
= mmreg(ctx
->opcode
& 0x7);
11831 switch (((ctx
->opcode
) >> 4) & 0x3f) {
11836 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
11842 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
11848 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
11854 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
11861 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
11862 int offset
= ZIMM(ctx
->opcode
, 0, 4);
11864 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
11873 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
11874 int offset
= ZIMM(ctx
->opcode
, 0, 4);
11876 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
11883 int reg
= ctx
->opcode
& 0x1f;
11885 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
11891 int reg
= ctx
->opcode
& 0x1f;
11892 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
11893 /* Let normal delay slot handling in our caller take us
11894 to the branch target. */
11899 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
11900 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
11904 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
11905 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
11909 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
11913 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
11916 generate_exception(ctx
, EXCP_BREAK
);
11919 /* XXX: not clear which exception should be raised
11920 * when in debug mode...
11922 check_insn(ctx
, ISA_MIPS32
);
11923 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11924 generate_exception(ctx
, EXCP_DBp
);
11926 generate_exception(ctx
, EXCP_DBp
);
11929 case JRADDIUSP
+ 0:
11930 case JRADDIUSP
+ 1:
11932 int imm
= ZIMM(ctx
->opcode
, 0, 5);
11933 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
11934 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
11935 /* Let normal delay slot handling in our caller take us
11936 to the branch target. */
11940 generate_exception(ctx
, EXCP_RI
);
11945 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
11947 TCGv t0
= tcg_temp_new();
11948 TCGv t1
= tcg_temp_new();
11950 gen_load_gpr(t0
, base
);
11953 gen_load_gpr(t1
, index
);
11954 tcg_gen_shli_tl(t1
, t1
, 2);
11955 gen_op_addr_add(ctx
, t0
, t1
, t0
);
11958 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11959 gen_store_gpr(t1
, rd
);
11965 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
11966 int base
, int16_t offset
)
11968 const char *opn
= "ldst_pair";
11971 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
11972 generate_exception(ctx
, EXCP_RI
);
11976 t0
= tcg_temp_new();
11977 t1
= tcg_temp_new();
11979 gen_base_offset_addr(ctx
, t0
, base
, offset
);
11984 generate_exception(ctx
, EXCP_RI
);
11987 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11988 gen_store_gpr(t1
, rd
);
11989 tcg_gen_movi_tl(t1
, 4);
11990 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11991 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11992 gen_store_gpr(t1
, rd
+1);
11996 gen_load_gpr(t1
, rd
);
11997 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11998 tcg_gen_movi_tl(t1
, 4);
11999 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12000 gen_load_gpr(t1
, rd
+1);
12001 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12004 #ifdef TARGET_MIPS64
12007 generate_exception(ctx
, EXCP_RI
);
12010 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12011 gen_store_gpr(t1
, rd
);
12012 tcg_gen_movi_tl(t1
, 8);
12013 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12014 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12015 gen_store_gpr(t1
, rd
+1);
12019 gen_load_gpr(t1
, rd
);
12020 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12021 tcg_gen_movi_tl(t1
, 8);
12022 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12023 gen_load_gpr(t1
, rd
+1);
12024 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12029 (void)opn
; /* avoid a compiler warning */
12030 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
12035 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
12037 int extension
= (ctx
->opcode
>> 6) & 0x3f;
12038 int minor
= (ctx
->opcode
>> 12) & 0xf;
12039 uint32_t mips32_op
;
12041 switch (extension
) {
12043 mips32_op
= OPC_TEQ
;
12046 mips32_op
= OPC_TGE
;
12049 mips32_op
= OPC_TGEU
;
12052 mips32_op
= OPC_TLT
;
12055 mips32_op
= OPC_TLTU
;
12058 mips32_op
= OPC_TNE
;
12060 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
12062 #ifndef CONFIG_USER_ONLY
12065 check_cp0_enabled(ctx
);
12067 /* Treat as NOP. */
12070 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
12074 check_cp0_enabled(ctx
);
12076 TCGv t0
= tcg_temp_new();
12078 gen_load_gpr(t0
, rt
);
12079 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
12085 switch (minor
& 3) {
12087 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12090 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12093 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12096 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12099 goto pool32axf_invalid
;
12103 switch (minor
& 3) {
12105 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12108 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12111 goto pool32axf_invalid
;
12117 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
12120 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
12123 mips32_op
= OPC_CLO
;
12126 mips32_op
= OPC_CLZ
;
12128 check_insn(ctx
, ISA_MIPS32
);
12129 gen_cl(ctx
, mips32_op
, rt
, rs
);
12132 gen_rdhwr(ctx
, rt
, rs
);
12135 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
12138 mips32_op
= OPC_MULT
;
12141 mips32_op
= OPC_MULTU
;
12144 mips32_op
= OPC_DIV
;
12147 mips32_op
= OPC_DIVU
;
12150 check_insn(ctx
, ISA_MIPS32
);
12151 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
12154 mips32_op
= OPC_MADD
;
12157 mips32_op
= OPC_MADDU
;
12160 mips32_op
= OPC_MSUB
;
12163 mips32_op
= OPC_MSUBU
;
12165 check_insn(ctx
, ISA_MIPS32
);
12166 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
12169 goto pool32axf_invalid
;
12180 generate_exception_err(ctx
, EXCP_CpU
, 2);
12183 goto pool32axf_invalid
;
12190 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
12191 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12195 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
12196 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12199 goto pool32axf_invalid
;
12205 check_cp0_enabled(ctx
);
12206 check_insn(ctx
, ISA_MIPS32R2
);
12207 gen_load_srsgpr(rt
, rs
);
12210 check_cp0_enabled(ctx
);
12211 check_insn(ctx
, ISA_MIPS32R2
);
12212 gen_store_srsgpr(rt
, rs
);
12215 goto pool32axf_invalid
;
12218 #ifndef CONFIG_USER_ONLY
12222 mips32_op
= OPC_TLBP
;
12225 mips32_op
= OPC_TLBR
;
12228 mips32_op
= OPC_TLBWI
;
12231 mips32_op
= OPC_TLBWR
;
12234 mips32_op
= OPC_WAIT
;
12237 mips32_op
= OPC_DERET
;
12240 mips32_op
= OPC_ERET
;
12242 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
12245 goto pool32axf_invalid
;
12251 check_cp0_enabled(ctx
);
12253 TCGv t0
= tcg_temp_new();
12255 save_cpu_state(ctx
, 1);
12256 gen_helper_di(t0
, cpu_env
);
12257 gen_store_gpr(t0
, rs
);
12258 /* Stop translation as we may have switched the execution mode */
12259 ctx
->bstate
= BS_STOP
;
12264 check_cp0_enabled(ctx
);
12266 TCGv t0
= tcg_temp_new();
12268 save_cpu_state(ctx
, 1);
12269 gen_helper_ei(t0
, cpu_env
);
12270 gen_store_gpr(t0
, rs
);
12271 /* Stop translation as we may have switched the execution mode */
12272 ctx
->bstate
= BS_STOP
;
12277 goto pool32axf_invalid
;
12287 generate_exception(ctx
, EXCP_SYSCALL
);
12288 ctx
->bstate
= BS_STOP
;
12291 check_insn(ctx
, ISA_MIPS32
);
12292 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
12293 generate_exception(ctx
, EXCP_DBp
);
12295 generate_exception(ctx
, EXCP_DBp
);
12299 goto pool32axf_invalid
;
12303 switch (minor
& 3) {
12305 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
12308 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
12311 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
12314 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
12317 goto pool32axf_invalid
;
12323 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
12326 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
12329 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
12332 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
12335 goto pool32axf_invalid
;
12340 MIPS_INVAL("pool32axf");
12341 generate_exception(ctx
, EXCP_RI
);
12346 /* Values for microMIPS fmt field. Variable-width, depending on which
12347 formats the instruction supports. */
12366 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
12368 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
12369 uint32_t mips32_op
;
12371 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12372 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12373 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12375 switch (extension
) {
12376 case FLOAT_1BIT_FMT(CFC1
, 0):
12377 mips32_op
= OPC_CFC1
;
12379 case FLOAT_1BIT_FMT(CTC1
, 0):
12380 mips32_op
= OPC_CTC1
;
12382 case FLOAT_1BIT_FMT(MFC1
, 0):
12383 mips32_op
= OPC_MFC1
;
12385 case FLOAT_1BIT_FMT(MTC1
, 0):
12386 mips32_op
= OPC_MTC1
;
12388 case FLOAT_1BIT_FMT(MFHC1
, 0):
12389 mips32_op
= OPC_MFHC1
;
12391 case FLOAT_1BIT_FMT(MTHC1
, 0):
12392 mips32_op
= OPC_MTHC1
;
12394 gen_cp1(ctx
, mips32_op
, rt
, rs
);
12397 /* Reciprocal square root */
12398 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
12399 mips32_op
= OPC_RSQRT_S
;
12401 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
12402 mips32_op
= OPC_RSQRT_D
;
12406 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
12407 mips32_op
= OPC_SQRT_S
;
12409 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
12410 mips32_op
= OPC_SQRT_D
;
12414 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
12415 mips32_op
= OPC_RECIP_S
;
12417 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
12418 mips32_op
= OPC_RECIP_D
;
12422 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
12423 mips32_op
= OPC_FLOOR_L_S
;
12425 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
12426 mips32_op
= OPC_FLOOR_L_D
;
12428 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
12429 mips32_op
= OPC_FLOOR_W_S
;
12431 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
12432 mips32_op
= OPC_FLOOR_W_D
;
12436 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
12437 mips32_op
= OPC_CEIL_L_S
;
12439 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
12440 mips32_op
= OPC_CEIL_L_D
;
12442 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
12443 mips32_op
= OPC_CEIL_W_S
;
12445 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
12446 mips32_op
= OPC_CEIL_W_D
;
12450 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
12451 mips32_op
= OPC_TRUNC_L_S
;
12453 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
12454 mips32_op
= OPC_TRUNC_L_D
;
12456 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
12457 mips32_op
= OPC_TRUNC_W_S
;
12459 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
12460 mips32_op
= OPC_TRUNC_W_D
;
12464 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
12465 mips32_op
= OPC_ROUND_L_S
;
12467 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
12468 mips32_op
= OPC_ROUND_L_D
;
12470 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
12471 mips32_op
= OPC_ROUND_W_S
;
12473 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
12474 mips32_op
= OPC_ROUND_W_D
;
12477 /* Integer to floating-point conversion */
12478 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
12479 mips32_op
= OPC_CVT_L_S
;
12481 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
12482 mips32_op
= OPC_CVT_L_D
;
12484 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
12485 mips32_op
= OPC_CVT_W_S
;
12487 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
12488 mips32_op
= OPC_CVT_W_D
;
12491 /* Paired-foo conversions */
12492 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
12493 mips32_op
= OPC_CVT_S_PL
;
12495 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
12496 mips32_op
= OPC_CVT_S_PU
;
12498 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
12499 mips32_op
= OPC_CVT_PW_PS
;
12501 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
12502 mips32_op
= OPC_CVT_PS_PW
;
12505 /* Floating-point moves */
12506 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
12507 mips32_op
= OPC_MOV_S
;
12509 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
12510 mips32_op
= OPC_MOV_D
;
12512 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
12513 mips32_op
= OPC_MOV_PS
;
12516 /* Absolute value */
12517 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
12518 mips32_op
= OPC_ABS_S
;
12520 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
12521 mips32_op
= OPC_ABS_D
;
12523 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
12524 mips32_op
= OPC_ABS_PS
;
12528 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
12529 mips32_op
= OPC_NEG_S
;
12531 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
12532 mips32_op
= OPC_NEG_D
;
12534 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
12535 mips32_op
= OPC_NEG_PS
;
12538 /* Reciprocal square root step */
12539 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
12540 mips32_op
= OPC_RSQRT1_S
;
12542 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
12543 mips32_op
= OPC_RSQRT1_D
;
12545 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
12546 mips32_op
= OPC_RSQRT1_PS
;
12549 /* Reciprocal step */
12550 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
12551 mips32_op
= OPC_RECIP1_S
;
12553 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
12554 mips32_op
= OPC_RECIP1_S
;
12556 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
12557 mips32_op
= OPC_RECIP1_PS
;
12560 /* Conversions from double */
12561 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
12562 mips32_op
= OPC_CVT_D_S
;
12564 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
12565 mips32_op
= OPC_CVT_D_W
;
12567 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
12568 mips32_op
= OPC_CVT_D_L
;
12571 /* Conversions from single */
12572 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
12573 mips32_op
= OPC_CVT_S_D
;
12575 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
12576 mips32_op
= OPC_CVT_S_W
;
12578 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
12579 mips32_op
= OPC_CVT_S_L
;
12581 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
12584 /* Conditional moves on floating-point codes */
12585 case COND_FLOAT_MOV(MOVT
, 0):
12586 case COND_FLOAT_MOV(MOVT
, 1):
12587 case COND_FLOAT_MOV(MOVT
, 2):
12588 case COND_FLOAT_MOV(MOVT
, 3):
12589 case COND_FLOAT_MOV(MOVT
, 4):
12590 case COND_FLOAT_MOV(MOVT
, 5):
12591 case COND_FLOAT_MOV(MOVT
, 6):
12592 case COND_FLOAT_MOV(MOVT
, 7):
12593 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
12595 case COND_FLOAT_MOV(MOVF
, 0):
12596 case COND_FLOAT_MOV(MOVF
, 1):
12597 case COND_FLOAT_MOV(MOVF
, 2):
12598 case COND_FLOAT_MOV(MOVF
, 3):
12599 case COND_FLOAT_MOV(MOVF
, 4):
12600 case COND_FLOAT_MOV(MOVF
, 5):
12601 case COND_FLOAT_MOV(MOVF
, 6):
12602 case COND_FLOAT_MOV(MOVF
, 7):
12603 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
12606 MIPS_INVAL("pool32fxf");
12607 generate_exception(ctx
, EXCP_RI
);
12612 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
12617 int rt
, rs
, rd
, rr
;
12619 uint32_t op
, minor
, mips32_op
;
12620 uint32_t cond
, fmt
, cc
;
12622 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
12623 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
12625 rt
= (ctx
->opcode
>> 21) & 0x1f;
12626 rs
= (ctx
->opcode
>> 16) & 0x1f;
12627 rd
= (ctx
->opcode
>> 11) & 0x1f;
12628 rr
= (ctx
->opcode
>> 6) & 0x1f;
12629 imm
= (int16_t) ctx
->opcode
;
12631 op
= (ctx
->opcode
>> 26) & 0x3f;
12634 minor
= ctx
->opcode
& 0x3f;
12637 minor
= (ctx
->opcode
>> 6) & 0xf;
12640 mips32_op
= OPC_SLL
;
12643 mips32_op
= OPC_SRA
;
12646 mips32_op
= OPC_SRL
;
12649 mips32_op
= OPC_ROTR
;
12651 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
12654 goto pool32a_invalid
;
12658 minor
= (ctx
->opcode
>> 6) & 0xf;
12662 mips32_op
= OPC_ADD
;
12665 mips32_op
= OPC_ADDU
;
12668 mips32_op
= OPC_SUB
;
12671 mips32_op
= OPC_SUBU
;
12674 mips32_op
= OPC_MUL
;
12676 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
12680 mips32_op
= OPC_SLLV
;
12683 mips32_op
= OPC_SRLV
;
12686 mips32_op
= OPC_SRAV
;
12689 mips32_op
= OPC_ROTRV
;
12691 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
12693 /* Logical operations */
12695 mips32_op
= OPC_AND
;
12698 mips32_op
= OPC_OR
;
12701 mips32_op
= OPC_NOR
;
12704 mips32_op
= OPC_XOR
;
12706 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
12708 /* Set less than */
12710 mips32_op
= OPC_SLT
;
12713 mips32_op
= OPC_SLTU
;
12715 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
12718 goto pool32a_invalid
;
12722 minor
= (ctx
->opcode
>> 6) & 0xf;
12724 /* Conditional moves */
12726 mips32_op
= OPC_MOVN
;
12729 mips32_op
= OPC_MOVZ
;
12731 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
12734 gen_ldxs(ctx
, rs
, rt
, rd
);
12737 goto pool32a_invalid
;
12741 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
12744 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
12747 gen_pool32axf(env
, ctx
, rt
, rs
);
12750 generate_exception(ctx
, EXCP_BREAK
);
12754 MIPS_INVAL("pool32a");
12755 generate_exception(ctx
, EXCP_RI
);
12760 minor
= (ctx
->opcode
>> 12) & 0xf;
12763 check_cp0_enabled(ctx
);
12764 /* Treat as no-op. */
12768 /* COP2: Not implemented. */
12769 generate_exception_err(ctx
, EXCP_CpU
, 2);
12773 #ifdef TARGET_MIPS64
12777 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12781 #ifdef TARGET_MIPS64
12785 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12788 MIPS_INVAL("pool32b");
12789 generate_exception(ctx
, EXCP_RI
);
12794 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
12795 minor
= ctx
->opcode
& 0x3f;
12796 check_cp1_enabled(ctx
);
12799 mips32_op
= OPC_ALNV_PS
;
12802 mips32_op
= OPC_MADD_S
;
12805 mips32_op
= OPC_MADD_D
;
12808 mips32_op
= OPC_MADD_PS
;
12811 mips32_op
= OPC_MSUB_S
;
12814 mips32_op
= OPC_MSUB_D
;
12817 mips32_op
= OPC_MSUB_PS
;
12820 mips32_op
= OPC_NMADD_S
;
12823 mips32_op
= OPC_NMADD_D
;
12826 mips32_op
= OPC_NMADD_PS
;
12829 mips32_op
= OPC_NMSUB_S
;
12832 mips32_op
= OPC_NMSUB_D
;
12835 mips32_op
= OPC_NMSUB_PS
;
12837 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
12839 case CABS_COND_FMT
:
12840 cond
= (ctx
->opcode
>> 6) & 0xf;
12841 cc
= (ctx
->opcode
>> 13) & 0x7;
12842 fmt
= (ctx
->opcode
>> 10) & 0x3;
12845 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
12848 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
12851 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
12854 goto pool32f_invalid
;
12858 cond
= (ctx
->opcode
>> 6) & 0xf;
12859 cc
= (ctx
->opcode
>> 13) & 0x7;
12860 fmt
= (ctx
->opcode
>> 10) & 0x3;
12863 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
12866 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
12869 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
12872 goto pool32f_invalid
;
12876 gen_pool32fxf(ctx
, rt
, rs
);
12880 switch ((ctx
->opcode
>> 6) & 0x7) {
12882 mips32_op
= OPC_PLL_PS
;
12885 mips32_op
= OPC_PLU_PS
;
12888 mips32_op
= OPC_PUL_PS
;
12891 mips32_op
= OPC_PUU_PS
;
12894 mips32_op
= OPC_CVT_PS_S
;
12896 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12899 goto pool32f_invalid
;
12904 switch ((ctx
->opcode
>> 6) & 0x7) {
12906 mips32_op
= OPC_LWXC1
;
12909 mips32_op
= OPC_SWXC1
;
12912 mips32_op
= OPC_LDXC1
;
12915 mips32_op
= OPC_SDXC1
;
12918 mips32_op
= OPC_LUXC1
;
12921 mips32_op
= OPC_SUXC1
;
12923 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
12926 goto pool32f_invalid
;
12931 fmt
= (ctx
->opcode
>> 9) & 0x3;
12932 switch ((ctx
->opcode
>> 6) & 0x7) {
12936 mips32_op
= OPC_RSQRT2_S
;
12939 mips32_op
= OPC_RSQRT2_D
;
12942 mips32_op
= OPC_RSQRT2_PS
;
12945 goto pool32f_invalid
;
12951 mips32_op
= OPC_RECIP2_S
;
12954 mips32_op
= OPC_RECIP2_D
;
12957 mips32_op
= OPC_RECIP2_PS
;
12960 goto pool32f_invalid
;
12964 mips32_op
= OPC_ADDR_PS
;
12967 mips32_op
= OPC_MULR_PS
;
12969 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12972 goto pool32f_invalid
;
12976 /* MOV[FT].fmt and PREFX */
12977 cc
= (ctx
->opcode
>> 13) & 0x7;
12978 fmt
= (ctx
->opcode
>> 9) & 0x3;
12979 switch ((ctx
->opcode
>> 6) & 0x7) {
12983 gen_movcf_s(rs
, rt
, cc
, 0);
12986 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
12989 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
12992 goto pool32f_invalid
;
12998 gen_movcf_s(rs
, rt
, cc
, 1);
13001 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
13004 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
13007 goto pool32f_invalid
;
13013 goto pool32f_invalid
;
13016 #define FINSN_3ARG_SDPS(prfx) \
13017 switch ((ctx->opcode >> 8) & 0x3) { \
13019 mips32_op = OPC_##prfx##_S; \
13022 mips32_op = OPC_##prfx##_D; \
13024 case FMT_SDPS_PS: \
13025 mips32_op = OPC_##prfx##_PS; \
13028 goto pool32f_invalid; \
13031 /* regular FP ops */
13032 switch ((ctx
->opcode
>> 6) & 0x3) {
13034 FINSN_3ARG_SDPS(ADD
);
13037 FINSN_3ARG_SDPS(SUB
);
13040 FINSN_3ARG_SDPS(MUL
);
13043 fmt
= (ctx
->opcode
>> 8) & 0x3;
13045 mips32_op
= OPC_DIV_D
;
13046 } else if (fmt
== 0) {
13047 mips32_op
= OPC_DIV_S
;
13049 goto pool32f_invalid
;
13053 goto pool32f_invalid
;
13058 switch ((ctx
->opcode
>> 6) & 0x3) {
13060 FINSN_3ARG_SDPS(MOVN
);
13063 FINSN_3ARG_SDPS(MOVZ
);
13066 goto pool32f_invalid
;
13070 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13074 MIPS_INVAL("pool32f");
13075 generate_exception(ctx
, EXCP_RI
);
13079 generate_exception_err(ctx
, EXCP_CpU
, 1);
13083 minor
= (ctx
->opcode
>> 21) & 0x1f;
13086 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
13089 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
13090 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13093 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
13094 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13097 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
13100 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
13101 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13104 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
13105 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13108 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
13111 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
13116 mips32_op
= OPC_TLTI
;
13119 mips32_op
= OPC_TGEI
;
13122 mips32_op
= OPC_TLTIU
;
13125 mips32_op
= OPC_TGEIU
;
13128 mips32_op
= OPC_TNEI
;
13131 mips32_op
= OPC_TEQI
;
13133 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
13138 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
13139 4, rs
, 0, imm
<< 1, 0);
13140 /* Compact branches don't have a delay slot, so just let
13141 the normal delay slot handling take us to the branch
13145 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
13148 /* Break the TB to be able to sync copied instructions
13150 ctx
->bstate
= BS_STOP
;
13154 /* COP2: Not implemented. */
13155 generate_exception_err(ctx
, EXCP_CpU
, 2);
13158 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
13161 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
13164 mips32_op
= OPC_BC1FANY4
;
13167 mips32_op
= OPC_BC1TANY4
;
13170 check_insn(ctx
, ASE_MIPS3D
);
13173 gen_compute_branch1(ctx
, mips32_op
,
13174 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
13178 /* MIPS DSP: not implemented */
13181 MIPS_INVAL("pool32i");
13182 generate_exception(ctx
, EXCP_RI
);
13187 minor
= (ctx
->opcode
>> 12) & 0xf;
13190 mips32_op
= OPC_LWL
;
13193 mips32_op
= OPC_SWL
;
13196 mips32_op
= OPC_LWR
;
13199 mips32_op
= OPC_SWR
;
13201 #if defined(TARGET_MIPS64)
13203 mips32_op
= OPC_LDL
;
13206 mips32_op
= OPC_SDL
;
13209 mips32_op
= OPC_LDR
;
13212 mips32_op
= OPC_SDR
;
13215 mips32_op
= OPC_LWU
;
13218 mips32_op
= OPC_LLD
;
13222 mips32_op
= OPC_LL
;
13225 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13228 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13231 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13233 #if defined(TARGET_MIPS64)
13235 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13239 /* Treat as no-op */
13242 MIPS_INVAL("pool32c");
13243 generate_exception(ctx
, EXCP_RI
);
13248 mips32_op
= OPC_ADDI
;
13251 mips32_op
= OPC_ADDIU
;
13253 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13256 /* Logical operations */
13258 mips32_op
= OPC_ORI
;
13261 mips32_op
= OPC_XORI
;
13264 mips32_op
= OPC_ANDI
;
13266 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13269 /* Set less than immediate */
13271 mips32_op
= OPC_SLTI
;
13274 mips32_op
= OPC_SLTIU
;
13276 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13279 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
13280 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
13281 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13284 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
13285 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
13286 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13289 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
13292 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
13295 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
13296 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
13299 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
13300 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
13301 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13303 /* Floating point (COP1) */
13305 mips32_op
= OPC_LWC1
;
13308 mips32_op
= OPC_LDC1
;
13311 mips32_op
= OPC_SWC1
;
13314 mips32_op
= OPC_SDC1
;
13316 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
13320 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
13321 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
13323 gen_addiupc(ctx
, reg
, offset
, 0, 0);
13326 /* Loads and stores */
13328 mips32_op
= OPC_LB
;
13331 mips32_op
= OPC_LBU
;
13334 mips32_op
= OPC_LH
;
13337 mips32_op
= OPC_LHU
;
13340 mips32_op
= OPC_LW
;
13342 #ifdef TARGET_MIPS64
13344 mips32_op
= OPC_LD
;
13347 mips32_op
= OPC_SD
;
13351 mips32_op
= OPC_SB
;
13354 mips32_op
= OPC_SH
;
13357 mips32_op
= OPC_SW
;
13360 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
13363 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
13366 generate_exception(ctx
, EXCP_RI
);
13371 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
13375 /* make sure instructions are on a halfword boundary */
13376 if (ctx
->pc
& 0x1) {
13377 env
->CP0_BadVAddr
= ctx
->pc
;
13378 generate_exception(ctx
, EXCP_AdEL
);
13379 ctx
->bstate
= BS_STOP
;
13383 op
= (ctx
->opcode
>> 10) & 0x3f;
13384 /* Enforce properly-sized instructions in a delay slot */
13385 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
13386 switch (op
& 0x7) { /* MSB-3..MSB-5 */
13388 /* POOL32A, POOL32B, POOL32I, POOL32C */
13390 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13392 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13394 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13396 /* LB32, LH32, LWC132, LDC132, LW32 */
13397 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
13398 generate_exception(ctx
, EXCP_RI
);
13399 /* Just stop translation; the user is confused. */
13400 ctx
->bstate
= BS_STOP
;
13405 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13407 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13409 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13410 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
13411 generate_exception(ctx
, EXCP_RI
);
13412 /* Just stop translation; the user is confused. */
13413 ctx
->bstate
= BS_STOP
;
13423 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13424 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
13425 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
13428 switch (ctx
->opcode
& 0x1) {
13437 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
13442 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13443 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
13444 int amount
= (ctx
->opcode
>> 1) & 0x7;
13446 amount
= amount
== 0 ? 8 : amount
;
13448 switch (ctx
->opcode
& 0x1) {
13457 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
13461 gen_pool16c_insn(ctx
);
13465 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13466 int rb
= 28; /* GP */
13467 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
13469 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13473 if (ctx
->opcode
& 1) {
13474 generate_exception(ctx
, EXCP_RI
);
13477 int enc_dest
= uMIPS_RD(ctx
->opcode
);
13478 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
13479 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
13480 int rd
, rs
, re
, rt
;
13481 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13482 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13483 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13485 rd
= rd_enc
[enc_dest
];
13486 re
= re_enc
[enc_dest
];
13487 rs
= rs_rt_enc
[enc_rs
];
13488 rt
= rs_rt_enc
[enc_rt
];
13490 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
13491 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
13496 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13497 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13498 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
13499 offset
= (offset
== 0xf ? -1 : offset
);
13501 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
13506 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13507 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13508 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
13510 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
13515 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13516 int rb
= 29; /* SP */
13517 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
13519 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13524 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13525 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13526 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
13528 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13533 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13534 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13535 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
13537 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
13542 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13543 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13544 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
13546 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
13551 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13552 int rb
= 29; /* SP */
13553 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
13555 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
13560 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13561 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13562 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
13564 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
13569 int rd
= uMIPS_RD5(ctx
->opcode
);
13570 int rs
= uMIPS_RS5(ctx
->opcode
);
13572 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
13579 switch (ctx
->opcode
& 0x1) {
13589 switch (ctx
->opcode
& 0x1) {
13594 gen_addiur1sp(ctx
);
13599 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
13600 SIMM(ctx
->opcode
, 0, 10) << 1, 4);
13604 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
13605 mmreg(uMIPS_RD(ctx
->opcode
)),
13606 0, SIMM(ctx
->opcode
, 0, 7) << 1, 4);
13610 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
13611 int imm
= ZIMM(ctx
->opcode
, 0, 7);
13613 imm
= (imm
== 0x7f ? -1 : imm
);
13614 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
13624 generate_exception(ctx
, EXCP_RI
);
13627 decode_micromips32_opc (env
, ctx
, op
);
13634 /* SmartMIPS extension to MIPS32 */
13636 #if defined(TARGET_MIPS64)
13638 /* MDMX extension to MIPS64 */
13642 /* MIPSDSP functions. */
13643 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
13644 int rd
, int base
, int offset
)
13646 const char *opn
= "ldx";
13650 t0
= tcg_temp_new();
13653 gen_load_gpr(t0
, offset
);
13654 } else if (offset
== 0) {
13655 gen_load_gpr(t0
, base
);
13657 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
13662 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
13663 gen_store_gpr(t0
, rd
);
13667 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
13668 gen_store_gpr(t0
, rd
);
13672 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
13673 gen_store_gpr(t0
, rd
);
13676 #if defined(TARGET_MIPS64)
13678 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13679 gen_store_gpr(t0
, rd
);
13684 (void)opn
; /* avoid a compiler warning */
13685 MIPS_DEBUG("%s %s, %s(%s)", opn
,
13686 regnames
[rd
], regnames
[offset
], regnames
[base
]);
13690 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13691 int ret
, int v1
, int v2
)
13693 const char *opn
= "mipsdsp arith";
13698 /* Treat as NOP. */
13703 v1_t
= tcg_temp_new();
13704 v2_t
= tcg_temp_new();
13706 gen_load_gpr(v1_t
, v1
);
13707 gen_load_gpr(v2_t
, v2
);
13710 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
13711 case OPC_MULT_G_2E
:
13715 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13717 case OPC_ADDUH_R_QB
:
13718 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13721 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13723 case OPC_ADDQH_R_PH
:
13724 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13727 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13729 case OPC_ADDQH_R_W
:
13730 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13733 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13735 case OPC_SUBUH_R_QB
:
13736 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13739 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13741 case OPC_SUBQH_R_PH
:
13742 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13745 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13747 case OPC_SUBQH_R_W
:
13748 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13752 case OPC_ABSQ_S_PH_DSP
:
13754 case OPC_ABSQ_S_QB
:
13756 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
13758 case OPC_ABSQ_S_PH
:
13760 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
13764 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
13766 case OPC_PRECEQ_W_PHL
:
13768 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
13769 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13771 case OPC_PRECEQ_W_PHR
:
13773 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
13774 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
13775 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13777 case OPC_PRECEQU_PH_QBL
:
13779 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
13781 case OPC_PRECEQU_PH_QBR
:
13783 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
13785 case OPC_PRECEQU_PH_QBLA
:
13787 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
13789 case OPC_PRECEQU_PH_QBRA
:
13791 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
13793 case OPC_PRECEU_PH_QBL
:
13795 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
13797 case OPC_PRECEU_PH_QBR
:
13799 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
13801 case OPC_PRECEU_PH_QBLA
:
13803 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
13805 case OPC_PRECEU_PH_QBRA
:
13807 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
13811 case OPC_ADDU_QB_DSP
:
13815 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13817 case OPC_ADDQ_S_PH
:
13819 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13823 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13827 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13829 case OPC_ADDU_S_QB
:
13831 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13835 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13837 case OPC_ADDU_S_PH
:
13839 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13843 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13845 case OPC_SUBQ_S_PH
:
13847 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13851 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13855 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13857 case OPC_SUBU_S_QB
:
13859 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13863 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13865 case OPC_SUBU_S_PH
:
13867 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13871 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13875 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13879 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
13881 case OPC_RADDU_W_QB
:
13883 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
13887 case OPC_CMPU_EQ_QB_DSP
:
13889 case OPC_PRECR_QB_PH
:
13891 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13893 case OPC_PRECRQ_QB_PH
:
13895 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13897 case OPC_PRECR_SRA_PH_W
:
13900 TCGv_i32 sa_t
= tcg_const_i32(v2
);
13901 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
13903 tcg_temp_free_i32(sa_t
);
13906 case OPC_PRECR_SRA_R_PH_W
:
13909 TCGv_i32 sa_t
= tcg_const_i32(v2
);
13910 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
13912 tcg_temp_free_i32(sa_t
);
13915 case OPC_PRECRQ_PH_W
:
13917 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13919 case OPC_PRECRQ_RS_PH_W
:
13921 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13923 case OPC_PRECRQU_S_QB_PH
:
13925 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13929 #ifdef TARGET_MIPS64
13930 case OPC_ABSQ_S_QH_DSP
:
13932 case OPC_PRECEQ_L_PWL
:
13934 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
13936 case OPC_PRECEQ_L_PWR
:
13938 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
13940 case OPC_PRECEQ_PW_QHL
:
13942 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
13944 case OPC_PRECEQ_PW_QHR
:
13946 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
13948 case OPC_PRECEQ_PW_QHLA
:
13950 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
13952 case OPC_PRECEQ_PW_QHRA
:
13954 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
13956 case OPC_PRECEQU_QH_OBL
:
13958 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
13960 case OPC_PRECEQU_QH_OBR
:
13962 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
13964 case OPC_PRECEQU_QH_OBLA
:
13966 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
13968 case OPC_PRECEQU_QH_OBRA
:
13970 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
13972 case OPC_PRECEU_QH_OBL
:
13974 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
13976 case OPC_PRECEU_QH_OBR
:
13978 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
13980 case OPC_PRECEU_QH_OBLA
:
13982 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
13984 case OPC_PRECEU_QH_OBRA
:
13986 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
13988 case OPC_ABSQ_S_OB
:
13990 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
13992 case OPC_ABSQ_S_PW
:
13994 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
13996 case OPC_ABSQ_S_QH
:
13998 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
14002 case OPC_ADDU_OB_DSP
:
14004 case OPC_RADDU_L_OB
:
14006 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
14010 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14012 case OPC_SUBQ_S_PW
:
14014 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14018 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14020 case OPC_SUBQ_S_QH
:
14022 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14026 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14028 case OPC_SUBU_S_OB
:
14030 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14034 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14036 case OPC_SUBU_S_QH
:
14038 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14042 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14044 case OPC_SUBUH_R_OB
:
14046 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14050 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14052 case OPC_ADDQ_S_PW
:
14054 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14058 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14060 case OPC_ADDQ_S_QH
:
14062 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14066 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14068 case OPC_ADDU_S_OB
:
14070 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14074 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14076 case OPC_ADDU_S_QH
:
14078 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14082 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14084 case OPC_ADDUH_R_OB
:
14086 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14090 case OPC_CMPU_EQ_OB_DSP
:
14092 case OPC_PRECR_OB_QH
:
14094 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
14096 case OPC_PRECR_SRA_QH_PW
:
14099 TCGv_i32 ret_t
= tcg_const_i32(ret
);
14100 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
14101 tcg_temp_free_i32(ret_t
);
14104 case OPC_PRECR_SRA_R_QH_PW
:
14107 TCGv_i32 sa_v
= tcg_const_i32(ret
);
14108 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
14109 tcg_temp_free_i32(sa_v
);
14112 case OPC_PRECRQ_OB_QH
:
14114 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
14116 case OPC_PRECRQ_PW_L
:
14118 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
14120 case OPC_PRECRQ_QH_PW
:
14122 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14124 case OPC_PRECRQ_RS_QH_PW
:
14126 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14128 case OPC_PRECRQU_S_OB_QH
:
14130 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14137 tcg_temp_free(v1_t
);
14138 tcg_temp_free(v2_t
);
14140 (void)opn
; /* avoid a compiler warning */
14141 MIPS_DEBUG("%s", opn
);
14144 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
14145 int ret
, int v1
, int v2
)
14148 const char *opn
= "mipsdsp shift";
14154 /* Treat as NOP. */
14159 t0
= tcg_temp_new();
14160 v1_t
= tcg_temp_new();
14161 v2_t
= tcg_temp_new();
14163 tcg_gen_movi_tl(t0
, v1
);
14164 gen_load_gpr(v1_t
, v1
);
14165 gen_load_gpr(v2_t
, v2
);
14168 case OPC_SHLL_QB_DSP
:
14170 op2
= MASK_SHLL_QB(ctx
->opcode
);
14174 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14178 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14182 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14186 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14188 case OPC_SHLL_S_PH
:
14190 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14192 case OPC_SHLLV_S_PH
:
14194 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14198 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14200 case OPC_SHLLV_S_W
:
14202 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14206 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
14210 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14214 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
14218 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14222 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
14224 case OPC_SHRA_R_QB
:
14226 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
14230 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14232 case OPC_SHRAV_R_QB
:
14234 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14238 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
14240 case OPC_SHRA_R_PH
:
14242 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
14246 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14248 case OPC_SHRAV_R_PH
:
14250 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14254 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
14256 case OPC_SHRAV_R_W
:
14258 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14260 default: /* Invalid */
14261 MIPS_INVAL("MASK SHLL.QB");
14262 generate_exception(ctx
, EXCP_RI
);
14267 #ifdef TARGET_MIPS64
14268 case OPC_SHLL_OB_DSP
:
14269 op2
= MASK_SHLL_OB(ctx
->opcode
);
14273 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14277 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14279 case OPC_SHLL_S_PW
:
14281 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14283 case OPC_SHLLV_S_PW
:
14285 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14289 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14293 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14297 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14301 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14303 case OPC_SHLL_S_QH
:
14305 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14307 case OPC_SHLLV_S_QH
:
14309 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14313 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
14317 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14319 case OPC_SHRA_R_OB
:
14321 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
14323 case OPC_SHRAV_R_OB
:
14325 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14329 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
14333 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
14335 case OPC_SHRA_R_PW
:
14337 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
14339 case OPC_SHRAV_R_PW
:
14341 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
14345 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
14349 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14351 case OPC_SHRA_R_QH
:
14353 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
14355 case OPC_SHRAV_R_QH
:
14357 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14361 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
14365 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14369 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
14373 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14375 default: /* Invalid */
14376 MIPS_INVAL("MASK SHLL.OB");
14377 generate_exception(ctx
, EXCP_RI
);
14385 tcg_temp_free(v1_t
);
14386 tcg_temp_free(v2_t
);
14387 (void)opn
; /* avoid a compiler warning */
14388 MIPS_DEBUG("%s", opn
);
14391 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14392 int ret
, int v1
, int v2
, int check_ret
)
14394 const char *opn
= "mipsdsp multiply";
14399 if ((ret
== 0) && (check_ret
== 1)) {
14400 /* Treat as NOP. */
14405 t0
= tcg_temp_new_i32();
14406 v1_t
= tcg_temp_new();
14407 v2_t
= tcg_temp_new();
14409 tcg_gen_movi_i32(t0
, ret
);
14410 gen_load_gpr(v1_t
, v1
);
14411 gen_load_gpr(v2_t
, v2
);
14414 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14415 * the same mask and op1. */
14416 case OPC_MULT_G_2E
:
14420 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14423 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14426 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14428 case OPC_MULQ_RS_W
:
14429 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14433 case OPC_DPA_W_PH_DSP
:
14435 case OPC_DPAU_H_QBL
:
14437 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
14439 case OPC_DPAU_H_QBR
:
14441 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
14443 case OPC_DPSU_H_QBL
:
14445 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
14447 case OPC_DPSU_H_QBR
:
14449 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
14453 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14455 case OPC_DPAX_W_PH
:
14457 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14459 case OPC_DPAQ_S_W_PH
:
14461 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14463 case OPC_DPAQX_S_W_PH
:
14465 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14467 case OPC_DPAQX_SA_W_PH
:
14469 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14473 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14475 case OPC_DPSX_W_PH
:
14477 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14479 case OPC_DPSQ_S_W_PH
:
14481 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14483 case OPC_DPSQX_S_W_PH
:
14485 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14487 case OPC_DPSQX_SA_W_PH
:
14489 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14491 case OPC_MULSAQ_S_W_PH
:
14493 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14495 case OPC_DPAQ_SA_L_W
:
14497 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
14499 case OPC_DPSQ_SA_L_W
:
14501 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
14503 case OPC_MAQ_S_W_PHL
:
14505 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
14507 case OPC_MAQ_S_W_PHR
:
14509 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
14511 case OPC_MAQ_SA_W_PHL
:
14513 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
14515 case OPC_MAQ_SA_W_PHR
:
14517 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
14519 case OPC_MULSA_W_PH
:
14521 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14525 #ifdef TARGET_MIPS64
14526 case OPC_DPAQ_W_QH_DSP
:
14528 int ac
= ret
& 0x03;
14529 tcg_gen_movi_i32(t0
, ac
);
14534 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
14538 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
14542 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
14546 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
14550 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14552 case OPC_DPAQ_S_W_QH
:
14554 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14556 case OPC_DPAQ_SA_L_PW
:
14558 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
14560 case OPC_DPAU_H_OBL
:
14562 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
14564 case OPC_DPAU_H_OBR
:
14566 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
14570 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14572 case OPC_DPSQ_S_W_QH
:
14574 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14576 case OPC_DPSQ_SA_L_PW
:
14578 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
14580 case OPC_DPSU_H_OBL
:
14582 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
14584 case OPC_DPSU_H_OBR
:
14586 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
14588 case OPC_MAQ_S_L_PWL
:
14590 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
14592 case OPC_MAQ_S_L_PWR
:
14594 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
14596 case OPC_MAQ_S_W_QHLL
:
14598 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
14600 case OPC_MAQ_SA_W_QHLL
:
14602 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
14604 case OPC_MAQ_S_W_QHLR
:
14606 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
14608 case OPC_MAQ_SA_W_QHLR
:
14610 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
14612 case OPC_MAQ_S_W_QHRL
:
14614 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
14616 case OPC_MAQ_SA_W_QHRL
:
14618 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
14620 case OPC_MAQ_S_W_QHRR
:
14622 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
14624 case OPC_MAQ_SA_W_QHRR
:
14626 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
14628 case OPC_MULSAQ_S_L_PW
:
14630 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
14632 case OPC_MULSAQ_S_W_QH
:
14634 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14640 case OPC_ADDU_QB_DSP
:
14642 case OPC_MULEU_S_PH_QBL
:
14644 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14646 case OPC_MULEU_S_PH_QBR
:
14648 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14650 case OPC_MULQ_RS_PH
:
14652 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14654 case OPC_MULEQ_S_W_PHL
:
14656 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14658 case OPC_MULEQ_S_W_PHR
:
14660 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14662 case OPC_MULQ_S_PH
:
14664 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14668 #ifdef TARGET_MIPS64
14669 case OPC_ADDU_OB_DSP
:
14671 case OPC_MULEQ_S_PW_QHL
:
14673 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14675 case OPC_MULEQ_S_PW_QHR
:
14677 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14679 case OPC_MULEU_S_QH_OBL
:
14681 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14683 case OPC_MULEU_S_QH_OBR
:
14685 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14687 case OPC_MULQ_RS_QH
:
14689 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14696 tcg_temp_free_i32(t0
);
14697 tcg_temp_free(v1_t
);
14698 tcg_temp_free(v2_t
);
14700 (void)opn
; /* avoid a compiler warning */
14701 MIPS_DEBUG("%s", opn
);
14705 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14708 const char *opn
= "mipsdsp Bit/ Manipulation";
14714 /* Treat as NOP. */
14719 t0
= tcg_temp_new();
14720 val_t
= tcg_temp_new();
14721 gen_load_gpr(val_t
, val
);
14724 case OPC_ABSQ_S_PH_DSP
:
14728 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
14733 target_long result
;
14734 imm
= (ctx
->opcode
>> 16) & 0xFF;
14735 result
= (uint32_t)imm
<< 24 |
14736 (uint32_t)imm
<< 16 |
14737 (uint32_t)imm
<< 8 |
14739 result
= (int32_t)result
;
14740 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
14745 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
14746 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
14747 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14748 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14749 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14750 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
14755 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14756 imm
= (int16_t)(imm
<< 6) >> 6;
14757 tcg_gen_movi_tl(cpu_gpr
[ret
], \
14758 (target_long
)((int32_t)imm
<< 16 | \
14764 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
14765 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14766 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14767 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
14771 #ifdef TARGET_MIPS64
14772 case OPC_ABSQ_S_QH_DSP
:
14779 imm
= (ctx
->opcode
>> 16) & 0xFF;
14780 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
14781 temp
= (temp
<< 16) | temp
;
14782 temp
= (temp
<< 32) | temp
;
14783 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
14791 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14792 imm
= (int16_t)(imm
<< 6) >> 6;
14793 temp
= ((target_long
)imm
<< 32) \
14794 | ((target_long
)imm
& 0xFFFFFFFF);
14795 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
14803 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14804 imm
= (int16_t)(imm
<< 6) >> 6;
14806 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
14807 ((uint64_t)(uint16_t)imm
<< 32) |
14808 ((uint64_t)(uint16_t)imm
<< 16) |
14809 (uint64_t)(uint16_t)imm
;
14810 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
14815 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
14816 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
14817 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14818 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14819 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14820 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
14821 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14825 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
14826 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
14827 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14831 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
14832 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14833 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14834 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
14835 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14842 tcg_temp_free(val_t
);
14844 (void)opn
; /* avoid a compiler warning */
14845 MIPS_DEBUG("%s", opn
);
14848 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
14849 uint32_t op1
, uint32_t op2
,
14850 int ret
, int v1
, int v2
, int check_ret
)
14852 const char *opn
= "mipsdsp add compare pick";
14857 if ((ret
== 0) && (check_ret
== 1)) {
14858 /* Treat as NOP. */
14863 t1
= tcg_temp_new();
14864 v1_t
= tcg_temp_new();
14865 v2_t
= tcg_temp_new();
14867 gen_load_gpr(v1_t
, v1
);
14868 gen_load_gpr(v2_t
, v2
);
14871 case OPC_CMPU_EQ_QB_DSP
:
14873 case OPC_CMPU_EQ_QB
:
14875 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
14877 case OPC_CMPU_LT_QB
:
14879 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
14881 case OPC_CMPU_LE_QB
:
14883 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
14885 case OPC_CMPGU_EQ_QB
:
14887 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14889 case OPC_CMPGU_LT_QB
:
14891 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14893 case OPC_CMPGU_LE_QB
:
14895 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14897 case OPC_CMPGDU_EQ_QB
:
14899 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
14900 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14901 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
14902 tcg_gen_shli_tl(t1
, t1
, 24);
14903 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14905 case OPC_CMPGDU_LT_QB
:
14907 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
14908 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14909 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
14910 tcg_gen_shli_tl(t1
, t1
, 24);
14911 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14913 case OPC_CMPGDU_LE_QB
:
14915 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
14916 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14917 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
14918 tcg_gen_shli_tl(t1
, t1
, 24);
14919 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14921 case OPC_CMP_EQ_PH
:
14923 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
14925 case OPC_CMP_LT_PH
:
14927 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
14929 case OPC_CMP_LE_PH
:
14931 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
14935 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14939 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14941 case OPC_PACKRL_PH
:
14943 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14947 #ifdef TARGET_MIPS64
14948 case OPC_CMPU_EQ_OB_DSP
:
14950 case OPC_CMP_EQ_PW
:
14952 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
14954 case OPC_CMP_LT_PW
:
14956 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
14958 case OPC_CMP_LE_PW
:
14960 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
14962 case OPC_CMP_EQ_QH
:
14964 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
14966 case OPC_CMP_LT_QH
:
14968 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
14970 case OPC_CMP_LE_QH
:
14972 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
14974 case OPC_CMPGDU_EQ_OB
:
14976 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14978 case OPC_CMPGDU_LT_OB
:
14980 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14982 case OPC_CMPGDU_LE_OB
:
14984 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14986 case OPC_CMPGU_EQ_OB
:
14988 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14990 case OPC_CMPGU_LT_OB
:
14992 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14994 case OPC_CMPGU_LE_OB
:
14996 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14998 case OPC_CMPU_EQ_OB
:
15000 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
15002 case OPC_CMPU_LT_OB
:
15004 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
15006 case OPC_CMPU_LE_OB
:
15008 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
15010 case OPC_PACKRL_PW
:
15012 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
15016 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15020 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15024 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15032 tcg_temp_free(v1_t
);
15033 tcg_temp_free(v2_t
);
15035 (void)opn
; /* avoid a compiler warning */
15036 MIPS_DEBUG("%s", opn
);
15039 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
15040 uint32_t op1
, int rt
, int rs
, int sa
)
15042 const char *opn
= "mipsdsp append/dappend";
15048 /* Treat as NOP. */
15053 t0
= tcg_temp_new();
15054 gen_load_gpr(t0
, rs
);
15057 case OPC_APPEND_DSP
:
15058 switch (MASK_APPEND(ctx
->opcode
)) {
15061 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
15063 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15067 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15068 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
15069 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
15070 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15072 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15076 if (sa
!= 0 && sa
!= 2) {
15077 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
15078 tcg_gen_ext32u_tl(t0
, t0
);
15079 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
15080 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15082 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15084 default: /* Invalid */
15085 MIPS_INVAL("MASK APPEND");
15086 generate_exception(ctx
, EXCP_RI
);
15090 #ifdef TARGET_MIPS64
15091 case OPC_DAPPEND_DSP
:
15092 switch (MASK_DAPPEND(ctx
->opcode
)) {
15095 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
15099 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
15100 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
15101 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
15105 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
15106 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
15107 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15112 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
15113 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
15114 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
15115 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15118 default: /* Invalid */
15119 MIPS_INVAL("MASK DAPPEND");
15120 generate_exception(ctx
, EXCP_RI
);
15127 (void)opn
; /* avoid a compiler warning */
15128 MIPS_DEBUG("%s", opn
);
15131 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15132 int ret
, int v1
, int v2
, int check_ret
)
15135 const char *opn
= "mipsdsp accumulator";
15142 if ((ret
== 0) && (check_ret
== 1)) {
15143 /* Treat as NOP. */
15148 t0
= tcg_temp_new();
15149 t1
= tcg_temp_new();
15150 v1_t
= tcg_temp_new();
15151 v2_t
= tcg_temp_new();
15153 gen_load_gpr(v1_t
, v1
);
15154 gen_load_gpr(v2_t
, v2
);
15157 case OPC_EXTR_W_DSP
:
15161 tcg_gen_movi_tl(t0
, v2
);
15162 tcg_gen_movi_tl(t1
, v1
);
15163 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15166 tcg_gen_movi_tl(t0
, v2
);
15167 tcg_gen_movi_tl(t1
, v1
);
15168 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15170 case OPC_EXTR_RS_W
:
15171 tcg_gen_movi_tl(t0
, v2
);
15172 tcg_gen_movi_tl(t1
, v1
);
15173 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15176 tcg_gen_movi_tl(t0
, v2
);
15177 tcg_gen_movi_tl(t1
, v1
);
15178 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15180 case OPC_EXTRV_S_H
:
15181 tcg_gen_movi_tl(t0
, v2
);
15182 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15185 tcg_gen_movi_tl(t0
, v2
);
15186 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15188 case OPC_EXTRV_R_W
:
15189 tcg_gen_movi_tl(t0
, v2
);
15190 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15192 case OPC_EXTRV_RS_W
:
15193 tcg_gen_movi_tl(t0
, v2
);
15194 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15197 tcg_gen_movi_tl(t0
, v2
);
15198 tcg_gen_movi_tl(t1
, v1
);
15199 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15202 tcg_gen_movi_tl(t0
, v2
);
15203 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15206 tcg_gen_movi_tl(t0
, v2
);
15207 tcg_gen_movi_tl(t1
, v1
);
15208 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15211 tcg_gen_movi_tl(t0
, v2
);
15212 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15215 imm
= (ctx
->opcode
>> 20) & 0x3F;
15216 tcg_gen_movi_tl(t0
, ret
);
15217 tcg_gen_movi_tl(t1
, imm
);
15218 gen_helper_shilo(t0
, t1
, cpu_env
);
15221 tcg_gen_movi_tl(t0
, ret
);
15222 gen_helper_shilo(t0
, v1_t
, cpu_env
);
15225 tcg_gen_movi_tl(t0
, ret
);
15226 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
15229 imm
= (ctx
->opcode
>> 11) & 0x3FF;
15230 tcg_gen_movi_tl(t0
, imm
);
15231 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
15234 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15235 tcg_gen_movi_tl(t0
, imm
);
15236 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
15240 #ifdef TARGET_MIPS64
15241 case OPC_DEXTR_W_DSP
:
15245 tcg_gen_movi_tl(t0
, ret
);
15246 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
15250 int shift
= (ctx
->opcode
>> 19) & 0x7F;
15251 int ac
= (ctx
->opcode
>> 11) & 0x03;
15252 tcg_gen_movi_tl(t0
, shift
);
15253 tcg_gen_movi_tl(t1
, ac
);
15254 gen_helper_dshilo(t0
, t1
, cpu_env
);
15259 int ac
= (ctx
->opcode
>> 11) & 0x03;
15260 tcg_gen_movi_tl(t0
, ac
);
15261 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
15265 tcg_gen_movi_tl(t0
, v2
);
15266 tcg_gen_movi_tl(t1
, v1
);
15268 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15271 tcg_gen_movi_tl(t0
, v2
);
15272 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15275 tcg_gen_movi_tl(t0
, v2
);
15276 tcg_gen_movi_tl(t1
, v1
);
15277 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15280 tcg_gen_movi_tl(t0
, v2
);
15281 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15284 tcg_gen_movi_tl(t0
, v2
);
15285 tcg_gen_movi_tl(t1
, v1
);
15286 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15288 case OPC_DEXTR_R_L
:
15289 tcg_gen_movi_tl(t0
, v2
);
15290 tcg_gen_movi_tl(t1
, v1
);
15291 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15293 case OPC_DEXTR_RS_L
:
15294 tcg_gen_movi_tl(t0
, v2
);
15295 tcg_gen_movi_tl(t1
, v1
);
15296 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15299 tcg_gen_movi_tl(t0
, v2
);
15300 tcg_gen_movi_tl(t1
, v1
);
15301 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15303 case OPC_DEXTR_R_W
:
15304 tcg_gen_movi_tl(t0
, v2
);
15305 tcg_gen_movi_tl(t1
, v1
);
15306 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15308 case OPC_DEXTR_RS_W
:
15309 tcg_gen_movi_tl(t0
, v2
);
15310 tcg_gen_movi_tl(t1
, v1
);
15311 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15313 case OPC_DEXTR_S_H
:
15314 tcg_gen_movi_tl(t0
, v2
);
15315 tcg_gen_movi_tl(t1
, v1
);
15316 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15318 case OPC_DEXTRV_S_H
:
15319 tcg_gen_movi_tl(t0
, v2
);
15320 tcg_gen_movi_tl(t1
, v1
);
15321 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15324 tcg_gen_movi_tl(t0
, v2
);
15325 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15327 case OPC_DEXTRV_R_L
:
15328 tcg_gen_movi_tl(t0
, v2
);
15329 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15331 case OPC_DEXTRV_RS_L
:
15332 tcg_gen_movi_tl(t0
, v2
);
15333 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15336 tcg_gen_movi_tl(t0
, v2
);
15337 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15339 case OPC_DEXTRV_R_W
:
15340 tcg_gen_movi_tl(t0
, v2
);
15341 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15343 case OPC_DEXTRV_RS_W
:
15344 tcg_gen_movi_tl(t0
, v2
);
15345 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15354 tcg_temp_free(v1_t
);
15355 tcg_temp_free(v2_t
);
15357 (void)opn
; /* avoid a compiler warning */
15358 MIPS_DEBUG("%s", opn
);
15361 /* End MIPSDSP functions. */
15363 /* Compact Branches */
15364 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
15365 int rs
, int rt
, int32_t offset
)
15367 int bcond_compute
= 0;
15368 TCGv t0
= tcg_temp_new();
15369 TCGv t1
= tcg_temp_new();
15371 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15372 #ifdef MIPS_DEBUG_DISAS
15373 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
15375 generate_exception(ctx
, EXCP_RI
);
15379 /* Load needed operands and calculate btarget */
15381 /* compact branch */
15382 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
15383 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
15384 gen_load_gpr(t0
, rs
);
15385 gen_load_gpr(t1
, rt
);
15387 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15388 if (rs
<= rt
&& rs
== 0) {
15389 /* OPC_BEQZALC, OPC_BNEZALC */
15390 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15393 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
15394 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
15395 gen_load_gpr(t0
, rs
);
15396 gen_load_gpr(t1
, rt
);
15398 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15400 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
15401 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
15402 if (rs
== 0 || rs
== rt
) {
15403 /* OPC_BLEZALC, OPC_BGEZALC */
15404 /* OPC_BGTZALC, OPC_BLTZALC */
15405 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15407 gen_load_gpr(t0
, rs
);
15408 gen_load_gpr(t1
, rt
);
15410 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15414 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15419 /* OPC_BEQZC, OPC_BNEZC */
15420 gen_load_gpr(t0
, rs
);
15422 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15424 /* OPC_JIC, OPC_JIALC */
15425 TCGv tbase
= tcg_temp_new();
15426 TCGv toffset
= tcg_temp_new();
15428 gen_load_gpr(tbase
, rt
);
15429 tcg_gen_movi_tl(toffset
, offset
);
15430 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
15431 tcg_temp_free(tbase
);
15432 tcg_temp_free(toffset
);
15436 MIPS_INVAL("Compact branch/jump");
15437 generate_exception(ctx
, EXCP_RI
);
15441 if (bcond_compute
== 0) {
15442 /* Uncoditional compact branch */
15445 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15448 ctx
->hflags
|= MIPS_HFLAG_BR
;
15451 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15454 ctx
->hflags
|= MIPS_HFLAG_B
;
15457 MIPS_INVAL("Compact branch/jump");
15458 generate_exception(ctx
, EXCP_RI
);
15462 /* Generating branch here as compact branches don't have delay slot */
15463 gen_branch(ctx
, 4);
15465 /* Conditional compact branch */
15466 int l1
= gen_new_label();
15467 save_cpu_state(ctx
, 0);
15470 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
15471 if (rs
== 0 && rt
!= 0) {
15473 tcg_gen_brcondi_tl(TCG_COND_LE
, t1
, 0, l1
);
15474 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15476 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
15479 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
15482 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
15483 if (rs
== 0 && rt
!= 0) {
15485 tcg_gen_brcondi_tl(TCG_COND_GT
, t1
, 0, l1
);
15486 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15488 tcg_gen_brcondi_tl(TCG_COND_LT
, t1
, 0, l1
);
15491 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
15494 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
15495 if (rs
== 0 && rt
!= 0) {
15497 tcg_gen_brcondi_tl(TCG_COND_LE
, t1
, 0, l1
);
15498 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15500 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
15503 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
15506 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
15507 if (rs
== 0 && rt
!= 0) {
15509 tcg_gen_brcondi_tl(TCG_COND_GT
, t1
, 0, l1
);
15510 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15512 tcg_gen_brcondi_tl(TCG_COND_LT
, t1
, 0, l1
);
15515 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
15518 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
15519 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
15521 /* OPC_BOVC, OPC_BNVC */
15522 TCGv t2
= tcg_temp_new();
15523 TCGv t3
= tcg_temp_new();
15524 TCGv t4
= tcg_temp_new();
15525 TCGv input_overflow
= tcg_temp_new();
15527 gen_load_gpr(t0
, rs
);
15528 gen_load_gpr(t1
, rt
);
15529 tcg_gen_ext32s_tl(t2
, t0
);
15530 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
15531 tcg_gen_ext32s_tl(t3
, t1
);
15532 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
15533 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
15535 tcg_gen_add_tl(t4
, t2
, t3
);
15536 tcg_gen_ext32s_tl(t4
, t4
);
15537 tcg_gen_xor_tl(t2
, t2
, t3
);
15538 tcg_gen_xor_tl(t3
, t4
, t3
);
15539 tcg_gen_andc_tl(t2
, t3
, t2
);
15540 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
15541 tcg_gen_or_tl(t4
, t4
, input_overflow
);
15542 if (opc
== OPC_BOVC
) {
15544 tcg_gen_brcondi_tl(TCG_COND_NE
, t4
, 0, l1
);
15547 tcg_gen_brcondi_tl(TCG_COND_EQ
, t4
, 0, l1
);
15549 tcg_temp_free(input_overflow
);
15553 } else if (rs
< rt
&& rs
== 0) {
15554 /* OPC_BEQZALC, OPC_BNEZALC */
15555 if (opc
== OPC_BEQZALC
) {
15557 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
15560 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
15563 /* OPC_BEQC, OPC_BNEC */
15564 if (opc
== OPC_BEQC
) {
15566 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
15569 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
15574 tcg_gen_brcondi_tl(TCG_COND_EQ
, t0
, 0, l1
);
15577 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
15580 MIPS_INVAL("Compact conditional branch/jump");
15581 generate_exception(ctx
, EXCP_RI
);
15585 /* Generating branch here as compact branches don't have delay slot */
15586 /* TODO: implement forbidden slot */
15587 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
15589 gen_goto_tb(ctx
, 0, ctx
->btarget
);
15590 MIPS_DEBUG("Compact conditional branch");
15591 ctx
->bstate
= BS_BRANCH
;
15599 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
15601 int rs
, rt
, rd
, sa
;
15604 rs
= (ctx
->opcode
>> 21) & 0x1f;
15605 rt
= (ctx
->opcode
>> 16) & 0x1f;
15606 rd
= (ctx
->opcode
>> 11) & 0x1f;
15607 sa
= (ctx
->opcode
>> 6) & 0x1f;
15609 op1
= MASK_SPECIAL(ctx
->opcode
);
15613 int imm2
= extract32(ctx
->opcode
, 6, 3);
15614 TCGv t0
= tcg_temp_new();
15615 TCGv t1
= tcg_temp_new();
15616 gen_load_gpr(t0
, rs
);
15617 gen_load_gpr(t1
, rt
);
15618 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
15619 tcg_gen_add_tl(t0
, t0
, t1
);
15620 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
15625 case OPC_MULT
... OPC_DIVU
:
15626 op2
= MASK_R6_MULDIV(ctx
->opcode
);
15636 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
15639 MIPS_INVAL("special_r6 muldiv");
15640 generate_exception(ctx
, EXCP_RI
);
15646 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
15650 if (rt
== 0 && sa
== 1) {
15651 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15652 We need additionally to check other fields */
15653 gen_cl(ctx
, op1
, rd
, rs
);
15655 generate_exception(ctx
, EXCP_RI
);
15659 generate_exception(ctx
, EXCP_DBp
);
15661 #if defined(TARGET_MIPS64)
15663 check_mips_64(ctx
);
15665 int imm2
= extract32(ctx
->opcode
, 6, 3);
15666 TCGv t0
= tcg_temp_new();
15667 TCGv t1
= tcg_temp_new();
15668 gen_load_gpr(t0
, rs
);
15669 gen_load_gpr(t1
, rt
);
15670 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
15671 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
15678 if (rt
== 0 && sa
== 1) {
15679 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15680 We need additionally to check other fields */
15681 check_mips_64(ctx
);
15682 gen_cl(ctx
, op1
, rd
, rs
);
15684 generate_exception(ctx
, EXCP_RI
);
15687 case OPC_DMULT
... OPC_DDIVU
:
15688 op2
= MASK_R6_MULDIV(ctx
->opcode
);
15698 check_mips_64(ctx
);
15699 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
15702 MIPS_INVAL("special_r6 muldiv");
15703 generate_exception(ctx
, EXCP_RI
);
15708 default: /* Invalid */
15709 MIPS_INVAL("special_r6");
15710 generate_exception(ctx
, EXCP_RI
);
15715 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
15717 int rs
, rt
, rd
, sa
;
15720 rs
= (ctx
->opcode
>> 21) & 0x1f;
15721 rt
= (ctx
->opcode
>> 16) & 0x1f;
15722 rd
= (ctx
->opcode
>> 11) & 0x1f;
15723 sa
= (ctx
->opcode
>> 6) & 0x1f;
15725 op1
= MASK_SPECIAL(ctx
->opcode
);
15727 case OPC_MOVN
: /* Conditional move */
15729 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
15730 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
15731 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
15733 case OPC_MFHI
: /* Move from HI/LO */
15735 gen_HILO(ctx
, op1
, rs
& 3, rd
);
15738 case OPC_MTLO
: /* Move to HI/LO */
15739 gen_HILO(ctx
, op1
, rd
& 3, rs
);
15742 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15743 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15744 check_cp1_enabled(ctx
);
15745 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
15746 (ctx
->opcode
>> 16) & 1);
15748 generate_exception_err(ctx
, EXCP_CpU
, 1);
15754 check_insn(ctx
, INSN_VR54XX
);
15755 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
15756 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
15758 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
15763 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
15765 #if defined(TARGET_MIPS64)
15766 case OPC_DMULT
... OPC_DDIVU
:
15767 check_insn(ctx
, ISA_MIPS3
);
15768 check_mips_64(ctx
);
15769 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
15773 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
15776 #ifdef MIPS_STRICT_STANDARD
15777 MIPS_INVAL("SPIM");
15778 generate_exception(ctx
, EXCP_RI
);
15780 /* Implemented as RI exception for now. */
15781 MIPS_INVAL("spim (unofficial)");
15782 generate_exception(ctx
, EXCP_RI
);
15785 default: /* Invalid */
15786 MIPS_INVAL("special_legacy");
15787 generate_exception(ctx
, EXCP_RI
);
15792 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
15794 int rs
, rt
, rd
, sa
;
15797 rs
= (ctx
->opcode
>> 21) & 0x1f;
15798 rt
= (ctx
->opcode
>> 16) & 0x1f;
15799 rd
= (ctx
->opcode
>> 11) & 0x1f;
15800 sa
= (ctx
->opcode
>> 6) & 0x1f;
15802 op1
= MASK_SPECIAL(ctx
->opcode
);
15804 case OPC_SLL
: /* Shift with immediate */
15806 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15809 switch ((ctx
->opcode
>> 21) & 0x1f) {
15811 /* rotr is decoded as srl on non-R2 CPUs */
15812 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15817 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15820 generate_exception(ctx
, EXCP_RI
);
15824 case OPC_ADD
... OPC_SUBU
:
15825 gen_arith(ctx
, op1
, rd
, rs
, rt
);
15827 case OPC_SLLV
: /* Shifts */
15829 gen_shift(ctx
, op1
, rd
, rs
, rt
);
15832 switch ((ctx
->opcode
>> 6) & 0x1f) {
15834 /* rotrv is decoded as srlv on non-R2 CPUs */
15835 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15840 gen_shift(ctx
, op1
, rd
, rs
, rt
);
15843 generate_exception(ctx
, EXCP_RI
);
15847 case OPC_SLT
: /* Set on less than */
15849 gen_slt(ctx
, op1
, rd
, rs
, rt
);
15851 case OPC_AND
: /* Logic*/
15855 gen_logic(ctx
, op1
, rd
, rs
, rt
);
15858 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
15860 case OPC_TGE
... OPC_TEQ
: /* Traps */
15862 gen_trap(ctx
, op1
, rs
, rt
, -1);
15864 case OPC_LSA
: /* OPC_PMON */
15865 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15866 decode_opc_special_r6(env
, ctx
);
15868 /* Pmon entry point, also R4010 selsl */
15869 #ifdef MIPS_STRICT_STANDARD
15870 MIPS_INVAL("PMON / selsl");
15871 generate_exception(ctx
, EXCP_RI
);
15873 gen_helper_0e0i(pmon
, sa
);
15878 generate_exception(ctx
, EXCP_SYSCALL
);
15879 ctx
->bstate
= BS_STOP
;
15882 generate_exception(ctx
, EXCP_BREAK
);
15885 /* Treat as NOP. */
15888 #if defined(TARGET_MIPS64)
15889 /* MIPS64 specific opcodes */
15894 check_insn(ctx
, ISA_MIPS3
);
15895 check_mips_64(ctx
);
15896 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15899 switch ((ctx
->opcode
>> 21) & 0x1f) {
15901 /* drotr is decoded as dsrl on non-R2 CPUs */
15902 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15907 check_insn(ctx
, ISA_MIPS3
);
15908 check_mips_64(ctx
);
15909 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15912 generate_exception(ctx
, EXCP_RI
);
15917 switch ((ctx
->opcode
>> 21) & 0x1f) {
15919 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
15920 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15925 check_insn(ctx
, ISA_MIPS3
);
15926 check_mips_64(ctx
);
15927 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15930 generate_exception(ctx
, EXCP_RI
);
15934 case OPC_DADD
... OPC_DSUBU
:
15935 check_insn(ctx
, ISA_MIPS3
);
15936 check_mips_64(ctx
);
15937 gen_arith(ctx
, op1
, rd
, rs
, rt
);
15941 check_insn(ctx
, ISA_MIPS3
);
15942 check_mips_64(ctx
);
15943 gen_shift(ctx
, op1
, rd
, rs
, rt
);
15946 switch ((ctx
->opcode
>> 6) & 0x1f) {
15948 /* drotrv is decoded as dsrlv on non-R2 CPUs */
15949 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15954 check_insn(ctx
, ISA_MIPS3
);
15955 check_mips_64(ctx
);
15956 gen_shift(ctx
, op1
, rd
, rs
, rt
);
15959 generate_exception(ctx
, EXCP_RI
);
15965 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15966 decode_opc_special_r6(env
, ctx
);
15968 decode_opc_special_legacy(env
, ctx
);
15973 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
15978 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
15980 rs
= (ctx
->opcode
>> 21) & 0x1f;
15981 rt
= (ctx
->opcode
>> 16) & 0x1f;
15982 rd
= (ctx
->opcode
>> 11) & 0x1f;
15984 op1
= MASK_SPECIAL2(ctx
->opcode
);
15986 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
15987 case OPC_MSUB
... OPC_MSUBU
:
15988 check_insn(ctx
, ISA_MIPS32
);
15989 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
15992 gen_arith(ctx
, op1
, rd
, rs
, rt
);
15995 case OPC_DIVU_G_2F
:
15996 case OPC_MULT_G_2F
:
15997 case OPC_MULTU_G_2F
:
15999 case OPC_MODU_G_2F
:
16000 check_insn(ctx
, INSN_LOONGSON2F
);
16001 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16005 check_insn(ctx
, ISA_MIPS32
);
16006 gen_cl(ctx
, op1
, rd
, rs
);
16009 /* XXX: not clear which exception should be raised
16010 * when in debug mode...
16012 check_insn(ctx
, ISA_MIPS32
);
16013 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
16014 generate_exception(ctx
, EXCP_DBp
);
16016 generate_exception(ctx
, EXCP_DBp
);
16018 /* Treat as NOP. */
16020 #if defined(TARGET_MIPS64)
16023 check_insn(ctx
, ISA_MIPS64
);
16024 check_mips_64(ctx
);
16025 gen_cl(ctx
, op1
, rd
, rs
);
16027 case OPC_DMULT_G_2F
:
16028 case OPC_DMULTU_G_2F
:
16029 case OPC_DDIV_G_2F
:
16030 case OPC_DDIVU_G_2F
:
16031 case OPC_DMOD_G_2F
:
16032 case OPC_DMODU_G_2F
:
16033 check_insn(ctx
, INSN_LOONGSON2F
);
16034 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16037 default: /* Invalid */
16038 MIPS_INVAL("special2_legacy");
16039 generate_exception(ctx
, EXCP_RI
);
16044 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
16046 int rs
, rt
, rd
, sa
;
16050 rs
= (ctx
->opcode
>> 21) & 0x1f;
16051 rt
= (ctx
->opcode
>> 16) & 0x1f;
16052 rd
= (ctx
->opcode
>> 11) & 0x1f;
16053 sa
= (ctx
->opcode
>> 6) & 0x1f;
16054 imm
= (int16_t)ctx
->opcode
>> 7;
16056 op1
= MASK_SPECIAL3(ctx
->opcode
);
16060 /* hint codes 24-31 are reserved and signal RI */
16061 generate_exception(ctx
, EXCP_RI
);
16063 /* Treat as NOP. */
16066 /* Treat as NOP. */
16069 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
16072 gen_ld(ctx
, op1
, rt
, rs
, imm
);
16077 /* Treat as NOP. */
16080 TCGv t0
= tcg_temp_new();
16081 gen_load_gpr(t0
, rt
);
16083 op2
= MASK_BSHFL(ctx
->opcode
);
16085 case OPC_ALIGN
... OPC_ALIGN_END
:
16088 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
16090 TCGv t1
= tcg_temp_new();
16091 TCGv_i64 t2
= tcg_temp_new_i64();
16092 gen_load_gpr(t1
, rs
);
16093 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
16094 tcg_gen_shri_i64(t2
, t2
, 8 * (4 - sa
));
16095 #if defined(TARGET_MIPS64)
16096 tcg_gen_ext32s_i64(cpu_gpr
[rd
], t2
);
16098 tcg_gen_trunc_i64_i32(cpu_gpr
[rd
], t2
);
16100 tcg_temp_free_i64(t2
);
16105 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
16111 #if defined(TARGET_MIPS64)
16113 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
16116 gen_ld(ctx
, op1
, rt
, rs
, imm
);
16119 check_mips_64(ctx
);
16122 /* Treat as NOP. */
16125 TCGv t0
= tcg_temp_new();
16126 gen_load_gpr(t0
, rt
);
16128 op2
= MASK_DBSHFL(ctx
->opcode
);
16130 case OPC_DALIGN
... OPC_DALIGN_END
:
16133 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
16135 TCGv t1
= tcg_temp_new();
16136 gen_load_gpr(t1
, rs
);
16137 tcg_gen_shli_tl(t0
, t0
, 8 * sa
);
16138 tcg_gen_shri_tl(t1
, t1
, 8 * (8 - sa
));
16139 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
16144 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
16151 default: /* Invalid */
16152 MIPS_INVAL("special3_r6");
16153 generate_exception(ctx
, EXCP_RI
);
16158 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16163 rs
= (ctx
->opcode
>> 21) & 0x1f;
16164 rt
= (ctx
->opcode
>> 16) & 0x1f;
16165 rd
= (ctx
->opcode
>> 11) & 0x1f;
16167 op1
= MASK_SPECIAL3(ctx
->opcode
);
16169 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
16170 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
16171 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
16172 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16173 * the same mask and op1. */
16174 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
16175 op2
= MASK_ADDUH_QB(ctx
->opcode
);
16178 case OPC_ADDUH_R_QB
:
16180 case OPC_ADDQH_R_PH
:
16182 case OPC_ADDQH_R_W
:
16184 case OPC_SUBUH_R_QB
:
16186 case OPC_SUBQH_R_PH
:
16188 case OPC_SUBQH_R_W
:
16189 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16194 case OPC_MULQ_RS_W
:
16195 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16198 MIPS_INVAL("MASK ADDUH.QB");
16199 generate_exception(ctx
, EXCP_RI
);
16202 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
16203 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16205 generate_exception(ctx
, EXCP_RI
);
16209 op2
= MASK_LX(ctx
->opcode
);
16211 #if defined(TARGET_MIPS64)
16217 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
16219 default: /* Invalid */
16220 MIPS_INVAL("MASK LX");
16221 generate_exception(ctx
, EXCP_RI
);
16225 case OPC_ABSQ_S_PH_DSP
:
16226 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
16228 case OPC_ABSQ_S_QB
:
16229 case OPC_ABSQ_S_PH
:
16231 case OPC_PRECEQ_W_PHL
:
16232 case OPC_PRECEQ_W_PHR
:
16233 case OPC_PRECEQU_PH_QBL
:
16234 case OPC_PRECEQU_PH_QBR
:
16235 case OPC_PRECEQU_PH_QBLA
:
16236 case OPC_PRECEQU_PH_QBRA
:
16237 case OPC_PRECEU_PH_QBL
:
16238 case OPC_PRECEU_PH_QBR
:
16239 case OPC_PRECEU_PH_QBLA
:
16240 case OPC_PRECEU_PH_QBRA
:
16241 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16248 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
16251 MIPS_INVAL("MASK ABSQ_S.PH");
16252 generate_exception(ctx
, EXCP_RI
);
16256 case OPC_ADDU_QB_DSP
:
16257 op2
= MASK_ADDU_QB(ctx
->opcode
);
16260 case OPC_ADDQ_S_PH
:
16263 case OPC_ADDU_S_QB
:
16265 case OPC_ADDU_S_PH
:
16267 case OPC_SUBQ_S_PH
:
16270 case OPC_SUBU_S_QB
:
16272 case OPC_SUBU_S_PH
:
16276 case OPC_RADDU_W_QB
:
16277 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16279 case OPC_MULEU_S_PH_QBL
:
16280 case OPC_MULEU_S_PH_QBR
:
16281 case OPC_MULQ_RS_PH
:
16282 case OPC_MULEQ_S_W_PHL
:
16283 case OPC_MULEQ_S_W_PHR
:
16284 case OPC_MULQ_S_PH
:
16285 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16287 default: /* Invalid */
16288 MIPS_INVAL("MASK ADDU.QB");
16289 generate_exception(ctx
, EXCP_RI
);
16294 case OPC_CMPU_EQ_QB_DSP
:
16295 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
16297 case OPC_PRECR_SRA_PH_W
:
16298 case OPC_PRECR_SRA_R_PH_W
:
16299 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
16301 case OPC_PRECR_QB_PH
:
16302 case OPC_PRECRQ_QB_PH
:
16303 case OPC_PRECRQ_PH_W
:
16304 case OPC_PRECRQ_RS_PH_W
:
16305 case OPC_PRECRQU_S_QB_PH
:
16306 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16308 case OPC_CMPU_EQ_QB
:
16309 case OPC_CMPU_LT_QB
:
16310 case OPC_CMPU_LE_QB
:
16311 case OPC_CMP_EQ_PH
:
16312 case OPC_CMP_LT_PH
:
16313 case OPC_CMP_LE_PH
:
16314 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16316 case OPC_CMPGU_EQ_QB
:
16317 case OPC_CMPGU_LT_QB
:
16318 case OPC_CMPGU_LE_QB
:
16319 case OPC_CMPGDU_EQ_QB
:
16320 case OPC_CMPGDU_LT_QB
:
16321 case OPC_CMPGDU_LE_QB
:
16324 case OPC_PACKRL_PH
:
16325 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16327 default: /* Invalid */
16328 MIPS_INVAL("MASK CMPU.EQ.QB");
16329 generate_exception(ctx
, EXCP_RI
);
16333 case OPC_SHLL_QB_DSP
:
16334 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
16336 case OPC_DPA_W_PH_DSP
:
16337 op2
= MASK_DPA_W_PH(ctx
->opcode
);
16339 case OPC_DPAU_H_QBL
:
16340 case OPC_DPAU_H_QBR
:
16341 case OPC_DPSU_H_QBL
:
16342 case OPC_DPSU_H_QBR
:
16344 case OPC_DPAX_W_PH
:
16345 case OPC_DPAQ_S_W_PH
:
16346 case OPC_DPAQX_S_W_PH
:
16347 case OPC_DPAQX_SA_W_PH
:
16349 case OPC_DPSX_W_PH
:
16350 case OPC_DPSQ_S_W_PH
:
16351 case OPC_DPSQX_S_W_PH
:
16352 case OPC_DPSQX_SA_W_PH
:
16353 case OPC_MULSAQ_S_W_PH
:
16354 case OPC_DPAQ_SA_L_W
:
16355 case OPC_DPSQ_SA_L_W
:
16356 case OPC_MAQ_S_W_PHL
:
16357 case OPC_MAQ_S_W_PHR
:
16358 case OPC_MAQ_SA_W_PHL
:
16359 case OPC_MAQ_SA_W_PHR
:
16360 case OPC_MULSA_W_PH
:
16361 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16363 default: /* Invalid */
16364 MIPS_INVAL("MASK DPAW.PH");
16365 generate_exception(ctx
, EXCP_RI
);
16370 op2
= MASK_INSV(ctx
->opcode
);
16382 t0
= tcg_temp_new();
16383 t1
= tcg_temp_new();
16385 gen_load_gpr(t0
, rt
);
16386 gen_load_gpr(t1
, rs
);
16388 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
16394 default: /* Invalid */
16395 MIPS_INVAL("MASK INSV");
16396 generate_exception(ctx
, EXCP_RI
);
16400 case OPC_APPEND_DSP
:
16401 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
16403 case OPC_EXTR_W_DSP
:
16404 op2
= MASK_EXTR_W(ctx
->opcode
);
16408 case OPC_EXTR_RS_W
:
16410 case OPC_EXTRV_S_H
:
16412 case OPC_EXTRV_R_W
:
16413 case OPC_EXTRV_RS_W
:
16418 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
16421 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16427 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16429 default: /* Invalid */
16430 MIPS_INVAL("MASK EXTR.W");
16431 generate_exception(ctx
, EXCP_RI
);
16435 #if defined(TARGET_MIPS64)
16436 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
16437 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
16438 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
16439 check_insn(ctx
, INSN_LOONGSON2E
);
16440 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16442 case OPC_ABSQ_S_QH_DSP
:
16443 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
16445 case OPC_PRECEQ_L_PWL
:
16446 case OPC_PRECEQ_L_PWR
:
16447 case OPC_PRECEQ_PW_QHL
:
16448 case OPC_PRECEQ_PW_QHR
:
16449 case OPC_PRECEQ_PW_QHLA
:
16450 case OPC_PRECEQ_PW_QHRA
:
16451 case OPC_PRECEQU_QH_OBL
:
16452 case OPC_PRECEQU_QH_OBR
:
16453 case OPC_PRECEQU_QH_OBLA
:
16454 case OPC_PRECEQU_QH_OBRA
:
16455 case OPC_PRECEU_QH_OBL
:
16456 case OPC_PRECEU_QH_OBR
:
16457 case OPC_PRECEU_QH_OBLA
:
16458 case OPC_PRECEU_QH_OBRA
:
16459 case OPC_ABSQ_S_OB
:
16460 case OPC_ABSQ_S_PW
:
16461 case OPC_ABSQ_S_QH
:
16462 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16470 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
16472 default: /* Invalid */
16473 MIPS_INVAL("MASK ABSQ_S.QH");
16474 generate_exception(ctx
, EXCP_RI
);
16478 case OPC_ADDU_OB_DSP
:
16479 op2
= MASK_ADDU_OB(ctx
->opcode
);
16481 case OPC_RADDU_L_OB
:
16483 case OPC_SUBQ_S_PW
:
16485 case OPC_SUBQ_S_QH
:
16487 case OPC_SUBU_S_OB
:
16489 case OPC_SUBU_S_QH
:
16491 case OPC_SUBUH_R_OB
:
16493 case OPC_ADDQ_S_PW
:
16495 case OPC_ADDQ_S_QH
:
16497 case OPC_ADDU_S_OB
:
16499 case OPC_ADDU_S_QH
:
16501 case OPC_ADDUH_R_OB
:
16502 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16504 case OPC_MULEQ_S_PW_QHL
:
16505 case OPC_MULEQ_S_PW_QHR
:
16506 case OPC_MULEU_S_QH_OBL
:
16507 case OPC_MULEU_S_QH_OBR
:
16508 case OPC_MULQ_RS_QH
:
16509 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16511 default: /* Invalid */
16512 MIPS_INVAL("MASK ADDU.OB");
16513 generate_exception(ctx
, EXCP_RI
);
16517 case OPC_CMPU_EQ_OB_DSP
:
16518 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
16520 case OPC_PRECR_SRA_QH_PW
:
16521 case OPC_PRECR_SRA_R_QH_PW
:
16522 /* Return value is rt. */
16523 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
16525 case OPC_PRECR_OB_QH
:
16526 case OPC_PRECRQ_OB_QH
:
16527 case OPC_PRECRQ_PW_L
:
16528 case OPC_PRECRQ_QH_PW
:
16529 case OPC_PRECRQ_RS_QH_PW
:
16530 case OPC_PRECRQU_S_OB_QH
:
16531 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16533 case OPC_CMPU_EQ_OB
:
16534 case OPC_CMPU_LT_OB
:
16535 case OPC_CMPU_LE_OB
:
16536 case OPC_CMP_EQ_QH
:
16537 case OPC_CMP_LT_QH
:
16538 case OPC_CMP_LE_QH
:
16539 case OPC_CMP_EQ_PW
:
16540 case OPC_CMP_LT_PW
:
16541 case OPC_CMP_LE_PW
:
16542 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16544 case OPC_CMPGDU_EQ_OB
:
16545 case OPC_CMPGDU_LT_OB
:
16546 case OPC_CMPGDU_LE_OB
:
16547 case OPC_CMPGU_EQ_OB
:
16548 case OPC_CMPGU_LT_OB
:
16549 case OPC_CMPGU_LE_OB
:
16550 case OPC_PACKRL_PW
:
16554 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16556 default: /* Invalid */
16557 MIPS_INVAL("MASK CMPU_EQ.OB");
16558 generate_exception(ctx
, EXCP_RI
);
16562 case OPC_DAPPEND_DSP
:
16563 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
16565 case OPC_DEXTR_W_DSP
:
16566 op2
= MASK_DEXTR_W(ctx
->opcode
);
16573 case OPC_DEXTR_R_L
:
16574 case OPC_DEXTR_RS_L
:
16576 case OPC_DEXTR_R_W
:
16577 case OPC_DEXTR_RS_W
:
16578 case OPC_DEXTR_S_H
:
16580 case OPC_DEXTRV_R_L
:
16581 case OPC_DEXTRV_RS_L
:
16582 case OPC_DEXTRV_S_H
:
16584 case OPC_DEXTRV_R_W
:
16585 case OPC_DEXTRV_RS_W
:
16586 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
16591 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16593 default: /* Invalid */
16594 MIPS_INVAL("MASK EXTR.W");
16595 generate_exception(ctx
, EXCP_RI
);
16599 case OPC_DPAQ_W_QH_DSP
:
16600 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
16602 case OPC_DPAU_H_OBL
:
16603 case OPC_DPAU_H_OBR
:
16604 case OPC_DPSU_H_OBL
:
16605 case OPC_DPSU_H_OBR
:
16607 case OPC_DPAQ_S_W_QH
:
16609 case OPC_DPSQ_S_W_QH
:
16610 case OPC_MULSAQ_S_W_QH
:
16611 case OPC_DPAQ_SA_L_PW
:
16612 case OPC_DPSQ_SA_L_PW
:
16613 case OPC_MULSAQ_S_L_PW
:
16614 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16616 case OPC_MAQ_S_W_QHLL
:
16617 case OPC_MAQ_S_W_QHLR
:
16618 case OPC_MAQ_S_W_QHRL
:
16619 case OPC_MAQ_S_W_QHRR
:
16620 case OPC_MAQ_SA_W_QHLL
:
16621 case OPC_MAQ_SA_W_QHLR
:
16622 case OPC_MAQ_SA_W_QHRL
:
16623 case OPC_MAQ_SA_W_QHRR
:
16624 case OPC_MAQ_S_L_PWL
:
16625 case OPC_MAQ_S_L_PWR
:
16630 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16632 default: /* Invalid */
16633 MIPS_INVAL("MASK DPAQ.W.QH");
16634 generate_exception(ctx
, EXCP_RI
);
16638 case OPC_DINSV_DSP
:
16639 op2
= MASK_INSV(ctx
->opcode
);
16651 t0
= tcg_temp_new();
16652 t1
= tcg_temp_new();
16654 gen_load_gpr(t0
, rt
);
16655 gen_load_gpr(t1
, rs
);
16657 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
16663 default: /* Invalid */
16664 MIPS_INVAL("MASK DINSV");
16665 generate_exception(ctx
, EXCP_RI
);
16669 case OPC_SHLL_OB_DSP
:
16670 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
16673 default: /* Invalid */
16674 MIPS_INVAL("special3_legacy");
16675 generate_exception(ctx
, EXCP_RI
);
16680 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
16682 int rs
, rt
, rd
, sa
;
16685 rs
= (ctx
->opcode
>> 21) & 0x1f;
16686 rt
= (ctx
->opcode
>> 16) & 0x1f;
16687 rd
= (ctx
->opcode
>> 11) & 0x1f;
16688 sa
= (ctx
->opcode
>> 6) & 0x1f;
16690 op1
= MASK_SPECIAL3(ctx
->opcode
);
16694 check_insn(ctx
, ISA_MIPS32R2
);
16695 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
16698 op2
= MASK_BSHFL(ctx
->opcode
);
16700 case OPC_ALIGN
... OPC_ALIGN_END
:
16702 check_insn(ctx
, ISA_MIPS32R6
);
16703 decode_opc_special3_r6(env
, ctx
);
16706 check_insn(ctx
, ISA_MIPS32R2
);
16707 gen_bshfl(ctx
, op2
, rt
, rd
);
16711 #if defined(TARGET_MIPS64)
16712 case OPC_DEXTM
... OPC_DEXT
:
16713 case OPC_DINSM
... OPC_DINS
:
16714 check_insn(ctx
, ISA_MIPS64R2
);
16715 check_mips_64(ctx
);
16716 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
16719 op2
= MASK_DBSHFL(ctx
->opcode
);
16721 case OPC_DALIGN
... OPC_DALIGN_END
:
16723 check_insn(ctx
, ISA_MIPS32R6
);
16724 decode_opc_special3_r6(env
, ctx
);
16727 check_insn(ctx
, ISA_MIPS64R2
);
16728 check_mips_64(ctx
);
16729 op2
= MASK_DBSHFL(ctx
->opcode
);
16730 gen_bshfl(ctx
, op2
, rt
, rd
);
16736 gen_rdhwr(ctx
, rt
, rd
);
16739 check_insn(ctx
, ASE_MT
);
16741 TCGv t0
= tcg_temp_new();
16742 TCGv t1
= tcg_temp_new();
16744 gen_load_gpr(t0
, rt
);
16745 gen_load_gpr(t1
, rs
);
16746 gen_helper_fork(t0
, t1
);
16752 check_insn(ctx
, ASE_MT
);
16754 TCGv t0
= tcg_temp_new();
16756 save_cpu_state(ctx
, 1);
16757 gen_load_gpr(t0
, rs
);
16758 gen_helper_yield(t0
, cpu_env
, t0
);
16759 gen_store_gpr(t0
, rd
);
16764 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16765 decode_opc_special3_r6(env
, ctx
);
16767 decode_opc_special3_legacy(env
, ctx
);
16772 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
16775 int rs
, rt
, rd
, sa
;
16779 /* make sure instructions are on a word boundary */
16780 if (ctx
->pc
& 0x3) {
16781 env
->CP0_BadVAddr
= ctx
->pc
;
16782 generate_exception(ctx
, EXCP_AdEL
);
16786 /* Handle blikely not taken case */
16787 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
16788 int l1
= gen_new_label();
16790 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
16791 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
16792 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
16793 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
16797 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
16798 tcg_gen_debug_insn_start(ctx
->pc
);
16801 op
= MASK_OP_MAJOR(ctx
->opcode
);
16802 rs
= (ctx
->opcode
>> 21) & 0x1f;
16803 rt
= (ctx
->opcode
>> 16) & 0x1f;
16804 rd
= (ctx
->opcode
>> 11) & 0x1f;
16805 sa
= (ctx
->opcode
>> 6) & 0x1f;
16806 imm
= (int16_t)ctx
->opcode
;
16809 decode_opc_special(env
, ctx
);
16812 decode_opc_special2_legacy(env
, ctx
);
16815 decode_opc_special3(env
, ctx
);
16818 op1
= MASK_REGIMM(ctx
->opcode
);
16820 case OPC_BLTZL
: /* REGIMM branches */
16824 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16827 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
16831 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16833 /* OPC_NAL, OPC_BAL */
16834 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
16836 generate_exception(ctx
, EXCP_RI
);
16839 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
16842 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
16844 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16845 gen_trap(ctx
, op1
, rs
, -1, imm
);
16848 check_insn(ctx
, ISA_MIPS32R2
);
16849 /* Break the TB to be able to sync copied instructions
16851 ctx
->bstate
= BS_STOP
;
16853 case OPC_BPOSGE32
: /* MIPS DSP branch */
16854 #if defined(TARGET_MIPS64)
16858 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
16860 #if defined(TARGET_MIPS64)
16862 check_insn(ctx
, ISA_MIPS32R6
);
16863 check_mips_64(ctx
);
16865 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
16867 MIPS_DEBUG("dahi %s, %04x", regnames
[rs
], imm
);
16870 check_insn(ctx
, ISA_MIPS32R6
);
16871 check_mips_64(ctx
);
16873 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
16875 MIPS_DEBUG("dati %s, %04x", regnames
[rs
], imm
);
16878 default: /* Invalid */
16879 MIPS_INVAL("regimm");
16880 generate_exception(ctx
, EXCP_RI
);
16885 check_cp0_enabled(ctx
);
16886 op1
= MASK_CP0(ctx
->opcode
);
16892 #if defined(TARGET_MIPS64)
16896 #ifndef CONFIG_USER_ONLY
16897 gen_cp0(env
, ctx
, op1
, rt
, rd
);
16898 #endif /* !CONFIG_USER_ONLY */
16900 case OPC_C0_FIRST
... OPC_C0_LAST
:
16901 #ifndef CONFIG_USER_ONLY
16902 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
16903 #endif /* !CONFIG_USER_ONLY */
16906 #ifndef CONFIG_USER_ONLY
16909 TCGv t0
= tcg_temp_new();
16911 op2
= MASK_MFMC0(ctx
->opcode
);
16914 check_insn(ctx
, ASE_MT
);
16915 gen_helper_dmt(t0
);
16916 gen_store_gpr(t0
, rt
);
16919 check_insn(ctx
, ASE_MT
);
16920 gen_helper_emt(t0
);
16921 gen_store_gpr(t0
, rt
);
16924 check_insn(ctx
, ASE_MT
);
16925 gen_helper_dvpe(t0
, cpu_env
);
16926 gen_store_gpr(t0
, rt
);
16929 check_insn(ctx
, ASE_MT
);
16930 gen_helper_evpe(t0
, cpu_env
);
16931 gen_store_gpr(t0
, rt
);
16934 check_insn(ctx
, ISA_MIPS32R2
);
16935 save_cpu_state(ctx
, 1);
16936 gen_helper_di(t0
, cpu_env
);
16937 gen_store_gpr(t0
, rt
);
16938 /* Stop translation as we may have switched the execution mode */
16939 ctx
->bstate
= BS_STOP
;
16942 check_insn(ctx
, ISA_MIPS32R2
);
16943 save_cpu_state(ctx
, 1);
16944 gen_helper_ei(t0
, cpu_env
);
16945 gen_store_gpr(t0
, rt
);
16946 /* Stop translation as we may have switched the execution mode */
16947 ctx
->bstate
= BS_STOP
;
16949 default: /* Invalid */
16950 MIPS_INVAL("mfmc0");
16951 generate_exception(ctx
, EXCP_RI
);
16956 #endif /* !CONFIG_USER_ONLY */
16959 check_insn(ctx
, ISA_MIPS32R2
);
16960 gen_load_srsgpr(rt
, rd
);
16963 check_insn(ctx
, ISA_MIPS32R2
);
16964 gen_store_srsgpr(rt
, rd
);
16968 generate_exception(ctx
, EXCP_RI
);
16972 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
16973 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16974 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
16975 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
16978 /* Arithmetic with immediate opcode */
16979 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
16983 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
16985 case OPC_SLTI
: /* Set on less than with immediate opcode */
16987 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
16989 case OPC_ANDI
: /* Arithmetic with immediate opcode */
16990 case OPC_LUI
: /* OPC_AUI */
16993 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
16995 case OPC_J
... OPC_JAL
: /* Jump */
16996 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
16997 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
17000 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
17001 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17003 generate_exception(ctx
, EXCP_RI
);
17006 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
17007 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17010 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17013 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
17014 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17016 generate_exception(ctx
, EXCP_RI
);
17019 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
17020 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17023 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17026 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
17029 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17031 check_insn(ctx
, ISA_MIPS32R6
);
17032 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
17033 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17036 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
17039 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17041 check_insn(ctx
, ISA_MIPS32R6
);
17042 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
17043 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17048 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17051 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17053 case OPC_LWL
: /* Load and stores */
17056 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17057 case OPC_LB
... OPC_LH
:
17058 case OPC_LW
... OPC_LHU
:
17059 gen_ld(ctx
, op
, rt
, rs
, imm
);
17063 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17064 case OPC_SB
... OPC_SH
:
17066 gen_st(ctx
, op
, rt
, rs
, imm
);
17069 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17070 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
17073 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17074 check_cp0_enabled(ctx
);
17075 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
17076 /* Treat as NOP. */
17079 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17080 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
17081 /* Treat as NOP. */
17084 /* Floating point (COP1). */
17089 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
17093 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
17094 check_cp1_enabled(ctx
);
17095 op1
= MASK_CP1(ctx
->opcode
);
17099 check_insn(ctx
, ISA_MIPS32R2
);
17104 gen_cp1(ctx
, op1
, rt
, rd
);
17106 #if defined(TARGET_MIPS64)
17109 check_insn(ctx
, ISA_MIPS3
);
17110 gen_cp1(ctx
, op1
, rt
, rd
);
17113 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
17114 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17116 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
17121 check_insn(ctx
, ASE_MIPS3D
);
17122 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
17123 (rt
>> 2) & 0x7, imm
<< 2);
17127 check_insn(ctx
, ISA_MIPS32R6
);
17128 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
17132 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17134 check_insn(ctx
, ASE_MIPS3D
);
17137 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17138 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
17139 (rt
>> 2) & 0x7, imm
<< 2);
17142 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17145 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
17151 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
17152 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17154 case R6_OPC_CMP_AF_S
:
17155 case R6_OPC_CMP_UN_S
:
17156 case R6_OPC_CMP_EQ_S
:
17157 case R6_OPC_CMP_UEQ_S
:
17158 case R6_OPC_CMP_LT_S
:
17159 case R6_OPC_CMP_ULT_S
:
17160 case R6_OPC_CMP_LE_S
:
17161 case R6_OPC_CMP_ULE_S
:
17162 case R6_OPC_CMP_SAF_S
:
17163 case R6_OPC_CMP_SUN_S
:
17164 case R6_OPC_CMP_SEQ_S
:
17165 case R6_OPC_CMP_SEUQ_S
:
17166 case R6_OPC_CMP_SLT_S
:
17167 case R6_OPC_CMP_SULT_S
:
17168 case R6_OPC_CMP_SLE_S
:
17169 case R6_OPC_CMP_SULE_S
:
17170 case R6_OPC_CMP_OR_S
:
17171 case R6_OPC_CMP_UNE_S
:
17172 case R6_OPC_CMP_NE_S
:
17173 case R6_OPC_CMP_SOR_S
:
17174 case R6_OPC_CMP_SUNE_S
:
17175 case R6_OPC_CMP_SNE_S
:
17176 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
17178 case R6_OPC_CMP_AF_D
:
17179 case R6_OPC_CMP_UN_D
:
17180 case R6_OPC_CMP_EQ_D
:
17181 case R6_OPC_CMP_UEQ_D
:
17182 case R6_OPC_CMP_LT_D
:
17183 case R6_OPC_CMP_ULT_D
:
17184 case R6_OPC_CMP_LE_D
:
17185 case R6_OPC_CMP_ULE_D
:
17186 case R6_OPC_CMP_SAF_D
:
17187 case R6_OPC_CMP_SUN_D
:
17188 case R6_OPC_CMP_SEQ_D
:
17189 case R6_OPC_CMP_SEUQ_D
:
17190 case R6_OPC_CMP_SLT_D
:
17191 case R6_OPC_CMP_SULT_D
:
17192 case R6_OPC_CMP_SLE_D
:
17193 case R6_OPC_CMP_SULE_D
:
17194 case R6_OPC_CMP_OR_D
:
17195 case R6_OPC_CMP_UNE_D
:
17196 case R6_OPC_CMP_NE_D
:
17197 case R6_OPC_CMP_SOR_D
:
17198 case R6_OPC_CMP_SUNE_D
:
17199 case R6_OPC_CMP_SNE_D
:
17200 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
17203 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
17208 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
17215 generate_exception (ctx
, EXCP_RI
);
17219 generate_exception_err(ctx
, EXCP_CpU
, 1);
17223 /* Compact branches [R6] and COP2 [non-R6] */
17224 case OPC_BC
: /* OPC_LWC2 */
17225 case OPC_BALC
: /* OPC_SWC2 */
17226 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17227 /* OPC_BC, OPC_BALC */
17228 gen_compute_compact_branch(ctx
, op
, 0, 0,
17229 sextract32(ctx
->opcode
<< 2, 0, 28));
17231 /* OPC_LWC2, OPC_SWC2 */
17232 /* COP2: Not implemented. */
17233 generate_exception_err(ctx
, EXCP_CpU
, 2);
17236 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
17237 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
17238 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17240 /* OPC_BEQZC, OPC_BNEZC */
17241 gen_compute_compact_branch(ctx
, op
, rs
, 0,
17242 sextract32(ctx
->opcode
<< 2, 0, 23));
17244 /* OPC_JIC, OPC_JIALC */
17245 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
17248 /* OPC_LWC2, OPC_SWC2 */
17249 /* COP2: Not implemented. */
17250 generate_exception_err(ctx
, EXCP_CpU
, 2);
17254 check_insn(ctx
, INSN_LOONGSON2F
);
17255 /* Note that these instructions use different fields. */
17256 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
17260 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17261 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
17262 check_cp1_enabled(ctx
);
17263 op1
= MASK_CP3(ctx
->opcode
);
17271 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
17274 /* Treat as NOP. */
17289 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
17293 generate_exception (ctx
, EXCP_RI
);
17297 generate_exception_err(ctx
, EXCP_CpU
, 1);
17301 #if defined(TARGET_MIPS64)
17302 /* MIPS64 opcodes */
17303 case OPC_LDL
... OPC_LDR
:
17305 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17308 check_insn(ctx
, ISA_MIPS3
);
17309 check_mips_64(ctx
);
17310 gen_ld(ctx
, op
, rt
, rs
, imm
);
17312 case OPC_SDL
... OPC_SDR
:
17313 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17315 check_insn(ctx
, ISA_MIPS3
);
17316 check_mips_64(ctx
);
17317 gen_st(ctx
, op
, rt
, rs
, imm
);
17320 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17321 check_insn(ctx
, ISA_MIPS3
);
17322 check_mips_64(ctx
);
17323 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
17325 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
17326 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17327 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
17328 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17331 check_insn(ctx
, ISA_MIPS3
);
17332 check_mips_64(ctx
);
17333 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17337 check_insn(ctx
, ISA_MIPS3
);
17338 check_mips_64(ctx
);
17339 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17342 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
17343 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17344 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17346 MIPS_INVAL("major opcode");
17347 generate_exception(ctx
, EXCP_RI
);
17351 case OPC_DAUI
: /* OPC_JALX */
17352 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17353 #if defined(TARGET_MIPS64)
17355 check_mips_64(ctx
);
17357 TCGv t0
= tcg_temp_new();
17358 gen_load_gpr(t0
, rs
);
17359 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
17362 MIPS_DEBUG("daui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
17364 generate_exception(ctx
, EXCP_RI
);
17365 MIPS_INVAL("major opcode");
17369 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
17370 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17371 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
17375 check_insn(ctx
, ASE_MDMX
);
17376 /* MDMX: Not implemented. */
17379 check_insn(ctx
, ISA_MIPS32R6
);
17380 gen_pcrel(ctx
, rs
, imm
);
17382 default: /* Invalid */
17383 MIPS_INVAL("major opcode");
17384 generate_exception(ctx
, EXCP_RI
);
17390 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
17393 CPUState
*cs
= CPU(cpu
);
17394 CPUMIPSState
*env
= &cpu
->env
;
17396 target_ulong pc_start
;
17397 uint16_t *gen_opc_end
;
17406 qemu_log("search pc %d\n", search_pc
);
17409 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
17412 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
17413 ctx
.insn_flags
= env
->insn_flags
;
17414 ctx
.CP0_Config1
= env
->CP0_Config1
;
17416 ctx
.bstate
= BS_NONE
;
17417 /* Restore delay slot state from the tb context. */
17418 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
17419 ctx
.ulri
= env
->CP0_Config3
& (1 << CP0C3_ULRI
);
17420 restore_cpu_state(env
, &ctx
);
17421 #ifdef CONFIG_USER_ONLY
17422 ctx
.mem_idx
= MIPS_HFLAG_UM
;
17424 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
17427 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
17428 if (max_insns
== 0)
17429 max_insns
= CF_COUNT_MASK
;
17430 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
17432 while (ctx
.bstate
== BS_NONE
) {
17433 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
17434 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
17435 if (bp
->pc
== ctx
.pc
) {
17436 save_cpu_state(&ctx
, 1);
17437 ctx
.bstate
= BS_BRANCH
;
17438 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
17439 /* Include the breakpoint location or the tb won't
17440 * be flushed when it must be. */
17442 goto done_generating
;
17448 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
17452 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
17454 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
17455 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
17456 gen_opc_btarget
[lj
] = ctx
.btarget
;
17457 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
17458 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
17460 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
17463 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
17464 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
17465 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
17467 decode_opc(env
, &ctx
);
17468 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
17469 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
17470 insn_bytes
= decode_micromips_opc(env
, &ctx
);
17471 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
17472 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
17473 insn_bytes
= decode_mips16_opc(env
, &ctx
);
17475 generate_exception(&ctx
, EXCP_RI
);
17476 ctx
.bstate
= BS_STOP
;
17480 if (ctx
.hflags
& MIPS_HFLAG_BMASK
) {
17481 if (!(ctx
.hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
))) {
17483 /* force to generate branch as no delay slot is required */
17487 gen_branch(&ctx
, insn_bytes
);
17489 ctx
.pc
+= insn_bytes
;
17493 /* Execute a branch and its delay slot as a single instruction.
17494 This is what GDB expects and is consistent with what the
17495 hardware does (e.g. if a delay slot instruction faults, the
17496 reported PC is the PC of the branch). */
17497 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
17501 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
17504 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
17508 if (num_insns
>= max_insns
)
17514 if (tb
->cflags
& CF_LAST_IO
) {
17517 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
17518 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
17519 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
17521 switch (ctx
.bstate
) {
17523 gen_goto_tb(&ctx
, 0, ctx
.pc
);
17526 save_cpu_state(&ctx
, 0);
17527 gen_goto_tb(&ctx
, 0, ctx
.pc
);
17530 tcg_gen_exit_tb(0);
17538 gen_tb_end(tb
, num_insns
);
17539 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
17541 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
17544 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
17546 tb
->size
= ctx
.pc
- pc_start
;
17547 tb
->icount
= num_insns
;
17551 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
17552 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
17553 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
17559 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
17561 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
17564 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
17566 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
17569 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
17573 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
17575 #define printfpr(fp) \
17578 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17579 " fd:%13g fs:%13g psu: %13g\n", \
17580 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
17581 (double)(fp)->fd, \
17582 (double)(fp)->fs[FP_ENDIAN_IDX], \
17583 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
17586 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
17587 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
17588 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17589 " fd:%13g fs:%13g psu:%13g\n", \
17590 tmp.w[FP_ENDIAN_IDX], tmp.d, \
17592 (double)tmp.fs[FP_ENDIAN_IDX], \
17593 (double)tmp.fs[!FP_ENDIAN_IDX]); \
17598 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
17599 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
17600 get_float_exception_flags(&env
->active_fpu
.fp_status
));
17601 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
17602 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
17603 printfpr(&env
->active_fpu
.fpr
[i
]);
17609 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
17610 /* Debug help: The architecture requires 32bit code to maintain proper
17611 sign-extended values on 64bit machines. */
17613 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
17616 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
17617 fprintf_function cpu_fprintf
,
17622 if (!SIGN_EXT_P(env
->active_tc
.PC
))
17623 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
17624 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
17625 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
17626 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
17627 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
17628 if (!SIGN_EXT_P(env
->btarget
))
17629 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
17631 for (i
= 0; i
< 32; i
++) {
17632 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
17633 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
17636 if (!SIGN_EXT_P(env
->CP0_EPC
))
17637 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
17638 if (!SIGN_EXT_P(env
->lladdr
))
17639 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
17643 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
17646 MIPSCPU
*cpu
= MIPS_CPU(cs
);
17647 CPUMIPSState
*env
= &cpu
->env
;
17650 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
17651 " LO=0x" TARGET_FMT_lx
" ds %04x "
17652 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
17653 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
17654 env
->hflags
, env
->btarget
, env
->bcond
);
17655 for (i
= 0; i
< 32; i
++) {
17657 cpu_fprintf(f
, "GPR%02d:", i
);
17658 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
17660 cpu_fprintf(f
, "\n");
17663 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
17664 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
17665 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
17666 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
17667 if (env
->hflags
& MIPS_HFLAG_FPU
)
17668 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
17669 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
17670 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
17674 void mips_tcg_init(void)
17679 /* Initialize various static tables. */
17683 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
17684 TCGV_UNUSED(cpu_gpr
[0]);
17685 for (i
= 1; i
< 32; i
++)
17686 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
17687 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
17690 for (i
= 0; i
< 32; i
++) {
17691 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
17692 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
17695 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
17696 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
17697 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
17698 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
17699 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
17701 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
17702 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
17705 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
17706 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
17708 bcond
= tcg_global_mem_new(TCG_AREG0
,
17709 offsetof(CPUMIPSState
, bcond
), "bcond");
17710 btarget
= tcg_global_mem_new(TCG_AREG0
,
17711 offsetof(CPUMIPSState
, btarget
), "btarget");
17712 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
17713 offsetof(CPUMIPSState
, hflags
), "hflags");
17715 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
17716 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
17718 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
17719 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
17725 #include "translate_init.c"
17727 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
17731 const mips_def_t
*def
;
17733 def
= cpu_mips_find_by_name(cpu_model
);
17736 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
17738 env
->cpu_model
= def
;
17740 #ifndef CONFIG_USER_ONLY
17741 mmu_init(env
, def
);
17743 fpu_init(env
, def
);
17744 mvp_init(env
, def
);
17746 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
17751 void cpu_state_reset(CPUMIPSState
*env
)
17753 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
17754 CPUState
*cs
= CPU(cpu
);
17756 /* Reset registers to their default values */
17757 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
17758 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
17759 #ifdef TARGET_WORDS_BIGENDIAN
17760 env
->CP0_Config0
|= (1 << CP0C0_BE
);
17762 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
17763 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
17764 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
17765 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
17766 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
17767 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
17768 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
17769 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
17770 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
17771 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
17772 << env
->cpu_model
->CP0_LLAddr_shift
;
17773 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
17774 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
17775 env
->CCRes
= env
->cpu_model
->CCRes
;
17776 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
17777 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
17778 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
17779 env
->current_tc
= 0;
17780 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
17781 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
17782 #if defined(TARGET_MIPS64)
17783 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
17784 env
->SEGMask
|= 3ULL << 62;
17787 env
->PABITS
= env
->cpu_model
->PABITS
;
17788 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
17789 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
17790 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
17791 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
17792 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
17793 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
17794 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
17795 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
17796 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
17797 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
17798 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
17799 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
17800 env
->insn_flags
= env
->cpu_model
->insn_flags
;
17802 #if defined(CONFIG_USER_ONLY)
17803 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
17804 # ifdef TARGET_MIPS64
17805 /* Enable 64-bit register mode. */
17806 env
->CP0_Status
|= (1 << CP0St_PX
);
17808 # ifdef TARGET_ABI_MIPSN64
17809 /* Enable 64-bit address mode. */
17810 env
->CP0_Status
|= (1 << CP0St_UX
);
17812 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
17813 hardware registers. */
17814 env
->CP0_HWREna
|= 0x0000000F;
17815 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17816 env
->CP0_Status
|= (1 << CP0St_CU1
);
17818 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
17819 env
->CP0_Status
|= (1 << CP0St_MX
);
17821 # if defined(TARGET_MIPS64)
17822 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
17823 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
17824 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
17825 env
->CP0_Status
|= (1 << CP0St_FR
);
17829 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
17830 /* If the exception was raised from a delay slot,
17831 come back to the jump. */
17832 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
17834 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
17836 env
->active_tc
.PC
= (int32_t)0xBFC00000;
17837 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
17838 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
17839 env
->CP0_Wired
= 0;
17840 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
17841 if (kvm_enabled()) {
17842 env
->CP0_EBase
|= 0x40000000;
17844 env
->CP0_EBase
|= 0x80000000;
17846 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
17847 /* vectored interrupts not implemented, timer on int 7,
17848 no performance counters. */
17849 env
->CP0_IntCtl
= 0xe0000000;
17853 for (i
= 0; i
< 7; i
++) {
17854 env
->CP0_WatchLo
[i
] = 0;
17855 env
->CP0_WatchHi
[i
] = 0x80000000;
17857 env
->CP0_WatchLo
[7] = 0;
17858 env
->CP0_WatchHi
[7] = 0;
17860 /* Count register increments in debug mode, EJTAG version 1 */
17861 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
17863 cpu_mips_store_count(env
, 1);
17865 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
17868 /* Only TC0 on VPE 0 starts as active. */
17869 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
17870 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
17871 env
->tcs
[i
].CP0_TCHalt
= 1;
17873 env
->active_tc
.CP0_TCHalt
= 1;
17876 if (cs
->cpu_index
== 0) {
17877 /* VPE0 starts up enabled. */
17878 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
17879 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
17881 /* TC0 starts up unhalted. */
17883 env
->active_tc
.CP0_TCHalt
= 0;
17884 env
->tcs
[0].CP0_TCHalt
= 0;
17885 /* With thread 0 active. */
17886 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
17887 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
17891 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
17892 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
17893 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
17894 env
->CP0_Status
|= (1 << CP0St_FR
);
17897 compute_hflags(env
);
17898 cs
->exception_index
= EXCP_NONE
;
17901 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
17903 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
17904 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
17905 env
->hflags
|= gen_opc_hflags
[pc_pos
];
17906 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
17907 case MIPS_HFLAG_BR
:
17909 case MIPS_HFLAG_BC
:
17910 case MIPS_HFLAG_BL
:
17912 env
->btarget
= gen_opc_btarget
[pc_pos
];