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_JALS
= OPC_JAL
| 0x5,
69 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
70 OPC_BEQL
= (0x14 << 26),
71 OPC_BNE
= (0x05 << 26),
72 OPC_BNEL
= (0x15 << 26),
73 OPC_BLEZ
= (0x06 << 26),
74 OPC_BLEZL
= (0x16 << 26),
75 OPC_BGTZ
= (0x07 << 26),
76 OPC_BGTZL
= (0x17 << 26),
77 OPC_JALX
= (0x1D << 26), /* MIPS 16 only */
78 OPC_DAUI
= (0x1D << 26),
79 OPC_JALXS
= OPC_JALX
| 0x5,
81 OPC_LDL
= (0x1A << 26),
82 OPC_LDR
= (0x1B << 26),
83 OPC_LB
= (0x20 << 26),
84 OPC_LH
= (0x21 << 26),
85 OPC_LWL
= (0x22 << 26),
86 OPC_LW
= (0x23 << 26),
87 OPC_LWPC
= OPC_LW
| 0x5,
88 OPC_LBU
= (0x24 << 26),
89 OPC_LHU
= (0x25 << 26),
90 OPC_LWR
= (0x26 << 26),
91 OPC_LWU
= (0x27 << 26),
92 OPC_SB
= (0x28 << 26),
93 OPC_SH
= (0x29 << 26),
94 OPC_SWL
= (0x2A << 26),
95 OPC_SW
= (0x2B << 26),
96 OPC_SDL
= (0x2C << 26),
97 OPC_SDR
= (0x2D << 26),
98 OPC_SWR
= (0x2E << 26),
99 OPC_LL
= (0x30 << 26),
100 OPC_LLD
= (0x34 << 26),
101 OPC_LD
= (0x37 << 26),
102 OPC_LDPC
= OPC_LD
| 0x5,
103 OPC_SC
= (0x38 << 26),
104 OPC_SCD
= (0x3C << 26),
105 OPC_SD
= (0x3F << 26),
106 /* Floating point load/store */
107 OPC_LWC1
= (0x31 << 26),
108 OPC_LWC2
= (0x32 << 26),
109 OPC_LDC1
= (0x35 << 26),
110 OPC_LDC2
= (0x36 << 26),
111 OPC_SWC1
= (0x39 << 26),
112 OPC_SWC2
= (0x3A << 26),
113 OPC_SDC1
= (0x3D << 26),
114 OPC_SDC2
= (0x3E << 26),
115 /* Compact Branches */
116 OPC_BLEZALC
= (0x06 << 26),
117 OPC_BGEZALC
= (0x06 << 26),
118 OPC_BGEUC
= (0x06 << 26),
119 OPC_BGTZALC
= (0x07 << 26),
120 OPC_BLTZALC
= (0x07 << 26),
121 OPC_BLTUC
= (0x07 << 26),
122 OPC_BOVC
= (0x08 << 26),
123 OPC_BEQZALC
= (0x08 << 26),
124 OPC_BEQC
= (0x08 << 26),
125 OPC_BLEZC
= (0x16 << 26),
126 OPC_BGEZC
= (0x16 << 26),
127 OPC_BGEC
= (0x16 << 26),
128 OPC_BGTZC
= (0x17 << 26),
129 OPC_BLTZC
= (0x17 << 26),
130 OPC_BLTC
= (0x17 << 26),
131 OPC_BNVC
= (0x18 << 26),
132 OPC_BNEZALC
= (0x18 << 26),
133 OPC_BNEC
= (0x18 << 26),
134 OPC_BC
= (0x32 << 26),
135 OPC_BEQZC
= (0x36 << 26),
136 OPC_JIC
= (0x36 << 26),
137 OPC_BALC
= (0x3A << 26),
138 OPC_BNEZC
= (0x3E << 26),
139 OPC_JIALC
= (0x3E << 26),
140 /* MDMX ASE specific */
141 OPC_MDMX
= (0x1E << 26),
142 /* Cache and prefetch */
143 OPC_CACHE
= (0x2F << 26),
144 OPC_PREF
= (0x33 << 26),
145 /* PC-relative address computation / loads */
146 OPC_PCREL
= (0x3B << 26),
149 /* PC-relative address computation / loads */
150 #define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
151 #define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
153 /* Instructions determined by bits 19 and 20 */
154 OPC_ADDIUPC
= OPC_PCREL
| (0 << 19),
155 R6_OPC_LWPC
= OPC_PCREL
| (1 << 19),
156 OPC_LWUPC
= OPC_PCREL
| (2 << 19),
158 /* Instructions determined by bits 16 ... 20 */
159 OPC_AUIPC
= OPC_PCREL
| (0x1e << 16),
160 OPC_ALUIPC
= OPC_PCREL
| (0x1f << 16),
163 R6_OPC_LDPC
= OPC_PCREL
| (6 << 18),
166 /* MIPS special opcodes */
167 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
171 OPC_SLL
= 0x00 | OPC_SPECIAL
,
172 /* NOP is SLL r0, r0, 0 */
173 /* SSNOP is SLL r0, r0, 1 */
174 /* EHB is SLL r0, r0, 3 */
175 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
176 OPC_ROTR
= OPC_SRL
| (1 << 21),
177 OPC_SRA
= 0x03 | OPC_SPECIAL
,
178 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
179 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
180 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
181 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
182 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
183 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
184 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
185 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
186 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
187 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
188 OPC_DROTR
= OPC_DSRL
| (1 << 21),
189 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
190 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
191 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
192 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
193 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
194 /* Multiplication / division */
195 OPC_MULT
= 0x18 | OPC_SPECIAL
,
196 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
197 OPC_DIV
= 0x1A | OPC_SPECIAL
,
198 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
199 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
200 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
201 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
202 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
204 /* 2 registers arithmetic / logic */
205 OPC_ADD
= 0x20 | OPC_SPECIAL
,
206 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
207 OPC_SUB
= 0x22 | OPC_SPECIAL
,
208 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
209 OPC_AND
= 0x24 | OPC_SPECIAL
,
210 OPC_OR
= 0x25 | OPC_SPECIAL
,
211 OPC_XOR
= 0x26 | OPC_SPECIAL
,
212 OPC_NOR
= 0x27 | OPC_SPECIAL
,
213 OPC_SLT
= 0x2A | OPC_SPECIAL
,
214 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
215 OPC_DADD
= 0x2C | OPC_SPECIAL
,
216 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
217 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
218 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
220 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
221 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
222 OPC_JALRC
= OPC_JALR
| (0x5 << 6),
223 OPC_JALRS
= 0x10 | OPC_SPECIAL
| (0x5 << 6),
225 OPC_TGE
= 0x30 | OPC_SPECIAL
,
226 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
227 OPC_TLT
= 0x32 | OPC_SPECIAL
,
228 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
229 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
230 OPC_TNE
= 0x36 | OPC_SPECIAL
,
231 /* HI / LO registers load & stores */
232 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
233 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
234 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
235 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
236 /* Conditional moves */
237 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
238 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
240 OPC_SELEQZ
= 0x35 | OPC_SPECIAL
,
241 OPC_SELNEZ
= 0x37 | OPC_SPECIAL
,
243 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
246 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
247 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
248 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
249 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
250 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
252 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
253 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
254 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
255 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
258 /* R6 Multiply and Divide instructions have the same Opcode
259 and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
260 #define MASK_R6_MULDIV(op) (MASK_SPECIAL(op) | (op & (0x7ff)))
263 R6_OPC_MUL
= OPC_MULT
| (2 << 6),
264 R6_OPC_MUH
= OPC_MULT
| (3 << 6),
265 R6_OPC_MULU
= OPC_MULTU
| (2 << 6),
266 R6_OPC_MUHU
= OPC_MULTU
| (3 << 6),
267 R6_OPC_DIV
= OPC_DIV
| (2 << 6),
268 R6_OPC_MOD
= OPC_DIV
| (3 << 6),
269 R6_OPC_DIVU
= OPC_DIVU
| (2 << 6),
270 R6_OPC_MODU
= OPC_DIVU
| (3 << 6),
272 R6_OPC_DMUL
= OPC_DMULT
| (2 << 6),
273 R6_OPC_DMUH
= OPC_DMULT
| (3 << 6),
274 R6_OPC_DMULU
= OPC_DMULTU
| (2 << 6),
275 R6_OPC_DMUHU
= OPC_DMULTU
| (3 << 6),
276 R6_OPC_DDIV
= OPC_DDIV
| (2 << 6),
277 R6_OPC_DMOD
= OPC_DDIV
| (3 << 6),
278 R6_OPC_DDIVU
= OPC_DDIVU
| (2 << 6),
279 R6_OPC_DMODU
= OPC_DDIVU
| (3 << 6),
281 R6_OPC_CLZ
= 0x10 | OPC_SPECIAL
,
282 R6_OPC_CLO
= 0x11 | OPC_SPECIAL
,
283 R6_OPC_DCLZ
= 0x12 | OPC_SPECIAL
,
284 R6_OPC_DCLO
= 0x13 | OPC_SPECIAL
,
285 R6_OPC_SDBBP
= 0x0e | OPC_SPECIAL
,
287 OPC_LSA
= 0x05 | OPC_SPECIAL
,
288 OPC_DLSA
= 0x15 | OPC_SPECIAL
,
291 /* Multiplication variants of the vr54xx. */
292 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
295 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
296 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
297 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
298 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
299 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
300 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
301 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
302 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
303 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
304 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
305 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
306 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
307 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
308 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
311 /* REGIMM (rt field) opcodes */
312 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
315 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
316 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
317 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
318 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
319 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
320 OPC_BLTZALS
= OPC_BLTZAL
| 0x5, /* microMIPS */
321 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
322 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
323 OPC_BGEZALS
= OPC_BGEZAL
| 0x5, /* microMIPS */
324 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
325 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
326 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
327 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
328 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
329 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
330 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
331 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
333 OPC_DAHI
= (0x06 << 16) | OPC_REGIMM
,
334 OPC_DATI
= (0x1e << 16) | OPC_REGIMM
,
337 /* Special2 opcodes */
338 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
341 /* Multiply & xxx operations */
342 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
343 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
344 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
345 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
346 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
348 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
349 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
350 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
351 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
352 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
353 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
354 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
355 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
356 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
357 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
358 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
359 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
361 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
362 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
363 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
364 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
366 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
369 /* Special3 opcodes */
370 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
373 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
374 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
375 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
376 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
377 OPC_INS
= 0x04 | OPC_SPECIAL3
,
378 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
379 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
380 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
381 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
382 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
383 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
384 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
385 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
388 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
389 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
390 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
391 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
392 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
393 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
394 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
395 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
396 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
397 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
398 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
399 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
402 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
403 /* MIPS DSP Arithmetic */
404 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
405 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
406 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
407 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
408 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
409 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
410 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
411 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
412 /* MIPS DSP GPR-Based Shift Sub-class */
413 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
414 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
415 /* MIPS DSP Multiply Sub-class insns */
416 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
417 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
418 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
419 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
420 /* DSP Bit/Manipulation Sub-class */
421 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
422 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
423 /* MIPS DSP Append Sub-class */
424 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
425 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
426 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
427 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
428 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
431 R6_OPC_PREF
= 0x35 | OPC_SPECIAL3
,
432 R6_OPC_CACHE
= 0x25 | OPC_SPECIAL3
,
433 R6_OPC_LL
= 0x36 | OPC_SPECIAL3
,
434 R6_OPC_SC
= 0x26 | OPC_SPECIAL3
,
435 R6_OPC_LLD
= 0x37 | OPC_SPECIAL3
,
436 R6_OPC_SCD
= 0x27 | OPC_SPECIAL3
,
440 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
443 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
444 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
445 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
446 OPC_ALIGN
= (0x08 << 6) | OPC_BSHFL
, /* 010.bp */
447 OPC_ALIGN_END
= (0x0B << 6) | OPC_BSHFL
, /* 010.00 to 010.11 */
448 OPC_BITSWAP
= (0x00 << 6) | OPC_BSHFL
/* 00000 */
452 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
455 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
456 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
457 OPC_DALIGN
= (0x08 << 6) | OPC_DBSHFL
, /* 01.bp */
458 OPC_DALIGN_END
= (0x0F << 6) | OPC_DBSHFL
, /* 01.000 to 01.111 */
459 OPC_DBITSWAP
= (0x00 << 6) | OPC_DBSHFL
, /* 00000 */
462 /* MIPS DSP REGIMM opcodes */
464 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
465 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
468 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
471 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
472 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
473 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
474 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
477 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
479 /* MIPS DSP Arithmetic Sub-class */
480 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
481 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
482 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
483 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
484 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
485 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
486 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
487 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
488 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
489 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
490 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
491 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
492 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
493 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
494 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
495 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
496 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
497 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
498 /* MIPS DSP Multiply Sub-class insns */
499 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
500 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
501 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
502 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
503 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
504 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
507 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
508 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
510 /* MIPS DSP Arithmetic Sub-class */
511 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
512 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
513 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
514 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
515 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
516 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
517 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
518 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
519 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
520 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
521 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
522 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
523 /* MIPS DSP Multiply Sub-class insns */
524 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
525 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
526 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
527 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
530 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
532 /* MIPS DSP Arithmetic Sub-class */
533 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
534 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
535 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
536 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
537 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
538 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
539 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
540 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
541 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
542 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
543 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
544 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
545 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
546 /* DSP Bit/Manipulation Sub-class */
547 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
548 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
549 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
550 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
551 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
554 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
556 /* MIPS DSP Arithmetic Sub-class */
557 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
558 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
559 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
560 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
561 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
562 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
563 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
564 /* DSP Compare-Pick Sub-class */
565 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
566 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
567 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
568 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
569 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
570 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
571 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
572 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
573 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
574 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
575 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
576 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
577 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
578 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
579 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
582 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
584 /* MIPS DSP GPR-Based Shift Sub-class */
585 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
586 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
587 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
588 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
589 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
590 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
591 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
592 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
593 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
594 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
595 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
596 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
597 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
598 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
599 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
600 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
601 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
602 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
603 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
604 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
605 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
606 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
609 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
611 /* MIPS DSP Multiply Sub-class insns */
612 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
613 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
614 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
615 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
616 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
617 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
618 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
619 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
620 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
621 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
622 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
623 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
624 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
625 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
626 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
627 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
628 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
629 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
630 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
631 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
632 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
633 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
636 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
638 /* DSP Bit/Manipulation Sub-class */
639 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
642 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
644 /* MIPS DSP Append Sub-class */
645 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
646 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
647 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
650 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
652 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
653 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
654 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
655 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
656 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
657 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
658 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
659 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
660 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
661 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
662 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
663 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
664 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
665 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
666 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
667 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
668 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
669 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
672 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
674 /* MIPS DSP Arithmetic Sub-class */
675 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
676 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
677 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
678 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
679 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
680 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
681 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
682 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
683 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
684 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
685 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
686 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
687 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
688 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
689 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
690 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
691 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
692 /* DSP Bit/Manipulation Sub-class */
693 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
694 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
695 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
696 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
697 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
698 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
701 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
703 /* MIPS DSP Multiply Sub-class insns */
704 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
705 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
706 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
707 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
708 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
709 /* MIPS DSP Arithmetic Sub-class */
710 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
711 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
712 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
713 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
714 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
715 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
716 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
717 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
718 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
719 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
720 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
721 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
722 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
723 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
724 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
725 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
726 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
727 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
728 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
729 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
730 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
733 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
735 /* DSP Compare-Pick Sub-class */
736 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
737 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
738 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
739 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
740 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
741 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
742 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
743 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
744 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
745 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
746 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
747 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
748 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
749 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
750 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
751 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
752 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
753 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
754 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
755 /* MIPS DSP Arithmetic Sub-class */
756 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
757 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
758 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
759 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
760 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
761 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
762 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
763 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
766 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
768 /* DSP Append Sub-class */
769 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
770 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
771 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
772 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
775 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
777 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
778 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
779 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
780 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
781 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
782 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
783 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
784 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
785 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
786 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
787 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
788 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
789 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
790 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
791 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
792 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
793 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
794 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
795 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
796 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
797 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
798 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
801 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
803 /* DSP Bit/Manipulation Sub-class */
804 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
807 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
809 /* MIPS DSP Multiply Sub-class insns */
810 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
811 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
812 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
813 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
814 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
815 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
816 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
817 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
818 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
819 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
820 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
821 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
822 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
823 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
824 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
825 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
826 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
827 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
828 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
829 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
830 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
831 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
832 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
833 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
834 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
835 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
838 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
840 /* MIPS DSP GPR-Based Shift Sub-class */
841 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
842 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
843 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
844 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
845 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
846 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
847 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
848 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
849 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
850 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
851 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
852 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
853 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
854 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
855 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
856 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
857 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
858 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
859 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
860 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
861 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
862 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
863 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
864 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
865 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
866 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
869 /* Coprocessor 0 (rs field) */
870 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
873 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
874 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
875 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
876 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
877 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
878 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
879 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
880 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
881 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
882 OPC_C0
= (0x10 << 21) | OPC_CP0
,
883 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
884 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
888 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
891 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
892 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
893 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
894 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
895 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
896 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
899 /* Coprocessor 0 (with rs == C0) */
900 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
903 OPC_TLBR
= 0x01 | OPC_C0
,
904 OPC_TLBWI
= 0x02 | OPC_C0
,
905 OPC_TLBWR
= 0x06 | OPC_C0
,
906 OPC_TLBP
= 0x08 | OPC_C0
,
907 OPC_RFE
= 0x10 | OPC_C0
,
908 OPC_ERET
= 0x18 | OPC_C0
,
909 OPC_DERET
= 0x1F | OPC_C0
,
910 OPC_WAIT
= 0x20 | OPC_C0
,
913 /* Coprocessor 1 (rs field) */
914 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
916 /* Values for the fmt field in FP instructions */
918 /* 0 - 15 are reserved */
919 FMT_S
= 16, /* single fp */
920 FMT_D
= 17, /* double fp */
921 FMT_E
= 18, /* extended fp */
922 FMT_Q
= 19, /* quad fp */
923 FMT_W
= 20, /* 32-bit fixed */
924 FMT_L
= 21, /* 64-bit fixed */
925 FMT_PS
= 22, /* paired single fp */
926 /* 23 - 31 are reserved */
930 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
931 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
932 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
933 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
934 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
935 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
936 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
937 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
938 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
939 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
940 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
941 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
942 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
943 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
944 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
945 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
946 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
947 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
948 OPC_BC1EQZ
= (0x09 << 21) | OPC_CP1
,
949 OPC_BC1NEZ
= (0x0D << 21) | OPC_CP1
,
952 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
953 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
956 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
957 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
958 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
959 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
963 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
964 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
968 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
969 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
972 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
975 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
976 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
977 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
978 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
979 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
980 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
981 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
982 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
983 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
984 OPC_BC2EQZ
= (0x09 << 21) | OPC_CP2
,
985 OPC_BC2NEZ
= (0x0D << 21) | OPC_CP2
,
988 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
991 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
992 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
993 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
994 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
995 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
996 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
997 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
998 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
1000 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
1001 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
1002 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
1003 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
1004 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
1005 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
1006 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
1007 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
1009 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
1010 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
1011 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
1012 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
1013 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
1014 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
1015 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
1016 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
1018 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
1019 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
1020 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
1021 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
1022 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
1023 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
1024 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
1025 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
1027 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
1028 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
1029 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
1030 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
1031 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
1032 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
1034 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
1035 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
1036 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
1037 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
1038 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
1039 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
1041 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
1042 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
1043 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
1044 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
1045 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
1046 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
1048 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
1049 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
1050 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
1051 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
1052 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
1053 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
1055 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
1056 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
1057 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
1058 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
1059 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
1060 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
1062 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
1063 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
1064 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
1065 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
1066 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
1067 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
1069 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
1070 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
1071 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
1072 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
1073 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
1074 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
1076 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
1077 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
1078 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
1079 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
1080 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
1081 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
1085 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
1088 OPC_LWXC1
= 0x00 | OPC_CP3
,
1089 OPC_LDXC1
= 0x01 | OPC_CP3
,
1090 OPC_LUXC1
= 0x05 | OPC_CP3
,
1091 OPC_SWXC1
= 0x08 | OPC_CP3
,
1092 OPC_SDXC1
= 0x09 | OPC_CP3
,
1093 OPC_SUXC1
= 0x0D | OPC_CP3
,
1094 OPC_PREFX
= 0x0F | OPC_CP3
,
1095 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
1096 OPC_MADD_S
= 0x20 | OPC_CP3
,
1097 OPC_MADD_D
= 0x21 | OPC_CP3
,
1098 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1099 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1100 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1101 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1102 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1103 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1104 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1105 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1106 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1107 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1110 /* global register indices */
1111 static TCGv_ptr cpu_env
;
1112 static TCGv cpu_gpr
[32], cpu_PC
;
1113 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
], cpu_ACX
[MIPS_DSP_ACC
];
1114 static TCGv cpu_dspctrl
, btarget
, bcond
;
1115 static TCGv_i32 hflags
;
1116 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1117 static TCGv_i64 fpu_f64
[32];
1119 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1120 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1122 #include "exec/gen-icount.h"
1124 #define gen_helper_0e0i(name, arg) do { \
1125 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1126 gen_helper_##name(cpu_env, helper_tmp); \
1127 tcg_temp_free_i32(helper_tmp); \
1130 #define gen_helper_0e1i(name, arg1, arg2) do { \
1131 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1132 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1133 tcg_temp_free_i32(helper_tmp); \
1136 #define gen_helper_1e0i(name, ret, arg1) do { \
1137 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1138 gen_helper_##name(ret, cpu_env, helper_tmp); \
1139 tcg_temp_free_i32(helper_tmp); \
1142 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1143 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1144 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1145 tcg_temp_free_i32(helper_tmp); \
1148 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1149 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1150 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1151 tcg_temp_free_i32(helper_tmp); \
1154 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1155 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1156 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1157 tcg_temp_free_i32(helper_tmp); \
1160 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1161 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1162 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1163 tcg_temp_free_i32(helper_tmp); \
1166 typedef struct DisasContext
{
1167 struct TranslationBlock
*tb
;
1168 target_ulong pc
, saved_pc
;
1170 int singlestep_enabled
;
1172 int32_t CP0_Config1
;
1173 /* Routine used to access memory */
1175 uint32_t hflags
, saved_hflags
;
1177 target_ulong btarget
;
1182 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1183 * exception condition */
1184 BS_STOP
= 1, /* We want to stop translation for any reason */
1185 BS_BRANCH
= 2, /* We reached a branch condition */
1186 BS_EXCP
= 3, /* We reached an exception condition */
1189 static const char * const regnames
[] = {
1190 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1191 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1192 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1193 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1196 static const char * const regnames_HI
[] = {
1197 "HI0", "HI1", "HI2", "HI3",
1200 static const char * const regnames_LO
[] = {
1201 "LO0", "LO1", "LO2", "LO3",
1204 static const char * const regnames_ACX
[] = {
1205 "ACX0", "ACX1", "ACX2", "ACX3",
1208 static const char * const fregnames
[] = {
1209 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1210 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1211 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1212 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1215 #define MIPS_DEBUG(fmt, ...) \
1217 if (MIPS_DEBUG_DISAS) { \
1218 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1219 TARGET_FMT_lx ": %08x " fmt "\n", \
1220 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1224 #define LOG_DISAS(...) \
1226 if (MIPS_DEBUG_DISAS) { \
1227 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1231 #define MIPS_INVAL(op) \
1232 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1233 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1235 /* General purpose registers moves. */
1236 static inline void gen_load_gpr (TCGv t
, int reg
)
1239 tcg_gen_movi_tl(t
, 0);
1241 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1244 static inline void gen_store_gpr (TCGv t
, int reg
)
1247 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1250 /* Moves to/from ACX register. */
1251 static inline void gen_load_ACX (TCGv t
, int reg
)
1253 tcg_gen_mov_tl(t
, cpu_ACX
[reg
]);
1256 static inline void gen_store_ACX (TCGv t
, int reg
)
1258 tcg_gen_mov_tl(cpu_ACX
[reg
], t
);
1261 /* Moves to/from shadow registers. */
1262 static inline void gen_load_srsgpr (int from
, int to
)
1264 TCGv t0
= tcg_temp_new();
1267 tcg_gen_movi_tl(t0
, 0);
1269 TCGv_i32 t2
= tcg_temp_new_i32();
1270 TCGv_ptr addr
= tcg_temp_new_ptr();
1272 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1273 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1274 tcg_gen_andi_i32(t2
, t2
, 0xf);
1275 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1276 tcg_gen_ext_i32_ptr(addr
, t2
);
1277 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1279 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1280 tcg_temp_free_ptr(addr
);
1281 tcg_temp_free_i32(t2
);
1283 gen_store_gpr(t0
, to
);
1287 static inline void gen_store_srsgpr (int from
, int to
)
1290 TCGv t0
= tcg_temp_new();
1291 TCGv_i32 t2
= tcg_temp_new_i32();
1292 TCGv_ptr addr
= tcg_temp_new_ptr();
1294 gen_load_gpr(t0
, from
);
1295 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1296 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1297 tcg_gen_andi_i32(t2
, t2
, 0xf);
1298 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1299 tcg_gen_ext_i32_ptr(addr
, t2
);
1300 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1302 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1303 tcg_temp_free_ptr(addr
);
1304 tcg_temp_free_i32(t2
);
1309 /* Floating point register moves. */
1310 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1312 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1315 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1317 TCGv_i64 t64
= tcg_temp_new_i64();
1318 tcg_gen_extu_i32_i64(t64
, t
);
1319 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1320 tcg_temp_free_i64(t64
);
1323 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1325 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1326 TCGv_i64 t64
= tcg_temp_new_i64();
1327 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1328 tcg_gen_trunc_i64_i32(t
, t64
);
1329 tcg_temp_free_i64(t64
);
1331 gen_load_fpr32(t
, reg
| 1);
1335 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1337 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1338 TCGv_i64 t64
= tcg_temp_new_i64();
1339 tcg_gen_extu_i32_i64(t64
, t
);
1340 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1341 tcg_temp_free_i64(t64
);
1343 gen_store_fpr32(t
, reg
| 1);
1347 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1349 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1350 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1352 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1356 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1358 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1359 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1362 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1363 t0
= tcg_temp_new_i64();
1364 tcg_gen_shri_i64(t0
, t
, 32);
1365 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1366 tcg_temp_free_i64(t0
);
1370 static inline int get_fp_bit (int cc
)
1379 static inline void gen_save_pc(target_ulong pc
)
1381 tcg_gen_movi_tl(cpu_PC
, pc
);
1384 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1386 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1387 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1388 gen_save_pc(ctx
->pc
);
1389 ctx
->saved_pc
= ctx
->pc
;
1391 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1392 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1393 ctx
->saved_hflags
= ctx
->hflags
;
1394 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1400 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1406 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1408 ctx
->saved_hflags
= ctx
->hflags
;
1409 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1415 ctx
->btarget
= env
->btarget
;
1421 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1423 TCGv_i32 texcp
= tcg_const_i32(excp
);
1424 TCGv_i32 terr
= tcg_const_i32(err
);
1425 save_cpu_state(ctx
, 1);
1426 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1427 tcg_temp_free_i32(terr
);
1428 tcg_temp_free_i32(texcp
);
1432 generate_exception (DisasContext
*ctx
, int excp
)
1434 save_cpu_state(ctx
, 1);
1435 gen_helper_0e0i(raise_exception
, excp
);
1438 /* Addresses computation */
1439 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1441 tcg_gen_add_tl(ret
, arg0
, arg1
);
1443 #if defined(TARGET_MIPS64)
1444 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1445 tcg_gen_ext32s_i64(ret
, ret
);
1450 /* Addresses computation (translation time) */
1451 static target_long
addr_add(DisasContext
*ctx
, target_long base
,
1454 target_long sum
= base
+ offset
;
1456 #if defined(TARGET_MIPS64)
1457 if (ctx
->hflags
& MIPS_HFLAG_AWRAP
) {
1464 static inline void check_cp0_enabled(DisasContext
*ctx
)
1466 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1467 generate_exception_err(ctx
, EXCP_CpU
, 0);
1470 static inline void check_cp1_enabled(DisasContext
*ctx
)
1472 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1473 generate_exception_err(ctx
, EXCP_CpU
, 1);
1476 /* Verify that the processor is running with COP1X instructions enabled.
1477 This is associated with the nabla symbol in the MIPS32 and MIPS64
1480 static inline void check_cop1x(DisasContext
*ctx
)
1482 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1483 generate_exception(ctx
, EXCP_RI
);
1486 /* Verify that the processor is running with 64-bit floating-point
1487 operations enabled. */
1489 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1491 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1492 generate_exception(ctx
, EXCP_RI
);
1496 * Verify if floating point register is valid; an operation is not defined
1497 * if bit 0 of any register specification is set and the FR bit in the
1498 * Status register equals zero, since the register numbers specify an
1499 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1500 * in the Status register equals one, both even and odd register numbers
1501 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1503 * Multiple 64 bit wide registers can be checked by calling
1504 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1506 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1508 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1509 generate_exception(ctx
, EXCP_RI
);
1512 /* Verify that the processor is running with DSP instructions enabled.
1513 This is enabled by CP0 Status register MX(24) bit.
1516 static inline void check_dsp(DisasContext
*ctx
)
1518 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1519 if (ctx
->insn_flags
& ASE_DSP
) {
1520 generate_exception(ctx
, EXCP_DSPDIS
);
1522 generate_exception(ctx
, EXCP_RI
);
1527 static inline void check_dspr2(DisasContext
*ctx
)
1529 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1530 if (ctx
->insn_flags
& ASE_DSP
) {
1531 generate_exception(ctx
, EXCP_DSPDIS
);
1533 generate_exception(ctx
, EXCP_RI
);
1538 /* This code generates a "reserved instruction" exception if the
1539 CPU does not support the instruction set corresponding to flags. */
1540 static inline void check_insn(DisasContext
*ctx
, int flags
)
1542 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1543 generate_exception(ctx
, EXCP_RI
);
1547 /* This code generates a "reserved instruction" exception if the
1548 CPU has corresponding flag set which indicates that the instruction
1549 has been removed. */
1550 static inline void check_insn_opc_removed(DisasContext
*ctx
, int flags
)
1552 if (unlikely(ctx
->insn_flags
& flags
)) {
1553 generate_exception(ctx
, EXCP_RI
);
1557 /* This code generates a "reserved instruction" exception if 64-bit
1558 instructions are not enabled. */
1559 static inline void check_mips_64(DisasContext
*ctx
)
1561 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1562 generate_exception(ctx
, EXCP_RI
);
1565 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1566 calling interface for 32 and 64-bit FPRs. No sense in changing
1567 all callers for gen_load_fpr32 when we need the CTX parameter for
1569 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1570 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1571 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1572 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1573 int ft, int fs, int cc) \
1575 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1576 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1579 check_cp1_64bitmode(ctx); \
1585 check_cp1_registers(ctx, fs | ft); \
1593 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1594 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1596 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1597 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1598 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1599 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1600 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1601 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1602 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1603 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1604 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1605 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1606 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1607 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1608 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1609 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1610 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1611 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1614 tcg_temp_free_i##bits (fp0); \
1615 tcg_temp_free_i##bits (fp1); \
1618 FOP_CONDS(, 0, d
, FMT_D
, 64)
1619 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1620 FOP_CONDS(, 0, s
, FMT_S
, 32)
1621 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1622 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1623 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1626 #define FOP_CONDNS(fmt, ifmt, bits, STORE) \
1627 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n, \
1628 int ft, int fs, int fd) \
1630 TCGv_i ## bits fp0 = tcg_temp_new_i ## bits(); \
1631 TCGv_i ## bits fp1 = tcg_temp_new_i ## bits(); \
1634 check_cp1_registers(ctx, fs | ft | fd); \
1637 gen_ldcmp_fpr ## bits(ctx, fp0, fs); \
1638 gen_ldcmp_fpr ## bits(ctx, fp1, ft); \
1641 gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1); \
1644 gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1); \
1647 gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1); \
1650 gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1); \
1653 gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1); \
1656 gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1); \
1659 gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1); \
1662 gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1); \
1665 gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1); \
1668 gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1); \
1671 gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1); \
1674 gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1); \
1677 gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1); \
1680 gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1); \
1683 gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1); \
1686 gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1); \
1689 gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1); \
1692 gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1); \
1695 gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1); \
1698 gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1); \
1701 gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1); \
1704 gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1); \
1710 tcg_temp_free_i ## bits (fp0); \
1711 tcg_temp_free_i ## bits (fp1); \
1714 FOP_CONDNS(d
, FMT_D
, 64, gen_store_fpr64(ctx
, fp0
, fd
))
1715 FOP_CONDNS(s
, FMT_S
, 32, gen_store_fpr32(fp0
, fd
))
1717 #undef gen_ldcmp_fpr32
1718 #undef gen_ldcmp_fpr64
1720 /* load/store instructions. */
1721 #ifdef CONFIG_USER_ONLY
1722 #define OP_LD_ATOMIC(insn,fname) \
1723 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1725 TCGv t0 = tcg_temp_new(); \
1726 tcg_gen_mov_tl(t0, arg1); \
1727 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1728 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1729 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1730 tcg_temp_free(t0); \
1733 #define OP_LD_ATOMIC(insn,fname) \
1734 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1736 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1739 OP_LD_ATOMIC(ll
,ld32s
);
1740 #if defined(TARGET_MIPS64)
1741 OP_LD_ATOMIC(lld
,ld64
);
1745 #ifdef CONFIG_USER_ONLY
1746 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1747 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1749 TCGv t0 = tcg_temp_new(); \
1750 int l1 = gen_new_label(); \
1751 int l2 = gen_new_label(); \
1753 tcg_gen_andi_tl(t0, arg2, almask); \
1754 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1755 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1756 generate_exception(ctx, EXCP_AdES); \
1757 gen_set_label(l1); \
1758 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1759 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1760 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1761 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1762 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1763 gen_helper_0e0i(raise_exception, EXCP_SC); \
1764 gen_set_label(l2); \
1765 tcg_gen_movi_tl(t0, 0); \
1766 gen_store_gpr(t0, rt); \
1767 tcg_temp_free(t0); \
1770 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1771 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1773 TCGv t0 = tcg_temp_new(); \
1774 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1775 gen_store_gpr(t0, rt); \
1776 tcg_temp_free(t0); \
1779 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1780 #if defined(TARGET_MIPS64)
1781 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1785 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1786 int base
, int16_t offset
)
1789 tcg_gen_movi_tl(addr
, offset
);
1790 } else if (offset
== 0) {
1791 gen_load_gpr(addr
, base
);
1793 tcg_gen_movi_tl(addr
, offset
);
1794 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1798 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1800 target_ulong pc
= ctx
->pc
;
1802 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1803 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1808 pc
&= ~(target_ulong
)3;
1813 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1814 int rt
, int base
, int16_t offset
)
1816 const char *opn
= "ld";
1819 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1820 /* Loongson CPU uses a load to zero register for prefetch.
1821 We emulate it as a NOP. On other CPU we must perform the
1822 actual memory access. */
1827 t0
= tcg_temp_new();
1828 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1831 #if defined(TARGET_MIPS64)
1833 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1834 gen_store_gpr(t0
, rt
);
1838 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1839 gen_store_gpr(t0
, rt
);
1844 save_cpu_state(ctx
, 1);
1845 op_ld_lld(t0
, t0
, ctx
);
1846 gen_store_gpr(t0
, rt
);
1850 t1
= tcg_temp_new();
1851 tcg_gen_andi_tl(t1
, t0
, 7);
1852 #ifndef TARGET_WORDS_BIGENDIAN
1853 tcg_gen_xori_tl(t1
, t1
, 7);
1855 tcg_gen_shli_tl(t1
, t1
, 3);
1856 tcg_gen_andi_tl(t0
, t0
, ~7);
1857 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1858 tcg_gen_shl_tl(t0
, t0
, t1
);
1859 tcg_gen_xori_tl(t1
, t1
, 63);
1860 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1861 tcg_gen_shr_tl(t2
, t2
, t1
);
1862 gen_load_gpr(t1
, rt
);
1863 tcg_gen_and_tl(t1
, t1
, t2
);
1865 tcg_gen_or_tl(t0
, t0
, t1
);
1867 gen_store_gpr(t0
, rt
);
1871 t1
= tcg_temp_new();
1872 tcg_gen_andi_tl(t1
, t0
, 7);
1873 #ifdef TARGET_WORDS_BIGENDIAN
1874 tcg_gen_xori_tl(t1
, t1
, 7);
1876 tcg_gen_shli_tl(t1
, t1
, 3);
1877 tcg_gen_andi_tl(t0
, t0
, ~7);
1878 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1879 tcg_gen_shr_tl(t0
, t0
, t1
);
1880 tcg_gen_xori_tl(t1
, t1
, 63);
1881 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1882 tcg_gen_shl_tl(t2
, t2
, t1
);
1883 gen_load_gpr(t1
, rt
);
1884 tcg_gen_and_tl(t1
, t1
, t2
);
1886 tcg_gen_or_tl(t0
, t0
, t1
);
1888 gen_store_gpr(t0
, rt
);
1892 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1893 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1895 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1896 gen_store_gpr(t0
, rt
);
1901 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1902 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1904 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1905 gen_store_gpr(t0
, rt
);
1909 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1910 gen_store_gpr(t0
, rt
);
1914 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
1915 gen_store_gpr(t0
, rt
);
1919 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
1920 gen_store_gpr(t0
, rt
);
1924 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
1925 gen_store_gpr(t0
, rt
);
1929 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
1930 gen_store_gpr(t0
, rt
);
1934 t1
= tcg_temp_new();
1935 tcg_gen_andi_tl(t1
, t0
, 3);
1936 #ifndef TARGET_WORDS_BIGENDIAN
1937 tcg_gen_xori_tl(t1
, t1
, 3);
1939 tcg_gen_shli_tl(t1
, t1
, 3);
1940 tcg_gen_andi_tl(t0
, t0
, ~3);
1941 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1942 tcg_gen_shl_tl(t0
, t0
, t1
);
1943 tcg_gen_xori_tl(t1
, t1
, 31);
1944 t2
= tcg_const_tl(0x7fffffffull
);
1945 tcg_gen_shr_tl(t2
, t2
, t1
);
1946 gen_load_gpr(t1
, rt
);
1947 tcg_gen_and_tl(t1
, t1
, t2
);
1949 tcg_gen_or_tl(t0
, t0
, t1
);
1951 tcg_gen_ext32s_tl(t0
, t0
);
1952 gen_store_gpr(t0
, rt
);
1956 t1
= tcg_temp_new();
1957 tcg_gen_andi_tl(t1
, t0
, 3);
1958 #ifdef TARGET_WORDS_BIGENDIAN
1959 tcg_gen_xori_tl(t1
, t1
, 3);
1961 tcg_gen_shli_tl(t1
, t1
, 3);
1962 tcg_gen_andi_tl(t0
, t0
, ~3);
1963 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1964 tcg_gen_shr_tl(t0
, t0
, t1
);
1965 tcg_gen_xori_tl(t1
, t1
, 31);
1966 t2
= tcg_const_tl(0xfffffffeull
);
1967 tcg_gen_shl_tl(t2
, t2
, t1
);
1968 gen_load_gpr(t1
, rt
);
1969 tcg_gen_and_tl(t1
, t1
, t2
);
1971 tcg_gen_or_tl(t0
, t0
, t1
);
1973 tcg_gen_ext32s_tl(t0
, t0
);
1974 gen_store_gpr(t0
, rt
);
1979 save_cpu_state(ctx
, 1);
1980 op_ld_ll(t0
, t0
, ctx
);
1981 gen_store_gpr(t0
, rt
);
1985 (void)opn
; /* avoid a compiler warning */
1986 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1991 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1992 int base
, int16_t offset
)
1994 const char *opn
= "st";
1995 TCGv t0
= tcg_temp_new();
1996 TCGv t1
= tcg_temp_new();
1998 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1999 gen_load_gpr(t1
, rt
);
2001 #if defined(TARGET_MIPS64)
2003 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
2007 save_cpu_state(ctx
, 1);
2008 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
2012 save_cpu_state(ctx
, 1);
2013 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
2018 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
2022 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
2026 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
2030 save_cpu_state(ctx
, 1);
2031 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
2035 save_cpu_state(ctx
, 1);
2036 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
2040 (void)opn
; /* avoid a compiler warning */
2041 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2047 /* Store conditional */
2048 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
2049 int base
, int16_t offset
)
2051 const char *opn
= "st_cond";
2054 #ifdef CONFIG_USER_ONLY
2055 t0
= tcg_temp_local_new();
2056 t1
= tcg_temp_local_new();
2058 t0
= tcg_temp_new();
2059 t1
= tcg_temp_new();
2061 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2062 gen_load_gpr(t1
, rt
);
2064 #if defined(TARGET_MIPS64)
2067 save_cpu_state(ctx
, 1);
2068 op_st_scd(t1
, t0
, rt
, ctx
);
2074 save_cpu_state(ctx
, 1);
2075 op_st_sc(t1
, t0
, rt
, ctx
);
2079 (void)opn
; /* avoid a compiler warning */
2080 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
2085 /* Load and store */
2086 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
2087 int base
, int16_t offset
)
2089 const char *opn
= "flt_ldst";
2090 TCGv t0
= tcg_temp_new();
2092 gen_base_offset_addr(ctx
, t0
, base
, offset
);
2093 /* Don't do NOP if destination is zero: we must perform the actual
2098 TCGv_i32 fp0
= tcg_temp_new_i32();
2099 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
2100 gen_store_fpr32(fp0
, ft
);
2101 tcg_temp_free_i32(fp0
);
2107 TCGv_i32 fp0
= tcg_temp_new_i32();
2108 gen_load_fpr32(fp0
, ft
);
2109 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
2110 tcg_temp_free_i32(fp0
);
2116 TCGv_i64 fp0
= tcg_temp_new_i64();
2117 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2118 gen_store_fpr64(ctx
, fp0
, ft
);
2119 tcg_temp_free_i64(fp0
);
2125 TCGv_i64 fp0
= tcg_temp_new_i64();
2126 gen_load_fpr64(ctx
, fp0
, ft
);
2127 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
2128 tcg_temp_free_i64(fp0
);
2134 generate_exception(ctx
, EXCP_RI
);
2137 (void)opn
; /* avoid a compiler warning */
2138 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
2143 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
2144 int rs
, int16_t imm
)
2146 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
2147 check_cp1_enabled(ctx
);
2148 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
2150 generate_exception_err(ctx
, EXCP_CpU
, 1);
2154 /* Arithmetic with immediate operand */
2155 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
2156 int rt
, int rs
, int16_t imm
)
2158 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2159 const char *opn
= "imm arith";
2161 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
2162 /* If no destination, treat it as a NOP.
2163 For addi, we must generate the overflow exception when needed. */
2170 TCGv t0
= tcg_temp_local_new();
2171 TCGv t1
= tcg_temp_new();
2172 TCGv t2
= tcg_temp_new();
2173 int l1
= gen_new_label();
2175 gen_load_gpr(t1
, rs
);
2176 tcg_gen_addi_tl(t0
, t1
, uimm
);
2177 tcg_gen_ext32s_tl(t0
, t0
);
2179 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2180 tcg_gen_xori_tl(t2
, t0
, uimm
);
2181 tcg_gen_and_tl(t1
, t1
, t2
);
2183 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2185 /* operands of same sign, result different sign */
2186 generate_exception(ctx
, EXCP_OVERFLOW
);
2188 tcg_gen_ext32s_tl(t0
, t0
);
2189 gen_store_gpr(t0
, rt
);
2196 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2197 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2199 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2203 #if defined(TARGET_MIPS64)
2206 TCGv t0
= tcg_temp_local_new();
2207 TCGv t1
= tcg_temp_new();
2208 TCGv t2
= tcg_temp_new();
2209 int l1
= gen_new_label();
2211 gen_load_gpr(t1
, rs
);
2212 tcg_gen_addi_tl(t0
, t1
, uimm
);
2214 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2215 tcg_gen_xori_tl(t2
, t0
, uimm
);
2216 tcg_gen_and_tl(t1
, t1
, t2
);
2218 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2220 /* operands of same sign, result different sign */
2221 generate_exception(ctx
, EXCP_OVERFLOW
);
2223 gen_store_gpr(t0
, rt
);
2230 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2232 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2238 (void)opn
; /* avoid a compiler warning */
2239 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2242 /* Logic with immediate operand */
2243 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2244 int rt
, int rs
, int16_t imm
)
2249 /* If no destination, treat it as a NOP. */
2253 uimm
= (uint16_t)imm
;
2256 if (likely(rs
!= 0))
2257 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2259 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2260 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2261 regnames
[rs
], uimm
);
2265 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2267 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2268 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2269 regnames
[rs
], uimm
);
2272 if (likely(rs
!= 0))
2273 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2275 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2276 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2277 regnames
[rs
], uimm
);
2280 if (rs
!= 0 && (ctx
->insn_flags
& ISA_MIPS32R6
)) {
2282 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], imm
<< 16);
2283 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
2284 MIPS_DEBUG("aui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
2286 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2287 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2292 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2297 /* Set on less than with immediate operand */
2298 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2299 int rt
, int rs
, int16_t imm
)
2301 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2302 const char *opn
= "imm arith";
2306 /* If no destination, treat it as a NOP. */
2310 t0
= tcg_temp_new();
2311 gen_load_gpr(t0
, rs
);
2314 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2318 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2322 (void)opn
; /* avoid a compiler warning */
2323 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2327 /* Shifts with immediate operand */
2328 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2329 int rt
, int rs
, int16_t imm
)
2331 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2332 const char *opn
= "imm shift";
2336 /* If no destination, treat it as a NOP. */
2341 t0
= tcg_temp_new();
2342 gen_load_gpr(t0
, rs
);
2345 tcg_gen_shli_tl(t0
, t0
, uimm
);
2346 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2350 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2355 tcg_gen_ext32u_tl(t0
, t0
);
2356 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2358 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2364 TCGv_i32 t1
= tcg_temp_new_i32();
2366 tcg_gen_trunc_tl_i32(t1
, t0
);
2367 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2368 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2369 tcg_temp_free_i32(t1
);
2371 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2375 #if defined(TARGET_MIPS64)
2377 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2381 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2385 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2390 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2392 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2397 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2401 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2405 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2409 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2414 (void)opn
; /* avoid a compiler warning */
2415 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2420 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2421 int rd
, int rs
, int rt
)
2423 const char *opn
= "arith";
2425 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2426 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2427 /* If no destination, treat it as a NOP.
2428 For add & sub, we must generate the overflow exception when needed. */
2436 TCGv t0
= tcg_temp_local_new();
2437 TCGv t1
= tcg_temp_new();
2438 TCGv t2
= tcg_temp_new();
2439 int l1
= gen_new_label();
2441 gen_load_gpr(t1
, rs
);
2442 gen_load_gpr(t2
, rt
);
2443 tcg_gen_add_tl(t0
, t1
, t2
);
2444 tcg_gen_ext32s_tl(t0
, t0
);
2445 tcg_gen_xor_tl(t1
, t1
, t2
);
2446 tcg_gen_xor_tl(t2
, t0
, t2
);
2447 tcg_gen_andc_tl(t1
, t2
, t1
);
2449 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2451 /* operands of same sign, result different sign */
2452 generate_exception(ctx
, EXCP_OVERFLOW
);
2454 gen_store_gpr(t0
, rd
);
2460 if (rs
!= 0 && rt
!= 0) {
2461 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2462 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2463 } else if (rs
== 0 && rt
!= 0) {
2464 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2465 } else if (rs
!= 0 && rt
== 0) {
2466 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2468 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2474 TCGv t0
= tcg_temp_local_new();
2475 TCGv t1
= tcg_temp_new();
2476 TCGv t2
= tcg_temp_new();
2477 int l1
= gen_new_label();
2479 gen_load_gpr(t1
, rs
);
2480 gen_load_gpr(t2
, rt
);
2481 tcg_gen_sub_tl(t0
, t1
, t2
);
2482 tcg_gen_ext32s_tl(t0
, t0
);
2483 tcg_gen_xor_tl(t2
, t1
, t2
);
2484 tcg_gen_xor_tl(t1
, t0
, t1
);
2485 tcg_gen_and_tl(t1
, t1
, t2
);
2487 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2489 /* operands of different sign, first operand and result different sign */
2490 generate_exception(ctx
, EXCP_OVERFLOW
);
2492 gen_store_gpr(t0
, rd
);
2498 if (rs
!= 0 && rt
!= 0) {
2499 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2500 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2501 } else if (rs
== 0 && rt
!= 0) {
2502 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2503 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2504 } else if (rs
!= 0 && rt
== 0) {
2505 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2507 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2511 #if defined(TARGET_MIPS64)
2514 TCGv t0
= tcg_temp_local_new();
2515 TCGv t1
= tcg_temp_new();
2516 TCGv t2
= tcg_temp_new();
2517 int l1
= gen_new_label();
2519 gen_load_gpr(t1
, rs
);
2520 gen_load_gpr(t2
, rt
);
2521 tcg_gen_add_tl(t0
, t1
, t2
);
2522 tcg_gen_xor_tl(t1
, t1
, t2
);
2523 tcg_gen_xor_tl(t2
, t0
, t2
);
2524 tcg_gen_andc_tl(t1
, t2
, t1
);
2526 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2528 /* operands of same sign, result different sign */
2529 generate_exception(ctx
, EXCP_OVERFLOW
);
2531 gen_store_gpr(t0
, rd
);
2537 if (rs
!= 0 && rt
!= 0) {
2538 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2539 } else if (rs
== 0 && rt
!= 0) {
2540 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2541 } else if (rs
!= 0 && rt
== 0) {
2542 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2544 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2550 TCGv t0
= tcg_temp_local_new();
2551 TCGv t1
= tcg_temp_new();
2552 TCGv t2
= tcg_temp_new();
2553 int l1
= gen_new_label();
2555 gen_load_gpr(t1
, rs
);
2556 gen_load_gpr(t2
, rt
);
2557 tcg_gen_sub_tl(t0
, t1
, t2
);
2558 tcg_gen_xor_tl(t2
, t1
, t2
);
2559 tcg_gen_xor_tl(t1
, t0
, t1
);
2560 tcg_gen_and_tl(t1
, t1
, t2
);
2562 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2564 /* operands of different sign, first operand and result different sign */
2565 generate_exception(ctx
, EXCP_OVERFLOW
);
2567 gen_store_gpr(t0
, rd
);
2573 if (rs
!= 0 && rt
!= 0) {
2574 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2575 } else if (rs
== 0 && rt
!= 0) {
2576 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2577 } else if (rs
!= 0 && rt
== 0) {
2578 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2580 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2586 if (likely(rs
!= 0 && rt
!= 0)) {
2587 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2588 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2590 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2595 (void)opn
; /* avoid a compiler warning */
2596 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2599 /* Conditional move */
2600 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2601 int rd
, int rs
, int rt
)
2603 const char *opn
= "cond move";
2607 /* If no destination, treat it as a NOP. */
2612 t0
= tcg_temp_new();
2613 gen_load_gpr(t0
, rt
);
2614 t1
= tcg_const_tl(0);
2615 t2
= tcg_temp_new();
2616 gen_load_gpr(t2
, rs
);
2619 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2623 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2627 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2631 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, t1
);
2639 (void)opn
; /* avoid a compiler warning */
2640 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2644 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2645 int rd
, int rs
, int rt
)
2647 const char *opn
= "logic";
2650 /* If no destination, treat it as a NOP. */
2657 if (likely(rs
!= 0 && rt
!= 0)) {
2658 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2660 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2665 if (rs
!= 0 && rt
!= 0) {
2666 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2667 } else if (rs
== 0 && rt
!= 0) {
2668 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2669 } else if (rs
!= 0 && rt
== 0) {
2670 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2672 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2677 if (likely(rs
!= 0 && rt
!= 0)) {
2678 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2679 } else if (rs
== 0 && rt
!= 0) {
2680 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2681 } else if (rs
!= 0 && rt
== 0) {
2682 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2684 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2689 if (likely(rs
!= 0 && rt
!= 0)) {
2690 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2691 } else if (rs
== 0 && rt
!= 0) {
2692 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2693 } else if (rs
!= 0 && rt
== 0) {
2694 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2696 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2701 (void)opn
; /* avoid a compiler warning */
2702 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2705 /* Set on lower than */
2706 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2707 int rd
, int rs
, int rt
)
2709 const char *opn
= "slt";
2713 /* If no destination, treat it as a NOP. */
2718 t0
= tcg_temp_new();
2719 t1
= tcg_temp_new();
2720 gen_load_gpr(t0
, rs
);
2721 gen_load_gpr(t1
, rt
);
2724 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2728 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2732 (void)opn
; /* avoid a compiler warning */
2733 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2739 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2740 int rd
, int rs
, int rt
)
2742 const char *opn
= "shifts";
2746 /* If no destination, treat it as a NOP.
2747 For add & sub, we must generate the overflow exception when needed. */
2752 t0
= tcg_temp_new();
2753 t1
= tcg_temp_new();
2754 gen_load_gpr(t0
, rs
);
2755 gen_load_gpr(t1
, rt
);
2758 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2759 tcg_gen_shl_tl(t0
, t1
, t0
);
2760 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2764 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2765 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2769 tcg_gen_ext32u_tl(t1
, t1
);
2770 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2771 tcg_gen_shr_tl(t0
, t1
, t0
);
2772 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2777 TCGv_i32 t2
= tcg_temp_new_i32();
2778 TCGv_i32 t3
= tcg_temp_new_i32();
2780 tcg_gen_trunc_tl_i32(t2
, t0
);
2781 tcg_gen_trunc_tl_i32(t3
, t1
);
2782 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2783 tcg_gen_rotr_i32(t2
, t3
, t2
);
2784 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2785 tcg_temp_free_i32(t2
);
2786 tcg_temp_free_i32(t3
);
2790 #if defined(TARGET_MIPS64)
2792 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2793 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2797 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2798 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2802 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2803 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2807 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2808 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2813 (void)opn
; /* avoid a compiler warning */
2814 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2819 /* Arithmetic on HI/LO registers */
2820 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2822 const char *opn
= "hilo";
2824 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2836 #if defined(TARGET_MIPS64)
2838 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2842 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2847 #if defined(TARGET_MIPS64)
2849 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2853 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2859 #if defined(TARGET_MIPS64)
2861 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2865 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2868 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2874 #if defined(TARGET_MIPS64)
2876 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2880 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2883 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2888 (void)opn
; /* avoid a compiler warning */
2889 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2892 static inline void gen_r6_ld(target_long addr
, int reg
, int memidx
,
2895 TCGv t0
= tcg_const_tl(addr
);
2896 tcg_gen_qemu_ld_tl(t0
, t0
, memidx
, memop
);
2897 gen_store_gpr(t0
, reg
);
2901 static inline void gen_pcrel(DisasContext
*ctx
, int rs
, int16_t imm
)
2906 switch (MASK_OPC_PCREL_TOP2BITS(ctx
->opcode
)) {
2909 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
2910 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2911 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
2915 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
2916 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2917 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TESL
);
2919 #if defined(TARGET_MIPS64)
2922 offset
= sextract32(ctx
->opcode
<< 2, 0, 21);
2923 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2924 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEUL
);
2928 switch (MASK_OPC_PCREL_TOP5BITS(ctx
->opcode
)) {
2932 addr
= addr_add(ctx
, ctx
->pc
, offset
);
2933 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
2939 addr
= ~0xFFFF & addr_add(ctx
, ctx
->pc
, offset
);
2940 tcg_gen_movi_tl(cpu_gpr
[rs
], addr
);
2943 #if defined(TARGET_MIPS64)
2944 case R6_OPC_LDPC
: /* bits 16 and 17 are part of immediate */
2945 case R6_OPC_LDPC
+ (1 << 16):
2946 case R6_OPC_LDPC
+ (2 << 16):
2947 case R6_OPC_LDPC
+ (3 << 16):
2949 offset
= sextract32(ctx
->opcode
<< 3, 0, 21);
2950 addr
= addr_add(ctx
, (ctx
->pc
& ~0x7), offset
);
2951 gen_r6_ld(addr
, rs
, ctx
->mem_idx
, MO_TEQ
);
2955 MIPS_INVAL("OPC_PCREL");
2956 generate_exception(ctx
, EXCP_RI
);
2963 static void gen_r6_muldiv(DisasContext
*ctx
, int opc
, int rd
, int rs
, int rt
)
2965 const char *opn
= "r6 mul/div";
2974 t0
= tcg_temp_new();
2975 t1
= tcg_temp_new();
2977 gen_load_gpr(t0
, rs
);
2978 gen_load_gpr(t1
, rt
);
2983 TCGv t2
= tcg_temp_new();
2984 TCGv t3
= tcg_temp_new();
2985 tcg_gen_ext32s_tl(t0
, t0
);
2986 tcg_gen_ext32s_tl(t1
, t1
);
2987 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2988 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2989 tcg_gen_and_tl(t2
, t2
, t3
);
2990 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2991 tcg_gen_or_tl(t2
, t2
, t3
);
2992 tcg_gen_movi_tl(t3
, 0);
2993 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2994 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
2995 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3003 TCGv t2
= tcg_temp_new();
3004 TCGv t3
= tcg_temp_new();
3005 tcg_gen_ext32s_tl(t0
, t0
);
3006 tcg_gen_ext32s_tl(t1
, t1
);
3007 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3008 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3009 tcg_gen_and_tl(t2
, t2
, t3
);
3010 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3011 tcg_gen_or_tl(t2
, t2
, t3
);
3012 tcg_gen_movi_tl(t3
, 0);
3013 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3014 tcg_gen_rem_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_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3029 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3037 TCGv t2
= tcg_const_tl(0);
3038 TCGv t3
= tcg_const_tl(1);
3039 tcg_gen_ext32u_tl(t0
, t0
);
3040 tcg_gen_ext32u_tl(t1
, t1
);
3041 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3042 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3043 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3051 TCGv_i32 t2
= tcg_temp_new_i32();
3052 TCGv_i32 t3
= tcg_temp_new_i32();
3053 tcg_gen_trunc_tl_i32(t2
, t0
);
3054 tcg_gen_trunc_tl_i32(t3
, t1
);
3055 tcg_gen_mul_i32(t2
, t2
, t3
);
3056 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3057 tcg_temp_free_i32(t2
);
3058 tcg_temp_free_i32(t3
);
3064 TCGv_i32 t2
= tcg_temp_new_i32();
3065 TCGv_i32 t3
= tcg_temp_new_i32();
3066 tcg_gen_trunc_tl_i32(t2
, t0
);
3067 tcg_gen_trunc_tl_i32(t3
, t1
);
3068 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
3069 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3070 tcg_temp_free_i32(t2
);
3071 tcg_temp_free_i32(t3
);
3077 TCGv_i32 t2
= tcg_temp_new_i32();
3078 TCGv_i32 t3
= tcg_temp_new_i32();
3079 tcg_gen_trunc_tl_i32(t2
, t0
);
3080 tcg_gen_trunc_tl_i32(t3
, t1
);
3081 tcg_gen_mul_i32(t2
, t2
, t3
);
3082 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
3083 tcg_temp_free_i32(t2
);
3084 tcg_temp_free_i32(t3
);
3090 TCGv_i32 t2
= tcg_temp_new_i32();
3091 TCGv_i32 t3
= tcg_temp_new_i32();
3092 tcg_gen_trunc_tl_i32(t2
, t0
);
3093 tcg_gen_trunc_tl_i32(t3
, t1
);
3094 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3095 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t3
);
3096 tcg_temp_free_i32(t2
);
3097 tcg_temp_free_i32(t3
);
3101 #if defined(TARGET_MIPS64)
3104 TCGv t2
= tcg_temp_new();
3105 TCGv t3
= tcg_temp_new();
3106 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3107 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3108 tcg_gen_and_tl(t2
, t2
, t3
);
3109 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3110 tcg_gen_or_tl(t2
, t2
, t3
);
3111 tcg_gen_movi_tl(t3
, 0);
3112 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3113 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3121 TCGv t2
= tcg_temp_new();
3122 TCGv t3
= tcg_temp_new();
3123 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3124 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3125 tcg_gen_and_tl(t2
, t2
, t3
);
3126 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3127 tcg_gen_or_tl(t2
, t2
, t3
);
3128 tcg_gen_movi_tl(t3
, 0);
3129 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3130 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3138 TCGv t2
= tcg_const_tl(0);
3139 TCGv t3
= tcg_const_tl(1);
3140 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3141 tcg_gen_divu_i64(cpu_gpr
[rd
], t0
, t1
);
3149 TCGv t2
= tcg_const_tl(0);
3150 TCGv t3
= tcg_const_tl(1);
3151 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3152 tcg_gen_remu_i64(cpu_gpr
[rd
], t0
, t1
);
3159 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3164 TCGv t2
= tcg_temp_new();
3165 tcg_gen_muls2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3171 tcg_gen_mul_i64(cpu_gpr
[rd
], t0
, t1
);
3176 TCGv t2
= tcg_temp_new();
3177 tcg_gen_mulu2_i64(t2
, cpu_gpr
[rd
], t0
, t1
);
3185 generate_exception(ctx
, EXCP_RI
);
3188 (void)opn
; /* avoid a compiler warning */
3189 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3195 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
3196 int acc
, int rs
, int rt
)
3198 const char *opn
= "mul/div";
3201 t0
= tcg_temp_new();
3202 t1
= tcg_temp_new();
3204 gen_load_gpr(t0
, rs
);
3205 gen_load_gpr(t1
, rt
);
3214 TCGv t2
= tcg_temp_new();
3215 TCGv t3
= tcg_temp_new();
3216 tcg_gen_ext32s_tl(t0
, t0
);
3217 tcg_gen_ext32s_tl(t1
, t1
);
3218 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
3219 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
3220 tcg_gen_and_tl(t2
, t2
, t3
);
3221 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3222 tcg_gen_or_tl(t2
, t2
, t3
);
3223 tcg_gen_movi_tl(t3
, 0);
3224 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3225 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3226 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3227 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3228 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
3236 TCGv t2
= tcg_const_tl(0);
3237 TCGv t3
= tcg_const_tl(1);
3238 tcg_gen_ext32u_tl(t0
, t0
);
3239 tcg_gen_ext32u_tl(t1
, t1
);
3240 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3241 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
3242 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
3243 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
3244 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
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_muls2_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
);
3266 TCGv_i32 t2
= tcg_temp_new_i32();
3267 TCGv_i32 t3
= tcg_temp_new_i32();
3268 tcg_gen_trunc_tl_i32(t2
, t0
);
3269 tcg_gen_trunc_tl_i32(t3
, t1
);
3270 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
3271 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
3272 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
3273 tcg_temp_free_i32(t2
);
3274 tcg_temp_free_i32(t3
);
3278 #if defined(TARGET_MIPS64)
3281 TCGv t2
= tcg_temp_new();
3282 TCGv t3
= tcg_temp_new();
3283 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
3284 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
3285 tcg_gen_and_tl(t2
, t2
, t3
);
3286 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
3287 tcg_gen_or_tl(t2
, t2
, t3
);
3288 tcg_gen_movi_tl(t3
, 0);
3289 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
3290 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
3291 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
3299 TCGv t2
= tcg_const_tl(0);
3300 TCGv t3
= tcg_const_tl(1);
3301 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
3302 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
3303 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
3310 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3314 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
3320 TCGv_i64 t2
= tcg_temp_new_i64();
3321 TCGv_i64 t3
= tcg_temp_new_i64();
3323 tcg_gen_ext_tl_i64(t2
, t0
);
3324 tcg_gen_ext_tl_i64(t3
, t1
);
3325 tcg_gen_mul_i64(t2
, t2
, t3
);
3326 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3327 tcg_gen_add_i64(t2
, t2
, t3
);
3328 tcg_temp_free_i64(t3
);
3329 tcg_gen_trunc_i64_tl(t0
, t2
);
3330 tcg_gen_shri_i64(t2
, t2
, 32);
3331 tcg_gen_trunc_i64_tl(t1
, t2
);
3332 tcg_temp_free_i64(t2
);
3333 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3334 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3340 TCGv_i64 t2
= tcg_temp_new_i64();
3341 TCGv_i64 t3
= tcg_temp_new_i64();
3343 tcg_gen_ext32u_tl(t0
, t0
);
3344 tcg_gen_ext32u_tl(t1
, t1
);
3345 tcg_gen_extu_tl_i64(t2
, t0
);
3346 tcg_gen_extu_tl_i64(t3
, t1
);
3347 tcg_gen_mul_i64(t2
, t2
, t3
);
3348 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3349 tcg_gen_add_i64(t2
, t2
, t3
);
3350 tcg_temp_free_i64(t3
);
3351 tcg_gen_trunc_i64_tl(t0
, t2
);
3352 tcg_gen_shri_i64(t2
, t2
, 32);
3353 tcg_gen_trunc_i64_tl(t1
, t2
);
3354 tcg_temp_free_i64(t2
);
3355 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3356 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3362 TCGv_i64 t2
= tcg_temp_new_i64();
3363 TCGv_i64 t3
= tcg_temp_new_i64();
3365 tcg_gen_ext_tl_i64(t2
, t0
);
3366 tcg_gen_ext_tl_i64(t3
, t1
);
3367 tcg_gen_mul_i64(t2
, t2
, t3
);
3368 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3369 tcg_gen_sub_i64(t2
, t3
, t2
);
3370 tcg_temp_free_i64(t3
);
3371 tcg_gen_trunc_i64_tl(t0
, t2
);
3372 tcg_gen_shri_i64(t2
, t2
, 32);
3373 tcg_gen_trunc_i64_tl(t1
, t2
);
3374 tcg_temp_free_i64(t2
);
3375 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3376 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3382 TCGv_i64 t2
= tcg_temp_new_i64();
3383 TCGv_i64 t3
= tcg_temp_new_i64();
3385 tcg_gen_ext32u_tl(t0
, t0
);
3386 tcg_gen_ext32u_tl(t1
, t1
);
3387 tcg_gen_extu_tl_i64(t2
, t0
);
3388 tcg_gen_extu_tl_i64(t3
, t1
);
3389 tcg_gen_mul_i64(t2
, t2
, t3
);
3390 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
3391 tcg_gen_sub_i64(t2
, t3
, t2
);
3392 tcg_temp_free_i64(t3
);
3393 tcg_gen_trunc_i64_tl(t0
, t2
);
3394 tcg_gen_shri_i64(t2
, t2
, 32);
3395 tcg_gen_trunc_i64_tl(t1
, t2
);
3396 tcg_temp_free_i64(t2
);
3397 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
3398 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
3404 generate_exception(ctx
, EXCP_RI
);
3407 (void)opn
; /* avoid a compiler warning */
3408 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
3414 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
3415 int rd
, int rs
, int rt
)
3417 const char *opn
= "mul vr54xx";
3418 TCGv t0
= tcg_temp_new();
3419 TCGv t1
= tcg_temp_new();
3421 gen_load_gpr(t0
, rs
);
3422 gen_load_gpr(t1
, rt
);
3425 case OPC_VR54XX_MULS
:
3426 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
3429 case OPC_VR54XX_MULSU
:
3430 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
3433 case OPC_VR54XX_MACC
:
3434 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
3437 case OPC_VR54XX_MACCU
:
3438 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
3441 case OPC_VR54XX_MSAC
:
3442 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
3445 case OPC_VR54XX_MSACU
:
3446 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
3449 case OPC_VR54XX_MULHI
:
3450 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
3453 case OPC_VR54XX_MULHIU
:
3454 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
3457 case OPC_VR54XX_MULSHI
:
3458 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
3461 case OPC_VR54XX_MULSHIU
:
3462 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
3465 case OPC_VR54XX_MACCHI
:
3466 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
3469 case OPC_VR54XX_MACCHIU
:
3470 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
3473 case OPC_VR54XX_MSACHI
:
3474 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
3477 case OPC_VR54XX_MSACHIU
:
3478 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
3482 MIPS_INVAL("mul vr54xx");
3483 generate_exception(ctx
, EXCP_RI
);
3486 gen_store_gpr(t0
, rd
);
3487 (void)opn
; /* avoid a compiler warning */
3488 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
3495 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
3498 const char *opn
= "CLx";
3506 t0
= tcg_temp_new();
3507 gen_load_gpr(t0
, rs
);
3511 gen_helper_clo(cpu_gpr
[rd
], t0
);
3516 gen_helper_clz(cpu_gpr
[rd
], t0
);
3519 #if defined(TARGET_MIPS64)
3522 gen_helper_dclo(cpu_gpr
[rd
], t0
);
3527 gen_helper_dclz(cpu_gpr
[rd
], t0
);
3532 (void)opn
; /* avoid a compiler warning */
3533 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3537 /* Godson integer instructions */
3538 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3539 int rd
, int rs
, int rt
)
3541 const char *opn
= "loongson";
3553 case OPC_MULTU_G_2E
:
3554 case OPC_MULTU_G_2F
:
3555 #if defined(TARGET_MIPS64)
3556 case OPC_DMULT_G_2E
:
3557 case OPC_DMULT_G_2F
:
3558 case OPC_DMULTU_G_2E
:
3559 case OPC_DMULTU_G_2F
:
3561 t0
= tcg_temp_new();
3562 t1
= tcg_temp_new();
3565 t0
= tcg_temp_local_new();
3566 t1
= tcg_temp_local_new();
3570 gen_load_gpr(t0
, rs
);
3571 gen_load_gpr(t1
, rt
);
3576 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3577 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3580 case OPC_MULTU_G_2E
:
3581 case OPC_MULTU_G_2F
:
3582 tcg_gen_ext32u_tl(t0
, t0
);
3583 tcg_gen_ext32u_tl(t1
, t1
);
3584 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3585 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3591 int l1
= gen_new_label();
3592 int l2
= gen_new_label();
3593 int l3
= gen_new_label();
3594 tcg_gen_ext32s_tl(t0
, t0
);
3595 tcg_gen_ext32s_tl(t1
, t1
);
3596 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3597 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3600 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3601 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3602 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3605 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3606 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3614 int l1
= gen_new_label();
3615 int l2
= gen_new_label();
3616 tcg_gen_ext32u_tl(t0
, t0
);
3617 tcg_gen_ext32u_tl(t1
, t1
);
3618 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3619 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3622 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3623 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3631 int l1
= gen_new_label();
3632 int l2
= gen_new_label();
3633 int l3
= gen_new_label();
3634 tcg_gen_ext32u_tl(t0
, t0
);
3635 tcg_gen_ext32u_tl(t1
, t1
);
3636 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3637 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3638 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3640 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3643 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3644 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3652 int l1
= gen_new_label();
3653 int l2
= gen_new_label();
3654 tcg_gen_ext32u_tl(t0
, t0
);
3655 tcg_gen_ext32u_tl(t1
, t1
);
3656 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3657 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3660 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3661 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3666 #if defined(TARGET_MIPS64)
3667 case OPC_DMULT_G_2E
:
3668 case OPC_DMULT_G_2F
:
3669 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3672 case OPC_DMULTU_G_2E
:
3673 case OPC_DMULTU_G_2F
:
3674 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3680 int l1
= gen_new_label();
3681 int l2
= gen_new_label();
3682 int l3
= gen_new_label();
3683 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3684 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3687 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3688 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3689 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3692 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3697 case OPC_DDIVU_G_2E
:
3698 case OPC_DDIVU_G_2F
:
3700 int l1
= gen_new_label();
3701 int l2
= gen_new_label();
3702 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3703 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3706 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3714 int l1
= gen_new_label();
3715 int l2
= gen_new_label();
3716 int l3
= gen_new_label();
3717 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3718 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3719 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3721 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3724 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3729 case OPC_DMODU_G_2E
:
3730 case OPC_DMODU_G_2F
:
3732 int l1
= gen_new_label();
3733 int l2
= gen_new_label();
3734 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3735 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3738 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3746 (void)opn
; /* avoid a compiler warning */
3747 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3752 /* Loongson multimedia instructions */
3753 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3755 const char *opn
= "loongson_cp2";
3756 uint32_t opc
, shift_max
;
3759 opc
= MASK_LMI(ctx
->opcode
);
3765 t0
= tcg_temp_local_new_i64();
3766 t1
= tcg_temp_local_new_i64();
3769 t0
= tcg_temp_new_i64();
3770 t1
= tcg_temp_new_i64();
3774 gen_load_fpr64(ctx
, t0
, rs
);
3775 gen_load_fpr64(ctx
, t1
, rt
);
3777 #define LMI_HELPER(UP, LO) \
3778 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3779 #define LMI_HELPER_1(UP, LO) \
3780 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3781 #define LMI_DIRECT(UP, LO, OP) \
3782 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3785 LMI_HELPER(PADDSH
, paddsh
);
3786 LMI_HELPER(PADDUSH
, paddush
);
3787 LMI_HELPER(PADDH
, paddh
);
3788 LMI_HELPER(PADDW
, paddw
);
3789 LMI_HELPER(PADDSB
, paddsb
);
3790 LMI_HELPER(PADDUSB
, paddusb
);
3791 LMI_HELPER(PADDB
, paddb
);
3793 LMI_HELPER(PSUBSH
, psubsh
);
3794 LMI_HELPER(PSUBUSH
, psubush
);
3795 LMI_HELPER(PSUBH
, psubh
);
3796 LMI_HELPER(PSUBW
, psubw
);
3797 LMI_HELPER(PSUBSB
, psubsb
);
3798 LMI_HELPER(PSUBUSB
, psubusb
);
3799 LMI_HELPER(PSUBB
, psubb
);
3801 LMI_HELPER(PSHUFH
, pshufh
);
3802 LMI_HELPER(PACKSSWH
, packsswh
);
3803 LMI_HELPER(PACKSSHB
, packsshb
);
3804 LMI_HELPER(PACKUSHB
, packushb
);
3806 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3807 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3808 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3809 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3810 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3811 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3813 LMI_HELPER(PAVGH
, pavgh
);
3814 LMI_HELPER(PAVGB
, pavgb
);
3815 LMI_HELPER(PMAXSH
, pmaxsh
);
3816 LMI_HELPER(PMINSH
, pminsh
);
3817 LMI_HELPER(PMAXUB
, pmaxub
);
3818 LMI_HELPER(PMINUB
, pminub
);
3820 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3821 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3822 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3823 LMI_HELPER(PCMPGTH
, pcmpgth
);
3824 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3825 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3827 LMI_HELPER(PSLLW
, psllw
);
3828 LMI_HELPER(PSLLH
, psllh
);
3829 LMI_HELPER(PSRLW
, psrlw
);
3830 LMI_HELPER(PSRLH
, psrlh
);
3831 LMI_HELPER(PSRAW
, psraw
);
3832 LMI_HELPER(PSRAH
, psrah
);
3834 LMI_HELPER(PMULLH
, pmullh
);
3835 LMI_HELPER(PMULHH
, pmulhh
);
3836 LMI_HELPER(PMULHUH
, pmulhuh
);
3837 LMI_HELPER(PMADDHW
, pmaddhw
);
3839 LMI_HELPER(PASUBUB
, pasubub
);
3840 LMI_HELPER_1(BIADD
, biadd
);
3841 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3843 LMI_DIRECT(PADDD
, paddd
, add
);
3844 LMI_DIRECT(PSUBD
, psubd
, sub
);
3845 LMI_DIRECT(XOR_CP2
, xor, xor);
3846 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3847 LMI_DIRECT(AND_CP2
, and, and);
3848 LMI_DIRECT(PANDN
, pandn
, andc
);
3849 LMI_DIRECT(OR
, or, or);
3852 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3856 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3860 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3864 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3869 tcg_gen_andi_i64(t1
, t1
, 3);
3870 tcg_gen_shli_i64(t1
, t1
, 4);
3871 tcg_gen_shr_i64(t0
, t0
, t1
);
3872 tcg_gen_ext16u_i64(t0
, t0
);
3877 tcg_gen_add_i64(t0
, t0
, t1
);
3878 tcg_gen_ext32s_i64(t0
, t0
);
3882 tcg_gen_sub_i64(t0
, t0
, t1
);
3883 tcg_gen_ext32s_i64(t0
, t0
);
3912 /* Make sure shift count isn't TCG undefined behaviour. */
3913 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3918 tcg_gen_shl_i64(t0
, t0
, t1
);
3922 /* Since SRA is UndefinedResult without sign-extended inputs,
3923 we can treat SRA and DSRA the same. */
3924 tcg_gen_sar_i64(t0
, t0
, t1
);
3927 /* We want to shift in zeros for SRL; zero-extend first. */
3928 tcg_gen_ext32u_i64(t0
, t0
);
3931 tcg_gen_shr_i64(t0
, t0
, t1
);
3935 if (shift_max
== 32) {
3936 tcg_gen_ext32s_i64(t0
, t0
);
3939 /* Shifts larger than MAX produce zero. */
3940 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3941 tcg_gen_neg_i64(t1
, t1
);
3942 tcg_gen_and_i64(t0
, t0
, t1
);
3948 TCGv_i64 t2
= tcg_temp_new_i64();
3949 int lab
= gen_new_label();
3951 tcg_gen_mov_i64(t2
, t0
);
3952 tcg_gen_add_i64(t0
, t1
, t2
);
3953 if (opc
== OPC_ADD_CP2
) {
3954 tcg_gen_ext32s_i64(t0
, t0
);
3956 tcg_gen_xor_i64(t1
, t1
, t2
);
3957 tcg_gen_xor_i64(t2
, t2
, t0
);
3958 tcg_gen_andc_i64(t1
, t2
, t1
);
3959 tcg_temp_free_i64(t2
);
3960 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3961 generate_exception(ctx
, EXCP_OVERFLOW
);
3964 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3971 TCGv_i64 t2
= tcg_temp_new_i64();
3972 int lab
= gen_new_label();
3974 tcg_gen_mov_i64(t2
, t0
);
3975 tcg_gen_sub_i64(t0
, t1
, t2
);
3976 if (opc
== OPC_SUB_CP2
) {
3977 tcg_gen_ext32s_i64(t0
, t0
);
3979 tcg_gen_xor_i64(t1
, t1
, t2
);
3980 tcg_gen_xor_i64(t2
, t2
, t0
);
3981 tcg_gen_and_i64(t1
, t1
, t2
);
3982 tcg_temp_free_i64(t2
);
3983 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3984 generate_exception(ctx
, EXCP_OVERFLOW
);
3987 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3992 tcg_gen_ext32u_i64(t0
, t0
);
3993 tcg_gen_ext32u_i64(t1
, t1
);
3994 tcg_gen_mul_i64(t0
, t0
, t1
);
4004 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
4005 FD field is the CC field? */
4008 generate_exception(ctx
, EXCP_RI
);
4015 gen_store_fpr64(ctx
, t0
, rd
);
4017 (void)opn
; /* avoid a compiler warning */
4018 MIPS_DEBUG("%s %s, %s, %s", opn
,
4019 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
4020 tcg_temp_free_i64(t0
);
4021 tcg_temp_free_i64(t1
);
4025 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
4026 int rs
, int rt
, int16_t imm
)
4029 TCGv t0
= tcg_temp_new();
4030 TCGv t1
= tcg_temp_new();
4033 /* Load needed operands */
4041 /* Compare two registers */
4043 gen_load_gpr(t0
, rs
);
4044 gen_load_gpr(t1
, rt
);
4054 /* Compare register to immediate */
4055 if (rs
!= 0 || imm
!= 0) {
4056 gen_load_gpr(t0
, rs
);
4057 tcg_gen_movi_tl(t1
, (int32_t)imm
);
4064 case OPC_TEQ
: /* rs == rs */
4065 case OPC_TEQI
: /* r0 == 0 */
4066 case OPC_TGE
: /* rs >= rs */
4067 case OPC_TGEI
: /* r0 >= 0 */
4068 case OPC_TGEU
: /* rs >= rs unsigned */
4069 case OPC_TGEIU
: /* r0 >= 0 unsigned */
4071 generate_exception(ctx
, EXCP_TRAP
);
4073 case OPC_TLT
: /* rs < rs */
4074 case OPC_TLTI
: /* r0 < 0 */
4075 case OPC_TLTU
: /* rs < rs unsigned */
4076 case OPC_TLTIU
: /* r0 < 0 unsigned */
4077 case OPC_TNE
: /* rs != rs */
4078 case OPC_TNEI
: /* r0 != 0 */
4079 /* Never trap: treat as NOP. */
4083 int l1
= gen_new_label();
4088 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
4092 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
4096 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
4100 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
4104 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
4108 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
4111 generate_exception(ctx
, EXCP_TRAP
);
4118 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
4120 TranslationBlock
*tb
;
4122 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
4123 likely(!ctx
->singlestep_enabled
)) {
4126 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
4129 if (ctx
->singlestep_enabled
) {
4130 save_cpu_state(ctx
, 0);
4131 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
4137 /* Branches (before delay slot) */
4138 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
4140 int rs
, int rt
, int32_t offset
)
4142 target_ulong btgt
= -1;
4144 int bcond_compute
= 0;
4145 TCGv t0
= tcg_temp_new();
4146 TCGv t1
= tcg_temp_new();
4148 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
4149 #ifdef MIPS_DEBUG_DISAS
4150 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
4152 generate_exception(ctx
, EXCP_RI
);
4156 /* Load needed operands */
4162 /* Compare two registers */
4164 gen_load_gpr(t0
, rs
);
4165 gen_load_gpr(t1
, rt
);
4168 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4184 /* Compare to zero */
4186 gen_load_gpr(t0
, rs
);
4189 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4192 #if defined(TARGET_MIPS64)
4194 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
4196 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
4199 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
4206 /* Jump to immediate */
4207 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
4213 /* Jump to register */
4214 if (offset
!= 0 && offset
!= 16) {
4215 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4216 others are reserved. */
4217 MIPS_INVAL("jump hint");
4218 generate_exception(ctx
, EXCP_RI
);
4221 gen_load_gpr(btarget
, rs
);
4224 MIPS_INVAL("branch/jump");
4225 generate_exception(ctx
, EXCP_RI
);
4228 if (bcond_compute
== 0) {
4229 /* No condition to be computed */
4231 case OPC_BEQ
: /* rx == rx */
4232 case OPC_BEQL
: /* rx == rx likely */
4233 case OPC_BGEZ
: /* 0 >= 0 */
4234 case OPC_BGEZL
: /* 0 >= 0 likely */
4235 case OPC_BLEZ
: /* 0 <= 0 */
4236 case OPC_BLEZL
: /* 0 <= 0 likely */
4238 ctx
->hflags
|= MIPS_HFLAG_B
;
4239 MIPS_DEBUG("balways");
4242 case OPC_BGEZAL
: /* 0 >= 0 */
4243 case OPC_BGEZALL
: /* 0 >= 0 likely */
4244 ctx
->hflags
|= (opc
== OPC_BGEZALS
4246 : MIPS_HFLAG_BDS32
);
4247 /* Always take and link */
4249 ctx
->hflags
|= MIPS_HFLAG_B
;
4250 MIPS_DEBUG("balways and link");
4252 case OPC_BNE
: /* rx != rx */
4253 case OPC_BGTZ
: /* 0 > 0 */
4254 case OPC_BLTZ
: /* 0 < 0 */
4256 MIPS_DEBUG("bnever (NOP)");
4259 case OPC_BLTZAL
: /* 0 < 0 */
4260 ctx
->hflags
|= (opc
== OPC_BLTZALS
4262 : MIPS_HFLAG_BDS32
);
4263 /* Handle as an unconditional branch to get correct delay
4266 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
4267 ctx
->hflags
|= MIPS_HFLAG_B
;
4268 MIPS_DEBUG("bnever and link");
4270 case OPC_BLTZALL
: /* 0 < 0 likely */
4271 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
4272 /* Skip the instruction in the delay slot */
4273 MIPS_DEBUG("bnever, link and skip");
4276 case OPC_BNEL
: /* rx != rx likely */
4277 case OPC_BGTZL
: /* 0 > 0 likely */
4278 case OPC_BLTZL
: /* 0 < 0 likely */
4279 /* Skip the instruction in the delay slot */
4280 MIPS_DEBUG("bnever and skip");
4284 ctx
->hflags
|= MIPS_HFLAG_B
;
4285 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
4289 ctx
->hflags
|= MIPS_HFLAG_BX
;
4294 ctx
->hflags
|= MIPS_HFLAG_B
;
4295 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
4297 : MIPS_HFLAG_BDS32
);
4298 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
4301 ctx
->hflags
|= MIPS_HFLAG_BR
;
4302 if (insn_bytes
== 4)
4303 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
4304 MIPS_DEBUG("jr %s", regnames
[rs
]);
4310 ctx
->hflags
|= MIPS_HFLAG_BR
;
4311 ctx
->hflags
|= (opc
== OPC_JALRS
4313 : MIPS_HFLAG_BDS32
);
4314 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
4317 MIPS_INVAL("branch/jump");
4318 generate_exception(ctx
, EXCP_RI
);
4324 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4325 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
4326 regnames
[rs
], regnames
[rt
], btgt
);
4329 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
4330 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
4331 regnames
[rs
], regnames
[rt
], btgt
);
4334 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4335 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
4336 regnames
[rs
], regnames
[rt
], btgt
);
4339 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
4340 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
4341 regnames
[rs
], regnames
[rt
], btgt
);
4344 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4345 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4348 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4349 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4353 ctx
->hflags
|= (opc
== OPC_BGEZALS
4355 : MIPS_HFLAG_BDS32
);
4356 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4357 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4361 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
4363 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4366 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4367 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4370 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
4371 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4374 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4375 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4378 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
4379 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4382 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4383 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4386 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4387 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4390 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
4391 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
4393 #if defined(TARGET_MIPS64)
4395 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
4396 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
4401 ctx
->hflags
|= (opc
== OPC_BLTZALS
4403 : MIPS_HFLAG_BDS32
);
4404 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4406 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4408 ctx
->hflags
|= MIPS_HFLAG_BC
;
4411 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
4413 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
4415 ctx
->hflags
|= MIPS_HFLAG_BL
;
4418 MIPS_INVAL("conditional branch/jump");
4419 generate_exception(ctx
, EXCP_RI
);
4423 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
4424 blink
, ctx
->hflags
, btgt
);
4426 ctx
->btarget
= btgt
;
4428 int post_delay
= insn_bytes
;
4429 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
4431 if (opc
!= OPC_JALRC
)
4432 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
4434 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
4438 if (insn_bytes
== 2)
4439 ctx
->hflags
|= MIPS_HFLAG_B16
;
4444 /* special3 bitfield operations */
4445 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
4446 int rs
, int lsb
, int msb
)
4448 TCGv t0
= tcg_temp_new();
4449 TCGv t1
= tcg_temp_new();
4451 gen_load_gpr(t1
, rs
);
4456 tcg_gen_shri_tl(t0
, t1
, lsb
);
4458 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
4460 tcg_gen_ext32s_tl(t0
, t0
);
4463 #if defined(TARGET_MIPS64)
4465 tcg_gen_shri_tl(t0
, t1
, lsb
);
4467 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
4471 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
4472 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4475 tcg_gen_shri_tl(t0
, t1
, lsb
);
4476 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
4482 gen_load_gpr(t0
, rt
);
4483 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4484 tcg_gen_ext32s_tl(t0
, t0
);
4486 #if defined(TARGET_MIPS64)
4488 gen_load_gpr(t0
, rt
);
4489 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
4492 gen_load_gpr(t0
, rt
);
4493 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
4496 gen_load_gpr(t0
, rt
);
4497 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
4502 MIPS_INVAL("bitops");
4503 generate_exception(ctx
, EXCP_RI
);
4508 gen_store_gpr(t0
, rt
);
4513 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4518 /* If no destination, treat it as a NOP. */
4523 t0
= tcg_temp_new();
4524 gen_load_gpr(t0
, rt
);
4528 TCGv t1
= tcg_temp_new();
4530 tcg_gen_shri_tl(t1
, t0
, 8);
4531 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4532 tcg_gen_shli_tl(t0
, t0
, 8);
4533 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4534 tcg_gen_or_tl(t0
, t0
, t1
);
4536 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4540 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4543 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4545 #if defined(TARGET_MIPS64)
4548 TCGv t1
= tcg_temp_new();
4550 tcg_gen_shri_tl(t1
, t0
, 8);
4551 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4552 tcg_gen_shli_tl(t0
, t0
, 8);
4553 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4554 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4560 TCGv t1
= tcg_temp_new();
4562 tcg_gen_shri_tl(t1
, t0
, 16);
4563 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4564 tcg_gen_shli_tl(t0
, t0
, 16);
4565 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4566 tcg_gen_or_tl(t0
, t0
, t1
);
4567 tcg_gen_shri_tl(t1
, t0
, 32);
4568 tcg_gen_shli_tl(t0
, t0
, 32);
4569 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4575 MIPS_INVAL("bsfhl");
4576 generate_exception(ctx
, EXCP_RI
);
4583 #ifndef CONFIG_USER_ONLY
4584 /* CP0 (MMU and control) */
4585 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4587 TCGv_i32 t0
= tcg_temp_new_i32();
4589 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4590 tcg_gen_ext_i32_tl(arg
, t0
);
4591 tcg_temp_free_i32(t0
);
4594 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4596 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4597 tcg_gen_ext32s_tl(arg
, arg
);
4600 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4602 TCGv_i32 t0
= tcg_temp_new_i32();
4604 tcg_gen_trunc_tl_i32(t0
, arg
);
4605 tcg_gen_st_i32(t0
, cpu_env
, off
);
4606 tcg_temp_free_i32(t0
);
4609 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4611 tcg_gen_ext32s_tl(arg
, arg
);
4612 tcg_gen_st_tl(arg
, cpu_env
, off
);
4615 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4617 const char *rn
= "invalid";
4620 check_insn(ctx
, ISA_MIPS32
);
4626 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4630 check_insn(ctx
, ASE_MT
);
4631 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4635 check_insn(ctx
, ASE_MT
);
4636 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4640 check_insn(ctx
, ASE_MT
);
4641 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4651 gen_helper_mfc0_random(arg
, cpu_env
);
4655 check_insn(ctx
, ASE_MT
);
4656 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4660 check_insn(ctx
, ASE_MT
);
4661 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4665 check_insn(ctx
, ASE_MT
);
4666 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4670 check_insn(ctx
, ASE_MT
);
4671 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4675 check_insn(ctx
, ASE_MT
);
4676 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4680 check_insn(ctx
, ASE_MT
);
4681 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4682 rn
= "VPEScheFBack";
4685 check_insn(ctx
, ASE_MT
);
4686 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4696 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4697 tcg_gen_ext32s_tl(arg
, arg
);
4701 check_insn(ctx
, ASE_MT
);
4702 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4706 check_insn(ctx
, ASE_MT
);
4707 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4711 check_insn(ctx
, ASE_MT
);
4712 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4716 check_insn(ctx
, ASE_MT
);
4717 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4721 check_insn(ctx
, ASE_MT
);
4722 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4726 check_insn(ctx
, ASE_MT
);
4727 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4731 check_insn(ctx
, ASE_MT
);
4732 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4742 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4743 tcg_gen_ext32s_tl(arg
, arg
);
4753 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4754 tcg_gen_ext32s_tl(arg
, arg
);
4758 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4759 rn
= "ContextConfig";
4764 tcg_gen_ld32s_tl(arg
, cpu_env
,
4765 offsetof(CPUMIPSState
,
4766 active_tc
.CP0_UserLocal
));
4769 tcg_gen_movi_tl(arg
, 0);
4779 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4783 check_insn(ctx
, ISA_MIPS32R2
);
4784 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4794 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4798 check_insn(ctx
, ISA_MIPS32R2
);
4799 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4803 check_insn(ctx
, ISA_MIPS32R2
);
4804 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4808 check_insn(ctx
, ISA_MIPS32R2
);
4809 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4813 check_insn(ctx
, ISA_MIPS32R2
);
4814 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4818 check_insn(ctx
, ISA_MIPS32R2
);
4819 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4829 check_insn(ctx
, ISA_MIPS32R2
);
4830 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4840 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4841 tcg_gen_ext32s_tl(arg
, arg
);
4851 /* Mark as an IO operation because we read the time. */
4854 gen_helper_mfc0_count(arg
, cpu_env
);
4858 /* Break the TB to be able to take timer interrupts immediately
4859 after reading count. */
4860 ctx
->bstate
= BS_STOP
;
4863 /* 6,7 are implementation dependent */
4871 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4872 tcg_gen_ext32s_tl(arg
, arg
);
4882 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4885 /* 6,7 are implementation dependent */
4893 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4897 check_insn(ctx
, ISA_MIPS32R2
);
4898 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4902 check_insn(ctx
, ISA_MIPS32R2
);
4903 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4907 check_insn(ctx
, ISA_MIPS32R2
);
4908 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4918 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4928 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4929 tcg_gen_ext32s_tl(arg
, arg
);
4939 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4943 check_insn(ctx
, ISA_MIPS32R2
);
4944 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4954 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4958 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4962 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4966 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4970 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
4974 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
4977 /* 6,7 are implementation dependent */
4979 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4983 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4993 gen_helper_mfc0_lladdr(arg
, cpu_env
);
5003 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
5013 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5023 #if defined(TARGET_MIPS64)
5024 check_insn(ctx
, ISA_MIPS3
);
5025 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5026 tcg_gen_ext32s_tl(arg
, arg
);
5035 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5038 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5046 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5047 rn
= "'Diagnostic"; /* implementation dependent */
5052 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5056 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
5057 rn
= "TraceControl";
5060 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
5061 rn
= "TraceControl2";
5064 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
5065 rn
= "UserTraceData";
5068 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
5079 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5080 tcg_gen_ext32s_tl(arg
, arg
);
5090 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5091 rn
= "Performance0";
5094 // gen_helper_mfc0_performance1(arg);
5095 rn
= "Performance1";
5098 // gen_helper_mfc0_performance2(arg);
5099 rn
= "Performance2";
5102 // gen_helper_mfc0_performance3(arg);
5103 rn
= "Performance3";
5106 // gen_helper_mfc0_performance4(arg);
5107 rn
= "Performance4";
5110 // gen_helper_mfc0_performance5(arg);
5111 rn
= "Performance5";
5114 // gen_helper_mfc0_performance6(arg);
5115 rn
= "Performance6";
5118 // gen_helper_mfc0_performance7(arg);
5119 rn
= "Performance7";
5126 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5132 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5145 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5152 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5165 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5172 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5182 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5183 tcg_gen_ext32s_tl(arg
, arg
);
5194 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5204 (void)rn
; /* avoid a compiler warning */
5205 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5209 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5210 generate_exception(ctx
, EXCP_RI
);
5213 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5215 const char *rn
= "invalid";
5218 check_insn(ctx
, ISA_MIPS32
);
5227 gen_helper_mtc0_index(cpu_env
, arg
);
5231 check_insn(ctx
, ASE_MT
);
5232 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5236 check_insn(ctx
, ASE_MT
);
5241 check_insn(ctx
, ASE_MT
);
5256 check_insn(ctx
, ASE_MT
);
5257 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5261 check_insn(ctx
, ASE_MT
);
5262 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5266 check_insn(ctx
, ASE_MT
);
5267 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5271 check_insn(ctx
, ASE_MT
);
5272 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5276 check_insn(ctx
, ASE_MT
);
5277 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5281 check_insn(ctx
, ASE_MT
);
5282 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5283 rn
= "VPEScheFBack";
5286 check_insn(ctx
, ASE_MT
);
5287 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5297 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5301 check_insn(ctx
, ASE_MT
);
5302 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5306 check_insn(ctx
, ASE_MT
);
5307 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5311 check_insn(ctx
, ASE_MT
);
5312 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5316 check_insn(ctx
, ASE_MT
);
5317 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5321 check_insn(ctx
, ASE_MT
);
5322 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5326 check_insn(ctx
, ASE_MT
);
5327 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5331 check_insn(ctx
, ASE_MT
);
5332 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5342 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5352 gen_helper_mtc0_context(cpu_env
, arg
);
5356 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5357 rn
= "ContextConfig";
5362 tcg_gen_st_tl(arg
, cpu_env
,
5363 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5374 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5378 check_insn(ctx
, ISA_MIPS32R2
);
5379 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5389 gen_helper_mtc0_wired(cpu_env
, arg
);
5393 check_insn(ctx
, ISA_MIPS32R2
);
5394 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5398 check_insn(ctx
, ISA_MIPS32R2
);
5399 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
5403 check_insn(ctx
, ISA_MIPS32R2
);
5404 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
5408 check_insn(ctx
, ISA_MIPS32R2
);
5409 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
5413 check_insn(ctx
, ISA_MIPS32R2
);
5414 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
5424 check_insn(ctx
, ISA_MIPS32R2
);
5425 gen_helper_mtc0_hwrena(cpu_env
, arg
);
5426 ctx
->bstate
= BS_STOP
;
5440 gen_helper_mtc0_count(cpu_env
, arg
);
5443 /* 6,7 are implementation dependent */
5451 gen_helper_mtc0_entryhi(cpu_env
, arg
);
5461 gen_helper_mtc0_compare(cpu_env
, arg
);
5464 /* 6,7 are implementation dependent */
5472 save_cpu_state(ctx
, 1);
5473 gen_helper_mtc0_status(cpu_env
, arg
);
5474 /* BS_STOP isn't good enough here, hflags may have changed. */
5475 gen_save_pc(ctx
->pc
+ 4);
5476 ctx
->bstate
= BS_EXCP
;
5480 check_insn(ctx
, ISA_MIPS32R2
);
5481 gen_helper_mtc0_intctl(cpu_env
, arg
);
5482 /* Stop translation as we may have switched the execution mode */
5483 ctx
->bstate
= BS_STOP
;
5487 check_insn(ctx
, ISA_MIPS32R2
);
5488 gen_helper_mtc0_srsctl(cpu_env
, arg
);
5489 /* Stop translation as we may have switched the execution mode */
5490 ctx
->bstate
= BS_STOP
;
5494 check_insn(ctx
, ISA_MIPS32R2
);
5495 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5496 /* Stop translation as we may have switched the execution mode */
5497 ctx
->bstate
= BS_STOP
;
5507 save_cpu_state(ctx
, 1);
5508 gen_helper_mtc0_cause(cpu_env
, arg
);
5518 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
5532 check_insn(ctx
, ISA_MIPS32R2
);
5533 gen_helper_mtc0_ebase(cpu_env
, arg
);
5543 gen_helper_mtc0_config0(cpu_env
, arg
);
5545 /* Stop translation as we may have switched the execution mode */
5546 ctx
->bstate
= BS_STOP
;
5549 /* ignored, read only */
5553 gen_helper_mtc0_config2(cpu_env
, arg
);
5555 /* Stop translation as we may have switched the execution mode */
5556 ctx
->bstate
= BS_STOP
;
5559 /* ignored, read only */
5563 gen_helper_mtc0_config4(cpu_env
, arg
);
5565 ctx
->bstate
= BS_STOP
;
5568 gen_helper_mtc0_config5(cpu_env
, arg
);
5570 /* Stop translation as we may have switched the execution mode */
5571 ctx
->bstate
= BS_STOP
;
5573 /* 6,7 are implementation dependent */
5583 rn
= "Invalid config selector";
5590 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5600 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5610 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5620 #if defined(TARGET_MIPS64)
5621 check_insn(ctx
, ISA_MIPS3
);
5622 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5631 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5634 gen_helper_mtc0_framemask(cpu_env
, arg
);
5643 rn
= "Diagnostic"; /* implementation dependent */
5648 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5649 /* BS_STOP isn't good enough here, hflags may have changed. */
5650 gen_save_pc(ctx
->pc
+ 4);
5651 ctx
->bstate
= BS_EXCP
;
5655 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5656 rn
= "TraceControl";
5657 /* Stop translation as we may have switched the execution mode */
5658 ctx
->bstate
= BS_STOP
;
5661 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5662 rn
= "TraceControl2";
5663 /* Stop translation as we may have switched the execution mode */
5664 ctx
->bstate
= BS_STOP
;
5667 /* Stop translation as we may have switched the execution mode */
5668 ctx
->bstate
= BS_STOP
;
5669 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5670 rn
= "UserTraceData";
5671 /* Stop translation as we may have switched the execution mode */
5672 ctx
->bstate
= BS_STOP
;
5675 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5676 /* Stop translation as we may have switched the execution mode */
5677 ctx
->bstate
= BS_STOP
;
5688 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5698 gen_helper_mtc0_performance0(cpu_env
, arg
);
5699 rn
= "Performance0";
5702 // gen_helper_mtc0_performance1(arg);
5703 rn
= "Performance1";
5706 // gen_helper_mtc0_performance2(arg);
5707 rn
= "Performance2";
5710 // gen_helper_mtc0_performance3(arg);
5711 rn
= "Performance3";
5714 // gen_helper_mtc0_performance4(arg);
5715 rn
= "Performance4";
5718 // gen_helper_mtc0_performance5(arg);
5719 rn
= "Performance5";
5722 // gen_helper_mtc0_performance6(arg);
5723 rn
= "Performance6";
5726 // gen_helper_mtc0_performance7(arg);
5727 rn
= "Performance7";
5753 gen_helper_mtc0_taglo(cpu_env
, arg
);
5760 gen_helper_mtc0_datalo(cpu_env
, arg
);
5773 gen_helper_mtc0_taghi(cpu_env
, arg
);
5780 gen_helper_mtc0_datahi(cpu_env
, arg
);
5791 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5802 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5808 /* Stop translation as we may have switched the execution mode */
5809 ctx
->bstate
= BS_STOP
;
5814 (void)rn
; /* avoid a compiler warning */
5815 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5816 /* For simplicity assume that all writes can cause interrupts. */
5819 ctx
->bstate
= BS_STOP
;
5824 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5825 generate_exception(ctx
, EXCP_RI
);
5828 #if defined(TARGET_MIPS64)
5829 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5831 const char *rn
= "invalid";
5834 check_insn(ctx
, ISA_MIPS64
);
5840 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5844 check_insn(ctx
, ASE_MT
);
5845 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5849 check_insn(ctx
, ASE_MT
);
5850 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5854 check_insn(ctx
, ASE_MT
);
5855 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5865 gen_helper_mfc0_random(arg
, cpu_env
);
5869 check_insn(ctx
, ASE_MT
);
5870 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5874 check_insn(ctx
, ASE_MT
);
5875 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5879 check_insn(ctx
, ASE_MT
);
5880 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5884 check_insn(ctx
, ASE_MT
);
5885 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5889 check_insn(ctx
, ASE_MT
);
5890 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5894 check_insn(ctx
, ASE_MT
);
5895 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5896 rn
= "VPEScheFBack";
5899 check_insn(ctx
, ASE_MT
);
5900 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5910 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5914 check_insn(ctx
, ASE_MT
);
5915 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5919 check_insn(ctx
, ASE_MT
);
5920 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5924 check_insn(ctx
, ASE_MT
);
5925 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5929 check_insn(ctx
, ASE_MT
);
5930 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5934 check_insn(ctx
, ASE_MT
);
5935 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5939 check_insn(ctx
, ASE_MT
);
5940 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5944 check_insn(ctx
, ASE_MT
);
5945 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5955 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5965 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5969 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5970 rn
= "ContextConfig";
5975 tcg_gen_ld_tl(arg
, cpu_env
,
5976 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5979 tcg_gen_movi_tl(arg
, 0);
5989 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5993 check_insn(ctx
, ISA_MIPS32R2
);
5994 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
6004 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
6008 check_insn(ctx
, ISA_MIPS32R2
);
6009 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
6013 check_insn(ctx
, ISA_MIPS32R2
);
6014 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
6018 check_insn(ctx
, ISA_MIPS32R2
);
6019 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
6023 check_insn(ctx
, ISA_MIPS32R2
);
6024 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
6028 check_insn(ctx
, ISA_MIPS32R2
);
6029 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
6039 check_insn(ctx
, ISA_MIPS32R2
);
6040 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
6050 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
6060 /* Mark as an IO operation because we read the time. */
6063 gen_helper_mfc0_count(arg
, cpu_env
);
6067 /* Break the TB to be able to take timer interrupts immediately
6068 after reading count. */
6069 ctx
->bstate
= BS_STOP
;
6072 /* 6,7 are implementation dependent */
6080 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
6090 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
6093 /* 6,7 are implementation dependent */
6101 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
6105 check_insn(ctx
, ISA_MIPS32R2
);
6106 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
6110 check_insn(ctx
, ISA_MIPS32R2
);
6111 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
6115 check_insn(ctx
, ISA_MIPS32R2
);
6116 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6126 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
6136 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6146 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
6150 check_insn(ctx
, ISA_MIPS32R2
);
6151 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
6161 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
6165 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
6169 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
6173 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
6176 /* 6,7 are implementation dependent */
6178 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
6182 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
6192 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
6202 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
6212 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
6222 check_insn(ctx
, ISA_MIPS3
);
6223 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
6231 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6234 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
6242 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6243 rn
= "'Diagnostic"; /* implementation dependent */
6248 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
6252 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
6253 rn
= "TraceControl";
6256 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
6257 rn
= "TraceControl2";
6260 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
6261 rn
= "UserTraceData";
6264 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
6275 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6285 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
6286 rn
= "Performance0";
6289 // gen_helper_dmfc0_performance1(arg);
6290 rn
= "Performance1";
6293 // gen_helper_dmfc0_performance2(arg);
6294 rn
= "Performance2";
6297 // gen_helper_dmfc0_performance3(arg);
6298 rn
= "Performance3";
6301 // gen_helper_dmfc0_performance4(arg);
6302 rn
= "Performance4";
6305 // gen_helper_dmfc0_performance5(arg);
6306 rn
= "Performance5";
6309 // gen_helper_dmfc0_performance6(arg);
6310 rn
= "Performance6";
6313 // gen_helper_dmfc0_performance7(arg);
6314 rn
= "Performance7";
6321 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6328 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
6341 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
6348 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
6361 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
6368 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
6378 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6389 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6399 (void)rn
; /* avoid a compiler warning */
6400 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6404 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6405 generate_exception(ctx
, EXCP_RI
);
6408 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
6410 const char *rn
= "invalid";
6413 check_insn(ctx
, ISA_MIPS64
);
6422 gen_helper_mtc0_index(cpu_env
, arg
);
6426 check_insn(ctx
, ASE_MT
);
6427 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
6431 check_insn(ctx
, ASE_MT
);
6436 check_insn(ctx
, ASE_MT
);
6451 check_insn(ctx
, ASE_MT
);
6452 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
6456 check_insn(ctx
, ASE_MT
);
6457 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
6461 check_insn(ctx
, ASE_MT
);
6462 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
6466 check_insn(ctx
, ASE_MT
);
6467 gen_helper_mtc0_yqmask(cpu_env
, arg
);
6471 check_insn(ctx
, ASE_MT
);
6472 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
6476 check_insn(ctx
, ASE_MT
);
6477 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
6478 rn
= "VPEScheFBack";
6481 check_insn(ctx
, ASE_MT
);
6482 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
6492 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
6496 check_insn(ctx
, ASE_MT
);
6497 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
6501 check_insn(ctx
, ASE_MT
);
6502 gen_helper_mtc0_tcbind(cpu_env
, arg
);
6506 check_insn(ctx
, ASE_MT
);
6507 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
6511 check_insn(ctx
, ASE_MT
);
6512 gen_helper_mtc0_tchalt(cpu_env
, arg
);
6516 check_insn(ctx
, ASE_MT
);
6517 gen_helper_mtc0_tccontext(cpu_env
, arg
);
6521 check_insn(ctx
, ASE_MT
);
6522 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
6526 check_insn(ctx
, ASE_MT
);
6527 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6537 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
6547 gen_helper_mtc0_context(cpu_env
, arg
);
6551 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6552 rn
= "ContextConfig";
6557 tcg_gen_st_tl(arg
, cpu_env
,
6558 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6569 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6573 check_insn(ctx
, ISA_MIPS32R2
);
6574 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6584 gen_helper_mtc0_wired(cpu_env
, arg
);
6588 check_insn(ctx
, ISA_MIPS32R2
);
6589 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6593 check_insn(ctx
, ISA_MIPS32R2
);
6594 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6598 check_insn(ctx
, ISA_MIPS32R2
);
6599 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6603 check_insn(ctx
, ISA_MIPS32R2
);
6604 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6608 check_insn(ctx
, ISA_MIPS32R2
);
6609 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6619 check_insn(ctx
, ISA_MIPS32R2
);
6620 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6621 ctx
->bstate
= BS_STOP
;
6635 gen_helper_mtc0_count(cpu_env
, arg
);
6638 /* 6,7 are implementation dependent */
6642 /* Stop translation as we may have switched the execution mode */
6643 ctx
->bstate
= BS_STOP
;
6648 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6658 gen_helper_mtc0_compare(cpu_env
, arg
);
6661 /* 6,7 are implementation dependent */
6665 /* Stop translation as we may have switched the execution mode */
6666 ctx
->bstate
= BS_STOP
;
6671 save_cpu_state(ctx
, 1);
6672 gen_helper_mtc0_status(cpu_env
, arg
);
6673 /* BS_STOP isn't good enough here, hflags may have changed. */
6674 gen_save_pc(ctx
->pc
+ 4);
6675 ctx
->bstate
= BS_EXCP
;
6679 check_insn(ctx
, ISA_MIPS32R2
);
6680 gen_helper_mtc0_intctl(cpu_env
, arg
);
6681 /* Stop translation as we may have switched the execution mode */
6682 ctx
->bstate
= BS_STOP
;
6686 check_insn(ctx
, ISA_MIPS32R2
);
6687 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6688 /* Stop translation as we may have switched the execution mode */
6689 ctx
->bstate
= BS_STOP
;
6693 check_insn(ctx
, ISA_MIPS32R2
);
6694 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6695 /* Stop translation as we may have switched the execution mode */
6696 ctx
->bstate
= BS_STOP
;
6706 save_cpu_state(ctx
, 1);
6707 /* Mark as an IO operation because we may trigger a software
6712 gen_helper_mtc0_cause(cpu_env
, arg
);
6716 /* Stop translation as we may have triggered an intetrupt */
6717 ctx
->bstate
= BS_STOP
;
6727 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6741 check_insn(ctx
, ISA_MIPS32R2
);
6742 gen_helper_mtc0_ebase(cpu_env
, arg
);
6752 gen_helper_mtc0_config0(cpu_env
, arg
);
6754 /* Stop translation as we may have switched the execution mode */
6755 ctx
->bstate
= BS_STOP
;
6758 /* ignored, read only */
6762 gen_helper_mtc0_config2(cpu_env
, arg
);
6764 /* Stop translation as we may have switched the execution mode */
6765 ctx
->bstate
= BS_STOP
;
6771 /* 6,7 are implementation dependent */
6773 rn
= "Invalid config selector";
6780 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6790 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6800 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6810 check_insn(ctx
, ISA_MIPS3
);
6811 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6819 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6822 gen_helper_mtc0_framemask(cpu_env
, arg
);
6831 rn
= "Diagnostic"; /* implementation dependent */
6836 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6837 /* BS_STOP isn't good enough here, hflags may have changed. */
6838 gen_save_pc(ctx
->pc
+ 4);
6839 ctx
->bstate
= BS_EXCP
;
6843 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6844 /* Stop translation as we may have switched the execution mode */
6845 ctx
->bstate
= BS_STOP
;
6846 rn
= "TraceControl";
6849 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6850 /* Stop translation as we may have switched the execution mode */
6851 ctx
->bstate
= BS_STOP
;
6852 rn
= "TraceControl2";
6855 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6856 /* Stop translation as we may have switched the execution mode */
6857 ctx
->bstate
= BS_STOP
;
6858 rn
= "UserTraceData";
6861 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6862 /* Stop translation as we may have switched the execution mode */
6863 ctx
->bstate
= BS_STOP
;
6874 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6884 gen_helper_mtc0_performance0(cpu_env
, arg
);
6885 rn
= "Performance0";
6888 // gen_helper_mtc0_performance1(cpu_env, arg);
6889 rn
= "Performance1";
6892 // gen_helper_mtc0_performance2(cpu_env, arg);
6893 rn
= "Performance2";
6896 // gen_helper_mtc0_performance3(cpu_env, arg);
6897 rn
= "Performance3";
6900 // gen_helper_mtc0_performance4(cpu_env, arg);
6901 rn
= "Performance4";
6904 // gen_helper_mtc0_performance5(cpu_env, arg);
6905 rn
= "Performance5";
6908 // gen_helper_mtc0_performance6(cpu_env, arg);
6909 rn
= "Performance6";
6912 // gen_helper_mtc0_performance7(cpu_env, arg);
6913 rn
= "Performance7";
6939 gen_helper_mtc0_taglo(cpu_env
, arg
);
6946 gen_helper_mtc0_datalo(cpu_env
, arg
);
6959 gen_helper_mtc0_taghi(cpu_env
, arg
);
6966 gen_helper_mtc0_datahi(cpu_env
, arg
);
6977 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6988 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6994 /* Stop translation as we may have switched the execution mode */
6995 ctx
->bstate
= BS_STOP
;
7000 (void)rn
; /* avoid a compiler warning */
7001 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7002 /* For simplicity assume that all writes can cause interrupts. */
7005 ctx
->bstate
= BS_STOP
;
7010 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
7011 generate_exception(ctx
, EXCP_RI
);
7013 #endif /* TARGET_MIPS64 */
7015 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
7016 int u
, int sel
, int h
)
7018 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7019 TCGv t0
= tcg_temp_local_new();
7021 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7022 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7023 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7024 tcg_gen_movi_tl(t0
, -1);
7025 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7026 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7027 tcg_gen_movi_tl(t0
, -1);
7033 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
7036 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
7046 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
7049 gen_helper_mftc0_tcbind(t0
, cpu_env
);
7052 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
7055 gen_helper_mftc0_tchalt(t0
, cpu_env
);
7058 gen_helper_mftc0_tccontext(t0
, cpu_env
);
7061 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
7064 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
7067 gen_mfc0(ctx
, t0
, rt
, sel
);
7074 gen_helper_mftc0_entryhi(t0
, cpu_env
);
7077 gen_mfc0(ctx
, t0
, rt
, sel
);
7083 gen_helper_mftc0_status(t0
, cpu_env
);
7086 gen_mfc0(ctx
, t0
, rt
, sel
);
7092 gen_helper_mftc0_cause(t0
, cpu_env
);
7102 gen_helper_mftc0_epc(t0
, cpu_env
);
7112 gen_helper_mftc0_ebase(t0
, cpu_env
);
7122 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
7132 gen_helper_mftc0_debug(t0
, cpu_env
);
7135 gen_mfc0(ctx
, t0
, rt
, sel
);
7140 gen_mfc0(ctx
, t0
, rt
, sel
);
7142 } else switch (sel
) {
7143 /* GPR registers. */
7145 gen_helper_1e0i(mftgpr
, t0
, rt
);
7147 /* Auxiliary CPU registers */
7151 gen_helper_1e0i(mftlo
, t0
, 0);
7154 gen_helper_1e0i(mfthi
, t0
, 0);
7157 gen_helper_1e0i(mftacx
, t0
, 0);
7160 gen_helper_1e0i(mftlo
, t0
, 1);
7163 gen_helper_1e0i(mfthi
, t0
, 1);
7166 gen_helper_1e0i(mftacx
, t0
, 1);
7169 gen_helper_1e0i(mftlo
, t0
, 2);
7172 gen_helper_1e0i(mfthi
, t0
, 2);
7175 gen_helper_1e0i(mftacx
, t0
, 2);
7178 gen_helper_1e0i(mftlo
, t0
, 3);
7181 gen_helper_1e0i(mfthi
, t0
, 3);
7184 gen_helper_1e0i(mftacx
, t0
, 3);
7187 gen_helper_mftdsp(t0
, cpu_env
);
7193 /* Floating point (COP1). */
7195 /* XXX: For now we support only a single FPU context. */
7197 TCGv_i32 fp0
= tcg_temp_new_i32();
7199 gen_load_fpr32(fp0
, rt
);
7200 tcg_gen_ext_i32_tl(t0
, fp0
);
7201 tcg_temp_free_i32(fp0
);
7203 TCGv_i32 fp0
= tcg_temp_new_i32();
7205 gen_load_fpr32h(ctx
, fp0
, rt
);
7206 tcg_gen_ext_i32_tl(t0
, fp0
);
7207 tcg_temp_free_i32(fp0
);
7211 /* XXX: For now we support only a single FPU context. */
7212 gen_helper_1e0i(cfc1
, t0
, rt
);
7214 /* COP2: Not implemented. */
7221 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7222 gen_store_gpr(t0
, rd
);
7228 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
7229 generate_exception(ctx
, EXCP_RI
);
7232 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
7233 int u
, int sel
, int h
)
7235 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
7236 TCGv t0
= tcg_temp_local_new();
7238 gen_load_gpr(t0
, rt
);
7239 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
7240 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
7241 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
7243 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
7244 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
7251 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
7254 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
7264 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
7267 gen_helper_mttc0_tcbind(cpu_env
, t0
);
7270 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
7273 gen_helper_mttc0_tchalt(cpu_env
, t0
);
7276 gen_helper_mttc0_tccontext(cpu_env
, t0
);
7279 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
7282 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
7285 gen_mtc0(ctx
, t0
, rd
, sel
);
7292 gen_helper_mttc0_entryhi(cpu_env
, t0
);
7295 gen_mtc0(ctx
, t0
, rd
, sel
);
7301 gen_helper_mttc0_status(cpu_env
, t0
);
7304 gen_mtc0(ctx
, t0
, rd
, sel
);
7310 gen_helper_mttc0_cause(cpu_env
, t0
);
7320 gen_helper_mttc0_ebase(cpu_env
, t0
);
7330 gen_helper_mttc0_debug(cpu_env
, t0
);
7333 gen_mtc0(ctx
, t0
, rd
, sel
);
7338 gen_mtc0(ctx
, t0
, rd
, sel
);
7340 } else switch (sel
) {
7341 /* GPR registers. */
7343 gen_helper_0e1i(mttgpr
, t0
, rd
);
7345 /* Auxiliary CPU registers */
7349 gen_helper_0e1i(mttlo
, t0
, 0);
7352 gen_helper_0e1i(mtthi
, t0
, 0);
7355 gen_helper_0e1i(mttacx
, t0
, 0);
7358 gen_helper_0e1i(mttlo
, t0
, 1);
7361 gen_helper_0e1i(mtthi
, t0
, 1);
7364 gen_helper_0e1i(mttacx
, t0
, 1);
7367 gen_helper_0e1i(mttlo
, t0
, 2);
7370 gen_helper_0e1i(mtthi
, t0
, 2);
7373 gen_helper_0e1i(mttacx
, t0
, 2);
7376 gen_helper_0e1i(mttlo
, t0
, 3);
7379 gen_helper_0e1i(mtthi
, t0
, 3);
7382 gen_helper_0e1i(mttacx
, t0
, 3);
7385 gen_helper_mttdsp(cpu_env
, t0
);
7391 /* Floating point (COP1). */
7393 /* XXX: For now we support only a single FPU context. */
7395 TCGv_i32 fp0
= tcg_temp_new_i32();
7397 tcg_gen_trunc_tl_i32(fp0
, t0
);
7398 gen_store_fpr32(fp0
, rd
);
7399 tcg_temp_free_i32(fp0
);
7401 TCGv_i32 fp0
= tcg_temp_new_i32();
7403 tcg_gen_trunc_tl_i32(fp0
, t0
);
7404 gen_store_fpr32h(ctx
, fp0
, rd
);
7405 tcg_temp_free_i32(fp0
);
7409 /* XXX: For now we support only a single FPU context. */
7411 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
7413 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7414 tcg_temp_free_i32(fs_tmp
);
7417 /* COP2: Not implemented. */
7424 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
7430 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
7431 generate_exception(ctx
, EXCP_RI
);
7434 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
7436 const char *opn
= "ldst";
7438 check_cp0_enabled(ctx
);
7445 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
7450 TCGv t0
= tcg_temp_new();
7452 gen_load_gpr(t0
, rt
);
7453 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
7458 #if defined(TARGET_MIPS64)
7460 check_insn(ctx
, ISA_MIPS3
);
7465 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
7469 check_insn(ctx
, ISA_MIPS3
);
7471 TCGv t0
= tcg_temp_new();
7473 gen_load_gpr(t0
, rt
);
7474 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
7481 check_insn(ctx
, ASE_MT
);
7486 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
7487 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
7491 check_insn(ctx
, ASE_MT
);
7492 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
7493 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
7498 if (!env
->tlb
->helper_tlbwi
)
7500 gen_helper_tlbwi(cpu_env
);
7504 if (!env
->tlb
->helper_tlbwr
)
7506 gen_helper_tlbwr(cpu_env
);
7510 if (!env
->tlb
->helper_tlbp
)
7512 gen_helper_tlbp(cpu_env
);
7516 if (!env
->tlb
->helper_tlbr
)
7518 gen_helper_tlbr(cpu_env
);
7522 check_insn(ctx
, ISA_MIPS2
);
7523 gen_helper_eret(cpu_env
);
7524 ctx
->bstate
= BS_EXCP
;
7528 check_insn(ctx
, ISA_MIPS32
);
7529 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
7531 generate_exception(ctx
, EXCP_RI
);
7533 gen_helper_deret(cpu_env
);
7534 ctx
->bstate
= BS_EXCP
;
7539 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
7540 /* If we get an exception, we want to restart at next instruction */
7542 save_cpu_state(ctx
, 1);
7544 gen_helper_wait(cpu_env
);
7545 ctx
->bstate
= BS_EXCP
;
7550 generate_exception(ctx
, EXCP_RI
);
7553 (void)opn
; /* avoid a compiler warning */
7554 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
7556 #endif /* !CONFIG_USER_ONLY */
7558 /* CP1 Branches (before delay slot) */
7559 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
7560 int32_t cc
, int32_t offset
)
7562 target_ulong btarget
;
7563 const char *opn
= "cp1 cond branch";
7564 TCGv_i32 t0
= tcg_temp_new_i32();
7567 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
7569 btarget
= ctx
->pc
+ 4 + offset
;
7573 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7574 tcg_gen_not_i32(t0
, t0
);
7575 tcg_gen_andi_i32(t0
, t0
, 1);
7576 tcg_gen_extu_i32_tl(bcond
, t0
);
7580 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7581 tcg_gen_not_i32(t0
, t0
);
7582 tcg_gen_andi_i32(t0
, t0
, 1);
7583 tcg_gen_extu_i32_tl(bcond
, t0
);
7587 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7588 tcg_gen_andi_i32(t0
, t0
, 1);
7589 tcg_gen_extu_i32_tl(bcond
, t0
);
7593 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7594 tcg_gen_andi_i32(t0
, t0
, 1);
7595 tcg_gen_extu_i32_tl(bcond
, t0
);
7598 ctx
->hflags
|= MIPS_HFLAG_BL
;
7602 TCGv_i32 t1
= tcg_temp_new_i32();
7603 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7604 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7605 tcg_gen_nand_i32(t0
, t0
, t1
);
7606 tcg_temp_free_i32(t1
);
7607 tcg_gen_andi_i32(t0
, t0
, 1);
7608 tcg_gen_extu_i32_tl(bcond
, t0
);
7614 TCGv_i32 t1
= tcg_temp_new_i32();
7615 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7616 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7617 tcg_gen_or_i32(t0
, t0
, t1
);
7618 tcg_temp_free_i32(t1
);
7619 tcg_gen_andi_i32(t0
, t0
, 1);
7620 tcg_gen_extu_i32_tl(bcond
, t0
);
7626 TCGv_i32 t1
= tcg_temp_new_i32();
7627 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7628 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7629 tcg_gen_and_i32(t0
, t0
, t1
);
7630 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7631 tcg_gen_and_i32(t0
, t0
, t1
);
7632 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7633 tcg_gen_nand_i32(t0
, t0
, t1
);
7634 tcg_temp_free_i32(t1
);
7635 tcg_gen_andi_i32(t0
, t0
, 1);
7636 tcg_gen_extu_i32_tl(bcond
, t0
);
7642 TCGv_i32 t1
= tcg_temp_new_i32();
7643 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7644 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7645 tcg_gen_or_i32(t0
, t0
, t1
);
7646 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7647 tcg_gen_or_i32(t0
, t0
, t1
);
7648 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7649 tcg_gen_or_i32(t0
, t0
, t1
);
7650 tcg_temp_free_i32(t1
);
7651 tcg_gen_andi_i32(t0
, t0
, 1);
7652 tcg_gen_extu_i32_tl(bcond
, t0
);
7656 ctx
->hflags
|= MIPS_HFLAG_BC
;
7660 generate_exception (ctx
, EXCP_RI
);
7663 (void)opn
; /* avoid a compiler warning */
7664 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7665 ctx
->hflags
, btarget
);
7666 ctx
->btarget
= btarget
;
7669 tcg_temp_free_i32(t0
);
7672 /* R6 CP1 Branches */
7673 static void gen_compute_branch1_r6(DisasContext
*ctx
, uint32_t op
,
7674 int32_t ft
, int32_t offset
)
7676 target_ulong btarget
;
7677 const char *opn
= "cp1 cond branch";
7678 TCGv_i64 t0
= tcg_temp_new_i64();
7680 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
7681 #ifdef MIPS_DEBUG_DISAS
7682 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
7684 generate_exception(ctx
, EXCP_RI
);
7688 gen_load_fpr64(ctx
, t0
, ft
);
7689 tcg_gen_andi_i64(t0
, t0
, 1);
7691 btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
7695 tcg_gen_xori_i64(t0
, t0
, 1);
7697 ctx
->hflags
|= MIPS_HFLAG_BC
;
7700 /* t0 already set */
7702 ctx
->hflags
|= MIPS_HFLAG_BC
;
7706 generate_exception(ctx
, EXCP_RI
);
7710 tcg_gen_trunc_i64_tl(bcond
, t0
);
7712 (void)opn
; /* avoid a compiler warning */
7713 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7714 ctx
->hflags
, btarget
);
7715 ctx
->btarget
= btarget
;
7718 tcg_temp_free_i64(t0
);
7721 /* Coprocessor 1 (FPU) */
7723 #define FOP(func, fmt) (((fmt) << 21) | (func))
7726 OPC_ADD_S
= FOP(0, FMT_S
),
7727 OPC_SUB_S
= FOP(1, FMT_S
),
7728 OPC_MUL_S
= FOP(2, FMT_S
),
7729 OPC_DIV_S
= FOP(3, FMT_S
),
7730 OPC_SQRT_S
= FOP(4, FMT_S
),
7731 OPC_ABS_S
= FOP(5, FMT_S
),
7732 OPC_MOV_S
= FOP(6, FMT_S
),
7733 OPC_NEG_S
= FOP(7, FMT_S
),
7734 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7735 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7736 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7737 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7738 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7739 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7740 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7741 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7742 OPC_SEL_S
= FOP(16, FMT_S
),
7743 OPC_MOVCF_S
= FOP(17, FMT_S
),
7744 OPC_MOVZ_S
= FOP(18, FMT_S
),
7745 OPC_MOVN_S
= FOP(19, FMT_S
),
7746 OPC_SELEQZ_S
= FOP(20, FMT_S
),
7747 OPC_RECIP_S
= FOP(21, FMT_S
),
7748 OPC_RSQRT_S
= FOP(22, FMT_S
),
7749 OPC_SELNEZ_S
= FOP(23, FMT_S
),
7750 OPC_MADDF_S
= FOP(24, FMT_S
),
7751 OPC_MSUBF_S
= FOP(25, FMT_S
),
7752 OPC_RINT_S
= FOP(26, FMT_S
),
7753 OPC_CLASS_S
= FOP(27, FMT_S
),
7754 OPC_MIN_S
= FOP(28, FMT_S
),
7755 OPC_RECIP2_S
= FOP(28, FMT_S
),
7756 OPC_MINA_S
= FOP(29, FMT_S
),
7757 OPC_RECIP1_S
= FOP(29, FMT_S
),
7758 OPC_MAX_S
= FOP(30, FMT_S
),
7759 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7760 OPC_MAXA_S
= FOP(31, FMT_S
),
7761 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7762 OPC_CVT_D_S
= FOP(33, FMT_S
),
7763 OPC_CVT_W_S
= FOP(36, FMT_S
),
7764 OPC_CVT_L_S
= FOP(37, FMT_S
),
7765 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7766 OPC_CMP_F_S
= FOP (48, FMT_S
),
7767 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7768 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7769 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7770 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7771 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7772 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7773 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7774 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7775 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7776 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7777 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7778 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7779 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7780 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7781 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7783 OPC_ADD_D
= FOP(0, FMT_D
),
7784 OPC_SUB_D
= FOP(1, FMT_D
),
7785 OPC_MUL_D
= FOP(2, FMT_D
),
7786 OPC_DIV_D
= FOP(3, FMT_D
),
7787 OPC_SQRT_D
= FOP(4, FMT_D
),
7788 OPC_ABS_D
= FOP(5, FMT_D
),
7789 OPC_MOV_D
= FOP(6, FMT_D
),
7790 OPC_NEG_D
= FOP(7, FMT_D
),
7791 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7792 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7793 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7794 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7795 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7796 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7797 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7798 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7799 OPC_SEL_D
= FOP(16, FMT_D
),
7800 OPC_MOVCF_D
= FOP(17, FMT_D
),
7801 OPC_MOVZ_D
= FOP(18, FMT_D
),
7802 OPC_MOVN_D
= FOP(19, FMT_D
),
7803 OPC_SELEQZ_D
= FOP(20, FMT_D
),
7804 OPC_RECIP_D
= FOP(21, FMT_D
),
7805 OPC_RSQRT_D
= FOP(22, FMT_D
),
7806 OPC_SELNEZ_D
= FOP(23, FMT_D
),
7807 OPC_MADDF_D
= FOP(24, FMT_D
),
7808 OPC_MSUBF_D
= FOP(25, FMT_D
),
7809 OPC_RINT_D
= FOP(26, FMT_D
),
7810 OPC_CLASS_D
= FOP(27, FMT_D
),
7811 OPC_MIN_D
= FOP(28, FMT_D
),
7812 OPC_RECIP2_D
= FOP(28, FMT_D
),
7813 OPC_MINA_D
= FOP(29, FMT_D
),
7814 OPC_RECIP1_D
= FOP(29, FMT_D
),
7815 OPC_MAX_D
= FOP(30, FMT_D
),
7816 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7817 OPC_MAXA_D
= FOP(31, FMT_D
),
7818 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7819 OPC_CVT_S_D
= FOP(32, FMT_D
),
7820 OPC_CVT_W_D
= FOP(36, FMT_D
),
7821 OPC_CVT_L_D
= FOP(37, FMT_D
),
7822 OPC_CMP_F_D
= FOP (48, FMT_D
),
7823 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7824 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7825 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7826 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7827 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7828 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7829 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7830 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7831 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7832 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7833 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7834 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7835 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7836 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7837 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7839 OPC_CVT_S_W
= FOP(32, FMT_W
),
7840 OPC_CVT_D_W
= FOP(33, FMT_W
),
7841 OPC_CVT_S_L
= FOP(32, FMT_L
),
7842 OPC_CVT_D_L
= FOP(33, FMT_L
),
7843 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7845 OPC_ADD_PS
= FOP(0, FMT_PS
),
7846 OPC_SUB_PS
= FOP(1, FMT_PS
),
7847 OPC_MUL_PS
= FOP(2, FMT_PS
),
7848 OPC_DIV_PS
= FOP(3, FMT_PS
),
7849 OPC_ABS_PS
= FOP(5, FMT_PS
),
7850 OPC_MOV_PS
= FOP(6, FMT_PS
),
7851 OPC_NEG_PS
= FOP(7, FMT_PS
),
7852 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7853 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7854 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7855 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7856 OPC_MULR_PS
= FOP(26, FMT_PS
),
7857 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7858 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7859 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7860 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7862 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7863 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7864 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7865 OPC_PLL_PS
= FOP(44, FMT_PS
),
7866 OPC_PLU_PS
= FOP(45, FMT_PS
),
7867 OPC_PUL_PS
= FOP(46, FMT_PS
),
7868 OPC_PUU_PS
= FOP(47, FMT_PS
),
7869 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7870 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7871 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7872 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7873 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7874 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7875 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7876 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7877 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7878 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7879 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7880 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7881 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7882 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7883 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7884 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7888 R6_OPC_CMP_AF_S
= FOP(0, FMT_W
),
7889 R6_OPC_CMP_UN_S
= FOP(1, FMT_W
),
7890 R6_OPC_CMP_EQ_S
= FOP(2, FMT_W
),
7891 R6_OPC_CMP_UEQ_S
= FOP(3, FMT_W
),
7892 R6_OPC_CMP_LT_S
= FOP(4, FMT_W
),
7893 R6_OPC_CMP_ULT_S
= FOP(5, FMT_W
),
7894 R6_OPC_CMP_LE_S
= FOP(6, FMT_W
),
7895 R6_OPC_CMP_ULE_S
= FOP(7, FMT_W
),
7896 R6_OPC_CMP_SAF_S
= FOP(8, FMT_W
),
7897 R6_OPC_CMP_SUN_S
= FOP(9, FMT_W
),
7898 R6_OPC_CMP_SEQ_S
= FOP(10, FMT_W
),
7899 R6_OPC_CMP_SEUQ_S
= FOP(11, FMT_W
),
7900 R6_OPC_CMP_SLT_S
= FOP(12, FMT_W
),
7901 R6_OPC_CMP_SULT_S
= FOP(13, FMT_W
),
7902 R6_OPC_CMP_SLE_S
= FOP(14, FMT_W
),
7903 R6_OPC_CMP_SULE_S
= FOP(15, FMT_W
),
7904 R6_OPC_CMP_OR_S
= FOP(17, FMT_W
),
7905 R6_OPC_CMP_UNE_S
= FOP(18, FMT_W
),
7906 R6_OPC_CMP_NE_S
= FOP(19, FMT_W
),
7907 R6_OPC_CMP_SOR_S
= FOP(25, FMT_W
),
7908 R6_OPC_CMP_SUNE_S
= FOP(26, FMT_W
),
7909 R6_OPC_CMP_SNE_S
= FOP(27, FMT_W
),
7911 R6_OPC_CMP_AF_D
= FOP(0, FMT_L
),
7912 R6_OPC_CMP_UN_D
= FOP(1, FMT_L
),
7913 R6_OPC_CMP_EQ_D
= FOP(2, FMT_L
),
7914 R6_OPC_CMP_UEQ_D
= FOP(3, FMT_L
),
7915 R6_OPC_CMP_LT_D
= FOP(4, FMT_L
),
7916 R6_OPC_CMP_ULT_D
= FOP(5, FMT_L
),
7917 R6_OPC_CMP_LE_D
= FOP(6, FMT_L
),
7918 R6_OPC_CMP_ULE_D
= FOP(7, FMT_L
),
7919 R6_OPC_CMP_SAF_D
= FOP(8, FMT_L
),
7920 R6_OPC_CMP_SUN_D
= FOP(9, FMT_L
),
7921 R6_OPC_CMP_SEQ_D
= FOP(10, FMT_L
),
7922 R6_OPC_CMP_SEUQ_D
= FOP(11, FMT_L
),
7923 R6_OPC_CMP_SLT_D
= FOP(12, FMT_L
),
7924 R6_OPC_CMP_SULT_D
= FOP(13, FMT_L
),
7925 R6_OPC_CMP_SLE_D
= FOP(14, FMT_L
),
7926 R6_OPC_CMP_SULE_D
= FOP(15, FMT_L
),
7927 R6_OPC_CMP_OR_D
= FOP(17, FMT_L
),
7928 R6_OPC_CMP_UNE_D
= FOP(18, FMT_L
),
7929 R6_OPC_CMP_NE_D
= FOP(19, FMT_L
),
7930 R6_OPC_CMP_SOR_D
= FOP(25, FMT_L
),
7931 R6_OPC_CMP_SUNE_D
= FOP(26, FMT_L
),
7932 R6_OPC_CMP_SNE_D
= FOP(27, FMT_L
),
7934 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7936 const char *opn
= "cp1 move";
7937 TCGv t0
= tcg_temp_new();
7942 TCGv_i32 fp0
= tcg_temp_new_i32();
7944 gen_load_fpr32(fp0
, fs
);
7945 tcg_gen_ext_i32_tl(t0
, fp0
);
7946 tcg_temp_free_i32(fp0
);
7948 gen_store_gpr(t0
, rt
);
7952 gen_load_gpr(t0
, rt
);
7954 TCGv_i32 fp0
= tcg_temp_new_i32();
7956 tcg_gen_trunc_tl_i32(fp0
, t0
);
7957 gen_store_fpr32(fp0
, fs
);
7958 tcg_temp_free_i32(fp0
);
7963 gen_helper_1e0i(cfc1
, t0
, fs
);
7964 gen_store_gpr(t0
, rt
);
7968 gen_load_gpr(t0
, rt
);
7970 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
7972 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7973 tcg_temp_free_i32(fs_tmp
);
7977 #if defined(TARGET_MIPS64)
7979 gen_load_fpr64(ctx
, t0
, fs
);
7980 gen_store_gpr(t0
, rt
);
7984 gen_load_gpr(t0
, rt
);
7985 gen_store_fpr64(ctx
, t0
, fs
);
7991 TCGv_i32 fp0
= tcg_temp_new_i32();
7993 gen_load_fpr32h(ctx
, fp0
, fs
);
7994 tcg_gen_ext_i32_tl(t0
, fp0
);
7995 tcg_temp_free_i32(fp0
);
7997 gen_store_gpr(t0
, rt
);
8001 gen_load_gpr(t0
, rt
);
8003 TCGv_i32 fp0
= tcg_temp_new_i32();
8005 tcg_gen_trunc_tl_i32(fp0
, t0
);
8006 gen_store_fpr32h(ctx
, fp0
, fs
);
8007 tcg_temp_free_i32(fp0
);
8013 generate_exception (ctx
, EXCP_RI
);
8016 (void)opn
; /* avoid a compiler warning */
8017 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
8023 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
8039 l1
= gen_new_label();
8040 t0
= tcg_temp_new_i32();
8041 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8042 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8043 tcg_temp_free_i32(t0
);
8045 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
8047 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
8052 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
8055 TCGv_i32 t0
= tcg_temp_new_i32();
8056 int l1
= gen_new_label();
8063 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8064 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8065 gen_load_fpr32(t0
, fs
);
8066 gen_store_fpr32(t0
, fd
);
8068 tcg_temp_free_i32(t0
);
8071 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
8074 TCGv_i32 t0
= tcg_temp_new_i32();
8076 int l1
= gen_new_label();
8083 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8084 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8085 tcg_temp_free_i32(t0
);
8086 fp0
= tcg_temp_new_i64();
8087 gen_load_fpr64(ctx
, fp0
, fs
);
8088 gen_store_fpr64(ctx
, fp0
, fd
);
8089 tcg_temp_free_i64(fp0
);
8093 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
8097 TCGv_i32 t0
= tcg_temp_new_i32();
8098 int l1
= gen_new_label();
8099 int l2
= gen_new_label();
8106 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
8107 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
8108 gen_load_fpr32(t0
, fs
);
8109 gen_store_fpr32(t0
, fd
);
8112 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
8113 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
8114 gen_load_fpr32h(ctx
, t0
, fs
);
8115 gen_store_fpr32h(ctx
, t0
, fd
);
8116 tcg_temp_free_i32(t0
);
8120 static void gen_sel_s(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8123 TCGv_i32 t1
= tcg_const_i32(0);
8124 TCGv_i32 fp0
= tcg_temp_new_i32();
8125 TCGv_i32 fp1
= tcg_temp_new_i32();
8126 TCGv_i32 fp2
= tcg_temp_new_i32();
8127 gen_load_fpr32(fp0
, fd
);
8128 gen_load_fpr32(fp1
, ft
);
8129 gen_load_fpr32(fp2
, fs
);
8133 tcg_gen_andi_i32(fp0
, fp0
, 1);
8134 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8137 tcg_gen_andi_i32(fp1
, fp1
, 1);
8138 tcg_gen_movcond_i32(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8141 tcg_gen_andi_i32(fp1
, fp1
, 1);
8142 tcg_gen_movcond_i32(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8145 MIPS_INVAL("gen_sel_s");
8146 generate_exception (ctx
, EXCP_RI
);
8150 gen_store_fpr32(fp0
, fd
);
8151 tcg_temp_free_i32(fp2
);
8152 tcg_temp_free_i32(fp1
);
8153 tcg_temp_free_i32(fp0
);
8154 tcg_temp_free_i32(t1
);
8157 static void gen_sel_d(DisasContext
*ctx
, enum fopcode op1
, int fd
, int ft
,
8160 TCGv_i64 t1
= tcg_const_i64(0);
8161 TCGv_i64 fp0
= tcg_temp_new_i64();
8162 TCGv_i64 fp1
= tcg_temp_new_i64();
8163 TCGv_i64 fp2
= tcg_temp_new_i64();
8164 gen_load_fpr64(ctx
, fp0
, fd
);
8165 gen_load_fpr64(ctx
, fp1
, ft
);
8166 gen_load_fpr64(ctx
, fp2
, fs
);
8170 tcg_gen_andi_i64(fp0
, fp0
, 1);
8171 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp0
, t1
, fp1
, fp2
);
8174 tcg_gen_andi_i64(fp1
, fp1
, 1);
8175 tcg_gen_movcond_i64(TCG_COND_EQ
, fp0
, fp1
, t1
, fp2
, t1
);
8178 tcg_gen_andi_i64(fp1
, fp1
, 1);
8179 tcg_gen_movcond_i64(TCG_COND_NE
, fp0
, fp1
, t1
, fp2
, t1
);
8182 MIPS_INVAL("gen_sel_d");
8183 generate_exception (ctx
, EXCP_RI
);
8187 gen_store_fpr64(ctx
, fp0
, fd
);
8188 tcg_temp_free_i64(fp2
);
8189 tcg_temp_free_i64(fp1
);
8190 tcg_temp_free_i64(fp0
);
8191 tcg_temp_free_i64(t1
);
8194 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
8195 int ft
, int fs
, int fd
, int cc
)
8197 const char *opn
= "farith";
8198 const char *condnames
[] = {
8216 const char *condnames_abs
[] = {
8234 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
8235 uint32_t func
= ctx
->opcode
& 0x3f;
8240 TCGv_i32 fp0
= tcg_temp_new_i32();
8241 TCGv_i32 fp1
= tcg_temp_new_i32();
8243 gen_load_fpr32(fp0
, fs
);
8244 gen_load_fpr32(fp1
, ft
);
8245 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
8246 tcg_temp_free_i32(fp1
);
8247 gen_store_fpr32(fp0
, fd
);
8248 tcg_temp_free_i32(fp0
);
8255 TCGv_i32 fp0
= tcg_temp_new_i32();
8256 TCGv_i32 fp1
= tcg_temp_new_i32();
8258 gen_load_fpr32(fp0
, fs
);
8259 gen_load_fpr32(fp1
, ft
);
8260 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
8261 tcg_temp_free_i32(fp1
);
8262 gen_store_fpr32(fp0
, fd
);
8263 tcg_temp_free_i32(fp0
);
8270 TCGv_i32 fp0
= tcg_temp_new_i32();
8271 TCGv_i32 fp1
= tcg_temp_new_i32();
8273 gen_load_fpr32(fp0
, fs
);
8274 gen_load_fpr32(fp1
, ft
);
8275 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
8276 tcg_temp_free_i32(fp1
);
8277 gen_store_fpr32(fp0
, fd
);
8278 tcg_temp_free_i32(fp0
);
8285 TCGv_i32 fp0
= tcg_temp_new_i32();
8286 TCGv_i32 fp1
= tcg_temp_new_i32();
8288 gen_load_fpr32(fp0
, fs
);
8289 gen_load_fpr32(fp1
, ft
);
8290 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
8291 tcg_temp_free_i32(fp1
);
8292 gen_store_fpr32(fp0
, fd
);
8293 tcg_temp_free_i32(fp0
);
8300 TCGv_i32 fp0
= tcg_temp_new_i32();
8302 gen_load_fpr32(fp0
, fs
);
8303 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
8304 gen_store_fpr32(fp0
, fd
);
8305 tcg_temp_free_i32(fp0
);
8311 TCGv_i32 fp0
= tcg_temp_new_i32();
8313 gen_load_fpr32(fp0
, fs
);
8314 gen_helper_float_abs_s(fp0
, fp0
);
8315 gen_store_fpr32(fp0
, fd
);
8316 tcg_temp_free_i32(fp0
);
8322 TCGv_i32 fp0
= tcg_temp_new_i32();
8324 gen_load_fpr32(fp0
, fs
);
8325 gen_store_fpr32(fp0
, fd
);
8326 tcg_temp_free_i32(fp0
);
8332 TCGv_i32 fp0
= tcg_temp_new_i32();
8334 gen_load_fpr32(fp0
, fs
);
8335 gen_helper_float_chs_s(fp0
, fp0
);
8336 gen_store_fpr32(fp0
, fd
);
8337 tcg_temp_free_i32(fp0
);
8342 check_cp1_64bitmode(ctx
);
8344 TCGv_i32 fp32
= tcg_temp_new_i32();
8345 TCGv_i64 fp64
= tcg_temp_new_i64();
8347 gen_load_fpr32(fp32
, fs
);
8348 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
8349 tcg_temp_free_i32(fp32
);
8350 gen_store_fpr64(ctx
, fp64
, fd
);
8351 tcg_temp_free_i64(fp64
);
8356 check_cp1_64bitmode(ctx
);
8358 TCGv_i32 fp32
= tcg_temp_new_i32();
8359 TCGv_i64 fp64
= tcg_temp_new_i64();
8361 gen_load_fpr32(fp32
, fs
);
8362 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
8363 tcg_temp_free_i32(fp32
);
8364 gen_store_fpr64(ctx
, fp64
, fd
);
8365 tcg_temp_free_i64(fp64
);
8370 check_cp1_64bitmode(ctx
);
8372 TCGv_i32 fp32
= tcg_temp_new_i32();
8373 TCGv_i64 fp64
= tcg_temp_new_i64();
8375 gen_load_fpr32(fp32
, fs
);
8376 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
8377 tcg_temp_free_i32(fp32
);
8378 gen_store_fpr64(ctx
, fp64
, fd
);
8379 tcg_temp_free_i64(fp64
);
8384 check_cp1_64bitmode(ctx
);
8386 TCGv_i32 fp32
= tcg_temp_new_i32();
8387 TCGv_i64 fp64
= tcg_temp_new_i64();
8389 gen_load_fpr32(fp32
, fs
);
8390 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
8391 tcg_temp_free_i32(fp32
);
8392 gen_store_fpr64(ctx
, fp64
, fd
);
8393 tcg_temp_free_i64(fp64
);
8399 TCGv_i32 fp0
= tcg_temp_new_i32();
8401 gen_load_fpr32(fp0
, fs
);
8402 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
8403 gen_store_fpr32(fp0
, fd
);
8404 tcg_temp_free_i32(fp0
);
8410 TCGv_i32 fp0
= tcg_temp_new_i32();
8412 gen_load_fpr32(fp0
, fs
);
8413 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
8414 gen_store_fpr32(fp0
, fd
);
8415 tcg_temp_free_i32(fp0
);
8421 TCGv_i32 fp0
= tcg_temp_new_i32();
8423 gen_load_fpr32(fp0
, fs
);
8424 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
8425 gen_store_fpr32(fp0
, fd
);
8426 tcg_temp_free_i32(fp0
);
8432 TCGv_i32 fp0
= tcg_temp_new_i32();
8434 gen_load_fpr32(fp0
, fs
);
8435 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
8436 gen_store_fpr32(fp0
, fd
);
8437 tcg_temp_free_i32(fp0
);
8442 check_insn(ctx
, ISA_MIPS32R6
);
8443 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8447 check_insn(ctx
, ISA_MIPS32R6
);
8448 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8452 check_insn(ctx
, ISA_MIPS32R6
);
8453 gen_sel_s(ctx
, op1
, fd
, ft
, fs
);
8457 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8458 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8462 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8464 int l1
= gen_new_label();
8468 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8470 fp0
= tcg_temp_new_i32();
8471 gen_load_fpr32(fp0
, fs
);
8472 gen_store_fpr32(fp0
, fd
);
8473 tcg_temp_free_i32(fp0
);
8479 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8481 int l1
= gen_new_label();
8485 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8486 fp0
= tcg_temp_new_i32();
8487 gen_load_fpr32(fp0
, fs
);
8488 gen_store_fpr32(fp0
, fd
);
8489 tcg_temp_free_i32(fp0
);
8498 TCGv_i32 fp0
= tcg_temp_new_i32();
8500 gen_load_fpr32(fp0
, fs
);
8501 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
8502 gen_store_fpr32(fp0
, fd
);
8503 tcg_temp_free_i32(fp0
);
8510 TCGv_i32 fp0
= tcg_temp_new_i32();
8512 gen_load_fpr32(fp0
, fs
);
8513 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
8514 gen_store_fpr32(fp0
, fd
);
8515 tcg_temp_free_i32(fp0
);
8520 check_insn(ctx
, ISA_MIPS32R6
);
8522 TCGv_i32 fp0
= tcg_temp_new_i32();
8523 TCGv_i32 fp1
= tcg_temp_new_i32();
8524 TCGv_i32 fp2
= tcg_temp_new_i32();
8525 gen_load_fpr32(fp0
, fs
);
8526 gen_load_fpr32(fp1
, ft
);
8527 gen_load_fpr32(fp2
, fd
);
8528 gen_helper_float_maddf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8529 gen_store_fpr32(fp2
, fd
);
8530 tcg_temp_free_i32(fp2
);
8531 tcg_temp_free_i32(fp1
);
8532 tcg_temp_free_i32(fp0
);
8537 check_insn(ctx
, ISA_MIPS32R6
);
8539 TCGv_i32 fp0
= tcg_temp_new_i32();
8540 TCGv_i32 fp1
= tcg_temp_new_i32();
8541 TCGv_i32 fp2
= tcg_temp_new_i32();
8542 gen_load_fpr32(fp0
, fs
);
8543 gen_load_fpr32(fp1
, ft
);
8544 gen_load_fpr32(fp2
, fd
);
8545 gen_helper_float_msubf_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8546 gen_store_fpr32(fp2
, fd
);
8547 tcg_temp_free_i32(fp2
);
8548 tcg_temp_free_i32(fp1
);
8549 tcg_temp_free_i32(fp0
);
8554 check_insn(ctx
, ISA_MIPS32R6
);
8556 TCGv_i32 fp0
= tcg_temp_new_i32();
8557 gen_load_fpr32(fp0
, fs
);
8558 gen_helper_float_rint_s(fp0
, cpu_env
, fp0
);
8559 gen_store_fpr32(fp0
, fd
);
8560 tcg_temp_free_i32(fp0
);
8565 check_insn(ctx
, ISA_MIPS32R6
);
8567 TCGv_i32 fp0
= tcg_temp_new_i32();
8568 gen_load_fpr32(fp0
, fs
);
8569 gen_helper_float_class_s(fp0
, fp0
);
8570 gen_store_fpr32(fp0
, fd
);
8571 tcg_temp_free_i32(fp0
);
8575 case OPC_MIN_S
: /* OPC_RECIP2_S */
8576 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8578 TCGv_i32 fp0
= tcg_temp_new_i32();
8579 TCGv_i32 fp1
= tcg_temp_new_i32();
8580 TCGv_i32 fp2
= tcg_temp_new_i32();
8581 gen_load_fpr32(fp0
, fs
);
8582 gen_load_fpr32(fp1
, ft
);
8583 gen_helper_float_min_s(fp2
, cpu_env
, fp0
, fp1
);
8584 gen_store_fpr32(fp2
, fd
);
8585 tcg_temp_free_i32(fp2
);
8586 tcg_temp_free_i32(fp1
);
8587 tcg_temp_free_i32(fp0
);
8591 check_cp1_64bitmode(ctx
);
8593 TCGv_i32 fp0
= tcg_temp_new_i32();
8594 TCGv_i32 fp1
= tcg_temp_new_i32();
8596 gen_load_fpr32(fp0
, fs
);
8597 gen_load_fpr32(fp1
, ft
);
8598 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
8599 tcg_temp_free_i32(fp1
);
8600 gen_store_fpr32(fp0
, fd
);
8601 tcg_temp_free_i32(fp0
);
8606 case OPC_MINA_S
: /* OPC_RECIP1_S */
8607 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8609 TCGv_i32 fp0
= tcg_temp_new_i32();
8610 TCGv_i32 fp1
= tcg_temp_new_i32();
8611 TCGv_i32 fp2
= tcg_temp_new_i32();
8612 gen_load_fpr32(fp0
, fs
);
8613 gen_load_fpr32(fp1
, ft
);
8614 gen_helper_float_mina_s(fp2
, cpu_env
, fp0
, fp1
);
8615 gen_store_fpr32(fp2
, fd
);
8616 tcg_temp_free_i32(fp2
);
8617 tcg_temp_free_i32(fp1
);
8618 tcg_temp_free_i32(fp0
);
8622 check_cp1_64bitmode(ctx
);
8624 TCGv_i32 fp0
= tcg_temp_new_i32();
8626 gen_load_fpr32(fp0
, fs
);
8627 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
8628 gen_store_fpr32(fp0
, fd
);
8629 tcg_temp_free_i32(fp0
);
8634 case OPC_MAX_S
: /* OPC_RSQRT1_S */
8635 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8637 TCGv_i32 fp0
= tcg_temp_new_i32();
8638 TCGv_i32 fp1
= tcg_temp_new_i32();
8639 gen_load_fpr32(fp0
, fs
);
8640 gen_load_fpr32(fp1
, ft
);
8641 gen_helper_float_max_s(fp1
, cpu_env
, fp0
, fp1
);
8642 gen_store_fpr32(fp1
, fd
);
8643 tcg_temp_free_i32(fp1
);
8644 tcg_temp_free_i32(fp0
);
8648 check_cp1_64bitmode(ctx
);
8650 TCGv_i32 fp0
= tcg_temp_new_i32();
8652 gen_load_fpr32(fp0
, fs
);
8653 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
8654 gen_store_fpr32(fp0
, fd
);
8655 tcg_temp_free_i32(fp0
);
8660 case OPC_MAXA_S
: /* OPC_RSQRT2_S */
8661 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
8663 TCGv_i32 fp0
= tcg_temp_new_i32();
8664 TCGv_i32 fp1
= tcg_temp_new_i32();
8665 gen_load_fpr32(fp0
, fs
);
8666 gen_load_fpr32(fp1
, ft
);
8667 gen_helper_float_maxa_s(fp1
, cpu_env
, fp0
, fp1
);
8668 gen_store_fpr32(fp1
, fd
);
8669 tcg_temp_free_i32(fp1
);
8670 tcg_temp_free_i32(fp0
);
8674 check_cp1_64bitmode(ctx
);
8676 TCGv_i32 fp0
= tcg_temp_new_i32();
8677 TCGv_i32 fp1
= tcg_temp_new_i32();
8679 gen_load_fpr32(fp0
, fs
);
8680 gen_load_fpr32(fp1
, ft
);
8681 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
8682 tcg_temp_free_i32(fp1
);
8683 gen_store_fpr32(fp0
, fd
);
8684 tcg_temp_free_i32(fp0
);
8690 check_cp1_registers(ctx
, fd
);
8692 TCGv_i32 fp32
= tcg_temp_new_i32();
8693 TCGv_i64 fp64
= tcg_temp_new_i64();
8695 gen_load_fpr32(fp32
, fs
);
8696 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
8697 tcg_temp_free_i32(fp32
);
8698 gen_store_fpr64(ctx
, fp64
, fd
);
8699 tcg_temp_free_i64(fp64
);
8705 TCGv_i32 fp0
= tcg_temp_new_i32();
8707 gen_load_fpr32(fp0
, fs
);
8708 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
8709 gen_store_fpr32(fp0
, fd
);
8710 tcg_temp_free_i32(fp0
);
8715 check_cp1_64bitmode(ctx
);
8717 TCGv_i32 fp32
= tcg_temp_new_i32();
8718 TCGv_i64 fp64
= tcg_temp_new_i64();
8720 gen_load_fpr32(fp32
, fs
);
8721 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
8722 tcg_temp_free_i32(fp32
);
8723 gen_store_fpr64(ctx
, fp64
, fd
);
8724 tcg_temp_free_i64(fp64
);
8729 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8730 check_cp1_64bitmode(ctx
);
8732 TCGv_i64 fp64
= tcg_temp_new_i64();
8733 TCGv_i32 fp32_0
= tcg_temp_new_i32();
8734 TCGv_i32 fp32_1
= tcg_temp_new_i32();
8736 gen_load_fpr32(fp32_0
, fs
);
8737 gen_load_fpr32(fp32_1
, ft
);
8738 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
8739 tcg_temp_free_i32(fp32_1
);
8740 tcg_temp_free_i32(fp32_0
);
8741 gen_store_fpr64(ctx
, fp64
, fd
);
8742 tcg_temp_free_i64(fp64
);
8755 case OPC_CMP_NGLE_S
:
8762 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
8763 if (ctx
->opcode
& (1 << 6)) {
8764 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
8765 opn
= condnames_abs
[func
-48];
8767 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
8768 opn
= condnames
[func
-48];
8772 check_cp1_registers(ctx
, fs
| ft
| fd
);
8774 TCGv_i64 fp0
= tcg_temp_new_i64();
8775 TCGv_i64 fp1
= tcg_temp_new_i64();
8777 gen_load_fpr64(ctx
, fp0
, fs
);
8778 gen_load_fpr64(ctx
, fp1
, ft
);
8779 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
8780 tcg_temp_free_i64(fp1
);
8781 gen_store_fpr64(ctx
, fp0
, fd
);
8782 tcg_temp_free_i64(fp0
);
8788 check_cp1_registers(ctx
, fs
| ft
| fd
);
8790 TCGv_i64 fp0
= tcg_temp_new_i64();
8791 TCGv_i64 fp1
= tcg_temp_new_i64();
8793 gen_load_fpr64(ctx
, fp0
, fs
);
8794 gen_load_fpr64(ctx
, fp1
, ft
);
8795 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
8796 tcg_temp_free_i64(fp1
);
8797 gen_store_fpr64(ctx
, fp0
, fd
);
8798 tcg_temp_free_i64(fp0
);
8804 check_cp1_registers(ctx
, fs
| ft
| fd
);
8806 TCGv_i64 fp0
= tcg_temp_new_i64();
8807 TCGv_i64 fp1
= tcg_temp_new_i64();
8809 gen_load_fpr64(ctx
, fp0
, fs
);
8810 gen_load_fpr64(ctx
, fp1
, ft
);
8811 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
8812 tcg_temp_free_i64(fp1
);
8813 gen_store_fpr64(ctx
, fp0
, fd
);
8814 tcg_temp_free_i64(fp0
);
8820 check_cp1_registers(ctx
, fs
| ft
| fd
);
8822 TCGv_i64 fp0
= tcg_temp_new_i64();
8823 TCGv_i64 fp1
= tcg_temp_new_i64();
8825 gen_load_fpr64(ctx
, fp0
, fs
);
8826 gen_load_fpr64(ctx
, fp1
, ft
);
8827 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
8828 tcg_temp_free_i64(fp1
);
8829 gen_store_fpr64(ctx
, fp0
, fd
);
8830 tcg_temp_free_i64(fp0
);
8836 check_cp1_registers(ctx
, fs
| fd
);
8838 TCGv_i64 fp0
= tcg_temp_new_i64();
8840 gen_load_fpr64(ctx
, fp0
, fs
);
8841 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
8842 gen_store_fpr64(ctx
, fp0
, fd
);
8843 tcg_temp_free_i64(fp0
);
8848 check_cp1_registers(ctx
, fs
| fd
);
8850 TCGv_i64 fp0
= tcg_temp_new_i64();
8852 gen_load_fpr64(ctx
, fp0
, fs
);
8853 gen_helper_float_abs_d(fp0
, fp0
);
8854 gen_store_fpr64(ctx
, fp0
, fd
);
8855 tcg_temp_free_i64(fp0
);
8860 check_cp1_registers(ctx
, fs
| fd
);
8862 TCGv_i64 fp0
= tcg_temp_new_i64();
8864 gen_load_fpr64(ctx
, fp0
, fs
);
8865 gen_store_fpr64(ctx
, fp0
, fd
);
8866 tcg_temp_free_i64(fp0
);
8871 check_cp1_registers(ctx
, fs
| fd
);
8873 TCGv_i64 fp0
= tcg_temp_new_i64();
8875 gen_load_fpr64(ctx
, fp0
, fs
);
8876 gen_helper_float_chs_d(fp0
, fp0
);
8877 gen_store_fpr64(ctx
, fp0
, fd
);
8878 tcg_temp_free_i64(fp0
);
8883 check_cp1_64bitmode(ctx
);
8885 TCGv_i64 fp0
= tcg_temp_new_i64();
8887 gen_load_fpr64(ctx
, fp0
, fs
);
8888 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
8889 gen_store_fpr64(ctx
, fp0
, fd
);
8890 tcg_temp_free_i64(fp0
);
8895 check_cp1_64bitmode(ctx
);
8897 TCGv_i64 fp0
= tcg_temp_new_i64();
8899 gen_load_fpr64(ctx
, fp0
, fs
);
8900 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
8901 gen_store_fpr64(ctx
, fp0
, fd
);
8902 tcg_temp_free_i64(fp0
);
8907 check_cp1_64bitmode(ctx
);
8909 TCGv_i64 fp0
= tcg_temp_new_i64();
8911 gen_load_fpr64(ctx
, fp0
, fs
);
8912 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
8913 gen_store_fpr64(ctx
, fp0
, fd
);
8914 tcg_temp_free_i64(fp0
);
8919 check_cp1_64bitmode(ctx
);
8921 TCGv_i64 fp0
= tcg_temp_new_i64();
8923 gen_load_fpr64(ctx
, fp0
, fs
);
8924 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8925 gen_store_fpr64(ctx
, fp0
, fd
);
8926 tcg_temp_free_i64(fp0
);
8931 check_cp1_registers(ctx
, fs
);
8933 TCGv_i32 fp32
= tcg_temp_new_i32();
8934 TCGv_i64 fp64
= tcg_temp_new_i64();
8936 gen_load_fpr64(ctx
, fp64
, fs
);
8937 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8938 tcg_temp_free_i64(fp64
);
8939 gen_store_fpr32(fp32
, fd
);
8940 tcg_temp_free_i32(fp32
);
8945 check_cp1_registers(ctx
, fs
);
8947 TCGv_i32 fp32
= tcg_temp_new_i32();
8948 TCGv_i64 fp64
= tcg_temp_new_i64();
8950 gen_load_fpr64(ctx
, fp64
, fs
);
8951 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8952 tcg_temp_free_i64(fp64
);
8953 gen_store_fpr32(fp32
, fd
);
8954 tcg_temp_free_i32(fp32
);
8959 check_cp1_registers(ctx
, fs
);
8961 TCGv_i32 fp32
= tcg_temp_new_i32();
8962 TCGv_i64 fp64
= tcg_temp_new_i64();
8964 gen_load_fpr64(ctx
, fp64
, fs
);
8965 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8966 tcg_temp_free_i64(fp64
);
8967 gen_store_fpr32(fp32
, fd
);
8968 tcg_temp_free_i32(fp32
);
8973 check_cp1_registers(ctx
, fs
);
8975 TCGv_i32 fp32
= tcg_temp_new_i32();
8976 TCGv_i64 fp64
= tcg_temp_new_i64();
8978 gen_load_fpr64(ctx
, fp64
, fs
);
8979 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8980 tcg_temp_free_i64(fp64
);
8981 gen_store_fpr32(fp32
, fd
);
8982 tcg_temp_free_i32(fp32
);
8987 check_insn(ctx
, ISA_MIPS32R6
);
8988 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
8992 check_insn(ctx
, ISA_MIPS32R6
);
8993 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
8997 check_insn(ctx
, ISA_MIPS32R6
);
8998 gen_sel_d(ctx
, op1
, fd
, ft
, fs
);
9002 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9003 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9007 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9009 int l1
= gen_new_label();
9013 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9015 fp0
= tcg_temp_new_i64();
9016 gen_load_fpr64(ctx
, fp0
, fs
);
9017 gen_store_fpr64(ctx
, fp0
, fd
);
9018 tcg_temp_free_i64(fp0
);
9024 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9026 int l1
= gen_new_label();
9030 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9031 fp0
= tcg_temp_new_i64();
9032 gen_load_fpr64(ctx
, fp0
, fs
);
9033 gen_store_fpr64(ctx
, fp0
, fd
);
9034 tcg_temp_free_i64(fp0
);
9041 check_cp1_64bitmode(ctx
);
9043 TCGv_i64 fp0
= tcg_temp_new_i64();
9045 gen_load_fpr64(ctx
, fp0
, fs
);
9046 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
9047 gen_store_fpr64(ctx
, fp0
, fd
);
9048 tcg_temp_free_i64(fp0
);
9053 check_cp1_64bitmode(ctx
);
9055 TCGv_i64 fp0
= tcg_temp_new_i64();
9057 gen_load_fpr64(ctx
, fp0
, fs
);
9058 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
9059 gen_store_fpr64(ctx
, fp0
, fd
);
9060 tcg_temp_free_i64(fp0
);
9065 check_insn(ctx
, ISA_MIPS32R6
);
9067 TCGv_i64 fp0
= tcg_temp_new_i64();
9068 TCGv_i64 fp1
= tcg_temp_new_i64();
9069 TCGv_i64 fp2
= tcg_temp_new_i64();
9070 gen_load_fpr64(ctx
, fp0
, fs
);
9071 gen_load_fpr64(ctx
, fp1
, ft
);
9072 gen_load_fpr64(ctx
, fp2
, fd
);
9073 gen_helper_float_maddf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9074 gen_store_fpr64(ctx
, fp2
, fd
);
9075 tcg_temp_free_i64(fp2
);
9076 tcg_temp_free_i64(fp1
);
9077 tcg_temp_free_i64(fp0
);
9082 check_insn(ctx
, ISA_MIPS32R6
);
9084 TCGv_i64 fp0
= tcg_temp_new_i64();
9085 TCGv_i64 fp1
= tcg_temp_new_i64();
9086 TCGv_i64 fp2
= tcg_temp_new_i64();
9087 gen_load_fpr64(ctx
, fp0
, fs
);
9088 gen_load_fpr64(ctx
, fp1
, ft
);
9089 gen_load_fpr64(ctx
, fp2
, fd
);
9090 gen_helper_float_msubf_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9091 gen_store_fpr64(ctx
, fp2
, fd
);
9092 tcg_temp_free_i64(fp2
);
9093 tcg_temp_free_i64(fp1
);
9094 tcg_temp_free_i64(fp0
);
9099 check_insn(ctx
, ISA_MIPS32R6
);
9101 TCGv_i64 fp0
= tcg_temp_new_i64();
9102 gen_load_fpr64(ctx
, fp0
, fs
);
9103 gen_helper_float_rint_d(fp0
, cpu_env
, fp0
);
9104 gen_store_fpr64(ctx
, fp0
, fd
);
9105 tcg_temp_free_i64(fp0
);
9110 check_insn(ctx
, ISA_MIPS32R6
);
9112 TCGv_i64 fp0
= tcg_temp_new_i64();
9113 gen_load_fpr64(ctx
, fp0
, fs
);
9114 gen_helper_float_class_d(fp0
, fp0
);
9115 gen_store_fpr64(ctx
, fp0
, fd
);
9116 tcg_temp_free_i64(fp0
);
9120 case OPC_MIN_D
: /* OPC_RECIP2_D */
9121 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9123 TCGv_i64 fp0
= tcg_temp_new_i64();
9124 TCGv_i64 fp1
= tcg_temp_new_i64();
9125 gen_load_fpr64(ctx
, fp0
, fs
);
9126 gen_load_fpr64(ctx
, fp1
, ft
);
9127 gen_helper_float_min_d(fp1
, cpu_env
, fp0
, fp1
);
9128 gen_store_fpr64(ctx
, fp1
, fd
);
9129 tcg_temp_free_i64(fp1
);
9130 tcg_temp_free_i64(fp0
);
9134 check_cp1_64bitmode(ctx
);
9136 TCGv_i64 fp0
= tcg_temp_new_i64();
9137 TCGv_i64 fp1
= tcg_temp_new_i64();
9139 gen_load_fpr64(ctx
, fp0
, fs
);
9140 gen_load_fpr64(ctx
, fp1
, ft
);
9141 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
9142 tcg_temp_free_i64(fp1
);
9143 gen_store_fpr64(ctx
, fp0
, fd
);
9144 tcg_temp_free_i64(fp0
);
9149 case OPC_MINA_D
: /* OPC_RECIP1_D */
9150 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9152 TCGv_i64 fp0
= tcg_temp_new_i64();
9153 TCGv_i64 fp1
= tcg_temp_new_i64();
9154 gen_load_fpr64(ctx
, fp0
, fs
);
9155 gen_load_fpr64(ctx
, fp1
, ft
);
9156 gen_helper_float_mina_d(fp1
, cpu_env
, fp0
, fp1
);
9157 gen_store_fpr64(ctx
, fp1
, fd
);
9158 tcg_temp_free_i64(fp1
);
9159 tcg_temp_free_i64(fp0
);
9163 check_cp1_64bitmode(ctx
);
9165 TCGv_i64 fp0
= tcg_temp_new_i64();
9167 gen_load_fpr64(ctx
, fp0
, fs
);
9168 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
9169 gen_store_fpr64(ctx
, fp0
, fd
);
9170 tcg_temp_free_i64(fp0
);
9175 case OPC_MAX_D
: /* OPC_RSQRT1_D */
9176 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9178 TCGv_i64 fp0
= tcg_temp_new_i64();
9179 TCGv_i64 fp1
= tcg_temp_new_i64();
9180 gen_load_fpr64(ctx
, fp0
, fs
);
9181 gen_load_fpr64(ctx
, fp1
, ft
);
9182 gen_helper_float_max_d(fp1
, cpu_env
, fp0
, fp1
);
9183 gen_store_fpr64(ctx
, fp1
, fd
);
9184 tcg_temp_free_i64(fp1
);
9185 tcg_temp_free_i64(fp0
);
9189 check_cp1_64bitmode(ctx
);
9191 TCGv_i64 fp0
= tcg_temp_new_i64();
9193 gen_load_fpr64(ctx
, fp0
, fs
);
9194 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
9195 gen_store_fpr64(ctx
, fp0
, fd
);
9196 tcg_temp_free_i64(fp0
);
9201 case OPC_MAXA_D
: /* OPC_RSQRT2_D */
9202 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
9204 TCGv_i64 fp0
= tcg_temp_new_i64();
9205 TCGv_i64 fp1
= tcg_temp_new_i64();
9206 gen_load_fpr64(ctx
, fp0
, fs
);
9207 gen_load_fpr64(ctx
, fp1
, ft
);
9208 gen_helper_float_maxa_d(fp1
, cpu_env
, fp0
, fp1
);
9209 gen_store_fpr64(ctx
, fp1
, fd
);
9210 tcg_temp_free_i64(fp1
);
9211 tcg_temp_free_i64(fp0
);
9215 check_cp1_64bitmode(ctx
);
9217 TCGv_i64 fp0
= tcg_temp_new_i64();
9218 TCGv_i64 fp1
= tcg_temp_new_i64();
9220 gen_load_fpr64(ctx
, fp0
, fs
);
9221 gen_load_fpr64(ctx
, fp1
, ft
);
9222 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
9223 tcg_temp_free_i64(fp1
);
9224 gen_store_fpr64(ctx
, fp0
, fd
);
9225 tcg_temp_free_i64(fp0
);
9239 case OPC_CMP_NGLE_D
:
9246 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9247 if (ctx
->opcode
& (1 << 6)) {
9248 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
9249 opn
= condnames_abs
[func
-48];
9251 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
9252 opn
= condnames
[func
-48];
9256 check_cp1_registers(ctx
, fs
);
9258 TCGv_i32 fp32
= tcg_temp_new_i32();
9259 TCGv_i64 fp64
= tcg_temp_new_i64();
9261 gen_load_fpr64(ctx
, fp64
, fs
);
9262 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
9263 tcg_temp_free_i64(fp64
);
9264 gen_store_fpr32(fp32
, fd
);
9265 tcg_temp_free_i32(fp32
);
9270 check_cp1_registers(ctx
, fs
);
9272 TCGv_i32 fp32
= tcg_temp_new_i32();
9273 TCGv_i64 fp64
= tcg_temp_new_i64();
9275 gen_load_fpr64(ctx
, fp64
, fs
);
9276 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
9277 tcg_temp_free_i64(fp64
);
9278 gen_store_fpr32(fp32
, fd
);
9279 tcg_temp_free_i32(fp32
);
9284 check_cp1_64bitmode(ctx
);
9286 TCGv_i64 fp0
= tcg_temp_new_i64();
9288 gen_load_fpr64(ctx
, fp0
, fs
);
9289 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
9290 gen_store_fpr64(ctx
, fp0
, fd
);
9291 tcg_temp_free_i64(fp0
);
9297 TCGv_i32 fp0
= tcg_temp_new_i32();
9299 gen_load_fpr32(fp0
, fs
);
9300 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
9301 gen_store_fpr32(fp0
, fd
);
9302 tcg_temp_free_i32(fp0
);
9307 check_cp1_registers(ctx
, fd
);
9309 TCGv_i32 fp32
= tcg_temp_new_i32();
9310 TCGv_i64 fp64
= tcg_temp_new_i64();
9312 gen_load_fpr32(fp32
, fs
);
9313 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
9314 tcg_temp_free_i32(fp32
);
9315 gen_store_fpr64(ctx
, fp64
, fd
);
9316 tcg_temp_free_i64(fp64
);
9321 check_cp1_64bitmode(ctx
);
9323 TCGv_i32 fp32
= tcg_temp_new_i32();
9324 TCGv_i64 fp64
= tcg_temp_new_i64();
9326 gen_load_fpr64(ctx
, fp64
, fs
);
9327 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
9328 tcg_temp_free_i64(fp64
);
9329 gen_store_fpr32(fp32
, fd
);
9330 tcg_temp_free_i32(fp32
);
9335 check_cp1_64bitmode(ctx
);
9337 TCGv_i64 fp0
= tcg_temp_new_i64();
9339 gen_load_fpr64(ctx
, fp0
, fs
);
9340 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
9341 gen_store_fpr64(ctx
, fp0
, fd
);
9342 tcg_temp_free_i64(fp0
);
9347 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
9348 check_cp1_64bitmode(ctx
);
9350 TCGv_i64 fp0
= tcg_temp_new_i64();
9352 gen_load_fpr64(ctx
, fp0
, fs
);
9353 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
9354 gen_store_fpr64(ctx
, fp0
, fd
);
9355 tcg_temp_free_i64(fp0
);
9360 check_cp1_64bitmode(ctx
);
9362 TCGv_i64 fp0
= tcg_temp_new_i64();
9363 TCGv_i64 fp1
= tcg_temp_new_i64();
9365 gen_load_fpr64(ctx
, fp0
, fs
);
9366 gen_load_fpr64(ctx
, fp1
, ft
);
9367 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
9368 tcg_temp_free_i64(fp1
);
9369 gen_store_fpr64(ctx
, fp0
, fd
);
9370 tcg_temp_free_i64(fp0
);
9375 check_cp1_64bitmode(ctx
);
9377 TCGv_i64 fp0
= tcg_temp_new_i64();
9378 TCGv_i64 fp1
= tcg_temp_new_i64();
9380 gen_load_fpr64(ctx
, fp0
, fs
);
9381 gen_load_fpr64(ctx
, fp1
, ft
);
9382 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
9383 tcg_temp_free_i64(fp1
);
9384 gen_store_fpr64(ctx
, fp0
, fd
);
9385 tcg_temp_free_i64(fp0
);
9390 check_cp1_64bitmode(ctx
);
9392 TCGv_i64 fp0
= tcg_temp_new_i64();
9393 TCGv_i64 fp1
= tcg_temp_new_i64();
9395 gen_load_fpr64(ctx
, fp0
, fs
);
9396 gen_load_fpr64(ctx
, fp1
, ft
);
9397 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
9398 tcg_temp_free_i64(fp1
);
9399 gen_store_fpr64(ctx
, fp0
, fd
);
9400 tcg_temp_free_i64(fp0
);
9405 check_cp1_64bitmode(ctx
);
9407 TCGv_i64 fp0
= tcg_temp_new_i64();
9409 gen_load_fpr64(ctx
, fp0
, fs
);
9410 gen_helper_float_abs_ps(fp0
, fp0
);
9411 gen_store_fpr64(ctx
, fp0
, fd
);
9412 tcg_temp_free_i64(fp0
);
9417 check_cp1_64bitmode(ctx
);
9419 TCGv_i64 fp0
= tcg_temp_new_i64();
9421 gen_load_fpr64(ctx
, fp0
, fs
);
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();
9432 gen_load_fpr64(ctx
, fp0
, fs
);
9433 gen_helper_float_chs_ps(fp0
, fp0
);
9434 gen_store_fpr64(ctx
, fp0
, fd
);
9435 tcg_temp_free_i64(fp0
);
9440 check_cp1_64bitmode(ctx
);
9441 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
9445 check_cp1_64bitmode(ctx
);
9447 int l1
= gen_new_label();
9451 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
9452 fp0
= tcg_temp_new_i64();
9453 gen_load_fpr64(ctx
, fp0
, fs
);
9454 gen_store_fpr64(ctx
, fp0
, fd
);
9455 tcg_temp_free_i64(fp0
);
9461 check_cp1_64bitmode(ctx
);
9463 int l1
= gen_new_label();
9467 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
9468 fp0
= tcg_temp_new_i64();
9469 gen_load_fpr64(ctx
, fp0
, fs
);
9470 gen_store_fpr64(ctx
, fp0
, fd
);
9471 tcg_temp_free_i64(fp0
);
9478 check_cp1_64bitmode(ctx
);
9480 TCGv_i64 fp0
= tcg_temp_new_i64();
9481 TCGv_i64 fp1
= tcg_temp_new_i64();
9483 gen_load_fpr64(ctx
, fp0
, ft
);
9484 gen_load_fpr64(ctx
, fp1
, fs
);
9485 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
9486 tcg_temp_free_i64(fp1
);
9487 gen_store_fpr64(ctx
, fp0
, fd
);
9488 tcg_temp_free_i64(fp0
);
9493 check_cp1_64bitmode(ctx
);
9495 TCGv_i64 fp0
= tcg_temp_new_i64();
9496 TCGv_i64 fp1
= tcg_temp_new_i64();
9498 gen_load_fpr64(ctx
, fp0
, ft
);
9499 gen_load_fpr64(ctx
, fp1
, fs
);
9500 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
9501 tcg_temp_free_i64(fp1
);
9502 gen_store_fpr64(ctx
, fp0
, fd
);
9503 tcg_temp_free_i64(fp0
);
9508 check_cp1_64bitmode(ctx
);
9510 TCGv_i64 fp0
= tcg_temp_new_i64();
9511 TCGv_i64 fp1
= tcg_temp_new_i64();
9513 gen_load_fpr64(ctx
, fp0
, fs
);
9514 gen_load_fpr64(ctx
, fp1
, ft
);
9515 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
9516 tcg_temp_free_i64(fp1
);
9517 gen_store_fpr64(ctx
, fp0
, fd
);
9518 tcg_temp_free_i64(fp0
);
9523 check_cp1_64bitmode(ctx
);
9525 TCGv_i64 fp0
= tcg_temp_new_i64();
9527 gen_load_fpr64(ctx
, fp0
, fs
);
9528 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
9529 gen_store_fpr64(ctx
, fp0
, fd
);
9530 tcg_temp_free_i64(fp0
);
9535 check_cp1_64bitmode(ctx
);
9537 TCGv_i64 fp0
= tcg_temp_new_i64();
9539 gen_load_fpr64(ctx
, fp0
, fs
);
9540 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
9541 gen_store_fpr64(ctx
, fp0
, fd
);
9542 tcg_temp_free_i64(fp0
);
9547 check_cp1_64bitmode(ctx
);
9549 TCGv_i64 fp0
= tcg_temp_new_i64();
9550 TCGv_i64 fp1
= tcg_temp_new_i64();
9552 gen_load_fpr64(ctx
, fp0
, fs
);
9553 gen_load_fpr64(ctx
, fp1
, ft
);
9554 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
9555 tcg_temp_free_i64(fp1
);
9556 gen_store_fpr64(ctx
, fp0
, fd
);
9557 tcg_temp_free_i64(fp0
);
9562 check_cp1_64bitmode(ctx
);
9564 TCGv_i32 fp0
= tcg_temp_new_i32();
9566 gen_load_fpr32h(ctx
, fp0
, fs
);
9567 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
9568 gen_store_fpr32(fp0
, fd
);
9569 tcg_temp_free_i32(fp0
);
9574 check_cp1_64bitmode(ctx
);
9576 TCGv_i64 fp0
= tcg_temp_new_i64();
9578 gen_load_fpr64(ctx
, fp0
, fs
);
9579 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
9580 gen_store_fpr64(ctx
, fp0
, fd
);
9581 tcg_temp_free_i64(fp0
);
9586 check_cp1_64bitmode(ctx
);
9588 TCGv_i32 fp0
= tcg_temp_new_i32();
9590 gen_load_fpr32(fp0
, fs
);
9591 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
9592 gen_store_fpr32(fp0
, fd
);
9593 tcg_temp_free_i32(fp0
);
9598 check_cp1_64bitmode(ctx
);
9600 TCGv_i32 fp0
= tcg_temp_new_i32();
9601 TCGv_i32 fp1
= tcg_temp_new_i32();
9603 gen_load_fpr32(fp0
, fs
);
9604 gen_load_fpr32(fp1
, ft
);
9605 gen_store_fpr32h(ctx
, fp0
, fd
);
9606 gen_store_fpr32(fp1
, fd
);
9607 tcg_temp_free_i32(fp0
);
9608 tcg_temp_free_i32(fp1
);
9613 check_cp1_64bitmode(ctx
);
9615 TCGv_i32 fp0
= tcg_temp_new_i32();
9616 TCGv_i32 fp1
= tcg_temp_new_i32();
9618 gen_load_fpr32(fp0
, fs
);
9619 gen_load_fpr32h(ctx
, fp1
, ft
);
9620 gen_store_fpr32(fp1
, fd
);
9621 gen_store_fpr32h(ctx
, fp0
, fd
);
9622 tcg_temp_free_i32(fp0
);
9623 tcg_temp_free_i32(fp1
);
9628 check_cp1_64bitmode(ctx
);
9630 TCGv_i32 fp0
= tcg_temp_new_i32();
9631 TCGv_i32 fp1
= tcg_temp_new_i32();
9633 gen_load_fpr32h(ctx
, fp0
, fs
);
9634 gen_load_fpr32(fp1
, ft
);
9635 gen_store_fpr32(fp1
, fd
);
9636 gen_store_fpr32h(ctx
, fp0
, fd
);
9637 tcg_temp_free_i32(fp0
);
9638 tcg_temp_free_i32(fp1
);
9643 check_cp1_64bitmode(ctx
);
9645 TCGv_i32 fp0
= tcg_temp_new_i32();
9646 TCGv_i32 fp1
= tcg_temp_new_i32();
9648 gen_load_fpr32h(ctx
, fp0
, fs
);
9649 gen_load_fpr32h(ctx
, fp1
, ft
);
9650 gen_store_fpr32(fp1
, fd
);
9651 gen_store_fpr32h(ctx
, fp0
, fd
);
9652 tcg_temp_free_i32(fp0
);
9653 tcg_temp_free_i32(fp1
);
9660 case OPC_CMP_UEQ_PS
:
9661 case OPC_CMP_OLT_PS
:
9662 case OPC_CMP_ULT_PS
:
9663 case OPC_CMP_OLE_PS
:
9664 case OPC_CMP_ULE_PS
:
9666 case OPC_CMP_NGLE_PS
:
9667 case OPC_CMP_SEQ_PS
:
9668 case OPC_CMP_NGL_PS
:
9670 case OPC_CMP_NGE_PS
:
9672 case OPC_CMP_NGT_PS
:
9673 if (ctx
->opcode
& (1 << 6)) {
9674 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
9675 opn
= condnames_abs
[func
-48];
9677 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
9678 opn
= condnames
[func
-48];
9683 generate_exception (ctx
, EXCP_RI
);
9686 (void)opn
; /* avoid a compiler warning */
9689 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
9692 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
9695 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
9700 /* Coprocessor 3 (FPU) */
9701 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
9702 int fd
, int fs
, int base
, int index
)
9704 const char *opn
= "extended float load/store";
9706 TCGv t0
= tcg_temp_new();
9709 gen_load_gpr(t0
, index
);
9710 } else if (index
== 0) {
9711 gen_load_gpr(t0
, base
);
9713 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
9715 /* Don't do NOP if destination is zero: we must perform the actual
9721 TCGv_i32 fp0
= tcg_temp_new_i32();
9723 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
9724 tcg_gen_trunc_tl_i32(fp0
, t0
);
9725 gen_store_fpr32(fp0
, fd
);
9726 tcg_temp_free_i32(fp0
);
9732 check_cp1_registers(ctx
, fd
);
9734 TCGv_i64 fp0
= tcg_temp_new_i64();
9735 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9736 gen_store_fpr64(ctx
, fp0
, fd
);
9737 tcg_temp_free_i64(fp0
);
9742 check_cp1_64bitmode(ctx
);
9743 tcg_gen_andi_tl(t0
, t0
, ~0x7);
9745 TCGv_i64 fp0
= tcg_temp_new_i64();
9747 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9748 gen_store_fpr64(ctx
, fp0
, fd
);
9749 tcg_temp_free_i64(fp0
);
9756 TCGv_i32 fp0
= tcg_temp_new_i32();
9757 gen_load_fpr32(fp0
, fs
);
9758 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
9759 tcg_temp_free_i32(fp0
);
9766 check_cp1_registers(ctx
, fs
);
9768 TCGv_i64 fp0
= tcg_temp_new_i64();
9769 gen_load_fpr64(ctx
, fp0
, fs
);
9770 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9771 tcg_temp_free_i64(fp0
);
9777 check_cp1_64bitmode(ctx
);
9778 tcg_gen_andi_tl(t0
, t0
, ~0x7);
9780 TCGv_i64 fp0
= tcg_temp_new_i64();
9781 gen_load_fpr64(ctx
, fp0
, fs
);
9782 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
9783 tcg_temp_free_i64(fp0
);
9790 (void)opn
; (void)store
; /* avoid compiler warnings */
9791 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
9792 regnames
[index
], regnames
[base
]);
9795 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
9796 int fd
, int fr
, int fs
, int ft
)
9798 const char *opn
= "flt3_arith";
9802 check_cp1_64bitmode(ctx
);
9804 TCGv t0
= tcg_temp_local_new();
9805 TCGv_i32 fp
= tcg_temp_new_i32();
9806 TCGv_i32 fph
= tcg_temp_new_i32();
9807 int l1
= gen_new_label();
9808 int l2
= gen_new_label();
9810 gen_load_gpr(t0
, fr
);
9811 tcg_gen_andi_tl(t0
, t0
, 0x7);
9813 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
9814 gen_load_fpr32(fp
, fs
);
9815 gen_load_fpr32h(ctx
, fph
, fs
);
9816 gen_store_fpr32(fp
, fd
);
9817 gen_store_fpr32h(ctx
, fph
, fd
);
9820 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
9822 #ifdef TARGET_WORDS_BIGENDIAN
9823 gen_load_fpr32(fp
, fs
);
9824 gen_load_fpr32h(ctx
, fph
, ft
);
9825 gen_store_fpr32h(ctx
, fp
, fd
);
9826 gen_store_fpr32(fph
, fd
);
9828 gen_load_fpr32h(ctx
, fph
, fs
);
9829 gen_load_fpr32(fp
, ft
);
9830 gen_store_fpr32(fph
, fd
);
9831 gen_store_fpr32h(ctx
, fp
, fd
);
9834 tcg_temp_free_i32(fp
);
9835 tcg_temp_free_i32(fph
);
9842 TCGv_i32 fp0
= tcg_temp_new_i32();
9843 TCGv_i32 fp1
= tcg_temp_new_i32();
9844 TCGv_i32 fp2
= tcg_temp_new_i32();
9846 gen_load_fpr32(fp0
, fs
);
9847 gen_load_fpr32(fp1
, ft
);
9848 gen_load_fpr32(fp2
, fr
);
9849 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9850 tcg_temp_free_i32(fp0
);
9851 tcg_temp_free_i32(fp1
);
9852 gen_store_fpr32(fp2
, fd
);
9853 tcg_temp_free_i32(fp2
);
9859 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9861 TCGv_i64 fp0
= tcg_temp_new_i64();
9862 TCGv_i64 fp1
= tcg_temp_new_i64();
9863 TCGv_i64 fp2
= tcg_temp_new_i64();
9865 gen_load_fpr64(ctx
, fp0
, fs
);
9866 gen_load_fpr64(ctx
, fp1
, ft
);
9867 gen_load_fpr64(ctx
, fp2
, fr
);
9868 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9869 tcg_temp_free_i64(fp0
);
9870 tcg_temp_free_i64(fp1
);
9871 gen_store_fpr64(ctx
, fp2
, fd
);
9872 tcg_temp_free_i64(fp2
);
9877 check_cp1_64bitmode(ctx
);
9879 TCGv_i64 fp0
= tcg_temp_new_i64();
9880 TCGv_i64 fp1
= tcg_temp_new_i64();
9881 TCGv_i64 fp2
= tcg_temp_new_i64();
9883 gen_load_fpr64(ctx
, fp0
, fs
);
9884 gen_load_fpr64(ctx
, fp1
, ft
);
9885 gen_load_fpr64(ctx
, fp2
, fr
);
9886 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9887 tcg_temp_free_i64(fp0
);
9888 tcg_temp_free_i64(fp1
);
9889 gen_store_fpr64(ctx
, fp2
, fd
);
9890 tcg_temp_free_i64(fp2
);
9897 TCGv_i32 fp0
= tcg_temp_new_i32();
9898 TCGv_i32 fp1
= tcg_temp_new_i32();
9899 TCGv_i32 fp2
= tcg_temp_new_i32();
9901 gen_load_fpr32(fp0
, fs
);
9902 gen_load_fpr32(fp1
, ft
);
9903 gen_load_fpr32(fp2
, fr
);
9904 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9905 tcg_temp_free_i32(fp0
);
9906 tcg_temp_free_i32(fp1
);
9907 gen_store_fpr32(fp2
, fd
);
9908 tcg_temp_free_i32(fp2
);
9914 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9916 TCGv_i64 fp0
= tcg_temp_new_i64();
9917 TCGv_i64 fp1
= tcg_temp_new_i64();
9918 TCGv_i64 fp2
= tcg_temp_new_i64();
9920 gen_load_fpr64(ctx
, fp0
, fs
);
9921 gen_load_fpr64(ctx
, fp1
, ft
);
9922 gen_load_fpr64(ctx
, fp2
, fr
);
9923 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9924 tcg_temp_free_i64(fp0
);
9925 tcg_temp_free_i64(fp1
);
9926 gen_store_fpr64(ctx
, fp2
, fd
);
9927 tcg_temp_free_i64(fp2
);
9932 check_cp1_64bitmode(ctx
);
9934 TCGv_i64 fp0
= tcg_temp_new_i64();
9935 TCGv_i64 fp1
= tcg_temp_new_i64();
9936 TCGv_i64 fp2
= tcg_temp_new_i64();
9938 gen_load_fpr64(ctx
, fp0
, fs
);
9939 gen_load_fpr64(ctx
, fp1
, ft
);
9940 gen_load_fpr64(ctx
, fp2
, fr
);
9941 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9942 tcg_temp_free_i64(fp0
);
9943 tcg_temp_free_i64(fp1
);
9944 gen_store_fpr64(ctx
, fp2
, fd
);
9945 tcg_temp_free_i64(fp2
);
9952 TCGv_i32 fp0
= tcg_temp_new_i32();
9953 TCGv_i32 fp1
= tcg_temp_new_i32();
9954 TCGv_i32 fp2
= tcg_temp_new_i32();
9956 gen_load_fpr32(fp0
, fs
);
9957 gen_load_fpr32(fp1
, ft
);
9958 gen_load_fpr32(fp2
, fr
);
9959 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9960 tcg_temp_free_i32(fp0
);
9961 tcg_temp_free_i32(fp1
);
9962 gen_store_fpr32(fp2
, fd
);
9963 tcg_temp_free_i32(fp2
);
9969 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9971 TCGv_i64 fp0
= tcg_temp_new_i64();
9972 TCGv_i64 fp1
= tcg_temp_new_i64();
9973 TCGv_i64 fp2
= tcg_temp_new_i64();
9975 gen_load_fpr64(ctx
, fp0
, fs
);
9976 gen_load_fpr64(ctx
, fp1
, ft
);
9977 gen_load_fpr64(ctx
, fp2
, fr
);
9978 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9979 tcg_temp_free_i64(fp0
);
9980 tcg_temp_free_i64(fp1
);
9981 gen_store_fpr64(ctx
, fp2
, fd
);
9982 tcg_temp_free_i64(fp2
);
9987 check_cp1_64bitmode(ctx
);
9989 TCGv_i64 fp0
= tcg_temp_new_i64();
9990 TCGv_i64 fp1
= tcg_temp_new_i64();
9991 TCGv_i64 fp2
= tcg_temp_new_i64();
9993 gen_load_fpr64(ctx
, fp0
, fs
);
9994 gen_load_fpr64(ctx
, fp1
, ft
);
9995 gen_load_fpr64(ctx
, fp2
, fr
);
9996 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9997 tcg_temp_free_i64(fp0
);
9998 tcg_temp_free_i64(fp1
);
9999 gen_store_fpr64(ctx
, fp2
, fd
);
10000 tcg_temp_free_i64(fp2
);
10007 TCGv_i32 fp0
= tcg_temp_new_i32();
10008 TCGv_i32 fp1
= tcg_temp_new_i32();
10009 TCGv_i32 fp2
= tcg_temp_new_i32();
10011 gen_load_fpr32(fp0
, fs
);
10012 gen_load_fpr32(fp1
, ft
);
10013 gen_load_fpr32(fp2
, fr
);
10014 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10015 tcg_temp_free_i32(fp0
);
10016 tcg_temp_free_i32(fp1
);
10017 gen_store_fpr32(fp2
, fd
);
10018 tcg_temp_free_i32(fp2
);
10024 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
10026 TCGv_i64 fp0
= tcg_temp_new_i64();
10027 TCGv_i64 fp1
= tcg_temp_new_i64();
10028 TCGv_i64 fp2
= tcg_temp_new_i64();
10030 gen_load_fpr64(ctx
, fp0
, fs
);
10031 gen_load_fpr64(ctx
, fp1
, ft
);
10032 gen_load_fpr64(ctx
, fp2
, fr
);
10033 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10034 tcg_temp_free_i64(fp0
);
10035 tcg_temp_free_i64(fp1
);
10036 gen_store_fpr64(ctx
, fp2
, fd
);
10037 tcg_temp_free_i64(fp2
);
10042 check_cp1_64bitmode(ctx
);
10044 TCGv_i64 fp0
= tcg_temp_new_i64();
10045 TCGv_i64 fp1
= tcg_temp_new_i64();
10046 TCGv_i64 fp2
= tcg_temp_new_i64();
10048 gen_load_fpr64(ctx
, fp0
, fs
);
10049 gen_load_fpr64(ctx
, fp1
, ft
);
10050 gen_load_fpr64(ctx
, fp2
, fr
);
10051 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
10052 tcg_temp_free_i64(fp0
);
10053 tcg_temp_free_i64(fp1
);
10054 gen_store_fpr64(ctx
, fp2
, fd
);
10055 tcg_temp_free_i64(fp2
);
10061 generate_exception (ctx
, EXCP_RI
);
10064 (void)opn
; /* avoid a compiler warning */
10065 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
10066 fregnames
[fs
], fregnames
[ft
]);
10069 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
10073 #if !defined(CONFIG_USER_ONLY)
10074 /* The Linux kernel will emulate rdhwr if it's not supported natively.
10075 Therefore only check the ISA in system mode. */
10076 check_insn(ctx
, ISA_MIPS32R2
);
10078 t0
= tcg_temp_new();
10082 save_cpu_state(ctx
, 1);
10083 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
10084 gen_store_gpr(t0
, rt
);
10087 save_cpu_state(ctx
, 1);
10088 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
10089 gen_store_gpr(t0
, rt
);
10092 save_cpu_state(ctx
, 1);
10093 gen_helper_rdhwr_cc(t0
, cpu_env
);
10094 gen_store_gpr(t0
, rt
);
10097 save_cpu_state(ctx
, 1);
10098 gen_helper_rdhwr_ccres(t0
, cpu_env
);
10099 gen_store_gpr(t0
, rt
);
10102 #if defined(CONFIG_USER_ONLY)
10103 tcg_gen_ld_tl(t0
, cpu_env
,
10104 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10105 gen_store_gpr(t0
, rt
);
10108 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
10109 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
10110 tcg_gen_ld_tl(t0
, cpu_env
,
10111 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
10112 gen_store_gpr(t0
, rt
);
10114 generate_exception(ctx
, EXCP_RI
);
10118 default: /* Invalid */
10119 MIPS_INVAL("rdhwr");
10120 generate_exception(ctx
, EXCP_RI
);
10126 static void gen_branch(DisasContext
*ctx
, int insn_bytes
)
10128 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10129 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
10130 /* Branches completion */
10131 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
10132 ctx
->bstate
= BS_BRANCH
;
10133 save_cpu_state(ctx
, 0);
10134 /* FIXME: Need to clear can_do_io. */
10135 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
10137 /* unconditional branch */
10138 MIPS_DEBUG("unconditional branch");
10139 if (proc_hflags
& MIPS_HFLAG_BX
) {
10140 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
10142 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10144 case MIPS_HFLAG_BL
:
10145 /* blikely taken case */
10146 MIPS_DEBUG("blikely branch taken");
10147 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10149 case MIPS_HFLAG_BC
:
10150 /* Conditional branch */
10151 MIPS_DEBUG("conditional branch");
10153 int l1
= gen_new_label();
10155 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
10156 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
10158 gen_goto_tb(ctx
, 0, ctx
->btarget
);
10161 case MIPS_HFLAG_BR
:
10162 /* unconditional branch to register */
10163 MIPS_DEBUG("branch to register");
10164 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
10165 TCGv t0
= tcg_temp_new();
10166 TCGv_i32 t1
= tcg_temp_new_i32();
10168 tcg_gen_andi_tl(t0
, btarget
, 0x1);
10169 tcg_gen_trunc_tl_i32(t1
, t0
);
10171 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
10172 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
10173 tcg_gen_or_i32(hflags
, hflags
, t1
);
10174 tcg_temp_free_i32(t1
);
10176 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
10178 tcg_gen_mov_tl(cpu_PC
, btarget
);
10180 if (ctx
->singlestep_enabled
) {
10181 save_cpu_state(ctx
, 0);
10182 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
10184 tcg_gen_exit_tb(0);
10187 MIPS_DEBUG("unknown branch");
10193 /* ISA extensions (ASEs) */
10194 /* MIPS16 extension to MIPS32 */
10196 /* MIPS16 major opcodes */
10198 M16_OPC_ADDIUSP
= 0x00,
10199 M16_OPC_ADDIUPC
= 0x01,
10201 M16_OPC_JAL
= 0x03,
10202 M16_OPC_BEQZ
= 0x04,
10203 M16_OPC_BNEQZ
= 0x05,
10204 M16_OPC_SHIFT
= 0x06,
10206 M16_OPC_RRIA
= 0x08,
10207 M16_OPC_ADDIU8
= 0x09,
10208 M16_OPC_SLTI
= 0x0a,
10209 M16_OPC_SLTIU
= 0x0b,
10212 M16_OPC_CMPI
= 0x0e,
10216 M16_OPC_LWSP
= 0x12,
10218 M16_OPC_LBU
= 0x14,
10219 M16_OPC_LHU
= 0x15,
10220 M16_OPC_LWPC
= 0x16,
10221 M16_OPC_LWU
= 0x17,
10224 M16_OPC_SWSP
= 0x1a,
10226 M16_OPC_RRR
= 0x1c,
10228 M16_OPC_EXTEND
= 0x1e,
10232 /* I8 funct field */
10251 /* RR funct field */
10285 /* I64 funct field */
10293 I64_DADDIUPC
= 0x6,
10297 /* RR ry field for CNVT */
10299 RR_RY_CNVT_ZEB
= 0x0,
10300 RR_RY_CNVT_ZEH
= 0x1,
10301 RR_RY_CNVT_ZEW
= 0x2,
10302 RR_RY_CNVT_SEB
= 0x4,
10303 RR_RY_CNVT_SEH
= 0x5,
10304 RR_RY_CNVT_SEW
= 0x6,
10307 static int xlat (int r
)
10309 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10314 static void gen_mips16_save (DisasContext
*ctx
,
10315 int xsregs
, int aregs
,
10316 int do_ra
, int do_s0
, int do_s1
,
10319 TCGv t0
= tcg_temp_new();
10320 TCGv t1
= tcg_temp_new();
10350 generate_exception(ctx
, EXCP_RI
);
10356 gen_base_offset_addr(ctx
, t0
, 29, 12);
10357 gen_load_gpr(t1
, 7);
10358 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10361 gen_base_offset_addr(ctx
, t0
, 29, 8);
10362 gen_load_gpr(t1
, 6);
10363 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10366 gen_base_offset_addr(ctx
, t0
, 29, 4);
10367 gen_load_gpr(t1
, 5);
10368 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10371 gen_base_offset_addr(ctx
, t0
, 29, 0);
10372 gen_load_gpr(t1
, 4);
10373 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10376 gen_load_gpr(t0
, 29);
10378 #define DECR_AND_STORE(reg) do { \
10379 tcg_gen_subi_tl(t0, t0, 4); \
10380 gen_load_gpr(t1, reg); \
10381 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
10385 DECR_AND_STORE(31);
10390 DECR_AND_STORE(30);
10393 DECR_AND_STORE(23);
10396 DECR_AND_STORE(22);
10399 DECR_AND_STORE(21);
10402 DECR_AND_STORE(20);
10405 DECR_AND_STORE(19);
10408 DECR_AND_STORE(18);
10412 DECR_AND_STORE(17);
10415 DECR_AND_STORE(16);
10445 generate_exception(ctx
, EXCP_RI
);
10461 #undef DECR_AND_STORE
10463 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
10468 static void gen_mips16_restore (DisasContext
*ctx
,
10469 int xsregs
, int aregs
,
10470 int do_ra
, int do_s0
, int do_s1
,
10474 TCGv t0
= tcg_temp_new();
10475 TCGv t1
= tcg_temp_new();
10477 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
10479 #define DECR_AND_LOAD(reg) do { \
10480 tcg_gen_subi_tl(t0, t0, 4); \
10481 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
10482 gen_store_gpr(t1, reg); \
10546 generate_exception(ctx
, EXCP_RI
);
10562 #undef DECR_AND_LOAD
10564 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
10569 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
10570 int is_64_bit
, int extended
)
10574 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10575 generate_exception(ctx
, EXCP_RI
);
10579 t0
= tcg_temp_new();
10581 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
10582 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
10584 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10590 #if defined(TARGET_MIPS64)
10591 static void decode_i64_mips16 (DisasContext
*ctx
,
10592 int ry
, int funct
, int16_t offset
,
10597 check_mips_64(ctx
);
10598 offset
= extended
? offset
: offset
<< 3;
10599 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
10602 check_mips_64(ctx
);
10603 offset
= extended
? offset
: offset
<< 3;
10604 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
10607 check_mips_64(ctx
);
10608 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
10609 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
10612 check_mips_64(ctx
);
10613 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
10614 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
10617 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
10618 generate_exception(ctx
, EXCP_RI
);
10620 offset
= extended
? offset
: offset
<< 3;
10621 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
10625 check_mips_64(ctx
);
10626 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
10627 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
10630 check_mips_64(ctx
);
10631 offset
= extended
? offset
: offset
<< 2;
10632 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
10635 check_mips_64(ctx
);
10636 offset
= extended
? offset
: offset
<< 2;
10637 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
10643 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
10645 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
10646 int op
, rx
, ry
, funct
, sa
;
10647 int16_t imm
, offset
;
10649 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
10650 op
= (ctx
->opcode
>> 11) & 0x1f;
10651 sa
= (ctx
->opcode
>> 22) & 0x1f;
10652 funct
= (ctx
->opcode
>> 8) & 0x7;
10653 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
10654 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
10655 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
10656 | ((ctx
->opcode
>> 21) & 0x3f) << 5
10657 | (ctx
->opcode
& 0x1f));
10659 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
10662 case M16_OPC_ADDIUSP
:
10663 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
10665 case M16_OPC_ADDIUPC
:
10666 gen_addiupc(ctx
, rx
, imm
, 0, 1);
10669 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
10670 /* No delay slot, so just process as a normal instruction */
10673 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
10674 /* No delay slot, so just process as a normal instruction */
10676 case M16_OPC_BNEQZ
:
10677 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
10678 /* No delay slot, so just process as a normal instruction */
10680 case M16_OPC_SHIFT
:
10681 switch (ctx
->opcode
& 0x3) {
10683 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
10686 #if defined(TARGET_MIPS64)
10687 check_mips_64(ctx
);
10688 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
10690 generate_exception(ctx
, EXCP_RI
);
10694 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
10697 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
10701 #if defined(TARGET_MIPS64)
10703 check_mips_64(ctx
);
10704 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
10708 imm
= ctx
->opcode
& 0xf;
10709 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
10710 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
10711 imm
= (int16_t) (imm
<< 1) >> 1;
10712 if ((ctx
->opcode
>> 4) & 0x1) {
10713 #if defined(TARGET_MIPS64)
10714 check_mips_64(ctx
);
10715 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
10717 generate_exception(ctx
, EXCP_RI
);
10720 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
10723 case M16_OPC_ADDIU8
:
10724 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
10727 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
10729 case M16_OPC_SLTIU
:
10730 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
10735 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
10738 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
10741 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
10744 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
10748 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
10749 int aregs
= (ctx
->opcode
>> 16) & 0xf;
10750 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
10751 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
10752 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
10753 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
10754 | (ctx
->opcode
& 0xf)) << 3;
10756 if (ctx
->opcode
& (1 << 7)) {
10757 gen_mips16_save(ctx
, xsregs
, aregs
,
10758 do_ra
, do_s0
, do_s1
,
10761 gen_mips16_restore(ctx
, xsregs
, aregs
,
10762 do_ra
, do_s0
, do_s1
,
10768 generate_exception(ctx
, EXCP_RI
);
10773 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
10776 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
10778 #if defined(TARGET_MIPS64)
10780 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
10784 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
10787 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
10790 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
10793 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
10796 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
10799 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
10802 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
10804 #if defined(TARGET_MIPS64)
10806 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
10810 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10813 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
10816 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
10819 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
10821 #if defined(TARGET_MIPS64)
10823 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
10827 generate_exception(ctx
, EXCP_RI
);
10834 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
10838 int op
, cnvt_op
, op1
, offset
;
10842 op
= (ctx
->opcode
>> 11) & 0x1f;
10843 sa
= (ctx
->opcode
>> 2) & 0x7;
10844 sa
= sa
== 0 ? 8 : sa
;
10845 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
10846 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
10847 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
10848 op1
= offset
= ctx
->opcode
& 0x1f;
10853 case M16_OPC_ADDIUSP
:
10855 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
10857 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
10860 case M16_OPC_ADDIUPC
:
10861 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
10864 offset
= (ctx
->opcode
& 0x7ff) << 1;
10865 offset
= (int16_t)(offset
<< 4) >> 4;
10866 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
10867 /* No delay slot, so just process as a normal instruction */
10870 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
10871 offset
= (((ctx
->opcode
& 0x1f) << 21)
10872 | ((ctx
->opcode
>> 5) & 0x1f) << 16
10874 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
10875 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
10879 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
10880 /* No delay slot, so just process as a normal instruction */
10882 case M16_OPC_BNEQZ
:
10883 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
10884 /* No delay slot, so just process as a normal instruction */
10886 case M16_OPC_SHIFT
:
10887 switch (ctx
->opcode
& 0x3) {
10889 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
10892 #if defined(TARGET_MIPS64)
10893 check_mips_64(ctx
);
10894 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
10896 generate_exception(ctx
, EXCP_RI
);
10900 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
10903 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
10907 #if defined(TARGET_MIPS64)
10909 check_mips_64(ctx
);
10910 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
10915 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
10917 if ((ctx
->opcode
>> 4) & 1) {
10918 #if defined(TARGET_MIPS64)
10919 check_mips_64(ctx
);
10920 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
10922 generate_exception(ctx
, EXCP_RI
);
10925 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
10929 case M16_OPC_ADDIU8
:
10931 int16_t imm
= (int8_t) ctx
->opcode
;
10933 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
10938 int16_t imm
= (uint8_t) ctx
->opcode
;
10939 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
10942 case M16_OPC_SLTIU
:
10944 int16_t imm
= (uint8_t) ctx
->opcode
;
10945 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
10952 funct
= (ctx
->opcode
>> 8) & 0x7;
10955 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
10956 ((int8_t)ctx
->opcode
) << 1);
10959 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
10960 ((int8_t)ctx
->opcode
) << 1);
10963 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
10966 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
10967 ((int8_t)ctx
->opcode
) << 3);
10971 int do_ra
= ctx
->opcode
& (1 << 6);
10972 int do_s0
= ctx
->opcode
& (1 << 5);
10973 int do_s1
= ctx
->opcode
& (1 << 4);
10974 int framesize
= ctx
->opcode
& 0xf;
10976 if (framesize
== 0) {
10979 framesize
= framesize
<< 3;
10982 if (ctx
->opcode
& (1 << 7)) {
10983 gen_mips16_save(ctx
, 0, 0,
10984 do_ra
, do_s0
, do_s1
, framesize
);
10986 gen_mips16_restore(ctx
, 0, 0,
10987 do_ra
, do_s0
, do_s1
, framesize
);
10993 int rz
= xlat(ctx
->opcode
& 0x7);
10995 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
10996 ((ctx
->opcode
>> 5) & 0x7);
10997 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
11001 reg32
= ctx
->opcode
& 0x1f;
11002 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
11005 generate_exception(ctx
, EXCP_RI
);
11012 int16_t imm
= (uint8_t) ctx
->opcode
;
11014 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
11019 int16_t imm
= (uint8_t) ctx
->opcode
;
11020 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
11023 #if defined(TARGET_MIPS64)
11025 check_mips_64(ctx
);
11026 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
11030 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
11033 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
11036 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11039 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
11042 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
11045 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
11048 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
11050 #if defined (TARGET_MIPS64)
11052 check_mips_64(ctx
);
11053 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
11057 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
11060 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
11063 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
11066 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
11070 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
11073 switch (ctx
->opcode
& 0x3) {
11075 mips32_op
= OPC_ADDU
;
11078 mips32_op
= OPC_SUBU
;
11080 #if defined(TARGET_MIPS64)
11082 mips32_op
= OPC_DADDU
;
11083 check_mips_64(ctx
);
11086 mips32_op
= OPC_DSUBU
;
11087 check_mips_64(ctx
);
11091 generate_exception(ctx
, EXCP_RI
);
11095 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
11104 int nd
= (ctx
->opcode
>> 7) & 0x1;
11105 int link
= (ctx
->opcode
>> 6) & 0x1;
11106 int ra
= (ctx
->opcode
>> 5) & 0x1;
11109 op
= nd
? OPC_JALRC
: OPC_JALRS
;
11114 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
11118 /* XXX: not clear which exception should be raised
11119 * when in debug mode...
11121 check_insn(ctx
, ISA_MIPS32
);
11122 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11123 generate_exception(ctx
, EXCP_DBp
);
11125 generate_exception(ctx
, EXCP_DBp
);
11129 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
11132 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
11135 generate_exception(ctx
, EXCP_BREAK
);
11138 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
11141 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
11144 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
11146 #if defined (TARGET_MIPS64)
11148 check_mips_64(ctx
);
11149 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
11153 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
11156 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
11159 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
11162 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
11165 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
11168 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
11171 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
11175 case RR_RY_CNVT_ZEB
:
11176 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11178 case RR_RY_CNVT_ZEH
:
11179 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11181 case RR_RY_CNVT_SEB
:
11182 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11184 case RR_RY_CNVT_SEH
:
11185 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11187 #if defined (TARGET_MIPS64)
11188 case RR_RY_CNVT_ZEW
:
11189 check_mips_64(ctx
);
11190 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11192 case RR_RY_CNVT_SEW
:
11193 check_mips_64(ctx
);
11194 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
11198 generate_exception(ctx
, EXCP_RI
);
11203 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
11205 #if defined (TARGET_MIPS64)
11207 check_mips_64(ctx
);
11208 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
11211 check_mips_64(ctx
);
11212 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
11215 check_mips_64(ctx
);
11216 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
11219 check_mips_64(ctx
);
11220 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
11224 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
11227 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
11230 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
11233 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
11235 #if defined (TARGET_MIPS64)
11237 check_mips_64(ctx
);
11238 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
11241 check_mips_64(ctx
);
11242 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
11245 check_mips_64(ctx
);
11246 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
11249 check_mips_64(ctx
);
11250 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
11254 generate_exception(ctx
, EXCP_RI
);
11258 case M16_OPC_EXTEND
:
11259 decode_extended_mips16_opc(env
, ctx
);
11262 #if defined(TARGET_MIPS64)
11264 funct
= (ctx
->opcode
>> 8) & 0x7;
11265 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
11269 generate_exception(ctx
, EXCP_RI
);
11276 /* microMIPS extension to MIPS32/MIPS64 */
11279 * microMIPS32/microMIPS64 major opcodes
11281 * 1. MIPS Architecture for Programmers Volume II-B:
11282 * The microMIPS32 Instruction Set (Revision 3.05)
11284 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
11286 * 2. MIPS Architecture For Programmers Volume II-A:
11287 * The MIPS64 Instruction Set (Revision 3.51)
11315 POOL32S
= 0x16, /* MIPS64 */
11316 DADDIU32
= 0x17, /* MIPS64 */
11318 /* 0x1f is reserved */
11327 /* 0x20 is reserved */
11337 /* 0x28 and 0x29 are reserved */
11347 /* 0x30 and 0x31 are reserved */
11354 SD32
= 0x36, /* MIPS64 */
11355 LD32
= 0x37, /* MIPS64 */
11357 /* 0x38 and 0x39 are reserved */
11368 /* POOL32A encoding of minor opcode field */
11371 /* These opcodes are distinguished only by bits 9..6; those bits are
11372 * what are recorded below. */
11398 /* The following can be distinguished by their lower 6 bits. */
11404 /* POOL32AXF encoding of minor opcode field extension */
11407 * 1. MIPS Architecture for Programmers Volume II-B:
11408 * The microMIPS32 Instruction Set (Revision 3.05)
11410 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
11412 * 2. MIPS Architecture for Programmers VolumeIV-e:
11413 * The MIPS DSP Application-Specific Extension
11414 * to the microMIPS32 Architecture (Revision 2.34)
11416 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
11431 /* begin of microMIPS32 DSP */
11433 /* bits 13..12 for 0x01 */
11439 /* bits 13..12 for 0x2a */
11445 /* bits 13..12 for 0x32 */
11449 /* end of microMIPS32 DSP */
11451 /* bits 15..12 for 0x2c */
11467 /* bits 15..12 for 0x34 */
11475 /* bits 15..12 for 0x3c */
11477 JR
= 0x0, /* alias */
11482 /* bits 15..12 for 0x05 */
11486 /* bits 15..12 for 0x0d */
11496 /* bits 15..12 for 0x15 */
11502 /* bits 15..12 for 0x1d */
11506 /* bits 15..12 for 0x2d */
11511 /* bits 15..12 for 0x35 */
11518 /* POOL32B encoding of minor opcode field (bits 15..12) */
11534 /* POOL32C encoding of minor opcode field (bits 15..12) */
11542 /* 0xa is reserved */
11549 /* 0x6 is reserved */
11555 /* POOL32F encoding of minor opcode field (bits 5..0) */
11558 /* These are the bit 7..6 values */
11569 /* These are the bit 8..6 values */
11613 CABS_COND_FMT
= 0x1c, /* MIPS3D */
11617 /* POOL32Fxf encoding of minor opcode extension field */
11655 /* POOL32I encoding of minor opcode field (bits 25..21) */
11680 /* These overlap and are distinguished by bit16 of the instruction */
11689 /* POOL16A encoding of minor opcode field */
11696 /* POOL16B encoding of minor opcode field */
11703 /* POOL16C encoding of minor opcode field */
11723 /* POOL16D encoding of minor opcode field */
11730 /* POOL16E encoding of minor opcode field */
11737 static int mmreg (int r
)
11739 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
11744 /* Used for 16-bit store instructions. */
11745 static int mmreg2 (int r
)
11747 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
11752 #define uMIPS_RD(op) ((op >> 7) & 0x7)
11753 #define uMIPS_RS(op) ((op >> 4) & 0x7)
11754 #define uMIPS_RS2(op) uMIPS_RS(op)
11755 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
11756 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
11757 #define uMIPS_RS5(op) (op & 0x1f)
11759 /* Signed immediate */
11760 #define SIMM(op, start, width) \
11761 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
11764 /* Zero-extended immediate */
11765 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
11767 static void gen_addiur1sp(DisasContext
*ctx
)
11769 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
11771 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
11774 static void gen_addiur2(DisasContext
*ctx
)
11776 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
11777 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
11778 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
11780 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
11783 static void gen_addiusp(DisasContext
*ctx
)
11785 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
11788 if (encoded
<= 1) {
11789 decoded
= 256 + encoded
;
11790 } else if (encoded
<= 255) {
11792 } else if (encoded
<= 509) {
11793 decoded
= encoded
- 512;
11795 decoded
= encoded
- 768;
11798 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
11801 static void gen_addius5(DisasContext
*ctx
)
11803 int imm
= SIMM(ctx
->opcode
, 1, 4);
11804 int rd
= (ctx
->opcode
>> 5) & 0x1f;
11806 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
11809 static void gen_andi16(DisasContext
*ctx
)
11811 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
11812 31, 32, 63, 64, 255, 32768, 65535 };
11813 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
11814 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
11815 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
11817 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
11820 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
11821 int base
, int16_t offset
)
11823 const char *opn
= "ldst_multiple";
11827 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
11828 generate_exception(ctx
, EXCP_RI
);
11832 t0
= tcg_temp_new();
11834 gen_base_offset_addr(ctx
, t0
, base
, offset
);
11836 t1
= tcg_const_tl(reglist
);
11837 t2
= tcg_const_i32(ctx
->mem_idx
);
11839 save_cpu_state(ctx
, 1);
11842 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
11846 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
11849 #ifdef TARGET_MIPS64
11851 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
11855 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
11861 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
11864 tcg_temp_free_i32(t2
);
11868 static void gen_pool16c_insn(DisasContext
*ctx
)
11870 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
11871 int rs
= mmreg(ctx
->opcode
& 0x7);
11874 switch (((ctx
->opcode
) >> 4) & 0x3f) {
11879 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
11885 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
11891 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
11897 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
11904 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
11905 int offset
= ZIMM(ctx
->opcode
, 0, 4);
11907 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
11916 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
11917 int offset
= ZIMM(ctx
->opcode
, 0, 4);
11919 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
11926 int reg
= ctx
->opcode
& 0x1f;
11928 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
11934 int reg
= ctx
->opcode
& 0x1f;
11936 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
11937 /* Let normal delay slot handling in our caller take us
11938 to the branch target. */
11950 int reg
= ctx
->opcode
& 0x1f;
11952 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
11957 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
11961 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
11964 generate_exception(ctx
, EXCP_BREAK
);
11967 /* XXX: not clear which exception should be raised
11968 * when in debug mode...
11970 check_insn(ctx
, ISA_MIPS32
);
11971 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11972 generate_exception(ctx
, EXCP_DBp
);
11974 generate_exception(ctx
, EXCP_DBp
);
11977 case JRADDIUSP
+ 0:
11978 case JRADDIUSP
+ 1:
11980 int imm
= ZIMM(ctx
->opcode
, 0, 5);
11982 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
11983 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
11984 /* Let normal delay slot handling in our caller take us
11985 to the branch target. */
11989 generate_exception(ctx
, EXCP_RI
);
11994 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
11996 TCGv t0
= tcg_temp_new();
11997 TCGv t1
= tcg_temp_new();
11999 gen_load_gpr(t0
, base
);
12002 gen_load_gpr(t1
, index
);
12003 tcg_gen_shli_tl(t1
, t1
, 2);
12004 gen_op_addr_add(ctx
, t0
, t1
, t0
);
12007 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12008 gen_store_gpr(t1
, rd
);
12014 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
12015 int base
, int16_t offset
)
12017 const char *opn
= "ldst_pair";
12020 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
12021 generate_exception(ctx
, EXCP_RI
);
12025 t0
= tcg_temp_new();
12026 t1
= tcg_temp_new();
12028 gen_base_offset_addr(ctx
, t0
, base
, offset
);
12033 generate_exception(ctx
, EXCP_RI
);
12036 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12037 gen_store_gpr(t1
, rd
);
12038 tcg_gen_movi_tl(t1
, 4);
12039 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12040 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
12041 gen_store_gpr(t1
, rd
+1);
12045 gen_load_gpr(t1
, rd
);
12046 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12047 tcg_gen_movi_tl(t1
, 4);
12048 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12049 gen_load_gpr(t1
, rd
+1);
12050 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
12053 #ifdef TARGET_MIPS64
12056 generate_exception(ctx
, EXCP_RI
);
12059 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12060 gen_store_gpr(t1
, rd
);
12061 tcg_gen_movi_tl(t1
, 8);
12062 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12063 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12064 gen_store_gpr(t1
, rd
+1);
12068 gen_load_gpr(t1
, rd
);
12069 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12070 tcg_gen_movi_tl(t1
, 8);
12071 gen_op_addr_add(ctx
, t0
, t0
, t1
);
12072 gen_load_gpr(t1
, rd
+1);
12073 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
12078 (void)opn
; /* avoid a compiler warning */
12079 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
12084 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
12086 int extension
= (ctx
->opcode
>> 6) & 0x3f;
12087 int minor
= (ctx
->opcode
>> 12) & 0xf;
12088 uint32_t mips32_op
;
12090 switch (extension
) {
12092 mips32_op
= OPC_TEQ
;
12095 mips32_op
= OPC_TGE
;
12098 mips32_op
= OPC_TGEU
;
12101 mips32_op
= OPC_TLT
;
12104 mips32_op
= OPC_TLTU
;
12107 mips32_op
= OPC_TNE
;
12109 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
12111 #ifndef CONFIG_USER_ONLY
12114 check_cp0_enabled(ctx
);
12116 /* Treat as NOP. */
12119 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
12123 check_cp0_enabled(ctx
);
12125 TCGv t0
= tcg_temp_new();
12127 gen_load_gpr(t0
, rt
);
12128 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
12134 switch (minor
& 3) {
12136 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12139 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12142 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12145 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12148 goto pool32axf_invalid
;
12152 switch (minor
& 3) {
12154 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12157 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
12160 goto pool32axf_invalid
;
12166 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
12169 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
12172 mips32_op
= OPC_CLO
;
12175 mips32_op
= OPC_CLZ
;
12177 check_insn(ctx
, ISA_MIPS32
);
12178 gen_cl(ctx
, mips32_op
, rt
, rs
);
12181 gen_rdhwr(ctx
, rt
, rs
);
12184 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
12187 mips32_op
= OPC_MULT
;
12190 mips32_op
= OPC_MULTU
;
12193 mips32_op
= OPC_DIV
;
12196 mips32_op
= OPC_DIVU
;
12199 check_insn(ctx
, ISA_MIPS32
);
12200 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
12203 mips32_op
= OPC_MADD
;
12206 mips32_op
= OPC_MADDU
;
12209 mips32_op
= OPC_MSUB
;
12212 mips32_op
= OPC_MSUBU
;
12214 check_insn(ctx
, ISA_MIPS32
);
12215 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
12218 goto pool32axf_invalid
;
12229 generate_exception_err(ctx
, EXCP_CpU
, 2);
12232 goto pool32axf_invalid
;
12239 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
12243 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
12246 goto pool32axf_invalid
;
12252 check_cp0_enabled(ctx
);
12253 check_insn(ctx
, ISA_MIPS32R2
);
12254 gen_load_srsgpr(rt
, rs
);
12257 check_cp0_enabled(ctx
);
12258 check_insn(ctx
, ISA_MIPS32R2
);
12259 gen_store_srsgpr(rt
, rs
);
12262 goto pool32axf_invalid
;
12265 #ifndef CONFIG_USER_ONLY
12269 mips32_op
= OPC_TLBP
;
12272 mips32_op
= OPC_TLBR
;
12275 mips32_op
= OPC_TLBWI
;
12278 mips32_op
= OPC_TLBWR
;
12281 mips32_op
= OPC_WAIT
;
12284 mips32_op
= OPC_DERET
;
12287 mips32_op
= OPC_ERET
;
12289 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
12292 goto pool32axf_invalid
;
12298 check_cp0_enabled(ctx
);
12300 TCGv t0
= tcg_temp_new();
12302 save_cpu_state(ctx
, 1);
12303 gen_helper_di(t0
, cpu_env
);
12304 gen_store_gpr(t0
, rs
);
12305 /* Stop translation as we may have switched the execution mode */
12306 ctx
->bstate
= BS_STOP
;
12311 check_cp0_enabled(ctx
);
12313 TCGv t0
= tcg_temp_new();
12315 save_cpu_state(ctx
, 1);
12316 gen_helper_ei(t0
, cpu_env
);
12317 gen_store_gpr(t0
, rs
);
12318 /* Stop translation as we may have switched the execution mode */
12319 ctx
->bstate
= BS_STOP
;
12324 goto pool32axf_invalid
;
12334 generate_exception(ctx
, EXCP_SYSCALL
);
12335 ctx
->bstate
= BS_STOP
;
12338 check_insn(ctx
, ISA_MIPS32
);
12339 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
12340 generate_exception(ctx
, EXCP_DBp
);
12342 generate_exception(ctx
, EXCP_DBp
);
12346 goto pool32axf_invalid
;
12350 switch (minor
& 3) {
12352 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
12355 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
12358 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
12361 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
12364 goto pool32axf_invalid
;
12370 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
12373 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
12376 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
12379 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
12382 goto pool32axf_invalid
;
12387 MIPS_INVAL("pool32axf");
12388 generate_exception(ctx
, EXCP_RI
);
12393 /* Values for microMIPS fmt field. Variable-width, depending on which
12394 formats the instruction supports. */
12413 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
12415 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
12416 uint32_t mips32_op
;
12418 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
12419 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
12420 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
12422 switch (extension
) {
12423 case FLOAT_1BIT_FMT(CFC1
, 0):
12424 mips32_op
= OPC_CFC1
;
12426 case FLOAT_1BIT_FMT(CTC1
, 0):
12427 mips32_op
= OPC_CTC1
;
12429 case FLOAT_1BIT_FMT(MFC1
, 0):
12430 mips32_op
= OPC_MFC1
;
12432 case FLOAT_1BIT_FMT(MTC1
, 0):
12433 mips32_op
= OPC_MTC1
;
12435 case FLOAT_1BIT_FMT(MFHC1
, 0):
12436 mips32_op
= OPC_MFHC1
;
12438 case FLOAT_1BIT_FMT(MTHC1
, 0):
12439 mips32_op
= OPC_MTHC1
;
12441 gen_cp1(ctx
, mips32_op
, rt
, rs
);
12444 /* Reciprocal square root */
12445 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
12446 mips32_op
= OPC_RSQRT_S
;
12448 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
12449 mips32_op
= OPC_RSQRT_D
;
12453 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
12454 mips32_op
= OPC_SQRT_S
;
12456 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
12457 mips32_op
= OPC_SQRT_D
;
12461 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
12462 mips32_op
= OPC_RECIP_S
;
12464 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
12465 mips32_op
= OPC_RECIP_D
;
12469 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
12470 mips32_op
= OPC_FLOOR_L_S
;
12472 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
12473 mips32_op
= OPC_FLOOR_L_D
;
12475 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
12476 mips32_op
= OPC_FLOOR_W_S
;
12478 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
12479 mips32_op
= OPC_FLOOR_W_D
;
12483 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
12484 mips32_op
= OPC_CEIL_L_S
;
12486 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
12487 mips32_op
= OPC_CEIL_L_D
;
12489 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
12490 mips32_op
= OPC_CEIL_W_S
;
12492 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
12493 mips32_op
= OPC_CEIL_W_D
;
12497 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
12498 mips32_op
= OPC_TRUNC_L_S
;
12500 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
12501 mips32_op
= OPC_TRUNC_L_D
;
12503 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
12504 mips32_op
= OPC_TRUNC_W_S
;
12506 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
12507 mips32_op
= OPC_TRUNC_W_D
;
12511 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
12512 mips32_op
= OPC_ROUND_L_S
;
12514 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
12515 mips32_op
= OPC_ROUND_L_D
;
12517 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
12518 mips32_op
= OPC_ROUND_W_S
;
12520 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
12521 mips32_op
= OPC_ROUND_W_D
;
12524 /* Integer to floating-point conversion */
12525 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
12526 mips32_op
= OPC_CVT_L_S
;
12528 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
12529 mips32_op
= OPC_CVT_L_D
;
12531 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
12532 mips32_op
= OPC_CVT_W_S
;
12534 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
12535 mips32_op
= OPC_CVT_W_D
;
12538 /* Paired-foo conversions */
12539 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
12540 mips32_op
= OPC_CVT_S_PL
;
12542 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
12543 mips32_op
= OPC_CVT_S_PU
;
12545 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
12546 mips32_op
= OPC_CVT_PW_PS
;
12548 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
12549 mips32_op
= OPC_CVT_PS_PW
;
12552 /* Floating-point moves */
12553 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
12554 mips32_op
= OPC_MOV_S
;
12556 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
12557 mips32_op
= OPC_MOV_D
;
12559 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
12560 mips32_op
= OPC_MOV_PS
;
12563 /* Absolute value */
12564 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
12565 mips32_op
= OPC_ABS_S
;
12567 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
12568 mips32_op
= OPC_ABS_D
;
12570 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
12571 mips32_op
= OPC_ABS_PS
;
12575 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
12576 mips32_op
= OPC_NEG_S
;
12578 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
12579 mips32_op
= OPC_NEG_D
;
12581 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
12582 mips32_op
= OPC_NEG_PS
;
12585 /* Reciprocal square root step */
12586 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
12587 mips32_op
= OPC_RSQRT1_S
;
12589 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
12590 mips32_op
= OPC_RSQRT1_D
;
12592 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
12593 mips32_op
= OPC_RSQRT1_PS
;
12596 /* Reciprocal step */
12597 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
12598 mips32_op
= OPC_RECIP1_S
;
12600 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
12601 mips32_op
= OPC_RECIP1_S
;
12603 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
12604 mips32_op
= OPC_RECIP1_PS
;
12607 /* Conversions from double */
12608 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
12609 mips32_op
= OPC_CVT_D_S
;
12611 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
12612 mips32_op
= OPC_CVT_D_W
;
12614 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
12615 mips32_op
= OPC_CVT_D_L
;
12618 /* Conversions from single */
12619 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
12620 mips32_op
= OPC_CVT_S_D
;
12622 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
12623 mips32_op
= OPC_CVT_S_W
;
12625 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
12626 mips32_op
= OPC_CVT_S_L
;
12628 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
12631 /* Conditional moves on floating-point codes */
12632 case COND_FLOAT_MOV(MOVT
, 0):
12633 case COND_FLOAT_MOV(MOVT
, 1):
12634 case COND_FLOAT_MOV(MOVT
, 2):
12635 case COND_FLOAT_MOV(MOVT
, 3):
12636 case COND_FLOAT_MOV(MOVT
, 4):
12637 case COND_FLOAT_MOV(MOVT
, 5):
12638 case COND_FLOAT_MOV(MOVT
, 6):
12639 case COND_FLOAT_MOV(MOVT
, 7):
12640 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
12642 case COND_FLOAT_MOV(MOVF
, 0):
12643 case COND_FLOAT_MOV(MOVF
, 1):
12644 case COND_FLOAT_MOV(MOVF
, 2):
12645 case COND_FLOAT_MOV(MOVF
, 3):
12646 case COND_FLOAT_MOV(MOVF
, 4):
12647 case COND_FLOAT_MOV(MOVF
, 5):
12648 case COND_FLOAT_MOV(MOVF
, 6):
12649 case COND_FLOAT_MOV(MOVF
, 7):
12650 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
12653 MIPS_INVAL("pool32fxf");
12654 generate_exception(ctx
, EXCP_RI
);
12659 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
12664 int rt
, rs
, rd
, rr
;
12666 uint32_t op
, minor
, mips32_op
;
12667 uint32_t cond
, fmt
, cc
;
12669 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
12670 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
12672 rt
= (ctx
->opcode
>> 21) & 0x1f;
12673 rs
= (ctx
->opcode
>> 16) & 0x1f;
12674 rd
= (ctx
->opcode
>> 11) & 0x1f;
12675 rr
= (ctx
->opcode
>> 6) & 0x1f;
12676 imm
= (int16_t) ctx
->opcode
;
12678 op
= (ctx
->opcode
>> 26) & 0x3f;
12681 minor
= ctx
->opcode
& 0x3f;
12684 minor
= (ctx
->opcode
>> 6) & 0xf;
12687 mips32_op
= OPC_SLL
;
12690 mips32_op
= OPC_SRA
;
12693 mips32_op
= OPC_SRL
;
12696 mips32_op
= OPC_ROTR
;
12698 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
12701 goto pool32a_invalid
;
12705 minor
= (ctx
->opcode
>> 6) & 0xf;
12709 mips32_op
= OPC_ADD
;
12712 mips32_op
= OPC_ADDU
;
12715 mips32_op
= OPC_SUB
;
12718 mips32_op
= OPC_SUBU
;
12721 mips32_op
= OPC_MUL
;
12723 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
12727 mips32_op
= OPC_SLLV
;
12730 mips32_op
= OPC_SRLV
;
12733 mips32_op
= OPC_SRAV
;
12736 mips32_op
= OPC_ROTRV
;
12738 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
12740 /* Logical operations */
12742 mips32_op
= OPC_AND
;
12745 mips32_op
= OPC_OR
;
12748 mips32_op
= OPC_NOR
;
12751 mips32_op
= OPC_XOR
;
12753 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
12755 /* Set less than */
12757 mips32_op
= OPC_SLT
;
12760 mips32_op
= OPC_SLTU
;
12762 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
12765 goto pool32a_invalid
;
12769 minor
= (ctx
->opcode
>> 6) & 0xf;
12771 /* Conditional moves */
12773 mips32_op
= OPC_MOVN
;
12776 mips32_op
= OPC_MOVZ
;
12778 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
12781 gen_ldxs(ctx
, rs
, rt
, rd
);
12784 goto pool32a_invalid
;
12788 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
12791 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
12794 gen_pool32axf(env
, ctx
, rt
, rs
);
12797 generate_exception(ctx
, EXCP_BREAK
);
12801 MIPS_INVAL("pool32a");
12802 generate_exception(ctx
, EXCP_RI
);
12807 minor
= (ctx
->opcode
>> 12) & 0xf;
12810 check_cp0_enabled(ctx
);
12811 /* Treat as no-op. */
12815 /* COP2: Not implemented. */
12816 generate_exception_err(ctx
, EXCP_CpU
, 2);
12820 #ifdef TARGET_MIPS64
12824 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12828 #ifdef TARGET_MIPS64
12832 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12835 MIPS_INVAL("pool32b");
12836 generate_exception(ctx
, EXCP_RI
);
12841 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
12842 minor
= ctx
->opcode
& 0x3f;
12843 check_cp1_enabled(ctx
);
12846 mips32_op
= OPC_ALNV_PS
;
12849 mips32_op
= OPC_MADD_S
;
12852 mips32_op
= OPC_MADD_D
;
12855 mips32_op
= OPC_MADD_PS
;
12858 mips32_op
= OPC_MSUB_S
;
12861 mips32_op
= OPC_MSUB_D
;
12864 mips32_op
= OPC_MSUB_PS
;
12867 mips32_op
= OPC_NMADD_S
;
12870 mips32_op
= OPC_NMADD_D
;
12873 mips32_op
= OPC_NMADD_PS
;
12876 mips32_op
= OPC_NMSUB_S
;
12879 mips32_op
= OPC_NMSUB_D
;
12882 mips32_op
= OPC_NMSUB_PS
;
12884 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
12886 case CABS_COND_FMT
:
12887 cond
= (ctx
->opcode
>> 6) & 0xf;
12888 cc
= (ctx
->opcode
>> 13) & 0x7;
12889 fmt
= (ctx
->opcode
>> 10) & 0x3;
12892 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
12895 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
12898 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
12901 goto pool32f_invalid
;
12905 cond
= (ctx
->opcode
>> 6) & 0xf;
12906 cc
= (ctx
->opcode
>> 13) & 0x7;
12907 fmt
= (ctx
->opcode
>> 10) & 0x3;
12910 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
12913 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
12916 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
12919 goto pool32f_invalid
;
12923 gen_pool32fxf(ctx
, rt
, rs
);
12927 switch ((ctx
->opcode
>> 6) & 0x7) {
12929 mips32_op
= OPC_PLL_PS
;
12932 mips32_op
= OPC_PLU_PS
;
12935 mips32_op
= OPC_PUL_PS
;
12938 mips32_op
= OPC_PUU_PS
;
12941 mips32_op
= OPC_CVT_PS_S
;
12943 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12946 goto pool32f_invalid
;
12951 switch ((ctx
->opcode
>> 6) & 0x7) {
12953 mips32_op
= OPC_LWXC1
;
12956 mips32_op
= OPC_SWXC1
;
12959 mips32_op
= OPC_LDXC1
;
12962 mips32_op
= OPC_SDXC1
;
12965 mips32_op
= OPC_LUXC1
;
12968 mips32_op
= OPC_SUXC1
;
12970 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
12973 goto pool32f_invalid
;
12978 fmt
= (ctx
->opcode
>> 9) & 0x3;
12979 switch ((ctx
->opcode
>> 6) & 0x7) {
12983 mips32_op
= OPC_RSQRT2_S
;
12986 mips32_op
= OPC_RSQRT2_D
;
12989 mips32_op
= OPC_RSQRT2_PS
;
12992 goto pool32f_invalid
;
12998 mips32_op
= OPC_RECIP2_S
;
13001 mips32_op
= OPC_RECIP2_D
;
13004 mips32_op
= OPC_RECIP2_PS
;
13007 goto pool32f_invalid
;
13011 mips32_op
= OPC_ADDR_PS
;
13014 mips32_op
= OPC_MULR_PS
;
13016 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13019 goto pool32f_invalid
;
13023 /* MOV[FT].fmt and PREFX */
13024 cc
= (ctx
->opcode
>> 13) & 0x7;
13025 fmt
= (ctx
->opcode
>> 9) & 0x3;
13026 switch ((ctx
->opcode
>> 6) & 0x7) {
13030 gen_movcf_s(rs
, rt
, cc
, 0);
13033 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
13036 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
13039 goto pool32f_invalid
;
13045 gen_movcf_s(rs
, rt
, cc
, 1);
13048 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
13051 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
13054 goto pool32f_invalid
;
13060 goto pool32f_invalid
;
13063 #define FINSN_3ARG_SDPS(prfx) \
13064 switch ((ctx->opcode >> 8) & 0x3) { \
13066 mips32_op = OPC_##prfx##_S; \
13069 mips32_op = OPC_##prfx##_D; \
13071 case FMT_SDPS_PS: \
13072 mips32_op = OPC_##prfx##_PS; \
13075 goto pool32f_invalid; \
13078 /* regular FP ops */
13079 switch ((ctx
->opcode
>> 6) & 0x3) {
13081 FINSN_3ARG_SDPS(ADD
);
13084 FINSN_3ARG_SDPS(SUB
);
13087 FINSN_3ARG_SDPS(MUL
);
13090 fmt
= (ctx
->opcode
>> 8) & 0x3;
13092 mips32_op
= OPC_DIV_D
;
13093 } else if (fmt
== 0) {
13094 mips32_op
= OPC_DIV_S
;
13096 goto pool32f_invalid
;
13100 goto pool32f_invalid
;
13105 switch ((ctx
->opcode
>> 6) & 0x3) {
13107 FINSN_3ARG_SDPS(MOVN
);
13110 FINSN_3ARG_SDPS(MOVZ
);
13113 goto pool32f_invalid
;
13117 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
13121 MIPS_INVAL("pool32f");
13122 generate_exception(ctx
, EXCP_RI
);
13126 generate_exception_err(ctx
, EXCP_CpU
, 1);
13130 minor
= (ctx
->opcode
>> 21) & 0x1f;
13133 mips32_op
= OPC_BLTZ
;
13136 mips32_op
= OPC_BLTZAL
;
13139 mips32_op
= OPC_BLTZALS
;
13142 mips32_op
= OPC_BGEZ
;
13145 mips32_op
= OPC_BGEZAL
;
13148 mips32_op
= OPC_BGEZALS
;
13151 mips32_op
= OPC_BLEZ
;
13154 mips32_op
= OPC_BGTZ
;
13156 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
13161 mips32_op
= OPC_TLTI
;
13164 mips32_op
= OPC_TGEI
;
13167 mips32_op
= OPC_TLTIU
;
13170 mips32_op
= OPC_TGEIU
;
13173 mips32_op
= OPC_TNEI
;
13176 mips32_op
= OPC_TEQI
;
13178 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
13183 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
13184 4, rs
, 0, imm
<< 1);
13185 /* Compact branches don't have a delay slot, so just let
13186 the normal delay slot handling take us to the branch
13190 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
13196 /* COP2: Not implemented. */
13197 generate_exception_err(ctx
, EXCP_CpU
, 2);
13200 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
13203 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
13206 mips32_op
= OPC_BC1FANY4
;
13209 mips32_op
= OPC_BC1TANY4
;
13212 check_insn(ctx
, ASE_MIPS3D
);
13215 gen_compute_branch1(ctx
, mips32_op
,
13216 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
13220 /* MIPS DSP: not implemented */
13223 MIPS_INVAL("pool32i");
13224 generate_exception(ctx
, EXCP_RI
);
13229 minor
= (ctx
->opcode
>> 12) & 0xf;
13232 mips32_op
= OPC_LWL
;
13235 mips32_op
= OPC_SWL
;
13238 mips32_op
= OPC_LWR
;
13241 mips32_op
= OPC_SWR
;
13243 #if defined(TARGET_MIPS64)
13245 mips32_op
= OPC_LDL
;
13248 mips32_op
= OPC_SDL
;
13251 mips32_op
= OPC_LDR
;
13254 mips32_op
= OPC_SDR
;
13257 mips32_op
= OPC_LWU
;
13260 mips32_op
= OPC_LLD
;
13264 mips32_op
= OPC_LL
;
13267 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13270 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13273 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13275 #if defined(TARGET_MIPS64)
13277 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
13281 /* Treat as no-op */
13284 MIPS_INVAL("pool32c");
13285 generate_exception(ctx
, EXCP_RI
);
13290 mips32_op
= OPC_ADDI
;
13293 mips32_op
= OPC_ADDIU
;
13295 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13298 /* Logical operations */
13300 mips32_op
= OPC_ORI
;
13303 mips32_op
= OPC_XORI
;
13306 mips32_op
= OPC_ANDI
;
13308 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13311 /* Set less than immediate */
13313 mips32_op
= OPC_SLTI
;
13316 mips32_op
= OPC_SLTIU
;
13318 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
13321 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
13322 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
13325 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
13326 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
13329 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
13332 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
13335 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
13336 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
13339 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
13340 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
13342 /* Floating point (COP1) */
13344 mips32_op
= OPC_LWC1
;
13347 mips32_op
= OPC_LDC1
;
13350 mips32_op
= OPC_SWC1
;
13353 mips32_op
= OPC_SDC1
;
13355 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
13359 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
13360 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
13362 gen_addiupc(ctx
, reg
, offset
, 0, 0);
13365 /* Loads and stores */
13367 mips32_op
= OPC_LB
;
13370 mips32_op
= OPC_LBU
;
13373 mips32_op
= OPC_LH
;
13376 mips32_op
= OPC_LHU
;
13379 mips32_op
= OPC_LW
;
13381 #ifdef TARGET_MIPS64
13383 mips32_op
= OPC_LD
;
13386 mips32_op
= OPC_SD
;
13390 mips32_op
= OPC_SB
;
13393 mips32_op
= OPC_SH
;
13396 mips32_op
= OPC_SW
;
13399 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
13402 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
13405 generate_exception(ctx
, EXCP_RI
);
13410 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
13414 /* make sure instructions are on a halfword boundary */
13415 if (ctx
->pc
& 0x1) {
13416 env
->CP0_BadVAddr
= ctx
->pc
;
13417 generate_exception(ctx
, EXCP_AdEL
);
13418 ctx
->bstate
= BS_STOP
;
13422 op
= (ctx
->opcode
>> 10) & 0x3f;
13423 /* Enforce properly-sized instructions in a delay slot */
13424 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
13425 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
13463 if (bits
& MIPS_HFLAG_BDS16
) {
13464 generate_exception(ctx
, EXCP_RI
);
13465 /* Just stop translation; the user is confused. */
13466 ctx
->bstate
= BS_STOP
;
13491 if (bits
& MIPS_HFLAG_BDS32
) {
13492 generate_exception(ctx
, EXCP_RI
);
13493 /* Just stop translation; the user is confused. */
13494 ctx
->bstate
= BS_STOP
;
13505 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13506 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
13507 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
13510 switch (ctx
->opcode
& 0x1) {
13519 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
13524 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13525 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
13526 int amount
= (ctx
->opcode
>> 1) & 0x7;
13528 amount
= amount
== 0 ? 8 : amount
;
13530 switch (ctx
->opcode
& 0x1) {
13539 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
13543 gen_pool16c_insn(ctx
);
13547 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13548 int rb
= 28; /* GP */
13549 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
13551 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13555 if (ctx
->opcode
& 1) {
13556 generate_exception(ctx
, EXCP_RI
);
13559 int enc_dest
= uMIPS_RD(ctx
->opcode
);
13560 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
13561 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
13562 int rd
, rs
, re
, rt
;
13563 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
13564 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
13565 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
13567 rd
= rd_enc
[enc_dest
];
13568 re
= re_enc
[enc_dest
];
13569 rs
= rs_rt_enc
[enc_rs
];
13570 rt
= rs_rt_enc
[enc_rt
];
13572 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
13573 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
13578 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13579 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13580 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
13581 offset
= (offset
== 0xf ? -1 : offset
);
13583 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
13588 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13589 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13590 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
13592 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
13597 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13598 int rb
= 29; /* SP */
13599 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
13601 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13606 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
13607 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13608 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
13610 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
13615 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13616 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13617 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
13619 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
13624 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13625 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13626 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
13628 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
13633 int rd
= (ctx
->opcode
>> 5) & 0x1f;
13634 int rb
= 29; /* SP */
13635 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
13637 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
13642 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
13643 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
13644 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
13646 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
13651 int rd
= uMIPS_RD5(ctx
->opcode
);
13652 int rs
= uMIPS_RS5(ctx
->opcode
);
13654 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
13661 switch (ctx
->opcode
& 0x1) {
13671 switch (ctx
->opcode
& 0x1) {
13676 gen_addiur1sp(ctx
);
13681 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
13682 SIMM(ctx
->opcode
, 0, 10) << 1);
13686 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
13687 mmreg(uMIPS_RD(ctx
->opcode
)),
13688 0, SIMM(ctx
->opcode
, 0, 7) << 1);
13692 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
13693 int imm
= ZIMM(ctx
->opcode
, 0, 7);
13695 imm
= (imm
== 0x7f ? -1 : imm
);
13696 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
13706 generate_exception(ctx
, EXCP_RI
);
13709 decode_micromips32_opc (env
, ctx
, op
);
13716 /* SmartMIPS extension to MIPS32 */
13718 #if defined(TARGET_MIPS64)
13720 /* MDMX extension to MIPS64 */
13724 /* MIPSDSP functions. */
13725 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
13726 int rd
, int base
, int offset
)
13728 const char *opn
= "ldx";
13732 t0
= tcg_temp_new();
13735 gen_load_gpr(t0
, offset
);
13736 } else if (offset
== 0) {
13737 gen_load_gpr(t0
, base
);
13739 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
13744 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
13745 gen_store_gpr(t0
, rd
);
13749 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
13750 gen_store_gpr(t0
, rd
);
13754 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
13755 gen_store_gpr(t0
, rd
);
13758 #if defined(TARGET_MIPS64)
13760 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
13761 gen_store_gpr(t0
, rd
);
13766 (void)opn
; /* avoid a compiler warning */
13767 MIPS_DEBUG("%s %s, %s(%s)", opn
,
13768 regnames
[rd
], regnames
[offset
], regnames
[base
]);
13772 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13773 int ret
, int v1
, int v2
)
13775 const char *opn
= "mipsdsp arith";
13780 /* Treat as NOP. */
13785 v1_t
= tcg_temp_new();
13786 v2_t
= tcg_temp_new();
13788 gen_load_gpr(v1_t
, v1
);
13789 gen_load_gpr(v2_t
, v2
);
13792 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
13793 case OPC_MULT_G_2E
:
13797 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13799 case OPC_ADDUH_R_QB
:
13800 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13803 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13805 case OPC_ADDQH_R_PH
:
13806 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13809 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13811 case OPC_ADDQH_R_W
:
13812 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13815 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13817 case OPC_SUBUH_R_QB
:
13818 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13821 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13823 case OPC_SUBQH_R_PH
:
13824 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13827 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13829 case OPC_SUBQH_R_W
:
13830 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13834 case OPC_ABSQ_S_PH_DSP
:
13836 case OPC_ABSQ_S_QB
:
13838 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
13840 case OPC_ABSQ_S_PH
:
13842 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
13846 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
13848 case OPC_PRECEQ_W_PHL
:
13850 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
13851 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13853 case OPC_PRECEQ_W_PHR
:
13855 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
13856 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
13857 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13859 case OPC_PRECEQU_PH_QBL
:
13861 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
13863 case OPC_PRECEQU_PH_QBR
:
13865 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
13867 case OPC_PRECEQU_PH_QBLA
:
13869 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
13871 case OPC_PRECEQU_PH_QBRA
:
13873 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
13875 case OPC_PRECEU_PH_QBL
:
13877 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
13879 case OPC_PRECEU_PH_QBR
:
13881 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
13883 case OPC_PRECEU_PH_QBLA
:
13885 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
13887 case OPC_PRECEU_PH_QBRA
:
13889 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
13893 case OPC_ADDU_QB_DSP
:
13897 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13899 case OPC_ADDQ_S_PH
:
13901 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13905 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13909 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13911 case OPC_ADDU_S_QB
:
13913 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13917 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13919 case OPC_ADDU_S_PH
:
13921 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13925 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13927 case OPC_SUBQ_S_PH
:
13929 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13933 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13937 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13939 case OPC_SUBU_S_QB
:
13941 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13945 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13947 case OPC_SUBU_S_PH
:
13949 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13953 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13957 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13961 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
13963 case OPC_RADDU_W_QB
:
13965 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
13969 case OPC_CMPU_EQ_QB_DSP
:
13971 case OPC_PRECR_QB_PH
:
13973 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13975 case OPC_PRECRQ_QB_PH
:
13977 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13979 case OPC_PRECR_SRA_PH_W
:
13982 TCGv_i32 sa_t
= tcg_const_i32(v2
);
13983 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
13985 tcg_temp_free_i32(sa_t
);
13988 case OPC_PRECR_SRA_R_PH_W
:
13991 TCGv_i32 sa_t
= tcg_const_i32(v2
);
13992 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
13994 tcg_temp_free_i32(sa_t
);
13997 case OPC_PRECRQ_PH_W
:
13999 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14001 case OPC_PRECRQ_RS_PH_W
:
14003 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14005 case OPC_PRECRQU_S_QB_PH
:
14007 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14011 #ifdef TARGET_MIPS64
14012 case OPC_ABSQ_S_QH_DSP
:
14014 case OPC_PRECEQ_L_PWL
:
14016 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
14018 case OPC_PRECEQ_L_PWR
:
14020 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
14022 case OPC_PRECEQ_PW_QHL
:
14024 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
14026 case OPC_PRECEQ_PW_QHR
:
14028 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
14030 case OPC_PRECEQ_PW_QHLA
:
14032 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
14034 case OPC_PRECEQ_PW_QHRA
:
14036 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
14038 case OPC_PRECEQU_QH_OBL
:
14040 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
14042 case OPC_PRECEQU_QH_OBR
:
14044 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
14046 case OPC_PRECEQU_QH_OBLA
:
14048 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
14050 case OPC_PRECEQU_QH_OBRA
:
14052 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
14054 case OPC_PRECEU_QH_OBL
:
14056 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
14058 case OPC_PRECEU_QH_OBR
:
14060 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
14062 case OPC_PRECEU_QH_OBLA
:
14064 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
14066 case OPC_PRECEU_QH_OBRA
:
14068 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
14070 case OPC_ABSQ_S_OB
:
14072 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
14074 case OPC_ABSQ_S_PW
:
14076 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
14078 case OPC_ABSQ_S_QH
:
14080 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
14084 case OPC_ADDU_OB_DSP
:
14086 case OPC_RADDU_L_OB
:
14088 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
14092 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14094 case OPC_SUBQ_S_PW
:
14096 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14100 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14102 case OPC_SUBQ_S_QH
:
14104 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14108 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14110 case OPC_SUBU_S_OB
:
14112 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14116 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14118 case OPC_SUBU_S_QH
:
14120 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14124 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14126 case OPC_SUBUH_R_OB
:
14128 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14132 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14134 case OPC_ADDQ_S_PW
:
14136 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14140 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14142 case OPC_ADDQ_S_QH
:
14144 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14148 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14150 case OPC_ADDU_S_OB
:
14152 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14156 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14158 case OPC_ADDU_S_QH
:
14160 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14164 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14166 case OPC_ADDUH_R_OB
:
14168 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14172 case OPC_CMPU_EQ_OB_DSP
:
14174 case OPC_PRECR_OB_QH
:
14176 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
14178 case OPC_PRECR_SRA_QH_PW
:
14181 TCGv_i32 ret_t
= tcg_const_i32(ret
);
14182 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
14183 tcg_temp_free_i32(ret_t
);
14186 case OPC_PRECR_SRA_R_QH_PW
:
14189 TCGv_i32 sa_v
= tcg_const_i32(ret
);
14190 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
14191 tcg_temp_free_i32(sa_v
);
14194 case OPC_PRECRQ_OB_QH
:
14196 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
14198 case OPC_PRECRQ_PW_L
:
14200 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
14202 case OPC_PRECRQ_QH_PW
:
14204 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14206 case OPC_PRECRQ_RS_QH_PW
:
14208 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14210 case OPC_PRECRQU_S_OB_QH
:
14212 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14219 tcg_temp_free(v1_t
);
14220 tcg_temp_free(v2_t
);
14222 (void)opn
; /* avoid a compiler warning */
14223 MIPS_DEBUG("%s", opn
);
14226 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
14227 int ret
, int v1
, int v2
)
14230 const char *opn
= "mipsdsp shift";
14236 /* Treat as NOP. */
14241 t0
= tcg_temp_new();
14242 v1_t
= tcg_temp_new();
14243 v2_t
= tcg_temp_new();
14245 tcg_gen_movi_tl(t0
, v1
);
14246 gen_load_gpr(v1_t
, v1
);
14247 gen_load_gpr(v2_t
, v2
);
14250 case OPC_SHLL_QB_DSP
:
14252 op2
= MASK_SHLL_QB(ctx
->opcode
);
14256 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14260 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14264 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14268 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14270 case OPC_SHLL_S_PH
:
14272 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14274 case OPC_SHLLV_S_PH
:
14276 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14280 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
14282 case OPC_SHLLV_S_W
:
14284 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14288 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
14292 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14296 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
14300 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14304 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
14306 case OPC_SHRA_R_QB
:
14308 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
14312 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14314 case OPC_SHRAV_R_QB
:
14316 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14320 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
14322 case OPC_SHRA_R_PH
:
14324 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
14328 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14330 case OPC_SHRAV_R_PH
:
14332 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14336 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
14338 case OPC_SHRAV_R_W
:
14340 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
14342 default: /* Invalid */
14343 MIPS_INVAL("MASK SHLL.QB");
14344 generate_exception(ctx
, EXCP_RI
);
14349 #ifdef TARGET_MIPS64
14350 case OPC_SHLL_OB_DSP
:
14351 op2
= MASK_SHLL_OB(ctx
->opcode
);
14355 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14359 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14361 case OPC_SHLL_S_PW
:
14363 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14365 case OPC_SHLLV_S_PW
:
14367 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14371 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14375 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14379 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14383 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14385 case OPC_SHLL_S_QH
:
14387 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
14389 case OPC_SHLLV_S_QH
:
14391 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
14395 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
14399 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14401 case OPC_SHRA_R_OB
:
14403 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
14405 case OPC_SHRAV_R_OB
:
14407 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14411 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
14415 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
14417 case OPC_SHRA_R_PW
:
14419 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
14421 case OPC_SHRAV_R_PW
:
14423 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
14427 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
14431 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14433 case OPC_SHRA_R_QH
:
14435 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
14437 case OPC_SHRAV_R_QH
:
14439 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14443 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
14447 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
14451 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
14455 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
14457 default: /* Invalid */
14458 MIPS_INVAL("MASK SHLL.OB");
14459 generate_exception(ctx
, EXCP_RI
);
14467 tcg_temp_free(v1_t
);
14468 tcg_temp_free(v2_t
);
14469 (void)opn
; /* avoid a compiler warning */
14470 MIPS_DEBUG("%s", opn
);
14473 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14474 int ret
, int v1
, int v2
, int check_ret
)
14476 const char *opn
= "mipsdsp multiply";
14481 if ((ret
== 0) && (check_ret
== 1)) {
14482 /* Treat as NOP. */
14487 t0
= tcg_temp_new_i32();
14488 v1_t
= tcg_temp_new();
14489 v2_t
= tcg_temp_new();
14491 tcg_gen_movi_i32(t0
, ret
);
14492 gen_load_gpr(v1_t
, v1
);
14493 gen_load_gpr(v2_t
, v2
);
14496 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14497 * the same mask and op1. */
14498 case OPC_MULT_G_2E
:
14502 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14505 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14508 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14510 case OPC_MULQ_RS_W
:
14511 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14515 case OPC_DPA_W_PH_DSP
:
14517 case OPC_DPAU_H_QBL
:
14519 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
14521 case OPC_DPAU_H_QBR
:
14523 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
14525 case OPC_DPSU_H_QBL
:
14527 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
14529 case OPC_DPSU_H_QBR
:
14531 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
14535 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14537 case OPC_DPAX_W_PH
:
14539 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14541 case OPC_DPAQ_S_W_PH
:
14543 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14545 case OPC_DPAQX_S_W_PH
:
14547 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14549 case OPC_DPAQX_SA_W_PH
:
14551 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14555 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14557 case OPC_DPSX_W_PH
:
14559 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14561 case OPC_DPSQ_S_W_PH
:
14563 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14565 case OPC_DPSQX_S_W_PH
:
14567 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14569 case OPC_DPSQX_SA_W_PH
:
14571 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14573 case OPC_MULSAQ_S_W_PH
:
14575 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14577 case OPC_DPAQ_SA_L_W
:
14579 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
14581 case OPC_DPSQ_SA_L_W
:
14583 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
14585 case OPC_MAQ_S_W_PHL
:
14587 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
14589 case OPC_MAQ_S_W_PHR
:
14591 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
14593 case OPC_MAQ_SA_W_PHL
:
14595 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
14597 case OPC_MAQ_SA_W_PHR
:
14599 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
14601 case OPC_MULSA_W_PH
:
14603 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
14607 #ifdef TARGET_MIPS64
14608 case OPC_DPAQ_W_QH_DSP
:
14610 int ac
= ret
& 0x03;
14611 tcg_gen_movi_i32(t0
, ac
);
14616 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
14620 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
14624 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
14628 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
14632 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14634 case OPC_DPAQ_S_W_QH
:
14636 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14638 case OPC_DPAQ_SA_L_PW
:
14640 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
14642 case OPC_DPAU_H_OBL
:
14644 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
14646 case OPC_DPAU_H_OBR
:
14648 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
14652 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14654 case OPC_DPSQ_S_W_QH
:
14656 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14658 case OPC_DPSQ_SA_L_PW
:
14660 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
14662 case OPC_DPSU_H_OBL
:
14664 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
14666 case OPC_DPSU_H_OBR
:
14668 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
14670 case OPC_MAQ_S_L_PWL
:
14672 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
14674 case OPC_MAQ_S_L_PWR
:
14676 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
14678 case OPC_MAQ_S_W_QHLL
:
14680 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
14682 case OPC_MAQ_SA_W_QHLL
:
14684 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
14686 case OPC_MAQ_S_W_QHLR
:
14688 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
14690 case OPC_MAQ_SA_W_QHLR
:
14692 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
14694 case OPC_MAQ_S_W_QHRL
:
14696 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
14698 case OPC_MAQ_SA_W_QHRL
:
14700 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
14702 case OPC_MAQ_S_W_QHRR
:
14704 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
14706 case OPC_MAQ_SA_W_QHRR
:
14708 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
14710 case OPC_MULSAQ_S_L_PW
:
14712 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
14714 case OPC_MULSAQ_S_W_QH
:
14716 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
14722 case OPC_ADDU_QB_DSP
:
14724 case OPC_MULEU_S_PH_QBL
:
14726 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14728 case OPC_MULEU_S_PH_QBR
:
14730 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14732 case OPC_MULQ_RS_PH
:
14734 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14736 case OPC_MULEQ_S_W_PHL
:
14738 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14740 case OPC_MULEQ_S_W_PHR
:
14742 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14744 case OPC_MULQ_S_PH
:
14746 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14750 #ifdef TARGET_MIPS64
14751 case OPC_ADDU_OB_DSP
:
14753 case OPC_MULEQ_S_PW_QHL
:
14755 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14757 case OPC_MULEQ_S_PW_QHR
:
14759 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14761 case OPC_MULEU_S_QH_OBL
:
14763 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14765 case OPC_MULEU_S_QH_OBR
:
14767 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14769 case OPC_MULQ_RS_QH
:
14771 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14778 tcg_temp_free_i32(t0
);
14779 tcg_temp_free(v1_t
);
14780 tcg_temp_free(v2_t
);
14782 (void)opn
; /* avoid a compiler warning */
14783 MIPS_DEBUG("%s", opn
);
14787 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14790 const char *opn
= "mipsdsp Bit/ Manipulation";
14796 /* Treat as NOP. */
14801 t0
= tcg_temp_new();
14802 val_t
= tcg_temp_new();
14803 gen_load_gpr(val_t
, val
);
14806 case OPC_ABSQ_S_PH_DSP
:
14810 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
14815 target_long result
;
14816 imm
= (ctx
->opcode
>> 16) & 0xFF;
14817 result
= (uint32_t)imm
<< 24 |
14818 (uint32_t)imm
<< 16 |
14819 (uint32_t)imm
<< 8 |
14821 result
= (int32_t)result
;
14822 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
14827 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
14828 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
14829 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14830 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14831 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14832 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
14837 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14838 imm
= (int16_t)(imm
<< 6) >> 6;
14839 tcg_gen_movi_tl(cpu_gpr
[ret
], \
14840 (target_long
)((int32_t)imm
<< 16 | \
14846 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
14847 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14848 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14849 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
14853 #ifdef TARGET_MIPS64
14854 case OPC_ABSQ_S_QH_DSP
:
14861 imm
= (ctx
->opcode
>> 16) & 0xFF;
14862 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
14863 temp
= (temp
<< 16) | temp
;
14864 temp
= (temp
<< 32) | temp
;
14865 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
14873 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14874 imm
= (int16_t)(imm
<< 6) >> 6;
14875 temp
= ((target_long
)imm
<< 32) \
14876 | ((target_long
)imm
& 0xFFFFFFFF);
14877 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
14885 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14886 imm
= (int16_t)(imm
<< 6) >> 6;
14888 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
14889 ((uint64_t)(uint16_t)imm
<< 32) |
14890 ((uint64_t)(uint16_t)imm
<< 16) |
14891 (uint64_t)(uint16_t)imm
;
14892 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
14897 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
14898 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
14899 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14900 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14901 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14902 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
14903 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14907 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
14908 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
14909 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14913 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
14914 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
14915 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14916 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
14917 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
14924 tcg_temp_free(val_t
);
14926 (void)opn
; /* avoid a compiler warning */
14927 MIPS_DEBUG("%s", opn
);
14930 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
14931 uint32_t op1
, uint32_t op2
,
14932 int ret
, int v1
, int v2
, int check_ret
)
14934 const char *opn
= "mipsdsp add compare pick";
14939 if ((ret
== 0) && (check_ret
== 1)) {
14940 /* Treat as NOP. */
14945 t1
= tcg_temp_new();
14946 v1_t
= tcg_temp_new();
14947 v2_t
= tcg_temp_new();
14949 gen_load_gpr(v1_t
, v1
);
14950 gen_load_gpr(v2_t
, v2
);
14953 case OPC_CMPU_EQ_QB_DSP
:
14955 case OPC_CMPU_EQ_QB
:
14957 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
14959 case OPC_CMPU_LT_QB
:
14961 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
14963 case OPC_CMPU_LE_QB
:
14965 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
14967 case OPC_CMPGU_EQ_QB
:
14969 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14971 case OPC_CMPGU_LT_QB
:
14973 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14975 case OPC_CMPGU_LE_QB
:
14977 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
14979 case OPC_CMPGDU_EQ_QB
:
14981 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
14982 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14983 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
14984 tcg_gen_shli_tl(t1
, t1
, 24);
14985 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14987 case OPC_CMPGDU_LT_QB
:
14989 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
14990 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14991 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
14992 tcg_gen_shli_tl(t1
, t1
, 24);
14993 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14995 case OPC_CMPGDU_LE_QB
:
14997 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
14998 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14999 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
15000 tcg_gen_shli_tl(t1
, t1
, 24);
15001 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
15003 case OPC_CMP_EQ_PH
:
15005 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
15007 case OPC_CMP_LT_PH
:
15009 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
15011 case OPC_CMP_LE_PH
:
15013 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
15017 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15021 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15023 case OPC_PACKRL_PH
:
15025 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
15029 #ifdef TARGET_MIPS64
15030 case OPC_CMPU_EQ_OB_DSP
:
15032 case OPC_CMP_EQ_PW
:
15034 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
15036 case OPC_CMP_LT_PW
:
15038 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
15040 case OPC_CMP_LE_PW
:
15042 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
15044 case OPC_CMP_EQ_QH
:
15046 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
15048 case OPC_CMP_LT_QH
:
15050 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
15052 case OPC_CMP_LE_QH
:
15054 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
15056 case OPC_CMPGDU_EQ_OB
:
15058 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15060 case OPC_CMPGDU_LT_OB
:
15062 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15064 case OPC_CMPGDU_LE_OB
:
15066 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15068 case OPC_CMPGU_EQ_OB
:
15070 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15072 case OPC_CMPGU_LT_OB
:
15074 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15076 case OPC_CMPGU_LE_OB
:
15078 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
15080 case OPC_CMPU_EQ_OB
:
15082 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
15084 case OPC_CMPU_LT_OB
:
15086 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
15088 case OPC_CMPU_LE_OB
:
15090 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
15092 case OPC_PACKRL_PW
:
15094 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
15098 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15102 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15106 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
15114 tcg_temp_free(v1_t
);
15115 tcg_temp_free(v2_t
);
15117 (void)opn
; /* avoid a compiler warning */
15118 MIPS_DEBUG("%s", opn
);
15121 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
15122 uint32_t op1
, int rt
, int rs
, int sa
)
15124 const char *opn
= "mipsdsp append/dappend";
15130 /* Treat as NOP. */
15135 t0
= tcg_temp_new();
15136 gen_load_gpr(t0
, rs
);
15139 case OPC_APPEND_DSP
:
15140 switch (MASK_APPEND(ctx
->opcode
)) {
15143 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
15145 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15149 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15150 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
15151 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
15152 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15154 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15158 if (sa
!= 0 && sa
!= 2) {
15159 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
15160 tcg_gen_ext32u_tl(t0
, t0
);
15161 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
15162 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15164 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
15166 default: /* Invalid */
15167 MIPS_INVAL("MASK APPEND");
15168 generate_exception(ctx
, EXCP_RI
);
15172 #ifdef TARGET_MIPS64
15173 case OPC_DAPPEND_DSP
:
15174 switch (MASK_DAPPEND(ctx
->opcode
)) {
15177 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
15181 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
15182 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
15183 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
15187 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
15188 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
15189 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15194 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
15195 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
15196 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
15197 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
15200 default: /* Invalid */
15201 MIPS_INVAL("MASK DAPPEND");
15202 generate_exception(ctx
, EXCP_RI
);
15209 (void)opn
; /* avoid a compiler warning */
15210 MIPS_DEBUG("%s", opn
);
15213 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
15214 int ret
, int v1
, int v2
, int check_ret
)
15217 const char *opn
= "mipsdsp accumulator";
15224 if ((ret
== 0) && (check_ret
== 1)) {
15225 /* Treat as NOP. */
15230 t0
= tcg_temp_new();
15231 t1
= tcg_temp_new();
15232 v1_t
= tcg_temp_new();
15233 v2_t
= tcg_temp_new();
15235 gen_load_gpr(v1_t
, v1
);
15236 gen_load_gpr(v2_t
, v2
);
15239 case OPC_EXTR_W_DSP
:
15243 tcg_gen_movi_tl(t0
, v2
);
15244 tcg_gen_movi_tl(t1
, v1
);
15245 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15248 tcg_gen_movi_tl(t0
, v2
);
15249 tcg_gen_movi_tl(t1
, v1
);
15250 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15252 case OPC_EXTR_RS_W
:
15253 tcg_gen_movi_tl(t0
, v2
);
15254 tcg_gen_movi_tl(t1
, v1
);
15255 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15258 tcg_gen_movi_tl(t0
, v2
);
15259 tcg_gen_movi_tl(t1
, v1
);
15260 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15262 case OPC_EXTRV_S_H
:
15263 tcg_gen_movi_tl(t0
, v2
);
15264 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15267 tcg_gen_movi_tl(t0
, v2
);
15268 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15270 case OPC_EXTRV_R_W
:
15271 tcg_gen_movi_tl(t0
, v2
);
15272 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15274 case OPC_EXTRV_RS_W
:
15275 tcg_gen_movi_tl(t0
, v2
);
15276 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15279 tcg_gen_movi_tl(t0
, v2
);
15280 tcg_gen_movi_tl(t1
, v1
);
15281 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15284 tcg_gen_movi_tl(t0
, v2
);
15285 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15288 tcg_gen_movi_tl(t0
, v2
);
15289 tcg_gen_movi_tl(t1
, v1
);
15290 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15293 tcg_gen_movi_tl(t0
, v2
);
15294 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15297 imm
= (ctx
->opcode
>> 20) & 0x3F;
15298 tcg_gen_movi_tl(t0
, ret
);
15299 tcg_gen_movi_tl(t1
, imm
);
15300 gen_helper_shilo(t0
, t1
, cpu_env
);
15303 tcg_gen_movi_tl(t0
, ret
);
15304 gen_helper_shilo(t0
, v1_t
, cpu_env
);
15307 tcg_gen_movi_tl(t0
, ret
);
15308 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
15311 imm
= (ctx
->opcode
>> 11) & 0x3FF;
15312 tcg_gen_movi_tl(t0
, imm
);
15313 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
15316 imm
= (ctx
->opcode
>> 16) & 0x03FF;
15317 tcg_gen_movi_tl(t0
, imm
);
15318 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
15322 #ifdef TARGET_MIPS64
15323 case OPC_DEXTR_W_DSP
:
15327 tcg_gen_movi_tl(t0
, ret
);
15328 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
15332 int shift
= (ctx
->opcode
>> 19) & 0x7F;
15333 int ac
= (ctx
->opcode
>> 11) & 0x03;
15334 tcg_gen_movi_tl(t0
, shift
);
15335 tcg_gen_movi_tl(t1
, ac
);
15336 gen_helper_dshilo(t0
, t1
, cpu_env
);
15341 int ac
= (ctx
->opcode
>> 11) & 0x03;
15342 tcg_gen_movi_tl(t0
, ac
);
15343 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
15347 tcg_gen_movi_tl(t0
, v2
);
15348 tcg_gen_movi_tl(t1
, v1
);
15350 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15353 tcg_gen_movi_tl(t0
, v2
);
15354 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15357 tcg_gen_movi_tl(t0
, v2
);
15358 tcg_gen_movi_tl(t1
, v1
);
15359 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15362 tcg_gen_movi_tl(t0
, v2
);
15363 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15366 tcg_gen_movi_tl(t0
, v2
);
15367 tcg_gen_movi_tl(t1
, v1
);
15368 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15370 case OPC_DEXTR_R_L
:
15371 tcg_gen_movi_tl(t0
, v2
);
15372 tcg_gen_movi_tl(t1
, v1
);
15373 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15375 case OPC_DEXTR_RS_L
:
15376 tcg_gen_movi_tl(t0
, v2
);
15377 tcg_gen_movi_tl(t1
, v1
);
15378 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15381 tcg_gen_movi_tl(t0
, v2
);
15382 tcg_gen_movi_tl(t1
, v1
);
15383 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15385 case OPC_DEXTR_R_W
:
15386 tcg_gen_movi_tl(t0
, v2
);
15387 tcg_gen_movi_tl(t1
, v1
);
15388 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15390 case OPC_DEXTR_RS_W
:
15391 tcg_gen_movi_tl(t0
, v2
);
15392 tcg_gen_movi_tl(t1
, v1
);
15393 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15395 case OPC_DEXTR_S_H
:
15396 tcg_gen_movi_tl(t0
, v2
);
15397 tcg_gen_movi_tl(t1
, v1
);
15398 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15400 case OPC_DEXTRV_S_H
:
15401 tcg_gen_movi_tl(t0
, v2
);
15402 tcg_gen_movi_tl(t1
, v1
);
15403 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
15406 tcg_gen_movi_tl(t0
, v2
);
15407 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15409 case OPC_DEXTRV_R_L
:
15410 tcg_gen_movi_tl(t0
, v2
);
15411 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15413 case OPC_DEXTRV_RS_L
:
15414 tcg_gen_movi_tl(t0
, v2
);
15415 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15418 tcg_gen_movi_tl(t0
, v2
);
15419 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15421 case OPC_DEXTRV_R_W
:
15422 tcg_gen_movi_tl(t0
, v2
);
15423 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15425 case OPC_DEXTRV_RS_W
:
15426 tcg_gen_movi_tl(t0
, v2
);
15427 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
15436 tcg_temp_free(v1_t
);
15437 tcg_temp_free(v2_t
);
15439 (void)opn
; /* avoid a compiler warning */
15440 MIPS_DEBUG("%s", opn
);
15443 /* End MIPSDSP functions. */
15445 /* Compact Branches */
15446 static void gen_compute_compact_branch(DisasContext
*ctx
, uint32_t opc
,
15447 int rs
, int rt
, int32_t offset
)
15449 int bcond_compute
= 0;
15450 TCGv t0
= tcg_temp_new();
15451 TCGv t1
= tcg_temp_new();
15453 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
15454 #ifdef MIPS_DEBUG_DISAS
15455 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
15457 generate_exception(ctx
, EXCP_RI
);
15461 /* Load needed operands and calculate btarget */
15463 /* compact branch */
15464 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
15465 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
15466 gen_load_gpr(t0
, rs
);
15467 gen_load_gpr(t1
, rt
);
15469 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15470 if (rs
<= rt
&& rs
== 0) {
15471 /* OPC_BEQZALC, OPC_BNEZALC */
15472 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15475 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
15476 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
15477 gen_load_gpr(t0
, rs
);
15478 gen_load_gpr(t1
, rt
);
15480 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15482 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
15483 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
15484 if (rs
== 0 || rs
== rt
) {
15485 /* OPC_BLEZALC, OPC_BGEZALC */
15486 /* OPC_BGTZALC, OPC_BLTZALC */
15487 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15489 gen_load_gpr(t0
, rs
);
15490 gen_load_gpr(t1
, rt
);
15492 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15496 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15501 /* OPC_BEQZC, OPC_BNEZC */
15502 gen_load_gpr(t0
, rs
);
15504 ctx
->btarget
= addr_add(ctx
, ctx
->pc
+ 4, offset
);
15506 /* OPC_JIC, OPC_JIALC */
15507 TCGv tbase
= tcg_temp_new();
15508 TCGv toffset
= tcg_temp_new();
15510 gen_load_gpr(tbase
, rt
);
15511 tcg_gen_movi_tl(toffset
, offset
);
15512 gen_op_addr_add(ctx
, btarget
, tbase
, toffset
);
15513 tcg_temp_free(tbase
);
15514 tcg_temp_free(toffset
);
15518 MIPS_INVAL("Compact branch/jump");
15519 generate_exception(ctx
, EXCP_RI
);
15523 if (bcond_compute
== 0) {
15524 /* Uncoditional compact branch */
15527 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15530 ctx
->hflags
|= MIPS_HFLAG_BR
;
15533 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 4);
15536 ctx
->hflags
|= MIPS_HFLAG_B
;
15539 MIPS_INVAL("Compact branch/jump");
15540 generate_exception(ctx
, EXCP_RI
);
15544 /* Generating branch here as compact branches don't have delay slot */
15545 gen_branch(ctx
, 4);
15547 /* Conditional compact branch */
15548 int l1
= gen_new_label();
15549 save_cpu_state(ctx
, 0);
15552 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC */
15553 if (rs
== 0 && rt
!= 0) {
15555 tcg_gen_brcondi_tl(TCG_COND_LE
, t1
, 0, l1
);
15556 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15558 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
15561 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
15564 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC */
15565 if (rs
== 0 && rt
!= 0) {
15567 tcg_gen_brcondi_tl(TCG_COND_GT
, t1
, 0, l1
);
15568 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15570 tcg_gen_brcondi_tl(TCG_COND_LT
, t1
, 0, l1
);
15573 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
15576 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC */
15577 if (rs
== 0 && rt
!= 0) {
15579 tcg_gen_brcondi_tl(TCG_COND_LE
, t1
, 0, l1
);
15580 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15582 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
15585 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
15588 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC */
15589 if (rs
== 0 && rt
!= 0) {
15591 tcg_gen_brcondi_tl(TCG_COND_GT
, t1
, 0, l1
);
15592 } else if (rs
!= 0 && rt
!= 0 && rs
== rt
) {
15594 tcg_gen_brcondi_tl(TCG_COND_LT
, t1
, 0, l1
);
15597 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
15600 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC */
15601 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
15603 /* OPC_BOVC, OPC_BNVC */
15604 TCGv t2
= tcg_temp_new();
15605 TCGv t3
= tcg_temp_new();
15606 TCGv t4
= tcg_temp_new();
15607 TCGv input_overflow
= tcg_temp_new();
15609 gen_load_gpr(t0
, rs
);
15610 gen_load_gpr(t1
, rt
);
15611 tcg_gen_ext32s_tl(t2
, t0
);
15612 tcg_gen_setcond_tl(TCG_COND_NE
, input_overflow
, t2
, t0
);
15613 tcg_gen_ext32s_tl(t3
, t1
);
15614 tcg_gen_setcond_tl(TCG_COND_NE
, t4
, t3
, t1
);
15615 tcg_gen_or_tl(input_overflow
, input_overflow
, t4
);
15617 tcg_gen_add_tl(t4
, t2
, t3
);
15618 tcg_gen_ext32s_tl(t4
, t4
);
15619 tcg_gen_xor_tl(t2
, t2
, t3
);
15620 tcg_gen_xor_tl(t3
, t4
, t3
);
15621 tcg_gen_andc_tl(t2
, t3
, t2
);
15622 tcg_gen_setcondi_tl(TCG_COND_LT
, t4
, t2
, 0);
15623 tcg_gen_or_tl(t4
, t4
, input_overflow
);
15624 if (opc
== OPC_BOVC
) {
15626 tcg_gen_brcondi_tl(TCG_COND_NE
, t4
, 0, l1
);
15629 tcg_gen_brcondi_tl(TCG_COND_EQ
, t4
, 0, l1
);
15631 tcg_temp_free(input_overflow
);
15635 } else if (rs
< rt
&& rs
== 0) {
15636 /* OPC_BEQZALC, OPC_BNEZALC */
15637 if (opc
== OPC_BEQZALC
) {
15639 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
15642 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
15645 /* OPC_BEQC, OPC_BNEC */
15646 if (opc
== OPC_BEQC
) {
15648 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
15651 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
15656 tcg_gen_brcondi_tl(TCG_COND_EQ
, t0
, 0, l1
);
15659 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
15662 MIPS_INVAL("Compact conditional branch/jump");
15663 generate_exception(ctx
, EXCP_RI
);
15667 /* Generating branch here as compact branches don't have delay slot */
15668 /* TODO: implement forbidden slot */
15669 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
15671 gen_goto_tb(ctx
, 0, ctx
->btarget
);
15672 MIPS_DEBUG("Compact conditional branch");
15673 ctx
->bstate
= BS_BRANCH
;
15681 static void decode_opc_special_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
15683 int rs
, rt
, rd
, sa
;
15686 rs
= (ctx
->opcode
>> 21) & 0x1f;
15687 rt
= (ctx
->opcode
>> 16) & 0x1f;
15688 rd
= (ctx
->opcode
>> 11) & 0x1f;
15689 sa
= (ctx
->opcode
>> 6) & 0x1f;
15691 op1
= MASK_SPECIAL(ctx
->opcode
);
15695 int imm2
= extract32(ctx
->opcode
, 6, 3);
15696 TCGv t0
= tcg_temp_new();
15697 TCGv t1
= tcg_temp_new();
15698 gen_load_gpr(t0
, rs
);
15699 gen_load_gpr(t1
, rt
);
15700 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
15701 tcg_gen_add_tl(t0
, t0
, t1
);
15702 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
15707 case OPC_MULT
... OPC_DIVU
:
15708 op2
= MASK_R6_MULDIV(ctx
->opcode
);
15718 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
15721 MIPS_INVAL("special_r6 muldiv");
15722 generate_exception(ctx
, EXCP_RI
);
15728 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
15732 if (rt
== 0 && sa
== 1) {
15733 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15734 We need additionally to check other fields */
15735 gen_cl(ctx
, op1
, rd
, rs
);
15737 generate_exception(ctx
, EXCP_RI
);
15741 generate_exception(ctx
, EXCP_DBp
);
15743 #if defined(TARGET_MIPS64)
15745 check_mips_64(ctx
);
15747 int imm2
= extract32(ctx
->opcode
, 6, 3);
15748 TCGv t0
= tcg_temp_new();
15749 TCGv t1
= tcg_temp_new();
15750 gen_load_gpr(t0
, rs
);
15751 gen_load_gpr(t1
, rt
);
15752 tcg_gen_shli_tl(t0
, t0
, imm2
+ 1);
15753 tcg_gen_add_tl(cpu_gpr
[rd
], t0
, t1
);
15760 if (rt
== 0 && sa
== 1) {
15761 /* Major opcode and function field is shared with preR6 MFHI/MTHI.
15762 We need additionally to check other fields */
15763 check_mips_64(ctx
);
15764 gen_cl(ctx
, op1
, rd
, rs
);
15766 generate_exception(ctx
, EXCP_RI
);
15769 case OPC_DMULT
... OPC_DDIVU
:
15770 op2
= MASK_R6_MULDIV(ctx
->opcode
);
15780 check_mips_64(ctx
);
15781 gen_r6_muldiv(ctx
, op2
, rd
, rs
, rt
);
15784 MIPS_INVAL("special_r6 muldiv");
15785 generate_exception(ctx
, EXCP_RI
);
15790 default: /* Invalid */
15791 MIPS_INVAL("special_r6");
15792 generate_exception(ctx
, EXCP_RI
);
15797 static void decode_opc_special_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
15799 int rs
, rt
, rd
, sa
;
15802 rs
= (ctx
->opcode
>> 21) & 0x1f;
15803 rt
= (ctx
->opcode
>> 16) & 0x1f;
15804 rd
= (ctx
->opcode
>> 11) & 0x1f;
15805 sa
= (ctx
->opcode
>> 6) & 0x1f;
15807 op1
= MASK_SPECIAL(ctx
->opcode
);
15809 case OPC_MOVN
: /* Conditional move */
15811 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
15812 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
15813 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
15815 case OPC_MFHI
: /* Move from HI/LO */
15817 gen_HILO(ctx
, op1
, rs
& 3, rd
);
15820 case OPC_MTLO
: /* Move to HI/LO */
15821 gen_HILO(ctx
, op1
, rd
& 3, rs
);
15824 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15825 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15826 check_cp1_enabled(ctx
);
15827 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
15828 (ctx
->opcode
>> 16) & 1);
15830 generate_exception_err(ctx
, EXCP_CpU
, 1);
15836 check_insn(ctx
, INSN_VR54XX
);
15837 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
15838 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
15840 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
15845 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
15847 #if defined(TARGET_MIPS64)
15848 case OPC_DMULT
... OPC_DDIVU
:
15849 check_insn(ctx
, ISA_MIPS3
);
15850 check_mips_64(ctx
);
15851 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
15855 #ifdef MIPS_STRICT_STANDARD
15856 MIPS_INVAL("SPIM");
15857 generate_exception(ctx
, EXCP_RI
);
15859 /* Implemented as RI exception for now. */
15860 MIPS_INVAL("spim (unofficial)");
15861 generate_exception(ctx
, EXCP_RI
);
15864 default: /* Invalid */
15865 MIPS_INVAL("special_legacy");
15866 generate_exception(ctx
, EXCP_RI
);
15871 static void decode_opc_special(CPUMIPSState
*env
, DisasContext
*ctx
)
15873 int rs
, rt
, rd
, sa
;
15876 rs
= (ctx
->opcode
>> 21) & 0x1f;
15877 rt
= (ctx
->opcode
>> 16) & 0x1f;
15878 rd
= (ctx
->opcode
>> 11) & 0x1f;
15879 sa
= (ctx
->opcode
>> 6) & 0x1f;
15881 op1
= MASK_SPECIAL(ctx
->opcode
);
15883 case OPC_SLL
: /* Shift with immediate */
15885 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15888 switch ((ctx
->opcode
>> 21) & 0x1f) {
15890 /* rotr is decoded as srl on non-R2 CPUs */
15891 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15896 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15899 generate_exception(ctx
, EXCP_RI
);
15903 case OPC_ADD
... OPC_SUBU
:
15904 gen_arith(ctx
, op1
, rd
, rs
, rt
);
15906 case OPC_SLLV
: /* Shifts */
15908 gen_shift(ctx
, op1
, rd
, rs
, rt
);
15911 switch ((ctx
->opcode
>> 6) & 0x1f) {
15913 /* rotrv is decoded as srlv on non-R2 CPUs */
15914 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15919 gen_shift(ctx
, op1
, rd
, rs
, rt
);
15922 generate_exception(ctx
, EXCP_RI
);
15926 case OPC_SLT
: /* Set on less than */
15928 gen_slt(ctx
, op1
, rd
, rs
, rt
);
15930 case OPC_AND
: /* Logic*/
15934 gen_logic(ctx
, op1
, rd
, rs
, rt
);
15936 case OPC_JR
... OPC_JALR
:
15937 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
15939 case OPC_TGE
... OPC_TEQ
: /* Traps */
15941 gen_trap(ctx
, op1
, rs
, rt
, -1);
15943 case OPC_LSA
: /* OPC_PMON */
15944 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
15945 decode_opc_special_r6(env
, ctx
);
15947 /* Pmon entry point, also R4010 selsl */
15948 #ifdef MIPS_STRICT_STANDARD
15949 MIPS_INVAL("PMON / selsl");
15950 generate_exception(ctx
, EXCP_RI
);
15952 gen_helper_0e0i(pmon
, sa
);
15957 generate_exception(ctx
, EXCP_SYSCALL
);
15958 ctx
->bstate
= BS_STOP
;
15961 generate_exception(ctx
, EXCP_BREAK
);
15964 /* Treat as NOP. */
15967 #if defined(TARGET_MIPS64)
15968 /* MIPS64 specific opcodes */
15973 check_insn(ctx
, ISA_MIPS3
);
15974 check_mips_64(ctx
);
15975 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15978 switch ((ctx
->opcode
>> 21) & 0x1f) {
15980 /* drotr is decoded as dsrl on non-R2 CPUs */
15981 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
15986 check_insn(ctx
, ISA_MIPS3
);
15987 check_mips_64(ctx
);
15988 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
15991 generate_exception(ctx
, EXCP_RI
);
15996 switch ((ctx
->opcode
>> 21) & 0x1f) {
15998 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
15999 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16004 check_insn(ctx
, ISA_MIPS3
);
16005 check_mips_64(ctx
);
16006 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
16009 generate_exception(ctx
, EXCP_RI
);
16013 case OPC_DADD
... OPC_DSUBU
:
16014 check_insn(ctx
, ISA_MIPS3
);
16015 check_mips_64(ctx
);
16016 gen_arith(ctx
, op1
, rd
, rs
, rt
);
16020 check_insn(ctx
, ISA_MIPS3
);
16021 check_mips_64(ctx
);
16022 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16025 switch ((ctx
->opcode
>> 6) & 0x1f) {
16027 /* drotrv is decoded as dsrlv on non-R2 CPUs */
16028 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
16033 check_insn(ctx
, ISA_MIPS3
);
16034 check_mips_64(ctx
);
16035 gen_shift(ctx
, op1
, rd
, rs
, rt
);
16038 generate_exception(ctx
, EXCP_RI
);
16044 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16045 decode_opc_special_r6(env
, ctx
);
16047 decode_opc_special_legacy(env
, ctx
);
16052 static void decode_opc_special2_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16057 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16059 rs
= (ctx
->opcode
>> 21) & 0x1f;
16060 rt
= (ctx
->opcode
>> 16) & 0x1f;
16061 rd
= (ctx
->opcode
>> 11) & 0x1f;
16063 op1
= MASK_SPECIAL2(ctx
->opcode
);
16065 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
16066 case OPC_MSUB
... OPC_MSUBU
:
16067 check_insn(ctx
, ISA_MIPS32
);
16068 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
16071 gen_arith(ctx
, op1
, rd
, rs
, rt
);
16074 case OPC_DIVU_G_2F
:
16075 case OPC_MULT_G_2F
:
16076 case OPC_MULTU_G_2F
:
16078 case OPC_MODU_G_2F
:
16079 check_insn(ctx
, INSN_LOONGSON2F
);
16080 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16084 check_insn(ctx
, ISA_MIPS32
);
16085 gen_cl(ctx
, op1
, rd
, rs
);
16088 /* XXX: not clear which exception should be raised
16089 * when in debug mode...
16091 check_insn(ctx
, ISA_MIPS32
);
16092 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
16093 generate_exception(ctx
, EXCP_DBp
);
16095 generate_exception(ctx
, EXCP_DBp
);
16097 /* Treat as NOP. */
16099 #if defined(TARGET_MIPS64)
16102 check_insn(ctx
, ISA_MIPS64
);
16103 check_mips_64(ctx
);
16104 gen_cl(ctx
, op1
, rd
, rs
);
16106 case OPC_DMULT_G_2F
:
16107 case OPC_DMULTU_G_2F
:
16108 case OPC_DDIV_G_2F
:
16109 case OPC_DDIVU_G_2F
:
16110 case OPC_DMOD_G_2F
:
16111 case OPC_DMODU_G_2F
:
16112 check_insn(ctx
, INSN_LOONGSON2F
);
16113 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16116 default: /* Invalid */
16117 MIPS_INVAL("special2_legacy");
16118 generate_exception(ctx
, EXCP_RI
);
16123 static void decode_opc_special3_r6(CPUMIPSState
*env
, DisasContext
*ctx
)
16125 int rs
, rt
, rd
, sa
;
16129 rs
= (ctx
->opcode
>> 21) & 0x1f;
16130 rt
= (ctx
->opcode
>> 16) & 0x1f;
16131 rd
= (ctx
->opcode
>> 11) & 0x1f;
16132 sa
= (ctx
->opcode
>> 6) & 0x1f;
16133 imm
= (int16_t)ctx
->opcode
>> 7;
16135 op1
= MASK_SPECIAL3(ctx
->opcode
);
16139 /* hint codes 24-31 are reserved and signal RI */
16140 generate_exception(ctx
, EXCP_RI
);
16142 /* Treat as NOP. */
16145 /* Treat as NOP. */
16148 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
16151 gen_ld(ctx
, op1
, rt
, rs
, imm
);
16156 /* Treat as NOP. */
16159 TCGv t0
= tcg_temp_new();
16160 gen_load_gpr(t0
, rt
);
16162 op2
= MASK_BSHFL(ctx
->opcode
);
16164 case OPC_ALIGN
... OPC_ALIGN_END
:
16167 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
16169 TCGv t1
= tcg_temp_new();
16170 TCGv_i64 t2
= tcg_temp_new_i64();
16171 gen_load_gpr(t1
, rs
);
16172 tcg_gen_concat_tl_i64(t2
, t1
, t0
);
16173 tcg_gen_shri_i64(t2
, t2
, 8 * (4 - sa
));
16174 #if defined(TARGET_MIPS64)
16175 tcg_gen_ext32s_i64(cpu_gpr
[rd
], t2
);
16177 tcg_gen_trunc_i64_i32(cpu_gpr
[rd
], t2
);
16179 tcg_temp_free_i64(t2
);
16184 gen_helper_bitswap(cpu_gpr
[rd
], t0
);
16190 #if defined(TARGET_MIPS64)
16192 gen_st_cond(ctx
, op1
, rt
, rs
, imm
);
16195 gen_ld(ctx
, op1
, rt
, rs
, imm
);
16198 check_mips_64(ctx
);
16201 /* Treat as NOP. */
16204 TCGv t0
= tcg_temp_new();
16205 gen_load_gpr(t0
, rt
);
16207 op2
= MASK_DBSHFL(ctx
->opcode
);
16209 case OPC_DALIGN
... OPC_DALIGN_END
:
16212 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
16214 TCGv t1
= tcg_temp_new();
16215 gen_load_gpr(t1
, rs
);
16216 tcg_gen_shli_tl(t0
, t0
, 8 * sa
);
16217 tcg_gen_shri_tl(t1
, t1
, 8 * (8 - sa
));
16218 tcg_gen_or_tl(cpu_gpr
[rd
], t1
, t0
);
16223 gen_helper_dbitswap(cpu_gpr
[rd
], t0
);
16230 default: /* Invalid */
16231 MIPS_INVAL("special3_r6");
16232 generate_exception(ctx
, EXCP_RI
);
16237 static void decode_opc_special3_legacy(CPUMIPSState
*env
, DisasContext
*ctx
)
16242 rs
= (ctx
->opcode
>> 21) & 0x1f;
16243 rt
= (ctx
->opcode
>> 16) & 0x1f;
16244 rd
= (ctx
->opcode
>> 11) & 0x1f;
16246 op1
= MASK_SPECIAL3(ctx
->opcode
);
16248 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
16249 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
16250 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
16251 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
16252 * the same mask and op1. */
16253 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
16254 op2
= MASK_ADDUH_QB(ctx
->opcode
);
16257 case OPC_ADDUH_R_QB
:
16259 case OPC_ADDQH_R_PH
:
16261 case OPC_ADDQH_R_W
:
16263 case OPC_SUBUH_R_QB
:
16265 case OPC_SUBQH_R_PH
:
16267 case OPC_SUBQH_R_W
:
16268 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16273 case OPC_MULQ_RS_W
:
16274 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16277 MIPS_INVAL("MASK ADDUH.QB");
16278 generate_exception(ctx
, EXCP_RI
);
16281 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
16282 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16284 generate_exception(ctx
, EXCP_RI
);
16288 op2
= MASK_LX(ctx
->opcode
);
16290 #if defined(TARGET_MIPS64)
16296 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
16298 default: /* Invalid */
16299 MIPS_INVAL("MASK LX");
16300 generate_exception(ctx
, EXCP_RI
);
16304 case OPC_ABSQ_S_PH_DSP
:
16305 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
16307 case OPC_ABSQ_S_QB
:
16308 case OPC_ABSQ_S_PH
:
16310 case OPC_PRECEQ_W_PHL
:
16311 case OPC_PRECEQ_W_PHR
:
16312 case OPC_PRECEQU_PH_QBL
:
16313 case OPC_PRECEQU_PH_QBR
:
16314 case OPC_PRECEQU_PH_QBLA
:
16315 case OPC_PRECEQU_PH_QBRA
:
16316 case OPC_PRECEU_PH_QBL
:
16317 case OPC_PRECEU_PH_QBR
:
16318 case OPC_PRECEU_PH_QBLA
:
16319 case OPC_PRECEU_PH_QBRA
:
16320 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16327 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
16330 MIPS_INVAL("MASK ABSQ_S.PH");
16331 generate_exception(ctx
, EXCP_RI
);
16335 case OPC_ADDU_QB_DSP
:
16336 op2
= MASK_ADDU_QB(ctx
->opcode
);
16339 case OPC_ADDQ_S_PH
:
16342 case OPC_ADDU_S_QB
:
16344 case OPC_ADDU_S_PH
:
16346 case OPC_SUBQ_S_PH
:
16349 case OPC_SUBU_S_QB
:
16351 case OPC_SUBU_S_PH
:
16355 case OPC_RADDU_W_QB
:
16356 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16358 case OPC_MULEU_S_PH_QBL
:
16359 case OPC_MULEU_S_PH_QBR
:
16360 case OPC_MULQ_RS_PH
:
16361 case OPC_MULEQ_S_W_PHL
:
16362 case OPC_MULEQ_S_W_PHR
:
16363 case OPC_MULQ_S_PH
:
16364 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16366 default: /* Invalid */
16367 MIPS_INVAL("MASK ADDU.QB");
16368 generate_exception(ctx
, EXCP_RI
);
16373 case OPC_CMPU_EQ_QB_DSP
:
16374 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
16376 case OPC_PRECR_SRA_PH_W
:
16377 case OPC_PRECR_SRA_R_PH_W
:
16378 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
16380 case OPC_PRECR_QB_PH
:
16381 case OPC_PRECRQ_QB_PH
:
16382 case OPC_PRECRQ_PH_W
:
16383 case OPC_PRECRQ_RS_PH_W
:
16384 case OPC_PRECRQU_S_QB_PH
:
16385 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16387 case OPC_CMPU_EQ_QB
:
16388 case OPC_CMPU_LT_QB
:
16389 case OPC_CMPU_LE_QB
:
16390 case OPC_CMP_EQ_PH
:
16391 case OPC_CMP_LT_PH
:
16392 case OPC_CMP_LE_PH
:
16393 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16395 case OPC_CMPGU_EQ_QB
:
16396 case OPC_CMPGU_LT_QB
:
16397 case OPC_CMPGU_LE_QB
:
16398 case OPC_CMPGDU_EQ_QB
:
16399 case OPC_CMPGDU_LT_QB
:
16400 case OPC_CMPGDU_LE_QB
:
16403 case OPC_PACKRL_PH
:
16404 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16406 default: /* Invalid */
16407 MIPS_INVAL("MASK CMPU.EQ.QB");
16408 generate_exception(ctx
, EXCP_RI
);
16412 case OPC_SHLL_QB_DSP
:
16413 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
16415 case OPC_DPA_W_PH_DSP
:
16416 op2
= MASK_DPA_W_PH(ctx
->opcode
);
16418 case OPC_DPAU_H_QBL
:
16419 case OPC_DPAU_H_QBR
:
16420 case OPC_DPSU_H_QBL
:
16421 case OPC_DPSU_H_QBR
:
16423 case OPC_DPAX_W_PH
:
16424 case OPC_DPAQ_S_W_PH
:
16425 case OPC_DPAQX_S_W_PH
:
16426 case OPC_DPAQX_SA_W_PH
:
16428 case OPC_DPSX_W_PH
:
16429 case OPC_DPSQ_S_W_PH
:
16430 case OPC_DPSQX_S_W_PH
:
16431 case OPC_DPSQX_SA_W_PH
:
16432 case OPC_MULSAQ_S_W_PH
:
16433 case OPC_DPAQ_SA_L_W
:
16434 case OPC_DPSQ_SA_L_W
:
16435 case OPC_MAQ_S_W_PHL
:
16436 case OPC_MAQ_S_W_PHR
:
16437 case OPC_MAQ_SA_W_PHL
:
16438 case OPC_MAQ_SA_W_PHR
:
16439 case OPC_MULSA_W_PH
:
16440 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16442 default: /* Invalid */
16443 MIPS_INVAL("MASK DPAW.PH");
16444 generate_exception(ctx
, EXCP_RI
);
16449 op2
= MASK_INSV(ctx
->opcode
);
16461 t0
= tcg_temp_new();
16462 t1
= tcg_temp_new();
16464 gen_load_gpr(t0
, rt
);
16465 gen_load_gpr(t1
, rs
);
16467 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
16473 default: /* Invalid */
16474 MIPS_INVAL("MASK INSV");
16475 generate_exception(ctx
, EXCP_RI
);
16479 case OPC_APPEND_DSP
:
16480 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
16482 case OPC_EXTR_W_DSP
:
16483 op2
= MASK_EXTR_W(ctx
->opcode
);
16487 case OPC_EXTR_RS_W
:
16489 case OPC_EXTRV_S_H
:
16491 case OPC_EXTRV_R_W
:
16492 case OPC_EXTRV_RS_W
:
16497 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
16500 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16506 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16508 default: /* Invalid */
16509 MIPS_INVAL("MASK EXTR.W");
16510 generate_exception(ctx
, EXCP_RI
);
16514 #if defined(TARGET_MIPS64)
16515 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
16516 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
16517 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
16518 check_insn(ctx
, INSN_LOONGSON2E
);
16519 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
16521 case OPC_ABSQ_S_QH_DSP
:
16522 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
16524 case OPC_PRECEQ_L_PWL
:
16525 case OPC_PRECEQ_L_PWR
:
16526 case OPC_PRECEQ_PW_QHL
:
16527 case OPC_PRECEQ_PW_QHR
:
16528 case OPC_PRECEQ_PW_QHLA
:
16529 case OPC_PRECEQ_PW_QHRA
:
16530 case OPC_PRECEQU_QH_OBL
:
16531 case OPC_PRECEQU_QH_OBR
:
16532 case OPC_PRECEQU_QH_OBLA
:
16533 case OPC_PRECEQU_QH_OBRA
:
16534 case OPC_PRECEU_QH_OBL
:
16535 case OPC_PRECEU_QH_OBR
:
16536 case OPC_PRECEU_QH_OBLA
:
16537 case OPC_PRECEU_QH_OBRA
:
16538 case OPC_ABSQ_S_OB
:
16539 case OPC_ABSQ_S_PW
:
16540 case OPC_ABSQ_S_QH
:
16541 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16549 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
16551 default: /* Invalid */
16552 MIPS_INVAL("MASK ABSQ_S.QH");
16553 generate_exception(ctx
, EXCP_RI
);
16557 case OPC_ADDU_OB_DSP
:
16558 op2
= MASK_ADDU_OB(ctx
->opcode
);
16560 case OPC_RADDU_L_OB
:
16562 case OPC_SUBQ_S_PW
:
16564 case OPC_SUBQ_S_QH
:
16566 case OPC_SUBU_S_OB
:
16568 case OPC_SUBU_S_QH
:
16570 case OPC_SUBUH_R_OB
:
16572 case OPC_ADDQ_S_PW
:
16574 case OPC_ADDQ_S_QH
:
16576 case OPC_ADDU_S_OB
:
16578 case OPC_ADDU_S_QH
:
16580 case OPC_ADDUH_R_OB
:
16581 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16583 case OPC_MULEQ_S_PW_QHL
:
16584 case OPC_MULEQ_S_PW_QHR
:
16585 case OPC_MULEU_S_QH_OBL
:
16586 case OPC_MULEU_S_QH_OBR
:
16587 case OPC_MULQ_RS_QH
:
16588 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16590 default: /* Invalid */
16591 MIPS_INVAL("MASK ADDU.OB");
16592 generate_exception(ctx
, EXCP_RI
);
16596 case OPC_CMPU_EQ_OB_DSP
:
16597 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
16599 case OPC_PRECR_SRA_QH_PW
:
16600 case OPC_PRECR_SRA_R_QH_PW
:
16601 /* Return value is rt. */
16602 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
16604 case OPC_PRECR_OB_QH
:
16605 case OPC_PRECRQ_OB_QH
:
16606 case OPC_PRECRQ_PW_L
:
16607 case OPC_PRECRQ_QH_PW
:
16608 case OPC_PRECRQ_RS_QH_PW
:
16609 case OPC_PRECRQU_S_OB_QH
:
16610 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
16612 case OPC_CMPU_EQ_OB
:
16613 case OPC_CMPU_LT_OB
:
16614 case OPC_CMPU_LE_OB
:
16615 case OPC_CMP_EQ_QH
:
16616 case OPC_CMP_LT_QH
:
16617 case OPC_CMP_LE_QH
:
16618 case OPC_CMP_EQ_PW
:
16619 case OPC_CMP_LT_PW
:
16620 case OPC_CMP_LE_PW
:
16621 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16623 case OPC_CMPGDU_EQ_OB
:
16624 case OPC_CMPGDU_LT_OB
:
16625 case OPC_CMPGDU_LE_OB
:
16626 case OPC_CMPGU_EQ_OB
:
16627 case OPC_CMPGU_LT_OB
:
16628 case OPC_CMPGU_LE_OB
:
16629 case OPC_PACKRL_PW
:
16633 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
16635 default: /* Invalid */
16636 MIPS_INVAL("MASK CMPU_EQ.OB");
16637 generate_exception(ctx
, EXCP_RI
);
16641 case OPC_DAPPEND_DSP
:
16642 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
16644 case OPC_DEXTR_W_DSP
:
16645 op2
= MASK_DEXTR_W(ctx
->opcode
);
16652 case OPC_DEXTR_R_L
:
16653 case OPC_DEXTR_RS_L
:
16655 case OPC_DEXTR_R_W
:
16656 case OPC_DEXTR_RS_W
:
16657 case OPC_DEXTR_S_H
:
16659 case OPC_DEXTRV_R_L
:
16660 case OPC_DEXTRV_RS_L
:
16661 case OPC_DEXTRV_S_H
:
16663 case OPC_DEXTRV_R_W
:
16664 case OPC_DEXTRV_RS_W
:
16665 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
16670 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16672 default: /* Invalid */
16673 MIPS_INVAL("MASK EXTR.W");
16674 generate_exception(ctx
, EXCP_RI
);
16678 case OPC_DPAQ_W_QH_DSP
:
16679 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
16681 case OPC_DPAU_H_OBL
:
16682 case OPC_DPAU_H_OBR
:
16683 case OPC_DPSU_H_OBL
:
16684 case OPC_DPSU_H_OBR
:
16686 case OPC_DPAQ_S_W_QH
:
16688 case OPC_DPSQ_S_W_QH
:
16689 case OPC_MULSAQ_S_W_QH
:
16690 case OPC_DPAQ_SA_L_PW
:
16691 case OPC_DPSQ_SA_L_PW
:
16692 case OPC_MULSAQ_S_L_PW
:
16693 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16695 case OPC_MAQ_S_W_QHLL
:
16696 case OPC_MAQ_S_W_QHLR
:
16697 case OPC_MAQ_S_W_QHRL
:
16698 case OPC_MAQ_S_W_QHRR
:
16699 case OPC_MAQ_SA_W_QHLL
:
16700 case OPC_MAQ_SA_W_QHLR
:
16701 case OPC_MAQ_SA_W_QHRL
:
16702 case OPC_MAQ_SA_W_QHRR
:
16703 case OPC_MAQ_S_L_PWL
:
16704 case OPC_MAQ_S_L_PWR
:
16709 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
16711 default: /* Invalid */
16712 MIPS_INVAL("MASK DPAQ.W.QH");
16713 generate_exception(ctx
, EXCP_RI
);
16717 case OPC_DINSV_DSP
:
16718 op2
= MASK_INSV(ctx
->opcode
);
16730 t0
= tcg_temp_new();
16731 t1
= tcg_temp_new();
16733 gen_load_gpr(t0
, rt
);
16734 gen_load_gpr(t1
, rs
);
16736 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
16742 default: /* Invalid */
16743 MIPS_INVAL("MASK DINSV");
16744 generate_exception(ctx
, EXCP_RI
);
16748 case OPC_SHLL_OB_DSP
:
16749 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
16752 default: /* Invalid */
16753 MIPS_INVAL("special3_legacy");
16754 generate_exception(ctx
, EXCP_RI
);
16759 static void decode_opc_special3(CPUMIPSState
*env
, DisasContext
*ctx
)
16761 int rs
, rt
, rd
, sa
;
16764 rs
= (ctx
->opcode
>> 21) & 0x1f;
16765 rt
= (ctx
->opcode
>> 16) & 0x1f;
16766 rd
= (ctx
->opcode
>> 11) & 0x1f;
16767 sa
= (ctx
->opcode
>> 6) & 0x1f;
16769 op1
= MASK_SPECIAL3(ctx
->opcode
);
16773 check_insn(ctx
, ISA_MIPS32R2
);
16774 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
16777 op2
= MASK_BSHFL(ctx
->opcode
);
16779 case OPC_ALIGN
... OPC_ALIGN_END
:
16781 check_insn(ctx
, ISA_MIPS32R6
);
16782 decode_opc_special3_r6(env
, ctx
);
16785 check_insn(ctx
, ISA_MIPS32R2
);
16786 gen_bshfl(ctx
, op2
, rt
, rd
);
16790 #if defined(TARGET_MIPS64)
16791 case OPC_DEXTM
... OPC_DEXT
:
16792 case OPC_DINSM
... OPC_DINS
:
16793 check_insn(ctx
, ISA_MIPS64R2
);
16794 check_mips_64(ctx
);
16795 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
16798 op2
= MASK_DBSHFL(ctx
->opcode
);
16800 case OPC_DALIGN
... OPC_DALIGN_END
:
16802 check_insn(ctx
, ISA_MIPS32R6
);
16803 decode_opc_special3_r6(env
, ctx
);
16806 check_insn(ctx
, ISA_MIPS64R2
);
16807 check_mips_64(ctx
);
16808 op2
= MASK_DBSHFL(ctx
->opcode
);
16809 gen_bshfl(ctx
, op2
, rt
, rd
);
16815 gen_rdhwr(ctx
, rt
, rd
);
16818 check_insn(ctx
, ASE_MT
);
16820 TCGv t0
= tcg_temp_new();
16821 TCGv t1
= tcg_temp_new();
16823 gen_load_gpr(t0
, rt
);
16824 gen_load_gpr(t1
, rs
);
16825 gen_helper_fork(t0
, t1
);
16831 check_insn(ctx
, ASE_MT
);
16833 TCGv t0
= tcg_temp_new();
16835 save_cpu_state(ctx
, 1);
16836 gen_load_gpr(t0
, rs
);
16837 gen_helper_yield(t0
, cpu_env
, t0
);
16838 gen_store_gpr(t0
, rd
);
16843 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
16844 decode_opc_special3_r6(env
, ctx
);
16846 decode_opc_special3_legacy(env
, ctx
);
16851 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
16854 int rs
, rt
, rd
, sa
;
16858 /* make sure instructions are on a word boundary */
16859 if (ctx
->pc
& 0x3) {
16860 env
->CP0_BadVAddr
= ctx
->pc
;
16861 generate_exception(ctx
, EXCP_AdEL
);
16865 /* Handle blikely not taken case */
16866 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
16867 int l1
= gen_new_label();
16869 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
16870 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
16871 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
16872 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
16876 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
16877 tcg_gen_debug_insn_start(ctx
->pc
);
16880 op
= MASK_OP_MAJOR(ctx
->opcode
);
16881 rs
= (ctx
->opcode
>> 21) & 0x1f;
16882 rt
= (ctx
->opcode
>> 16) & 0x1f;
16883 rd
= (ctx
->opcode
>> 11) & 0x1f;
16884 sa
= (ctx
->opcode
>> 6) & 0x1f;
16885 imm
= (int16_t)ctx
->opcode
;
16888 decode_opc_special(env
, ctx
);
16891 decode_opc_special2_legacy(env
, ctx
);
16894 decode_opc_special3(env
, ctx
);
16897 op1
= MASK_REGIMM(ctx
->opcode
);
16899 case OPC_BLTZL
: /* REGIMM branches */
16903 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16908 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
16910 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
16912 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
16913 gen_trap(ctx
, op1
, rs
, -1, imm
);
16916 check_insn(ctx
, ISA_MIPS32R2
);
16917 /* Treat as NOP. */
16919 case OPC_BPOSGE32
: /* MIPS DSP branch */
16920 #if defined(TARGET_MIPS64)
16924 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
16926 #if defined(TARGET_MIPS64)
16928 check_insn(ctx
, ISA_MIPS32R6
);
16929 check_mips_64(ctx
);
16931 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 32);
16933 MIPS_DEBUG("dahi %s, %04x", regnames
[rs
], imm
);
16936 check_insn(ctx
, ISA_MIPS32R6
);
16937 check_mips_64(ctx
);
16939 tcg_gen_addi_tl(cpu_gpr
[rs
], cpu_gpr
[rs
], (int64_t)imm
<< 48);
16941 MIPS_DEBUG("dati %s, %04x", regnames
[rs
], imm
);
16944 default: /* Invalid */
16945 MIPS_INVAL("regimm");
16946 generate_exception(ctx
, EXCP_RI
);
16951 check_cp0_enabled(ctx
);
16952 op1
= MASK_CP0(ctx
->opcode
);
16958 #if defined(TARGET_MIPS64)
16962 #ifndef CONFIG_USER_ONLY
16963 gen_cp0(env
, ctx
, op1
, rt
, rd
);
16964 #endif /* !CONFIG_USER_ONLY */
16966 case OPC_C0_FIRST
... OPC_C0_LAST
:
16967 #ifndef CONFIG_USER_ONLY
16968 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
16969 #endif /* !CONFIG_USER_ONLY */
16972 #ifndef CONFIG_USER_ONLY
16975 TCGv t0
= tcg_temp_new();
16977 op2
= MASK_MFMC0(ctx
->opcode
);
16980 check_insn(ctx
, ASE_MT
);
16981 gen_helper_dmt(t0
);
16982 gen_store_gpr(t0
, rt
);
16985 check_insn(ctx
, ASE_MT
);
16986 gen_helper_emt(t0
);
16987 gen_store_gpr(t0
, rt
);
16990 check_insn(ctx
, ASE_MT
);
16991 gen_helper_dvpe(t0
, cpu_env
);
16992 gen_store_gpr(t0
, rt
);
16995 check_insn(ctx
, ASE_MT
);
16996 gen_helper_evpe(t0
, cpu_env
);
16997 gen_store_gpr(t0
, rt
);
17000 check_insn(ctx
, ISA_MIPS32R2
);
17001 save_cpu_state(ctx
, 1);
17002 gen_helper_di(t0
, cpu_env
);
17003 gen_store_gpr(t0
, rt
);
17004 /* Stop translation as we may have switched the execution mode */
17005 ctx
->bstate
= BS_STOP
;
17008 check_insn(ctx
, ISA_MIPS32R2
);
17009 save_cpu_state(ctx
, 1);
17010 gen_helper_ei(t0
, cpu_env
);
17011 gen_store_gpr(t0
, rt
);
17012 /* Stop translation as we may have switched the execution mode */
17013 ctx
->bstate
= BS_STOP
;
17015 default: /* Invalid */
17016 MIPS_INVAL("mfmc0");
17017 generate_exception(ctx
, EXCP_RI
);
17022 #endif /* !CONFIG_USER_ONLY */
17025 check_insn(ctx
, ISA_MIPS32R2
);
17026 gen_load_srsgpr(rt
, rd
);
17029 check_insn(ctx
, ISA_MIPS32R2
);
17030 gen_store_srsgpr(rt
, rd
);
17034 generate_exception(ctx
, EXCP_RI
);
17038 case OPC_BOVC
: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
17039 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17040 /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
17041 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17044 /* Arithmetic with immediate opcode */
17045 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17049 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17051 case OPC_SLTI
: /* Set on less than with immediate opcode */
17053 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
17055 case OPC_ANDI
: /* Arithmetic with immediate opcode */
17056 case OPC_LUI
: /* OPC_AUI */
17059 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
17061 case OPC_J
... OPC_JAL
: /* Jump */
17062 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17063 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
17066 case OPC_BLEZC
: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
17067 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17069 generate_exception(ctx
, EXCP_RI
);
17072 /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
17073 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17076 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
17079 case OPC_BGTZC
: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
17080 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17082 generate_exception(ctx
, EXCP_RI
);
17085 /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
17086 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17089 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
17092 case OPC_BLEZALC
: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
17095 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
17097 check_insn(ctx
, ISA_MIPS32R6
);
17098 /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
17099 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17102 case OPC_BGTZALC
: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
17105 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
17107 check_insn(ctx
, ISA_MIPS32R6
);
17108 /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
17109 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17114 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17117 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
17119 case OPC_LWL
: /* Load and stores */
17122 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17123 case OPC_LB
... OPC_LH
:
17124 case OPC_LW
... OPC_LHU
:
17125 gen_ld(ctx
, op
, rt
, rs
, imm
);
17129 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17130 case OPC_SB
... OPC_SH
:
17132 gen_st(ctx
, op
, rt
, rs
, imm
);
17135 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17136 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
17139 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17140 check_cp0_enabled(ctx
);
17141 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
17142 /* Treat as NOP. */
17145 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17146 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
17147 /* Treat as NOP. */
17150 /* Floating point (COP1). */
17155 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
17159 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
17160 check_cp1_enabled(ctx
);
17161 op1
= MASK_CP1(ctx
->opcode
);
17165 check_insn(ctx
, ISA_MIPS32R2
);
17170 gen_cp1(ctx
, op1
, rt
, rd
);
17172 #if defined(TARGET_MIPS64)
17175 check_insn(ctx
, ISA_MIPS3
);
17176 gen_cp1(ctx
, op1
, rt
, rd
);
17179 case OPC_BC1EQZ
: /* OPC_BC1ANY2 */
17180 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17182 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
17187 check_insn(ctx
, ASE_MIPS3D
);
17188 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
17189 (rt
>> 2) & 0x7, imm
<< 2);
17193 check_insn(ctx
, ISA_MIPS32R6
);
17194 gen_compute_branch1_r6(ctx
, MASK_CP1(ctx
->opcode
),
17198 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17200 check_insn(ctx
, ASE_MIPS3D
);
17203 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17204 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
17205 (rt
>> 2) & 0x7, imm
<< 2);
17208 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17211 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
17217 int r6_op
= ctx
->opcode
& FOP(0x3f, 0x1f);
17218 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17220 case R6_OPC_CMP_AF_S
:
17221 case R6_OPC_CMP_UN_S
:
17222 case R6_OPC_CMP_EQ_S
:
17223 case R6_OPC_CMP_UEQ_S
:
17224 case R6_OPC_CMP_LT_S
:
17225 case R6_OPC_CMP_ULT_S
:
17226 case R6_OPC_CMP_LE_S
:
17227 case R6_OPC_CMP_ULE_S
:
17228 case R6_OPC_CMP_SAF_S
:
17229 case R6_OPC_CMP_SUN_S
:
17230 case R6_OPC_CMP_SEQ_S
:
17231 case R6_OPC_CMP_SEUQ_S
:
17232 case R6_OPC_CMP_SLT_S
:
17233 case R6_OPC_CMP_SULT_S
:
17234 case R6_OPC_CMP_SLE_S
:
17235 case R6_OPC_CMP_SULE_S
:
17236 case R6_OPC_CMP_OR_S
:
17237 case R6_OPC_CMP_UNE_S
:
17238 case R6_OPC_CMP_NE_S
:
17239 case R6_OPC_CMP_SOR_S
:
17240 case R6_OPC_CMP_SUNE_S
:
17241 case R6_OPC_CMP_SNE_S
:
17242 gen_r6_cmp_s(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
17244 case R6_OPC_CMP_AF_D
:
17245 case R6_OPC_CMP_UN_D
:
17246 case R6_OPC_CMP_EQ_D
:
17247 case R6_OPC_CMP_UEQ_D
:
17248 case R6_OPC_CMP_LT_D
:
17249 case R6_OPC_CMP_ULT_D
:
17250 case R6_OPC_CMP_LE_D
:
17251 case R6_OPC_CMP_ULE_D
:
17252 case R6_OPC_CMP_SAF_D
:
17253 case R6_OPC_CMP_SUN_D
:
17254 case R6_OPC_CMP_SEQ_D
:
17255 case R6_OPC_CMP_SEUQ_D
:
17256 case R6_OPC_CMP_SLT_D
:
17257 case R6_OPC_CMP_SULT_D
:
17258 case R6_OPC_CMP_SLE_D
:
17259 case R6_OPC_CMP_SULE_D
:
17260 case R6_OPC_CMP_OR_D
:
17261 case R6_OPC_CMP_UNE_D
:
17262 case R6_OPC_CMP_NE_D
:
17263 case R6_OPC_CMP_SOR_D
:
17264 case R6_OPC_CMP_SUNE_D
:
17265 case R6_OPC_CMP_SNE_D
:
17266 gen_r6_cmp_d(ctx
, ctx
->opcode
& 0x1f, rt
, rd
, sa
);
17269 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
17274 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
17281 generate_exception (ctx
, EXCP_RI
);
17285 generate_exception_err(ctx
, EXCP_CpU
, 1);
17289 /* Compact branches [R6] and COP2 [non-R6] */
17290 case OPC_BC
: /* OPC_LWC2 */
17291 case OPC_BALC
: /* OPC_SWC2 */
17292 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17293 /* OPC_BC, OPC_BALC */
17294 gen_compute_compact_branch(ctx
, op
, 0, 0,
17295 sextract32(ctx
->opcode
<< 2, 0, 28));
17297 /* OPC_LWC2, OPC_SWC2 */
17298 /* COP2: Not implemented. */
17299 generate_exception_err(ctx
, EXCP_CpU
, 2);
17302 case OPC_BEQZC
: /* OPC_JIC, OPC_LDC2 */
17303 case OPC_BNEZC
: /* OPC_JIALC, OPC_SDC2 */
17304 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17306 /* OPC_BEQZC, OPC_BNEZC */
17307 gen_compute_compact_branch(ctx
, op
, rs
, 0,
17308 sextract32(ctx
->opcode
<< 2, 0, 23));
17310 /* OPC_JIC, OPC_JIALC */
17311 gen_compute_compact_branch(ctx
, op
, 0, rt
, imm
);
17314 /* OPC_LWC2, OPC_SWC2 */
17315 /* COP2: Not implemented. */
17316 generate_exception_err(ctx
, EXCP_CpU
, 2);
17320 check_insn(ctx
, INSN_LOONGSON2F
);
17321 /* Note that these instructions use different fields. */
17322 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
17326 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17327 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
17328 check_cp1_enabled(ctx
);
17329 op1
= MASK_CP3(ctx
->opcode
);
17337 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
17340 /* Treat as NOP. */
17355 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
17359 generate_exception (ctx
, EXCP_RI
);
17363 generate_exception_err(ctx
, EXCP_CpU
, 1);
17367 #if defined(TARGET_MIPS64)
17368 /* MIPS64 opcodes */
17369 case OPC_LDL
... OPC_LDR
:
17371 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17374 check_insn(ctx
, ISA_MIPS3
);
17375 check_mips_64(ctx
);
17376 gen_ld(ctx
, op
, rt
, rs
, imm
);
17378 case OPC_SDL
... OPC_SDR
:
17379 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17381 check_insn(ctx
, ISA_MIPS3
);
17382 check_mips_64(ctx
);
17383 gen_st(ctx
, op
, rt
, rs
, imm
);
17386 check_insn_opc_removed(ctx
, ISA_MIPS32R6
);
17387 check_insn(ctx
, ISA_MIPS3
);
17388 check_mips_64(ctx
);
17389 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
17391 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
17392 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17393 /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
17394 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17397 check_insn(ctx
, ISA_MIPS3
);
17398 check_mips_64(ctx
);
17399 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17403 check_insn(ctx
, ISA_MIPS3
);
17404 check_mips_64(ctx
);
17405 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
17408 case OPC_BNVC
: /* OPC_BNEZALC, OPC_BNEC */
17409 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17410 gen_compute_compact_branch(ctx
, op
, rs
, rt
, imm
<< 2);
17412 MIPS_INVAL("major opcode");
17413 generate_exception(ctx
, EXCP_RI
);
17417 case OPC_DAUI
: /* OPC_JALX */
17418 if (ctx
->insn_flags
& ISA_MIPS32R6
) {
17419 #if defined(TARGET_MIPS64)
17421 check_mips_64(ctx
);
17423 TCGv t0
= tcg_temp_new();
17424 gen_load_gpr(t0
, rs
);
17425 tcg_gen_addi_tl(cpu_gpr
[rt
], t0
, imm
<< 16);
17428 MIPS_DEBUG("daui %s, %s, %04x", regnames
[rt
], regnames
[rs
], imm
);
17430 generate_exception(ctx
, EXCP_RI
);
17431 MIPS_INVAL("major opcode");
17435 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
17436 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
17437 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
17441 check_insn(ctx
, ASE_MDMX
);
17442 /* MDMX: Not implemented. */
17445 check_insn(ctx
, ISA_MIPS32R6
);
17446 gen_pcrel(ctx
, rs
, imm
);
17448 default: /* Invalid */
17449 MIPS_INVAL("major opcode");
17450 generate_exception(ctx
, EXCP_RI
);
17456 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
17459 CPUState
*cs
= CPU(cpu
);
17460 CPUMIPSState
*env
= &cpu
->env
;
17462 target_ulong pc_start
;
17463 uint16_t *gen_opc_end
;
17472 qemu_log("search pc %d\n", search_pc
);
17475 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
17478 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
17479 ctx
.insn_flags
= env
->insn_flags
;
17480 ctx
.CP0_Config1
= env
->CP0_Config1
;
17482 ctx
.bstate
= BS_NONE
;
17483 /* Restore delay slot state from the tb context. */
17484 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
17485 ctx
.ulri
= env
->CP0_Config3
& (1 << CP0C3_ULRI
);
17486 restore_cpu_state(env
, &ctx
);
17487 #ifdef CONFIG_USER_ONLY
17488 ctx
.mem_idx
= MIPS_HFLAG_UM
;
17490 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
17493 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
17494 if (max_insns
== 0)
17495 max_insns
= CF_COUNT_MASK
;
17496 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
17498 while (ctx
.bstate
== BS_NONE
) {
17499 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
17500 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
17501 if (bp
->pc
== ctx
.pc
) {
17502 save_cpu_state(&ctx
, 1);
17503 ctx
.bstate
= BS_BRANCH
;
17504 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
17505 /* Include the breakpoint location or the tb won't
17506 * be flushed when it must be. */
17508 goto done_generating
;
17514 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
17518 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
17520 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
17521 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
17522 gen_opc_btarget
[lj
] = ctx
.btarget
;
17523 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
17524 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
17526 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
17529 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
17530 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
17531 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
17533 decode_opc(env
, &ctx
);
17534 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
17535 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
17536 insn_bytes
= decode_micromips_opc(env
, &ctx
);
17537 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
17538 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
17539 insn_bytes
= decode_mips16_opc(env
, &ctx
);
17541 generate_exception(&ctx
, EXCP_RI
);
17542 ctx
.bstate
= BS_STOP
;
17547 gen_branch(&ctx
, insn_bytes
);
17549 ctx
.pc
+= insn_bytes
;
17553 /* Execute a branch and its delay slot as a single instruction.
17554 This is what GDB expects and is consistent with what the
17555 hardware does (e.g. if a delay slot instruction faults, the
17556 reported PC is the PC of the branch). */
17557 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
17561 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
17564 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
17568 if (num_insns
>= max_insns
)
17574 if (tb
->cflags
& CF_LAST_IO
) {
17577 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
17578 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
17579 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
17581 switch (ctx
.bstate
) {
17583 gen_goto_tb(&ctx
, 0, ctx
.pc
);
17586 save_cpu_state(&ctx
, 0);
17587 gen_goto_tb(&ctx
, 0, ctx
.pc
);
17590 tcg_gen_exit_tb(0);
17598 gen_tb_end(tb
, num_insns
);
17599 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
17601 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
17604 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
17606 tb
->size
= ctx
.pc
- pc_start
;
17607 tb
->icount
= num_insns
;
17611 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
17612 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
17613 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
17619 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
17621 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
17624 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
17626 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
17629 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
17633 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
17635 #define printfpr(fp) \
17638 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17639 " fd:%13g fs:%13g psu: %13g\n", \
17640 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
17641 (double)(fp)->fd, \
17642 (double)(fp)->fs[FP_ENDIAN_IDX], \
17643 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
17646 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
17647 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
17648 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
17649 " fd:%13g fs:%13g psu:%13g\n", \
17650 tmp.w[FP_ENDIAN_IDX], tmp.d, \
17652 (double)tmp.fs[FP_ENDIAN_IDX], \
17653 (double)tmp.fs[!FP_ENDIAN_IDX]); \
17658 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
17659 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
17660 get_float_exception_flags(&env
->active_fpu
.fp_status
));
17661 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
17662 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
17663 printfpr(&env
->active_fpu
.fpr
[i
]);
17669 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
17670 /* Debug help: The architecture requires 32bit code to maintain proper
17671 sign-extended values on 64bit machines. */
17673 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
17676 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
17677 fprintf_function cpu_fprintf
,
17682 if (!SIGN_EXT_P(env
->active_tc
.PC
))
17683 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
17684 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
17685 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
17686 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
17687 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
17688 if (!SIGN_EXT_P(env
->btarget
))
17689 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
17691 for (i
= 0; i
< 32; i
++) {
17692 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
17693 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
17696 if (!SIGN_EXT_P(env
->CP0_EPC
))
17697 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
17698 if (!SIGN_EXT_P(env
->lladdr
))
17699 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
17703 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
17706 MIPSCPU
*cpu
= MIPS_CPU(cs
);
17707 CPUMIPSState
*env
= &cpu
->env
;
17710 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
17711 " LO=0x" TARGET_FMT_lx
" ds %04x "
17712 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
17713 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
17714 env
->hflags
, env
->btarget
, env
->bcond
);
17715 for (i
= 0; i
< 32; i
++) {
17717 cpu_fprintf(f
, "GPR%02d:", i
);
17718 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
17720 cpu_fprintf(f
, "\n");
17723 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
17724 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
17725 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
17726 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
17727 if (env
->hflags
& MIPS_HFLAG_FPU
)
17728 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
17729 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
17730 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
17734 void mips_tcg_init(void)
17739 /* Initialize various static tables. */
17743 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
17744 TCGV_UNUSED(cpu_gpr
[0]);
17745 for (i
= 1; i
< 32; i
++)
17746 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
17747 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
17750 for (i
= 0; i
< 32; i
++) {
17751 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
17752 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
17755 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
17756 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
17757 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
17758 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
17759 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
17761 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
17762 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
17764 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
17765 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
17768 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
17769 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
17771 bcond
= tcg_global_mem_new(TCG_AREG0
,
17772 offsetof(CPUMIPSState
, bcond
), "bcond");
17773 btarget
= tcg_global_mem_new(TCG_AREG0
,
17774 offsetof(CPUMIPSState
, btarget
), "btarget");
17775 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
17776 offsetof(CPUMIPSState
, hflags
), "hflags");
17778 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
17779 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
17781 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
17782 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
17788 #include "translate_init.c"
17790 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
17794 const mips_def_t
*def
;
17796 def
= cpu_mips_find_by_name(cpu_model
);
17799 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
17801 env
->cpu_model
= def
;
17803 #ifndef CONFIG_USER_ONLY
17804 mmu_init(env
, def
);
17806 fpu_init(env
, def
);
17807 mvp_init(env
, def
);
17809 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
17814 void cpu_state_reset(CPUMIPSState
*env
)
17816 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
17817 CPUState
*cs
= CPU(cpu
);
17819 /* Reset registers to their default values */
17820 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
17821 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
17822 #ifdef TARGET_WORDS_BIGENDIAN
17823 env
->CP0_Config0
|= (1 << CP0C0_BE
);
17825 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
17826 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
17827 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
17828 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
17829 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
17830 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
17831 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
17832 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
17833 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
17834 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
17835 << env
->cpu_model
->CP0_LLAddr_shift
;
17836 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
17837 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
17838 env
->CCRes
= env
->cpu_model
->CCRes
;
17839 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
17840 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
17841 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
17842 env
->current_tc
= 0;
17843 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
17844 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
17845 #if defined(TARGET_MIPS64)
17846 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
17847 env
->SEGMask
|= 3ULL << 62;
17850 env
->PABITS
= env
->cpu_model
->PABITS
;
17851 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
17852 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
17853 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
17854 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
17855 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
17856 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
17857 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
17858 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
17859 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
17860 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
17861 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
17862 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
17863 env
->insn_flags
= env
->cpu_model
->insn_flags
;
17865 #if defined(CONFIG_USER_ONLY)
17866 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
17867 # ifdef TARGET_MIPS64
17868 /* Enable 64-bit register mode. */
17869 env
->CP0_Status
|= (1 << CP0St_PX
);
17871 # ifdef TARGET_ABI_MIPSN64
17872 /* Enable 64-bit address mode. */
17873 env
->CP0_Status
|= (1 << CP0St_UX
);
17875 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
17876 hardware registers. */
17877 env
->CP0_HWREna
|= 0x0000000F;
17878 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
17879 env
->CP0_Status
|= (1 << CP0St_CU1
);
17881 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
17882 env
->CP0_Status
|= (1 << CP0St_MX
);
17884 # if defined(TARGET_MIPS64)
17885 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
17886 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
17887 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
17888 env
->CP0_Status
|= (1 << CP0St_FR
);
17892 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
17893 /* If the exception was raised from a delay slot,
17894 come back to the jump. */
17895 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
17897 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
17899 env
->active_tc
.PC
= (int32_t)0xBFC00000;
17900 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
17901 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
17902 env
->CP0_Wired
= 0;
17903 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
17904 if (kvm_enabled()) {
17905 env
->CP0_EBase
|= 0x40000000;
17907 env
->CP0_EBase
|= 0x80000000;
17909 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
17910 /* vectored interrupts not implemented, timer on int 7,
17911 no performance counters. */
17912 env
->CP0_IntCtl
= 0xe0000000;
17916 for (i
= 0; i
< 7; i
++) {
17917 env
->CP0_WatchLo
[i
] = 0;
17918 env
->CP0_WatchHi
[i
] = 0x80000000;
17920 env
->CP0_WatchLo
[7] = 0;
17921 env
->CP0_WatchHi
[7] = 0;
17923 /* Count register increments in debug mode, EJTAG version 1 */
17924 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
17926 cpu_mips_store_count(env
, 1);
17928 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
17931 /* Only TC0 on VPE 0 starts as active. */
17932 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
17933 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
17934 env
->tcs
[i
].CP0_TCHalt
= 1;
17936 env
->active_tc
.CP0_TCHalt
= 1;
17939 if (cs
->cpu_index
== 0) {
17940 /* VPE0 starts up enabled. */
17941 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
17942 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
17944 /* TC0 starts up unhalted. */
17946 env
->active_tc
.CP0_TCHalt
= 0;
17947 env
->tcs
[0].CP0_TCHalt
= 0;
17948 /* With thread 0 active. */
17949 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
17950 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
17954 if ((env
->insn_flags
& ISA_MIPS32R6
) &&
17955 (env
->active_fpu
.fcr0
& (1 << FCR0_F64
))) {
17956 /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
17957 env
->CP0_Status
|= (1 << CP0St_FR
);
17960 compute_hflags(env
);
17961 cs
->exception_index
= EXCP_NONE
;
17964 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
17966 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
17967 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
17968 env
->hflags
|= gen_opc_hflags
[pc_pos
];
17969 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
17970 case MIPS_HFLAG_BR
:
17972 case MIPS_HFLAG_BC
:
17973 case MIPS_HFLAG_BL
:
17975 env
->btarget
= gen_opc_btarget
[pc_pos
];