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_TLBINV
= 0x03 | OPC_C0
,
900 OPC_TLBINVF
= 0x04 | OPC_C0
,
901 OPC_TLBWR
= 0x06 | OPC_C0
,
902 OPC_TLBP
= 0x08 | OPC_C0
,
903 OPC_RFE
= 0x10 | OPC_C0
,
904 OPC_ERET
= 0x18 | OPC_C0
,
905 OPC_DERET
= 0x1F | OPC_C0
,
906 OPC_WAIT
= 0x20 | OPC_C0
,
909 /* Coprocessor 1 (rs field) */
910 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
912 /* Values for the fmt field in FP instructions */
914 /* 0 - 15 are reserved */
915 FMT_S
= 16, /* single fp */
916 FMT_D
= 17, /* double fp */
917 FMT_E
= 18, /* extended fp */
918 FMT_Q
= 19, /* quad fp */
919 FMT_W
= 20, /* 32-bit fixed */
920 FMT_L
= 21, /* 64-bit fixed */
921 FMT_PS
= 22, /* paired single fp */
922 /* 23 - 31 are reserved */
926 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
927 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
928 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
929 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
930 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
931 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
932 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
933 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
934 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
935 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
936 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
937 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
938 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
939 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
940 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
941 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
942 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
943 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
944 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
945 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
948 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
949 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
952 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
953 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
954 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
955 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
959 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
960 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
964 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
965 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
968 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
971 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
972 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
973 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
974 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
975 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
976 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
977 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
978 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
979 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
980 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
981 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
984 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
987 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
988 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
989 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
990 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
991 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
992 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
993 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
994 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
996 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
997 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
998 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
999 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1000 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1001 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1002 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1003 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1005 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1006 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1007 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1008 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1009 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1010 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1011 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1012 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1014 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1015 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1016 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1017 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1018 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1019 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1020 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1021 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1023 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1024 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1025 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1026 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1027 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1028 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1030 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1031 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1032 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1033 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1034 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1035 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1037 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1038 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1039 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1040 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1041 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1042 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1044 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1045 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1046 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1047 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1048 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1049 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1051 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1052 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1053 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1054 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1055 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1056 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1058 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1059 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1060 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1061 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1062 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1063 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1065 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1066 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1067 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1068 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1069 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1070 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1072 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1073 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1074 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1075 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1076 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1077 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1081 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1084 OPC_LWXC1
= 0x00 | OPC_CP3
,
1085 OPC_LDXC1
= 0x01 | OPC_CP3
,
1086 OPC_LUXC1
= 0x05 | OPC_CP3
,
1087 OPC_SWXC1
= 0x08 | OPC_CP3
,
1088 OPC_SDXC1
= 0x09 | OPC_CP3
,
1089 OPC_SUXC1
= 0x0D | OPC_CP3
,
1090 OPC_PREFX
= 0x0F | OPC_CP3
,
1091 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1092 OPC_MADD_S
= 0x20 | OPC_CP3
,
1093 OPC_MADD_D
= 0x21 | OPC_CP3
,
1094 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1095 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1096 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1097 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1098 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1099 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1100 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1101 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1102 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1103 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1106 /* global register indices */
1107 static TCGv_ptr cpu_env
;
1108 static TCGv cpu_gpr
[32], cpu_PC
;
1109 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
];
1110 static TCGv cpu_dspctrl
, btarget
, bcond
;
1111 static TCGv_i32 hflags
;
1112 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1113 static TCGv_i64 fpu_f64
[32];
1115 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1116 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1118 #include "exec/gen-icount.h"
1120 #define gen_helper_0e0i(name, arg) do { \
1121 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1122 gen_helper_##name(cpu_env, helper_tmp); \
1123 tcg_temp_free_i32(helper_tmp); \
1126 #define gen_helper_0e1i(name, arg1, arg2) do { \
1127 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1128 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1129 tcg_temp_free_i32(helper_tmp); \
1132 #define gen_helper_1e0i(name, ret, arg1) do { \
1133 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1134 gen_helper_##name(ret, cpu_env, helper_tmp); \
1135 tcg_temp_free_i32(helper_tmp); \
1138 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1139 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1140 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1141 tcg_temp_free_i32(helper_tmp); \
1144 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1145 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1146 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1147 tcg_temp_free_i32(helper_tmp); \
1150 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1151 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1152 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1153 tcg_temp_free_i32(helper_tmp); \
1156 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1157 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1158 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1159 tcg_temp_free_i32(helper_tmp); \
1162 typedef struct DisasContext
{
1163 struct TranslationBlock
*tb
;
1164 target_ulong pc
, saved_pc
;
1166 int singlestep_enabled
;
1168 int32_t CP0_Config1
;
1169 /* Routine used to access memory */
1171 uint32_t hflags
, saved_hflags
;
1173 target_ulong btarget
;
1181 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1182 * exception condition */
1183 BS_STOP
= 1, /* We want to stop translation for any reason */
1184 BS_BRANCH
= 2, /* We reached a branch condition */
1185 BS_EXCP
= 3, /* We reached an exception condition */
1188 static const char * const regnames
[] = {
1189 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1190 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1191 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1192 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1195 static const char * const regnames_HI
[] = {
1196 "HI0", "HI1", "HI2", "HI3",
1199 static const char * const regnames_LO
[] = {
1200 "LO0", "LO1", "LO2", "LO3",
1203 static const char * const fregnames
[] = {
1204 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1205 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1206 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1207 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1210 #define MIPS_DEBUG(fmt, ...) \
1212 if (MIPS_DEBUG_DISAS) { \
1213 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1214 TARGET_FMT_lx ": %08x " fmt "\n", \
1215 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1219 #define LOG_DISAS(...) \
1221 if (MIPS_DEBUG_DISAS) { \
1222 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1226 #define MIPS_INVAL(op) \
1227 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1228 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1230 /* General purpose registers moves. */
1231 static inline void gen_load_gpr (TCGv t
, int reg
)
1234 tcg_gen_movi_tl(t
, 0);
1236 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1239 static inline void gen_store_gpr (TCGv t
, int reg
)
1242 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1245 /* Moves to/from shadow registers. */
1246 static inline void gen_load_srsgpr (int from
, int to
)
1248 TCGv t0
= tcg_temp_new();
1251 tcg_gen_movi_tl(t0
, 0);
1253 TCGv_i32 t2
= tcg_temp_new_i32();
1254 TCGv_ptr addr
= tcg_temp_new_ptr();
1256 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1257 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1258 tcg_gen_andi_i32(t2
, t2
, 0xf);
1259 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1260 tcg_gen_ext_i32_ptr(addr
, t2
);
1261 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1263 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1264 tcg_temp_free_ptr(addr
);
1265 tcg_temp_free_i32(t2
);
1267 gen_store_gpr(t0
, to
);
1271 static inline void gen_store_srsgpr (int from
, int to
)
1274 TCGv t0
= tcg_temp_new();
1275 TCGv_i32 t2
= tcg_temp_new_i32();
1276 TCGv_ptr addr
= tcg_temp_new_ptr();
1278 gen_load_gpr(t0
, from
);
1279 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1280 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1281 tcg_gen_andi_i32(t2
, t2
, 0xf);
1282 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1283 tcg_gen_ext_i32_ptr(addr
, t2
);
1284 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1286 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1287 tcg_temp_free_ptr(addr
);
1288 tcg_temp_free_i32(t2
);
1293 /* Floating point register moves. */
1294 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1296 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1299 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1301 TCGv_i64 t64
= tcg_temp_new_i64();
1302 tcg_gen_extu_i32_i64(t64
, t
);
1303 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1304 tcg_temp_free_i64(t64
);
1307 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1309 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1310 TCGv_i64 t64
= tcg_temp_new_i64();
1311 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1312 tcg_gen_trunc_i64_i32(t
, t64
);
1313 tcg_temp_free_i64(t64
);
1315 gen_load_fpr32(t
, reg
| 1);
1319 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1321 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1322 TCGv_i64 t64
= tcg_temp_new_i64();
1323 tcg_gen_extu_i32_i64(t64
, t
);
1324 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1325 tcg_temp_free_i64(t64
);
1327 gen_store_fpr32(t
, reg
| 1);
1331 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1333 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1334 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1336 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1340 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1342 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1343 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1346 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1347 t0
= tcg_temp_new_i64();
1348 tcg_gen_shri_i64(t0
, t
, 32);
1349 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1350 tcg_temp_free_i64(t0
);
1354 static inline int get_fp_bit (int cc
)
1363 static inline void gen_save_pc(target_ulong pc
)
1365 tcg_gen_movi_tl(cpu_PC
, pc
);
1368 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1370 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1371 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1372 gen_save_pc(ctx
->pc
);
1373 ctx
->saved_pc
= ctx
->pc
;
1375 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1376 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1377 ctx
->saved_hflags
= ctx
->hflags
;
1378 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1384 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1390 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1392 ctx
->saved_hflags
= ctx
->hflags
;
1393 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1399 ctx
->btarget
= env
->btarget
;
1405 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1407 TCGv_i32 texcp
= tcg_const_i32(excp
);
1408 TCGv_i32 terr
= tcg_const_i32(err
);
1409 save_cpu_state(ctx
, 1);
1410 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1411 tcg_temp_free_i32(terr
);
1412 tcg_temp_free_i32(texcp
);
1416 generate_exception (DisasContext
*ctx
, int excp
)
1418 save_cpu_state(ctx
, 1);
1419 gen_helper_0e0i(raise_exception
, excp
);
1422 /* Addresses computation */
1423 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1425 tcg_gen_add_tl(ret
, arg0
, arg1
);
1427 #if defined(TARGET_MIPS64)
1428 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1429 tcg_gen_ext32s_i64(ret
, ret
);
1434 /* Addresses computation (translation time) */
1435 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1438 target_long sum
= base
+ offset
;
1440 #if defined(TARGET_MIPS64)
1441 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1448 static inline void check_cp0_enabled(DisasContext
*ctx
)
1450 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1451 generate_exception_err(ctx
, EXCP_CpU
, 0);
1454 static inline void check_cp1_enabled(DisasContext
*ctx
)
1456 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1457 generate_exception_err(ctx
, EXCP_CpU
, 1);
1460 /* Verify that the processor is running with COP1X instructions enabled.
1461 This is associated with the nabla symbol in the MIPS32 and MIPS64
1464 static inline void check_cop1x(DisasContext
*ctx
)
1466 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1467 generate_exception(ctx
, EXCP_RI
);
1470 /* Verify that the processor is running with 64-bit floating-point
1471 operations enabled. */
1473 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1475 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1476 generate_exception(ctx
, EXCP_RI
);
1480 * Verify if floating point register is valid; an operation is not defined
1481 * if bit 0 of any register specification is set and the FR bit in the
1482 * Status register equals zero, since the register numbers specify an
1483 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1484 * in the Status register equals one, both even and odd register numbers
1485 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1487 * Multiple 64 bit wide registers can be checked by calling
1488 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1490 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1492 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1493 generate_exception(ctx
, EXCP_RI
);
1496 /* Verify that the processor is running with DSP instructions enabled.
1497 This is enabled by CP0 Status register MX(24) bit.
1500 static inline void check_dsp(DisasContext
*ctx
)
1502 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1503 if (ctx
->insn_flags
& ASE_DSP
) {
1504 generate_exception(ctx
, EXCP_DSPDIS
);
1506 generate_exception(ctx
, EXCP_RI
);
1511 static inline void check_dspr2(DisasContext
*ctx
)
1513 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1514 if (ctx
->insn_flags
& ASE_DSP
) {
1515 generate_exception(ctx
, EXCP_DSPDIS
);
1517 generate_exception(ctx
, EXCP_RI
);
1522 /* This code generates a "reserved instruction" exception if the
1523 CPU does not support the instruction set corresponding to flags. */
1524 static inline void check_insn(DisasContext
*ctx
, int flags
)
1526 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1527 generate_exception(ctx
, EXCP_RI
);
1531 /* This code generates a "reserved instruction" exception if the
1532 CPU has corresponding flag set which indicates that the instruction
1533 has been removed. */
1534 static inline void check_insn_opc_removed(DisasContext
*ctx
, int flags
)
1536 if (unlikely(ctx
->insn_flags
& flags
)) {
1537 generate_exception(ctx
, EXCP_RI
);
1541 #ifdef TARGET_MIPS64
1542 /* This code generates a "reserved instruction" exception if 64-bit
1543 instructions are not enabled. */
1544 static inline void check_mips_64(DisasContext
*ctx
)
1546 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1547 generate_exception(ctx
, EXCP_RI
);
1551 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1552 calling interface for 32 and 64-bit FPRs. No sense in changing
1553 all callers for gen_load_fpr32 when we need the CTX parameter for
1555 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1556 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1557 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1558 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1559 int ft, int fs, int cc) \
1561 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1562 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1565 check_cp1_64bitmode(ctx); \
1571 check_cp1_registers(ctx, fs | ft); \
1579 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1580 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1582 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1583 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1584 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1585 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1586 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1587 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1588 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1589 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1590 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1591 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1592 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1593 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1594 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1595 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1596 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1597 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1600 tcg_temp_free_i##bits (fp0); \
1601 tcg_temp_free_i##bits (fp1); \
1604 FOP_CONDS(, 0, d
, FMT_D
, 64)
1605 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1606 FOP_CONDS(, 0, s
, FMT_S
, 32)
1607 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1608 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1609 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1612 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1613 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1614 int ft, int fs, int fd) \
1616 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1617 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1620 check_cp1_registers(ctx, fs | ft | fd); \
1623 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1624 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1627 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1630 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1633 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1636 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1639 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1642 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1645 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1648 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1651 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1654 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1657 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1660 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1663 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1666 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1669 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1672 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1675 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1678 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1681 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1684 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1687 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1690 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1696 tcg_temp_free_i ## bits (fp0); \
1697 tcg_temp_free_i ## bits (fp1); \
1700 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
1701 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(fp0
, fd
))
1703 #undef gen_ldcmp_fpr32
1704 #undef gen_ldcmp_fpr64
1706 /* load/store instructions. */
1707 #ifdef CONFIG_USER_ONLY
1708 #define OP_LD_ATOMIC(insn,fname) \
1709 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1711 TCGv t0 = tcg_temp_new(); \
1712 tcg_gen_mov_tl(t0, arg1); \
1713 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1714 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1715 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1716 tcg_temp_free(t0); \
1719 #define OP_LD_ATOMIC(insn,fname) \
1720 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1722 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1725 OP_LD_ATOMIC(ll
,ld32s
);
1726 #if defined(TARGET_MIPS64)
1727 OP_LD_ATOMIC(lld
,ld64
);
1731 #ifdef CONFIG_USER_ONLY
1732 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1733 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1735 TCGv t0 = tcg_temp_new(); \
1736 int l1 = gen_new_label(); \
1737 int l2 = gen_new_label(); \
1739 tcg_gen_andi_tl(t0, arg2, almask); \
1740 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1741 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1742 generate_exception(ctx, EXCP_AdES); \
1743 gen_set_label(l1); \
1744 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1745 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1746 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1747 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1748 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1749 gen_helper_0e0i(raise_exception, EXCP_SC); \
1750 gen_set_label(l2); \
1751 tcg_gen_movi_tl(t0, 0); \
1752 gen_store_gpr(t0, rt); \
1753 tcg_temp_free(t0); \
1756 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1757 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1759 TCGv t0 = tcg_temp_new(); \
1760 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1761 gen_store_gpr(t0, rt); \
1762 tcg_temp_free(t0); \
1765 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1766 #if defined(TARGET_MIPS64)
1767 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1771 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1772 int base
, int16_t offset
)
1775 tcg_gen_movi_tl(addr
, offset
);
1776 } else if (offset
== 0) {
1777 gen_load_gpr(addr
, base
);
1779 tcg_gen_movi_tl(addr
, offset
);
1780 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1784 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1786 target_ulong pc
= ctx
->pc
;
1788 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1789 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1794 pc
&= ~(target_ulong
)3;
1799 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1800 int rt
, int base
, int16_t offset
)
1802 const char *opn
= "ld";
1805 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1806 /* Loongson CPU uses a load to zero register for prefetch.
1807 We emulate it as a NOP. On other CPU we must perform the
1808 actual memory access. */
1813 t0
= tcg_temp_new();
1814 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1817 #if defined(TARGET_MIPS64)
1819 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1820 gen_store_gpr(t0
, rt
);
1824 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1825 gen_store_gpr(t0
, rt
);
1830 save_cpu_state(ctx
, 1);
1831 op_ld_lld(t0
, t0
, ctx
);
1832 gen_store_gpr(t0
, rt
);
1836 t1
= tcg_temp_new();
1837 tcg_gen_andi_tl(t1
, t0
, 7);
1838 #ifndef TARGET_WORDS_BIGENDIAN
1839 tcg_gen_xori_tl(t1
, t1
, 7);
1841 tcg_gen_shli_tl(t1
, t1
, 3);
1842 tcg_gen_andi_tl(t0
, t0
, ~7);
1843 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1844 tcg_gen_shl_tl(t0
, t0
, t1
);
1845 tcg_gen_xori_tl(t1
, t1
, 63);
1846 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1847 tcg_gen_shr_tl(t2
, t2
, t1
);
1848 gen_load_gpr(t1
, rt
);
1849 tcg_gen_and_tl(t1
, t1
, t2
);
1851 tcg_gen_or_tl(t0
, t0
, t1
);
1853 gen_store_gpr(t0
, rt
);
1857 t1
= tcg_temp_new();
1858 tcg_gen_andi_tl(t1
, t0
, 7);
1859 #ifdef TARGET_WORDS_BIGENDIAN
1860 tcg_gen_xori_tl(t1
, t1
, 7);
1862 tcg_gen_shli_tl(t1
, t1
, 3);
1863 tcg_gen_andi_tl(t0
, t0
, ~7);
1864 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1865 tcg_gen_shr_tl(t0
, t0
, t1
);
1866 tcg_gen_xori_tl(t1
, t1
, 63);
1867 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1868 tcg_gen_shl_tl(t2
, t2
, t1
);
1869 gen_load_gpr(t1
, rt
);
1870 tcg_gen_and_tl(t1
, t1
, t2
);
1872 tcg_gen_or_tl(t0
, t0
, t1
);
1874 gen_store_gpr(t0
, rt
);
1878 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1879 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1881 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1882 gen_store_gpr(t0
, rt
);
1887 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1888 gen_op_addr_add(ctx
, t0
, t0
, t1
);
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_TESL
);
1896 gen_store_gpr(t0
, rt
);
1900 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
1901 gen_store_gpr(t0
, rt
);
1905 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
1906 gen_store_gpr(t0
, rt
);
1910 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
1911 gen_store_gpr(t0
, rt
);
1915 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
1916 gen_store_gpr(t0
, rt
);
1920 t1
= tcg_temp_new();
1921 tcg_gen_andi_tl(t1
, t0
, 3);
1922 #ifndef TARGET_WORDS_BIGENDIAN
1923 tcg_gen_xori_tl(t1
, t1
, 3);
1925 tcg_gen_shli_tl(t1
, t1
, 3);
1926 tcg_gen_andi_tl(t0
, t0
, ~3);
1927 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1928 tcg_gen_shl_tl(t0
, t0
, t1
);
1929 tcg_gen_xori_tl(t1
, t1
, 31);
1930 t2
= tcg_const_tl(0x7fffffffull
);
1931 tcg_gen_shr_tl(t2
, t2
, t1
);
1932 gen_load_gpr(t1
, rt
);
1933 tcg_gen_and_tl(t1
, t1
, t2
);
1935 tcg_gen_or_tl(t0
, t0
, t1
);
1937 tcg_gen_ext32s_tl(t0
, t0
);
1938 gen_store_gpr(t0
, rt
);
1942 t1
= tcg_temp_new();
1943 tcg_gen_andi_tl(t1
, t0
, 3);
1944 #ifdef TARGET_WORDS_BIGENDIAN
1945 tcg_gen_xori_tl(t1
, t1
, 3);
1947 tcg_gen_shli_tl(t1
, t1
, 3);
1948 tcg_gen_andi_tl(t0
, t0
, ~3);
1949 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1950 tcg_gen_shr_tl(t0
, t0
, t1
);
1951 tcg_gen_xori_tl(t1
, t1
, 31);
1952 t2
= tcg_const_tl(0xfffffffeull
);
1953 tcg_gen_shl_tl(t2
, t2
, t1
);
1954 gen_load_gpr(t1
, rt
);
1955 tcg_gen_and_tl(t1
, t1
, t2
);
1957 tcg_gen_or_tl(t0
, t0
, t1
);
1959 tcg_gen_ext32s_tl(t0
, t0
);
1960 gen_store_gpr(t0
, rt
);
1965 save_cpu_state(ctx
, 1);
1966 op_ld_ll(t0
, t0
, ctx
);
1967 gen_store_gpr(t0
, rt
);
1971 (void)opn
; /* avoid a compiler warning */
1972 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1977 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1978 int base
, int16_t offset
)
1980 const char *opn
= "st";
1981 TCGv t0
= tcg_temp_new();
1982 TCGv t1
= tcg_temp_new();
1984 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1985 gen_load_gpr(t1
, rt
);
1987 #if defined(TARGET_MIPS64)
1989 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
1993 save_cpu_state(ctx
, 1);
1994 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1998 save_cpu_state(ctx
, 1);
1999 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
2004 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
2008 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
2012 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
2016 save_cpu_state(ctx
, 1);
2017 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
2021 save_cpu_state(ctx
, 1);
2022 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
2026 (void)opn
; /* avoid a compiler warning */
2027 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2033 /* Store conditional */
2034 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
2035 int base
, int16_t offset
)
2037 const char *opn
= "st_cond";
2040 #ifdef CONFIG_USER_ONLY
2041 t0
= tcg_temp_local_new();
2042 t1
= tcg_temp_local_new();
2044 t0
= tcg_temp_new();
2045 t1
= tcg_temp_new();
2047 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2048 gen_load_gpr(t1
, rt
);
2050 #if defined(TARGET_MIPS64)
2053 save_cpu_state(ctx
, 1);
2054 op_st_scd(t1
, t0
, rt
, ctx
);
2060 save_cpu_state(ctx
, 1);
2061 op_st_sc(t1
, t0
, rt
, ctx
);
2065 (void)opn
; /* avoid a compiler warning */
2066 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2071 /* Load and store */
2072 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
2073 int base
, int16_t offset
)
2075 const char *opn
= "flt_ldst";
2076 TCGv t0
= tcg_temp_new();
2078 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2079 /* Don't do NOP if destination is zero: we must perform the actual
2084 TCGv_i32 fp0
= tcg_temp_new_i32();
2085 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
2086 gen_store_fpr32(fp0
, ft
);
2087 tcg_temp_free_i32(fp0
);
2093 TCGv_i32 fp0
= tcg_temp_new_i32();
2094 gen_load_fpr32(fp0
, ft
);
2095 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2096 tcg_temp_free_i32(fp0
);
2102 TCGv_i64 fp0
= tcg_temp_new_i64();
2103 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2104 gen_store_fpr64(ctx
, fp0
, ft
);
2105 tcg_temp_free_i64(fp0
);
2111 TCGv_i64 fp0
= tcg_temp_new_i64();
2112 gen_load_fpr64(ctx
, fp0
, ft
);
2113 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2114 tcg_temp_free_i64(fp0
);
2120 generate_exception(ctx
, EXCP_RI
);
2123 (void)opn
; /* avoid a compiler warning */
2124 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
2129 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2130 int rs
, int16_t imm
)
2132 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2133 check_cp1_enabled(ctx
);
2134 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
2136 generate_exception_err(ctx
, EXCP_CpU
, 1);
2140 /* Arithmetic with immediate operand */
2141 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2142 int rt
, int rs
, int16_t imm
)
2144 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2145 const char *opn
= "imm arith";
2147 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2148 /* If no destination, treat it as a NOP.
2149 For addi, we must generate the overflow exception when needed. */
2156 TCGv t0
= tcg_temp_local_new();
2157 TCGv t1
= tcg_temp_new();
2158 TCGv t2
= tcg_temp_new();
2159 int l1
= gen_new_label();
2161 gen_load_gpr(t1
, rs
);
2162 tcg_gen_addi_tl(t0
, t1
, uimm
);
2163 tcg_gen_ext32s_tl(t0
, t0
);
2165 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2166 tcg_gen_xori_tl(t2
, t0
, uimm
);
2167 tcg_gen_and_tl(t1
, t1
, t2
);
2169 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2171 /* operands of same sign, result different sign */
2172 generate_exception(ctx
, EXCP_OVERFLOW
);
2174 tcg_gen_ext32s_tl(t0
, t0
);
2175 gen_store_gpr(t0
, rt
);
2182 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2183 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2185 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2189 #if defined(TARGET_MIPS64)
2192 TCGv t0
= tcg_temp_local_new();
2193 TCGv t1
= tcg_temp_new();
2194 TCGv t2
= tcg_temp_new();
2195 int l1
= gen_new_label();
2197 gen_load_gpr(t1
, rs
);
2198 tcg_gen_addi_tl(t0
, t1
, uimm
);
2200 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2201 tcg_gen_xori_tl(t2
, t0
, uimm
);
2202 tcg_gen_and_tl(t1
, t1
, t2
);
2204 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2206 /* operands of same sign, result different sign */
2207 generate_exception(ctx
, EXCP_OVERFLOW
);
2209 gen_store_gpr(t0
, rt
);
2216 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2218 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2224 (void)opn
; /* avoid a compiler warning */
2225 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2228 /* Logic with immediate operand */
2229 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2230 int rt
, int rs
, int16_t imm
)
2235 /* If no destination, treat it as a NOP. */
2239 uimm
= (uint16_t)imm
;
2242 if (likely(rs
!= 0))
2243 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2245 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2246 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2247 regnames
[rs
], uimm
);
2251 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2253 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2254 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2255 regnames
[rs
], uimm
);
2258 if (likely(rs
!= 0))
2259 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2261 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2262 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2263 regnames
[rs
], uimm
);
2266 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
2268 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2269 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2270 MIPS_DEBUG("aui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
2272 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2273 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2278 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2283 /* Set on less than with immediate operand */
2284 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2285 int rt
, int rs
, int16_t imm
)
2287 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2288 const char *opn
= "imm arith";
2292 /* If no destination, treat it as a NOP. */
2296 t0
= tcg_temp_new();
2297 gen_load_gpr(t0
, rs
);
2300 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2304 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2308 (void)opn
; /* avoid a compiler warning */
2309 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2313 /* Shifts with immediate operand */
2314 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2315 int rt
, int rs
, int16_t imm
)
2317 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2318 const char *opn
= "imm shift";
2322 /* If no destination, treat it as a NOP. */
2327 t0
= tcg_temp_new();
2328 gen_load_gpr(t0
, rs
);
2331 tcg_gen_shli_tl(t0
, t0
, uimm
);
2332 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2336 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2341 tcg_gen_ext32u_tl(t0
, t0
);
2342 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2344 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2350 TCGv_i32 t1
= tcg_temp_new_i32();
2352 tcg_gen_trunc_tl_i32(t1
, t0
);
2353 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2354 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2355 tcg_temp_free_i32(t1
);
2357 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2361 #if defined(TARGET_MIPS64)
2363 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2367 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2371 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2376 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2378 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2383 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2387 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2391 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2395 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2400 (void)opn
; /* avoid a compiler warning */
2401 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2406 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2407 int rd
, int rs
, int rt
)
2409 const char *opn
= "arith";
2411 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2412 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2413 /* If no destination, treat it as a NOP.
2414 For add & sub, we must generate the overflow exception when needed. */
2422 TCGv t0
= tcg_temp_local_new();
2423 TCGv t1
= tcg_temp_new();
2424 TCGv t2
= tcg_temp_new();
2425 int l1
= gen_new_label();
2427 gen_load_gpr(t1
, rs
);
2428 gen_load_gpr(t2
, rt
);
2429 tcg_gen_add_tl(t0
, t1
, t2
);
2430 tcg_gen_ext32s_tl(t0
, t0
);
2431 tcg_gen_xor_tl(t1
, t1
, t2
);
2432 tcg_gen_xor_tl(t2
, t0
, t2
);
2433 tcg_gen_andc_tl(t1
, t2
, t1
);
2435 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2437 /* operands of same sign, result different sign */
2438 generate_exception(ctx
, EXCP_OVERFLOW
);
2440 gen_store_gpr(t0
, rd
);
2446 if (rs
!= 0 && rt
!= 0) {
2447 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2448 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2449 } else if (rs
== 0 && rt
!= 0) {
2450 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2451 } else if (rs
!= 0 && rt
== 0) {
2452 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2454 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2460 TCGv t0
= tcg_temp_local_new();
2461 TCGv t1
= tcg_temp_new();
2462 TCGv t2
= tcg_temp_new();
2463 int l1
= gen_new_label();
2465 gen_load_gpr(t1
, rs
);
2466 gen_load_gpr(t2
, rt
);
2467 tcg_gen_sub_tl(t0
, t1
, t2
);
2468 tcg_gen_ext32s_tl(t0
, t0
);
2469 tcg_gen_xor_tl(t2
, t1
, t2
);
2470 tcg_gen_xor_tl(t1
, t0
, t1
);
2471 tcg_gen_and_tl(t1
, t1
, t2
);
2473 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2475 /* operands of different sign, first operand and result different sign */
2476 generate_exception(ctx
, EXCP_OVERFLOW
);
2478 gen_store_gpr(t0
, rd
);
2484 if (rs
!= 0 && rt
!= 0) {
2485 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2486 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2487 } else if (rs
== 0 && rt
!= 0) {
2488 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2489 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2490 } else if (rs
!= 0 && rt
== 0) {
2491 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2493 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2497 #if defined(TARGET_MIPS64)
2500 TCGv t0
= tcg_temp_local_new();
2501 TCGv t1
= tcg_temp_new();
2502 TCGv t2
= tcg_temp_new();
2503 int l1
= gen_new_label();
2505 gen_load_gpr(t1
, rs
);
2506 gen_load_gpr(t2
, rt
);
2507 tcg_gen_add_tl(t0
, t1
, t2
);
2508 tcg_gen_xor_tl(t1
, t1
, t2
);
2509 tcg_gen_xor_tl(t2
, t0
, t2
);
2510 tcg_gen_andc_tl(t1
, t2
, t1
);
2512 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2514 /* operands of same sign, result different sign */
2515 generate_exception(ctx
, EXCP_OVERFLOW
);
2517 gen_store_gpr(t0
, rd
);
2523 if (rs
!= 0 && rt
!= 0) {
2524 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2525 } else if (rs
== 0 && rt
!= 0) {
2526 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2527 } else if (rs
!= 0 && rt
== 0) {
2528 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2530 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2536 TCGv t0
= tcg_temp_local_new();
2537 TCGv t1
= tcg_temp_new();
2538 TCGv t2
= tcg_temp_new();
2539 int l1
= gen_new_label();
2541 gen_load_gpr(t1
, rs
);
2542 gen_load_gpr(t2
, rt
);
2543 tcg_gen_sub_tl(t0
, t1
, t2
);
2544 tcg_gen_xor_tl(t2
, t1
, t2
);
2545 tcg_gen_xor_tl(t1
, t0
, t1
);
2546 tcg_gen_and_tl(t1
, t1
, t2
);
2548 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2550 /* operands of different sign, first operand and result different sign */
2551 generate_exception(ctx
, EXCP_OVERFLOW
);
2553 gen_store_gpr(t0
, rd
);
2559 if (rs
!= 0 && rt
!= 0) {
2560 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2561 } else if (rs
== 0 && rt
!= 0) {
2562 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2563 } else if (rs
!= 0 && rt
== 0) {
2564 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2566 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2572 if (likely(rs
!= 0 && rt
!= 0)) {
2573 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2574 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2576 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2581 (void)opn
; /* avoid a compiler warning */
2582 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2585 /* Conditional move */
2586 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2587 int rd
, int rs
, int rt
)
2589 const char *opn
= "cond move";
2593 /* If no destination, treat it as a NOP. */
2598 t0
= tcg_temp_new();
2599 gen_load_gpr(t0
, rt
);
2600 t1
= tcg_const_tl(0);
2601 t2
= tcg_temp_new();
2602 gen_load_gpr(t2
, rs
);
2605 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2609 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2613 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2617 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2625 (void)opn
; /* avoid a compiler warning */
2626 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2630 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2631 int rd
, int rs
, int rt
)
2633 const char *opn
= "logic";
2636 /* If no destination, treat it as a NOP. */
2643 if (likely(rs
!= 0 && rt
!= 0)) {
2644 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2646 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2651 if (rs
!= 0 && rt
!= 0) {
2652 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2653 } else if (rs
== 0 && rt
!= 0) {
2654 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2655 } else if (rs
!= 0 && rt
== 0) {
2656 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2658 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2663 if (likely(rs
!= 0 && rt
!= 0)) {
2664 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2665 } else if (rs
== 0 && rt
!= 0) {
2666 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2667 } else if (rs
!= 0 && rt
== 0) {
2668 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2670 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2675 if (likely(rs
!= 0 && rt
!= 0)) {
2676 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2677 } else if (rs
== 0 && rt
!= 0) {
2678 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2679 } else if (rs
!= 0 && rt
== 0) {
2680 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2682 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2687 (void)opn
; /* avoid a compiler warning */
2688 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2691 /* Set on lower than */
2692 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2693 int rd
, int rs
, int rt
)
2695 const char *opn
= "slt";
2699 /* If no destination, treat it as a NOP. */
2704 t0
= tcg_temp_new();
2705 t1
= tcg_temp_new();
2706 gen_load_gpr(t0
, rs
);
2707 gen_load_gpr(t1
, rt
);
2710 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2714 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2718 (void)opn
; /* avoid a compiler warning */
2719 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2725 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2726 int rd
, int rs
, int rt
)
2728 const char *opn
= "shifts";
2732 /* If no destination, treat it as a NOP.
2733 For add & sub, we must generate the overflow exception when needed. */
2738 t0
= tcg_temp_new();
2739 t1
= tcg_temp_new();
2740 gen_load_gpr(t0
, rs
);
2741 gen_load_gpr(t1
, rt
);
2744 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2745 tcg_gen_shl_tl(t0
, t1
, t0
);
2746 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2750 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2751 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2755 tcg_gen_ext32u_tl(t1
, t1
);
2756 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2757 tcg_gen_shr_tl(t0
, t1
, t0
);
2758 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2763 TCGv_i32 t2
= tcg_temp_new_i32();
2764 TCGv_i32 t3
= tcg_temp_new_i32();
2766 tcg_gen_trunc_tl_i32(t2
, t0
);
2767 tcg_gen_trunc_tl_i32(t3
, t1
);
2768 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2769 tcg_gen_rotr_i32(t2
, t3
, t2
);
2770 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2771 tcg_temp_free_i32(t2
);
2772 tcg_temp_free_i32(t3
);
2776 #if defined(TARGET_MIPS64)
2778 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2779 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2783 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2784 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2788 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2789 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2793 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2794 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2799 (void)opn
; /* avoid a compiler warning */
2800 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2805 /* Arithmetic on HI/LO registers */
2806 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2808 const char *opn
= "hilo";
2810 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2822 #if defined(TARGET_MIPS64)
2824 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2828 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2833 #if defined(TARGET_MIPS64)
2835 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2839 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2845 #if defined(TARGET_MIPS64)
2847 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2851 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2854 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2860 #if defined(TARGET_MIPS64)
2862 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2866 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2869 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2874 (void)opn
; /* avoid a compiler warning */
2875 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2878 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
2881 TCGv t0
= tcg_const_tl(addr
);
2882 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
2883 gen_store_gpr(t0
, reg
);
2887 static inline void gen_pcrel(DisasContext
*ctx
, int rs
, int16_t imm
)
2892 switch (MASK_OPC_PCREL_TOP2BITS(ctx
->opcode
)) {
2895 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
2896 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2897 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
2901 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
2902 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2903 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
2905 #if defined(TARGET_MIPS64)
2908 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
2909 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2910 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
2914 switch (MASK_OPC_PCREL_TOP5BITS(ctx
->opcode
)) {
2918 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2919 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
2925 addr
= ~0xFFFF & addr_add(ctx
, ctx
->pc
, offset
);
2926 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
2929 #if defined(TARGET_MIPS64)
2930 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
2931 case R6_OPC_LDPC
+ (1 << 16):
2932 case R6_OPC_LDPC
+ (2 << 16):
2933 case R6_OPC_LDPC
+ (3 << 16):
2935 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
2936 addr
= addr_add(ctx
, (ctx
->pc
& ~0x7), offset
);
2937 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
2941 MIPS_INVAL("OPC_PCREL");
2942 generate_exception(ctx
, EXCP_RI
);
2949 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
2951 const char *opn
= "r6 mul/div";
2960 t0
= tcg_temp_new();
2961 t1
= tcg_temp_new();
2963 gen_load_gpr(t0
, rs
);
2964 gen_load_gpr(t1
, rt
);
2969 TCGv t2
= tcg_temp_new();
2970 TCGv t3
= tcg_temp_new();
2971 tcg_gen_ext32s_tl(t0
, t0
);
2972 tcg_gen_ext32s_tl(t1
, t1
);
2973 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2974 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2975 tcg_gen_and_tl(t2
, t2
, t3
);
2976 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2977 tcg_gen_or_tl(t2
, t2
, t3
);
2978 tcg_gen_movi_tl(t3
, 0);
2979 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2980 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
2981 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2989 TCGv t2
= tcg_temp_new();
2990 TCGv t3
= tcg_temp_new();
2991 tcg_gen_ext32s_tl(t0
, t0
);
2992 tcg_gen_ext32s_tl(t1
, t1
);
2993 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2994 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2995 tcg_gen_and_tl(t2
, t2
, t3
);
2996 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2997 tcg_gen_or_tl(t2
, t2
, t3
);
2998 tcg_gen_movi_tl(t3
, 0);
2999 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3000 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3001 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3009 TCGv t2
= tcg_const_tl(0);
3010 TCGv t3
= tcg_const_tl(1);
3011 tcg_gen_ext32u_tl(t0
, t0
);
3012 tcg_gen_ext32u_tl(t1
, t1
);
3013 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3014 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3015 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3023 TCGv t2
= tcg_const_tl(0);
3024 TCGv t3
= tcg_const_tl(1);
3025 tcg_gen_ext32u_tl(t0
, t0
);
3026 tcg_gen_ext32u_tl(t1
, t1
);
3027 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3028 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3029 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3037 TCGv_i32 t2
= tcg_temp_new_i32();
3038 TCGv_i32 t3
= tcg_temp_new_i32();
3039 tcg_gen_trunc_tl_i32(t2
, t0
);
3040 tcg_gen_trunc_tl_i32(t3
, t1
);
3041 tcg_gen_mul_i32(t2
, t2
, t3
);
3042 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3043 tcg_temp_free_i32(t2
);
3044 tcg_temp_free_i32(t3
);
3050 TCGv_i32 t2
= tcg_temp_new_i32();
3051 TCGv_i32 t3
= tcg_temp_new_i32();
3052 tcg_gen_trunc_tl_i32(t2
, t0
);
3053 tcg_gen_trunc_tl_i32(t3
, t1
);
3054 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3055 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3056 tcg_temp_free_i32(t2
);
3057 tcg_temp_free_i32(t3
);
3063 TCGv_i32 t2
= tcg_temp_new_i32();
3064 TCGv_i32 t3
= tcg_temp_new_i32();
3065 tcg_gen_trunc_tl_i32(t2
, t0
);
3066 tcg_gen_trunc_tl_i32(t3
, t1
);
3067 tcg_gen_mul_i32(t2
, t2
, t3
);
3068 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3069 tcg_temp_free_i32(t2
);
3070 tcg_temp_free_i32(t3
);
3076 TCGv_i32 t2
= tcg_temp_new_i32();
3077 TCGv_i32 t3
= tcg_temp_new_i32();
3078 tcg_gen_trunc_tl_i32(t2
, t0
);
3079 tcg_gen_trunc_tl_i32(t3
, t1
);
3080 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3081 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3082 tcg_temp_free_i32(t2
);
3083 tcg_temp_free_i32(t3
);
3087 #if defined(TARGET_MIPS64)
3090 TCGv t2
= tcg_temp_new();
3091 TCGv t3
= tcg_temp_new();
3092 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3093 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3094 tcg_gen_and_tl(t2
, t2
, t3
);
3095 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3096 tcg_gen_or_tl(t2
, t2
, t3
);
3097 tcg_gen_movi_tl(t3
, 0);
3098 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3099 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3107 TCGv t2
= tcg_temp_new();
3108 TCGv t3
= tcg_temp_new();
3109 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3110 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3111 tcg_gen_and_tl(t2
, t2
, t3
);
3112 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3113 tcg_gen_or_tl(t2
, t2
, t3
);
3114 tcg_gen_movi_tl(t3
, 0);
3115 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3116 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3124 TCGv t2
= tcg_const_tl(0);
3125 TCGv t3
= tcg_const_tl(1);
3126 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3127 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3135 TCGv t2
= tcg_const_tl(0);
3136 TCGv t3
= tcg_const_tl(1);
3137 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3138 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3145 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3150 TCGv t2
= tcg_temp_new();
3151 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3157 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3162 TCGv t2
= tcg_temp_new();
3163 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3171 generate_exception(ctx
, EXCP_RI
);
3174 (void)opn
; /* avoid a compiler warning */
3175 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3181 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3182 int acc
, int rs
, int rt
)
3184 const char *opn
= "mul/div";
3187 t0
= tcg_temp_new();
3188 t1
= tcg_temp_new();
3190 gen_load_gpr(t0
, rs
);
3191 gen_load_gpr(t1
, rt
);
3200 TCGv t2
= tcg_temp_new();
3201 TCGv t3
= tcg_temp_new();
3202 tcg_gen_ext32s_tl(t0
, t0
);
3203 tcg_gen_ext32s_tl(t1
, t1
);
3204 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3205 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3206 tcg_gen_and_tl(t2
, t2
, t3
);
3207 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3208 tcg_gen_or_tl(t2
, t2
, t3
);
3209 tcg_gen_movi_tl(t3
, 0);
3210 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3211 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3212 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3213 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3214 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3222 TCGv t2
= tcg_const_tl(0);
3223 TCGv t3
= tcg_const_tl(1);
3224 tcg_gen_ext32u_tl(t0
, t0
);
3225 tcg_gen_ext32u_tl(t1
, t1
);
3226 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3227 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3228 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3229 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3230 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3238 TCGv_i32 t2
= tcg_temp_new_i32();
3239 TCGv_i32 t3
= tcg_temp_new_i32();
3240 tcg_gen_trunc_tl_i32(t2
, t0
);
3241 tcg_gen_trunc_tl_i32(t3
, t1
);
3242 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3243 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3244 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3245 tcg_temp_free_i32(t2
);
3246 tcg_temp_free_i32(t3
);
3252 TCGv_i32 t2
= tcg_temp_new_i32();
3253 TCGv_i32 t3
= tcg_temp_new_i32();
3254 tcg_gen_trunc_tl_i32(t2
, t0
);
3255 tcg_gen_trunc_tl_i32(t3
, t1
);
3256 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3257 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3258 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3259 tcg_temp_free_i32(t2
);
3260 tcg_temp_free_i32(t3
);
3264 #if defined(TARGET_MIPS64)
3267 TCGv t2
= tcg_temp_new();
3268 TCGv t3
= tcg_temp_new();
3269 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3270 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3271 tcg_gen_and_tl(t2
, t2
, t3
);
3272 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3273 tcg_gen_or_tl(t2
, t2
, t3
);
3274 tcg_gen_movi_tl(t3
, 0);
3275 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3276 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3277 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3285 TCGv t2
= tcg_const_tl(0);
3286 TCGv t3
= tcg_const_tl(1);
3287 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3288 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3289 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3296 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3300 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3306 TCGv_i64 t2
= tcg_temp_new_i64();
3307 TCGv_i64 t3
= tcg_temp_new_i64();
3309 tcg_gen_ext_tl_i64(t2
, t0
);
3310 tcg_gen_ext_tl_i64(t3
, t1
);
3311 tcg_gen_mul_i64(t2
, t2
, t3
);
3312 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3313 tcg_gen_add_i64(t2
, t2
, t3
);
3314 tcg_temp_free_i64(t3
);
3315 tcg_gen_trunc_i64_tl(t0
, t2
);
3316 tcg_gen_shri_i64(t2
, t2
, 32);
3317 tcg_gen_trunc_i64_tl(t1
, t2
);
3318 tcg_temp_free_i64(t2
);
3319 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3320 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3326 TCGv_i64 t2
= tcg_temp_new_i64();
3327 TCGv_i64 t3
= tcg_temp_new_i64();
3329 tcg_gen_ext32u_tl(t0
, t0
);
3330 tcg_gen_ext32u_tl(t1
, t1
);
3331 tcg_gen_extu_tl_i64(t2
, t0
);
3332 tcg_gen_extu_tl_i64(t3
, t1
);
3333 tcg_gen_mul_i64(t2
, t2
, t3
);
3334 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3335 tcg_gen_add_i64(t2
, t2
, t3
);
3336 tcg_temp_free_i64(t3
);
3337 tcg_gen_trunc_i64_tl(t0
, t2
);
3338 tcg_gen_shri_i64(t2
, t2
, 32);
3339 tcg_gen_trunc_i64_tl(t1
, t2
);
3340 tcg_temp_free_i64(t2
);
3341 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3342 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3348 TCGv_i64 t2
= tcg_temp_new_i64();
3349 TCGv_i64 t3
= tcg_temp_new_i64();
3351 tcg_gen_ext_tl_i64(t2
, t0
);
3352 tcg_gen_ext_tl_i64(t3
, t1
);
3353 tcg_gen_mul_i64(t2
, t2
, t3
);
3354 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3355 tcg_gen_sub_i64(t2
, t3
, t2
);
3356 tcg_temp_free_i64(t3
);
3357 tcg_gen_trunc_i64_tl(t0
, t2
);
3358 tcg_gen_shri_i64(t2
, t2
, 32);
3359 tcg_gen_trunc_i64_tl(t1
, t2
);
3360 tcg_temp_free_i64(t2
);
3361 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3362 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3368 TCGv_i64 t2
= tcg_temp_new_i64();
3369 TCGv_i64 t3
= tcg_temp_new_i64();
3371 tcg_gen_ext32u_tl(t0
, t0
);
3372 tcg_gen_ext32u_tl(t1
, t1
);
3373 tcg_gen_extu_tl_i64(t2
, t0
);
3374 tcg_gen_extu_tl_i64(t3
, t1
);
3375 tcg_gen_mul_i64(t2
, t2
, t3
);
3376 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3377 tcg_gen_sub_i64(t2
, t3
, t2
);
3378 tcg_temp_free_i64(t3
);
3379 tcg_gen_trunc_i64_tl(t0
, t2
);
3380 tcg_gen_shri_i64(t2
, t2
, 32);
3381 tcg_gen_trunc_i64_tl(t1
, t2
);
3382 tcg_temp_free_i64(t2
);
3383 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3384 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3390 generate_exception(ctx
, EXCP_RI
);
3393 (void)opn
; /* avoid a compiler warning */
3394 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3400 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
3401 int rd
, int rs
, int rt
)
3403 const char *opn
= "mul vr54xx";
3404 TCGv t0
= tcg_temp_new();
3405 TCGv t1
= tcg_temp_new();
3407 gen_load_gpr(t0
, rs
);
3408 gen_load_gpr(t1
, rt
);
3411 case OPC_VR54XX_MULS
:
3412 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3415 case OPC_VR54XX_MULSU
:
3416 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3419 case OPC_VR54XX_MACC
:
3420 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3423 case OPC_VR54XX_MACCU
:
3424 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3427 case OPC_VR54XX_MSAC
:
3428 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3431 case OPC_VR54XX_MSACU
:
3432 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3435 case OPC_VR54XX_MULHI
:
3436 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3439 case OPC_VR54XX_MULHIU
:
3440 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3443 case OPC_VR54XX_MULSHI
:
3444 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3447 case OPC_VR54XX_MULSHIU
:
3448 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3451 case OPC_VR54XX_MACCHI
:
3452 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3455 case OPC_VR54XX_MACCHIU
:
3456 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3459 case OPC_VR54XX_MSACHI
:
3460 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3463 case OPC_VR54XX_MSACHIU
:
3464 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3468 MIPS_INVAL("mul vr54xx");
3469 generate_exception(ctx
, EXCP_RI
);
3472 gen_store_gpr(t0
, rd
);
3473 (void)opn
; /* avoid a compiler warning */
3474 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3481 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
3484 const char *opn
= "CLx";
3492 t0
= tcg_temp_new();
3493 gen_load_gpr(t0
, rs
);
3497 gen_helper_clo(cpu_gpr
[rd
], t0
);
3502 gen_helper_clz(cpu_gpr
[rd
], t0
);
3505 #if defined(TARGET_MIPS64)
3508 gen_helper_dclo(cpu_gpr
[rd
], t0
);
3513 gen_helper_dclz(cpu_gpr
[rd
], t0
);
3518 (void)opn
; /* avoid a compiler warning */
3519 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3523 /* Godson integer instructions */
3524 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3525 int rd
, int rs
, int rt
)
3527 const char *opn
= "loongson";
3539 case OPC_MULTU_G_2E
:
3540 case OPC_MULTU_G_2F
:
3541 #if defined(TARGET_MIPS64)
3542 case OPC_DMULT_G_2E
:
3543 case OPC_DMULT_G_2F
:
3544 case OPC_DMULTU_G_2E
:
3545 case OPC_DMULTU_G_2F
:
3547 t0
= tcg_temp_new();
3548 t1
= tcg_temp_new();
3551 t0
= tcg_temp_local_new();
3552 t1
= tcg_temp_local_new();
3556 gen_load_gpr(t0
, rs
);
3557 gen_load_gpr(t1
, rt
);
3562 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3563 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3566 case OPC_MULTU_G_2E
:
3567 case OPC_MULTU_G_2F
:
3568 tcg_gen_ext32u_tl(t0
, t0
);
3569 tcg_gen_ext32u_tl(t1
, t1
);
3570 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3571 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3577 int l1
= gen_new_label();
3578 int l2
= gen_new_label();
3579 int l3
= gen_new_label();
3580 tcg_gen_ext32s_tl(t0
, t0
);
3581 tcg_gen_ext32s_tl(t1
, t1
);
3582 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3583 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3586 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3587 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3588 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3591 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3592 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3600 int l1
= gen_new_label();
3601 int l2
= gen_new_label();
3602 tcg_gen_ext32u_tl(t0
, t0
);
3603 tcg_gen_ext32u_tl(t1
, t1
);
3604 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3605 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3608 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3609 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3617 int l1
= gen_new_label();
3618 int l2
= gen_new_label();
3619 int l3
= gen_new_label();
3620 tcg_gen_ext32u_tl(t0
, t0
);
3621 tcg_gen_ext32u_tl(t1
, t1
);
3622 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3623 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3624 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3626 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3629 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3630 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3638 int l1
= gen_new_label();
3639 int l2
= gen_new_label();
3640 tcg_gen_ext32u_tl(t0
, t0
);
3641 tcg_gen_ext32u_tl(t1
, t1
);
3642 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3643 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3646 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3647 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3652 #if defined(TARGET_MIPS64)
3653 case OPC_DMULT_G_2E
:
3654 case OPC_DMULT_G_2F
:
3655 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3658 case OPC_DMULTU_G_2E
:
3659 case OPC_DMULTU_G_2F
:
3660 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3666 int l1
= gen_new_label();
3667 int l2
= gen_new_label();
3668 int l3
= gen_new_label();
3669 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3670 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3673 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3674 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3675 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3678 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3683 case OPC_DDIVU_G_2E
:
3684 case OPC_DDIVU_G_2F
:
3686 int l1
= gen_new_label();
3687 int l2
= gen_new_label();
3688 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3689 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3692 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3700 int l1
= gen_new_label();
3701 int l2
= gen_new_label();
3702 int l3
= gen_new_label();
3703 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3704 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3705 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3707 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3710 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3715 case OPC_DMODU_G_2E
:
3716 case OPC_DMODU_G_2F
:
3718 int l1
= gen_new_label();
3719 int l2
= gen_new_label();
3720 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3721 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3724 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3732 (void)opn
; /* avoid a compiler warning */
3733 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3738 /* Loongson multimedia instructions */
3739 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3741 const char *opn
= "loongson_cp2";
3742 uint32_t opc
, shift_max
;
3745 opc
= MASK_LMI(ctx
->opcode
);
3751 t0
= tcg_temp_local_new_i64();
3752 t1
= tcg_temp_local_new_i64();
3755 t0
= tcg_temp_new_i64();
3756 t1
= tcg_temp_new_i64();
3760 gen_load_fpr64(ctx
, t0
, rs
);
3761 gen_load_fpr64(ctx
, t1
, rt
);
3763 #define LMI_HELPER(UP, LO) \
3764 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3765 #define LMI_HELPER_1(UP, LO) \
3766 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3767 #define LMI_DIRECT(UP, LO, OP) \
3768 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3771 LMI_HELPER(PADDSH
, paddsh
);
3772 LMI_HELPER(PADDUSH
, paddush
);
3773 LMI_HELPER(PADDH
, paddh
);
3774 LMI_HELPER(PADDW
, paddw
);
3775 LMI_HELPER(PADDSB
, paddsb
);
3776 LMI_HELPER(PADDUSB
, paddusb
);
3777 LMI_HELPER(PADDB
, paddb
);
3779 LMI_HELPER(PSUBSH
, psubsh
);
3780 LMI_HELPER(PSUBUSH
, psubush
);
3781 LMI_HELPER(PSUBH
, psubh
);
3782 LMI_HELPER(PSUBW
, psubw
);
3783 LMI_HELPER(PSUBSB
, psubsb
);
3784 LMI_HELPER(PSUBUSB
, psubusb
);
3785 LMI_HELPER(PSUBB
, psubb
);
3787 LMI_HELPER(PSHUFH
, pshufh
);
3788 LMI_HELPER(PACKSSWH
, packsswh
);
3789 LMI_HELPER(PACKSSHB
, packsshb
);
3790 LMI_HELPER(PACKUSHB
, packushb
);
3792 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3793 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3794 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3795 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3796 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3797 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3799 LMI_HELPER(PAVGH
, pavgh
);
3800 LMI_HELPER(PAVGB
, pavgb
);
3801 LMI_HELPER(PMAXSH
, pmaxsh
);
3802 LMI_HELPER(PMINSH
, pminsh
);
3803 LMI_HELPER(PMAXUB
, pmaxub
);
3804 LMI_HELPER(PMINUB
, pminub
);
3806 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3807 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3808 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3809 LMI_HELPER(PCMPGTH
, pcmpgth
);
3810 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3811 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3813 LMI_HELPER(PSLLW
, psllw
);
3814 LMI_HELPER(PSLLH
, psllh
);
3815 LMI_HELPER(PSRLW
, psrlw
);
3816 LMI_HELPER(PSRLH
, psrlh
);
3817 LMI_HELPER(PSRAW
, psraw
);
3818 LMI_HELPER(PSRAH
, psrah
);
3820 LMI_HELPER(PMULLH
, pmullh
);
3821 LMI_HELPER(PMULHH
, pmulhh
);
3822 LMI_HELPER(PMULHUH
, pmulhuh
);
3823 LMI_HELPER(PMADDHW
, pmaddhw
);
3825 LMI_HELPER(PASUBUB
, pasubub
);
3826 LMI_HELPER_1(BIADD
, biadd
);
3827 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3829 LMI_DIRECT(PADDD
, paddd
, add
);
3830 LMI_DIRECT(PSUBD
, psubd
, sub
);
3831 LMI_DIRECT(XOR_CP2
, xor, xor);
3832 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3833 LMI_DIRECT(AND_CP2
, and, and);
3834 LMI_DIRECT(PANDN
, pandn
, andc
);
3835 LMI_DIRECT(OR
, or, or);
3838 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3842 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3846 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3850 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3855 tcg_gen_andi_i64(t1
, t1
, 3);
3856 tcg_gen_shli_i64(t1
, t1
, 4);
3857 tcg_gen_shr_i64(t0
, t0
, t1
);
3858 tcg_gen_ext16u_i64(t0
, t0
);
3863 tcg_gen_add_i64(t0
, t0
, t1
);
3864 tcg_gen_ext32s_i64(t0
, t0
);
3868 tcg_gen_sub_i64(t0
, t0
, t1
);
3869 tcg_gen_ext32s_i64(t0
, t0
);
3898 /* Make sure shift count isn't TCG undefined behaviour. */
3899 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3904 tcg_gen_shl_i64(t0
, t0
, t1
);
3908 /* Since SRA is UndefinedResult without sign-extended inputs,
3909 we can treat SRA and DSRA the same. */
3910 tcg_gen_sar_i64(t0
, t0
, t1
);
3913 /* We want to shift in zeros for SRL; zero-extend first. */
3914 tcg_gen_ext32u_i64(t0
, t0
);
3917 tcg_gen_shr_i64(t0
, t0
, t1
);
3921 if (shift_max
== 32) {
3922 tcg_gen_ext32s_i64(t0
, t0
);
3925 /* Shifts larger than MAX produce zero. */
3926 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3927 tcg_gen_neg_i64(t1
, t1
);
3928 tcg_gen_and_i64(t0
, t0
, t1
);
3934 TCGv_i64 t2
= tcg_temp_new_i64();
3935 int lab
= gen_new_label();
3937 tcg_gen_mov_i64(t2
, t0
);
3938 tcg_gen_add_i64(t0
, t1
, t2
);
3939 if (opc
== OPC_ADD_CP2
) {
3940 tcg_gen_ext32s_i64(t0
, t0
);
3942 tcg_gen_xor_i64(t1
, t1
, t2
);
3943 tcg_gen_xor_i64(t2
, t2
, t0
);
3944 tcg_gen_andc_i64(t1
, t2
, t1
);
3945 tcg_temp_free_i64(t2
);
3946 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3947 generate_exception(ctx
, EXCP_OVERFLOW
);
3950 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3957 TCGv_i64 t2
= tcg_temp_new_i64();
3958 int lab
= gen_new_label();
3960 tcg_gen_mov_i64(t2
, t0
);
3961 tcg_gen_sub_i64(t0
, t1
, t2
);
3962 if (opc
== OPC_SUB_CP2
) {
3963 tcg_gen_ext32s_i64(t0
, t0
);
3965 tcg_gen_xor_i64(t1
, t1
, t2
);
3966 tcg_gen_xor_i64(t2
, t2
, t0
);
3967 tcg_gen_and_i64(t1
, t1
, t2
);
3968 tcg_temp_free_i64(t2
);
3969 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3970 generate_exception(ctx
, EXCP_OVERFLOW
);
3973 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3978 tcg_gen_ext32u_i64(t0
, t0
);
3979 tcg_gen_ext32u_i64(t1
, t1
);
3980 tcg_gen_mul_i64(t0
, t0
, t1
);
3990 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3991 FD field is the CC field? */
3994 generate_exception(ctx
, EXCP_RI
);
4001 gen_store_fpr64(ctx
, t0
, rd
);
4003 (void)opn
; /* avoid a compiler warning */
4004 MIPS_DEBUG("%s %s, %s, %s", opn
,
4005 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
4006 tcg_temp_free_i64(t0
);
4007 tcg_temp_free_i64(t1
);
4011 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
4012 int rs
, int rt
, int16_t imm
)
4015 TCGv t0
= tcg_temp_new();
4016 TCGv t1
= tcg_temp_new();
4019 /* Load needed operands */
4027 /* Compare two registers */
4029 gen_load_gpr(t0
, rs
);
4030 gen_load_gpr(t1
, rt
);
4040 /* Compare register to immediate */
4041 if (rs
!= 0 || imm
!= 0) {
4042 gen_load_gpr(t0
, rs
);
4043 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4050 case OPC_TEQ
: /* rs == rs */
4051 case OPC_TEQI
: /* r0 == 0 */
4052 case OPC_TGE
: /* rs >= rs */
4053 case OPC_TGEI
: /* r0 >= 0 */
4054 case OPC_TGEU
: /* rs >= rs unsigned */
4055 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4057 generate_exception(ctx
, EXCP_TRAP
);
4059 case OPC_TLT
: /* rs < rs */
4060 case OPC_TLTI
: /* r0 < 0 */
4061 case OPC_TLTU
: /* rs < rs unsigned */
4062 case OPC_TLTIU
: /* r0 < 0 unsigned */
4063 case OPC_TNE
: /* rs != rs */
4064 case OPC_TNEI
: /* r0 != 0 */
4065 /* Never trap: treat as NOP. */
4069 int l1
= gen_new_label();
4074 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4078 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4082 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
4086 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
4090 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
4094 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
4097 generate_exception(ctx
, EXCP_TRAP
);
4104 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
4106 TranslationBlock
*tb
;
4108 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
4109 likely(!ctx
->singlestep_enabled
)) {
4112 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
4115 if (ctx
->singlestep_enabled
) {
4116 save_cpu_state(ctx
, 0);
4117 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
4123 /* Branches (before delay slot) */
4124 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
4126 int rs
, int rt
, int32_t offset
,
4129 target_ulong btgt
= -1;
4131 int bcond_compute
= 0;
4132 TCGv t0
= tcg_temp_new();
4133 TCGv t1
= tcg_temp_new();
4135 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
4136 #ifdef MIPS_DEBUG_DISAS
4137 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
4139 generate_exception(ctx
, EXCP_RI
);
4143 /* Load needed operands */
4149 /* Compare two registers */
4151 gen_load_gpr(t0
, rs
);
4152 gen_load_gpr(t1
, rt
);
4155 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4169 /* Compare to zero */
4171 gen_load_gpr(t0
, rs
);
4174 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4177 #if defined(TARGET_MIPS64)
4179 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
4181 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
4184 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4189 /* Jump to immediate */
4190 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
4194 /* Jump to register */
4195 if (offset
!= 0 && offset
!= 16) {
4196 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4197 others are reserved. */
4198 MIPS_INVAL("jump hint");
4199 generate_exception(ctx
, EXCP_RI
);
4202 gen_load_gpr(btarget
, rs
);
4205 MIPS_INVAL("branch/jump");
4206 generate_exception(ctx
, EXCP_RI
);
4209 if (bcond_compute
== 0) {
4210 /* No condition to be computed */
4212 case OPC_BEQ
: /* rx == rx */
4213 case OPC_BEQL
: /* rx == rx likely */
4214 case OPC_BGEZ
: /* 0 >= 0 */
4215 case OPC_BGEZL
: /* 0 >= 0 likely */
4216 case OPC_BLEZ
: /* 0 <= 0 */
4217 case OPC_BLEZL
: /* 0 <= 0 likely */
4219 ctx
->hflags
|= MIPS_HFLAG_B
;
4220 MIPS_DEBUG("balways");
4222 case OPC_BGEZAL
: /* 0 >= 0 */
4223 case OPC_BGEZALL
: /* 0 >= 0 likely */
4224 /* Always take and link */
4226 ctx
->hflags
|= MIPS_HFLAG_B
;
4227 MIPS_DEBUG("balways and link");
4229 case OPC_BNE
: /* rx != rx */
4230 case OPC_BGTZ
: /* 0 > 0 */
4231 case OPC_BLTZ
: /* 0 < 0 */
4233 MIPS_DEBUG("bnever (NOP)");
4235 case OPC_BLTZAL
: /* 0 < 0 */
4236 /* Handle as an unconditional branch to get correct delay
4239 btgt
= ctx
->pc
+ insn_bytes
+ delayslot_size
;
4240 ctx
->hflags
|= MIPS_HFLAG_B
;
4241 MIPS_DEBUG("bnever and link");
4243 case OPC_BLTZALL
: /* 0 < 0 likely */
4244 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
4245 /* Skip the instruction in the delay slot */
4246 MIPS_DEBUG("bnever, link and skip");
4249 case OPC_BNEL
: /* rx != rx likely */
4250 case OPC_BGTZL
: /* 0 > 0 likely */
4251 case OPC_BLTZL
: /* 0 < 0 likely */
4252 /* Skip the instruction in the delay slot */
4253 MIPS_DEBUG("bnever and skip");
4257 ctx
->hflags
|= MIPS_HFLAG_B
;
4258 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
4261 ctx
->hflags
|= MIPS_HFLAG_BX
;
4265 ctx
->hflags
|= MIPS_HFLAG_B
;
4266 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
4269 ctx
->hflags
|= MIPS_HFLAG_BR
;
4270 MIPS_DEBUG("jr %s", regnames
[rs
]);
4274 ctx
->hflags
|= MIPS_HFLAG_BR
;
4275 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
4278 MIPS_INVAL("branch/jump");
4279 generate_exception(ctx
, EXCP_RI
);
4285 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4286 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
4287 regnames
[rs
], regnames
[rt
], btgt
);
4290 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4291 MIPS_DEBUG("beql %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("bne %s, %s, " TARGET_FMT_lx
,
4297 regnames
[rs
], regnames
[rt
], btgt
);
4300 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4301 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
4302 regnames
[rs
], regnames
[rt
], btgt
);
4305 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4306 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4309 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4310 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4313 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4314 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4318 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4320 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4323 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4324 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4327 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4328 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4331 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4332 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4335 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4336 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4339 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4340 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4343 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4344 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4347 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
4348 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
4350 #if defined(TARGET_MIPS64)
4352 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
4353 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
4357 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4359 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4361 ctx
->hflags
|= MIPS_HFLAG_BC
;
4364 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4366 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4368 ctx
->hflags
|= MIPS_HFLAG_BL
;
4371 MIPS_INVAL("conditional branch/jump");
4372 generate_exception(ctx
, EXCP_RI
);
4376 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
4377 blink
, ctx
->hflags
, btgt
);
4379 ctx
->btarget
= btgt
;
4381 switch (delayslot_size
) {
4383 ctx
->hflags
|= MIPS_HFLAG_BDS16
;
4386 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
4391 int post_delay
= insn_bytes
+ delayslot_size
;
4392 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
4394 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
4398 if (insn_bytes
== 2)
4399 ctx
->hflags
|= MIPS_HFLAG_B16
;
4404 /* special3 bitfield operations */
4405 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
4406 int rs
, int lsb
, int msb
)
4408 TCGv t0
= tcg_temp_new();
4409 TCGv t1
= tcg_temp_new();
4411 gen_load_gpr(t1
, rs
);
4416 tcg_gen_shri_tl(t0
, t1
, lsb
);
4418 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
4420 tcg_gen_ext32s_tl(t0
, t0
);
4423 #if defined(TARGET_MIPS64)
4425 tcg_gen_shri_tl(t0
, t1
, lsb
);
4427 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
4431 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
4432 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4435 tcg_gen_shri_tl(t0
, t1
, lsb
);
4436 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4442 gen_load_gpr(t0
, rt
);
4443 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4444 tcg_gen_ext32s_tl(t0
, t0
);
4446 #if defined(TARGET_MIPS64)
4448 gen_load_gpr(t0
, rt
);
4449 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
4452 gen_load_gpr(t0
, rt
);
4453 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
4456 gen_load_gpr(t0
, rt
);
4457 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4462 MIPS_INVAL("bitops");
4463 generate_exception(ctx
, EXCP_RI
);
4468 gen_store_gpr(t0
, rt
);
4473 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4478 /* If no destination, treat it as a NOP. */
4483 t0
= tcg_temp_new();
4484 gen_load_gpr(t0
, rt
);
4488 TCGv t1
= tcg_temp_new();
4490 tcg_gen_shri_tl(t1
, t0
, 8);
4491 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4492 tcg_gen_shli_tl(t0
, t0
, 8);
4493 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4494 tcg_gen_or_tl(t0
, t0
, t1
);
4496 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4500 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4503 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4505 #if defined(TARGET_MIPS64)
4508 TCGv t1
= tcg_temp_new();
4510 tcg_gen_shri_tl(t1
, t0
, 8);
4511 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4512 tcg_gen_shli_tl(t0
, t0
, 8);
4513 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4514 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4520 TCGv t1
= tcg_temp_new();
4522 tcg_gen_shri_tl(t1
, t0
, 16);
4523 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4524 tcg_gen_shli_tl(t0
, t0
, 16);
4525 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4526 tcg_gen_or_tl(t0
, t0
, t1
);
4527 tcg_gen_shri_tl(t1
, t0
, 32);
4528 tcg_gen_shli_tl(t0
, t0
, 32);
4529 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4535 MIPS_INVAL("bsfhl");
4536 generate_exception(ctx
, EXCP_RI
);
4543 #ifndef CONFIG_USER_ONLY
4544 /* CP0 (MMU and control) */
4545 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4547 TCGv_i32 t0
= tcg_temp_new_i32();
4549 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4550 tcg_gen_ext_i32_tl(arg
, t0
);
4551 tcg_temp_free_i32(t0
);
4554 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4556 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4557 tcg_gen_ext32s_tl(arg
, arg
);
4560 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4562 TCGv_i32 t0
= tcg_temp_new_i32();
4564 tcg_gen_trunc_tl_i32(t0
, arg
);
4565 tcg_gen_st_i32(t0
, cpu_env
, off
);
4566 tcg_temp_free_i32(t0
);
4569 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4571 tcg_gen_ext32s_tl(arg
, arg
);
4572 tcg_gen_st_tl(arg
, cpu_env
, off
);
4575 static inline void gen_mfc0_unimplemented(DisasContext
*ctx
, TCGv arg
)
4577 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
4578 tcg_gen_movi_tl(arg
, 0);
4580 tcg_gen_movi_tl(arg
, ~0);
4584 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4586 const char *rn
= "invalid";
4589 check_insn(ctx
, ISA_MIPS32
);
4595 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4599 check_insn(ctx
, ASE_MT
);
4600 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4604 check_insn(ctx
, ASE_MT
);
4605 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4609 check_insn(ctx
, ASE_MT
);
4610 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4620 gen_helper_mfc0_random(arg
, cpu_env
);
4624 check_insn(ctx
, ASE_MT
);
4625 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4629 check_insn(ctx
, ASE_MT
);
4630 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4634 check_insn(ctx
, ASE_MT
);
4635 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4639 check_insn(ctx
, ASE_MT
);
4640 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4644 check_insn(ctx
, ASE_MT
);
4645 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4649 check_insn(ctx
, ASE_MT
);
4650 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4651 rn
= "VPEScheFBack";
4654 check_insn(ctx
, ASE_MT
);
4655 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4665 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4666 #if defined(TARGET_MIPS64)
4668 TCGv tmp
= tcg_temp_new();
4669 tcg_gen_andi_tl(tmp
, arg
, (3ull << 62));
4670 tcg_gen_shri_tl(tmp
, tmp
, 32);
4671 tcg_gen_or_tl(arg
, arg
, tmp
);
4675 tcg_gen_ext32s_tl(arg
, arg
);
4679 check_insn(ctx
, ASE_MT
);
4680 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4684 check_insn(ctx
, ASE_MT
);
4685 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4689 check_insn(ctx
, ASE_MT
);
4690 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4694 check_insn(ctx
, ASE_MT
);
4695 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4699 check_insn(ctx
, ASE_MT
);
4700 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4704 check_insn(ctx
, ASE_MT
);
4705 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4709 check_insn(ctx
, ASE_MT
);
4710 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4720 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4721 #if defined(TARGET_MIPS64)
4723 TCGv tmp
= tcg_temp_new();
4724 tcg_gen_andi_tl(tmp
, arg
, (3ull << 62));
4725 tcg_gen_shri_tl(tmp
, tmp
, 32);
4726 tcg_gen_or_tl(arg
, arg
, tmp
);
4730 tcg_gen_ext32s_tl(arg
, arg
);
4740 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4741 tcg_gen_ext32s_tl(arg
, arg
);
4745 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4746 rn
= "ContextConfig";
4751 tcg_gen_ld32s_tl(arg
, cpu_env
,
4752 offsetof(CPUMIPSState
,
4753 active_tc
.CP0_UserLocal
));
4756 tcg_gen_movi_tl(arg
, 0);
4766 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4770 check_insn(ctx
, ISA_MIPS32R2
);
4771 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4781 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4785 check_insn(ctx
, ISA_MIPS32R2
);
4786 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4790 check_insn(ctx
, ISA_MIPS32R2
);
4791 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4795 check_insn(ctx
, ISA_MIPS32R2
);
4796 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4800 check_insn(ctx
, ISA_MIPS32R2
);
4801 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4805 check_insn(ctx
, ISA_MIPS32R2
);
4806 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4816 check_insn(ctx
, ISA_MIPS32R2
);
4817 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4827 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4828 tcg_gen_ext32s_tl(arg
, arg
);
4838 /* Mark as an IO operation because we read the time. */
4841 gen_helper_mfc0_count(arg
, cpu_env
);
4845 /* Break the TB to be able to take timer interrupts immediately
4846 after reading count. */
4847 ctx
->bstate
= BS_STOP
;
4850 /* 6,7 are implementation dependent */
4858 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4859 tcg_gen_ext32s_tl(arg
, arg
);
4869 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4872 /* 6,7 are implementation dependent */
4880 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4884 check_insn(ctx
, ISA_MIPS32R2
);
4885 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4889 check_insn(ctx
, ISA_MIPS32R2
);
4890 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4894 check_insn(ctx
, ISA_MIPS32R2
);
4895 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4905 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4915 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4916 tcg_gen_ext32s_tl(arg
, arg
);
4926 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4930 check_insn(ctx
, ISA_MIPS32R2
);
4931 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4941 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4945 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4949 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4953 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4957 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
4961 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
4964 /* 6,7 are implementation dependent */
4966 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4970 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4980 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4990 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
5000 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5010 #if defined(TARGET_MIPS64)
5011 check_insn(ctx
, ISA_MIPS3
);
5012 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5013 tcg_gen_ext32s_tl(arg
, arg
);
5022 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5025 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5033 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5034 rn
= "'Diagnostic"; /* implementation dependent */
5039 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5043 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5044 rn
= "TraceControl";
5047 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5048 rn
= "TraceControl2";
5051 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5052 rn
= "UserTraceData";
5055 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5066 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5067 tcg_gen_ext32s_tl(arg
, arg
);
5077 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5078 rn
= "Performance0";
5081 // gen_helper_mfc0_performance1(arg);
5082 rn
= "Performance1";
5085 // gen_helper_mfc0_performance2(arg);
5086 rn
= "Performance2";
5089 // gen_helper_mfc0_performance3(arg);
5090 rn
= "Performance3";
5093 // gen_helper_mfc0_performance4(arg);
5094 rn
= "Performance4";
5097 // gen_helper_mfc0_performance5(arg);
5098 rn
= "Performance5";
5101 // gen_helper_mfc0_performance6(arg);
5102 rn
= "Performance6";
5105 // gen_helper_mfc0_performance7(arg);
5106 rn
= "Performance7";
5113 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5119 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5132 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5139 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5152 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5159 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5169 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5170 tcg_gen_ext32s_tl(arg
, arg
);
5181 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5185 if (ctx
->kscrexist
& (1 << sel
)) {
5186 tcg_gen_ld_tl(arg
, cpu_env
,
5187 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
5188 tcg_gen_ext32s_tl(arg
, arg
);
5191 gen_mfc0_unimplemented(ctx
, arg
);
5201 (void)rn
; /* avoid a compiler warning */
5202 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5206 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5207 generate_exception(ctx
, EXCP_RI
);
5210 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5212 const char *rn
= "invalid";
5215 check_insn(ctx
, ISA_MIPS32
);
5224 gen_helper_mtc0_index(cpu_env
, arg
);
5228 check_insn(ctx
, ASE_MT
);
5229 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5233 check_insn(ctx
, ASE_MT
);
5238 check_insn(ctx
, ASE_MT
);
5253 check_insn(ctx
, ASE_MT
);
5254 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5258 check_insn(ctx
, ASE_MT
);
5259 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5263 check_insn(ctx
, ASE_MT
);
5264 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5268 check_insn(ctx
, ASE_MT
);
5269 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5273 check_insn(ctx
, ASE_MT
);
5274 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5278 check_insn(ctx
, ASE_MT
);
5279 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5280 rn
= "VPEScheFBack";
5283 check_insn(ctx
, ASE_MT
);
5284 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5294 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5298 check_insn(ctx
, ASE_MT
);
5299 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5303 check_insn(ctx
, ASE_MT
);
5304 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5308 check_insn(ctx
, ASE_MT
);
5309 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5313 check_insn(ctx
, ASE_MT
);
5314 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5318 check_insn(ctx
, ASE_MT
);
5319 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5323 check_insn(ctx
, ASE_MT
);
5324 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5328 check_insn(ctx
, ASE_MT
);
5329 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5339 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5349 gen_helper_mtc0_context(cpu_env
, arg
);
5353 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5354 rn
= "ContextConfig";
5359 tcg_gen_st_tl(arg
, cpu_env
,
5360 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5371 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5375 check_insn(ctx
, ISA_MIPS32R2
);
5376 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5386 gen_helper_mtc0_wired(cpu_env
, arg
);
5390 check_insn(ctx
, ISA_MIPS32R2
);
5391 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5395 check_insn(ctx
, ISA_MIPS32R2
);
5396 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
5400 check_insn(ctx
, ISA_MIPS32R2
);
5401 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
5405 check_insn(ctx
, ISA_MIPS32R2
);
5406 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
5410 check_insn(ctx
, ISA_MIPS32R2
);
5411 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
5421 check_insn(ctx
, ISA_MIPS32R2
);
5422 gen_helper_mtc0_hwrena(cpu_env
, arg
);
5423 ctx
->bstate
= BS_STOP
;
5437 gen_helper_mtc0_count(cpu_env
, arg
);
5440 /* 6,7 are implementation dependent */
5448 gen_helper_mtc0_entryhi(cpu_env
, arg
);
5458 gen_helper_mtc0_compare(cpu_env
, arg
);
5461 /* 6,7 are implementation dependent */
5469 save_cpu_state(ctx
, 1);
5470 gen_helper_mtc0_status(cpu_env
, arg
);
5471 /* BS_STOP isn't good enough here, hflags may have changed. */
5472 gen_save_pc(ctx
->pc
+ 4);
5473 ctx
->bstate
= BS_EXCP
;
5477 check_insn(ctx
, ISA_MIPS32R2
);
5478 gen_helper_mtc0_intctl(cpu_env
, arg
);
5479 /* Stop translation as we may have switched the execution mode */
5480 ctx
->bstate
= BS_STOP
;
5484 check_insn(ctx
, ISA_MIPS32R2
);
5485 gen_helper_mtc0_srsctl(cpu_env
, arg
);
5486 /* Stop translation as we may have switched the execution mode */
5487 ctx
->bstate
= BS_STOP
;
5491 check_insn(ctx
, ISA_MIPS32R2
);
5492 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5493 /* Stop translation as we may have switched the execution mode */
5494 ctx
->bstate
= BS_STOP
;
5504 save_cpu_state(ctx
, 1);
5505 gen_helper_mtc0_cause(cpu_env
, arg
);
5515 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
5529 check_insn(ctx
, ISA_MIPS32R2
);
5530 gen_helper_mtc0_ebase(cpu_env
, arg
);
5540 gen_helper_mtc0_config0(cpu_env
, arg
);
5542 /* Stop translation as we may have switched the execution mode */
5543 ctx
->bstate
= BS_STOP
;
5546 /* ignored, read only */
5550 gen_helper_mtc0_config2(cpu_env
, arg
);
5552 /* Stop translation as we may have switched the execution mode */
5553 ctx
->bstate
= BS_STOP
;
5556 /* ignored, read only */
5560 gen_helper_mtc0_config4(cpu_env
, arg
);
5562 ctx
->bstate
= BS_STOP
;
5565 gen_helper_mtc0_config5(cpu_env
, arg
);
5567 /* Stop translation as we may have switched the execution mode */
5568 ctx
->bstate
= BS_STOP
;
5570 /* 6,7 are implementation dependent */
5580 rn
= "Invalid config selector";
5587 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5597 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5607 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5617 #if defined(TARGET_MIPS64)
5618 check_insn(ctx
, ISA_MIPS3
);
5619 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5628 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5631 gen_helper_mtc0_framemask(cpu_env
, arg
);
5640 rn
= "Diagnostic"; /* implementation dependent */
5645 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5646 /* BS_STOP isn't good enough here, hflags may have changed. */
5647 gen_save_pc(ctx
->pc
+ 4);
5648 ctx
->bstate
= BS_EXCP
;
5652 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5653 rn
= "TraceControl";
5654 /* Stop translation as we may have switched the execution mode */
5655 ctx
->bstate
= BS_STOP
;
5658 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5659 rn
= "TraceControl2";
5660 /* Stop translation as we may have switched the execution mode */
5661 ctx
->bstate
= BS_STOP
;
5664 /* Stop translation as we may have switched the execution mode */
5665 ctx
->bstate
= BS_STOP
;
5666 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5667 rn
= "UserTraceData";
5668 /* Stop translation as we may have switched the execution mode */
5669 ctx
->bstate
= BS_STOP
;
5672 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5673 /* Stop translation as we may have switched the execution mode */
5674 ctx
->bstate
= BS_STOP
;
5685 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5695 gen_helper_mtc0_performance0(cpu_env
, arg
);
5696 rn
= "Performance0";
5699 // gen_helper_mtc0_performance1(arg);
5700 rn
= "Performance1";
5703 // gen_helper_mtc0_performance2(arg);
5704 rn
= "Performance2";
5707 // gen_helper_mtc0_performance3(arg);
5708 rn
= "Performance3";
5711 // gen_helper_mtc0_performance4(arg);
5712 rn
= "Performance4";
5715 // gen_helper_mtc0_performance5(arg);
5716 rn
= "Performance5";
5719 // gen_helper_mtc0_performance6(arg);
5720 rn
= "Performance6";
5723 // gen_helper_mtc0_performance7(arg);
5724 rn
= "Performance7";
5750 gen_helper_mtc0_taglo(cpu_env
, arg
);
5757 gen_helper_mtc0_datalo(cpu_env
, arg
);
5770 gen_helper_mtc0_taghi(cpu_env
, arg
);
5777 gen_helper_mtc0_datahi(cpu_env
, arg
);
5788 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5799 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5803 if (ctx
->kscrexist
& (1 << sel
)) {
5804 tcg_gen_st_tl(arg
, cpu_env
,
5805 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
5812 /* Stop translation as we may have switched the execution mode */
5813 ctx
->bstate
= BS_STOP
;
5818 (void)rn
; /* avoid a compiler warning */
5819 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5820 /* For simplicity assume that all writes can cause interrupts. */
5823 ctx
->bstate
= BS_STOP
;
5828 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5829 generate_exception(ctx
, EXCP_RI
);
5832 #if defined(TARGET_MIPS64)
5833 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5835 const char *rn
= "invalid";
5838 check_insn(ctx
, ISA_MIPS64
);
5844 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5848 check_insn(ctx
, ASE_MT
);
5849 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5853 check_insn(ctx
, ASE_MT
);
5854 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5858 check_insn(ctx
, ASE_MT
);
5859 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5869 gen_helper_mfc0_random(arg
, cpu_env
);
5873 check_insn(ctx
, ASE_MT
);
5874 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5878 check_insn(ctx
, ASE_MT
);
5879 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5883 check_insn(ctx
, ASE_MT
);
5884 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5888 check_insn(ctx
, ASE_MT
);
5889 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5893 check_insn(ctx
, ASE_MT
);
5894 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5898 check_insn(ctx
, ASE_MT
);
5899 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5900 rn
= "VPEScheFBack";
5903 check_insn(ctx
, ASE_MT
);
5904 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5914 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5918 check_insn(ctx
, ASE_MT
);
5919 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5923 check_insn(ctx
, ASE_MT
);
5924 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5928 check_insn(ctx
, ASE_MT
);
5929 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5933 check_insn(ctx
, ASE_MT
);
5934 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5938 check_insn(ctx
, ASE_MT
);
5939 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5943 check_insn(ctx
, ASE_MT
);
5944 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5948 check_insn(ctx
, ASE_MT
);
5949 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5959 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5969 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5973 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5974 rn
= "ContextConfig";
5979 tcg_gen_ld_tl(arg
, cpu_env
,
5980 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5983 tcg_gen_movi_tl(arg
, 0);
5993 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5997 check_insn(ctx
, ISA_MIPS32R2
);
5998 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6008 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6012 check_insn(ctx
, ISA_MIPS32R2
);
6013 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6017 check_insn(ctx
, ISA_MIPS32R2
);
6018 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6022 check_insn(ctx
, ISA_MIPS32R2
);
6023 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6027 check_insn(ctx
, ISA_MIPS32R2
);
6028 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6032 check_insn(ctx
, ISA_MIPS32R2
);
6033 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6043 check_insn(ctx
, ISA_MIPS32R2
);
6044 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6054 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6064 /* Mark as an IO operation because we read the time. */
6067 gen_helper_mfc0_count(arg
, cpu_env
);
6071 /* Break the TB to be able to take timer interrupts immediately
6072 after reading count. */
6073 ctx
->bstate
= BS_STOP
;
6076 /* 6,7 are implementation dependent */
6084 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6094 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6097 /* 6,7 are implementation dependent */
6105 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6109 check_insn(ctx
, ISA_MIPS32R2
);
6110 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6114 check_insn(ctx
, ISA_MIPS32R2
);
6115 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6119 check_insn(ctx
, ISA_MIPS32R2
);
6120 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6130 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6140 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6150 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6154 check_insn(ctx
, ISA_MIPS32R2
);
6155 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
6165 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6169 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6173 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6177 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6180 /* 6,7 are implementation dependent */
6182 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6186 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6196 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
6206 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
6216 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6226 check_insn(ctx
, ISA_MIPS3
);
6227 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6235 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6238 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6246 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6247 rn
= "'Diagnostic"; /* implementation dependent */
6252 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6256 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6257 rn
= "TraceControl";
6260 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6261 rn
= "TraceControl2";
6264 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6265 rn
= "UserTraceData";
6268 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6279 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6289 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6290 rn
= "Performance0";
6293 // gen_helper_dmfc0_performance1(arg);
6294 rn
= "Performance1";
6297 // gen_helper_dmfc0_performance2(arg);
6298 rn
= "Performance2";
6301 // gen_helper_dmfc0_performance3(arg);
6302 rn
= "Performance3";
6305 // gen_helper_dmfc0_performance4(arg);
6306 rn
= "Performance4";
6309 // gen_helper_dmfc0_performance5(arg);
6310 rn
= "Performance5";
6313 // gen_helper_dmfc0_performance6(arg);
6314 rn
= "Performance6";
6317 // gen_helper_dmfc0_performance7(arg);
6318 rn
= "Performance7";
6325 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6332 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6345 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6352 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6365 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6372 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6382 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6393 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6397 if (ctx
->kscrexist
& (1 << sel
)) {
6398 tcg_gen_ld_tl(arg
, cpu_env
,
6399 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
6402 gen_mfc0_unimplemented(ctx
, arg
);
6412 (void)rn
; /* avoid a compiler warning */
6413 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6417 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6418 generate_exception(ctx
, EXCP_RI
);
6421 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6423 const char *rn
= "invalid";
6426 check_insn(ctx
, ISA_MIPS64
);
6435 gen_helper_mtc0_index(cpu_env
, arg
);
6439 check_insn(ctx
, ASE_MT
);
6440 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6444 check_insn(ctx
, ASE_MT
);
6449 check_insn(ctx
, ASE_MT
);
6464 check_insn(ctx
, ASE_MT
);
6465 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6469 check_insn(ctx
, ASE_MT
);
6470 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6474 check_insn(ctx
, ASE_MT
);
6475 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6479 check_insn(ctx
, ASE_MT
);
6480 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6484 check_insn(ctx
, ASE_MT
);
6485 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6489 check_insn(ctx
, ASE_MT
);
6490 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6491 rn
= "VPEScheFBack";
6494 check_insn(ctx
, ASE_MT
);
6495 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6505 gen_helper_dmtc0_entrylo0(cpu_env
, arg
);
6509 check_insn(ctx
, ASE_MT
);
6510 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6514 check_insn(ctx
, ASE_MT
);
6515 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6519 check_insn(ctx
, ASE_MT
);
6520 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
6524 check_insn(ctx
, ASE_MT
);
6525 gen_helper_mtc0_tchalt(cpu_env
, arg
);
6529 check_insn(ctx
, ASE_MT
);
6530 gen_helper_mtc0_tccontext(cpu_env
, arg
);
6534 check_insn(ctx
, ASE_MT
);
6535 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
6539 check_insn(ctx
, ASE_MT
);
6540 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6550 gen_helper_dmtc0_entrylo1(cpu_env
, arg
);
6560 gen_helper_mtc0_context(cpu_env
, arg
);
6564 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6565 rn
= "ContextConfig";
6570 tcg_gen_st_tl(arg
, cpu_env
,
6571 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6582 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6586 check_insn(ctx
, ISA_MIPS32R2
);
6587 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6597 gen_helper_mtc0_wired(cpu_env
, arg
);
6601 check_insn(ctx
, ISA_MIPS32R2
);
6602 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6606 check_insn(ctx
, ISA_MIPS32R2
);
6607 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6611 check_insn(ctx
, ISA_MIPS32R2
);
6612 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6616 check_insn(ctx
, ISA_MIPS32R2
);
6617 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6621 check_insn(ctx
, ISA_MIPS32R2
);
6622 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6632 check_insn(ctx
, ISA_MIPS32R2
);
6633 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6634 ctx
->bstate
= BS_STOP
;
6648 gen_helper_mtc0_count(cpu_env
, arg
);
6651 /* 6,7 are implementation dependent */
6655 /* Stop translation as we may have switched the execution mode */
6656 ctx
->bstate
= BS_STOP
;
6661 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6671 gen_helper_mtc0_compare(cpu_env
, arg
);
6674 /* 6,7 are implementation dependent */
6678 /* Stop translation as we may have switched the execution mode */
6679 ctx
->bstate
= BS_STOP
;
6684 save_cpu_state(ctx
, 1);
6685 gen_helper_mtc0_status(cpu_env
, arg
);
6686 /* BS_STOP isn't good enough here, hflags may have changed. */
6687 gen_save_pc(ctx
->pc
+ 4);
6688 ctx
->bstate
= BS_EXCP
;
6692 check_insn(ctx
, ISA_MIPS32R2
);
6693 gen_helper_mtc0_intctl(cpu_env
, arg
);
6694 /* Stop translation as we may have switched the execution mode */
6695 ctx
->bstate
= BS_STOP
;
6699 check_insn(ctx
, ISA_MIPS32R2
);
6700 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6701 /* Stop translation as we may have switched the execution mode */
6702 ctx
->bstate
= BS_STOP
;
6706 check_insn(ctx
, ISA_MIPS32R2
);
6707 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6708 /* Stop translation as we may have switched the execution mode */
6709 ctx
->bstate
= BS_STOP
;
6719 save_cpu_state(ctx
, 1);
6720 /* Mark as an IO operation because we may trigger a software
6725 gen_helper_mtc0_cause(cpu_env
, arg
);
6729 /* Stop translation as we may have triggered an intetrupt */
6730 ctx
->bstate
= BS_STOP
;
6740 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6754 check_insn(ctx
, ISA_MIPS32R2
);
6755 gen_helper_mtc0_ebase(cpu_env
, arg
);
6765 gen_helper_mtc0_config0(cpu_env
, arg
);
6767 /* Stop translation as we may have switched the execution mode */
6768 ctx
->bstate
= BS_STOP
;
6771 /* ignored, read only */
6775 gen_helper_mtc0_config2(cpu_env
, arg
);
6777 /* Stop translation as we may have switched the execution mode */
6778 ctx
->bstate
= BS_STOP
;
6784 /* 6,7 are implementation dependent */
6786 rn
= "Invalid config selector";
6793 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6803 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6813 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6823 check_insn(ctx
, ISA_MIPS3
);
6824 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6832 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6835 gen_helper_mtc0_framemask(cpu_env
, arg
);
6844 rn
= "Diagnostic"; /* implementation dependent */
6849 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6850 /* BS_STOP isn't good enough here, hflags may have changed. */
6851 gen_save_pc(ctx
->pc
+ 4);
6852 ctx
->bstate
= BS_EXCP
;
6856 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6857 /* Stop translation as we may have switched the execution mode */
6858 ctx
->bstate
= BS_STOP
;
6859 rn
= "TraceControl";
6862 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6863 /* Stop translation as we may have switched the execution mode */
6864 ctx
->bstate
= BS_STOP
;
6865 rn
= "TraceControl2";
6868 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6869 /* Stop translation as we may have switched the execution mode */
6870 ctx
->bstate
= BS_STOP
;
6871 rn
= "UserTraceData";
6874 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6875 /* Stop translation as we may have switched the execution mode */
6876 ctx
->bstate
= BS_STOP
;
6887 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6897 gen_helper_mtc0_performance0(cpu_env
, arg
);
6898 rn
= "Performance0";
6901 // gen_helper_mtc0_performance1(cpu_env, arg);
6902 rn
= "Performance1";
6905 // gen_helper_mtc0_performance2(cpu_env, arg);
6906 rn
= "Performance2";
6909 // gen_helper_mtc0_performance3(cpu_env, arg);
6910 rn
= "Performance3";
6913 // gen_helper_mtc0_performance4(cpu_env, arg);
6914 rn
= "Performance4";
6917 // gen_helper_mtc0_performance5(cpu_env, arg);
6918 rn
= "Performance5";
6921 // gen_helper_mtc0_performance6(cpu_env, arg);
6922 rn
= "Performance6";
6925 // gen_helper_mtc0_performance7(cpu_env, arg);
6926 rn
= "Performance7";
6952 gen_helper_mtc0_taglo(cpu_env
, arg
);
6959 gen_helper_mtc0_datalo(cpu_env
, arg
);
6972 gen_helper_mtc0_taghi(cpu_env
, arg
);
6979 gen_helper_mtc0_datahi(cpu_env
, arg
);
6990 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
7001 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
7005 if (ctx
->kscrexist
& (1 << sel
)) {
7006 tcg_gen_st_tl(arg
, cpu_env
,
7007 offsetof(CPUMIPSState
, CP0_KScratch
[sel
-2]));
7014 /* Stop translation as we may have switched the execution mode */
7015 ctx
->bstate
= BS_STOP
;
7020 (void)rn
; /* avoid a compiler warning */
7021 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7022 /* For simplicity assume that all writes can cause interrupts. */
7025 ctx
->bstate
= BS_STOP
;
7030 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7031 generate_exception(ctx
, EXCP_RI
);
7033 #endif /* TARGET_MIPS64 */
7035 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
7036 int u
, int sel
, int h
)
7038 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7039 TCGv t0
= tcg_temp_local_new();
7041 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7042 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7043 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7044 tcg_gen_movi_tl(t0
, -1);
7045 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7046 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7047 tcg_gen_movi_tl(t0
, -1);
7053 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
7056 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
7066 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
7069 gen_helper_mftc0_tcbind(t0
, cpu_env
);
7072 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
7075 gen_helper_mftc0_tchalt(t0
, cpu_env
);
7078 gen_helper_mftc0_tccontext(t0
, cpu_env
);
7081 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
7084 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
7087 gen_mfc0(ctx
, t0
, rt
, sel
);
7094 gen_helper_mftc0_entryhi(t0
, cpu_env
);
7097 gen_mfc0(ctx
, t0
, rt
, sel
);
7103 gen_helper_mftc0_status(t0
, cpu_env
);
7106 gen_mfc0(ctx
, t0
, rt
, sel
);
7112 gen_helper_mftc0_cause(t0
, cpu_env
);
7122 gen_helper_mftc0_epc(t0
, cpu_env
);
7132 gen_helper_mftc0_ebase(t0
, cpu_env
);
7142 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
7152 gen_helper_mftc0_debug(t0
, cpu_env
);
7155 gen_mfc0(ctx
, t0
, rt
, sel
);
7160 gen_mfc0(ctx
, t0
, rt
, sel
);
7162 } else switch (sel
) {
7163 /* GPR registers. */
7165 gen_helper_1e0i(mftgpr
, t0
, rt
);
7167 /* Auxiliary CPU registers */
7171 gen_helper_1e0i(mftlo
, t0
, 0);
7174 gen_helper_1e0i(mfthi
, t0
, 0);
7177 gen_helper_1e0i(mftacx
, t0
, 0);
7180 gen_helper_1e0i(mftlo
, t0
, 1);
7183 gen_helper_1e0i(mfthi
, t0
, 1);
7186 gen_helper_1e0i(mftacx
, t0
, 1);
7189 gen_helper_1e0i(mftlo
, t0
, 2);
7192 gen_helper_1e0i(mfthi
, t0
, 2);
7195 gen_helper_1e0i(mftacx
, t0
, 2);
7198 gen_helper_1e0i(mftlo
, t0
, 3);
7201 gen_helper_1e0i(mfthi
, t0
, 3);
7204 gen_helper_1e0i(mftacx
, t0
, 3);
7207 gen_helper_mftdsp(t0
, cpu_env
);
7213 /* Floating point (COP1). */
7215 /* XXX: For now we support only a single FPU context. */
7217 TCGv_i32 fp0
= tcg_temp_new_i32();
7219 gen_load_fpr32(fp0
, rt
);
7220 tcg_gen_ext_i32_tl(t0
, fp0
);
7221 tcg_temp_free_i32(fp0
);
7223 TCGv_i32 fp0
= tcg_temp_new_i32();
7225 gen_load_fpr32h(ctx
, fp0
, rt
);
7226 tcg_gen_ext_i32_tl(t0
, fp0
);
7227 tcg_temp_free_i32(fp0
);
7231 /* XXX: For now we support only a single FPU context. */
7232 gen_helper_1e0i(cfc1
, t0
, rt
);
7234 /* COP2: Not implemented. */
7241 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7242 gen_store_gpr(t0
, rd
);
7248 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7249 generate_exception(ctx
, EXCP_RI
);
7252 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
7253 int u
, int sel
, int h
)
7255 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7256 TCGv t0
= tcg_temp_local_new();
7258 gen_load_gpr(t0
, rt
);
7259 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7260 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7261 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7263 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7264 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7271 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
7274 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
7284 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
7287 gen_helper_mttc0_tcbind(cpu_env
, t0
);
7290 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
7293 gen_helper_mttc0_tchalt(cpu_env
, t0
);
7296 gen_helper_mttc0_tccontext(cpu_env
, t0
);
7299 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
7302 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
7305 gen_mtc0(ctx
, t0
, rd
, sel
);
7312 gen_helper_mttc0_entryhi(cpu_env
, t0
);
7315 gen_mtc0(ctx
, t0
, rd
, sel
);
7321 gen_helper_mttc0_status(cpu_env
, t0
);
7324 gen_mtc0(ctx
, t0
, rd
, sel
);
7330 gen_helper_mttc0_cause(cpu_env
, t0
);
7340 gen_helper_mttc0_ebase(cpu_env
, t0
);
7350 gen_helper_mttc0_debug(cpu_env
, t0
);
7353 gen_mtc0(ctx
, t0
, rd
, sel
);
7358 gen_mtc0(ctx
, t0
, rd
, sel
);
7360 } else switch (sel
) {
7361 /* GPR registers. */
7363 gen_helper_0e1i(mttgpr
, t0
, rd
);
7365 /* Auxiliary CPU registers */
7369 gen_helper_0e1i(mttlo
, t0
, 0);
7372 gen_helper_0e1i(mtthi
, t0
, 0);
7375 gen_helper_0e1i(mttacx
, t0
, 0);
7378 gen_helper_0e1i(mttlo
, t0
, 1);
7381 gen_helper_0e1i(mtthi
, t0
, 1);
7384 gen_helper_0e1i(mttacx
, t0
, 1);
7387 gen_helper_0e1i(mttlo
, t0
, 2);
7390 gen_helper_0e1i(mtthi
, t0
, 2);
7393 gen_helper_0e1i(mttacx
, t0
, 2);
7396 gen_helper_0e1i(mttlo
, t0
, 3);
7399 gen_helper_0e1i(mtthi
, t0
, 3);
7402 gen_helper_0e1i(mttacx
, t0
, 3);
7405 gen_helper_mttdsp(cpu_env
, t0
);
7411 /* Floating point (COP1). */
7413 /* XXX: For now we support only a single FPU context. */
7415 TCGv_i32 fp0
= tcg_temp_new_i32();
7417 tcg_gen_trunc_tl_i32(fp0
, t0
);
7418 gen_store_fpr32(fp0
, rd
);
7419 tcg_temp_free_i32(fp0
);
7421 TCGv_i32 fp0
= tcg_temp_new_i32();
7423 tcg_gen_trunc_tl_i32(fp0
, t0
);
7424 gen_store_fpr32h(ctx
, fp0
, rd
);
7425 tcg_temp_free_i32(fp0
);
7429 /* XXX: For now we support only a single FPU context. */
7431 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
7433 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7434 tcg_temp_free_i32(fs_tmp
);
7437 /* COP2: Not implemented. */
7444 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
7450 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
7451 generate_exception(ctx
, EXCP_RI
);
7454 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
7456 const char *opn
= "ldst";
7458 check_cp0_enabled(ctx
);
7465 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
7470 TCGv t0
= tcg_temp_new();
7472 gen_load_gpr(t0
, rt
);
7473 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
7478 #if defined(TARGET_MIPS64)
7480 check_insn(ctx
, ISA_MIPS3
);
7485 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
7489 check_insn(ctx
, ISA_MIPS3
);
7491 TCGv t0
= tcg_temp_new();
7493 gen_load_gpr(t0
, rt
);
7494 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
7501 check_insn(ctx
, ASE_MT
);
7506 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
7507 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
7511 check_insn(ctx
, ASE_MT
);
7512 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
7513 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
7518 if (!env
->tlb
->helper_tlbwi
)
7520 gen_helper_tlbwi(cpu_env
);
7525 if (!env
->tlb
->helper_tlbinv
) {
7528 gen_helper_tlbinv(cpu_env
);
7529 } /* treat as nop if TLBINV not supported */
7534 if (!env
->tlb
->helper_tlbinvf
) {
7537 gen_helper_tlbinvf(cpu_env
);
7538 } /* treat as nop if TLBINV not supported */
7542 if (!env
->tlb
->helper_tlbwr
)
7544 gen_helper_tlbwr(cpu_env
);
7548 if (!env
->tlb
->helper_tlbp
)
7550 gen_helper_tlbp(cpu_env
);
7554 if (!env
->tlb
->helper_tlbr
)
7556 gen_helper_tlbr(cpu_env
);
7560 check_insn(ctx
, ISA_MIPS2
);
7561 gen_helper_eret(cpu_env
);
7562 ctx
->bstate
= BS_EXCP
;
7566 check_insn(ctx
, ISA_MIPS32
);
7567 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
7569 generate_exception(ctx
, EXCP_RI
);
7571 gen_helper_deret(cpu_env
);
7572 ctx
->bstate
= BS_EXCP
;
7577 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
7578 /* If we get an exception, we want to restart at next instruction */
7580 save_cpu_state(ctx
, 1);
7582 gen_helper_wait(cpu_env
);
7583 ctx
->bstate
= BS_EXCP
;
7588 generate_exception(ctx
, EXCP_RI
);
7591 (void)opn
; /* avoid a compiler warning */
7592 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
7594 #endif /* !CONFIG_USER_ONLY */
7596 /* CP1 Branches (before delay slot) */
7597 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
7598 int32_t cc
, int32_t offset
)
7600 target_ulong btarget
;
7601 const char *opn
= "cp1 cond branch";
7602 TCGv_i32 t0
= tcg_temp_new_i32();
7605 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
7607 btarget
= ctx
->pc
+ 4 + offset
;
7611 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7612 tcg_gen_not_i32(t0
, t0
);
7613 tcg_gen_andi_i32(t0
, t0
, 1);
7614 tcg_gen_extu_i32_tl(bcond
, t0
);
7618 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7619 tcg_gen_not_i32(t0
, t0
);
7620 tcg_gen_andi_i32(t0
, t0
, 1);
7621 tcg_gen_extu_i32_tl(bcond
, t0
);
7625 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7626 tcg_gen_andi_i32(t0
, t0
, 1);
7627 tcg_gen_extu_i32_tl(bcond
, t0
);
7631 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7632 tcg_gen_andi_i32(t0
, t0
, 1);
7633 tcg_gen_extu_i32_tl(bcond
, t0
);
7636 ctx
->hflags
|= MIPS_HFLAG_BL
;
7640 TCGv_i32 t1
= tcg_temp_new_i32();
7641 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7642 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7643 tcg_gen_nand_i32(t0
, t0
, t1
);
7644 tcg_temp_free_i32(t1
);
7645 tcg_gen_andi_i32(t0
, t0
, 1);
7646 tcg_gen_extu_i32_tl(bcond
, t0
);
7652 TCGv_i32 t1
= tcg_temp_new_i32();
7653 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7654 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7655 tcg_gen_or_i32(t0
, t0
, t1
);
7656 tcg_temp_free_i32(t1
);
7657 tcg_gen_andi_i32(t0
, t0
, 1);
7658 tcg_gen_extu_i32_tl(bcond
, t0
);
7664 TCGv_i32 t1
= tcg_temp_new_i32();
7665 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7666 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7667 tcg_gen_and_i32(t0
, t0
, t1
);
7668 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7669 tcg_gen_and_i32(t0
, t0
, t1
);
7670 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7671 tcg_gen_nand_i32(t0
, t0
, t1
);
7672 tcg_temp_free_i32(t1
);
7673 tcg_gen_andi_i32(t0
, t0
, 1);
7674 tcg_gen_extu_i32_tl(bcond
, t0
);
7680 TCGv_i32 t1
= tcg_temp_new_i32();
7681 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7682 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7683 tcg_gen_or_i32(t0
, t0
, t1
);
7684 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7685 tcg_gen_or_i32(t0
, t0
, t1
);
7686 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7687 tcg_gen_or_i32(t0
, t0
, t1
);
7688 tcg_temp_free_i32(t1
);
7689 tcg_gen_andi_i32(t0
, t0
, 1);
7690 tcg_gen_extu_i32_tl(bcond
, t0
);
7694 ctx
->hflags
|= MIPS_HFLAG_BC
;
7698 generate_exception (ctx
, EXCP_RI
);
7701 (void)opn
; /* avoid a compiler warning */
7702 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7703 ctx
->hflags
, btarget
);
7704 ctx
->btarget
= btarget
;
7705 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
7707 tcg_temp_free_i32(t0
);
7710 /* R6 CP1 Branches */
7711 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
7712 int32_t ft
, int32_t offset
)
7714 target_ulong btarget
;
7715 const char *opn
= "cp1 cond branch";
7716 TCGv_i64 t0
= tcg_temp_new_i64();
7718 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
7719 #ifdef MIPS_DEBUG_DISAS
7720 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
7722 generate_exception(ctx
, EXCP_RI
);
7726 gen_load_fpr64(ctx
, t0
, ft
);
7727 tcg_gen_andi_i64(t0
, t0
, 1);
7729 btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
7733 tcg_gen_xori_i64(t0
, t0
, 1);
7735 ctx
->hflags
|= MIPS_HFLAG_BC
;
7738 /* t0 already set */
7740 ctx
->hflags
|= MIPS_HFLAG_BC
;
7744 generate_exception(ctx
, EXCP_RI
);
7748 tcg_gen_trunc_i64_tl(bcond
, t0
);
7750 (void)opn
; /* avoid a compiler warning */
7751 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7752 ctx
->hflags
, btarget
);
7753 ctx
->btarget
= btarget
;
7756 tcg_temp_free_i64(t0
);
7759 /* Coprocessor 1 (FPU) */
7761 #define FOP(func, fmt) (((fmt) << 21) | (func))
7764 OPC_ADD_S
= FOP(0, FMT_S
),
7765 OPC_SUB_S
= FOP(1, FMT_S
),
7766 OPC_MUL_S
= FOP(2, FMT_S
),
7767 OPC_DIV_S
= FOP(3, FMT_S
),
7768 OPC_SQRT_S
= FOP(4, FMT_S
),
7769 OPC_ABS_S
= FOP(5, FMT_S
),
7770 OPC_MOV_S
= FOP(6, FMT_S
),
7771 OPC_NEG_S
= FOP(7, FMT_S
),
7772 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7773 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7774 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7775 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7776 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7777 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7778 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7779 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7780 OPC_SEL_S
= FOP(16, FMT_S
),
7781 OPC_MOVCF_S
= FOP(17, FMT_S
),
7782 OPC_MOVZ_S
= FOP(18, FMT_S
),
7783 OPC_MOVN_S
= FOP(19, FMT_S
),
7784 OPC_SELEQZ_S
= FOP(20, FMT_S
),
7785 OPC_RECIP_S
= FOP(21, FMT_S
),
7786 OPC_RSQRT_S
= FOP(22, FMT_S
),
7787 OPC_SELNEZ_S
= FOP(23, FMT_S
),
7788 OPC_MADDF_S
= FOP(24, FMT_S
),
7789 OPC_MSUBF_S
= FOP(25, FMT_S
),
7790 OPC_RINT_S
= FOP(26, FMT_S
),
7791 OPC_CLASS_S
= FOP(27, FMT_S
),
7792 OPC_MIN_S
= FOP(28, FMT_S
),
7793 OPC_RECIP2_S
= FOP(28, FMT_S
),
7794 OPC_MINA_S
= FOP(29, FMT_S
),
7795 OPC_RECIP1_S
= FOP(29, FMT_S
),
7796 OPC_MAX_S
= FOP(30, FMT_S
),
7797 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7798 OPC_MAXA_S
= FOP(31, FMT_S
),
7799 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7800 OPC_CVT_D_S
= FOP(33, FMT_S
),
7801 OPC_CVT_W_S
= FOP(36, FMT_S
),
7802 OPC_CVT_L_S
= FOP(37, FMT_S
),
7803 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7804 OPC_CMP_F_S
= FOP (48, FMT_S
),
7805 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7806 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7807 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7808 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7809 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7810 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7811 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7812 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7813 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7814 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7815 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7816 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7817 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7818 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7819 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7821 OPC_ADD_D
= FOP(0, FMT_D
),
7822 OPC_SUB_D
= FOP(1, FMT_D
),
7823 OPC_MUL_D
= FOP(2, FMT_D
),
7824 OPC_DIV_D
= FOP(3, FMT_D
),
7825 OPC_SQRT_D
= FOP(4, FMT_D
),
7826 OPC_ABS_D
= FOP(5, FMT_D
),
7827 OPC_MOV_D
= FOP(6, FMT_D
),
7828 OPC_NEG_D
= FOP(7, FMT_D
),
7829 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7830 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7831 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7832 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7833 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7834 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7835 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7836 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7837 OPC_SEL_D
= FOP(16, FMT_D
),
7838 OPC_MOVCF_D
= FOP(17, FMT_D
),
7839 OPC_MOVZ_D
= FOP(18, FMT_D
),
7840 OPC_MOVN_D
= FOP(19, FMT_D
),
7841 OPC_SELEQZ_D
= FOP(20, FMT_D
),
7842 OPC_RECIP_D
= FOP(21, FMT_D
),
7843 OPC_RSQRT_D
= FOP(22, FMT_D
),
7844 OPC_SELNEZ_D
= FOP(23, FMT_D
),
7845 OPC_MADDF_D
= FOP(24, FMT_D
),
7846 OPC_MSUBF_D
= FOP(25, FMT_D
),
7847 OPC_RINT_D
= FOP(26, FMT_D
),
7848 OPC_CLASS_D
= FOP(27, FMT_D
),
7849 OPC_MIN_D
= FOP(28, FMT_D
),
7850 OPC_RECIP2_D
= FOP(28, FMT_D
),
7851 OPC_MINA_D
= FOP(29, FMT_D
),
7852 OPC_RECIP1_D
= FOP(29, FMT_D
),
7853 OPC_MAX_D
= FOP(30, FMT_D
),
7854 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7855 OPC_MAXA_D
= FOP(31, FMT_D
),
7856 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7857 OPC_CVT_S_D
= FOP(32, FMT_D
),
7858 OPC_CVT_W_D
= FOP(36, FMT_D
),
7859 OPC_CVT_L_D
= FOP(37, FMT_D
),
7860 OPC_CMP_F_D
= FOP (48, FMT_D
),
7861 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7862 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7863 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7864 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7865 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7866 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7867 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7868 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7869 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7870 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7871 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7872 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7873 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7874 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7875 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7877 OPC_CVT_S_W
= FOP(32, FMT_W
),
7878 OPC_CVT_D_W
= FOP(33, FMT_W
),
7879 OPC_CVT_S_L
= FOP(32, FMT_L
),
7880 OPC_CVT_D_L
= FOP(33, FMT_L
),
7881 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7883 OPC_ADD_PS
= FOP(0, FMT_PS
),
7884 OPC_SUB_PS
= FOP(1, FMT_PS
),
7885 OPC_MUL_PS
= FOP(2, FMT_PS
),
7886 OPC_DIV_PS
= FOP(3, FMT_PS
),
7887 OPC_ABS_PS
= FOP(5, FMT_PS
),
7888 OPC_MOV_PS
= FOP(6, FMT_PS
),
7889 OPC_NEG_PS
= FOP(7, FMT_PS
),
7890 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7891 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7892 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7893 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7894 OPC_MULR_PS
= FOP(26, FMT_PS
),
7895 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7896 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7897 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7898 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7900 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7901 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7902 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7903 OPC_PLL_PS
= FOP(44, FMT_PS
),
7904 OPC_PLU_PS
= FOP(45, FMT_PS
),
7905 OPC_PUL_PS
= FOP(46, FMT_PS
),
7906 OPC_PUU_PS
= FOP(47, FMT_PS
),
7907 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7908 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7909 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7910 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7911 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7912 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7913 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7914 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7915 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7916 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7917 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7918 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7919 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7920 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7921 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7922 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7926 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
7927 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
7928 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
7929 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
7930 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
7931 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
7932 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
7933 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
7934 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
7935 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
7936 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
7937 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
7938 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
7939 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
7940 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
7941 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
7942 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
7943 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
7944 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
7945 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
7946 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
7947 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
7949 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
7950 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
7951 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
7952 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
7953 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
7954 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
7955 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
7956 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
7957 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
7958 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
7959 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
7960 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
7961 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
7962 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
7963 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
7964 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
7965 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
7966 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
7967 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
7968 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
7969 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
7970 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
7972 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7974 const char *opn
= "cp1 move";
7975 TCGv t0
= tcg_temp_new();
7980 TCGv_i32 fp0
= tcg_temp_new_i32();
7982 gen_load_fpr32(fp0
, fs
);
7983 tcg_gen_ext_i32_tl(t0
, fp0
);
7984 tcg_temp_free_i32(fp0
);
7986 gen_store_gpr(t0
, rt
);
7990 gen_load_gpr(t0
, rt
);
7992 TCGv_i32 fp0
= tcg_temp_new_i32();
7994 tcg_gen_trunc_tl_i32(fp0
, t0
);
7995 gen_store_fpr32(fp0
, fs
);
7996 tcg_temp_free_i32(fp0
);
8001 gen_helper_1e0i(cfc1
, t0
, fs
);
8002 gen_store_gpr(t0
, rt
);
8006 gen_load_gpr(t0
, rt
);
8008 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
8010 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
8011 tcg_temp_free_i32(fs_tmp
);
8015 #if defined(TARGET_MIPS64)
8017 gen_load_fpr64(ctx
, t0
, fs
);
8018 gen_store_gpr(t0
, rt
);
8022 gen_load_gpr(t0
, rt
);
8023 gen_store_fpr64(ctx
, t0
, fs
);
8029 TCGv_i32 fp0
= tcg_temp_new_i32();
8031 gen_load_fpr32h(ctx
, fp0
, fs
);
8032 tcg_gen_ext_i32_tl(t0
, fp0
);
8033 tcg_temp_free_i32(fp0
);
8035 gen_store_gpr(t0
, rt
);
8039 gen_load_gpr(t0
, rt
);
8041 TCGv_i32 fp0
= tcg_temp_new_i32();
8043 tcg_gen_trunc_tl_i32(fp0
, t0
);
8044 gen_store_fpr32h(ctx
, fp0
, fs
);
8045 tcg_temp_free_i32(fp0
);
8051 generate_exception (ctx
, EXCP_RI
);
8054 (void)opn
; /* avoid a compiler warning */
8055 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
8061 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
8077 l1
= gen_new_label();
8078 t0
= tcg_temp_new_i32();
8079 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8080 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8081 tcg_temp_free_i32(t0
);
8083 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
8085 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
8090 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
8093 TCGv_i32 t0
= tcg_temp_new_i32();
8094 int l1
= gen_new_label();
8101 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8102 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8103 gen_load_fpr32(t0
, fs
);
8104 gen_store_fpr32(t0
, fd
);
8106 tcg_temp_free_i32(t0
);
8109 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
8112 TCGv_i32 t0
= tcg_temp_new_i32();
8114 int l1
= gen_new_label();
8121 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8122 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8123 tcg_temp_free_i32(t0
);
8124 fp0
= tcg_temp_new_i64();
8125 gen_load_fpr64(ctx
, fp0
, fs
);
8126 gen_store_fpr64(ctx
, fp0
, fd
);
8127 tcg_temp_free_i64(fp0
);
8131 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
8135 TCGv_i32 t0
= tcg_temp_new_i32();
8136 int l1
= gen_new_label();
8137 int l2
= gen_new_label();
8144 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8145 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8146 gen_load_fpr32(t0
, fs
);
8147 gen_store_fpr32(t0
, fd
);
8150 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
8151 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
8152 gen_load_fpr32h(ctx
, t0
, fs
);
8153 gen_store_fpr32h(ctx
, t0
, fd
);
8154 tcg_temp_free_i32(t0
);
8158 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8161 TCGv_i32 t1
= tcg_const_i32(0);
8162 TCGv_i32 fp0
= tcg_temp_new_i32();
8163 TCGv_i32 fp1
= tcg_temp_new_i32();
8164 TCGv_i32 fp2
= tcg_temp_new_i32();
8165 gen_load_fpr32(fp0
, fd
);
8166 gen_load_fpr32(fp1
, ft
);
8167 gen_load_fpr32(fp2
, fs
);
8171 tcg_gen_andi_i32(fp0
, fp0
, 1);
8172 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8175 tcg_gen_andi_i32(fp1
, fp1
, 1);
8176 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8179 tcg_gen_andi_i32(fp1
, fp1
, 1);
8180 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8183 MIPS_INVAL("gen_sel_s");
8184 generate_exception (ctx
, EXCP_RI
);
8188 gen_store_fpr32(fp0
, fd
);
8189 tcg_temp_free_i32(fp2
);
8190 tcg_temp_free_i32(fp1
);
8191 tcg_temp_free_i32(fp0
);
8192 tcg_temp_free_i32(t1
);
8195 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8198 TCGv_i64 t1
= tcg_const_i64(0);
8199 TCGv_i64 fp0
= tcg_temp_new_i64();
8200 TCGv_i64 fp1
= tcg_temp_new_i64();
8201 TCGv_i64 fp2
= tcg_temp_new_i64();
8202 gen_load_fpr64(ctx
, fp0
, fd
);
8203 gen_load_fpr64(ctx
, fp1
, ft
);
8204 gen_load_fpr64(ctx
, fp2
, fs
);
8208 tcg_gen_andi_i64(fp0
, fp0
, 1);
8209 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8212 tcg_gen_andi_i64(fp1
, fp1
, 1);
8213 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8216 tcg_gen_andi_i64(fp1
, fp1
, 1);
8217 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8220 MIPS_INVAL("gen_sel_d");
8221 generate_exception (ctx
, EXCP_RI
);
8225 gen_store_fpr64(ctx
, fp0
, fd
);
8226 tcg_temp_free_i64(fp2
);
8227 tcg_temp_free_i64(fp1
);
8228 tcg_temp_free_i64(fp0
);
8229 tcg_temp_free_i64(t1
);
8232 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
8233 int ft
, int fs
, int fd
, int cc
)
8235 const char *opn
= "farith";
8236 const char *condnames
[] = {
8254 const char *condnames_abs
[] = {
8272 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
8273 uint32_t func
= ctx
->opcode
& 0x3f;
8278 TCGv_i32 fp0
= tcg_temp_new_i32();
8279 TCGv_i32 fp1
= tcg_temp_new_i32();
8281 gen_load_fpr32(fp0
, fs
);
8282 gen_load_fpr32(fp1
, ft
);
8283 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
8284 tcg_temp_free_i32(fp1
);
8285 gen_store_fpr32(fp0
, fd
);
8286 tcg_temp_free_i32(fp0
);
8293 TCGv_i32 fp0
= tcg_temp_new_i32();
8294 TCGv_i32 fp1
= tcg_temp_new_i32();
8296 gen_load_fpr32(fp0
, fs
);
8297 gen_load_fpr32(fp1
, ft
);
8298 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
8299 tcg_temp_free_i32(fp1
);
8300 gen_store_fpr32(fp0
, fd
);
8301 tcg_temp_free_i32(fp0
);
8308 TCGv_i32 fp0
= tcg_temp_new_i32();
8309 TCGv_i32 fp1
= tcg_temp_new_i32();
8311 gen_load_fpr32(fp0
, fs
);
8312 gen_load_fpr32(fp1
, ft
);
8313 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
8314 tcg_temp_free_i32(fp1
);
8315 gen_store_fpr32(fp0
, fd
);
8316 tcg_temp_free_i32(fp0
);
8323 TCGv_i32 fp0
= tcg_temp_new_i32();
8324 TCGv_i32 fp1
= tcg_temp_new_i32();
8326 gen_load_fpr32(fp0
, fs
);
8327 gen_load_fpr32(fp1
, ft
);
8328 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
8329 tcg_temp_free_i32(fp1
);
8330 gen_store_fpr32(fp0
, fd
);
8331 tcg_temp_free_i32(fp0
);
8338 TCGv_i32 fp0
= tcg_temp_new_i32();
8340 gen_load_fpr32(fp0
, fs
);
8341 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
8342 gen_store_fpr32(fp0
, fd
);
8343 tcg_temp_free_i32(fp0
);
8349 TCGv_i32 fp0
= tcg_temp_new_i32();
8351 gen_load_fpr32(fp0
, fs
);
8352 gen_helper_float_abs_s(fp0
, fp0
);
8353 gen_store_fpr32(fp0
, fd
);
8354 tcg_temp_free_i32(fp0
);
8360 TCGv_i32 fp0
= tcg_temp_new_i32();
8362 gen_load_fpr32(fp0
, fs
);
8363 gen_store_fpr32(fp0
, fd
);
8364 tcg_temp_free_i32(fp0
);
8370 TCGv_i32 fp0
= tcg_temp_new_i32();
8372 gen_load_fpr32(fp0
, fs
);
8373 gen_helper_float_chs_s(fp0
, fp0
);
8374 gen_store_fpr32(fp0
, fd
);
8375 tcg_temp_free_i32(fp0
);
8380 check_cp1_64bitmode(ctx
);
8382 TCGv_i32 fp32
= tcg_temp_new_i32();
8383 TCGv_i64 fp64
= tcg_temp_new_i64();
8385 gen_load_fpr32(fp32
, fs
);
8386 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
8387 tcg_temp_free_i32(fp32
);
8388 gen_store_fpr64(ctx
, fp64
, fd
);
8389 tcg_temp_free_i64(fp64
);
8394 check_cp1_64bitmode(ctx
);
8396 TCGv_i32 fp32
= tcg_temp_new_i32();
8397 TCGv_i64 fp64
= tcg_temp_new_i64();
8399 gen_load_fpr32(fp32
, fs
);
8400 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
8401 tcg_temp_free_i32(fp32
);
8402 gen_store_fpr64(ctx
, fp64
, fd
);
8403 tcg_temp_free_i64(fp64
);
8408 check_cp1_64bitmode(ctx
);
8410 TCGv_i32 fp32
= tcg_temp_new_i32();
8411 TCGv_i64 fp64
= tcg_temp_new_i64();
8413 gen_load_fpr32(fp32
, fs
);
8414 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
8415 tcg_temp_free_i32(fp32
);
8416 gen_store_fpr64(ctx
, fp64
, fd
);
8417 tcg_temp_free_i64(fp64
);
8422 check_cp1_64bitmode(ctx
);
8424 TCGv_i32 fp32
= tcg_temp_new_i32();
8425 TCGv_i64 fp64
= tcg_temp_new_i64();
8427 gen_load_fpr32(fp32
, fs
);
8428 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
8429 tcg_temp_free_i32(fp32
);
8430 gen_store_fpr64(ctx
, fp64
, fd
);
8431 tcg_temp_free_i64(fp64
);
8437 TCGv_i32 fp0
= tcg_temp_new_i32();
8439 gen_load_fpr32(fp0
, fs
);
8440 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
8441 gen_store_fpr32(fp0
, fd
);
8442 tcg_temp_free_i32(fp0
);
8448 TCGv_i32 fp0
= tcg_temp_new_i32();
8450 gen_load_fpr32(fp0
, fs
);
8451 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
8452 gen_store_fpr32(fp0
, fd
);
8453 tcg_temp_free_i32(fp0
);
8459 TCGv_i32 fp0
= tcg_temp_new_i32();
8461 gen_load_fpr32(fp0
, fs
);
8462 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
8463 gen_store_fpr32(fp0
, fd
);
8464 tcg_temp_free_i32(fp0
);
8470 TCGv_i32 fp0
= tcg_temp_new_i32();
8472 gen_load_fpr32(fp0
, fs
);
8473 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
8474 gen_store_fpr32(fp0
, fd
);
8475 tcg_temp_free_i32(fp0
);
8480 check_insn(ctx
, ISA_MIPS32R6
);
8481 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8485 check_insn(ctx
, ISA_MIPS32R6
);
8486 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8490 check_insn(ctx
, ISA_MIPS32R6
);
8491 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8495 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8496 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8500 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8502 int l1
= gen_new_label();
8506 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8508 fp0
= tcg_temp_new_i32();
8509 gen_load_fpr32(fp0
, fs
);
8510 gen_store_fpr32(fp0
, fd
);
8511 tcg_temp_free_i32(fp0
);
8517 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8519 int l1
= gen_new_label();
8523 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8524 fp0
= tcg_temp_new_i32();
8525 gen_load_fpr32(fp0
, fs
);
8526 gen_store_fpr32(fp0
, fd
);
8527 tcg_temp_free_i32(fp0
);
8536 TCGv_i32 fp0
= tcg_temp_new_i32();
8538 gen_load_fpr32(fp0
, fs
);
8539 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
8540 gen_store_fpr32(fp0
, fd
);
8541 tcg_temp_free_i32(fp0
);
8548 TCGv_i32 fp0
= tcg_temp_new_i32();
8550 gen_load_fpr32(fp0
, fs
);
8551 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
8552 gen_store_fpr32(fp0
, fd
);
8553 tcg_temp_free_i32(fp0
);
8558 check_insn(ctx
, ISA_MIPS32R6
);
8560 TCGv_i32 fp0
= tcg_temp_new_i32();
8561 TCGv_i32 fp1
= tcg_temp_new_i32();
8562 TCGv_i32 fp2
= tcg_temp_new_i32();
8563 gen_load_fpr32(fp0
, fs
);
8564 gen_load_fpr32(fp1
, ft
);
8565 gen_load_fpr32(fp2
, fd
);
8566 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8567 gen_store_fpr32(fp2
, fd
);
8568 tcg_temp_free_i32(fp2
);
8569 tcg_temp_free_i32(fp1
);
8570 tcg_temp_free_i32(fp0
);
8575 check_insn(ctx
, ISA_MIPS32R6
);
8577 TCGv_i32 fp0
= tcg_temp_new_i32();
8578 TCGv_i32 fp1
= tcg_temp_new_i32();
8579 TCGv_i32 fp2
= tcg_temp_new_i32();
8580 gen_load_fpr32(fp0
, fs
);
8581 gen_load_fpr32(fp1
, ft
);
8582 gen_load_fpr32(fp2
, fd
);
8583 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8584 gen_store_fpr32(fp2
, fd
);
8585 tcg_temp_free_i32(fp2
);
8586 tcg_temp_free_i32(fp1
);
8587 tcg_temp_free_i32(fp0
);
8592 check_insn(ctx
, ISA_MIPS32R6
);
8594 TCGv_i32 fp0
= tcg_temp_new_i32();
8595 gen_load_fpr32(fp0
, fs
);
8596 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
8597 gen_store_fpr32(fp0
, fd
);
8598 tcg_temp_free_i32(fp0
);
8603 check_insn(ctx
, ISA_MIPS32R6
);
8605 TCGv_i32 fp0
= tcg_temp_new_i32();
8606 gen_load_fpr32(fp0
, fs
);
8607 gen_helper_float_class_s(fp0
, fp0
);
8608 gen_store_fpr32(fp0
, fd
);
8609 tcg_temp_free_i32(fp0
);
8613 case OPC_MIN_S
: /* OPC_RECIP2_S */
8614 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8616 TCGv_i32 fp0
= tcg_temp_new_i32();
8617 TCGv_i32 fp1
= tcg_temp_new_i32();
8618 TCGv_i32 fp2
= tcg_temp_new_i32();
8619 gen_load_fpr32(fp0
, fs
);
8620 gen_load_fpr32(fp1
, ft
);
8621 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
8622 gen_store_fpr32(fp2
, fd
);
8623 tcg_temp_free_i32(fp2
);
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_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
8637 tcg_temp_free_i32(fp1
);
8638 gen_store_fpr32(fp0
, fd
);
8639 tcg_temp_free_i32(fp0
);
8644 case OPC_MINA_S
: /* OPC_RECIP1_S */
8645 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8647 TCGv_i32 fp0
= tcg_temp_new_i32();
8648 TCGv_i32 fp1
= tcg_temp_new_i32();
8649 TCGv_i32 fp2
= tcg_temp_new_i32();
8650 gen_load_fpr32(fp0
, fs
);
8651 gen_load_fpr32(fp1
, ft
);
8652 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
8653 gen_store_fpr32(fp2
, fd
);
8654 tcg_temp_free_i32(fp2
);
8655 tcg_temp_free_i32(fp1
);
8656 tcg_temp_free_i32(fp0
);
8660 check_cp1_64bitmode(ctx
);
8662 TCGv_i32 fp0
= tcg_temp_new_i32();
8664 gen_load_fpr32(fp0
, fs
);
8665 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
8666 gen_store_fpr32(fp0
, fd
);
8667 tcg_temp_free_i32(fp0
);
8672 case OPC_MAX_S
: /* OPC_RSQRT1_S */
8673 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8675 TCGv_i32 fp0
= tcg_temp_new_i32();
8676 TCGv_i32 fp1
= tcg_temp_new_i32();
8677 gen_load_fpr32(fp0
, fs
);
8678 gen_load_fpr32(fp1
, ft
);
8679 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
8680 gen_store_fpr32(fp1
, fd
);
8681 tcg_temp_free_i32(fp1
);
8682 tcg_temp_free_i32(fp0
);
8686 check_cp1_64bitmode(ctx
);
8688 TCGv_i32 fp0
= tcg_temp_new_i32();
8690 gen_load_fpr32(fp0
, fs
);
8691 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
8692 gen_store_fpr32(fp0
, fd
);
8693 tcg_temp_free_i32(fp0
);
8698 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
8699 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8701 TCGv_i32 fp0
= tcg_temp_new_i32();
8702 TCGv_i32 fp1
= tcg_temp_new_i32();
8703 gen_load_fpr32(fp0
, fs
);
8704 gen_load_fpr32(fp1
, ft
);
8705 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
8706 gen_store_fpr32(fp1
, fd
);
8707 tcg_temp_free_i32(fp1
);
8708 tcg_temp_free_i32(fp0
);
8712 check_cp1_64bitmode(ctx
);
8714 TCGv_i32 fp0
= tcg_temp_new_i32();
8715 TCGv_i32 fp1
= tcg_temp_new_i32();
8717 gen_load_fpr32(fp0
, fs
);
8718 gen_load_fpr32(fp1
, ft
);
8719 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
8720 tcg_temp_free_i32(fp1
);
8721 gen_store_fpr32(fp0
, fd
);
8722 tcg_temp_free_i32(fp0
);
8728 check_cp1_registers(ctx
, fd
);
8730 TCGv_i32 fp32
= tcg_temp_new_i32();
8731 TCGv_i64 fp64
= tcg_temp_new_i64();
8733 gen_load_fpr32(fp32
, fs
);
8734 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
8735 tcg_temp_free_i32(fp32
);
8736 gen_store_fpr64(ctx
, fp64
, fd
);
8737 tcg_temp_free_i64(fp64
);
8743 TCGv_i32 fp0
= tcg_temp_new_i32();
8745 gen_load_fpr32(fp0
, fs
);
8746 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
8747 gen_store_fpr32(fp0
, fd
);
8748 tcg_temp_free_i32(fp0
);
8753 check_cp1_64bitmode(ctx
);
8755 TCGv_i32 fp32
= tcg_temp_new_i32();
8756 TCGv_i64 fp64
= tcg_temp_new_i64();
8758 gen_load_fpr32(fp32
, fs
);
8759 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
8760 tcg_temp_free_i32(fp32
);
8761 gen_store_fpr64(ctx
, fp64
, fd
);
8762 tcg_temp_free_i64(fp64
);
8767 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8768 check_cp1_64bitmode(ctx
);
8770 TCGv_i64 fp64
= tcg_temp_new_i64();
8771 TCGv_i32 fp32_0
= tcg_temp_new_i32();
8772 TCGv_i32 fp32_1
= tcg_temp_new_i32();
8774 gen_load_fpr32(fp32_0
, fs
);
8775 gen_load_fpr32(fp32_1
, ft
);
8776 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
8777 tcg_temp_free_i32(fp32_1
);
8778 tcg_temp_free_i32(fp32_0
);
8779 gen_store_fpr64(ctx
, fp64
, fd
);
8780 tcg_temp_free_i64(fp64
);
8793 case OPC_CMP_NGLE_S
:
8800 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8801 if (ctx
->opcode
& (1 << 6)) {
8802 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
8803 opn
= condnames_abs
[func
-48];
8805 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
8806 opn
= condnames
[func
-48];
8810 check_cp1_registers(ctx
, fs
| ft
| fd
);
8812 TCGv_i64 fp0
= tcg_temp_new_i64();
8813 TCGv_i64 fp1
= tcg_temp_new_i64();
8815 gen_load_fpr64(ctx
, fp0
, fs
);
8816 gen_load_fpr64(ctx
, fp1
, ft
);
8817 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
8818 tcg_temp_free_i64(fp1
);
8819 gen_store_fpr64(ctx
, fp0
, fd
);
8820 tcg_temp_free_i64(fp0
);
8826 check_cp1_registers(ctx
, fs
| ft
| fd
);
8828 TCGv_i64 fp0
= tcg_temp_new_i64();
8829 TCGv_i64 fp1
= tcg_temp_new_i64();
8831 gen_load_fpr64(ctx
, fp0
, fs
);
8832 gen_load_fpr64(ctx
, fp1
, ft
);
8833 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
8834 tcg_temp_free_i64(fp1
);
8835 gen_store_fpr64(ctx
, fp0
, fd
);
8836 tcg_temp_free_i64(fp0
);
8842 check_cp1_registers(ctx
, fs
| ft
| fd
);
8844 TCGv_i64 fp0
= tcg_temp_new_i64();
8845 TCGv_i64 fp1
= tcg_temp_new_i64();
8847 gen_load_fpr64(ctx
, fp0
, fs
);
8848 gen_load_fpr64(ctx
, fp1
, ft
);
8849 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
8850 tcg_temp_free_i64(fp1
);
8851 gen_store_fpr64(ctx
, fp0
, fd
);
8852 tcg_temp_free_i64(fp0
);
8858 check_cp1_registers(ctx
, fs
| ft
| fd
);
8860 TCGv_i64 fp0
= tcg_temp_new_i64();
8861 TCGv_i64 fp1
= tcg_temp_new_i64();
8863 gen_load_fpr64(ctx
, fp0
, fs
);
8864 gen_load_fpr64(ctx
, fp1
, ft
);
8865 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
8866 tcg_temp_free_i64(fp1
);
8867 gen_store_fpr64(ctx
, fp0
, fd
);
8868 tcg_temp_free_i64(fp0
);
8874 check_cp1_registers(ctx
, fs
| fd
);
8876 TCGv_i64 fp0
= tcg_temp_new_i64();
8878 gen_load_fpr64(ctx
, fp0
, fs
);
8879 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
8880 gen_store_fpr64(ctx
, fp0
, fd
);
8881 tcg_temp_free_i64(fp0
);
8886 check_cp1_registers(ctx
, fs
| fd
);
8888 TCGv_i64 fp0
= tcg_temp_new_i64();
8890 gen_load_fpr64(ctx
, fp0
, fs
);
8891 gen_helper_float_abs_d(fp0
, fp0
);
8892 gen_store_fpr64(ctx
, fp0
, fd
);
8893 tcg_temp_free_i64(fp0
);
8898 check_cp1_registers(ctx
, fs
| fd
);
8900 TCGv_i64 fp0
= tcg_temp_new_i64();
8902 gen_load_fpr64(ctx
, fp0
, fs
);
8903 gen_store_fpr64(ctx
, fp0
, fd
);
8904 tcg_temp_free_i64(fp0
);
8909 check_cp1_registers(ctx
, fs
| fd
);
8911 TCGv_i64 fp0
= tcg_temp_new_i64();
8913 gen_load_fpr64(ctx
, fp0
, fs
);
8914 gen_helper_float_chs_d(fp0
, fp0
);
8915 gen_store_fpr64(ctx
, fp0
, fd
);
8916 tcg_temp_free_i64(fp0
);
8921 check_cp1_64bitmode(ctx
);
8923 TCGv_i64 fp0
= tcg_temp_new_i64();
8925 gen_load_fpr64(ctx
, fp0
, fs
);
8926 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
8927 gen_store_fpr64(ctx
, fp0
, fd
);
8928 tcg_temp_free_i64(fp0
);
8933 check_cp1_64bitmode(ctx
);
8935 TCGv_i64 fp0
= tcg_temp_new_i64();
8937 gen_load_fpr64(ctx
, fp0
, fs
);
8938 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
8939 gen_store_fpr64(ctx
, fp0
, fd
);
8940 tcg_temp_free_i64(fp0
);
8945 check_cp1_64bitmode(ctx
);
8947 TCGv_i64 fp0
= tcg_temp_new_i64();
8949 gen_load_fpr64(ctx
, fp0
, fs
);
8950 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
8951 gen_store_fpr64(ctx
, fp0
, fd
);
8952 tcg_temp_free_i64(fp0
);
8957 check_cp1_64bitmode(ctx
);
8959 TCGv_i64 fp0
= tcg_temp_new_i64();
8961 gen_load_fpr64(ctx
, fp0
, fs
);
8962 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8963 gen_store_fpr64(ctx
, fp0
, fd
);
8964 tcg_temp_free_i64(fp0
);
8969 check_cp1_registers(ctx
, fs
);
8971 TCGv_i32 fp32
= tcg_temp_new_i32();
8972 TCGv_i64 fp64
= tcg_temp_new_i64();
8974 gen_load_fpr64(ctx
, fp64
, fs
);
8975 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8976 tcg_temp_free_i64(fp64
);
8977 gen_store_fpr32(fp32
, fd
);
8978 tcg_temp_free_i32(fp32
);
8983 check_cp1_registers(ctx
, fs
);
8985 TCGv_i32 fp32
= tcg_temp_new_i32();
8986 TCGv_i64 fp64
= tcg_temp_new_i64();
8988 gen_load_fpr64(ctx
, fp64
, fs
);
8989 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8990 tcg_temp_free_i64(fp64
);
8991 gen_store_fpr32(fp32
, fd
);
8992 tcg_temp_free_i32(fp32
);
8997 check_cp1_registers(ctx
, fs
);
8999 TCGv_i32 fp32
= tcg_temp_new_i32();
9000 TCGv_i64 fp64
= tcg_temp_new_i64();
9002 gen_load_fpr64(ctx
, fp64
, fs
);
9003 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
9004 tcg_temp_free_i64(fp64
);
9005 gen_store_fpr32(fp32
, fd
);
9006 tcg_temp_free_i32(fp32
);
9011 check_cp1_registers(ctx
, fs
);
9013 TCGv_i32 fp32
= tcg_temp_new_i32();
9014 TCGv_i64 fp64
= tcg_temp_new_i64();
9016 gen_load_fpr64(ctx
, fp64
, fs
);
9017 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
9018 tcg_temp_free_i64(fp64
);
9019 gen_store_fpr32(fp32
, fd
);
9020 tcg_temp_free_i32(fp32
);
9025 check_insn(ctx
, ISA_MIPS32R6
);
9026 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9030 check_insn(ctx
, ISA_MIPS32R6
);
9031 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9035 check_insn(ctx
, ISA_MIPS32R6
);
9036 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9040 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9041 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9045 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9047 int l1
= gen_new_label();
9051 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9053 fp0
= tcg_temp_new_i64();
9054 gen_load_fpr64(ctx
, fp0
, fs
);
9055 gen_store_fpr64(ctx
, fp0
, fd
);
9056 tcg_temp_free_i64(fp0
);
9062 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9064 int l1
= gen_new_label();
9068 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9069 fp0
= tcg_temp_new_i64();
9070 gen_load_fpr64(ctx
, fp0
, fs
);
9071 gen_store_fpr64(ctx
, fp0
, fd
);
9072 tcg_temp_free_i64(fp0
);
9079 check_cp1_64bitmode(ctx
);
9081 TCGv_i64 fp0
= tcg_temp_new_i64();
9083 gen_load_fpr64(ctx
, fp0
, fs
);
9084 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
9085 gen_store_fpr64(ctx
, fp0
, fd
);
9086 tcg_temp_free_i64(fp0
);
9091 check_cp1_64bitmode(ctx
);
9093 TCGv_i64 fp0
= tcg_temp_new_i64();
9095 gen_load_fpr64(ctx
, fp0
, fs
);
9096 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
9097 gen_store_fpr64(ctx
, fp0
, fd
);
9098 tcg_temp_free_i64(fp0
);
9103 check_insn(ctx
, ISA_MIPS32R6
);
9105 TCGv_i64 fp0
= tcg_temp_new_i64();
9106 TCGv_i64 fp1
= tcg_temp_new_i64();
9107 TCGv_i64 fp2
= tcg_temp_new_i64();
9108 gen_load_fpr64(ctx
, fp0
, fs
);
9109 gen_load_fpr64(ctx
, fp1
, ft
);
9110 gen_load_fpr64(ctx
, fp2
, fd
);
9111 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9112 gen_store_fpr64(ctx
, fp2
, fd
);
9113 tcg_temp_free_i64(fp2
);
9114 tcg_temp_free_i64(fp1
);
9115 tcg_temp_free_i64(fp0
);
9120 check_insn(ctx
, ISA_MIPS32R6
);
9122 TCGv_i64 fp0
= tcg_temp_new_i64();
9123 TCGv_i64 fp1
= tcg_temp_new_i64();
9124 TCGv_i64 fp2
= tcg_temp_new_i64();
9125 gen_load_fpr64(ctx
, fp0
, fs
);
9126 gen_load_fpr64(ctx
, fp1
, ft
);
9127 gen_load_fpr64(ctx
, fp2
, fd
);
9128 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9129 gen_store_fpr64(ctx
, fp2
, fd
);
9130 tcg_temp_free_i64(fp2
);
9131 tcg_temp_free_i64(fp1
);
9132 tcg_temp_free_i64(fp0
);
9137 check_insn(ctx
, ISA_MIPS32R6
);
9139 TCGv_i64 fp0
= tcg_temp_new_i64();
9140 gen_load_fpr64(ctx
, fp0
, fs
);
9141 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
9142 gen_store_fpr64(ctx
, fp0
, fd
);
9143 tcg_temp_free_i64(fp0
);
9148 check_insn(ctx
, ISA_MIPS32R6
);
9150 TCGv_i64 fp0
= tcg_temp_new_i64();
9151 gen_load_fpr64(ctx
, fp0
, fs
);
9152 gen_helper_float_class_d(fp0
, fp0
);
9153 gen_store_fpr64(ctx
, fp0
, fd
);
9154 tcg_temp_free_i64(fp0
);
9158 case OPC_MIN_D
: /* OPC_RECIP2_D */
9159 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9161 TCGv_i64 fp0
= tcg_temp_new_i64();
9162 TCGv_i64 fp1
= tcg_temp_new_i64();
9163 gen_load_fpr64(ctx
, fp0
, fs
);
9164 gen_load_fpr64(ctx
, fp1
, ft
);
9165 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
9166 gen_store_fpr64(ctx
, fp1
, fd
);
9167 tcg_temp_free_i64(fp1
);
9168 tcg_temp_free_i64(fp0
);
9172 check_cp1_64bitmode(ctx
);
9174 TCGv_i64 fp0
= tcg_temp_new_i64();
9175 TCGv_i64 fp1
= tcg_temp_new_i64();
9177 gen_load_fpr64(ctx
, fp0
, fs
);
9178 gen_load_fpr64(ctx
, fp1
, ft
);
9179 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
9180 tcg_temp_free_i64(fp1
);
9181 gen_store_fpr64(ctx
, fp0
, fd
);
9182 tcg_temp_free_i64(fp0
);
9187 case OPC_MINA_D
: /* OPC_RECIP1_D */
9188 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9190 TCGv_i64 fp0
= tcg_temp_new_i64();
9191 TCGv_i64 fp1
= tcg_temp_new_i64();
9192 gen_load_fpr64(ctx
, fp0
, fs
);
9193 gen_load_fpr64(ctx
, fp1
, ft
);
9194 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
9195 gen_store_fpr64(ctx
, fp1
, fd
);
9196 tcg_temp_free_i64(fp1
);
9197 tcg_temp_free_i64(fp0
);
9201 check_cp1_64bitmode(ctx
);
9203 TCGv_i64 fp0
= tcg_temp_new_i64();
9205 gen_load_fpr64(ctx
, fp0
, fs
);
9206 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
9207 gen_store_fpr64(ctx
, fp0
, fd
);
9208 tcg_temp_free_i64(fp0
);
9213 case OPC_MAX_D
: /* OPC_RSQRT1_D */
9214 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9216 TCGv_i64 fp0
= tcg_temp_new_i64();
9217 TCGv_i64 fp1
= tcg_temp_new_i64();
9218 gen_load_fpr64(ctx
, fp0
, fs
);
9219 gen_load_fpr64(ctx
, fp1
, ft
);
9220 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
9221 gen_store_fpr64(ctx
, fp1
, fd
);
9222 tcg_temp_free_i64(fp1
);
9223 tcg_temp_free_i64(fp0
);
9227 check_cp1_64bitmode(ctx
);
9229 TCGv_i64 fp0
= tcg_temp_new_i64();
9231 gen_load_fpr64(ctx
, fp0
, fs
);
9232 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
9233 gen_store_fpr64(ctx
, fp0
, fd
);
9234 tcg_temp_free_i64(fp0
);
9239 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
9240 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9242 TCGv_i64 fp0
= tcg_temp_new_i64();
9243 TCGv_i64 fp1
= tcg_temp_new_i64();
9244 gen_load_fpr64(ctx
, fp0
, fs
);
9245 gen_load_fpr64(ctx
, fp1
, ft
);
9246 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
9247 gen_store_fpr64(ctx
, fp1
, fd
);
9248 tcg_temp_free_i64(fp1
);
9249 tcg_temp_free_i64(fp0
);
9253 check_cp1_64bitmode(ctx
);
9255 TCGv_i64 fp0
= tcg_temp_new_i64();
9256 TCGv_i64 fp1
= tcg_temp_new_i64();
9258 gen_load_fpr64(ctx
, fp0
, fs
);
9259 gen_load_fpr64(ctx
, fp1
, ft
);
9260 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
9261 tcg_temp_free_i64(fp1
);
9262 gen_store_fpr64(ctx
, fp0
, fd
);
9263 tcg_temp_free_i64(fp0
);
9277 case OPC_CMP_NGLE_D
:
9284 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9285 if (ctx
->opcode
& (1 << 6)) {
9286 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
9287 opn
= condnames_abs
[func
-48];
9289 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
9290 opn
= condnames
[func
-48];
9294 check_cp1_registers(ctx
, fs
);
9296 TCGv_i32 fp32
= tcg_temp_new_i32();
9297 TCGv_i64 fp64
= tcg_temp_new_i64();
9299 gen_load_fpr64(ctx
, fp64
, fs
);
9300 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
9301 tcg_temp_free_i64(fp64
);
9302 gen_store_fpr32(fp32
, fd
);
9303 tcg_temp_free_i32(fp32
);
9308 check_cp1_registers(ctx
, fs
);
9310 TCGv_i32 fp32
= tcg_temp_new_i32();
9311 TCGv_i64 fp64
= tcg_temp_new_i64();
9313 gen_load_fpr64(ctx
, fp64
, fs
);
9314 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
9315 tcg_temp_free_i64(fp64
);
9316 gen_store_fpr32(fp32
, fd
);
9317 tcg_temp_free_i32(fp32
);
9322 check_cp1_64bitmode(ctx
);
9324 TCGv_i64 fp0
= tcg_temp_new_i64();
9326 gen_load_fpr64(ctx
, fp0
, fs
);
9327 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
9328 gen_store_fpr64(ctx
, fp0
, fd
);
9329 tcg_temp_free_i64(fp0
);
9335 TCGv_i32 fp0
= tcg_temp_new_i32();
9337 gen_load_fpr32(fp0
, fs
);
9338 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
9339 gen_store_fpr32(fp0
, fd
);
9340 tcg_temp_free_i32(fp0
);
9345 check_cp1_registers(ctx
, fd
);
9347 TCGv_i32 fp32
= tcg_temp_new_i32();
9348 TCGv_i64 fp64
= tcg_temp_new_i64();
9350 gen_load_fpr32(fp32
, fs
);
9351 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
9352 tcg_temp_free_i32(fp32
);
9353 gen_store_fpr64(ctx
, fp64
, fd
);
9354 tcg_temp_free_i64(fp64
);
9359 check_cp1_64bitmode(ctx
);
9361 TCGv_i32 fp32
= tcg_temp_new_i32();
9362 TCGv_i64 fp64
= tcg_temp_new_i64();
9364 gen_load_fpr64(ctx
, fp64
, fs
);
9365 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
9366 tcg_temp_free_i64(fp64
);
9367 gen_store_fpr32(fp32
, fd
);
9368 tcg_temp_free_i32(fp32
);
9373 check_cp1_64bitmode(ctx
);
9375 TCGv_i64 fp0
= tcg_temp_new_i64();
9377 gen_load_fpr64(ctx
, fp0
, fs
);
9378 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
9379 gen_store_fpr64(ctx
, fp0
, fd
);
9380 tcg_temp_free_i64(fp0
);
9385 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9386 check_cp1_64bitmode(ctx
);
9388 TCGv_i64 fp0
= tcg_temp_new_i64();
9390 gen_load_fpr64(ctx
, fp0
, fs
);
9391 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
9392 gen_store_fpr64(ctx
, fp0
, fd
);
9393 tcg_temp_free_i64(fp0
);
9398 check_cp1_64bitmode(ctx
);
9400 TCGv_i64 fp0
= tcg_temp_new_i64();
9401 TCGv_i64 fp1
= tcg_temp_new_i64();
9403 gen_load_fpr64(ctx
, fp0
, fs
);
9404 gen_load_fpr64(ctx
, fp1
, ft
);
9405 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
9406 tcg_temp_free_i64(fp1
);
9407 gen_store_fpr64(ctx
, fp0
, fd
);
9408 tcg_temp_free_i64(fp0
);
9413 check_cp1_64bitmode(ctx
);
9415 TCGv_i64 fp0
= tcg_temp_new_i64();
9416 TCGv_i64 fp1
= tcg_temp_new_i64();
9418 gen_load_fpr64(ctx
, fp0
, fs
);
9419 gen_load_fpr64(ctx
, fp1
, ft
);
9420 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
9421 tcg_temp_free_i64(fp1
);
9422 gen_store_fpr64(ctx
, fp0
, fd
);
9423 tcg_temp_free_i64(fp0
);
9428 check_cp1_64bitmode(ctx
);
9430 TCGv_i64 fp0
= tcg_temp_new_i64();
9431 TCGv_i64 fp1
= tcg_temp_new_i64();
9433 gen_load_fpr64(ctx
, fp0
, fs
);
9434 gen_load_fpr64(ctx
, fp1
, ft
);
9435 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
9436 tcg_temp_free_i64(fp1
);
9437 gen_store_fpr64(ctx
, fp0
, fd
);
9438 tcg_temp_free_i64(fp0
);
9443 check_cp1_64bitmode(ctx
);
9445 TCGv_i64 fp0
= tcg_temp_new_i64();
9447 gen_load_fpr64(ctx
, fp0
, fs
);
9448 gen_helper_float_abs_ps(fp0
, fp0
);
9449 gen_store_fpr64(ctx
, fp0
, fd
);
9450 tcg_temp_free_i64(fp0
);
9455 check_cp1_64bitmode(ctx
);
9457 TCGv_i64 fp0
= tcg_temp_new_i64();
9459 gen_load_fpr64(ctx
, fp0
, fs
);
9460 gen_store_fpr64(ctx
, fp0
, fd
);
9461 tcg_temp_free_i64(fp0
);
9466 check_cp1_64bitmode(ctx
);
9468 TCGv_i64 fp0
= tcg_temp_new_i64();
9470 gen_load_fpr64(ctx
, fp0
, fs
);
9471 gen_helper_float_chs_ps(fp0
, fp0
);
9472 gen_store_fpr64(ctx
, fp0
, fd
);
9473 tcg_temp_free_i64(fp0
);
9478 check_cp1_64bitmode(ctx
);
9479 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9483 check_cp1_64bitmode(ctx
);
9485 int l1
= gen_new_label();
9489 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9490 fp0
= tcg_temp_new_i64();
9491 gen_load_fpr64(ctx
, fp0
, fs
);
9492 gen_store_fpr64(ctx
, fp0
, fd
);
9493 tcg_temp_free_i64(fp0
);
9499 check_cp1_64bitmode(ctx
);
9501 int l1
= gen_new_label();
9505 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9506 fp0
= tcg_temp_new_i64();
9507 gen_load_fpr64(ctx
, fp0
, fs
);
9508 gen_store_fpr64(ctx
, fp0
, fd
);
9509 tcg_temp_free_i64(fp0
);
9516 check_cp1_64bitmode(ctx
);
9518 TCGv_i64 fp0
= tcg_temp_new_i64();
9519 TCGv_i64 fp1
= tcg_temp_new_i64();
9521 gen_load_fpr64(ctx
, fp0
, ft
);
9522 gen_load_fpr64(ctx
, fp1
, fs
);
9523 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
9524 tcg_temp_free_i64(fp1
);
9525 gen_store_fpr64(ctx
, fp0
, fd
);
9526 tcg_temp_free_i64(fp0
);
9531 check_cp1_64bitmode(ctx
);
9533 TCGv_i64 fp0
= tcg_temp_new_i64();
9534 TCGv_i64 fp1
= tcg_temp_new_i64();
9536 gen_load_fpr64(ctx
, fp0
, ft
);
9537 gen_load_fpr64(ctx
, fp1
, fs
);
9538 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
9539 tcg_temp_free_i64(fp1
);
9540 gen_store_fpr64(ctx
, fp0
, fd
);
9541 tcg_temp_free_i64(fp0
);
9546 check_cp1_64bitmode(ctx
);
9548 TCGv_i64 fp0
= tcg_temp_new_i64();
9549 TCGv_i64 fp1
= tcg_temp_new_i64();
9551 gen_load_fpr64(ctx
, fp0
, fs
);
9552 gen_load_fpr64(ctx
, fp1
, ft
);
9553 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
9554 tcg_temp_free_i64(fp1
);
9555 gen_store_fpr64(ctx
, fp0
, fd
);
9556 tcg_temp_free_i64(fp0
);
9561 check_cp1_64bitmode(ctx
);
9563 TCGv_i64 fp0
= tcg_temp_new_i64();
9565 gen_load_fpr64(ctx
, fp0
, fs
);
9566 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
9567 gen_store_fpr64(ctx
, fp0
, fd
);
9568 tcg_temp_free_i64(fp0
);
9573 check_cp1_64bitmode(ctx
);
9575 TCGv_i64 fp0
= tcg_temp_new_i64();
9577 gen_load_fpr64(ctx
, fp0
, fs
);
9578 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
9579 gen_store_fpr64(ctx
, fp0
, fd
);
9580 tcg_temp_free_i64(fp0
);
9585 check_cp1_64bitmode(ctx
);
9587 TCGv_i64 fp0
= tcg_temp_new_i64();
9588 TCGv_i64 fp1
= tcg_temp_new_i64();
9590 gen_load_fpr64(ctx
, fp0
, fs
);
9591 gen_load_fpr64(ctx
, fp1
, ft
);
9592 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
9593 tcg_temp_free_i64(fp1
);
9594 gen_store_fpr64(ctx
, fp0
, fd
);
9595 tcg_temp_free_i64(fp0
);
9600 check_cp1_64bitmode(ctx
);
9602 TCGv_i32 fp0
= tcg_temp_new_i32();
9604 gen_load_fpr32h(ctx
, fp0
, fs
);
9605 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
9606 gen_store_fpr32(fp0
, fd
);
9607 tcg_temp_free_i32(fp0
);
9612 check_cp1_64bitmode(ctx
);
9614 TCGv_i64 fp0
= tcg_temp_new_i64();
9616 gen_load_fpr64(ctx
, fp0
, fs
);
9617 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
9618 gen_store_fpr64(ctx
, fp0
, fd
);
9619 tcg_temp_free_i64(fp0
);
9624 check_cp1_64bitmode(ctx
);
9626 TCGv_i32 fp0
= tcg_temp_new_i32();
9628 gen_load_fpr32(fp0
, fs
);
9629 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
9630 gen_store_fpr32(fp0
, fd
);
9631 tcg_temp_free_i32(fp0
);
9636 check_cp1_64bitmode(ctx
);
9638 TCGv_i32 fp0
= tcg_temp_new_i32();
9639 TCGv_i32 fp1
= tcg_temp_new_i32();
9641 gen_load_fpr32(fp0
, fs
);
9642 gen_load_fpr32(fp1
, ft
);
9643 gen_store_fpr32h(ctx
, fp0
, fd
);
9644 gen_store_fpr32(fp1
, fd
);
9645 tcg_temp_free_i32(fp0
);
9646 tcg_temp_free_i32(fp1
);
9651 check_cp1_64bitmode(ctx
);
9653 TCGv_i32 fp0
= tcg_temp_new_i32();
9654 TCGv_i32 fp1
= tcg_temp_new_i32();
9656 gen_load_fpr32(fp0
, fs
);
9657 gen_load_fpr32h(ctx
, fp1
, ft
);
9658 gen_store_fpr32(fp1
, fd
);
9659 gen_store_fpr32h(ctx
, fp0
, fd
);
9660 tcg_temp_free_i32(fp0
);
9661 tcg_temp_free_i32(fp1
);
9666 check_cp1_64bitmode(ctx
);
9668 TCGv_i32 fp0
= tcg_temp_new_i32();
9669 TCGv_i32 fp1
= tcg_temp_new_i32();
9671 gen_load_fpr32h(ctx
, fp0
, fs
);
9672 gen_load_fpr32(fp1
, ft
);
9673 gen_store_fpr32(fp1
, fd
);
9674 gen_store_fpr32h(ctx
, fp0
, fd
);
9675 tcg_temp_free_i32(fp0
);
9676 tcg_temp_free_i32(fp1
);
9681 check_cp1_64bitmode(ctx
);
9683 TCGv_i32 fp0
= tcg_temp_new_i32();
9684 TCGv_i32 fp1
= tcg_temp_new_i32();
9686 gen_load_fpr32h(ctx
, fp0
, fs
);
9687 gen_load_fpr32h(ctx
, fp1
, ft
);
9688 gen_store_fpr32(fp1
, fd
);
9689 gen_store_fpr32h(ctx
, fp0
, fd
);
9690 tcg_temp_free_i32(fp0
);
9691 tcg_temp_free_i32(fp1
);
9698 case OPC_CMP_UEQ_PS
:
9699 case OPC_CMP_OLT_PS
:
9700 case OPC_CMP_ULT_PS
:
9701 case OPC_CMP_OLE_PS
:
9702 case OPC_CMP_ULE_PS
:
9704 case OPC_CMP_NGLE_PS
:
9705 case OPC_CMP_SEQ_PS
:
9706 case OPC_CMP_NGL_PS
:
9708 case OPC_CMP_NGE_PS
:
9710 case OPC_CMP_NGT_PS
:
9711 if (ctx
->opcode
& (1 << 6)) {
9712 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
9713 opn
= condnames_abs
[func
-48];
9715 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
9716 opn
= condnames
[func
-48];
9721 generate_exception (ctx
, EXCP_RI
);
9724 (void)opn
; /* avoid a compiler warning */
9727 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
9730 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
9733 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
9738 /* Coprocessor 3 (FPU) */
9739 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
9740 int fd
, int fs
, int base
, int index
)
9742 const char *opn
= "extended float load/store";
9744 TCGv t0
= tcg_temp_new();
9747 gen_load_gpr(t0
, index
);
9748 } else if (index
== 0) {
9749 gen_load_gpr(t0
, base
);
9751 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
9753 /* Don't do NOP if destination is zero: we must perform the actual
9759 TCGv_i32 fp0
= tcg_temp_new_i32();
9761 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
9762 tcg_gen_trunc_tl_i32(fp0
, t0
);
9763 gen_store_fpr32(fp0
, fd
);
9764 tcg_temp_free_i32(fp0
);
9770 check_cp1_registers(ctx
, fd
);
9772 TCGv_i64 fp0
= tcg_temp_new_i64();
9773 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9774 gen_store_fpr64(ctx
, fp0
, fd
);
9775 tcg_temp_free_i64(fp0
);
9780 check_cp1_64bitmode(ctx
);
9781 tcg_gen_andi_tl(t0
, t0
, ~0x7);
9783 TCGv_i64 fp0
= tcg_temp_new_i64();
9785 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9786 gen_store_fpr64(ctx
, fp0
, fd
);
9787 tcg_temp_free_i64(fp0
);
9794 TCGv_i32 fp0
= tcg_temp_new_i32();
9795 gen_load_fpr32(fp0
, fs
);
9796 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
9797 tcg_temp_free_i32(fp0
);
9804 check_cp1_registers(ctx
, fs
);
9806 TCGv_i64 fp0
= tcg_temp_new_i64();
9807 gen_load_fpr64(ctx
, fp0
, fs
);
9808 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9809 tcg_temp_free_i64(fp0
);
9815 check_cp1_64bitmode(ctx
);
9816 tcg_gen_andi_tl(t0
, t0
, ~0x7);
9818 TCGv_i64 fp0
= tcg_temp_new_i64();
9819 gen_load_fpr64(ctx
, fp0
, fs
);
9820 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9821 tcg_temp_free_i64(fp0
);
9828 (void)opn
; (void)store
; /* avoid compiler warnings */
9829 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
9830 regnames
[index
], regnames
[base
]);
9833 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
9834 int fd
, int fr
, int fs
, int ft
)
9836 const char *opn
= "flt3_arith";
9840 check_cp1_64bitmode(ctx
);
9842 TCGv t0
= tcg_temp_local_new();
9843 TCGv_i32 fp
= tcg_temp_new_i32();
9844 TCGv_i32 fph
= tcg_temp_new_i32();
9845 int l1
= gen_new_label();
9846 int l2
= gen_new_label();
9848 gen_load_gpr(t0
, fr
);
9849 tcg_gen_andi_tl(t0
, t0
, 0x7);
9851 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
9852 gen_load_fpr32(fp
, fs
);
9853 gen_load_fpr32h(ctx
, fph
, fs
);
9854 gen_store_fpr32(fp
, fd
);
9855 gen_store_fpr32h(ctx
, fph
, fd
);
9858 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
9860 #ifdef TARGET_WORDS_BIGENDIAN
9861 gen_load_fpr32(fp
, fs
);
9862 gen_load_fpr32h(ctx
, fph
, ft
);
9863 gen_store_fpr32h(ctx
, fp
, fd
);
9864 gen_store_fpr32(fph
, fd
);
9866 gen_load_fpr32h(ctx
, fph
, fs
);
9867 gen_load_fpr32(fp
, ft
);
9868 gen_store_fpr32(fph
, fd
);
9869 gen_store_fpr32h(ctx
, fp
, fd
);
9872 tcg_temp_free_i32(fp
);
9873 tcg_temp_free_i32(fph
);
9880 TCGv_i32 fp0
= tcg_temp_new_i32();
9881 TCGv_i32 fp1
= tcg_temp_new_i32();
9882 TCGv_i32 fp2
= tcg_temp_new_i32();
9884 gen_load_fpr32(fp0
, fs
);
9885 gen_load_fpr32(fp1
, ft
);
9886 gen_load_fpr32(fp2
, fr
);
9887 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9888 tcg_temp_free_i32(fp0
);
9889 tcg_temp_free_i32(fp1
);
9890 gen_store_fpr32(fp2
, fd
);
9891 tcg_temp_free_i32(fp2
);
9897 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9899 TCGv_i64 fp0
= tcg_temp_new_i64();
9900 TCGv_i64 fp1
= tcg_temp_new_i64();
9901 TCGv_i64 fp2
= tcg_temp_new_i64();
9903 gen_load_fpr64(ctx
, fp0
, fs
);
9904 gen_load_fpr64(ctx
, fp1
, ft
);
9905 gen_load_fpr64(ctx
, fp2
, fr
);
9906 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9907 tcg_temp_free_i64(fp0
);
9908 tcg_temp_free_i64(fp1
);
9909 gen_store_fpr64(ctx
, fp2
, fd
);
9910 tcg_temp_free_i64(fp2
);
9915 check_cp1_64bitmode(ctx
);
9917 TCGv_i64 fp0
= tcg_temp_new_i64();
9918 TCGv_i64 fp1
= tcg_temp_new_i64();
9919 TCGv_i64 fp2
= tcg_temp_new_i64();
9921 gen_load_fpr64(ctx
, fp0
, fs
);
9922 gen_load_fpr64(ctx
, fp1
, ft
);
9923 gen_load_fpr64(ctx
, fp2
, fr
);
9924 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9925 tcg_temp_free_i64(fp0
);
9926 tcg_temp_free_i64(fp1
);
9927 gen_store_fpr64(ctx
, fp2
, fd
);
9928 tcg_temp_free_i64(fp2
);
9935 TCGv_i32 fp0
= tcg_temp_new_i32();
9936 TCGv_i32 fp1
= tcg_temp_new_i32();
9937 TCGv_i32 fp2
= tcg_temp_new_i32();
9939 gen_load_fpr32(fp0
, fs
);
9940 gen_load_fpr32(fp1
, ft
);
9941 gen_load_fpr32(fp2
, fr
);
9942 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9943 tcg_temp_free_i32(fp0
);
9944 tcg_temp_free_i32(fp1
);
9945 gen_store_fpr32(fp2
, fd
);
9946 tcg_temp_free_i32(fp2
);
9952 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9954 TCGv_i64 fp0
= tcg_temp_new_i64();
9955 TCGv_i64 fp1
= tcg_temp_new_i64();
9956 TCGv_i64 fp2
= tcg_temp_new_i64();
9958 gen_load_fpr64(ctx
, fp0
, fs
);
9959 gen_load_fpr64(ctx
, fp1
, ft
);
9960 gen_load_fpr64(ctx
, fp2
, fr
);
9961 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9962 tcg_temp_free_i64(fp0
);
9963 tcg_temp_free_i64(fp1
);
9964 gen_store_fpr64(ctx
, fp2
, fd
);
9965 tcg_temp_free_i64(fp2
);
9970 check_cp1_64bitmode(ctx
);
9972 TCGv_i64 fp0
= tcg_temp_new_i64();
9973 TCGv_i64 fp1
= tcg_temp_new_i64();
9974 TCGv_i64 fp2
= tcg_temp_new_i64();
9976 gen_load_fpr64(ctx
, fp0
, fs
);
9977 gen_load_fpr64(ctx
, fp1
, ft
);
9978 gen_load_fpr64(ctx
, fp2
, fr
);
9979 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9980 tcg_temp_free_i64(fp0
);
9981 tcg_temp_free_i64(fp1
);
9982 gen_store_fpr64(ctx
, fp2
, fd
);
9983 tcg_temp_free_i64(fp2
);
9990 TCGv_i32 fp0
= tcg_temp_new_i32();
9991 TCGv_i32 fp1
= tcg_temp_new_i32();
9992 TCGv_i32 fp2
= tcg_temp_new_i32();
9994 gen_load_fpr32(fp0
, fs
);
9995 gen_load_fpr32(fp1
, ft
);
9996 gen_load_fpr32(fp2
, fr
);
9997 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9998 tcg_temp_free_i32(fp0
);
9999 tcg_temp_free_i32(fp1
);
10000 gen_store_fpr32(fp2
, fd
);
10001 tcg_temp_free_i32(fp2
);
10007 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10009 TCGv_i64 fp0
= tcg_temp_new_i64();
10010 TCGv_i64 fp1
= tcg_temp_new_i64();
10011 TCGv_i64 fp2
= tcg_temp_new_i64();
10013 gen_load_fpr64(ctx
, fp0
, fs
);
10014 gen_load_fpr64(ctx
, fp1
, ft
);
10015 gen_load_fpr64(ctx
, fp2
, fr
);
10016 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10017 tcg_temp_free_i64(fp0
);
10018 tcg_temp_free_i64(fp1
);
10019 gen_store_fpr64(ctx
, fp2
, fd
);
10020 tcg_temp_free_i64(fp2
);
10025 check_cp1_64bitmode(ctx
);
10027 TCGv_i64 fp0
= tcg_temp_new_i64();
10028 TCGv_i64 fp1
= tcg_temp_new_i64();
10029 TCGv_i64 fp2
= tcg_temp_new_i64();
10031 gen_load_fpr64(ctx
, fp0
, fs
);
10032 gen_load_fpr64(ctx
, fp1
, ft
);
10033 gen_load_fpr64(ctx
, fp2
, fr
);
10034 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10035 tcg_temp_free_i64(fp0
);
10036 tcg_temp_free_i64(fp1
);
10037 gen_store_fpr64(ctx
, fp2
, fd
);
10038 tcg_temp_free_i64(fp2
);
10045 TCGv_i32 fp0
= tcg_temp_new_i32();
10046 TCGv_i32 fp1
= tcg_temp_new_i32();
10047 TCGv_i32 fp2
= tcg_temp_new_i32();
10049 gen_load_fpr32(fp0
, fs
);
10050 gen_load_fpr32(fp1
, ft
);
10051 gen_load_fpr32(fp2
, fr
);
10052 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10053 tcg_temp_free_i32(fp0
);
10054 tcg_temp_free_i32(fp1
);
10055 gen_store_fpr32(fp2
, fd
);
10056 tcg_temp_free_i32(fp2
);
10062 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10064 TCGv_i64 fp0
= tcg_temp_new_i64();
10065 TCGv_i64 fp1
= tcg_temp_new_i64();
10066 TCGv_i64 fp2
= tcg_temp_new_i64();
10068 gen_load_fpr64(ctx
, fp0
, fs
);
10069 gen_load_fpr64(ctx
, fp1
, ft
);
10070 gen_load_fpr64(ctx
, fp2
, fr
);
10071 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10072 tcg_temp_free_i64(fp0
);
10073 tcg_temp_free_i64(fp1
);
10074 gen_store_fpr64(ctx
, fp2
, fd
);
10075 tcg_temp_free_i64(fp2
);
10080 check_cp1_64bitmode(ctx
);
10082 TCGv_i64 fp0
= tcg_temp_new_i64();
10083 TCGv_i64 fp1
= tcg_temp_new_i64();
10084 TCGv_i64 fp2
= tcg_temp_new_i64();
10086 gen_load_fpr64(ctx
, fp0
, fs
);
10087 gen_load_fpr64(ctx
, fp1
, ft
);
10088 gen_load_fpr64(ctx
, fp2
, fr
);
10089 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10090 tcg_temp_free_i64(fp0
);
10091 tcg_temp_free_i64(fp1
);
10092 gen_store_fpr64(ctx
, fp2
, fd
);
10093 tcg_temp_free_i64(fp2
);
10099 generate_exception (ctx
, EXCP_RI
);
10102 (void)opn
; /* avoid a compiler warning */
10103 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
10104 fregnames
[fs
], fregnames
[ft
]);
10107 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
10111 #if !defined(CONFIG_USER_ONLY)
10112 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10113 Therefore only check the ISA in system mode. */
10114 check_insn(ctx
, ISA_MIPS32R2
);
10116 t0
= tcg_temp_new();
10120 save_cpu_state(ctx
, 1);
10121 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
10122 gen_store_gpr(t0
, rt
);
10125 save_cpu_state(ctx
, 1);
10126 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
10127 gen_store_gpr(t0
, rt
);
10130 save_cpu_state(ctx
, 1);
10131 gen_helper_rdhwr_cc(t0
, cpu_env
);
10132 gen_store_gpr(t0
, rt
);
10135 save_cpu_state(ctx
, 1);
10136 gen_helper_rdhwr_ccres(t0
, cpu_env
);
10137 gen_store_gpr(t0
, rt
);
10140 #if defined(CONFIG_USER_ONLY)
10141 tcg_gen_ld_tl(t0
, cpu_env
,
10142 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10143 gen_store_gpr(t0
, rt
);
10146 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
10147 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
10148 tcg_gen_ld_tl(t0
, cpu_env
,
10149 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10150 gen_store_gpr(t0
, rt
);
10152 generate_exception(ctx
, EXCP_RI
);
10156 default: /* Invalid */
10157 MIPS_INVAL("rdhwr");
10158 generate_exception(ctx
, EXCP_RI
);
10164 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
10166 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10167 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
10168 /* Branches completion */
10169 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
10170 ctx
->bstate
= BS_BRANCH
;
10171 save_cpu_state(ctx
, 0);
10172 /* FIXME: Need to clear can_do_io. */
10173 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
10175 /* unconditional branch */
10176 MIPS_DEBUG("unconditional branch");
10177 if (proc_hflags
& MIPS_HFLAG_BX
) {
10178 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
10180 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10182 case MIPS_HFLAG_BL
:
10183 /* blikely taken case */
10184 MIPS_DEBUG("blikely branch taken");
10185 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10187 case MIPS_HFLAG_BC
:
10188 /* Conditional branch */
10189 MIPS_DEBUG("conditional branch");
10191 int l1
= gen_new_label();
10193 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
10194 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
10196 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10199 case MIPS_HFLAG_BR
:
10200 /* unconditional branch to register */
10201 MIPS_DEBUG("branch to register");
10202 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
10203 TCGv t0
= tcg_temp_new();
10204 TCGv_i32 t1
= tcg_temp_new_i32();
10206 tcg_gen_andi_tl(t0
, btarget
, 0x1);
10207 tcg_gen_trunc_tl_i32(t1
, t0
);
10209 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
10210 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
10211 tcg_gen_or_i32(hflags
, hflags
, t1
);
10212 tcg_temp_free_i32(t1
);
10214 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
10216 tcg_gen_mov_tl(cpu_PC
, btarget
);
10218 if (ctx
->singlestep_enabled
) {
10219 save_cpu_state(ctx
, 0);
10220 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
10222 tcg_gen_exit_tb(0);
10225 MIPS_DEBUG("unknown branch");
10231 /* ISA extensions (ASEs) */
10232 /* MIPS16 extension to MIPS32 */
10234 /* MIPS16 major opcodes */
10236 M16_OPC_ADDIUSP
= 0x00,
10237 M16_OPC_ADDIUPC
= 0x01,
10239 M16_OPC_JAL
= 0x03,
10240 M16_OPC_BEQZ
= 0x04,
10241 M16_OPC_BNEQZ
= 0x05,
10242 M16_OPC_SHIFT
= 0x06,
10244 M16_OPC_RRIA
= 0x08,
10245 M16_OPC_ADDIU8
= 0x09,
10246 M16_OPC_SLTI
= 0x0a,
10247 M16_OPC_SLTIU
= 0x0b,
10250 M16_OPC_CMPI
= 0x0e,
10254 M16_OPC_LWSP
= 0x12,
10256 M16_OPC_LBU
= 0x14,
10257 M16_OPC_LHU
= 0x15,
10258 M16_OPC_LWPC
= 0x16,
10259 M16_OPC_LWU
= 0x17,
10262 M16_OPC_SWSP
= 0x1a,
10264 M16_OPC_RRR
= 0x1c,
10266 M16_OPC_EXTEND
= 0x1e,
10270 /* I8 funct field */
10289 /* RR funct field */
10323 /* I64 funct field */
10331 I64_DADDIUPC
= 0x6,
10335 /* RR ry field for CNVT */
10337 RR_RY_CNVT_ZEB
= 0x0,
10338 RR_RY_CNVT_ZEH
= 0x1,
10339 RR_RY_CNVT_ZEW
= 0x2,
10340 RR_RY_CNVT_SEB
= 0x4,
10341 RR_RY_CNVT_SEH
= 0x5,
10342 RR_RY_CNVT_SEW
= 0x6,
10345 static int xlat (int r
)
10347 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10352 static void gen_mips16_save (DisasContext
*ctx
,
10353 int xsregs
, int aregs
,
10354 int do_ra
, int do_s0
, int do_s1
,
10357 TCGv t0
= tcg_temp_new();
10358 TCGv t1
= tcg_temp_new();
10388 generate_exception(ctx
, EXCP_RI
);
10394 gen_base_offset_addr(ctx
, t0
, 29, 12);
10395 gen_load_gpr(t1
, 7);
10396 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10399 gen_base_offset_addr(ctx
, t0
, 29, 8);
10400 gen_load_gpr(t1
, 6);
10401 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10404 gen_base_offset_addr(ctx
, t0
, 29, 4);
10405 gen_load_gpr(t1
, 5);
10406 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10409 gen_base_offset_addr(ctx
, t0
, 29, 0);
10410 gen_load_gpr(t1
, 4);
10411 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10414 gen_load_gpr(t0
, 29);
10416 #define DECR_AND_STORE(reg) do { \
10417 tcg_gen_subi_tl(t0, t0, 4); \
10418 gen_load_gpr(t1, reg); \
10419 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
10423 DECR_AND_STORE(31);
10428 DECR_AND_STORE(30);
10431 DECR_AND_STORE(23);
10434 DECR_AND_STORE(22);
10437 DECR_AND_STORE(21);
10440 DECR_AND_STORE(20);
10443 DECR_AND_STORE(19);
10446 DECR_AND_STORE(18);
10450 DECR_AND_STORE(17);
10453 DECR_AND_STORE(16);
10483 generate_exception(ctx
, EXCP_RI
);
10499 #undef DECR_AND_STORE
10501 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
10506 static void gen_mips16_restore (DisasContext
*ctx
,
10507 int xsregs
, int aregs
,
10508 int do_ra
, int do_s0
, int do_s1
,
10512 TCGv t0
= tcg_temp_new();
10513 TCGv t1
= tcg_temp_new();
10515 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
10517 #define DECR_AND_LOAD(reg) do { \
10518 tcg_gen_subi_tl(t0, t0, 4); \
10519 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10520 gen_store_gpr(t1, reg); \
10584 generate_exception(ctx
, EXCP_RI
);
10600 #undef DECR_AND_LOAD
10602 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
10607 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
10608 int is_64_bit
, int extended
)
10612 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10613 generate_exception(ctx
, EXCP_RI
);
10617 t0
= tcg_temp_new();
10619 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
10620 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
10622 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10628 #if defined(TARGET_MIPS64)
10629 static void decode_i64_mips16 (DisasContext
*ctx
,
10630 int ry
, int funct
, int16_t offset
,
10635 check_mips_64(ctx
);
10636 offset
= extended
? offset
: offset
<< 3;
10637 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
10640 check_mips_64(ctx
);
10641 offset
= extended
? offset
: offset
<< 3;
10642 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
10645 check_mips_64(ctx
);
10646 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
10647 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
10650 check_mips_64(ctx
);
10651 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
10652 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
10655 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10656 generate_exception(ctx
, EXCP_RI
);
10658 offset
= extended
? offset
: offset
<< 3;
10659 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
10663 check_mips_64(ctx
);
10664 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
10665 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
10668 check_mips_64(ctx
);
10669 offset
= extended
? offset
: offset
<< 2;
10670 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
10673 check_mips_64(ctx
);
10674 offset
= extended
? offset
: offset
<< 2;
10675 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
10681 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
10683 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
10684 int op
, rx
, ry
, funct
, sa
;
10685 int16_t imm
, offset
;
10687 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
10688 op
= (ctx
->opcode
>> 11) & 0x1f;
10689 sa
= (ctx
->opcode
>> 22) & 0x1f;
10690 funct
= (ctx
->opcode
>> 8) & 0x7;
10691 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
10692 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
10693 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
10694 | ((ctx
->opcode
>> 21) & 0x3f) << 5
10695 | (ctx
->opcode
& 0x1f));
10697 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
10700 case M16_OPC_ADDIUSP
:
10701 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
10703 case M16_OPC_ADDIUPC
:
10704 gen_addiupc(ctx
, rx
, imm
, 0, 1);
10707 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1, 0);
10708 /* No delay slot, so just process as a normal instruction */
10711 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1, 0);
10712 /* No delay slot, so just process as a normal instruction */
10714 case M16_OPC_BNEQZ
:
10715 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1, 0);
10716 /* No delay slot, so just process as a normal instruction */
10718 case M16_OPC_SHIFT
:
10719 switch (ctx
->opcode
& 0x3) {
10721 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
10724 #if defined(TARGET_MIPS64)
10725 check_mips_64(ctx
);
10726 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
10728 generate_exception(ctx
, EXCP_RI
);
10732 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
10735 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
10739 #if defined(TARGET_MIPS64)
10741 check_mips_64(ctx
);
10742 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
10746 imm
= ctx
->opcode
& 0xf;
10747 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
10748 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
10749 imm
= (int16_t) (imm
<< 1) >> 1;
10750 if ((ctx
->opcode
>> 4) & 0x1) {
10751 #if defined(TARGET_MIPS64)
10752 check_mips_64(ctx
);
10753 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
10755 generate_exception(ctx
, EXCP_RI
);
10758 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
10761 case M16_OPC_ADDIU8
:
10762 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
10765 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
10767 case M16_OPC_SLTIU
:
10768 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
10773 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1, 0);
10776 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1, 0);
10779 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
10782 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
10786 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
10787 int aregs
= (ctx
->opcode
>> 16) & 0xf;
10788 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
10789 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
10790 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
10791 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
10792 | (ctx
->opcode
& 0xf)) << 3;
10794 if (ctx
->opcode
& (1 << 7)) {
10795 gen_mips16_save(ctx
, xsregs
, aregs
,
10796 do_ra
, do_s0
, do_s1
,
10799 gen_mips16_restore(ctx
, xsregs
, aregs
,
10800 do_ra
, do_s0
, do_s1
,
10806 generate_exception(ctx
, EXCP_RI
);
10811 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
10814 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
10816 #if defined(TARGET_MIPS64)
10818 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
10822 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
10825 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
10828 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
10831 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
10834 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
10837 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
10840 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
10842 #if defined(TARGET_MIPS64)
10844 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
10848 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10851 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
10854 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
10857 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
10859 #if defined(TARGET_MIPS64)
10861 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
10865 generate_exception(ctx
, EXCP_RI
);
10872 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
10876 int op
, cnvt_op
, op1
, offset
;
10880 op
= (ctx
->opcode
>> 11) & 0x1f;
10881 sa
= (ctx
->opcode
>> 2) & 0x7;
10882 sa
= sa
== 0 ? 8 : sa
;
10883 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
10884 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
10885 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
10886 op1
= offset
= ctx
->opcode
& 0x1f;
10891 case M16_OPC_ADDIUSP
:
10893 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
10895 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
10898 case M16_OPC_ADDIUPC
:
10899 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
10902 offset
= (ctx
->opcode
& 0x7ff) << 1;
10903 offset
= (int16_t)(offset
<< 4) >> 4;
10904 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
, 0);
10905 /* No delay slot, so just process as a normal instruction */
10908 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
10909 offset
= (((ctx
->opcode
& 0x1f) << 21)
10910 | ((ctx
->opcode
>> 5) & 0x1f) << 16
10912 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALX
: OPC_JAL
;
10913 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
, 2);
10917 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0,
10918 ((int8_t)ctx
->opcode
) << 1, 0);
10919 /* No delay slot, so just process as a normal instruction */
10921 case M16_OPC_BNEQZ
:
10922 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0,
10923 ((int8_t)ctx
->opcode
) << 1, 0);
10924 /* No delay slot, so just process as a normal instruction */
10926 case M16_OPC_SHIFT
:
10927 switch (ctx
->opcode
& 0x3) {
10929 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
10932 #if defined(TARGET_MIPS64)
10933 check_mips_64(ctx
);
10934 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
10936 generate_exception(ctx
, EXCP_RI
);
10940 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
10943 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
10947 #if defined(TARGET_MIPS64)
10949 check_mips_64(ctx
);
10950 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
10955 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
10957 if ((ctx
->opcode
>> 4) & 1) {
10958 #if defined(TARGET_MIPS64)
10959 check_mips_64(ctx
);
10960 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
10962 generate_exception(ctx
, EXCP_RI
);
10965 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
10969 case M16_OPC_ADDIU8
:
10971 int16_t imm
= (int8_t) ctx
->opcode
;
10973 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
10978 int16_t imm
= (uint8_t) ctx
->opcode
;
10979 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
10982 case M16_OPC_SLTIU
:
10984 int16_t imm
= (uint8_t) ctx
->opcode
;
10985 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
10992 funct
= (ctx
->opcode
>> 8) & 0x7;
10995 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
10996 ((int8_t)ctx
->opcode
) << 1, 0);
10999 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
11000 ((int8_t)ctx
->opcode
) << 1, 0);
11003 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
11006 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
11007 ((int8_t)ctx
->opcode
) << 3);
11011 int do_ra
= ctx
->opcode
& (1 << 6);
11012 int do_s0
= ctx
->opcode
& (1 << 5);
11013 int do_s1
= ctx
->opcode
& (1 << 4);
11014 int framesize
= ctx
->opcode
& 0xf;
11016 if (framesize
== 0) {
11019 framesize
= framesize
<< 3;
11022 if (ctx
->opcode
& (1 << 7)) {
11023 gen_mips16_save(ctx
, 0, 0,
11024 do_ra
, do_s0
, do_s1
, framesize
);
11026 gen_mips16_restore(ctx
, 0, 0,
11027 do_ra
, do_s0
, do_s1
, framesize
);
11033 int rz
= xlat(ctx
->opcode
& 0x7);
11035 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
11036 ((ctx
->opcode
>> 5) & 0x7);
11037 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
11041 reg32
= ctx
->opcode
& 0x1f;
11042 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
11045 generate_exception(ctx
, EXCP_RI
);
11052 int16_t imm
= (uint8_t) ctx
->opcode
;
11054 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
11059 int16_t imm
= (uint8_t) ctx
->opcode
;
11060 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
11063 #if defined(TARGET_MIPS64)
11065 check_mips_64(ctx
);
11066 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
11070 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11073 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
11076 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11079 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
11082 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11085 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
11088 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
11090 #if defined (TARGET_MIPS64)
11092 check_mips_64(ctx
);
11093 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
11097 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11100 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
11103 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11106 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
11110 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
11113 switch (ctx
->opcode
& 0x3) {
11115 mips32_op
= OPC_ADDU
;
11118 mips32_op
= OPC_SUBU
;
11120 #if defined(TARGET_MIPS64)
11122 mips32_op
= OPC_DADDU
;
11123 check_mips_64(ctx
);
11126 mips32_op
= OPC_DSUBU
;
11127 check_mips_64(ctx
);
11131 generate_exception(ctx
, EXCP_RI
);
11135 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
11144 int nd
= (ctx
->opcode
>> 7) & 0x1;
11145 int link
= (ctx
->opcode
>> 6) & 0x1;
11146 int ra
= (ctx
->opcode
>> 5) & 0x1;
11154 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0,
11159 /* XXX: not clear which exception should be raised
11160 * when in debug mode...
11162 check_insn(ctx
, ISA_MIPS32
);
11163 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11164 generate_exception(ctx
, EXCP_DBp
);
11166 generate_exception(ctx
, EXCP_DBp
);
11170 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
11173 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
11176 generate_exception(ctx
, EXCP_BREAK
);
11179 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
11182 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
11185 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
11187 #if defined (TARGET_MIPS64)
11189 check_mips_64(ctx
);
11190 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
11194 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
11197 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
11200 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
11203 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
11206 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
11209 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
11212 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
11216 case RR_RY_CNVT_ZEB
:
11217 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11219 case RR_RY_CNVT_ZEH
:
11220 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11222 case RR_RY_CNVT_SEB
:
11223 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11225 case RR_RY_CNVT_SEH
:
11226 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11228 #if defined (TARGET_MIPS64)
11229 case RR_RY_CNVT_ZEW
:
11230 check_mips_64(ctx
);
11231 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11233 case RR_RY_CNVT_SEW
:
11234 check_mips_64(ctx
);
11235 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11239 generate_exception(ctx
, EXCP_RI
);
11244 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
11246 #if defined (TARGET_MIPS64)
11248 check_mips_64(ctx
);
11249 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
11252 check_mips_64(ctx
);
11253 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
11256 check_mips_64(ctx
);
11257 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
11260 check_mips_64(ctx
);
11261 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
11265 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
11268 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
11271 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
11274 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
11276 #if defined (TARGET_MIPS64)
11278 check_mips_64(ctx
);
11279 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
11282 check_mips_64(ctx
);
11283 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
11286 check_mips_64(ctx
);
11287 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
11290 check_mips_64(ctx
);
11291 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
11295 generate_exception(ctx
, EXCP_RI
);
11299 case M16_OPC_EXTEND
:
11300 decode_extended_mips16_opc(env
, ctx
);
11303 #if defined(TARGET_MIPS64)
11305 funct
= (ctx
->opcode
>> 8) & 0x7;
11306 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
11310 generate_exception(ctx
, EXCP_RI
);
11317 /* microMIPS extension to MIPS32/MIPS64 */
11320 * microMIPS32/microMIPS64 major opcodes
11322 * 1. MIPS Architecture for Programmers Volume II-B:
11323 * The microMIPS32 Instruction Set (Revision 3.05)
11325 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11327 * 2. MIPS Architecture For Programmers Volume II-A:
11328 * The MIPS64 Instruction Set (Revision 3.51)
11356 POOL32S
= 0x16, /* MIPS64 */
11357 DADDIU32
= 0x17, /* MIPS64 */
11359 /* 0x1f is reserved */
11368 /* 0x20 is reserved */
11378 /* 0x28 and 0x29 are reserved */
11388 /* 0x30 and 0x31 are reserved */
11395 SD32
= 0x36, /* MIPS64 */
11396 LD32
= 0x37, /* MIPS64 */
11398 /* 0x38 and 0x39 are reserved */
11409 /* POOL32A encoding of minor opcode field */
11412 /* These opcodes are distinguished only by bits 9..6; those bits are
11413 * what are recorded below. */
11439 /* The following can be distinguished by their lower 6 bits. */
11445 /* POOL32AXF encoding of minor opcode field extension */
11448 * 1. MIPS Architecture for Programmers Volume II-B:
11449 * The microMIPS32 Instruction Set (Revision 3.05)
11451 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11453 * 2. MIPS Architecture for Programmers VolumeIV-e:
11454 * The MIPS DSP Application-Specific Extension
11455 * to the microMIPS32 Architecture (Revision 2.34)
11457 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11472 /* begin of microMIPS32 DSP */
11474 /* bits 13..12 for 0x01 */
11480 /* bits 13..12 for 0x2a */
11486 /* bits 13..12 for 0x32 */
11490 /* end of microMIPS32 DSP */
11492 /* bits 15..12 for 0x2c */
11508 /* bits 15..12 for 0x34 */
11516 /* bits 15..12 for 0x3c */
11518 JR
= 0x0, /* alias */
11523 /* bits 15..12 for 0x05 */
11527 /* bits 15..12 for 0x0d */
11537 /* bits 15..12 for 0x15 */
11543 /* bits 15..12 for 0x1d */
11547 /* bits 15..12 for 0x2d */
11552 /* bits 15..12 for 0x35 */
11559 /* POOL32B encoding of minor opcode field (bits 15..12) */
11575 /* POOL32C encoding of minor opcode field (bits 15..12) */
11583 /* 0xa is reserved */
11590 /* 0x6 is reserved */
11596 /* POOL32F encoding of minor opcode field (bits 5..0) */
11599 /* These are the bit 7..6 values */
11610 /* These are the bit 8..6 values */
11654 CABS_COND_FMT
= 0x1c, /* MIPS3D */
11658 /* POOL32Fxf encoding of minor opcode extension field */
11696 /* POOL32I encoding of minor opcode field (bits 25..21) */
11721 /* These overlap and are distinguished by bit16 of the instruction */
11730 /* POOL16A encoding of minor opcode field */
11737 /* POOL16B encoding of minor opcode field */
11744 /* POOL16C encoding of minor opcode field */
11764 /* POOL16D encoding of minor opcode field */
11771 /* POOL16E encoding of minor opcode field */
11778 static int mmreg (int r
)
11780 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11785 /* Used for 16-bit store instructions. */
11786 static int mmreg2 (int r
)
11788 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
11793 #define uMIPS_RD(op) ((op >> 7) & 0x7)
11794 #define uMIPS_RS(op) ((op >> 4) & 0x7)
11795 #define uMIPS_RS2(op) uMIPS_RS(op)
11796 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
11797 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
11798 #define uMIPS_RS5(op) (op & 0x1f)
11800 /* Signed immediate */
11801 #define SIMM(op, start, width) \
11802 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
11805 /* Zero-extended immediate */
11806 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
11808 static void gen_addiur1sp(DisasContext
*ctx
)
11810 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
11812 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
11815 static void gen_addiur2(DisasContext
*ctx
)
11817 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
11818 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
11819 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
11821 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
11824 static void gen_addiusp(DisasContext
*ctx
)
11826 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
11829 if (encoded
<= 1) {
11830 decoded
= 256 + encoded
;
11831 } else if (encoded
<= 255) {
11833 } else if (encoded
<= 509) {
11834 decoded
= encoded
- 512;
11836 decoded
= encoded
- 768;
11839 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
11842 static void gen_addius5(DisasContext
*ctx
)
11844 int imm
= SIMM(ctx
->opcode
, 1, 4);
11845 int rd
= (ctx
->opcode
>> 5) & 0x1f;
11847 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
11850 static void gen_andi16(DisasContext
*ctx
)
11852 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
11853 31, 32, 63, 64, 255, 32768, 65535 };
11854 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
11855 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
11856 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
11858 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
11861 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
11862 int base
, int16_t offset
)
11864 const char *opn
= "ldst_multiple";
11868 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11869 generate_exception(ctx
, EXCP_RI
);
11873 t0
= tcg_temp_new();
11875 gen_base_offset_addr(ctx
, t0
, base
, offset
);
11877 t1
= tcg_const_tl(reglist
);
11878 t2
= tcg_const_i32(ctx
->mem_idx
);
11880 save_cpu_state(ctx
, 1);
11883 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
11887 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
11890 #ifdef TARGET_MIPS64
11892 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
11896 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
11902 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
11905 tcg_temp_free_i32(t2
);
11909 static void gen_pool16c_insn(DisasContext
*ctx
)
11911 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
11912 int rs
= mmreg(ctx
->opcode
& 0x7);
11914 switch (((ctx
->opcode
) >> 4) & 0x3f) {
11919 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
11925 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
11931 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
11937 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
11944 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
11945 int offset
= ZIMM(ctx
->opcode
, 0, 4);
11947 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
11956 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
11957 int offset
= ZIMM(ctx
->opcode
, 0, 4);
11959 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
11966 int reg
= ctx
->opcode
& 0x1f;
11968 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 4);
11974 int reg
= ctx
->opcode
& 0x1f;
11975 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0, 0);
11976 /* Let normal delay slot handling in our caller take us
11977 to the branch target. */
11982 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 4);
11983 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
11987 gen_compute_branch(ctx
, OPC_JALR
, 2, ctx
->opcode
& 0x1f, 31, 0, 2);
11988 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
11992 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
11996 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
11999 generate_exception(ctx
, EXCP_BREAK
);
12002 /* XXX: not clear which exception should be raised
12003 * when in debug mode...
12005 check_insn(ctx
, ISA_MIPS32
);
12006 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
12007 generate_exception(ctx
, EXCP_DBp
);
12009 generate_exception(ctx
, EXCP_DBp
);
12012 case JRADDIUSP
+ 0:
12013 case JRADDIUSP
+ 1:
12015 int imm
= ZIMM(ctx
->opcode
, 0, 5);
12016 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0, 0);
12017 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
12018 /* Let normal delay slot handling in our caller take us
12019 to the branch target. */
12023 generate_exception(ctx
, EXCP_RI
);
12028 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
12030 TCGv t0
= tcg_temp_new();
12031 TCGv t1
= tcg_temp_new();
12033 gen_load_gpr(t0
, base
);
12036 gen_load_gpr(t1
, index
);
12037 tcg_gen_shli_tl(t1
, t1
, 2);
12038 gen_op_addr_add(ctx
, t0
, t1
, t0
);
12041 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12042 gen_store_gpr(t1
, rd
);
12048 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
12049 int base
, int16_t offset
)
12051 const char *opn
= "ldst_pair";
12054 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
12055 generate_exception(ctx
, EXCP_RI
);
12059 t0
= tcg_temp_new();
12060 t1
= tcg_temp_new();
12062 gen_base_offset_addr(ctx
, t0
, base
, offset
);
12067 generate_exception(ctx
, EXCP_RI
);
12070 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12071 gen_store_gpr(t1
, rd
);
12072 tcg_gen_movi_tl(t1
, 4);
12073 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12074 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12075 gen_store_gpr(t1
, rd
+1);
12079 gen_load_gpr(t1
, rd
);
12080 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12081 tcg_gen_movi_tl(t1
, 4);
12082 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12083 gen_load_gpr(t1
, rd
+1);
12084 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12087 #ifdef TARGET_MIPS64
12090 generate_exception(ctx
, EXCP_RI
);
12093 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12094 gen_store_gpr(t1
, rd
);
12095 tcg_gen_movi_tl(t1
, 8);
12096 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12097 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12098 gen_store_gpr(t1
, rd
+1);
12102 gen_load_gpr(t1
, rd
);
12103 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12104 tcg_gen_movi_tl(t1
, 8);
12105 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12106 gen_load_gpr(t1
, rd
+1);
12107 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12112 (void)opn
; /* avoid a compiler warning */
12113 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
12118 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
12120 int extension
= (ctx
->opcode
>> 6) & 0x3f;
12121 int minor
= (ctx
->opcode
>> 12) & 0xf;
12122 uint32_t mips32_op
;
12124 switch (extension
) {
12126 mips32_op
= OPC_TEQ
;
12129 mips32_op
= OPC_TGE
;
12132 mips32_op
= OPC_TGEU
;
12135 mips32_op
= OPC_TLT
;
12138 mips32_op
= OPC_TLTU
;
12141 mips32_op
= OPC_TNE
;
12143 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
12145 #ifndef CONFIG_USER_ONLY
12148 check_cp0_enabled(ctx
);
12150 /* Treat as NOP. */
12153 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
12157 check_cp0_enabled(ctx
);
12159 TCGv t0
= tcg_temp_new();
12161 gen_load_gpr(t0
, rt
);
12162 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
12168 switch (minor
& 3) {
12170 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12173 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12176 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12179 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12182 goto pool32axf_invalid
;
12186 switch (minor
& 3) {
12188 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12191 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12194 goto pool32axf_invalid
;
12200 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
12203 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
12206 mips32_op
= OPC_CLO
;
12209 mips32_op
= OPC_CLZ
;
12211 check_insn(ctx
, ISA_MIPS32
);
12212 gen_cl(ctx
, mips32_op
, rt
, rs
);
12215 gen_rdhwr(ctx
, rt
, rs
);
12218 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
12221 mips32_op
= OPC_MULT
;
12224 mips32_op
= OPC_MULTU
;
12227 mips32_op
= OPC_DIV
;
12230 mips32_op
= OPC_DIVU
;
12233 check_insn(ctx
, ISA_MIPS32
);
12234 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
12237 mips32_op
= OPC_MADD
;
12240 mips32_op
= OPC_MADDU
;
12243 mips32_op
= OPC_MSUB
;
12246 mips32_op
= OPC_MSUBU
;
12248 check_insn(ctx
, ISA_MIPS32
);
12249 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
12252 goto pool32axf_invalid
;
12263 generate_exception_err(ctx
, EXCP_CpU
, 2);
12266 goto pool32axf_invalid
;
12273 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 4);
12274 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12278 gen_compute_branch(ctx
, OPC_JALR
, 4, rs
, rt
, 0, 2);
12279 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
12282 goto pool32axf_invalid
;
12288 check_cp0_enabled(ctx
);
12289 check_insn(ctx
, ISA_MIPS32R2
);
12290 gen_load_srsgpr(rt
, rs
);
12293 check_cp0_enabled(ctx
);
12294 check_insn(ctx
, ISA_MIPS32R2
);
12295 gen_store_srsgpr(rt
, rs
);
12298 goto pool32axf_invalid
;
12301 #ifndef CONFIG_USER_ONLY
12305 mips32_op
= OPC_TLBP
;
12308 mips32_op
= OPC_TLBR
;
12311 mips32_op
= OPC_TLBWI
;
12314 mips32_op
= OPC_TLBWR
;
12317 mips32_op
= OPC_WAIT
;
12320 mips32_op
= OPC_DERET
;
12323 mips32_op
= OPC_ERET
;
12325 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
12328 goto pool32axf_invalid
;
12334 check_cp0_enabled(ctx
);
12336 TCGv t0
= tcg_temp_new();
12338 save_cpu_state(ctx
, 1);
12339 gen_helper_di(t0
, cpu_env
);
12340 gen_store_gpr(t0
, rs
);
12341 /* Stop translation as we may have switched the execution mode */
12342 ctx
->bstate
= BS_STOP
;
12347 check_cp0_enabled(ctx
);
12349 TCGv t0
= tcg_temp_new();
12351 save_cpu_state(ctx
, 1);
12352 gen_helper_ei(t0
, cpu_env
);
12353 gen_store_gpr(t0
, rs
);
12354 /* Stop translation as we may have switched the execution mode */
12355 ctx
->bstate
= BS_STOP
;
12360 goto pool32axf_invalid
;
12370 generate_exception(ctx
, EXCP_SYSCALL
);
12371 ctx
->bstate
= BS_STOP
;
12374 check_insn(ctx
, ISA_MIPS32
);
12375 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
12376 generate_exception(ctx
, EXCP_DBp
);
12378 generate_exception(ctx
, EXCP_DBp
);
12382 goto pool32axf_invalid
;
12386 switch (minor
& 3) {
12388 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
12391 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
12394 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
12397 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
12400 goto pool32axf_invalid
;
12406 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
12409 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
12412 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
12415 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
12418 goto pool32axf_invalid
;
12423 MIPS_INVAL("pool32axf");
12424 generate_exception(ctx
, EXCP_RI
);
12429 /* Values for microMIPS fmt field. Variable-width, depending on which
12430 formats the instruction supports. */
12449 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
12451 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
12452 uint32_t mips32_op
;
12454 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12455 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12456 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12458 switch (extension
) {
12459 case FLOAT_1BIT_FMT(CFC1
, 0):
12460 mips32_op
= OPC_CFC1
;
12462 case FLOAT_1BIT_FMT(CTC1
, 0):
12463 mips32_op
= OPC_CTC1
;
12465 case FLOAT_1BIT_FMT(MFC1
, 0):
12466 mips32_op
= OPC_MFC1
;
12468 case FLOAT_1BIT_FMT(MTC1
, 0):
12469 mips32_op
= OPC_MTC1
;
12471 case FLOAT_1BIT_FMT(MFHC1
, 0):
12472 mips32_op
= OPC_MFHC1
;
12474 case FLOAT_1BIT_FMT(MTHC1
, 0):
12475 mips32_op
= OPC_MTHC1
;
12477 gen_cp1(ctx
, mips32_op
, rt
, rs
);
12480 /* Reciprocal square root */
12481 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
12482 mips32_op
= OPC_RSQRT_S
;
12484 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
12485 mips32_op
= OPC_RSQRT_D
;
12489 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
12490 mips32_op
= OPC_SQRT_S
;
12492 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
12493 mips32_op
= OPC_SQRT_D
;
12497 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
12498 mips32_op
= OPC_RECIP_S
;
12500 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
12501 mips32_op
= OPC_RECIP_D
;
12505 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
12506 mips32_op
= OPC_FLOOR_L_S
;
12508 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
12509 mips32_op
= OPC_FLOOR_L_D
;
12511 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
12512 mips32_op
= OPC_FLOOR_W_S
;
12514 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
12515 mips32_op
= OPC_FLOOR_W_D
;
12519 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
12520 mips32_op
= OPC_CEIL_L_S
;
12522 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
12523 mips32_op
= OPC_CEIL_L_D
;
12525 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
12526 mips32_op
= OPC_CEIL_W_S
;
12528 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
12529 mips32_op
= OPC_CEIL_W_D
;
12533 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
12534 mips32_op
= OPC_TRUNC_L_S
;
12536 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
12537 mips32_op
= OPC_TRUNC_L_D
;
12539 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
12540 mips32_op
= OPC_TRUNC_W_S
;
12542 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
12543 mips32_op
= OPC_TRUNC_W_D
;
12547 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
12548 mips32_op
= OPC_ROUND_L_S
;
12550 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
12551 mips32_op
= OPC_ROUND_L_D
;
12553 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
12554 mips32_op
= OPC_ROUND_W_S
;
12556 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
12557 mips32_op
= OPC_ROUND_W_D
;
12560 /* Integer to floating-point conversion */
12561 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
12562 mips32_op
= OPC_CVT_L_S
;
12564 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
12565 mips32_op
= OPC_CVT_L_D
;
12567 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
12568 mips32_op
= OPC_CVT_W_S
;
12570 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
12571 mips32_op
= OPC_CVT_W_D
;
12574 /* Paired-foo conversions */
12575 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
12576 mips32_op
= OPC_CVT_S_PL
;
12578 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
12579 mips32_op
= OPC_CVT_S_PU
;
12581 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
12582 mips32_op
= OPC_CVT_PW_PS
;
12584 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
12585 mips32_op
= OPC_CVT_PS_PW
;
12588 /* Floating-point moves */
12589 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
12590 mips32_op
= OPC_MOV_S
;
12592 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
12593 mips32_op
= OPC_MOV_D
;
12595 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
12596 mips32_op
= OPC_MOV_PS
;
12599 /* Absolute value */
12600 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
12601 mips32_op
= OPC_ABS_S
;
12603 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
12604 mips32_op
= OPC_ABS_D
;
12606 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
12607 mips32_op
= OPC_ABS_PS
;
12611 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
12612 mips32_op
= OPC_NEG_S
;
12614 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
12615 mips32_op
= OPC_NEG_D
;
12617 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
12618 mips32_op
= OPC_NEG_PS
;
12621 /* Reciprocal square root step */
12622 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
12623 mips32_op
= OPC_RSQRT1_S
;
12625 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
12626 mips32_op
= OPC_RSQRT1_D
;
12628 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
12629 mips32_op
= OPC_RSQRT1_PS
;
12632 /* Reciprocal step */
12633 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
12634 mips32_op
= OPC_RECIP1_S
;
12636 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
12637 mips32_op
= OPC_RECIP1_S
;
12639 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
12640 mips32_op
= OPC_RECIP1_PS
;
12643 /* Conversions from double */
12644 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
12645 mips32_op
= OPC_CVT_D_S
;
12647 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
12648 mips32_op
= OPC_CVT_D_W
;
12650 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
12651 mips32_op
= OPC_CVT_D_L
;
12654 /* Conversions from single */
12655 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
12656 mips32_op
= OPC_CVT_S_D
;
12658 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
12659 mips32_op
= OPC_CVT_S_W
;
12661 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
12662 mips32_op
= OPC_CVT_S_L
;
12664 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
12667 /* Conditional moves on floating-point codes */
12668 case COND_FLOAT_MOV(MOVT
, 0):
12669 case COND_FLOAT_MOV(MOVT
, 1):
12670 case COND_FLOAT_MOV(MOVT
, 2):
12671 case COND_FLOAT_MOV(MOVT
, 3):
12672 case COND_FLOAT_MOV(MOVT
, 4):
12673 case COND_FLOAT_MOV(MOVT
, 5):
12674 case COND_FLOAT_MOV(MOVT
, 6):
12675 case COND_FLOAT_MOV(MOVT
, 7):
12676 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
12678 case COND_FLOAT_MOV(MOVF
, 0):
12679 case COND_FLOAT_MOV(MOVF
, 1):
12680 case COND_FLOAT_MOV(MOVF
, 2):
12681 case COND_FLOAT_MOV(MOVF
, 3):
12682 case COND_FLOAT_MOV(MOVF
, 4):
12683 case COND_FLOAT_MOV(MOVF
, 5):
12684 case COND_FLOAT_MOV(MOVF
, 6):
12685 case COND_FLOAT_MOV(MOVF
, 7):
12686 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
12689 MIPS_INVAL("pool32fxf");
12690 generate_exception(ctx
, EXCP_RI
);
12695 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
12700 int rt
, rs
, rd
, rr
;
12702 uint32_t op
, minor
, mips32_op
;
12703 uint32_t cond
, fmt
, cc
;
12705 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
12706 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
12708 rt
= (ctx
->opcode
>> 21) & 0x1f;
12709 rs
= (ctx
->opcode
>> 16) & 0x1f;
12710 rd
= (ctx
->opcode
>> 11) & 0x1f;
12711 rr
= (ctx
->opcode
>> 6) & 0x1f;
12712 imm
= (int16_t) ctx
->opcode
;
12714 op
= (ctx
->opcode
>> 26) & 0x3f;
12717 minor
= ctx
->opcode
& 0x3f;
12720 minor
= (ctx
->opcode
>> 6) & 0xf;
12723 mips32_op
= OPC_SLL
;
12726 mips32_op
= OPC_SRA
;
12729 mips32_op
= OPC_SRL
;
12732 mips32_op
= OPC_ROTR
;
12734 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
12737 goto pool32a_invalid
;
12741 minor
= (ctx
->opcode
>> 6) & 0xf;
12745 mips32_op
= OPC_ADD
;
12748 mips32_op
= OPC_ADDU
;
12751 mips32_op
= OPC_SUB
;
12754 mips32_op
= OPC_SUBU
;
12757 mips32_op
= OPC_MUL
;
12759 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
12763 mips32_op
= OPC_SLLV
;
12766 mips32_op
= OPC_SRLV
;
12769 mips32_op
= OPC_SRAV
;
12772 mips32_op
= OPC_ROTRV
;
12774 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
12776 /* Logical operations */
12778 mips32_op
= OPC_AND
;
12781 mips32_op
= OPC_OR
;
12784 mips32_op
= OPC_NOR
;
12787 mips32_op
= OPC_XOR
;
12789 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
12791 /* Set less than */
12793 mips32_op
= OPC_SLT
;
12796 mips32_op
= OPC_SLTU
;
12798 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
12801 goto pool32a_invalid
;
12805 minor
= (ctx
->opcode
>> 6) & 0xf;
12807 /* Conditional moves */
12809 mips32_op
= OPC_MOVN
;
12812 mips32_op
= OPC_MOVZ
;
12814 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
12817 gen_ldxs(ctx
, rs
, rt
, rd
);
12820 goto pool32a_invalid
;
12824 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
12827 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
12830 gen_pool32axf(env
, ctx
, rt
, rs
);
12833 generate_exception(ctx
, EXCP_BREAK
);
12837 MIPS_INVAL("pool32a");
12838 generate_exception(ctx
, EXCP_RI
);
12843 minor
= (ctx
->opcode
>> 12) & 0xf;
12846 check_cp0_enabled(ctx
);
12847 /* Treat as no-op. */
12851 /* COP2: Not implemented. */
12852 generate_exception_err(ctx
, EXCP_CpU
, 2);
12856 #ifdef TARGET_MIPS64
12860 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12864 #ifdef TARGET_MIPS64
12868 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12871 MIPS_INVAL("pool32b");
12872 generate_exception(ctx
, EXCP_RI
);
12877 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
12878 minor
= ctx
->opcode
& 0x3f;
12879 check_cp1_enabled(ctx
);
12882 mips32_op
= OPC_ALNV_PS
;
12885 mips32_op
= OPC_MADD_S
;
12888 mips32_op
= OPC_MADD_D
;
12891 mips32_op
= OPC_MADD_PS
;
12894 mips32_op
= OPC_MSUB_S
;
12897 mips32_op
= OPC_MSUB_D
;
12900 mips32_op
= OPC_MSUB_PS
;
12903 mips32_op
= OPC_NMADD_S
;
12906 mips32_op
= OPC_NMADD_D
;
12909 mips32_op
= OPC_NMADD_PS
;
12912 mips32_op
= OPC_NMSUB_S
;
12915 mips32_op
= OPC_NMSUB_D
;
12918 mips32_op
= OPC_NMSUB_PS
;
12920 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
12922 case CABS_COND_FMT
:
12923 cond
= (ctx
->opcode
>> 6) & 0xf;
12924 cc
= (ctx
->opcode
>> 13) & 0x7;
12925 fmt
= (ctx
->opcode
>> 10) & 0x3;
12928 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
12931 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
12934 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
12937 goto pool32f_invalid
;
12941 cond
= (ctx
->opcode
>> 6) & 0xf;
12942 cc
= (ctx
->opcode
>> 13) & 0x7;
12943 fmt
= (ctx
->opcode
>> 10) & 0x3;
12946 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
12949 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
12952 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
12955 goto pool32f_invalid
;
12959 gen_pool32fxf(ctx
, rt
, rs
);
12963 switch ((ctx
->opcode
>> 6) & 0x7) {
12965 mips32_op
= OPC_PLL_PS
;
12968 mips32_op
= OPC_PLU_PS
;
12971 mips32_op
= OPC_PUL_PS
;
12974 mips32_op
= OPC_PUU_PS
;
12977 mips32_op
= OPC_CVT_PS_S
;
12979 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12982 goto pool32f_invalid
;
12987 switch ((ctx
->opcode
>> 6) & 0x7) {
12989 mips32_op
= OPC_LWXC1
;
12992 mips32_op
= OPC_SWXC1
;
12995 mips32_op
= OPC_LDXC1
;
12998 mips32_op
= OPC_SDXC1
;
13001 mips32_op
= OPC_LUXC1
;
13004 mips32_op
= OPC_SUXC1
;
13006 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
13009 goto pool32f_invalid
;
13014 fmt
= (ctx
->opcode
>> 9) & 0x3;
13015 switch ((ctx
->opcode
>> 6) & 0x7) {
13019 mips32_op
= OPC_RSQRT2_S
;
13022 mips32_op
= OPC_RSQRT2_D
;
13025 mips32_op
= OPC_RSQRT2_PS
;
13028 goto pool32f_invalid
;
13034 mips32_op
= OPC_RECIP2_S
;
13037 mips32_op
= OPC_RECIP2_D
;
13040 mips32_op
= OPC_RECIP2_PS
;
13043 goto pool32f_invalid
;
13047 mips32_op
= OPC_ADDR_PS
;
13050 mips32_op
= OPC_MULR_PS
;
13052 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13055 goto pool32f_invalid
;
13059 /* MOV[FT].fmt and PREFX */
13060 cc
= (ctx
->opcode
>> 13) & 0x7;
13061 fmt
= (ctx
->opcode
>> 9) & 0x3;
13062 switch ((ctx
->opcode
>> 6) & 0x7) {
13066 gen_movcf_s(rs
, rt
, cc
, 0);
13069 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
13072 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
13075 goto pool32f_invalid
;
13081 gen_movcf_s(rs
, rt
, cc
, 1);
13084 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
13087 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
13090 goto pool32f_invalid
;
13096 goto pool32f_invalid
;
13099 #define FINSN_3ARG_SDPS(prfx) \
13100 switch ((ctx->opcode >> 8) & 0x3) { \
13102 mips32_op = OPC_##prfx##_S; \
13105 mips32_op = OPC_##prfx##_D; \
13107 case FMT_SDPS_PS: \
13108 mips32_op = OPC_##prfx##_PS; \
13111 goto pool32f_invalid; \
13114 /* regular FP ops */
13115 switch ((ctx
->opcode
>> 6) & 0x3) {
13117 FINSN_3ARG_SDPS(ADD
);
13120 FINSN_3ARG_SDPS(SUB
);
13123 FINSN_3ARG_SDPS(MUL
);
13126 fmt
= (ctx
->opcode
>> 8) & 0x3;
13128 mips32_op
= OPC_DIV_D
;
13129 } else if (fmt
== 0) {
13130 mips32_op
= OPC_DIV_S
;
13132 goto pool32f_invalid
;
13136 goto pool32f_invalid
;
13141 switch ((ctx
->opcode
>> 6) & 0x3) {
13143 FINSN_3ARG_SDPS(MOVN
);
13146 FINSN_3ARG_SDPS(MOVZ
);
13149 goto pool32f_invalid
;
13153 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13157 MIPS_INVAL("pool32f");
13158 generate_exception(ctx
, EXCP_RI
);
13162 generate_exception_err(ctx
, EXCP_CpU
, 1);
13166 minor
= (ctx
->opcode
>> 21) & 0x1f;
13169 gen_compute_branch(ctx
, OPC_BLTZ
, 4, rs
, -1, imm
<< 1, 4);
13172 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 4);
13173 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13176 gen_compute_branch(ctx
, OPC_BLTZAL
, 4, rs
, -1, imm
<< 1, 2);
13177 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13180 gen_compute_branch(ctx
, OPC_BGEZ
, 4, rs
, -1, imm
<< 1, 4);
13183 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 4);
13184 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13187 gen_compute_branch(ctx
, OPC_BGEZAL
, 4, rs
, -1, imm
<< 1, 2);
13188 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13191 gen_compute_branch(ctx
, OPC_BLEZ
, 4, rs
, -1, imm
<< 1, 4);
13194 gen_compute_branch(ctx
, OPC_BGTZ
, 4, rs
, -1, imm
<< 1, 4);
13199 mips32_op
= OPC_TLTI
;
13202 mips32_op
= OPC_TGEI
;
13205 mips32_op
= OPC_TLTIU
;
13208 mips32_op
= OPC_TGEIU
;
13211 mips32_op
= OPC_TNEI
;
13214 mips32_op
= OPC_TEQI
;
13216 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
13221 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
13222 4, rs
, 0, imm
<< 1, 0);
13223 /* Compact branches don't have a delay slot, so just let
13224 the normal delay slot handling take us to the branch
13228 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
13231 /* Break the TB to be able to sync copied instructions
13233 ctx
->bstate
= BS_STOP
;
13237 /* COP2: Not implemented. */
13238 generate_exception_err(ctx
, EXCP_CpU
, 2);
13241 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
13244 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
13247 mips32_op
= OPC_BC1FANY4
;
13250 mips32_op
= OPC_BC1TANY4
;
13253 check_insn(ctx
, ASE_MIPS3D
);
13256 gen_compute_branch1(ctx
, mips32_op
,
13257 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
13261 /* MIPS DSP: not implemented */
13264 MIPS_INVAL("pool32i");
13265 generate_exception(ctx
, EXCP_RI
);
13270 minor
= (ctx
->opcode
>> 12) & 0xf;
13273 mips32_op
= OPC_LWL
;
13276 mips32_op
= OPC_SWL
;
13279 mips32_op
= OPC_LWR
;
13282 mips32_op
= OPC_SWR
;
13284 #if defined(TARGET_MIPS64)
13286 mips32_op
= OPC_LDL
;
13289 mips32_op
= OPC_SDL
;
13292 mips32_op
= OPC_LDR
;
13295 mips32_op
= OPC_SDR
;
13298 mips32_op
= OPC_LWU
;
13301 mips32_op
= OPC_LLD
;
13305 mips32_op
= OPC_LL
;
13308 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13311 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13314 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13316 #if defined(TARGET_MIPS64)
13318 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13322 /* Treat as no-op */
13325 MIPS_INVAL("pool32c");
13326 generate_exception(ctx
, EXCP_RI
);
13331 mips32_op
= OPC_ADDI
;
13334 mips32_op
= OPC_ADDIU
;
13336 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13339 /* Logical operations */
13341 mips32_op
= OPC_ORI
;
13344 mips32_op
= OPC_XORI
;
13347 mips32_op
= OPC_ANDI
;
13349 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13352 /* Set less than immediate */
13354 mips32_op
= OPC_SLTI
;
13357 mips32_op
= OPC_SLTIU
;
13359 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13362 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
13363 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
, 4);
13364 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13367 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
13368 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
, offset
, 2);
13369 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13372 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1, 4);
13375 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1, 4);
13378 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
13379 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
13382 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
13383 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1, 4);
13384 ctx
->hflags
|= MIPS_HFLAG_BDS_STRICT
;
13386 /* Floating point (COP1) */
13388 mips32_op
= OPC_LWC1
;
13391 mips32_op
= OPC_LDC1
;
13394 mips32_op
= OPC_SWC1
;
13397 mips32_op
= OPC_SDC1
;
13399 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
13403 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
13404 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
13406 gen_addiupc(ctx
, reg
, offset
, 0, 0);
13409 /* Loads and stores */
13411 mips32_op
= OPC_LB
;
13414 mips32_op
= OPC_LBU
;
13417 mips32_op
= OPC_LH
;
13420 mips32_op
= OPC_LHU
;
13423 mips32_op
= OPC_LW
;
13425 #ifdef TARGET_MIPS64
13427 mips32_op
= OPC_LD
;
13430 mips32_op
= OPC_SD
;
13434 mips32_op
= OPC_SB
;
13437 mips32_op
= OPC_SH
;
13440 mips32_op
= OPC_SW
;
13443 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
13446 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
13449 generate_exception(ctx
, EXCP_RI
);
13454 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
13458 /* make sure instructions are on a halfword boundary */
13459 if (ctx
->pc
& 0x1) {
13460 env
->CP0_BadVAddr
= ctx
->pc
;
13461 generate_exception(ctx
, EXCP_AdEL
);
13462 ctx
->bstate
= BS_STOP
;
13466 op
= (ctx
->opcode
>> 10) & 0x3f;
13467 /* Enforce properly-sized instructions in a delay slot */
13468 if (ctx
->hflags
& MIPS_HFLAG_BDS_STRICT
) {
13469 switch (op
& 0x7) { /* MSB-3..MSB-5 */
13471 /* POOL32A, POOL32B, POOL32I, POOL32C */
13473 /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
13475 /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
13477 /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
13479 /* LB32, LH32, LWC132, LDC132, LW32 */
13480 if (ctx
->hflags
& MIPS_HFLAG_BDS16
) {
13481 generate_exception(ctx
, EXCP_RI
);
13482 /* Just stop translation; the user is confused. */
13483 ctx
->bstate
= BS_STOP
;
13488 /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
13490 /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
13492 /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
13493 if (ctx
->hflags
& MIPS_HFLAG_BDS32
) {
13494 generate_exception(ctx
, EXCP_RI
);
13495 /* Just stop translation; the user is confused. */
13496 ctx
->bstate
= BS_STOP
;
13506 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13507 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
13508 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
13511 switch (ctx
->opcode
& 0x1) {
13520 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
13525 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13526 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
13527 int amount
= (ctx
->opcode
>> 1) & 0x7;
13529 amount
= amount
== 0 ? 8 : amount
;
13531 switch (ctx
->opcode
& 0x1) {
13540 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
13544 gen_pool16c_insn(ctx
);
13548 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13549 int rb
= 28; /* GP */
13550 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
13552 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13556 if (ctx
->opcode
& 1) {
13557 generate_exception(ctx
, EXCP_RI
);
13560 int enc_dest
= uMIPS_RD(ctx
->opcode
);
13561 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
13562 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
13563 int rd
, rs
, re
, rt
;
13564 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13565 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13566 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13568 rd
= rd_enc
[enc_dest
];
13569 re
= re_enc
[enc_dest
];
13570 rs
= rs_rt_enc
[enc_rs
];
13571 rt
= rs_rt_enc
[enc_rt
];
13573 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
13574 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
13579 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13580 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13581 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
13582 offset
= (offset
== 0xf ? -1 : offset
);
13584 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
13589 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13590 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13591 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
13593 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
13598 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13599 int rb
= 29; /* SP */
13600 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
13602 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13607 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13608 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13609 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
13611 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13616 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13617 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13618 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
13620 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
13625 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13626 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13627 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
13629 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
13634 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13635 int rb
= 29; /* SP */
13636 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
13638 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
13643 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13644 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13645 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
13647 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
13652 int rd
= uMIPS_RD5(ctx
->opcode
);
13653 int rs
= uMIPS_RS5(ctx
->opcode
);
13655 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
13662 switch (ctx
->opcode
& 0x1) {
13672 switch (ctx
->opcode
& 0x1) {
13677 gen_addiur1sp(ctx
);
13682 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
13683 SIMM(ctx
->opcode
, 0, 10) << 1, 4);
13687 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
13688 mmreg(uMIPS_RD(ctx
->opcode
)),
13689 0, SIMM(ctx
->opcode
, 0, 7) << 1, 4);
13693 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
13694 int imm
= ZIMM(ctx
->opcode
, 0, 7);
13696 imm
= (imm
== 0x7f ? -1 : imm
);
13697 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
13707 generate_exception(ctx
, EXCP_RI
);
13710 decode_micromips32_opc (env
, ctx
, op
);
13717 /* SmartMIPS extension to MIPS32 */
13719 #if defined(TARGET_MIPS64)
13721 /* MDMX extension to MIPS64 */
13725 /* MIPSDSP functions. */
13726 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
13727 int rd
, int base
, int offset
)
13729 const char *opn
= "ldx";
13733 t0
= tcg_temp_new();
13736 gen_load_gpr(t0
, offset
);
13737 } else if (offset
== 0) {
13738 gen_load_gpr(t0
, base
);
13740 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
13745 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
13746 gen_store_gpr(t0
, rd
);
13750 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
13751 gen_store_gpr(t0
, rd
);
13755 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
13756 gen_store_gpr(t0
, rd
);
13759 #if defined(TARGET_MIPS64)
13761 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13762 gen_store_gpr(t0
, rd
);
13767 (void)opn
; /* avoid a compiler warning */
13768 MIPS_DEBUG("%s %s, %s(%s)", opn
,
13769 regnames
[rd
], regnames
[offset
], regnames
[base
]);
13773 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13774 int ret
, int v1
, int v2
)
13776 const char *opn
= "mipsdsp arith";
13781 /* Treat as NOP. */
13786 v1_t
= tcg_temp_new();
13787 v2_t
= tcg_temp_new();
13789 gen_load_gpr(v1_t
, v1
);
13790 gen_load_gpr(v2_t
, v2
);
13793 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
13794 case OPC_MULT_G_2E
:
13798 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13800 case OPC_ADDUH_R_QB
:
13801 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13804 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13806 case OPC_ADDQH_R_PH
:
13807 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13810 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13812 case OPC_ADDQH_R_W
:
13813 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13816 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13818 case OPC_SUBUH_R_QB
:
13819 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13822 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13824 case OPC_SUBQH_R_PH
:
13825 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13828 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13830 case OPC_SUBQH_R_W
:
13831 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13835 case OPC_ABSQ_S_PH_DSP
:
13837 case OPC_ABSQ_S_QB
:
13839 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
13841 case OPC_ABSQ_S_PH
:
13843 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
13847 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
13849 case OPC_PRECEQ_W_PHL
:
13851 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
13852 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13854 case OPC_PRECEQ_W_PHR
:
13856 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
13857 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
13858 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13860 case OPC_PRECEQU_PH_QBL
:
13862 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
13864 case OPC_PRECEQU_PH_QBR
:
13866 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
13868 case OPC_PRECEQU_PH_QBLA
:
13870 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
13872 case OPC_PRECEQU_PH_QBRA
:
13874 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
13876 case OPC_PRECEU_PH_QBL
:
13878 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
13880 case OPC_PRECEU_PH_QBR
:
13882 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
13884 case OPC_PRECEU_PH_QBLA
:
13886 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
13888 case OPC_PRECEU_PH_QBRA
:
13890 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
13894 case OPC_ADDU_QB_DSP
:
13898 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13900 case OPC_ADDQ_S_PH
:
13902 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13906 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13910 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13912 case OPC_ADDU_S_QB
:
13914 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13918 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13920 case OPC_ADDU_S_PH
:
13922 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13926 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13928 case OPC_SUBQ_S_PH
:
13930 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13934 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13938 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13940 case OPC_SUBU_S_QB
:
13942 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13946 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13948 case OPC_SUBU_S_PH
:
13950 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13954 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13958 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13962 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
13964 case OPC_RADDU_W_QB
:
13966 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
13970 case OPC_CMPU_EQ_QB_DSP
:
13972 case OPC_PRECR_QB_PH
:
13974 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13976 case OPC_PRECRQ_QB_PH
:
13978 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13980 case OPC_PRECR_SRA_PH_W
:
13983 TCGv_i32 sa_t
= tcg_const_i32(v2
);
13984 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
13986 tcg_temp_free_i32(sa_t
);
13989 case OPC_PRECR_SRA_R_PH_W
:
13992 TCGv_i32 sa_t
= tcg_const_i32(v2
);
13993 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
13995 tcg_temp_free_i32(sa_t
);
13998 case OPC_PRECRQ_PH_W
:
14000 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14002 case OPC_PRECRQ_RS_PH_W
:
14004 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14006 case OPC_PRECRQU_S_QB_PH
:
14008 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14012 #ifdef TARGET_MIPS64
14013 case OPC_ABSQ_S_QH_DSP
:
14015 case OPC_PRECEQ_L_PWL
:
14017 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
14019 case OPC_PRECEQ_L_PWR
:
14021 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
14023 case OPC_PRECEQ_PW_QHL
:
14025 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
14027 case OPC_PRECEQ_PW_QHR
:
14029 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
14031 case OPC_PRECEQ_PW_QHLA
:
14033 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
14035 case OPC_PRECEQ_PW_QHRA
:
14037 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
14039 case OPC_PRECEQU_QH_OBL
:
14041 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
14043 case OPC_PRECEQU_QH_OBR
:
14045 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
14047 case OPC_PRECEQU_QH_OBLA
:
14049 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
14051 case OPC_PRECEQU_QH_OBRA
:
14053 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
14055 case OPC_PRECEU_QH_OBL
:
14057 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
14059 case OPC_PRECEU_QH_OBR
:
14061 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
14063 case OPC_PRECEU_QH_OBLA
:
14065 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
14067 case OPC_PRECEU_QH_OBRA
:
14069 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
14071 case OPC_ABSQ_S_OB
:
14073 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
14075 case OPC_ABSQ_S_PW
:
14077 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
14079 case OPC_ABSQ_S_QH
:
14081 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
14085 case OPC_ADDU_OB_DSP
:
14087 case OPC_RADDU_L_OB
:
14089 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
14093 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14095 case OPC_SUBQ_S_PW
:
14097 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14101 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14103 case OPC_SUBQ_S_QH
:
14105 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14109 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14111 case OPC_SUBU_S_OB
:
14113 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14117 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14119 case OPC_SUBU_S_QH
:
14121 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14125 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14127 case OPC_SUBUH_R_OB
:
14129 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14133 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14135 case OPC_ADDQ_S_PW
:
14137 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14141 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14143 case OPC_ADDQ_S_QH
:
14145 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14149 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14151 case OPC_ADDU_S_OB
:
14153 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14157 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14159 case OPC_ADDU_S_QH
:
14161 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14165 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14167 case OPC_ADDUH_R_OB
:
14169 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14173 case OPC_CMPU_EQ_OB_DSP
:
14175 case OPC_PRECR_OB_QH
:
14177 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
14179 case OPC_PRECR_SRA_QH_PW
:
14182 TCGv_i32 ret_t
= tcg_const_i32(ret
);
14183 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
14184 tcg_temp_free_i32(ret_t
);
14187 case OPC_PRECR_SRA_R_QH_PW
:
14190 TCGv_i32 sa_v
= tcg_const_i32(ret
);
14191 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
14192 tcg_temp_free_i32(sa_v
);
14195 case OPC_PRECRQ_OB_QH
:
14197 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
14199 case OPC_PRECRQ_PW_L
:
14201 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
14203 case OPC_PRECRQ_QH_PW
:
14205 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14207 case OPC_PRECRQ_RS_QH_PW
:
14209 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14211 case OPC_PRECRQU_S_OB_QH
:
14213 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14220 tcg_temp_free(v1_t
);
14221 tcg_temp_free(v2_t
);
14223 (void)opn
; /* avoid a compiler warning */
14224 MIPS_DEBUG("%s", opn
);
14227 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
14228 int ret
, int v1
, int v2
)
14231 const char *opn
= "mipsdsp shift";
14237 /* Treat as NOP. */
14242 t0
= tcg_temp_new();
14243 v1_t
= tcg_temp_new();
14244 v2_t
= tcg_temp_new();
14246 tcg_gen_movi_tl(t0
, v1
);
14247 gen_load_gpr(v1_t
, v1
);
14248 gen_load_gpr(v2_t
, v2
);
14251 case OPC_SHLL_QB_DSP
:
14253 op2
= MASK_SHLL_QB(ctx
->opcode
);
14257 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14261 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14265 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14269 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14271 case OPC_SHLL_S_PH
:
14273 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14275 case OPC_SHLLV_S_PH
:
14277 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14281 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14283 case OPC_SHLLV_S_W
:
14285 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14289 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
14293 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14297 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
14301 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14305 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
14307 case OPC_SHRA_R_QB
:
14309 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
14313 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14315 case OPC_SHRAV_R_QB
:
14317 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14321 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
14323 case OPC_SHRA_R_PH
:
14325 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
14329 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14331 case OPC_SHRAV_R_PH
:
14333 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14337 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
14339 case OPC_SHRAV_R_W
:
14341 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14343 default: /* Invalid */
14344 MIPS_INVAL("MASK SHLL.QB");
14345 generate_exception(ctx
, EXCP_RI
);
14350 #ifdef TARGET_MIPS64
14351 case OPC_SHLL_OB_DSP
:
14352 op2
= MASK_SHLL_OB(ctx
->opcode
);
14356 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14360 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14362 case OPC_SHLL_S_PW
:
14364 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14366 case OPC_SHLLV_S_PW
:
14368 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14372 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14376 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14380 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14384 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14386 case OPC_SHLL_S_QH
:
14388 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14390 case OPC_SHLLV_S_QH
:
14392 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14396 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
14400 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14402 case OPC_SHRA_R_OB
:
14404 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
14406 case OPC_SHRAV_R_OB
:
14408 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14412 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
14416 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
14418 case OPC_SHRA_R_PW
:
14420 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
14422 case OPC_SHRAV_R_PW
:
14424 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
14428 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
14432 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14434 case OPC_SHRA_R_QH
:
14436 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
14438 case OPC_SHRAV_R_QH
:
14440 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14444 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
14448 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14452 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
14456 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14458 default: /* Invalid */
14459 MIPS_INVAL("MASK SHLL.OB");
14460 generate_exception(ctx
, EXCP_RI
);
14468 tcg_temp_free(v1_t
);
14469 tcg_temp_free(v2_t
);
14470 (void)opn
; /* avoid a compiler warning */
14471 MIPS_DEBUG("%s", opn
);
14474 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14475 int ret
, int v1
, int v2
, int check_ret
)
14477 const char *opn
= "mipsdsp multiply";
14482 if ((ret
== 0) && (check_ret
== 1)) {
14483 /* Treat as NOP. */
14488 t0
= tcg_temp_new_i32();
14489 v1_t
= tcg_temp_new();
14490 v2_t
= tcg_temp_new();
14492 tcg_gen_movi_i32(t0
, ret
);
14493 gen_load_gpr(v1_t
, v1
);
14494 gen_load_gpr(v2_t
, v2
);
14497 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14498 * the same mask and op1. */
14499 case OPC_MULT_G_2E
:
14503 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14506 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14509 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14511 case OPC_MULQ_RS_W
:
14512 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14516 case OPC_DPA_W_PH_DSP
:
14518 case OPC_DPAU_H_QBL
:
14520 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
14522 case OPC_DPAU_H_QBR
:
14524 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
14526 case OPC_DPSU_H_QBL
:
14528 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
14530 case OPC_DPSU_H_QBR
:
14532 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
14536 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14538 case OPC_DPAX_W_PH
:
14540 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14542 case OPC_DPAQ_S_W_PH
:
14544 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14546 case OPC_DPAQX_S_W_PH
:
14548 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14550 case OPC_DPAQX_SA_W_PH
:
14552 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14556 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14558 case OPC_DPSX_W_PH
:
14560 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14562 case OPC_DPSQ_S_W_PH
:
14564 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14566 case OPC_DPSQX_S_W_PH
:
14568 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14570 case OPC_DPSQX_SA_W_PH
:
14572 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14574 case OPC_MULSAQ_S_W_PH
:
14576 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14578 case OPC_DPAQ_SA_L_W
:
14580 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
14582 case OPC_DPSQ_SA_L_W
:
14584 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
14586 case OPC_MAQ_S_W_PHL
:
14588 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
14590 case OPC_MAQ_S_W_PHR
:
14592 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
14594 case OPC_MAQ_SA_W_PHL
:
14596 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
14598 case OPC_MAQ_SA_W_PHR
:
14600 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
14602 case OPC_MULSA_W_PH
:
14604 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14608 #ifdef TARGET_MIPS64
14609 case OPC_DPAQ_W_QH_DSP
:
14611 int ac
= ret
& 0x03;
14612 tcg_gen_movi_i32(t0
, ac
);
14617 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
14621 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
14625 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
14629 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
14633 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14635 case OPC_DPAQ_S_W_QH
:
14637 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14639 case OPC_DPAQ_SA_L_PW
:
14641 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
14643 case OPC_DPAU_H_OBL
:
14645 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
14647 case OPC_DPAU_H_OBR
:
14649 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
14653 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14655 case OPC_DPSQ_S_W_QH
:
14657 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14659 case OPC_DPSQ_SA_L_PW
:
14661 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
14663 case OPC_DPSU_H_OBL
:
14665 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
14667 case OPC_DPSU_H_OBR
:
14669 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
14671 case OPC_MAQ_S_L_PWL
:
14673 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
14675 case OPC_MAQ_S_L_PWR
:
14677 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
14679 case OPC_MAQ_S_W_QHLL
:
14681 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
14683 case OPC_MAQ_SA_W_QHLL
:
14685 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
14687 case OPC_MAQ_S_W_QHLR
:
14689 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
14691 case OPC_MAQ_SA_W_QHLR
:
14693 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
14695 case OPC_MAQ_S_W_QHRL
:
14697 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
14699 case OPC_MAQ_SA_W_QHRL
:
14701 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
14703 case OPC_MAQ_S_W_QHRR
:
14705 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
14707 case OPC_MAQ_SA_W_QHRR
:
14709 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
14711 case OPC_MULSAQ_S_L_PW
:
14713 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
14715 case OPC_MULSAQ_S_W_QH
:
14717 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14723 case OPC_ADDU_QB_DSP
:
14725 case OPC_MULEU_S_PH_QBL
:
14727 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14729 case OPC_MULEU_S_PH_QBR
:
14731 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14733 case OPC_MULQ_RS_PH
:
14735 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14737 case OPC_MULEQ_S_W_PHL
:
14739 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14741 case OPC_MULEQ_S_W_PHR
:
14743 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14745 case OPC_MULQ_S_PH
:
14747 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14751 #ifdef TARGET_MIPS64
14752 case OPC_ADDU_OB_DSP
:
14754 case OPC_MULEQ_S_PW_QHL
:
14756 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14758 case OPC_MULEQ_S_PW_QHR
:
14760 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14762 case OPC_MULEU_S_QH_OBL
:
14764 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14766 case OPC_MULEU_S_QH_OBR
:
14768 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14770 case OPC_MULQ_RS_QH
:
14772 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14779 tcg_temp_free_i32(t0
);
14780 tcg_temp_free(v1_t
);
14781 tcg_temp_free(v2_t
);
14783 (void)opn
; /* avoid a compiler warning */
14784 MIPS_DEBUG("%s", opn
);
14788 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14791 const char *opn
= "mipsdsp Bit/ Manipulation";
14797 /* Treat as NOP. */
14802 t0
= tcg_temp_new();
14803 val_t
= tcg_temp_new();
14804 gen_load_gpr(val_t
, val
);
14807 case OPC_ABSQ_S_PH_DSP
:
14811 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
14816 target_long result
;
14817 imm
= (ctx
->opcode
>> 16) & 0xFF;
14818 result
= (uint32_t)imm
<< 24 |
14819 (uint32_t)imm
<< 16 |
14820 (uint32_t)imm
<< 8 |
14822 result
= (int32_t)result
;
14823 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
14828 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
14829 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
14830 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14831 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14832 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14833 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
14838 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14839 imm
= (int16_t)(imm
<< 6) >> 6;
14840 tcg_gen_movi_tl(cpu_gpr
[ret
], \
14841 (target_long
)((int32_t)imm
<< 16 | \
14847 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
14848 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14849 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14850 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
14854 #ifdef TARGET_MIPS64
14855 case OPC_ABSQ_S_QH_DSP
:
14862 imm
= (ctx
->opcode
>> 16) & 0xFF;
14863 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
14864 temp
= (temp
<< 16) | temp
;
14865 temp
= (temp
<< 32) | temp
;
14866 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
14874 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14875 imm
= (int16_t)(imm
<< 6) >> 6;
14876 temp
= ((target_long
)imm
<< 32) \
14877 | ((target_long
)imm
& 0xFFFFFFFF);
14878 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
14886 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14887 imm
= (int16_t)(imm
<< 6) >> 6;
14889 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
14890 ((uint64_t)(uint16_t)imm
<< 32) |
14891 ((uint64_t)(uint16_t)imm
<< 16) |
14892 (uint64_t)(uint16_t)imm
;
14893 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
14898 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
14899 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
14900 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14901 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14902 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14903 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
14904 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14908 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
14909 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
14910 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14914 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
14915 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14916 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14917 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
14918 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14925 tcg_temp_free(val_t
);
14927 (void)opn
; /* avoid a compiler warning */
14928 MIPS_DEBUG("%s", opn
);
14931 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
14932 uint32_t op1
, uint32_t op2
,
14933 int ret
, int v1
, int v2
, int check_ret
)
14935 const char *opn
= "mipsdsp add compare pick";
14940 if ((ret
== 0) && (check_ret
== 1)) {
14941 /* Treat as NOP. */
14946 t1
= tcg_temp_new();
14947 v1_t
= tcg_temp_new();
14948 v2_t
= tcg_temp_new();
14950 gen_load_gpr(v1_t
, v1
);
14951 gen_load_gpr(v2_t
, v2
);
14954 case OPC_CMPU_EQ_QB_DSP
:
14956 case OPC_CMPU_EQ_QB
:
14958 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
14960 case OPC_CMPU_LT_QB
:
14962 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
14964 case OPC_CMPU_LE_QB
:
14966 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
14968 case OPC_CMPGU_EQ_QB
:
14970 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14972 case OPC_CMPGU_LT_QB
:
14974 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14976 case OPC_CMPGU_LE_QB
:
14978 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14980 case OPC_CMPGDU_EQ_QB
:
14982 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
14983 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14984 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
14985 tcg_gen_shli_tl(t1
, t1
, 24);
14986 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14988 case OPC_CMPGDU_LT_QB
:
14990 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
14991 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14992 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
14993 tcg_gen_shli_tl(t1
, t1
, 24);
14994 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14996 case OPC_CMPGDU_LE_QB
:
14998 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
14999 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
15000 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
15001 tcg_gen_shli_tl(t1
, t1
, 24);
15002 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
15004 case OPC_CMP_EQ_PH
:
15006 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
15008 case OPC_CMP_LT_PH
:
15010 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
15012 case OPC_CMP_LE_PH
:
15014 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
15018 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15022 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15024 case OPC_PACKRL_PH
:
15026 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15030 #ifdef TARGET_MIPS64
15031 case OPC_CMPU_EQ_OB_DSP
:
15033 case OPC_CMP_EQ_PW
:
15035 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
15037 case OPC_CMP_LT_PW
:
15039 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
15041 case OPC_CMP_LE_PW
:
15043 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
15045 case OPC_CMP_EQ_QH
:
15047 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
15049 case OPC_CMP_LT_QH
:
15051 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
15053 case OPC_CMP_LE_QH
:
15055 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
15057 case OPC_CMPGDU_EQ_OB
:
15059 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15061 case OPC_CMPGDU_LT_OB
:
15063 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15065 case OPC_CMPGDU_LE_OB
:
15067 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15069 case OPC_CMPGU_EQ_OB
:
15071 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15073 case OPC_CMPGU_LT_OB
:
15075 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15077 case OPC_CMPGU_LE_OB
:
15079 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15081 case OPC_CMPU_EQ_OB
:
15083 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
15085 case OPC_CMPU_LT_OB
:
15087 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
15089 case OPC_CMPU_LE_OB
:
15091 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
15093 case OPC_PACKRL_PW
:
15095 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
15099 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15103 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15107 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15115 tcg_temp_free(v1_t
);
15116 tcg_temp_free(v2_t
);
15118 (void)opn
; /* avoid a compiler warning */
15119 MIPS_DEBUG("%s", opn
);
15122 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
15123 uint32_t op1
, int rt
, int rs
, int sa
)
15125 const char *opn
= "mipsdsp append/dappend";
15131 /* Treat as NOP. */
15136 t0
= tcg_temp_new();
15137 gen_load_gpr(t0
, rs
);
15140 case OPC_APPEND_DSP
:
15141 switch (MASK_APPEND(ctx
->opcode
)) {
15144 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
15146 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15150 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15151 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
15152 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
15153 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15155 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15159 if (sa
!= 0 && sa
!= 2) {
15160 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
15161 tcg_gen_ext32u_tl(t0
, t0
);
15162 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
15163 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15165 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15167 default: /* Invalid */
15168 MIPS_INVAL("MASK APPEND");
15169 generate_exception(ctx
, EXCP_RI
);
15173 #ifdef TARGET_MIPS64
15174 case OPC_DAPPEND_DSP
:
15175 switch (MASK_DAPPEND(ctx
->opcode
)) {
15178 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
15182 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
15183 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
15184 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
15188 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
15189 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
15190 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15195 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
15196 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
15197 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
15198 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15201 default: /* Invalid */
15202 MIPS_INVAL("MASK DAPPEND");
15203 generate_exception(ctx
, EXCP_RI
);
15210 (void)opn
; /* avoid a compiler warning */
15211 MIPS_DEBUG("%s", opn
);
15214 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15215 int ret
, int v1
, int v2
, int check_ret
)
15218 const char *opn
= "mipsdsp accumulator";
15225 if ((ret
== 0) && (check_ret
== 1)) {
15226 /* Treat as NOP. */
15231 t0
= tcg_temp_new();
15232 t1
= tcg_temp_new();
15233 v1_t
= tcg_temp_new();
15234 v2_t
= tcg_temp_new();
15236 gen_load_gpr(v1_t
, v1
);
15237 gen_load_gpr(v2_t
, v2
);
15240 case OPC_EXTR_W_DSP
:
15244 tcg_gen_movi_tl(t0
, v2
);
15245 tcg_gen_movi_tl(t1
, v1
);
15246 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15249 tcg_gen_movi_tl(t0
, v2
);
15250 tcg_gen_movi_tl(t1
, v1
);
15251 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15253 case OPC_EXTR_RS_W
:
15254 tcg_gen_movi_tl(t0
, v2
);
15255 tcg_gen_movi_tl(t1
, v1
);
15256 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15259 tcg_gen_movi_tl(t0
, v2
);
15260 tcg_gen_movi_tl(t1
, v1
);
15261 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15263 case OPC_EXTRV_S_H
:
15264 tcg_gen_movi_tl(t0
, v2
);
15265 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15268 tcg_gen_movi_tl(t0
, v2
);
15269 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15271 case OPC_EXTRV_R_W
:
15272 tcg_gen_movi_tl(t0
, v2
);
15273 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15275 case OPC_EXTRV_RS_W
:
15276 tcg_gen_movi_tl(t0
, v2
);
15277 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15280 tcg_gen_movi_tl(t0
, v2
);
15281 tcg_gen_movi_tl(t1
, v1
);
15282 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15285 tcg_gen_movi_tl(t0
, v2
);
15286 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15289 tcg_gen_movi_tl(t0
, v2
);
15290 tcg_gen_movi_tl(t1
, v1
);
15291 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15294 tcg_gen_movi_tl(t0
, v2
);
15295 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15298 imm
= (ctx
->opcode
>> 20) & 0x3F;
15299 tcg_gen_movi_tl(t0
, ret
);
15300 tcg_gen_movi_tl(t1
, imm
);
15301 gen_helper_shilo(t0
, t1
, cpu_env
);
15304 tcg_gen_movi_tl(t0
, ret
);
15305 gen_helper_shilo(t0
, v1_t
, cpu_env
);
15308 tcg_gen_movi_tl(t0
, ret
);
15309 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
15312 imm
= (ctx
->opcode
>> 11) & 0x3FF;
15313 tcg_gen_movi_tl(t0
, imm
);
15314 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
15317 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15318 tcg_gen_movi_tl(t0
, imm
);
15319 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
15323 #ifdef TARGET_MIPS64
15324 case OPC_DEXTR_W_DSP
:
15328 tcg_gen_movi_tl(t0
, ret
);
15329 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
15333 int shift
= (ctx
->opcode
>> 19) & 0x7F;
15334 int ac
= (ctx
->opcode
>> 11) & 0x03;
15335 tcg_gen_movi_tl(t0
, shift
);
15336 tcg_gen_movi_tl(t1
, ac
);
15337 gen_helper_dshilo(t0
, t1
, cpu_env
);
15342 int ac
= (ctx
->opcode
>> 11) & 0x03;
15343 tcg_gen_movi_tl(t0
, ac
);
15344 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
15348 tcg_gen_movi_tl(t0
, v2
);
15349 tcg_gen_movi_tl(t1
, v1
);
15351 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15354 tcg_gen_movi_tl(t0
, v2
);
15355 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15358 tcg_gen_movi_tl(t0
, v2
);
15359 tcg_gen_movi_tl(t1
, v1
);
15360 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15363 tcg_gen_movi_tl(t0
, v2
);
15364 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15367 tcg_gen_movi_tl(t0
, v2
);
15368 tcg_gen_movi_tl(t1
, v1
);
15369 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15371 case OPC_DEXTR_R_L
:
15372 tcg_gen_movi_tl(t0
, v2
);
15373 tcg_gen_movi_tl(t1
, v1
);
15374 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15376 case OPC_DEXTR_RS_L
:
15377 tcg_gen_movi_tl(t0
, v2
);
15378 tcg_gen_movi_tl(t1
, v1
);
15379 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15382 tcg_gen_movi_tl(t0
, v2
);
15383 tcg_gen_movi_tl(t1
, v1
);
15384 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15386 case OPC_DEXTR_R_W
:
15387 tcg_gen_movi_tl(t0
, v2
);
15388 tcg_gen_movi_tl(t1
, v1
);
15389 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15391 case OPC_DEXTR_RS_W
:
15392 tcg_gen_movi_tl(t0
, v2
);
15393 tcg_gen_movi_tl(t1
, v1
);
15394 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15396 case OPC_DEXTR_S_H
:
15397 tcg_gen_movi_tl(t0
, v2
);
15398 tcg_gen_movi_tl(t1
, v1
);
15399 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15401 case OPC_DEXTRV_S_H
:
15402 tcg_gen_movi_tl(t0
, v2
);
15403 tcg_gen_movi_tl(t1
, v1
);
15404 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15407 tcg_gen_movi_tl(t0
, v2
);
15408 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15410 case OPC_DEXTRV_R_L
:
15411 tcg_gen_movi_tl(t0
, v2
);
15412 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15414 case OPC_DEXTRV_RS_L
:
15415 tcg_gen_movi_tl(t0
, v2
);
15416 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15419 tcg_gen_movi_tl(t0
, v2
);
15420 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15422 case OPC_DEXTRV_R_W
:
15423 tcg_gen_movi_tl(t0
, v2
);
15424 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15426 case OPC_DEXTRV_RS_W
:
15427 tcg_gen_movi_tl(t0
, v2
);
15428 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15437 tcg_temp_free(v1_t
);
15438 tcg_temp_free(v2_t
);
15440 (void)opn
; /* avoid a compiler warning */
15441 MIPS_DEBUG("%s", opn
);
15444 /* End MIPSDSP functions. */
15446 /* Compact Branches */
15447 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
15448 int rs
, int rt
, int32_t offset
)
15450 int bcond_compute
= 0;
15451 TCGv t0
= tcg_temp_new();
15452 TCGv t1
= tcg_temp_new();
15454 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15455 #ifdef MIPS_DEBUG_DISAS
15456 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
15458 generate_exception(ctx
, EXCP_RI
);
15462 /* Load needed operands and calculate btarget */
15464 /* compact branch */
15465 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
15466 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
15467 gen_load_gpr(t0
, rs
);
15468 gen_load_gpr(t1
, rt
);
15470 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15471 if (rs
<= rt
&& rs
== 0) {
15472 /* OPC_BEQZALC, OPC_BNEZALC */
15473 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15476 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
15477 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
15478 gen_load_gpr(t0
, rs
);
15479 gen_load_gpr(t1
, rt
);
15481 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15483 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
15484 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
15485 if (rs
== 0 || rs
== rt
) {
15486 /* OPC_BLEZALC, OPC_BGEZALC */
15487 /* OPC_BGTZALC, OPC_BLTZALC */
15488 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15490 gen_load_gpr(t0
, rs
);
15491 gen_load_gpr(t1
, rt
);
15493 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15497 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15502 /* OPC_BEQZC, OPC_BNEZC */
15503 gen_load_gpr(t0
, rs
);
15505 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15507 /* OPC_JIC, OPC_JIALC */
15508 TCGv tbase
= tcg_temp_new();
15509 TCGv toffset
= tcg_temp_new();
15511 gen_load_gpr(tbase
, rt
);
15512 tcg_gen_movi_tl(toffset
, offset
);
15513 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
15514 tcg_temp_free(tbase
);
15515 tcg_temp_free(toffset
);
15519 MIPS_INVAL("Compact branch/jump");
15520 generate_exception(ctx
, EXCP_RI
);
15524 if (bcond_compute
== 0) {
15525 /* Uncoditional compact branch */
15528 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15531 ctx
->hflags
|= MIPS_HFLAG_BR
;
15534 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15537 ctx
->hflags
|= MIPS_HFLAG_B
;
15540 MIPS_INVAL("Compact branch/jump");
15541 generate_exception(ctx
, EXCP_RI
);
15545 /* Generating branch here as compact branches don't have delay slot */
15546 gen_branch(ctx
, 4);
15548 /* Conditional compact branch */
15549 int l1
= gen_new_label();
15550 save_cpu_state(ctx
, 0);
15553 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
15554 if (rs
== 0 && rt
!= 0) {
15556 tcg_gen_brcondi_tl(TCG_COND_LE
, t1
, 0, l1
);
15557 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15559 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
15562 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
15565 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
15566 if (rs
== 0 && rt
!= 0) {
15568 tcg_gen_brcondi_tl(TCG_COND_GT
, t1
, 0, l1
);
15569 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15571 tcg_gen_brcondi_tl(TCG_COND_LT
, t1
, 0, l1
);
15574 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
15577 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
15578 if (rs
== 0 && rt
!= 0) {
15580 tcg_gen_brcondi_tl(TCG_COND_LE
, t1
, 0, l1
);
15581 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15583 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
15586 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
15589 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
15590 if (rs
== 0 && rt
!= 0) {
15592 tcg_gen_brcondi_tl(TCG_COND_GT
, t1
, 0, l1
);
15593 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15595 tcg_gen_brcondi_tl(TCG_COND_LT
, t1
, 0, l1
);
15598 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
15601 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
15602 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
15604 /* OPC_BOVC, OPC_BNVC */
15605 TCGv t2
= tcg_temp_new();
15606 TCGv t3
= tcg_temp_new();
15607 TCGv t4
= tcg_temp_new();
15608 TCGv input_overflow
= tcg_temp_new();
15610 gen_load_gpr(t0
, rs
);
15611 gen_load_gpr(t1
, rt
);
15612 tcg_gen_ext32s_tl(t2
, t0
);
15613 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
15614 tcg_gen_ext32s_tl(t3
, t1
);
15615 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
15616 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
15618 tcg_gen_add_tl(t4
, t2
, t3
);
15619 tcg_gen_ext32s_tl(t4
, t4
);
15620 tcg_gen_xor_tl(t2
, t2
, t3
);
15621 tcg_gen_xor_tl(t3
, t4
, t3
);
15622 tcg_gen_andc_tl(t2
, t3
, t2
);
15623 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
15624 tcg_gen_or_tl(t4
, t4
, input_overflow
);
15625 if (opc
== OPC_BOVC
) {
15627 tcg_gen_brcondi_tl(TCG_COND_NE
, t4
, 0, l1
);
15630 tcg_gen_brcondi_tl(TCG_COND_EQ
, t4
, 0, l1
);
15632 tcg_temp_free(input_overflow
);
15636 } else if (rs
< rt
&& rs
== 0) {
15637 /* OPC_BEQZALC, OPC_BNEZALC */
15638 if (opc
== OPC_BEQZALC
) {
15640 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
15643 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
15646 /* OPC_BEQC, OPC_BNEC */
15647 if (opc
== OPC_BEQC
) {
15649 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
15652 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
15657 tcg_gen_brcondi_tl(TCG_COND_EQ
, t0
, 0, l1
);
15660 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
15663 MIPS_INVAL("Compact conditional branch/jump");
15664 generate_exception(ctx
, EXCP_RI
);
15668 /* Generating branch here as compact branches don't have delay slot */
15669 /* TODO: implement forbidden slot */
15670 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
15672 gen_goto_tb(ctx
, 0, ctx
->btarget
);
15673 MIPS_DEBUG("Compact conditional branch");
15674 ctx
->bstate
= BS_BRANCH
;
15682 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
15684 int rs
, rt
, rd
, sa
;
15687 rs
= (ctx
->opcode
>> 21) & 0x1f;
15688 rt
= (ctx
->opcode
>> 16) & 0x1f;
15689 rd
= (ctx
->opcode
>> 11) & 0x1f;
15690 sa
= (ctx
->opcode
>> 6) & 0x1f;
15692 op1
= MASK_SPECIAL(ctx
->opcode
);
15696 int imm2
= extract32(ctx
->opcode
, 6, 3);
15697 TCGv t0
= tcg_temp_new();
15698 TCGv t1
= tcg_temp_new();
15699 gen_load_gpr(t0
, rs
);
15700 gen_load_gpr(t1
, rt
);
15701 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
15702 tcg_gen_add_tl(t0
, t0
, t1
);
15703 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
15708 case OPC_MULT
... OPC_DIVU
:
15709 op2
= MASK_R6_MULDIV(ctx
->opcode
);
15719 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
15722 MIPS_INVAL("special_r6 muldiv");
15723 generate_exception(ctx
, EXCP_RI
);
15729 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
15733 if (rt
== 0 && sa
== 1) {
15734 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15735 We need additionally to check other fields */
15736 gen_cl(ctx
, op1
, rd
, rs
);
15738 generate_exception(ctx
, EXCP_RI
);
15742 generate_exception(ctx
, EXCP_DBp
);
15744 #if defined(TARGET_MIPS64)
15746 check_mips_64(ctx
);
15748 int imm2
= extract32(ctx
->opcode
, 6, 3);
15749 TCGv t0
= tcg_temp_new();
15750 TCGv t1
= tcg_temp_new();
15751 gen_load_gpr(t0
, rs
);
15752 gen_load_gpr(t1
, rt
);
15753 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
15754 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
15761 if (rt
== 0 && sa
== 1) {
15762 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15763 We need additionally to check other fields */
15764 check_mips_64(ctx
);
15765 gen_cl(ctx
, op1
, rd
, rs
);
15767 generate_exception(ctx
, EXCP_RI
);
15770 case OPC_DMULT
... OPC_DDIVU
:
15771 op2
= MASK_R6_MULDIV(ctx
->opcode
);
15781 check_mips_64(ctx
);
15782 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
15785 MIPS_INVAL("special_r6 muldiv");
15786 generate_exception(ctx
, EXCP_RI
);
15791 default: /* Invalid */
15792 MIPS_INVAL("special_r6");
15793 generate_exception(ctx
, EXCP_RI
);
15798 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
15800 int rs
, rt
, rd
, sa
;
15803 rs
= (ctx
->opcode
>> 21) & 0x1f;
15804 rt
= (ctx
->opcode
>> 16) & 0x1f;
15805 rd
= (ctx
->opcode
>> 11) & 0x1f;
15806 sa
= (ctx
->opcode
>> 6) & 0x1f;
15808 op1
= MASK_SPECIAL(ctx
->opcode
);
15810 case OPC_MOVN
: /* Conditional move */
15812 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
15813 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
15814 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
15816 case OPC_MFHI
: /* Move from HI/LO */
15818 gen_HILO(ctx
, op1
, rs
& 3, rd
);
15821 case OPC_MTLO
: /* Move to HI/LO */
15822 gen_HILO(ctx
, op1
, rd
& 3, rs
);
15825 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15826 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15827 check_cp1_enabled(ctx
);
15828 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
15829 (ctx
->opcode
>> 16) & 1);
15831 generate_exception_err(ctx
, EXCP_CpU
, 1);
15837 check_insn(ctx
, INSN_VR54XX
);
15838 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
15839 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
15841 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
15846 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
15848 #if defined(TARGET_MIPS64)
15849 case OPC_DMULT
... OPC_DDIVU
:
15850 check_insn(ctx
, ISA_MIPS3
);
15851 check_mips_64(ctx
);
15852 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
15856 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
15859 #ifdef MIPS_STRICT_STANDARD
15860 MIPS_INVAL("SPIM");
15861 generate_exception(ctx
, EXCP_RI
);
15863 /* Implemented as RI exception for now. */
15864 MIPS_INVAL("spim (unofficial)");
15865 generate_exception(ctx
, EXCP_RI
);
15868 default: /* Invalid */
15869 MIPS_INVAL("special_legacy");
15870 generate_exception(ctx
, EXCP_RI
);
15875 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
15877 int rs
, rt
, rd
, sa
;
15880 rs
= (ctx
->opcode
>> 21) & 0x1f;
15881 rt
= (ctx
->opcode
>> 16) & 0x1f;
15882 rd
= (ctx
->opcode
>> 11) & 0x1f;
15883 sa
= (ctx
->opcode
>> 6) & 0x1f;
15885 op1
= MASK_SPECIAL(ctx
->opcode
);
15887 case OPC_SLL
: /* Shift with immediate */
15889 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15892 switch ((ctx
->opcode
>> 21) & 0x1f) {
15894 /* rotr is decoded as srl on non-R2 CPUs */
15895 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15900 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15903 generate_exception(ctx
, EXCP_RI
);
15907 case OPC_ADD
... OPC_SUBU
:
15908 gen_arith(ctx
, op1
, rd
, rs
, rt
);
15910 case OPC_SLLV
: /* Shifts */
15912 gen_shift(ctx
, op1
, rd
, rs
, rt
);
15915 switch ((ctx
->opcode
>> 6) & 0x1f) {
15917 /* rotrv is decoded as srlv on non-R2 CPUs */
15918 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15923 gen_shift(ctx
, op1
, rd
, rs
, rt
);
15926 generate_exception(ctx
, EXCP_RI
);
15930 case OPC_SLT
: /* Set on less than */
15932 gen_slt(ctx
, op1
, rd
, rs
, rt
);
15934 case OPC_AND
: /* Logic*/
15938 gen_logic(ctx
, op1
, rd
, rs
, rt
);
15941 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
, 4);
15943 case OPC_TGE
... OPC_TEQ
: /* Traps */
15945 gen_trap(ctx
, op1
, rs
, rt
, -1);
15947 case OPC_LSA
: /* OPC_PMON */
15948 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15949 decode_opc_special_r6(env
, ctx
);
15951 /* Pmon entry point, also R4010 selsl */
15952 #ifdef MIPS_STRICT_STANDARD
15953 MIPS_INVAL("PMON / selsl");
15954 generate_exception(ctx
, EXCP_RI
);
15956 gen_helper_0e0i(pmon
, sa
);
15961 generate_exception(ctx
, EXCP_SYSCALL
);
15962 ctx
->bstate
= BS_STOP
;
15965 generate_exception(ctx
, EXCP_BREAK
);
15968 /* Treat as NOP. */
15971 #if defined(TARGET_MIPS64)
15972 /* MIPS64 specific opcodes */
15977 check_insn(ctx
, ISA_MIPS3
);
15978 check_mips_64(ctx
);
15979 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15982 switch ((ctx
->opcode
>> 21) & 0x1f) {
15984 /* drotr is decoded as dsrl on non-R2 CPUs */
15985 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15990 check_insn(ctx
, ISA_MIPS3
);
15991 check_mips_64(ctx
);
15992 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15995 generate_exception(ctx
, EXCP_RI
);
16000 switch ((ctx
->opcode
>> 21) & 0x1f) {
16002 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
16003 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16008 check_insn(ctx
, ISA_MIPS3
);
16009 check_mips_64(ctx
);
16010 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16013 generate_exception(ctx
, EXCP_RI
);
16017 case OPC_DADD
... OPC_DSUBU
:
16018 check_insn(ctx
, ISA_MIPS3
);
16019 check_mips_64(ctx
);
16020 gen_arith(ctx
, op1
, rd
, rs
, rt
);
16024 check_insn(ctx
, ISA_MIPS3
);
16025 check_mips_64(ctx
);
16026 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16029 switch ((ctx
->opcode
>> 6) & 0x1f) {
16031 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16032 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16037 check_insn(ctx
, ISA_MIPS3
);
16038 check_mips_64(ctx
);
16039 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16042 generate_exception(ctx
, EXCP_RI
);
16048 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16049 decode_opc_special_r6(env
, ctx
);
16051 decode_opc_special_legacy(env
, ctx
);
16056 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16061 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16063 rs
= (ctx
->opcode
>> 21) & 0x1f;
16064 rt
= (ctx
->opcode
>> 16) & 0x1f;
16065 rd
= (ctx
->opcode
>> 11) & 0x1f;
16067 op1
= MASK_SPECIAL2(ctx
->opcode
);
16069 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
16070 case OPC_MSUB
... OPC_MSUBU
:
16071 check_insn(ctx
, ISA_MIPS32
);
16072 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
16075 gen_arith(ctx
, op1
, rd
, rs
, rt
);
16078 case OPC_DIVU_G_2F
:
16079 case OPC_MULT_G_2F
:
16080 case OPC_MULTU_G_2F
:
16082 case OPC_MODU_G_2F
:
16083 check_insn(ctx
, INSN_LOONGSON2F
);
16084 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16088 check_insn(ctx
, ISA_MIPS32
);
16089 gen_cl(ctx
, op1
, rd
, rs
);
16092 /* XXX: not clear which exception should be raised
16093 * when in debug mode...
16095 check_insn(ctx
, ISA_MIPS32
);
16096 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
16097 generate_exception(ctx
, EXCP_DBp
);
16099 generate_exception(ctx
, EXCP_DBp
);
16101 /* Treat as NOP. */
16103 #if defined(TARGET_MIPS64)
16106 check_insn(ctx
, ISA_MIPS64
);
16107 check_mips_64(ctx
);
16108 gen_cl(ctx
, op1
, rd
, rs
);
16110 case OPC_DMULT_G_2F
:
16111 case OPC_DMULTU_G_2F
:
16112 case OPC_DDIV_G_2F
:
16113 case OPC_DDIVU_G_2F
:
16114 case OPC_DMOD_G_2F
:
16115 case OPC_DMODU_G_2F
:
16116 check_insn(ctx
, INSN_LOONGSON2F
);
16117 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16120 default: /* Invalid */
16121 MIPS_INVAL("special2_legacy");
16122 generate_exception(ctx
, EXCP_RI
);
16127 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
16129 int rs
, rt
, rd
, sa
;
16133 rs
= (ctx
->opcode
>> 21) & 0x1f;
16134 rt
= (ctx
->opcode
>> 16) & 0x1f;
16135 rd
= (ctx
->opcode
>> 11) & 0x1f;
16136 sa
= (ctx
->opcode
>> 6) & 0x1f;
16137 imm
= (int16_t)ctx
->opcode
>> 7;
16139 op1
= MASK_SPECIAL3(ctx
->opcode
);
16143 /* hint codes 24-31 are reserved and signal RI */
16144 generate_exception(ctx
, EXCP_RI
);
16146 /* Treat as NOP. */
16149 /* Treat as NOP. */
16152 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
16155 gen_ld(ctx
, op1
, rt
, rs
, imm
);
16160 /* Treat as NOP. */
16163 TCGv t0
= tcg_temp_new();
16164 gen_load_gpr(t0
, rt
);
16166 op2
= MASK_BSHFL(ctx
->opcode
);
16168 case OPC_ALIGN
... OPC_ALIGN_END
:
16171 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
16173 TCGv t1
= tcg_temp_new();
16174 TCGv_i64 t2
= tcg_temp_new_i64();
16175 gen_load_gpr(t1
, rs
);
16176 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
16177 tcg_gen_shri_i64(t2
, t2
, 8 * (4 - sa
));
16178 #if defined(TARGET_MIPS64)
16179 tcg_gen_ext32s_i64(cpu_gpr
[rd
], t2
);
16181 tcg_gen_trunc_i64_i32(cpu_gpr
[rd
], t2
);
16183 tcg_temp_free_i64(t2
);
16188 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
16194 #if defined(TARGET_MIPS64)
16196 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
16199 gen_ld(ctx
, op1
, rt
, rs
, imm
);
16202 check_mips_64(ctx
);
16205 /* Treat as NOP. */
16208 TCGv t0
= tcg_temp_new();
16209 gen_load_gpr(t0
, rt
);
16211 op2
= MASK_DBSHFL(ctx
->opcode
);
16213 case OPC_DALIGN
... OPC_DALIGN_END
:
16216 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
16218 TCGv t1
= tcg_temp_new();
16219 gen_load_gpr(t1
, rs
);
16220 tcg_gen_shli_tl(t0
, t0
, 8 * sa
);
16221 tcg_gen_shri_tl(t1
, t1
, 8 * (8 - sa
));
16222 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
16227 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
16234 default: /* Invalid */
16235 MIPS_INVAL("special3_r6");
16236 generate_exception(ctx
, EXCP_RI
);
16241 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16246 rs
= (ctx
->opcode
>> 21) & 0x1f;
16247 rt
= (ctx
->opcode
>> 16) & 0x1f;
16248 rd
= (ctx
->opcode
>> 11) & 0x1f;
16250 op1
= MASK_SPECIAL3(ctx
->opcode
);
16252 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
16253 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
16254 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
16255 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16256 * the same mask and op1. */
16257 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
16258 op2
= MASK_ADDUH_QB(ctx
->opcode
);
16261 case OPC_ADDUH_R_QB
:
16263 case OPC_ADDQH_R_PH
:
16265 case OPC_ADDQH_R_W
:
16267 case OPC_SUBUH_R_QB
:
16269 case OPC_SUBQH_R_PH
:
16271 case OPC_SUBQH_R_W
:
16272 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16277 case OPC_MULQ_RS_W
:
16278 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16281 MIPS_INVAL("MASK ADDUH.QB");
16282 generate_exception(ctx
, EXCP_RI
);
16285 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
16286 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16288 generate_exception(ctx
, EXCP_RI
);
16292 op2
= MASK_LX(ctx
->opcode
);
16294 #if defined(TARGET_MIPS64)
16300 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
16302 default: /* Invalid */
16303 MIPS_INVAL("MASK LX");
16304 generate_exception(ctx
, EXCP_RI
);
16308 case OPC_ABSQ_S_PH_DSP
:
16309 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
16311 case OPC_ABSQ_S_QB
:
16312 case OPC_ABSQ_S_PH
:
16314 case OPC_PRECEQ_W_PHL
:
16315 case OPC_PRECEQ_W_PHR
:
16316 case OPC_PRECEQU_PH_QBL
:
16317 case OPC_PRECEQU_PH_QBR
:
16318 case OPC_PRECEQU_PH_QBLA
:
16319 case OPC_PRECEQU_PH_QBRA
:
16320 case OPC_PRECEU_PH_QBL
:
16321 case OPC_PRECEU_PH_QBR
:
16322 case OPC_PRECEU_PH_QBLA
:
16323 case OPC_PRECEU_PH_QBRA
:
16324 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16331 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
16334 MIPS_INVAL("MASK ABSQ_S.PH");
16335 generate_exception(ctx
, EXCP_RI
);
16339 case OPC_ADDU_QB_DSP
:
16340 op2
= MASK_ADDU_QB(ctx
->opcode
);
16343 case OPC_ADDQ_S_PH
:
16346 case OPC_ADDU_S_QB
:
16348 case OPC_ADDU_S_PH
:
16350 case OPC_SUBQ_S_PH
:
16353 case OPC_SUBU_S_QB
:
16355 case OPC_SUBU_S_PH
:
16359 case OPC_RADDU_W_QB
:
16360 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16362 case OPC_MULEU_S_PH_QBL
:
16363 case OPC_MULEU_S_PH_QBR
:
16364 case OPC_MULQ_RS_PH
:
16365 case OPC_MULEQ_S_W_PHL
:
16366 case OPC_MULEQ_S_W_PHR
:
16367 case OPC_MULQ_S_PH
:
16368 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16370 default: /* Invalid */
16371 MIPS_INVAL("MASK ADDU.QB");
16372 generate_exception(ctx
, EXCP_RI
);
16377 case OPC_CMPU_EQ_QB_DSP
:
16378 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
16380 case OPC_PRECR_SRA_PH_W
:
16381 case OPC_PRECR_SRA_R_PH_W
:
16382 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
16384 case OPC_PRECR_QB_PH
:
16385 case OPC_PRECRQ_QB_PH
:
16386 case OPC_PRECRQ_PH_W
:
16387 case OPC_PRECRQ_RS_PH_W
:
16388 case OPC_PRECRQU_S_QB_PH
:
16389 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16391 case OPC_CMPU_EQ_QB
:
16392 case OPC_CMPU_LT_QB
:
16393 case OPC_CMPU_LE_QB
:
16394 case OPC_CMP_EQ_PH
:
16395 case OPC_CMP_LT_PH
:
16396 case OPC_CMP_LE_PH
:
16397 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16399 case OPC_CMPGU_EQ_QB
:
16400 case OPC_CMPGU_LT_QB
:
16401 case OPC_CMPGU_LE_QB
:
16402 case OPC_CMPGDU_EQ_QB
:
16403 case OPC_CMPGDU_LT_QB
:
16404 case OPC_CMPGDU_LE_QB
:
16407 case OPC_PACKRL_PH
:
16408 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16410 default: /* Invalid */
16411 MIPS_INVAL("MASK CMPU.EQ.QB");
16412 generate_exception(ctx
, EXCP_RI
);
16416 case OPC_SHLL_QB_DSP
:
16417 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
16419 case OPC_DPA_W_PH_DSP
:
16420 op2
= MASK_DPA_W_PH(ctx
->opcode
);
16422 case OPC_DPAU_H_QBL
:
16423 case OPC_DPAU_H_QBR
:
16424 case OPC_DPSU_H_QBL
:
16425 case OPC_DPSU_H_QBR
:
16427 case OPC_DPAX_W_PH
:
16428 case OPC_DPAQ_S_W_PH
:
16429 case OPC_DPAQX_S_W_PH
:
16430 case OPC_DPAQX_SA_W_PH
:
16432 case OPC_DPSX_W_PH
:
16433 case OPC_DPSQ_S_W_PH
:
16434 case OPC_DPSQX_S_W_PH
:
16435 case OPC_DPSQX_SA_W_PH
:
16436 case OPC_MULSAQ_S_W_PH
:
16437 case OPC_DPAQ_SA_L_W
:
16438 case OPC_DPSQ_SA_L_W
:
16439 case OPC_MAQ_S_W_PHL
:
16440 case OPC_MAQ_S_W_PHR
:
16441 case OPC_MAQ_SA_W_PHL
:
16442 case OPC_MAQ_SA_W_PHR
:
16443 case OPC_MULSA_W_PH
:
16444 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16446 default: /* Invalid */
16447 MIPS_INVAL("MASK DPAW.PH");
16448 generate_exception(ctx
, EXCP_RI
);
16453 op2
= MASK_INSV(ctx
->opcode
);
16465 t0
= tcg_temp_new();
16466 t1
= tcg_temp_new();
16468 gen_load_gpr(t0
, rt
);
16469 gen_load_gpr(t1
, rs
);
16471 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
16477 default: /* Invalid */
16478 MIPS_INVAL("MASK INSV");
16479 generate_exception(ctx
, EXCP_RI
);
16483 case OPC_APPEND_DSP
:
16484 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
16486 case OPC_EXTR_W_DSP
:
16487 op2
= MASK_EXTR_W(ctx
->opcode
);
16491 case OPC_EXTR_RS_W
:
16493 case OPC_EXTRV_S_H
:
16495 case OPC_EXTRV_R_W
:
16496 case OPC_EXTRV_RS_W
:
16501 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
16504 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16510 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16512 default: /* Invalid */
16513 MIPS_INVAL("MASK EXTR.W");
16514 generate_exception(ctx
, EXCP_RI
);
16518 #if defined(TARGET_MIPS64)
16519 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
16520 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
16521 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
16522 check_insn(ctx
, INSN_LOONGSON2E
);
16523 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16525 case OPC_ABSQ_S_QH_DSP
:
16526 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
16528 case OPC_PRECEQ_L_PWL
:
16529 case OPC_PRECEQ_L_PWR
:
16530 case OPC_PRECEQ_PW_QHL
:
16531 case OPC_PRECEQ_PW_QHR
:
16532 case OPC_PRECEQ_PW_QHLA
:
16533 case OPC_PRECEQ_PW_QHRA
:
16534 case OPC_PRECEQU_QH_OBL
:
16535 case OPC_PRECEQU_QH_OBR
:
16536 case OPC_PRECEQU_QH_OBLA
:
16537 case OPC_PRECEQU_QH_OBRA
:
16538 case OPC_PRECEU_QH_OBL
:
16539 case OPC_PRECEU_QH_OBR
:
16540 case OPC_PRECEU_QH_OBLA
:
16541 case OPC_PRECEU_QH_OBRA
:
16542 case OPC_ABSQ_S_OB
:
16543 case OPC_ABSQ_S_PW
:
16544 case OPC_ABSQ_S_QH
:
16545 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16553 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
16555 default: /* Invalid */
16556 MIPS_INVAL("MASK ABSQ_S.QH");
16557 generate_exception(ctx
, EXCP_RI
);
16561 case OPC_ADDU_OB_DSP
:
16562 op2
= MASK_ADDU_OB(ctx
->opcode
);
16564 case OPC_RADDU_L_OB
:
16566 case OPC_SUBQ_S_PW
:
16568 case OPC_SUBQ_S_QH
:
16570 case OPC_SUBU_S_OB
:
16572 case OPC_SUBU_S_QH
:
16574 case OPC_SUBUH_R_OB
:
16576 case OPC_ADDQ_S_PW
:
16578 case OPC_ADDQ_S_QH
:
16580 case OPC_ADDU_S_OB
:
16582 case OPC_ADDU_S_QH
:
16584 case OPC_ADDUH_R_OB
:
16585 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16587 case OPC_MULEQ_S_PW_QHL
:
16588 case OPC_MULEQ_S_PW_QHR
:
16589 case OPC_MULEU_S_QH_OBL
:
16590 case OPC_MULEU_S_QH_OBR
:
16591 case OPC_MULQ_RS_QH
:
16592 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16594 default: /* Invalid */
16595 MIPS_INVAL("MASK ADDU.OB");
16596 generate_exception(ctx
, EXCP_RI
);
16600 case OPC_CMPU_EQ_OB_DSP
:
16601 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
16603 case OPC_PRECR_SRA_QH_PW
:
16604 case OPC_PRECR_SRA_R_QH_PW
:
16605 /* Return value is rt. */
16606 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
16608 case OPC_PRECR_OB_QH
:
16609 case OPC_PRECRQ_OB_QH
:
16610 case OPC_PRECRQ_PW_L
:
16611 case OPC_PRECRQ_QH_PW
:
16612 case OPC_PRECRQ_RS_QH_PW
:
16613 case OPC_PRECRQU_S_OB_QH
:
16614 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16616 case OPC_CMPU_EQ_OB
:
16617 case OPC_CMPU_LT_OB
:
16618 case OPC_CMPU_LE_OB
:
16619 case OPC_CMP_EQ_QH
:
16620 case OPC_CMP_LT_QH
:
16621 case OPC_CMP_LE_QH
:
16622 case OPC_CMP_EQ_PW
:
16623 case OPC_CMP_LT_PW
:
16624 case OPC_CMP_LE_PW
:
16625 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16627 case OPC_CMPGDU_EQ_OB
:
16628 case OPC_CMPGDU_LT_OB
:
16629 case OPC_CMPGDU_LE_OB
:
16630 case OPC_CMPGU_EQ_OB
:
16631 case OPC_CMPGU_LT_OB
:
16632 case OPC_CMPGU_LE_OB
:
16633 case OPC_PACKRL_PW
:
16637 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16639 default: /* Invalid */
16640 MIPS_INVAL("MASK CMPU_EQ.OB");
16641 generate_exception(ctx
, EXCP_RI
);
16645 case OPC_DAPPEND_DSP
:
16646 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
16648 case OPC_DEXTR_W_DSP
:
16649 op2
= MASK_DEXTR_W(ctx
->opcode
);
16656 case OPC_DEXTR_R_L
:
16657 case OPC_DEXTR_RS_L
:
16659 case OPC_DEXTR_R_W
:
16660 case OPC_DEXTR_RS_W
:
16661 case OPC_DEXTR_S_H
:
16663 case OPC_DEXTRV_R_L
:
16664 case OPC_DEXTRV_RS_L
:
16665 case OPC_DEXTRV_S_H
:
16667 case OPC_DEXTRV_R_W
:
16668 case OPC_DEXTRV_RS_W
:
16669 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
16674 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16676 default: /* Invalid */
16677 MIPS_INVAL("MASK EXTR.W");
16678 generate_exception(ctx
, EXCP_RI
);
16682 case OPC_DPAQ_W_QH_DSP
:
16683 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
16685 case OPC_DPAU_H_OBL
:
16686 case OPC_DPAU_H_OBR
:
16687 case OPC_DPSU_H_OBL
:
16688 case OPC_DPSU_H_OBR
:
16690 case OPC_DPAQ_S_W_QH
:
16692 case OPC_DPSQ_S_W_QH
:
16693 case OPC_MULSAQ_S_W_QH
:
16694 case OPC_DPAQ_SA_L_PW
:
16695 case OPC_DPSQ_SA_L_PW
:
16696 case OPC_MULSAQ_S_L_PW
:
16697 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16699 case OPC_MAQ_S_W_QHLL
:
16700 case OPC_MAQ_S_W_QHLR
:
16701 case OPC_MAQ_S_W_QHRL
:
16702 case OPC_MAQ_S_W_QHRR
:
16703 case OPC_MAQ_SA_W_QHLL
:
16704 case OPC_MAQ_SA_W_QHLR
:
16705 case OPC_MAQ_SA_W_QHRL
:
16706 case OPC_MAQ_SA_W_QHRR
:
16707 case OPC_MAQ_S_L_PWL
:
16708 case OPC_MAQ_S_L_PWR
:
16713 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16715 default: /* Invalid */
16716 MIPS_INVAL("MASK DPAQ.W.QH");
16717 generate_exception(ctx
, EXCP_RI
);
16721 case OPC_DINSV_DSP
:
16722 op2
= MASK_INSV(ctx
->opcode
);
16734 t0
= tcg_temp_new();
16735 t1
= tcg_temp_new();
16737 gen_load_gpr(t0
, rt
);
16738 gen_load_gpr(t1
, rs
);
16740 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
16746 default: /* Invalid */
16747 MIPS_INVAL("MASK DINSV");
16748 generate_exception(ctx
, EXCP_RI
);
16752 case OPC_SHLL_OB_DSP
:
16753 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
16756 default: /* Invalid */
16757 MIPS_INVAL("special3_legacy");
16758 generate_exception(ctx
, EXCP_RI
);
16763 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
16765 int rs
, rt
, rd
, sa
;
16768 rs
= (ctx
->opcode
>> 21) & 0x1f;
16769 rt
= (ctx
->opcode
>> 16) & 0x1f;
16770 rd
= (ctx
->opcode
>> 11) & 0x1f;
16771 sa
= (ctx
->opcode
>> 6) & 0x1f;
16773 op1
= MASK_SPECIAL3(ctx
->opcode
);
16777 check_insn(ctx
, ISA_MIPS32R2
);
16778 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
16781 op2
= MASK_BSHFL(ctx
->opcode
);
16783 case OPC_ALIGN
... OPC_ALIGN_END
:
16785 check_insn(ctx
, ISA_MIPS32R6
);
16786 decode_opc_special3_r6(env
, ctx
);
16789 check_insn(ctx
, ISA_MIPS32R2
);
16790 gen_bshfl(ctx
, op2
, rt
, rd
);
16794 #if defined(TARGET_MIPS64)
16795 case OPC_DEXTM
... OPC_DEXT
:
16796 case OPC_DINSM
... OPC_DINS
:
16797 check_insn(ctx
, ISA_MIPS64R2
);
16798 check_mips_64(ctx
);
16799 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
16802 op2
= MASK_DBSHFL(ctx
->opcode
);
16804 case OPC_DALIGN
... OPC_DALIGN_END
:
16806 check_insn(ctx
, ISA_MIPS32R6
);
16807 decode_opc_special3_r6(env
, ctx
);
16810 check_insn(ctx
, ISA_MIPS64R2
);
16811 check_mips_64(ctx
);
16812 op2
= MASK_DBSHFL(ctx
->opcode
);
16813 gen_bshfl(ctx
, op2
, rt
, rd
);
16819 gen_rdhwr(ctx
, rt
, rd
);
16822 check_insn(ctx
, ASE_MT
);
16824 TCGv t0
= tcg_temp_new();
16825 TCGv t1
= tcg_temp_new();
16827 gen_load_gpr(t0
, rt
);
16828 gen_load_gpr(t1
, rs
);
16829 gen_helper_fork(t0
, t1
);
16835 check_insn(ctx
, ASE_MT
);
16837 TCGv t0
= tcg_temp_new();
16839 save_cpu_state(ctx
, 1);
16840 gen_load_gpr(t0
, rs
);
16841 gen_helper_yield(t0
, cpu_env
, t0
);
16842 gen_store_gpr(t0
, rd
);
16847 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16848 decode_opc_special3_r6(env
, ctx
);
16850 decode_opc_special3_legacy(env
, ctx
);
16855 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
16858 int rs
, rt
, rd
, sa
;
16862 /* make sure instructions are on a word boundary */
16863 if (ctx
->pc
& 0x3) {
16864 env
->CP0_BadVAddr
= ctx
->pc
;
16865 generate_exception(ctx
, EXCP_AdEL
);
16869 /* Handle blikely not taken case */
16870 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
16871 int l1
= gen_new_label();
16873 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
16874 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
16875 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
16876 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
16880 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
16881 tcg_gen_debug_insn_start(ctx
->pc
);
16884 op
= MASK_OP_MAJOR(ctx
->opcode
);
16885 rs
= (ctx
->opcode
>> 21) & 0x1f;
16886 rt
= (ctx
->opcode
>> 16) & 0x1f;
16887 rd
= (ctx
->opcode
>> 11) & 0x1f;
16888 sa
= (ctx
->opcode
>> 6) & 0x1f;
16889 imm
= (int16_t)ctx
->opcode
;
16892 decode_opc_special(env
, ctx
);
16895 decode_opc_special2_legacy(env
, ctx
);
16898 decode_opc_special3(env
, ctx
);
16901 op1
= MASK_REGIMM(ctx
->opcode
);
16903 case OPC_BLTZL
: /* REGIMM branches */
16907 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16910 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
16914 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16916 /* OPC_NAL, OPC_BAL */
16917 gen_compute_branch(ctx
, op1
, 4, 0, -1, imm
<< 2, 4);
16919 generate_exception(ctx
, EXCP_RI
);
16922 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2, 4);
16925 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
16927 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16928 gen_trap(ctx
, op1
, rs
, -1, imm
);
16931 check_insn(ctx
, ISA_MIPS32R2
);
16932 /* Break the TB to be able to sync copied instructions
16934 ctx
->bstate
= BS_STOP
;
16936 case OPC_BPOSGE32
: /* MIPS DSP branch */
16937 #if defined(TARGET_MIPS64)
16941 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2, 4);
16943 #if defined(TARGET_MIPS64)
16945 check_insn(ctx
, ISA_MIPS32R6
);
16946 check_mips_64(ctx
);
16948 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
16950 MIPS_DEBUG("dahi %s, %04x", regnames
[rs
], imm
);
16953 check_insn(ctx
, ISA_MIPS32R6
);
16954 check_mips_64(ctx
);
16956 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
16958 MIPS_DEBUG("dati %s, %04x", regnames
[rs
], imm
);
16961 default: /* Invalid */
16962 MIPS_INVAL("regimm");
16963 generate_exception(ctx
, EXCP_RI
);
16968 check_cp0_enabled(ctx
);
16969 op1
= MASK_CP0(ctx
->opcode
);
16975 #if defined(TARGET_MIPS64)
16979 #ifndef CONFIG_USER_ONLY
16980 gen_cp0(env
, ctx
, op1
, rt
, rd
);
16981 #endif /* !CONFIG_USER_ONLY */
16983 case OPC_C0_FIRST
... OPC_C0_LAST
:
16984 #ifndef CONFIG_USER_ONLY
16985 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
16986 #endif /* !CONFIG_USER_ONLY */
16989 #ifndef CONFIG_USER_ONLY
16992 TCGv t0
= tcg_temp_new();
16994 op2
= MASK_MFMC0(ctx
->opcode
);
16997 check_insn(ctx
, ASE_MT
);
16998 gen_helper_dmt(t0
);
16999 gen_store_gpr(t0
, rt
);
17002 check_insn(ctx
, ASE_MT
);
17003 gen_helper_emt(t0
);
17004 gen_store_gpr(t0
, rt
);
17007 check_insn(ctx
, ASE_MT
);
17008 gen_helper_dvpe(t0
, cpu_env
);
17009 gen_store_gpr(t0
, rt
);
17012 check_insn(ctx
, ASE_MT
);
17013 gen_helper_evpe(t0
, cpu_env
);
17014 gen_store_gpr(t0
, rt
);
17017 check_insn(ctx
, ISA_MIPS32R2
);
17018 save_cpu_state(ctx
, 1);
17019 gen_helper_di(t0
, cpu_env
);
17020 gen_store_gpr(t0
, rt
);
17021 /* Stop translation as we may have switched the execution mode */
17022 ctx
->bstate
= BS_STOP
;
17025 check_insn(ctx
, ISA_MIPS32R2
);
17026 save_cpu_state(ctx
, 1);
17027 gen_helper_ei(t0
, cpu_env
);
17028 gen_store_gpr(t0
, rt
);
17029 /* Stop translation as we may have switched the execution mode */
17030 ctx
->bstate
= BS_STOP
;
17032 default: /* Invalid */
17033 MIPS_INVAL("mfmc0");
17034 generate_exception(ctx
, EXCP_RI
);
17039 #endif /* !CONFIG_USER_ONLY */
17042 check_insn(ctx
, ISA_MIPS32R2
);
17043 gen_load_srsgpr(rt
, rd
);
17046 check_insn(ctx
, ISA_MIPS32R2
);
17047 gen_store_srsgpr(rt
, rd
);
17051 generate_exception(ctx
, EXCP_RI
);
17055 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
17056 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17057 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
17058 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17061 /* Arithmetic with immediate opcode */
17062 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17066 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17068 case OPC_SLTI
: /* Set on less than with immediate opcode */
17070 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
17072 case OPC_ANDI
: /* Arithmetic with immediate opcode */
17073 case OPC_LUI
: /* OPC_AUI */
17076 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
17078 case OPC_J
... OPC_JAL
: /* Jump */
17079 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17080 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
17083 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
17084 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17086 generate_exception(ctx
, EXCP_RI
);
17089 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
17090 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17093 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17096 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
17097 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17099 generate_exception(ctx
, EXCP_RI
);
17102 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
17103 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17106 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17109 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
17112 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17114 check_insn(ctx
, ISA_MIPS32R6
);
17115 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
17116 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17119 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
17122 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17124 check_insn(ctx
, ISA_MIPS32R6
);
17125 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
17126 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17131 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17134 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2, 4);
17136 case OPC_LWL
: /* Load and stores */
17139 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17140 case OPC_LB
... OPC_LH
:
17141 case OPC_LW
... OPC_LHU
:
17142 gen_ld(ctx
, op
, rt
, rs
, imm
);
17146 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17147 case OPC_SB
... OPC_SH
:
17149 gen_st(ctx
, op
, rt
, rs
, imm
);
17152 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17153 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
17156 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17157 check_cp0_enabled(ctx
);
17158 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
17159 /* Treat as NOP. */
17162 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17163 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
17164 /* Treat as NOP. */
17167 /* Floating point (COP1). */
17172 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
17176 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
17177 check_cp1_enabled(ctx
);
17178 op1
= MASK_CP1(ctx
->opcode
);
17182 check_insn(ctx
, ISA_MIPS32R2
);
17187 gen_cp1(ctx
, op1
, rt
, rd
);
17189 #if defined(TARGET_MIPS64)
17192 check_insn(ctx
, ISA_MIPS3
);
17193 gen_cp1(ctx
, op1
, rt
, rd
);
17196 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
17197 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17199 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
17204 check_insn(ctx
, ASE_MIPS3D
);
17205 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
17206 (rt
>> 2) & 0x7, imm
<< 2);
17210 check_insn(ctx
, ISA_MIPS32R6
);
17211 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
17215 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17217 check_insn(ctx
, ASE_MIPS3D
);
17220 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17221 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
17222 (rt
>> 2) & 0x7, imm
<< 2);
17225 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17228 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
17234 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
17235 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17237 case R6_OPC_CMP_AF_S
:
17238 case R6_OPC_CMP_UN_S
:
17239 case R6_OPC_CMP_EQ_S
:
17240 case R6_OPC_CMP_UEQ_S
:
17241 case R6_OPC_CMP_LT_S
:
17242 case R6_OPC_CMP_ULT_S
:
17243 case R6_OPC_CMP_LE_S
:
17244 case R6_OPC_CMP_ULE_S
:
17245 case R6_OPC_CMP_SAF_S
:
17246 case R6_OPC_CMP_SUN_S
:
17247 case R6_OPC_CMP_SEQ_S
:
17248 case R6_OPC_CMP_SEUQ_S
:
17249 case R6_OPC_CMP_SLT_S
:
17250 case R6_OPC_CMP_SULT_S
:
17251 case R6_OPC_CMP_SLE_S
:
17252 case R6_OPC_CMP_SULE_S
:
17253 case R6_OPC_CMP_OR_S
:
17254 case R6_OPC_CMP_UNE_S
:
17255 case R6_OPC_CMP_NE_S
:
17256 case R6_OPC_CMP_SOR_S
:
17257 case R6_OPC_CMP_SUNE_S
:
17258 case R6_OPC_CMP_SNE_S
:
17259 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
17261 case R6_OPC_CMP_AF_D
:
17262 case R6_OPC_CMP_UN_D
:
17263 case R6_OPC_CMP_EQ_D
:
17264 case R6_OPC_CMP_UEQ_D
:
17265 case R6_OPC_CMP_LT_D
:
17266 case R6_OPC_CMP_ULT_D
:
17267 case R6_OPC_CMP_LE_D
:
17268 case R6_OPC_CMP_ULE_D
:
17269 case R6_OPC_CMP_SAF_D
:
17270 case R6_OPC_CMP_SUN_D
:
17271 case R6_OPC_CMP_SEQ_D
:
17272 case R6_OPC_CMP_SEUQ_D
:
17273 case R6_OPC_CMP_SLT_D
:
17274 case R6_OPC_CMP_SULT_D
:
17275 case R6_OPC_CMP_SLE_D
:
17276 case R6_OPC_CMP_SULE_D
:
17277 case R6_OPC_CMP_OR_D
:
17278 case R6_OPC_CMP_UNE_D
:
17279 case R6_OPC_CMP_NE_D
:
17280 case R6_OPC_CMP_SOR_D
:
17281 case R6_OPC_CMP_SUNE_D
:
17282 case R6_OPC_CMP_SNE_D
:
17283 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
17286 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
17291 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
17298 generate_exception (ctx
, EXCP_RI
);
17302 generate_exception_err(ctx
, EXCP_CpU
, 1);
17306 /* Compact branches [R6] and COP2 [non-R6] */
17307 case OPC_BC
: /* OPC_LWC2 */
17308 case OPC_BALC
: /* OPC_SWC2 */
17309 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17310 /* OPC_BC, OPC_BALC */
17311 gen_compute_compact_branch(ctx
, op
, 0, 0,
17312 sextract32(ctx
->opcode
<< 2, 0, 28));
17314 /* OPC_LWC2, OPC_SWC2 */
17315 /* COP2: Not implemented. */
17316 generate_exception_err(ctx
, EXCP_CpU
, 2);
17319 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
17320 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
17321 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17323 /* OPC_BEQZC, OPC_BNEZC */
17324 gen_compute_compact_branch(ctx
, op
, rs
, 0,
17325 sextract32(ctx
->opcode
<< 2, 0, 23));
17327 /* OPC_JIC, OPC_JIALC */
17328 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
17331 /* OPC_LWC2, OPC_SWC2 */
17332 /* COP2: Not implemented. */
17333 generate_exception_err(ctx
, EXCP_CpU
, 2);
17337 check_insn(ctx
, INSN_LOONGSON2F
);
17338 /* Note that these instructions use different fields. */
17339 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
17343 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17344 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
17345 check_cp1_enabled(ctx
);
17346 op1
= MASK_CP3(ctx
->opcode
);
17354 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
17357 /* Treat as NOP. */
17372 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
17376 generate_exception (ctx
, EXCP_RI
);
17380 generate_exception_err(ctx
, EXCP_CpU
, 1);
17384 #if defined(TARGET_MIPS64)
17385 /* MIPS64 opcodes */
17386 case OPC_LDL
... OPC_LDR
:
17388 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17391 check_insn(ctx
, ISA_MIPS3
);
17392 check_mips_64(ctx
);
17393 gen_ld(ctx
, op
, rt
, rs
, imm
);
17395 case OPC_SDL
... OPC_SDR
:
17396 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17398 check_insn(ctx
, ISA_MIPS3
);
17399 check_mips_64(ctx
);
17400 gen_st(ctx
, op
, rt
, rs
, imm
);
17403 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17404 check_insn(ctx
, ISA_MIPS3
);
17405 check_mips_64(ctx
);
17406 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
17408 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
17409 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17410 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
17411 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17414 check_insn(ctx
, ISA_MIPS3
);
17415 check_mips_64(ctx
);
17416 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17420 check_insn(ctx
, ISA_MIPS3
);
17421 check_mips_64(ctx
);
17422 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17425 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
17426 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17427 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17429 MIPS_INVAL("major opcode");
17430 generate_exception(ctx
, EXCP_RI
);
17434 case OPC_DAUI
: /* OPC_JALX */
17435 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17436 #if defined(TARGET_MIPS64)
17438 check_mips_64(ctx
);
17440 TCGv t0
= tcg_temp_new();
17441 gen_load_gpr(t0
, rs
);
17442 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
17445 MIPS_DEBUG("daui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
17447 generate_exception(ctx
, EXCP_RI
);
17448 MIPS_INVAL("major opcode");
17452 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
17453 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17454 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
, 4);
17458 check_insn(ctx
, ASE_MDMX
);
17459 /* MDMX: Not implemented. */
17462 check_insn(ctx
, ISA_MIPS32R6
);
17463 gen_pcrel(ctx
, rs
, imm
);
17465 default: /* Invalid */
17466 MIPS_INVAL("major opcode");
17467 generate_exception(ctx
, EXCP_RI
);
17473 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
17476 CPUState
*cs
= CPU(cpu
);
17477 CPUMIPSState
*env
= &cpu
->env
;
17479 target_ulong pc_start
;
17480 uint16_t *gen_opc_end
;
17489 qemu_log("search pc %d\n", search_pc
);
17492 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
17495 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
17496 ctx
.insn_flags
= env
->insn_flags
;
17497 ctx
.CP0_Config1
= env
->CP0_Config1
;
17499 ctx
.bstate
= BS_NONE
;
17500 ctx
.kscrexist
= (env
->CP0_Config4
>> CP0C4_KScrExist
) & 0xff;
17501 ctx
.rxi
= (env
->CP0_Config3
>> CP0C3_RXI
) & 1;
17502 ctx
.ie
= (env
->CP0_Config4
>> CP0C4_IE
) & 3;
17503 /* Restore delay slot state from the tb context. */
17504 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
17505 ctx
.ulri
= env
->CP0_Config3
& (1 << CP0C3_ULRI
);
17506 restore_cpu_state(env
, &ctx
);
17507 #ifdef CONFIG_USER_ONLY
17508 ctx
.mem_idx
= MIPS_HFLAG_UM
;
17510 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
17513 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
17514 if (max_insns
== 0)
17515 max_insns
= CF_COUNT_MASK
;
17516 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
17518 while (ctx
.bstate
== BS_NONE
) {
17519 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
17520 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
17521 if (bp
->pc
== ctx
.pc
) {
17522 save_cpu_state(&ctx
, 1);
17523 ctx
.bstate
= BS_BRANCH
;
17524 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
17525 /* Include the breakpoint location or the tb won't
17526 * be flushed when it must be. */
17528 goto done_generating
;
17534 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
17538 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
17540 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
17541 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
17542 gen_opc_btarget
[lj
] = ctx
.btarget
;
17543 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
17544 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
17546 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
17549 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
17550 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
17551 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
17553 decode_opc(env
, &ctx
);
17554 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
17555 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
17556 insn_bytes
= decode_micromips_opc(env
, &ctx
);
17557 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
17558 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
17559 insn_bytes
= decode_mips16_opc(env
, &ctx
);
17561 generate_exception(&ctx
, EXCP_RI
);
17562 ctx
.bstate
= BS_STOP
;
17566 if (ctx
.hflags
& MIPS_HFLAG_BMASK
) {
17567 if (!(ctx
.hflags
& (MIPS_HFLAG_BDS16
| MIPS_HFLAG_BDS32
))) {
17569 /* force to generate branch as no delay slot is required */
17573 gen_branch(&ctx
, insn_bytes
);
17575 ctx
.pc
+= insn_bytes
;
17579 /* Execute a branch and its delay slot as a single instruction.
17580 This is what GDB expects and is consistent with what the
17581 hardware does (e.g. if a delay slot instruction faults, the
17582 reported PC is the PC of the branch). */
17583 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
17587 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
17590 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
17594 if (num_insns
>= max_insns
)
17600 if (tb
->cflags
& CF_LAST_IO
) {
17603 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
17604 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
17605 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
17607 switch (ctx
.bstate
) {
17609 gen_goto_tb(&ctx
, 0, ctx
.pc
);
17612 save_cpu_state(&ctx
, 0);
17613 gen_goto_tb(&ctx
, 0, ctx
.pc
);
17616 tcg_gen_exit_tb(0);
17624 gen_tb_end(tb
, num_insns
);
17625 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
17627 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
17630 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
17632 tb
->size
= ctx
.pc
- pc_start
;
17633 tb
->icount
= num_insns
;
17637 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
17638 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
17639 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
17645 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
17647 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
17650 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
17652 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
17655 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
17659 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
17661 #define printfpr(fp) \
17664 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17665 " fd:%13g fs:%13g psu: %13g\n", \
17666 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
17667 (double)(fp)->fd, \
17668 (double)(fp)->fs[FP_ENDIAN_IDX], \
17669 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
17672 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
17673 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
17674 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17675 " fd:%13g fs:%13g psu:%13g\n", \
17676 tmp.w[FP_ENDIAN_IDX], tmp.d, \
17678 (double)tmp.fs[FP_ENDIAN_IDX], \
17679 (double)tmp.fs[!FP_ENDIAN_IDX]); \
17684 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
17685 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
17686 get_float_exception_flags(&env
->active_fpu
.fp_status
));
17687 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
17688 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
17689 printfpr(&env
->active_fpu
.fpr
[i
]);
17695 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
17696 /* Debug help: The architecture requires 32bit code to maintain proper
17697 sign-extended values on 64bit machines. */
17699 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
17702 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
17703 fprintf_function cpu_fprintf
,
17708 if (!SIGN_EXT_P(env
->active_tc
.PC
))
17709 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
17710 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
17711 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
17712 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
17713 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
17714 if (!SIGN_EXT_P(env
->btarget
))
17715 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
17717 for (i
= 0; i
< 32; i
++) {
17718 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
17719 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
17722 if (!SIGN_EXT_P(env
->CP0_EPC
))
17723 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
17724 if (!SIGN_EXT_P(env
->lladdr
))
17725 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
17729 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
17732 MIPSCPU
*cpu
= MIPS_CPU(cs
);
17733 CPUMIPSState
*env
= &cpu
->env
;
17736 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
17737 " LO=0x" TARGET_FMT_lx
" ds %04x "
17738 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
17739 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
17740 env
->hflags
, env
->btarget
, env
->bcond
);
17741 for (i
= 0; i
< 32; i
++) {
17743 cpu_fprintf(f
, "GPR%02d:", i
);
17744 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
17746 cpu_fprintf(f
, "\n");
17749 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
17750 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
17751 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
17752 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
17753 if (env
->hflags
& MIPS_HFLAG_FPU
)
17754 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
17755 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
17756 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
17760 void mips_tcg_init(void)
17765 /* Initialize various static tables. */
17769 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
17770 TCGV_UNUSED(cpu_gpr
[0]);
17771 for (i
= 1; i
< 32; i
++)
17772 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
17773 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
17776 for (i
= 0; i
< 32; i
++) {
17777 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
17778 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
17781 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
17782 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
17783 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
17784 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
17785 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
17787 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
17788 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
17791 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
17792 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
17794 bcond
= tcg_global_mem_new(TCG_AREG0
,
17795 offsetof(CPUMIPSState
, bcond
), "bcond");
17796 btarget
= tcg_global_mem_new(TCG_AREG0
,
17797 offsetof(CPUMIPSState
, btarget
), "btarget");
17798 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
17799 offsetof(CPUMIPSState
, hflags
), "hflags");
17801 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
17802 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
17804 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
17805 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
17811 #include "translate_init.c"
17813 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
17817 const mips_def_t
*def
;
17819 def
= cpu_mips_find_by_name(cpu_model
);
17822 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
17824 env
->cpu_model
= def
;
17826 #ifndef CONFIG_USER_ONLY
17827 mmu_init(env
, def
);
17829 fpu_init(env
, def
);
17830 mvp_init(env
, def
);
17832 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
17837 void cpu_state_reset(CPUMIPSState
*env
)
17839 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
17840 CPUState
*cs
= CPU(cpu
);
17842 /* Reset registers to their default values */
17843 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
17844 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
17845 #ifdef TARGET_WORDS_BIGENDIAN
17846 env
->CP0_Config0
|= (1 << CP0C0_BE
);
17848 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
17849 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
17850 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
17851 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
17852 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
17853 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
17854 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
17855 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
17856 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
17857 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
17858 << env
->cpu_model
->CP0_LLAddr_shift
;
17859 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
17860 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
17861 env
->CCRes
= env
->cpu_model
->CCRes
;
17862 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
17863 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
17864 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
17865 env
->current_tc
= 0;
17866 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
17867 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
17868 #if defined(TARGET_MIPS64)
17869 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
17870 env
->SEGMask
|= 3ULL << 62;
17873 env
->PABITS
= env
->cpu_model
->PABITS
;
17874 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
17875 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
17876 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
17877 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
17878 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
17879 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
17880 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
17881 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
17882 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
17883 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
17884 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
17885 env
->CP0_PageGrain_rw_bitmask
= env
->cpu_model
->CP0_PageGrain_rw_bitmask
;
17886 env
->CP0_PageGrain
= env
->cpu_model
->CP0_PageGrain
;
17887 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
17888 env
->insn_flags
= env
->cpu_model
->insn_flags
;
17890 #if defined(CONFIG_USER_ONLY)
17891 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
17892 # ifdef TARGET_MIPS64
17893 /* Enable 64-bit register mode. */
17894 env
->CP0_Status
|= (1 << CP0St_PX
);
17896 # ifdef TARGET_ABI_MIPSN64
17897 /* Enable 64-bit address mode. */
17898 env
->CP0_Status
|= (1 << CP0St_UX
);
17900 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
17901 hardware registers. */
17902 env
->CP0_HWREna
|= 0x0000000F;
17903 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17904 env
->CP0_Status
|= (1 << CP0St_CU1
);
17906 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
17907 env
->CP0_Status
|= (1 << CP0St_MX
);
17909 # if defined(TARGET_MIPS64)
17910 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
17911 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
17912 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
17913 env
->CP0_Status
|= (1 << CP0St_FR
);
17917 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
17918 /* If the exception was raised from a delay slot,
17919 come back to the jump. */
17920 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
17922 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
17924 env
->active_tc
.PC
= (int32_t)0xBFC00000;
17925 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
17926 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
17927 env
->CP0_Wired
= 0;
17928 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
17929 if (kvm_enabled()) {
17930 env
->CP0_EBase
|= 0x40000000;
17932 env
->CP0_EBase
|= 0x80000000;
17934 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
17935 /* vectored interrupts not implemented, timer on int 7,
17936 no performance counters. */
17937 env
->CP0_IntCtl
= 0xe0000000;
17941 for (i
= 0; i
< 7; i
++) {
17942 env
->CP0_WatchLo
[i
] = 0;
17943 env
->CP0_WatchHi
[i
] = 0x80000000;
17945 env
->CP0_WatchLo
[7] = 0;
17946 env
->CP0_WatchHi
[7] = 0;
17948 /* Count register increments in debug mode, EJTAG version 1 */
17949 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
17951 cpu_mips_store_count(env
, 1);
17953 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
17956 /* Only TC0 on VPE 0 starts as active. */
17957 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
17958 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
17959 env
->tcs
[i
].CP0_TCHalt
= 1;
17961 env
->active_tc
.CP0_TCHalt
= 1;
17964 if (cs
->cpu_index
== 0) {
17965 /* VPE0 starts up enabled. */
17966 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
17967 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
17969 /* TC0 starts up unhalted. */
17971 env
->active_tc
.CP0_TCHalt
= 0;
17972 env
->tcs
[0].CP0_TCHalt
= 0;
17973 /* With thread 0 active. */
17974 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
17975 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
17979 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
17980 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
17981 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
17982 env
->CP0_Status
|= (1 << CP0St_FR
);
17985 compute_hflags(env
);
17986 cs
->exception_index
= EXCP_NONE
;
17989 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
17991 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
17992 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
17993 env
->hflags
|= gen_opc_hflags
[pc_pos
];
17994 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
17995 case MIPS_HFLAG_BR
:
17997 case MIPS_HFLAG_BC
:
17998 case MIPS_HFLAG_BL
:
18000 env
->btarget
= gen_opc_btarget
[pc_pos
];