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"
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
39 /* indirect opcode tables */
40 OPC_SPECIAL
= (0x00 << 26),
41 OPC_REGIMM
= (0x01 << 26),
42 OPC_CP0
= (0x10 << 26),
43 OPC_CP1
= (0x11 << 26),
44 OPC_CP2
= (0x12 << 26),
45 OPC_CP3
= (0x13 << 26),
46 OPC_SPECIAL2
= (0x1C << 26),
47 OPC_SPECIAL3
= (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI
= (0x08 << 26),
50 OPC_ADDIU
= (0x09 << 26),
51 OPC_SLTI
= (0x0A << 26),
52 OPC_SLTIU
= (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI
= (0x0C << 26),
55 OPC_ORI
= (0x0D << 26),
56 OPC_XORI
= (0x0E << 26),
57 OPC_LUI
= (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI
= (0x18 << 26),
60 OPC_DADDIU
= (0x19 << 26),
61 /* Jump and branches */
63 OPC_JAL
= (0x03 << 26),
64 OPC_JALS
= OPC_JAL
| 0x5,
65 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL
= (0x14 << 26),
67 OPC_BNE
= (0x05 << 26),
68 OPC_BNEL
= (0x15 << 26),
69 OPC_BLEZ
= (0x06 << 26),
70 OPC_BLEZL
= (0x16 << 26),
71 OPC_BGTZ
= (0x07 << 26),
72 OPC_BGTZL
= (0x17 << 26),
73 OPC_JALX
= (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS
= OPC_JALX
| 0x5,
76 OPC_LDL
= (0x1A << 26),
77 OPC_LDR
= (0x1B << 26),
78 OPC_LB
= (0x20 << 26),
79 OPC_LH
= (0x21 << 26),
80 OPC_LWL
= (0x22 << 26),
81 OPC_LW
= (0x23 << 26),
82 OPC_LWPC
= OPC_LW
| 0x5,
83 OPC_LBU
= (0x24 << 26),
84 OPC_LHU
= (0x25 << 26),
85 OPC_LWR
= (0x26 << 26),
86 OPC_LWU
= (0x27 << 26),
87 OPC_SB
= (0x28 << 26),
88 OPC_SH
= (0x29 << 26),
89 OPC_SWL
= (0x2A << 26),
90 OPC_SW
= (0x2B << 26),
91 OPC_SDL
= (0x2C << 26),
92 OPC_SDR
= (0x2D << 26),
93 OPC_SWR
= (0x2E << 26),
94 OPC_LL
= (0x30 << 26),
95 OPC_LLD
= (0x34 << 26),
96 OPC_LD
= (0x37 << 26),
97 OPC_LDPC
= OPC_LD
| 0x5,
98 OPC_SC
= (0x38 << 26),
99 OPC_SCD
= (0x3C << 26),
100 OPC_SD
= (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1
= (0x31 << 26),
103 OPC_LWC2
= (0x32 << 26),
104 OPC_LDC1
= (0x35 << 26),
105 OPC_LDC2
= (0x36 << 26),
106 OPC_SWC1
= (0x39 << 26),
107 OPC_SWC2
= (0x3A << 26),
108 OPC_SDC1
= (0x3D << 26),
109 OPC_SDC2
= (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX
= (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE
= (0x2F << 26),
114 OPC_PREF
= (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED
= (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124 OPC_SLL
= 0x00 | OPC_SPECIAL
,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
129 OPC_ROTR
= OPC_SRL
| (1 << 21),
130 OPC_SRA
= 0x03 | OPC_SPECIAL
,
131 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
132 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
133 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
134 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
135 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
136 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
137 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
138 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
139 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
140 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
141 OPC_DROTR
= OPC_DSRL
| (1 << 21),
142 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
143 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
144 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
145 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
146 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
147 /* Multiplication / division */
148 OPC_MULT
= 0x18 | OPC_SPECIAL
,
149 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
150 OPC_DIV
= 0x1A | OPC_SPECIAL
,
151 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
152 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
153 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
154 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
155 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD
= 0x20 | OPC_SPECIAL
,
158 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
159 OPC_SUB
= 0x22 | OPC_SPECIAL
,
160 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
161 OPC_AND
= 0x24 | OPC_SPECIAL
,
162 OPC_OR
= 0x25 | OPC_SPECIAL
,
163 OPC_XOR
= 0x26 | OPC_SPECIAL
,
164 OPC_NOR
= 0x27 | OPC_SPECIAL
,
165 OPC_SLT
= 0x2A | OPC_SPECIAL
,
166 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
167 OPC_DADD
= 0x2C | OPC_SPECIAL
,
168 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
169 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
170 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
172 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
173 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
174 OPC_JALRC
= OPC_JALR
| (0x5 << 6),
175 OPC_JALRS
= 0x10 | OPC_SPECIAL
| (0x5 << 6),
177 OPC_TGE
= 0x30 | OPC_SPECIAL
,
178 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
179 OPC_TLT
= 0x32 | OPC_SPECIAL
,
180 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
181 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
182 OPC_TNE
= 0x36 | OPC_SPECIAL
,
183 /* HI / LO registers load & stores */
184 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
185 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
186 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
187 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
188 /* Conditional moves */
189 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
190 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
192 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
195 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
196 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
197 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
198 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
199 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
201 OPC_SPECIAL15_RESERVED
= 0x15 | OPC_SPECIAL
,
202 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
203 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
204 OPC_SPECIAL35_RESERVED
= 0x35 | OPC_SPECIAL
,
205 OPC_SPECIAL37_RESERVED
= 0x37 | OPC_SPECIAL
,
206 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
207 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
214 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
215 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
216 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
217 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
218 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
219 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
220 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
221 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
222 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
223 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
224 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
225 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
226 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
227 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
234 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
235 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
236 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
237 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
238 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
239 OPC_BLTZALS
= OPC_BLTZAL
| 0x5, /* microMIPS */
240 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
241 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
242 OPC_BGEZALS
= OPC_BGEZAL
| 0x5, /* microMIPS */
243 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
244 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
245 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
246 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
247 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
248 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
249 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
250 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
257 /* Multiply & xxx operations */
258 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
259 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
260 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
261 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
262 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
264 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
265 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
266 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
267 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
268 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
269 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
270 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
271 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
272 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
273 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
274 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
275 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
277 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
278 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
279 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
280 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
282 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
289 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
290 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
291 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
292 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
293 OPC_INS
= 0x04 | OPC_SPECIAL3
,
294 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
295 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
296 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
297 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
298 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
299 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
300 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
301 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
304 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
305 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
306 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
307 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
308 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
309 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
310 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
311 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
312 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
313 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
314 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
315 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
318 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
321 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
322 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
323 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
327 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
330 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
335 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
338 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
339 /* MIPS DSP Append Sub-class */
340 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
341 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
344 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
352 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
353 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
361 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
367 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
374 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
375 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
376 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
383 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
384 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
385 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
386 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
387 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
388 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
389 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
390 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
391 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
392 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
393 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
394 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
395 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
396 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
397 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
398 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
399 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
402 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
403 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
404 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
405 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
406 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
414 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
415 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
416 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
417 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
418 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
419 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
420 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
421 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
422 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
423 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
424 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
427 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
428 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
429 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
436 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
437 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
438 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
439 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
440 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
441 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
442 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
443 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
444 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
445 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
446 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
447 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
450 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
451 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
452 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
453 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
460 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
461 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
462 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
463 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
464 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
465 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
468 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
469 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
470 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
471 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
472 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
473 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
474 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
475 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
476 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
477 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
478 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
479 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
480 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
481 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
488 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
489 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
490 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
491 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
492 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
493 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
494 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
495 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
496 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
497 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
498 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
499 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
500 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
501 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
502 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
503 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
504 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
505 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
506 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
507 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
508 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
515 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
516 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
517 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
518 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
519 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
520 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
521 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
522 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
523 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
524 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
525 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
526 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
527 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
528 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
529 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
530 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
531 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
532 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
533 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
534 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
535 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Append Sub-class */
547 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
548 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
549 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
556 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
557 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
558 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
559 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
560 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
561 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
562 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
563 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
564 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
565 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
566 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
567 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
568 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
569 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
570 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
571 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
578 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
579 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
580 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
581 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
582 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
583 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
584 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
585 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
586 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
587 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
588 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
589 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
590 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
591 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
592 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
593 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
596 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
597 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
598 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
599 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
600 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
607 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
608 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
609 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
610 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
613 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
614 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
615 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
616 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
617 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
618 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
619 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
620 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
621 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
622 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
623 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
624 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
625 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
626 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
627 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
628 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
629 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
630 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
631 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
632 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
639 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
640 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
641 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
642 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
643 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
644 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
645 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
646 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
647 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
648 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
649 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
650 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
651 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
652 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
653 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
654 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
655 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
656 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
659 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
660 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
661 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
662 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
663 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
664 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
665 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Append Sub-class */
671 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
672 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
673 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
674 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
681 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
682 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
683 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
684 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
685 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
686 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
687 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
688 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
689 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
690 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
691 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
692 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
693 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
694 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
695 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
696 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
697 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
698 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
699 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
700 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
713 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
714 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
715 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
716 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
717 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
718 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
719 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
720 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
721 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
722 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
723 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
724 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
725 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
726 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
727 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
728 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
729 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
730 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
731 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
732 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
733 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
734 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
735 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
736 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
737 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
744 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
745 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
746 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
747 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
748 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
749 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
750 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
751 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
752 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
753 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
754 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
755 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
756 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
757 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
758 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
759 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
760 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
761 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
762 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
763 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
764 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
765 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
766 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
767 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
768 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
776 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
777 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
778 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
779 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
780 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
781 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
782 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
783 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
784 OPC_C0
= (0x10 << 21) | OPC_CP0
,
785 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
786 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
794 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
795 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
796 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
797 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
798 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR
= 0x01 | OPC_C0
,
806 OPC_TLBWI
= 0x02 | OPC_C0
,
807 OPC_TLBWR
= 0x06 | OPC_C0
,
808 OPC_TLBP
= 0x08 | OPC_C0
,
809 OPC_RFE
= 0x10 | OPC_C0
,
810 OPC_ERET
= 0x18 | OPC_C0
,
811 OPC_DERET
= 0x1F | OPC_C0
,
812 OPC_WAIT
= 0x20 | OPC_C0
,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S
= 16, /* single fp */
822 FMT_D
= 17, /* double fp */
823 FMT_E
= 18, /* extended fp */
824 FMT_Q
= 19, /* quad fp */
825 FMT_W
= 20, /* 32-bit fixed */
826 FMT_L
= 21, /* 64-bit fixed */
827 FMT_PS
= 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
833 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
834 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
835 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
836 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
837 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
838 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
839 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
840 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
841 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
842 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
843 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
844 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
845 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
846 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
847 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
848 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
849 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
857 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
858 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
859 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
863 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
864 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
868 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
869 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
876 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
877 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
878 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
879 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
880 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
881 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
882 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
883 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
890 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
891 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
892 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
893 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
894 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
895 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
896 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
898 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
899 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
900 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
901 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
902 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
903 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
904 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
905 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
907 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
908 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
909 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
910 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
911 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
912 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
913 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
914 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
916 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
917 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
918 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
919 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
920 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
921 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
922 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
923 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
925 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
926 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
927 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
928 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
929 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
930 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
932 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
933 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
934 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
935 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
936 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
937 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
939 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
940 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
941 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
942 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
943 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
944 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
946 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
947 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
948 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
949 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
950 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
951 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
953 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
954 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
955 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
956 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
957 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
958 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
960 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
961 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
962 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
963 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
964 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
965 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
967 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
968 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
969 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
970 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
971 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
972 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
974 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
975 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
976 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
977 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
978 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
979 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1
= 0x00 | OPC_CP3
,
987 OPC_LDXC1
= 0x01 | OPC_CP3
,
988 OPC_LUXC1
= 0x05 | OPC_CP3
,
989 OPC_SWXC1
= 0x08 | OPC_CP3
,
990 OPC_SDXC1
= 0x09 | OPC_CP3
,
991 OPC_SUXC1
= 0x0D | OPC_CP3
,
992 OPC_PREFX
= 0x0F | OPC_CP3
,
993 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
994 OPC_MADD_S
= 0x20 | OPC_CP3
,
995 OPC_MADD_D
= 0x21 | OPC_CP3
,
996 OPC_MADD_PS
= 0x26 | OPC_CP3
,
997 OPC_MSUB_S
= 0x28 | OPC_CP3
,
998 OPC_MSUB_D
= 0x29 | OPC_CP3
,
999 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1000 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1001 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1002 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1003 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1004 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1005 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env
;
1010 static TCGv cpu_gpr
[32], cpu_PC
;
1011 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
], cpu_ACX
[MIPS_DSP_ACC
];
1012 static TCGv cpu_dspctrl
, btarget
, bcond
;
1013 static TCGv_i32 hflags
;
1014 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1015 static TCGv_i64 fpu_f64
[32];
1017 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1018 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1020 #include "exec/gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext
{
1065 struct TranslationBlock
*tb
;
1066 target_ulong pc
, saved_pc
;
1068 int singlestep_enabled
;
1070 /* Routine used to access memory */
1072 uint32_t hflags
, saved_hflags
;
1074 target_ulong btarget
;
1078 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1079 * exception condition */
1080 BS_STOP
= 1, /* We want to stop translation for any reason */
1081 BS_BRANCH
= 2, /* We reached a branch condition */
1082 BS_EXCP
= 3, /* We reached an exception condition */
1085 static const char * const regnames
[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1092 static const char * const regnames_HI
[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1096 static const char * const regnames_LO
[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1100 static const char * const regnames_ACX
[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1104 static const char * const fregnames
[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1111 #define MIPS_DEBUG(fmt, ...) \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1120 #define LOG_DISAS(...) \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1127 #define MIPS_INVAL(op) \
1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1131 /* General purpose registers moves. */
1132 static inline void gen_load_gpr (TCGv t
, int reg
)
1135 tcg_gen_movi_tl(t
, 0);
1137 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1140 static inline void gen_store_gpr (TCGv t
, int reg
)
1143 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1146 /* Moves to/from ACX register. */
1147 static inline void gen_load_ACX (TCGv t
, int reg
)
1149 tcg_gen_mov_tl(t
, cpu_ACX
[reg
]);
1152 static inline void gen_store_ACX (TCGv t
, int reg
)
1154 tcg_gen_mov_tl(cpu_ACX
[reg
], t
);
1157 /* Moves to/from shadow registers. */
1158 static inline void gen_load_srsgpr (int from
, int to
)
1160 TCGv t0
= tcg_temp_new();
1163 tcg_gen_movi_tl(t0
, 0);
1165 TCGv_i32 t2
= tcg_temp_new_i32();
1166 TCGv_ptr addr
= tcg_temp_new_ptr();
1168 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1169 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1170 tcg_gen_andi_i32(t2
, t2
, 0xf);
1171 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1172 tcg_gen_ext_i32_ptr(addr
, t2
);
1173 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1175 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1176 tcg_temp_free_ptr(addr
);
1177 tcg_temp_free_i32(t2
);
1179 gen_store_gpr(t0
, to
);
1183 static inline void gen_store_srsgpr (int from
, int to
)
1186 TCGv t0
= tcg_temp_new();
1187 TCGv_i32 t2
= tcg_temp_new_i32();
1188 TCGv_ptr addr
= tcg_temp_new_ptr();
1190 gen_load_gpr(t0
, from
);
1191 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1192 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1193 tcg_gen_andi_i32(t2
, t2
, 0xf);
1194 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1195 tcg_gen_ext_i32_ptr(addr
, t2
);
1196 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1198 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1199 tcg_temp_free_ptr(addr
);
1200 tcg_temp_free_i32(t2
);
1205 /* Floating point register moves. */
1206 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1208 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1211 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1213 TCGv_i64 t64
= tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64
, t
);
1215 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1216 tcg_temp_free_i64(t64
);
1219 static void gen_load_fpr32h(TCGv_i32 t
, int reg
)
1221 TCGv_i64 t64
= tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1223 tcg_gen_trunc_i64_i32(t
, t64
);
1224 tcg_temp_free_i64(t64
);
1227 static void gen_store_fpr32h(TCGv_i32 t
, int reg
)
1229 TCGv_i64 t64
= tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64
, t
);
1231 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1232 tcg_temp_free_i64(t64
);
1235 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1237 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1238 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1240 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1244 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1246 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1247 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1250 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1251 t0
= tcg_temp_new_i64();
1252 tcg_gen_shri_i64(t0
, t
, 32);
1253 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1254 tcg_temp_free_i64(t0
);
1258 static inline int get_fp_bit (int cc
)
1267 static inline void gen_save_pc(target_ulong pc
)
1269 tcg_gen_movi_tl(cpu_PC
, pc
);
1272 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1274 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1275 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1276 gen_save_pc(ctx
->pc
);
1277 ctx
->saved_pc
= ctx
->pc
;
1279 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1280 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1281 ctx
->saved_hflags
= ctx
->hflags
;
1282 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1288 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1294 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1296 ctx
->saved_hflags
= ctx
->hflags
;
1297 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1303 ctx
->btarget
= env
->btarget
;
1309 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1311 TCGv_i32 texcp
= tcg_const_i32(excp
);
1312 TCGv_i32 terr
= tcg_const_i32(err
);
1313 save_cpu_state(ctx
, 1);
1314 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1315 tcg_temp_free_i32(terr
);
1316 tcg_temp_free_i32(texcp
);
1320 generate_exception (DisasContext
*ctx
, int excp
)
1322 save_cpu_state(ctx
, 1);
1323 gen_helper_0e0i(raise_exception
, excp
);
1326 /* Addresses computation */
1327 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1329 tcg_gen_add_tl(ret
, arg0
, arg1
);
1331 #if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
1335 if (((ctx
->hflags
& MIPS_HFLAG_KSU
) == MIPS_HFLAG_UM
) &&
1336 !(ctx
->hflags
& MIPS_HFLAG_UX
)) {
1337 tcg_gen_ext32s_i64(ret
, ret
);
1342 static inline void check_cp0_enabled(DisasContext
*ctx
)
1344 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1345 generate_exception_err(ctx
, EXCP_CpU
, 0);
1348 static inline void check_cp1_enabled(DisasContext
*ctx
)
1350 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1351 generate_exception_err(ctx
, EXCP_CpU
, 1);
1354 /* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1358 static inline void check_cop1x(DisasContext
*ctx
)
1360 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1361 generate_exception(ctx
, EXCP_RI
);
1364 /* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1367 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1369 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1370 generate_exception(ctx
, EXCP_RI
);
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1384 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1386 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1387 generate_exception(ctx
, EXCP_RI
);
1390 /* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1394 static inline void check_dsp(DisasContext
*ctx
)
1396 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1397 if (ctx
->insn_flags
& ASE_DSP
) {
1398 generate_exception(ctx
, EXCP_DSPDIS
);
1400 generate_exception(ctx
, EXCP_RI
);
1405 static inline void check_dspr2(DisasContext
*ctx
)
1407 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1408 if (ctx
->insn_flags
& ASE_DSP
) {
1409 generate_exception(ctx
, EXCP_DSPDIS
);
1411 generate_exception(ctx
, EXCP_RI
);
1416 /* This code generates a "reserved instruction" exception if the
1417 CPU does not support the instruction set corresponding to flags. */
1418 static inline void check_insn(DisasContext
*ctx
, int flags
)
1420 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1421 generate_exception(ctx
, EXCP_RI
);
1425 /* This code generates a "reserved instruction" exception if 64-bit
1426 instructions are not enabled. */
1427 static inline void check_mips_64(DisasContext
*ctx
)
1429 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1430 generate_exception(ctx
, EXCP_RI
);
1433 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1434 calling interface for 32 and 64-bit FPRs. No sense in changing
1435 all callers for gen_load_fpr32 when we need the CTX parameter for
1437 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1440 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1441 int ft, int fs, int cc) \
1443 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1444 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1447 check_cp1_64bitmode(ctx); \
1453 check_cp1_registers(ctx, fs | ft); \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1464 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1465 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1466 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1467 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1468 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1469 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1470 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1471 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1472 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1473 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1475 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1476 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1477 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1478 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1479 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1482 tcg_temp_free_i##bits (fp0); \
1483 tcg_temp_free_i##bits (fp1); \
1486 FOP_CONDS(, 0, d
, FMT_D
, 64)
1487 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1488 FOP_CONDS(, 0, s
, FMT_S
, 32)
1489 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1490 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1491 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1493 #undef gen_ldcmp_fpr32
1494 #undef gen_ldcmp_fpr64
1496 /* load/store instructions. */
1497 #ifdef CONFIG_USER_ONLY
1498 #define OP_LD_ATOMIC(insn,fname) \
1499 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1501 TCGv t0 = tcg_temp_new(); \
1502 tcg_gen_mov_tl(t0, arg1); \
1503 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1504 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1505 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1506 tcg_temp_free(t0); \
1509 #define OP_LD_ATOMIC(insn,fname) \
1510 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1512 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1515 OP_LD_ATOMIC(ll
,ld32s
);
1516 #if defined(TARGET_MIPS64)
1517 OP_LD_ATOMIC(lld
,ld64
);
1521 #ifdef CONFIG_USER_ONLY
1522 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1523 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1525 TCGv t0 = tcg_temp_new(); \
1526 int l1 = gen_new_label(); \
1527 int l2 = gen_new_label(); \
1529 tcg_gen_andi_tl(t0, arg2, almask); \
1530 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1531 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1532 generate_exception(ctx, EXCP_AdES); \
1533 gen_set_label(l1); \
1534 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1535 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1536 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1537 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1538 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1539 gen_helper_0e0i(raise_exception, EXCP_SC); \
1540 gen_set_label(l2); \
1541 tcg_gen_movi_tl(t0, 0); \
1542 gen_store_gpr(t0, rt); \
1543 tcg_temp_free(t0); \
1546 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1547 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1549 TCGv t0 = tcg_temp_new(); \
1550 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1551 gen_store_gpr(t0, rt); \
1552 tcg_temp_free(t0); \
1555 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1556 #if defined(TARGET_MIPS64)
1557 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1561 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1562 int base
, int16_t offset
)
1565 tcg_gen_movi_tl(addr
, offset
);
1566 } else if (offset
== 0) {
1567 gen_load_gpr(addr
, base
);
1569 tcg_gen_movi_tl(addr
, offset
);
1570 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1574 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1576 target_ulong pc
= ctx
->pc
;
1578 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1579 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1584 pc
&= ~(target_ulong
)3;
1589 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1590 int rt
, int base
, int16_t offset
)
1592 const char *opn
= "ld";
1595 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1596 /* Loongson CPU uses a load to zero register for prefetch.
1597 We emulate it as a NOP. On other CPU we must perform the
1598 actual memory access. */
1603 t0
= tcg_temp_new();
1604 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1607 #if defined(TARGET_MIPS64)
1609 tcg_gen_qemu_ld32u(t0
, t0
, ctx
->mem_idx
);
1610 gen_store_gpr(t0
, rt
);
1614 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1615 gen_store_gpr(t0
, rt
);
1619 save_cpu_state(ctx
, 1);
1620 op_ld_lld(t0
, t0
, ctx
);
1621 gen_store_gpr(t0
, rt
);
1625 t1
= tcg_temp_new();
1626 tcg_gen_andi_tl(t1
, t0
, 7);
1627 #ifndef TARGET_WORDS_BIGENDIAN
1628 tcg_gen_xori_tl(t1
, t1
, 7);
1630 tcg_gen_shli_tl(t1
, t1
, 3);
1631 tcg_gen_andi_tl(t0
, t0
, ~7);
1632 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1633 tcg_gen_shl_tl(t0
, t0
, t1
);
1634 tcg_gen_xori_tl(t1
, t1
, 63);
1635 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1636 tcg_gen_shr_tl(t2
, t2
, t1
);
1637 gen_load_gpr(t1
, rt
);
1638 tcg_gen_and_tl(t1
, t1
, t2
);
1640 tcg_gen_or_tl(t0
, t0
, t1
);
1642 gen_store_gpr(t0
, rt
);
1646 t1
= tcg_temp_new();
1647 tcg_gen_andi_tl(t1
, t0
, 7);
1648 #ifdef TARGET_WORDS_BIGENDIAN
1649 tcg_gen_xori_tl(t1
, t1
, 7);
1651 tcg_gen_shli_tl(t1
, t1
, 3);
1652 tcg_gen_andi_tl(t0
, t0
, ~7);
1653 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1654 tcg_gen_shr_tl(t0
, t0
, t1
);
1655 tcg_gen_xori_tl(t1
, t1
, 63);
1656 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1657 tcg_gen_shl_tl(t2
, t2
, t1
);
1658 gen_load_gpr(t1
, rt
);
1659 tcg_gen_and_tl(t1
, t1
, t2
);
1661 tcg_gen_or_tl(t0
, t0
, t1
);
1663 gen_store_gpr(t0
, rt
);
1667 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1668 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1670 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1671 gen_store_gpr(t0
, rt
);
1676 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1677 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1679 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
1680 gen_store_gpr(t0
, rt
);
1684 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
1685 gen_store_gpr(t0
, rt
);
1689 tcg_gen_qemu_ld16s(t0
, t0
, ctx
->mem_idx
);
1690 gen_store_gpr(t0
, rt
);
1694 tcg_gen_qemu_ld16u(t0
, t0
, ctx
->mem_idx
);
1695 gen_store_gpr(t0
, rt
);
1699 tcg_gen_qemu_ld8s(t0
, t0
, ctx
->mem_idx
);
1700 gen_store_gpr(t0
, rt
);
1704 tcg_gen_qemu_ld8u(t0
, t0
, ctx
->mem_idx
);
1705 gen_store_gpr(t0
, rt
);
1709 t1
= tcg_temp_new();
1710 tcg_gen_andi_tl(t1
, t0
, 3);
1711 #ifndef TARGET_WORDS_BIGENDIAN
1712 tcg_gen_xori_tl(t1
, t1
, 3);
1714 tcg_gen_shli_tl(t1
, t1
, 3);
1715 tcg_gen_andi_tl(t0
, t0
, ~3);
1716 tcg_gen_qemu_ld32u(t0
, t0
, ctx
->mem_idx
);
1717 tcg_gen_shl_tl(t0
, t0
, t1
);
1718 tcg_gen_xori_tl(t1
, t1
, 31);
1719 t2
= tcg_const_tl(0x7fffffffull
);
1720 tcg_gen_shr_tl(t2
, t2
, t1
);
1721 gen_load_gpr(t1
, rt
);
1722 tcg_gen_and_tl(t1
, t1
, t2
);
1724 tcg_gen_or_tl(t0
, t0
, t1
);
1726 tcg_gen_ext32s_tl(t0
, t0
);
1727 gen_store_gpr(t0
, rt
);
1731 t1
= tcg_temp_new();
1732 tcg_gen_andi_tl(t1
, t0
, 3);
1733 #ifdef TARGET_WORDS_BIGENDIAN
1734 tcg_gen_xori_tl(t1
, t1
, 3);
1736 tcg_gen_shli_tl(t1
, t1
, 3);
1737 tcg_gen_andi_tl(t0
, t0
, ~3);
1738 tcg_gen_qemu_ld32u(t0
, t0
, ctx
->mem_idx
);
1739 tcg_gen_shr_tl(t0
, t0
, t1
);
1740 tcg_gen_xori_tl(t1
, t1
, 31);
1741 t2
= tcg_const_tl(0xfffffffeull
);
1742 tcg_gen_shl_tl(t2
, t2
, t1
);
1743 gen_load_gpr(t1
, rt
);
1744 tcg_gen_and_tl(t1
, t1
, t2
);
1746 tcg_gen_or_tl(t0
, t0
, t1
);
1748 tcg_gen_ext32s_tl(t0
, t0
);
1749 gen_store_gpr(t0
, rt
);
1753 save_cpu_state(ctx
, 1);
1754 op_ld_ll(t0
, t0
, ctx
);
1755 gen_store_gpr(t0
, rt
);
1759 (void)opn
; /* avoid a compiler warning */
1760 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1765 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1766 int base
, int16_t offset
)
1768 const char *opn
= "st";
1769 TCGv t0
= tcg_temp_new();
1770 TCGv t1
= tcg_temp_new();
1772 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1773 gen_load_gpr(t1
, rt
);
1775 #if defined(TARGET_MIPS64)
1777 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
1781 save_cpu_state(ctx
, 1);
1782 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1786 save_cpu_state(ctx
, 1);
1787 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
1792 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
1796 tcg_gen_qemu_st16(t1
, t0
, ctx
->mem_idx
);
1800 tcg_gen_qemu_st8(t1
, t0
, ctx
->mem_idx
);
1804 save_cpu_state(ctx
, 1);
1805 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
1809 save_cpu_state(ctx
, 1);
1810 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
1814 (void)opn
; /* avoid a compiler warning */
1815 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1821 /* Store conditional */
1822 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
1823 int base
, int16_t offset
)
1825 const char *opn
= "st_cond";
1828 #ifdef CONFIG_USER_ONLY
1829 t0
= tcg_temp_local_new();
1830 t1
= tcg_temp_local_new();
1832 t0
= tcg_temp_new();
1833 t1
= tcg_temp_new();
1835 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1836 gen_load_gpr(t1
, rt
);
1838 #if defined(TARGET_MIPS64)
1840 save_cpu_state(ctx
, 1);
1841 op_st_scd(t1
, t0
, rt
, ctx
);
1846 save_cpu_state(ctx
, 1);
1847 op_st_sc(t1
, t0
, rt
, ctx
);
1851 (void)opn
; /* avoid a compiler warning */
1852 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1857 /* Load and store */
1858 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
1859 int base
, int16_t offset
)
1861 const char *opn
= "flt_ldst";
1862 TCGv t0
= tcg_temp_new();
1864 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1865 /* Don't do NOP if destination is zero: we must perform the actual
1870 TCGv_i32 fp0
= tcg_temp_new_i32();
1872 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
1873 tcg_gen_trunc_tl_i32(fp0
, t0
);
1874 gen_store_fpr32(fp0
, ft
);
1875 tcg_temp_free_i32(fp0
);
1881 TCGv_i32 fp0
= tcg_temp_new_i32();
1882 TCGv t1
= tcg_temp_new();
1884 gen_load_fpr32(fp0
, ft
);
1885 tcg_gen_extu_i32_tl(t1
, fp0
);
1886 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
1888 tcg_temp_free_i32(fp0
);
1894 TCGv_i64 fp0
= tcg_temp_new_i64();
1896 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
1897 gen_store_fpr64(ctx
, fp0
, ft
);
1898 tcg_temp_free_i64(fp0
);
1904 TCGv_i64 fp0
= tcg_temp_new_i64();
1906 gen_load_fpr64(ctx
, fp0
, ft
);
1907 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
1908 tcg_temp_free_i64(fp0
);
1914 generate_exception(ctx
, EXCP_RI
);
1917 (void)opn
; /* avoid a compiler warning */
1918 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
1923 static void gen_cop1_ldst(CPUMIPSState
*env
, DisasContext
*ctx
,
1924 uint32_t op
, int rt
, int rs
, int16_t imm
)
1926 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
1927 check_cp1_enabled(ctx
);
1928 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
1930 generate_exception_err(ctx
, EXCP_CpU
, 1);
1934 /* Arithmetic with immediate operand */
1935 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
1936 int rt
, int rs
, int16_t imm
)
1938 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
1939 const char *opn
= "imm arith";
1941 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
1942 /* If no destination, treat it as a NOP.
1943 For addi, we must generate the overflow exception when needed. */
1950 TCGv t0
= tcg_temp_local_new();
1951 TCGv t1
= tcg_temp_new();
1952 TCGv t2
= tcg_temp_new();
1953 int l1
= gen_new_label();
1955 gen_load_gpr(t1
, rs
);
1956 tcg_gen_addi_tl(t0
, t1
, uimm
);
1957 tcg_gen_ext32s_tl(t0
, t0
);
1959 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1960 tcg_gen_xori_tl(t2
, t0
, uimm
);
1961 tcg_gen_and_tl(t1
, t1
, t2
);
1963 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1965 /* operands of same sign, result different sign */
1966 generate_exception(ctx
, EXCP_OVERFLOW
);
1968 tcg_gen_ext32s_tl(t0
, t0
);
1969 gen_store_gpr(t0
, rt
);
1976 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1977 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
1979 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1983 #if defined(TARGET_MIPS64)
1986 TCGv t0
= tcg_temp_local_new();
1987 TCGv t1
= tcg_temp_new();
1988 TCGv t2
= tcg_temp_new();
1989 int l1
= gen_new_label();
1991 gen_load_gpr(t1
, rs
);
1992 tcg_gen_addi_tl(t0
, t1
, uimm
);
1994 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1995 tcg_gen_xori_tl(t2
, t0
, uimm
);
1996 tcg_gen_and_tl(t1
, t1
, t2
);
1998 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2000 /* operands of same sign, result different sign */
2001 generate_exception(ctx
, EXCP_OVERFLOW
);
2003 gen_store_gpr(t0
, rt
);
2010 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2012 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2018 (void)opn
; /* avoid a compiler warning */
2019 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2022 /* Logic with immediate operand */
2023 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2024 int rt
, int rs
, int16_t imm
)
2029 /* If no destination, treat it as a NOP. */
2033 uimm
= (uint16_t)imm
;
2036 if (likely(rs
!= 0))
2037 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2039 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2040 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2041 regnames
[rs
], uimm
);
2045 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2047 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2048 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2049 regnames
[rs
], uimm
);
2052 if (likely(rs
!= 0))
2053 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2055 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2056 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2057 regnames
[rs
], uimm
);
2060 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2061 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2065 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2070 /* Set on less than with immediate operand */
2071 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2072 int rt
, int rs
, int16_t imm
)
2074 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2075 const char *opn
= "imm arith";
2079 /* If no destination, treat it as a NOP. */
2083 t0
= tcg_temp_new();
2084 gen_load_gpr(t0
, rs
);
2087 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2091 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2095 (void)opn
; /* avoid a compiler warning */
2096 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2100 /* Shifts with immediate operand */
2101 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2102 int rt
, int rs
, int16_t imm
)
2104 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2105 const char *opn
= "imm shift";
2109 /* If no destination, treat it as a NOP. */
2114 t0
= tcg_temp_new();
2115 gen_load_gpr(t0
, rs
);
2118 tcg_gen_shli_tl(t0
, t0
, uimm
);
2119 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2123 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2128 tcg_gen_ext32u_tl(t0
, t0
);
2129 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2131 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2137 TCGv_i32 t1
= tcg_temp_new_i32();
2139 tcg_gen_trunc_tl_i32(t1
, t0
);
2140 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2141 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2142 tcg_temp_free_i32(t1
);
2144 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2148 #if defined(TARGET_MIPS64)
2150 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2154 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2158 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2163 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2165 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2170 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2174 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2178 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2182 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2187 (void)opn
; /* avoid a compiler warning */
2188 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2193 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2194 int rd
, int rs
, int rt
)
2196 const char *opn
= "arith";
2198 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2199 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2200 /* If no destination, treat it as a NOP.
2201 For add & sub, we must generate the overflow exception when needed. */
2209 TCGv t0
= tcg_temp_local_new();
2210 TCGv t1
= tcg_temp_new();
2211 TCGv t2
= tcg_temp_new();
2212 int l1
= gen_new_label();
2214 gen_load_gpr(t1
, rs
);
2215 gen_load_gpr(t2
, rt
);
2216 tcg_gen_add_tl(t0
, t1
, t2
);
2217 tcg_gen_ext32s_tl(t0
, t0
);
2218 tcg_gen_xor_tl(t1
, t1
, t2
);
2219 tcg_gen_xor_tl(t2
, t0
, t2
);
2220 tcg_gen_andc_tl(t1
, t2
, t1
);
2222 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2224 /* operands of same sign, result different sign */
2225 generate_exception(ctx
, EXCP_OVERFLOW
);
2227 gen_store_gpr(t0
, rd
);
2233 if (rs
!= 0 && rt
!= 0) {
2234 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2235 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2236 } else if (rs
== 0 && rt
!= 0) {
2237 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2238 } else if (rs
!= 0 && rt
== 0) {
2239 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2241 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2247 TCGv t0
= tcg_temp_local_new();
2248 TCGv t1
= tcg_temp_new();
2249 TCGv t2
= tcg_temp_new();
2250 int l1
= gen_new_label();
2252 gen_load_gpr(t1
, rs
);
2253 gen_load_gpr(t2
, rt
);
2254 tcg_gen_sub_tl(t0
, t1
, t2
);
2255 tcg_gen_ext32s_tl(t0
, t0
);
2256 tcg_gen_xor_tl(t2
, t1
, t2
);
2257 tcg_gen_xor_tl(t1
, t0
, t1
);
2258 tcg_gen_and_tl(t1
, t1
, t2
);
2260 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2262 /* operands of different sign, first operand and result different sign */
2263 generate_exception(ctx
, EXCP_OVERFLOW
);
2265 gen_store_gpr(t0
, rd
);
2271 if (rs
!= 0 && rt
!= 0) {
2272 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2273 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2274 } else if (rs
== 0 && rt
!= 0) {
2275 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2276 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2277 } else if (rs
!= 0 && rt
== 0) {
2278 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2280 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2284 #if defined(TARGET_MIPS64)
2287 TCGv t0
= tcg_temp_local_new();
2288 TCGv t1
= tcg_temp_new();
2289 TCGv t2
= tcg_temp_new();
2290 int l1
= gen_new_label();
2292 gen_load_gpr(t1
, rs
);
2293 gen_load_gpr(t2
, rt
);
2294 tcg_gen_add_tl(t0
, t1
, t2
);
2295 tcg_gen_xor_tl(t1
, t1
, t2
);
2296 tcg_gen_xor_tl(t2
, t0
, t2
);
2297 tcg_gen_andc_tl(t1
, t2
, t1
);
2299 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2301 /* operands of same sign, result different sign */
2302 generate_exception(ctx
, EXCP_OVERFLOW
);
2304 gen_store_gpr(t0
, rd
);
2310 if (rs
!= 0 && rt
!= 0) {
2311 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2312 } else if (rs
== 0 && rt
!= 0) {
2313 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2314 } else if (rs
!= 0 && rt
== 0) {
2315 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2317 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2323 TCGv t0
= tcg_temp_local_new();
2324 TCGv t1
= tcg_temp_new();
2325 TCGv t2
= tcg_temp_new();
2326 int l1
= gen_new_label();
2328 gen_load_gpr(t1
, rs
);
2329 gen_load_gpr(t2
, rt
);
2330 tcg_gen_sub_tl(t0
, t1
, t2
);
2331 tcg_gen_xor_tl(t2
, t1
, t2
);
2332 tcg_gen_xor_tl(t1
, t0
, t1
);
2333 tcg_gen_and_tl(t1
, t1
, t2
);
2335 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2337 /* operands of different sign, first operand and result different sign */
2338 generate_exception(ctx
, EXCP_OVERFLOW
);
2340 gen_store_gpr(t0
, rd
);
2346 if (rs
!= 0 && rt
!= 0) {
2347 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2348 } else if (rs
== 0 && rt
!= 0) {
2349 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2350 } else if (rs
!= 0 && rt
== 0) {
2351 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2353 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2359 if (likely(rs
!= 0 && rt
!= 0)) {
2360 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2361 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2363 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2368 (void)opn
; /* avoid a compiler warning */
2369 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2372 /* Conditional move */
2373 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2374 int rd
, int rs
, int rt
)
2376 const char *opn
= "cond move";
2380 /* If no destination, treat it as a NOP. */
2385 t0
= tcg_temp_new();
2386 gen_load_gpr(t0
, rt
);
2387 t1
= tcg_const_tl(0);
2388 t2
= tcg_temp_new();
2389 gen_load_gpr(t2
, rs
);
2392 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2396 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2404 (void)opn
; /* avoid a compiler warning */
2405 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2409 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2410 int rd
, int rs
, int rt
)
2412 const char *opn
= "logic";
2415 /* If no destination, treat it as a NOP. */
2422 if (likely(rs
!= 0 && rt
!= 0)) {
2423 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2425 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2430 if (rs
!= 0 && rt
!= 0) {
2431 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2432 } else if (rs
== 0 && rt
!= 0) {
2433 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2434 } else if (rs
!= 0 && rt
== 0) {
2435 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2437 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2442 if (likely(rs
!= 0 && rt
!= 0)) {
2443 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2444 } else if (rs
== 0 && rt
!= 0) {
2445 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2446 } else if (rs
!= 0 && rt
== 0) {
2447 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2449 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2454 if (likely(rs
!= 0 && rt
!= 0)) {
2455 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2456 } else if (rs
== 0 && rt
!= 0) {
2457 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2458 } else if (rs
!= 0 && rt
== 0) {
2459 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2461 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2466 (void)opn
; /* avoid a compiler warning */
2467 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2470 /* Set on lower than */
2471 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2472 int rd
, int rs
, int rt
)
2474 const char *opn
= "slt";
2478 /* If no destination, treat it as a NOP. */
2483 t0
= tcg_temp_new();
2484 t1
= tcg_temp_new();
2485 gen_load_gpr(t0
, rs
);
2486 gen_load_gpr(t1
, rt
);
2489 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2493 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2497 (void)opn
; /* avoid a compiler warning */
2498 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2504 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2505 int rd
, int rs
, int rt
)
2507 const char *opn
= "shifts";
2511 /* If no destination, treat it as a NOP.
2512 For add & sub, we must generate the overflow exception when needed. */
2517 t0
= tcg_temp_new();
2518 t1
= tcg_temp_new();
2519 gen_load_gpr(t0
, rs
);
2520 gen_load_gpr(t1
, rt
);
2523 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2524 tcg_gen_shl_tl(t0
, t1
, t0
);
2525 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2529 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2530 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2534 tcg_gen_ext32u_tl(t1
, t1
);
2535 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2536 tcg_gen_shr_tl(t0
, t1
, t0
);
2537 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2542 TCGv_i32 t2
= tcg_temp_new_i32();
2543 TCGv_i32 t3
= tcg_temp_new_i32();
2545 tcg_gen_trunc_tl_i32(t2
, t0
);
2546 tcg_gen_trunc_tl_i32(t3
, t1
);
2547 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2548 tcg_gen_rotr_i32(t2
, t3
, t2
);
2549 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2550 tcg_temp_free_i32(t2
);
2551 tcg_temp_free_i32(t3
);
2555 #if defined(TARGET_MIPS64)
2557 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2558 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2562 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2563 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2567 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2568 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2572 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2573 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2578 (void)opn
; /* avoid a compiler warning */
2579 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2584 /* Arithmetic on HI/LO registers */
2585 static void gen_HILO (DisasContext
*ctx
, uint32_t opc
, int reg
)
2587 const char *opn
= "hilo";
2590 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2596 if (opc
== OPC_MFHI
|| opc
== OPC_MFLO
) {
2597 acc
= ((ctx
->opcode
) >> 21) & 0x03;
2599 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2608 #if defined(TARGET_MIPS64)
2610 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2614 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2619 #if defined(TARGET_MIPS64)
2621 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2625 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2631 #if defined(TARGET_MIPS64)
2633 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2637 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2640 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2646 #if defined(TARGET_MIPS64)
2648 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2652 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2655 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2660 (void)opn
; /* avoid a compiler warning */
2661 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2664 static void gen_muldiv (DisasContext
*ctx
, uint32_t opc
,
2667 const char *opn
= "mul/div";
2671 t0
= tcg_temp_new();
2672 t1
= tcg_temp_new();
2674 gen_load_gpr(t0
, rs
);
2675 gen_load_gpr(t1
, rt
);
2680 TCGv t2
= tcg_temp_new();
2681 TCGv t3
= tcg_temp_new();
2682 tcg_gen_ext32s_tl(t0
, t0
);
2683 tcg_gen_ext32s_tl(t1
, t1
);
2684 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2685 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2686 tcg_gen_and_tl(t2
, t2
, t3
);
2687 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2688 tcg_gen_or_tl(t2
, t2
, t3
);
2689 tcg_gen_movi_tl(t3
, 0);
2690 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2691 tcg_gen_div_tl(cpu_LO
[0], t0
, t1
);
2692 tcg_gen_rem_tl(cpu_HI
[0], t0
, t1
);
2693 tcg_gen_ext32s_tl(cpu_LO
[0], cpu_LO
[0]);
2694 tcg_gen_ext32s_tl(cpu_HI
[0], cpu_HI
[0]);
2702 TCGv t2
= tcg_const_tl(0);
2703 TCGv t3
= tcg_const_tl(1);
2704 tcg_gen_ext32u_tl(t0
, t0
);
2705 tcg_gen_ext32u_tl(t1
, t1
);
2706 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2707 tcg_gen_divu_tl(cpu_LO
[0], t0
, t1
);
2708 tcg_gen_remu_tl(cpu_HI
[0], t0
, t1
);
2709 tcg_gen_ext32s_tl(cpu_LO
[0], cpu_LO
[0]);
2710 tcg_gen_ext32s_tl(cpu_HI
[0], cpu_HI
[0]);
2718 TCGv_i64 t2
= tcg_temp_new_i64();
2719 TCGv_i64 t3
= tcg_temp_new_i64();
2720 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2725 tcg_gen_ext_tl_i64(t2
, t0
);
2726 tcg_gen_ext_tl_i64(t3
, t1
);
2727 tcg_gen_mul_i64(t2
, t2
, t3
);
2728 tcg_temp_free_i64(t3
);
2729 tcg_gen_trunc_i64_tl(t0
, t2
);
2730 tcg_gen_shri_i64(t2
, t2
, 32);
2731 tcg_gen_trunc_i64_tl(t1
, t2
);
2732 tcg_temp_free_i64(t2
);
2733 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2734 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2740 TCGv_i64 t2
= tcg_temp_new_i64();
2741 TCGv_i64 t3
= tcg_temp_new_i64();
2742 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2747 tcg_gen_ext32u_tl(t0
, t0
);
2748 tcg_gen_ext32u_tl(t1
, t1
);
2749 tcg_gen_extu_tl_i64(t2
, t0
);
2750 tcg_gen_extu_tl_i64(t3
, t1
);
2751 tcg_gen_mul_i64(t2
, t2
, t3
);
2752 tcg_temp_free_i64(t3
);
2753 tcg_gen_trunc_i64_tl(t0
, t2
);
2754 tcg_gen_shri_i64(t2
, t2
, 32);
2755 tcg_gen_trunc_i64_tl(t1
, t2
);
2756 tcg_temp_free_i64(t2
);
2757 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2758 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2762 #if defined(TARGET_MIPS64)
2765 TCGv t2
= tcg_temp_new();
2766 TCGv t3
= tcg_temp_new();
2767 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2768 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2769 tcg_gen_and_tl(t2
, t2
, t3
);
2770 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2771 tcg_gen_or_tl(t2
, t2
, t3
);
2772 tcg_gen_movi_tl(t3
, 0);
2773 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2774 tcg_gen_div_tl(cpu_LO
[0], t0
, t1
);
2775 tcg_gen_rem_tl(cpu_HI
[0], t0
, t1
);
2783 TCGv t2
= tcg_const_tl(0);
2784 TCGv t3
= tcg_const_tl(1);
2785 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2786 tcg_gen_divu_i64(cpu_LO
[0], t0
, t1
);
2787 tcg_gen_remu_i64(cpu_HI
[0], t0
, t1
);
2794 gen_helper_dmult(cpu_env
, t0
, t1
);
2798 gen_helper_dmultu(cpu_env
, t0
, t1
);
2804 TCGv_i64 t2
= tcg_temp_new_i64();
2805 TCGv_i64 t3
= tcg_temp_new_i64();
2806 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2811 tcg_gen_ext_tl_i64(t2
, t0
);
2812 tcg_gen_ext_tl_i64(t3
, t1
);
2813 tcg_gen_mul_i64(t2
, t2
, t3
);
2814 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2815 tcg_gen_add_i64(t2
, t2
, t3
);
2816 tcg_temp_free_i64(t3
);
2817 tcg_gen_trunc_i64_tl(t0
, t2
);
2818 tcg_gen_shri_i64(t2
, t2
, 32);
2819 tcg_gen_trunc_i64_tl(t1
, t2
);
2820 tcg_temp_free_i64(t2
);
2821 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2822 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2828 TCGv_i64 t2
= tcg_temp_new_i64();
2829 TCGv_i64 t3
= tcg_temp_new_i64();
2830 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2835 tcg_gen_ext32u_tl(t0
, t0
);
2836 tcg_gen_ext32u_tl(t1
, t1
);
2837 tcg_gen_extu_tl_i64(t2
, t0
);
2838 tcg_gen_extu_tl_i64(t3
, t1
);
2839 tcg_gen_mul_i64(t2
, t2
, t3
);
2840 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2841 tcg_gen_add_i64(t2
, t2
, t3
);
2842 tcg_temp_free_i64(t3
);
2843 tcg_gen_trunc_i64_tl(t0
, t2
);
2844 tcg_gen_shri_i64(t2
, t2
, 32);
2845 tcg_gen_trunc_i64_tl(t1
, t2
);
2846 tcg_temp_free_i64(t2
);
2847 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2848 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2854 TCGv_i64 t2
= tcg_temp_new_i64();
2855 TCGv_i64 t3
= tcg_temp_new_i64();
2856 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2861 tcg_gen_ext_tl_i64(t2
, t0
);
2862 tcg_gen_ext_tl_i64(t3
, t1
);
2863 tcg_gen_mul_i64(t2
, t2
, t3
);
2864 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2865 tcg_gen_sub_i64(t2
, t3
, t2
);
2866 tcg_temp_free_i64(t3
);
2867 tcg_gen_trunc_i64_tl(t0
, t2
);
2868 tcg_gen_shri_i64(t2
, t2
, 32);
2869 tcg_gen_trunc_i64_tl(t1
, t2
);
2870 tcg_temp_free_i64(t2
);
2871 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2872 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2878 TCGv_i64 t2
= tcg_temp_new_i64();
2879 TCGv_i64 t3
= tcg_temp_new_i64();
2880 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2885 tcg_gen_ext32u_tl(t0
, t0
);
2886 tcg_gen_ext32u_tl(t1
, t1
);
2887 tcg_gen_extu_tl_i64(t2
, t0
);
2888 tcg_gen_extu_tl_i64(t3
, t1
);
2889 tcg_gen_mul_i64(t2
, t2
, t3
);
2890 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2891 tcg_gen_sub_i64(t2
, t3
, t2
);
2892 tcg_temp_free_i64(t3
);
2893 tcg_gen_trunc_i64_tl(t0
, t2
);
2894 tcg_gen_shri_i64(t2
, t2
, 32);
2895 tcg_gen_trunc_i64_tl(t1
, t2
);
2896 tcg_temp_free_i64(t2
);
2897 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2898 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2904 generate_exception(ctx
, EXCP_RI
);
2907 (void)opn
; /* avoid a compiler warning */
2908 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2914 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2915 int rd
, int rs
, int rt
)
2917 const char *opn
= "mul vr54xx";
2918 TCGv t0
= tcg_temp_new();
2919 TCGv t1
= tcg_temp_new();
2921 gen_load_gpr(t0
, rs
);
2922 gen_load_gpr(t1
, rt
);
2925 case OPC_VR54XX_MULS
:
2926 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2929 case OPC_VR54XX_MULSU
:
2930 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2933 case OPC_VR54XX_MACC
:
2934 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2937 case OPC_VR54XX_MACCU
:
2938 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2941 case OPC_VR54XX_MSAC
:
2942 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2945 case OPC_VR54XX_MSACU
:
2946 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2949 case OPC_VR54XX_MULHI
:
2950 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2953 case OPC_VR54XX_MULHIU
:
2954 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2957 case OPC_VR54XX_MULSHI
:
2958 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2961 case OPC_VR54XX_MULSHIU
:
2962 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2965 case OPC_VR54XX_MACCHI
:
2966 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2969 case OPC_VR54XX_MACCHIU
:
2970 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2973 case OPC_VR54XX_MSACHI
:
2974 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2977 case OPC_VR54XX_MSACHIU
:
2978 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2982 MIPS_INVAL("mul vr54xx");
2983 generate_exception(ctx
, EXCP_RI
);
2986 gen_store_gpr(t0
, rd
);
2987 (void)opn
; /* avoid a compiler warning */
2988 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2995 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2998 const char *opn
= "CLx";
3006 t0
= tcg_temp_new();
3007 gen_load_gpr(t0
, rs
);
3010 gen_helper_clo(cpu_gpr
[rd
], t0
);
3014 gen_helper_clz(cpu_gpr
[rd
], t0
);
3017 #if defined(TARGET_MIPS64)
3019 gen_helper_dclo(cpu_gpr
[rd
], t0
);
3023 gen_helper_dclz(cpu_gpr
[rd
], t0
);
3028 (void)opn
; /* avoid a compiler warning */
3029 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3033 /* Godson integer instructions */
3034 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3035 int rd
, int rs
, int rt
)
3037 const char *opn
= "loongson";
3049 case OPC_MULTU_G_2E
:
3050 case OPC_MULTU_G_2F
:
3051 #if defined(TARGET_MIPS64)
3052 case OPC_DMULT_G_2E
:
3053 case OPC_DMULT_G_2F
:
3054 case OPC_DMULTU_G_2E
:
3055 case OPC_DMULTU_G_2F
:
3057 t0
= tcg_temp_new();
3058 t1
= tcg_temp_new();
3061 t0
= tcg_temp_local_new();
3062 t1
= tcg_temp_local_new();
3066 gen_load_gpr(t0
, rs
);
3067 gen_load_gpr(t1
, rt
);
3072 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3073 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3076 case OPC_MULTU_G_2E
:
3077 case OPC_MULTU_G_2F
:
3078 tcg_gen_ext32u_tl(t0
, t0
);
3079 tcg_gen_ext32u_tl(t1
, t1
);
3080 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3081 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3087 int l1
= gen_new_label();
3088 int l2
= gen_new_label();
3089 int l3
= gen_new_label();
3090 tcg_gen_ext32s_tl(t0
, t0
);
3091 tcg_gen_ext32s_tl(t1
, t1
);
3092 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3093 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3096 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3097 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3098 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3101 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3102 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3110 int l1
= gen_new_label();
3111 int l2
= gen_new_label();
3112 tcg_gen_ext32u_tl(t0
, t0
);
3113 tcg_gen_ext32u_tl(t1
, t1
);
3114 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3115 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3118 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3119 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3127 int l1
= gen_new_label();
3128 int l2
= gen_new_label();
3129 int l3
= gen_new_label();
3130 tcg_gen_ext32u_tl(t0
, t0
);
3131 tcg_gen_ext32u_tl(t1
, t1
);
3132 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3133 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3134 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3136 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3139 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3140 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3148 int l1
= gen_new_label();
3149 int l2
= gen_new_label();
3150 tcg_gen_ext32u_tl(t0
, t0
);
3151 tcg_gen_ext32u_tl(t1
, t1
);
3152 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3153 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3156 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3157 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3162 #if defined(TARGET_MIPS64)
3163 case OPC_DMULT_G_2E
:
3164 case OPC_DMULT_G_2F
:
3165 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3168 case OPC_DMULTU_G_2E
:
3169 case OPC_DMULTU_G_2F
:
3170 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3176 int l1
= gen_new_label();
3177 int l2
= gen_new_label();
3178 int l3
= gen_new_label();
3179 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3180 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3183 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3184 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3185 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3188 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3193 case OPC_DDIVU_G_2E
:
3194 case OPC_DDIVU_G_2F
:
3196 int l1
= gen_new_label();
3197 int l2
= gen_new_label();
3198 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3199 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3202 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3210 int l1
= gen_new_label();
3211 int l2
= gen_new_label();
3212 int l3
= gen_new_label();
3213 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3214 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3215 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3217 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3220 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3225 case OPC_DMODU_G_2E
:
3226 case OPC_DMODU_G_2F
:
3228 int l1
= gen_new_label();
3229 int l2
= gen_new_label();
3230 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3231 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3234 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3242 (void)opn
; /* avoid a compiler warning */
3243 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3248 /* Loongson multimedia instructions */
3249 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3251 const char *opn
= "loongson_cp2";
3252 uint32_t opc
, shift_max
;
3255 opc
= MASK_LMI(ctx
->opcode
);
3261 t0
= tcg_temp_local_new_i64();
3262 t1
= tcg_temp_local_new_i64();
3265 t0
= tcg_temp_new_i64();
3266 t1
= tcg_temp_new_i64();
3270 gen_load_fpr64(ctx
, t0
, rs
);
3271 gen_load_fpr64(ctx
, t1
, rt
);
3273 #define LMI_HELPER(UP, LO) \
3274 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3275 #define LMI_HELPER_1(UP, LO) \
3276 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3277 #define LMI_DIRECT(UP, LO, OP) \
3278 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3281 LMI_HELPER(PADDSH
, paddsh
);
3282 LMI_HELPER(PADDUSH
, paddush
);
3283 LMI_HELPER(PADDH
, paddh
);
3284 LMI_HELPER(PADDW
, paddw
);
3285 LMI_HELPER(PADDSB
, paddsb
);
3286 LMI_HELPER(PADDUSB
, paddusb
);
3287 LMI_HELPER(PADDB
, paddb
);
3289 LMI_HELPER(PSUBSH
, psubsh
);
3290 LMI_HELPER(PSUBUSH
, psubush
);
3291 LMI_HELPER(PSUBH
, psubh
);
3292 LMI_HELPER(PSUBW
, psubw
);
3293 LMI_HELPER(PSUBSB
, psubsb
);
3294 LMI_HELPER(PSUBUSB
, psubusb
);
3295 LMI_HELPER(PSUBB
, psubb
);
3297 LMI_HELPER(PSHUFH
, pshufh
);
3298 LMI_HELPER(PACKSSWH
, packsswh
);
3299 LMI_HELPER(PACKSSHB
, packsshb
);
3300 LMI_HELPER(PACKUSHB
, packushb
);
3302 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3303 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3304 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3305 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3306 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3307 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3309 LMI_HELPER(PAVGH
, pavgh
);
3310 LMI_HELPER(PAVGB
, pavgb
);
3311 LMI_HELPER(PMAXSH
, pmaxsh
);
3312 LMI_HELPER(PMINSH
, pminsh
);
3313 LMI_HELPER(PMAXUB
, pmaxub
);
3314 LMI_HELPER(PMINUB
, pminub
);
3316 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3317 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3318 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3319 LMI_HELPER(PCMPGTH
, pcmpgth
);
3320 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3321 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3323 LMI_HELPER(PSLLW
, psllw
);
3324 LMI_HELPER(PSLLH
, psllh
);
3325 LMI_HELPER(PSRLW
, psrlw
);
3326 LMI_HELPER(PSRLH
, psrlh
);
3327 LMI_HELPER(PSRAW
, psraw
);
3328 LMI_HELPER(PSRAH
, psrah
);
3330 LMI_HELPER(PMULLH
, pmullh
);
3331 LMI_HELPER(PMULHH
, pmulhh
);
3332 LMI_HELPER(PMULHUH
, pmulhuh
);
3333 LMI_HELPER(PMADDHW
, pmaddhw
);
3335 LMI_HELPER(PASUBUB
, pasubub
);
3336 LMI_HELPER_1(BIADD
, biadd
);
3337 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3339 LMI_DIRECT(PADDD
, paddd
, add
);
3340 LMI_DIRECT(PSUBD
, psubd
, sub
);
3341 LMI_DIRECT(XOR_CP2
, xor, xor);
3342 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3343 LMI_DIRECT(AND_CP2
, and, and);
3344 LMI_DIRECT(PANDN
, pandn
, andc
);
3345 LMI_DIRECT(OR
, or, or);
3348 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3352 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3356 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3360 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3365 tcg_gen_andi_i64(t1
, t1
, 3);
3366 tcg_gen_shli_i64(t1
, t1
, 4);
3367 tcg_gen_shr_i64(t0
, t0
, t1
);
3368 tcg_gen_ext16u_i64(t0
, t0
);
3373 tcg_gen_add_i64(t0
, t0
, t1
);
3374 tcg_gen_ext32s_i64(t0
, t0
);
3378 tcg_gen_sub_i64(t0
, t0
, t1
);
3379 tcg_gen_ext32s_i64(t0
, t0
);
3408 /* Make sure shift count isn't TCG undefined behaviour. */
3409 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3414 tcg_gen_shl_i64(t0
, t0
, t1
);
3418 /* Since SRA is UndefinedResult without sign-extended inputs,
3419 we can treat SRA and DSRA the same. */
3420 tcg_gen_sar_i64(t0
, t0
, t1
);
3423 /* We want to shift in zeros for SRL; zero-extend first. */
3424 tcg_gen_ext32u_i64(t0
, t0
);
3427 tcg_gen_shr_i64(t0
, t0
, t1
);
3431 if (shift_max
== 32) {
3432 tcg_gen_ext32s_i64(t0
, t0
);
3435 /* Shifts larger than MAX produce zero. */
3436 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3437 tcg_gen_neg_i64(t1
, t1
);
3438 tcg_gen_and_i64(t0
, t0
, t1
);
3444 TCGv_i64 t2
= tcg_temp_new_i64();
3445 int lab
= gen_new_label();
3447 tcg_gen_mov_i64(t2
, t0
);
3448 tcg_gen_add_i64(t0
, t1
, t2
);
3449 if (opc
== OPC_ADD_CP2
) {
3450 tcg_gen_ext32s_i64(t0
, t0
);
3452 tcg_gen_xor_i64(t1
, t1
, t2
);
3453 tcg_gen_xor_i64(t2
, t2
, t0
);
3454 tcg_gen_andc_i64(t1
, t2
, t1
);
3455 tcg_temp_free_i64(t2
);
3456 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3457 generate_exception(ctx
, EXCP_OVERFLOW
);
3460 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3467 TCGv_i64 t2
= tcg_temp_new_i64();
3468 int lab
= gen_new_label();
3470 tcg_gen_mov_i64(t2
, t0
);
3471 tcg_gen_sub_i64(t0
, t1
, t2
);
3472 if (opc
== OPC_SUB_CP2
) {
3473 tcg_gen_ext32s_i64(t0
, t0
);
3475 tcg_gen_xor_i64(t1
, t1
, t2
);
3476 tcg_gen_xor_i64(t2
, t2
, t0
);
3477 tcg_gen_and_i64(t1
, t1
, t2
);
3478 tcg_temp_free_i64(t2
);
3479 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3480 generate_exception(ctx
, EXCP_OVERFLOW
);
3483 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3488 tcg_gen_ext32u_i64(t0
, t0
);
3489 tcg_gen_ext32u_i64(t1
, t1
);
3490 tcg_gen_mul_i64(t0
, t0
, t1
);
3500 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3501 FD field is the CC field? */
3504 generate_exception(ctx
, EXCP_RI
);
3511 gen_store_fpr64(ctx
, t0
, rd
);
3513 (void)opn
; /* avoid a compiler warning */
3514 MIPS_DEBUG("%s %s, %s, %s", opn
,
3515 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3516 tcg_temp_free_i64(t0
);
3517 tcg_temp_free_i64(t1
);
3521 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3522 int rs
, int rt
, int16_t imm
)
3525 TCGv t0
= tcg_temp_new();
3526 TCGv t1
= tcg_temp_new();
3529 /* Load needed operands */
3537 /* Compare two registers */
3539 gen_load_gpr(t0
, rs
);
3540 gen_load_gpr(t1
, rt
);
3550 /* Compare register to immediate */
3551 if (rs
!= 0 || imm
!= 0) {
3552 gen_load_gpr(t0
, rs
);
3553 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3560 case OPC_TEQ
: /* rs == rs */
3561 case OPC_TEQI
: /* r0 == 0 */
3562 case OPC_TGE
: /* rs >= rs */
3563 case OPC_TGEI
: /* r0 >= 0 */
3564 case OPC_TGEU
: /* rs >= rs unsigned */
3565 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3567 generate_exception(ctx
, EXCP_TRAP
);
3569 case OPC_TLT
: /* rs < rs */
3570 case OPC_TLTI
: /* r0 < 0 */
3571 case OPC_TLTU
: /* rs < rs unsigned */
3572 case OPC_TLTIU
: /* r0 < 0 unsigned */
3573 case OPC_TNE
: /* rs != rs */
3574 case OPC_TNEI
: /* r0 != 0 */
3575 /* Never trap: treat as NOP. */
3579 int l1
= gen_new_label();
3584 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3588 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3592 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3596 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3600 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3604 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3607 generate_exception(ctx
, EXCP_TRAP
);
3614 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3616 TranslationBlock
*tb
;
3618 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3619 likely(!ctx
->singlestep_enabled
)) {
3622 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3625 if (ctx
->singlestep_enabled
) {
3626 save_cpu_state(ctx
, 0);
3627 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3633 /* Branches (before delay slot) */
3634 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3636 int rs
, int rt
, int32_t offset
)
3638 target_ulong btgt
= -1;
3640 int bcond_compute
= 0;
3641 TCGv t0
= tcg_temp_new();
3642 TCGv t1
= tcg_temp_new();
3644 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3645 #ifdef MIPS_DEBUG_DISAS
3646 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3648 generate_exception(ctx
, EXCP_RI
);
3652 /* Load needed operands */
3658 /* Compare two registers */
3660 gen_load_gpr(t0
, rs
);
3661 gen_load_gpr(t1
, rt
);
3664 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3680 /* Compare to zero */
3682 gen_load_gpr(t0
, rs
);
3685 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3688 #if defined(TARGET_MIPS64)
3690 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3692 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3695 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3702 /* Jump to immediate */
3703 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3709 /* Jump to register */
3710 if (offset
!= 0 && offset
!= 16) {
3711 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3712 others are reserved. */
3713 MIPS_INVAL("jump hint");
3714 generate_exception(ctx
, EXCP_RI
);
3717 gen_load_gpr(btarget
, rs
);
3720 MIPS_INVAL("branch/jump");
3721 generate_exception(ctx
, EXCP_RI
);
3724 if (bcond_compute
== 0) {
3725 /* No condition to be computed */
3727 case OPC_BEQ
: /* rx == rx */
3728 case OPC_BEQL
: /* rx == rx likely */
3729 case OPC_BGEZ
: /* 0 >= 0 */
3730 case OPC_BGEZL
: /* 0 >= 0 likely */
3731 case OPC_BLEZ
: /* 0 <= 0 */
3732 case OPC_BLEZL
: /* 0 <= 0 likely */
3734 ctx
->hflags
|= MIPS_HFLAG_B
;
3735 MIPS_DEBUG("balways");
3738 case OPC_BGEZAL
: /* 0 >= 0 */
3739 case OPC_BGEZALL
: /* 0 >= 0 likely */
3740 ctx
->hflags
|= (opc
== OPC_BGEZALS
3742 : MIPS_HFLAG_BDS32
);
3743 /* Always take and link */
3745 ctx
->hflags
|= MIPS_HFLAG_B
;
3746 MIPS_DEBUG("balways and link");
3748 case OPC_BNE
: /* rx != rx */
3749 case OPC_BGTZ
: /* 0 > 0 */
3750 case OPC_BLTZ
: /* 0 < 0 */
3752 MIPS_DEBUG("bnever (NOP)");
3755 case OPC_BLTZAL
: /* 0 < 0 */
3756 ctx
->hflags
|= (opc
== OPC_BLTZALS
3758 : MIPS_HFLAG_BDS32
);
3759 /* Handle as an unconditional branch to get correct delay
3762 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3763 ctx
->hflags
|= MIPS_HFLAG_B
;
3764 MIPS_DEBUG("bnever and link");
3766 case OPC_BLTZALL
: /* 0 < 0 likely */
3767 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3768 /* Skip the instruction in the delay slot */
3769 MIPS_DEBUG("bnever, link and skip");
3772 case OPC_BNEL
: /* rx != rx likely */
3773 case OPC_BGTZL
: /* 0 > 0 likely */
3774 case OPC_BLTZL
: /* 0 < 0 likely */
3775 /* Skip the instruction in the delay slot */
3776 MIPS_DEBUG("bnever and skip");
3780 ctx
->hflags
|= MIPS_HFLAG_B
;
3781 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3785 ctx
->hflags
|= MIPS_HFLAG_BX
;
3790 ctx
->hflags
|= MIPS_HFLAG_B
;
3791 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3793 : MIPS_HFLAG_BDS32
);
3794 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3797 ctx
->hflags
|= MIPS_HFLAG_BR
;
3798 if (insn_bytes
== 4)
3799 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3800 MIPS_DEBUG("jr %s", regnames
[rs
]);
3806 ctx
->hflags
|= MIPS_HFLAG_BR
;
3807 ctx
->hflags
|= (opc
== OPC_JALRS
3809 : MIPS_HFLAG_BDS32
);
3810 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3813 MIPS_INVAL("branch/jump");
3814 generate_exception(ctx
, EXCP_RI
);
3820 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3821 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3822 regnames
[rs
], regnames
[rt
], btgt
);
3825 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3826 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3827 regnames
[rs
], regnames
[rt
], btgt
);
3830 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3831 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3832 regnames
[rs
], regnames
[rt
], btgt
);
3835 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3836 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3837 regnames
[rs
], regnames
[rt
], btgt
);
3840 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3841 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3844 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3845 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3849 ctx
->hflags
|= (opc
== OPC_BGEZALS
3851 : MIPS_HFLAG_BDS32
);
3852 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3853 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3857 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3859 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3862 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3863 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3866 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3867 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3870 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3871 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3874 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3875 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3878 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3879 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3882 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3883 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3886 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3887 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3889 #if defined(TARGET_MIPS64)
3891 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3892 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3897 ctx
->hflags
|= (opc
== OPC_BLTZALS
3899 : MIPS_HFLAG_BDS32
);
3900 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3902 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3904 ctx
->hflags
|= MIPS_HFLAG_BC
;
3907 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3909 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3911 ctx
->hflags
|= MIPS_HFLAG_BL
;
3914 MIPS_INVAL("conditional branch/jump");
3915 generate_exception(ctx
, EXCP_RI
);
3919 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3920 blink
, ctx
->hflags
, btgt
);
3922 ctx
->btarget
= btgt
;
3924 int post_delay
= insn_bytes
;
3925 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3927 if (opc
!= OPC_JALRC
)
3928 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3930 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3934 if (insn_bytes
== 2)
3935 ctx
->hflags
|= MIPS_HFLAG_B16
;
3940 /* special3 bitfield operations */
3941 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3942 int rs
, int lsb
, int msb
)
3944 TCGv t0
= tcg_temp_new();
3945 TCGv t1
= tcg_temp_new();
3947 gen_load_gpr(t1
, rs
);
3952 tcg_gen_shri_tl(t0
, t1
, lsb
);
3954 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3956 tcg_gen_ext32s_tl(t0
, t0
);
3959 #if defined(TARGET_MIPS64)
3961 tcg_gen_shri_tl(t0
, t1
, lsb
);
3963 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3967 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3968 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3971 tcg_gen_shri_tl(t0
, t1
, lsb
);
3972 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3978 gen_load_gpr(t0
, rt
);
3979 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3980 tcg_gen_ext32s_tl(t0
, t0
);
3982 #if defined(TARGET_MIPS64)
3984 gen_load_gpr(t0
, rt
);
3985 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3988 gen_load_gpr(t0
, rt
);
3989 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3992 gen_load_gpr(t0
, rt
);
3993 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3998 MIPS_INVAL("bitops");
3999 generate_exception(ctx
, EXCP_RI
);
4004 gen_store_gpr(t0
, rt
);
4009 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4014 /* If no destination, treat it as a NOP. */
4019 t0
= tcg_temp_new();
4020 gen_load_gpr(t0
, rt
);
4024 TCGv t1
= tcg_temp_new();
4026 tcg_gen_shri_tl(t1
, t0
, 8);
4027 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4028 tcg_gen_shli_tl(t0
, t0
, 8);
4029 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4030 tcg_gen_or_tl(t0
, t0
, t1
);
4032 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4036 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4039 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4041 #if defined(TARGET_MIPS64)
4044 TCGv t1
= tcg_temp_new();
4046 tcg_gen_shri_tl(t1
, t0
, 8);
4047 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4048 tcg_gen_shli_tl(t0
, t0
, 8);
4049 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4050 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4056 TCGv t1
= tcg_temp_new();
4058 tcg_gen_shri_tl(t1
, t0
, 16);
4059 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4060 tcg_gen_shli_tl(t0
, t0
, 16);
4061 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4062 tcg_gen_or_tl(t0
, t0
, t1
);
4063 tcg_gen_shri_tl(t1
, t0
, 32);
4064 tcg_gen_shli_tl(t0
, t0
, 32);
4065 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4071 MIPS_INVAL("bsfhl");
4072 generate_exception(ctx
, EXCP_RI
);
4079 #ifndef CONFIG_USER_ONLY
4080 /* CP0 (MMU and control) */
4081 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4083 TCGv_i32 t0
= tcg_temp_new_i32();
4085 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4086 tcg_gen_ext_i32_tl(arg
, t0
);
4087 tcg_temp_free_i32(t0
);
4090 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4092 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4093 tcg_gen_ext32s_tl(arg
, arg
);
4096 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4098 TCGv_i32 t0
= tcg_temp_new_i32();
4100 tcg_gen_trunc_tl_i32(t0
, arg
);
4101 tcg_gen_st_i32(t0
, cpu_env
, off
);
4102 tcg_temp_free_i32(t0
);
4105 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4107 tcg_gen_ext32s_tl(arg
, arg
);
4108 tcg_gen_st_tl(arg
, cpu_env
, off
);
4111 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4113 const char *rn
= "invalid";
4116 check_insn(ctx
, ISA_MIPS32
);
4122 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4126 check_insn(ctx
, ASE_MT
);
4127 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4131 check_insn(ctx
, ASE_MT
);
4132 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4136 check_insn(ctx
, ASE_MT
);
4137 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4147 gen_helper_mfc0_random(arg
, cpu_env
);
4151 check_insn(ctx
, ASE_MT
);
4152 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4156 check_insn(ctx
, ASE_MT
);
4157 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4161 check_insn(ctx
, ASE_MT
);
4162 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4166 check_insn(ctx
, ASE_MT
);
4167 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4171 check_insn(ctx
, ASE_MT
);
4172 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4176 check_insn(ctx
, ASE_MT
);
4177 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4178 rn
= "VPEScheFBack";
4181 check_insn(ctx
, ASE_MT
);
4182 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4192 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4193 tcg_gen_ext32s_tl(arg
, arg
);
4197 check_insn(ctx
, ASE_MT
);
4198 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4202 check_insn(ctx
, ASE_MT
);
4203 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4207 check_insn(ctx
, ASE_MT
);
4208 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4212 check_insn(ctx
, ASE_MT
);
4213 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4217 check_insn(ctx
, ASE_MT
);
4218 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4222 check_insn(ctx
, ASE_MT
);
4223 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4227 check_insn(ctx
, ASE_MT
);
4228 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4238 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4239 tcg_gen_ext32s_tl(arg
, arg
);
4249 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4250 tcg_gen_ext32s_tl(arg
, arg
);
4254 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4255 rn
= "ContextConfig";
4264 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4268 check_insn(ctx
, ISA_MIPS32R2
);
4269 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4279 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4283 check_insn(ctx
, ISA_MIPS32R2
);
4284 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4288 check_insn(ctx
, ISA_MIPS32R2
);
4289 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4293 check_insn(ctx
, ISA_MIPS32R2
);
4294 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4298 check_insn(ctx
, ISA_MIPS32R2
);
4299 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4303 check_insn(ctx
, ISA_MIPS32R2
);
4304 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4314 check_insn(ctx
, ISA_MIPS32R2
);
4315 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4325 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4326 tcg_gen_ext32s_tl(arg
, arg
);
4336 /* Mark as an IO operation because we read the time. */
4339 gen_helper_mfc0_count(arg
, cpu_env
);
4343 /* Break the TB to be able to take timer interrupts immediately
4344 after reading count. */
4345 ctx
->bstate
= BS_STOP
;
4348 /* 6,7 are implementation dependent */
4356 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4357 tcg_gen_ext32s_tl(arg
, arg
);
4367 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4370 /* 6,7 are implementation dependent */
4378 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4382 check_insn(ctx
, ISA_MIPS32R2
);
4383 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4387 check_insn(ctx
, ISA_MIPS32R2
);
4388 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4392 check_insn(ctx
, ISA_MIPS32R2
);
4393 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4403 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4413 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4414 tcg_gen_ext32s_tl(arg
, arg
);
4424 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4428 check_insn(ctx
, ISA_MIPS32R2
);
4429 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4439 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4443 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4447 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4451 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4454 /* 4,5 are reserved */
4455 /* 6,7 are implementation dependent */
4457 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4461 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4471 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4481 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4491 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4501 #if defined(TARGET_MIPS64)
4502 check_insn(ctx
, ISA_MIPS3
);
4503 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4504 tcg_gen_ext32s_tl(arg
, arg
);
4513 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4516 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4524 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4525 rn
= "'Diagnostic"; /* implementation dependent */
4530 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4534 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4535 rn
= "TraceControl";
4538 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4539 rn
= "TraceControl2";
4542 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4543 rn
= "UserTraceData";
4546 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4557 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4558 tcg_gen_ext32s_tl(arg
, arg
);
4568 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4569 rn
= "Performance0";
4572 // gen_helper_mfc0_performance1(arg);
4573 rn
= "Performance1";
4576 // gen_helper_mfc0_performance2(arg);
4577 rn
= "Performance2";
4580 // gen_helper_mfc0_performance3(arg);
4581 rn
= "Performance3";
4584 // gen_helper_mfc0_performance4(arg);
4585 rn
= "Performance4";
4588 // gen_helper_mfc0_performance5(arg);
4589 rn
= "Performance5";
4592 // gen_helper_mfc0_performance6(arg);
4593 rn
= "Performance6";
4596 // gen_helper_mfc0_performance7(arg);
4597 rn
= "Performance7";
4604 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4610 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4623 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4630 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4643 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4650 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4660 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4661 tcg_gen_ext32s_tl(arg
, arg
);
4672 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4682 (void)rn
; /* avoid a compiler warning */
4683 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4687 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4688 generate_exception(ctx
, EXCP_RI
);
4691 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4693 const char *rn
= "invalid";
4696 check_insn(ctx
, ISA_MIPS32
);
4705 gen_helper_mtc0_index(cpu_env
, arg
);
4709 check_insn(ctx
, ASE_MT
);
4710 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4714 check_insn(ctx
, ASE_MT
);
4719 check_insn(ctx
, ASE_MT
);
4734 check_insn(ctx
, ASE_MT
);
4735 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4739 check_insn(ctx
, ASE_MT
);
4740 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4744 check_insn(ctx
, ASE_MT
);
4745 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4749 check_insn(ctx
, ASE_MT
);
4750 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4754 check_insn(ctx
, ASE_MT
);
4755 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4759 check_insn(ctx
, ASE_MT
);
4760 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4761 rn
= "VPEScheFBack";
4764 check_insn(ctx
, ASE_MT
);
4765 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4775 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4779 check_insn(ctx
, ASE_MT
);
4780 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4784 check_insn(ctx
, ASE_MT
);
4785 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4789 check_insn(ctx
, ASE_MT
);
4790 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4794 check_insn(ctx
, ASE_MT
);
4795 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4799 check_insn(ctx
, ASE_MT
);
4800 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4804 check_insn(ctx
, ASE_MT
);
4805 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4809 check_insn(ctx
, ASE_MT
);
4810 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4820 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4830 gen_helper_mtc0_context(cpu_env
, arg
);
4834 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4835 rn
= "ContextConfig";
4844 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4848 check_insn(ctx
, ISA_MIPS32R2
);
4849 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4859 gen_helper_mtc0_wired(cpu_env
, arg
);
4863 check_insn(ctx
, ISA_MIPS32R2
);
4864 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4868 check_insn(ctx
, ISA_MIPS32R2
);
4869 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4873 check_insn(ctx
, ISA_MIPS32R2
);
4874 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4878 check_insn(ctx
, ISA_MIPS32R2
);
4879 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4883 check_insn(ctx
, ISA_MIPS32R2
);
4884 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4894 check_insn(ctx
, ISA_MIPS32R2
);
4895 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4909 gen_helper_mtc0_count(cpu_env
, arg
);
4912 /* 6,7 are implementation dependent */
4920 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4930 gen_helper_mtc0_compare(cpu_env
, arg
);
4933 /* 6,7 are implementation dependent */
4941 save_cpu_state(ctx
, 1);
4942 gen_helper_mtc0_status(cpu_env
, arg
);
4943 /* BS_STOP isn't good enough here, hflags may have changed. */
4944 gen_save_pc(ctx
->pc
+ 4);
4945 ctx
->bstate
= BS_EXCP
;
4949 check_insn(ctx
, ISA_MIPS32R2
);
4950 gen_helper_mtc0_intctl(cpu_env
, arg
);
4951 /* Stop translation as we may have switched the execution mode */
4952 ctx
->bstate
= BS_STOP
;
4956 check_insn(ctx
, ISA_MIPS32R2
);
4957 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4958 /* Stop translation as we may have switched the execution mode */
4959 ctx
->bstate
= BS_STOP
;
4963 check_insn(ctx
, ISA_MIPS32R2
);
4964 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4965 /* Stop translation as we may have switched the execution mode */
4966 ctx
->bstate
= BS_STOP
;
4976 save_cpu_state(ctx
, 1);
4977 gen_helper_mtc0_cause(cpu_env
, arg
);
4987 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
5001 check_insn(ctx
, ISA_MIPS32R2
);
5002 gen_helper_mtc0_ebase(cpu_env
, arg
);
5012 gen_helper_mtc0_config0(cpu_env
, arg
);
5014 /* Stop translation as we may have switched the execution mode */
5015 ctx
->bstate
= BS_STOP
;
5018 /* ignored, read only */
5022 gen_helper_mtc0_config2(cpu_env
, arg
);
5024 /* Stop translation as we may have switched the execution mode */
5025 ctx
->bstate
= BS_STOP
;
5028 /* ignored, read only */
5031 /* 4,5 are reserved */
5032 /* 6,7 are implementation dependent */
5042 rn
= "Invalid config selector";
5049 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5059 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5069 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5079 #if defined(TARGET_MIPS64)
5080 check_insn(ctx
, ISA_MIPS3
);
5081 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5090 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5093 gen_helper_mtc0_framemask(cpu_env
, arg
);
5102 rn
= "Diagnostic"; /* implementation dependent */
5107 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5108 /* BS_STOP isn't good enough here, hflags may have changed. */
5109 gen_save_pc(ctx
->pc
+ 4);
5110 ctx
->bstate
= BS_EXCP
;
5114 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5115 rn
= "TraceControl";
5116 /* Stop translation as we may have switched the execution mode */
5117 ctx
->bstate
= BS_STOP
;
5120 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5121 rn
= "TraceControl2";
5122 /* Stop translation as we may have switched the execution mode */
5123 ctx
->bstate
= BS_STOP
;
5126 /* Stop translation as we may have switched the execution mode */
5127 ctx
->bstate
= BS_STOP
;
5128 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5129 rn
= "UserTraceData";
5130 /* Stop translation as we may have switched the execution mode */
5131 ctx
->bstate
= BS_STOP
;
5134 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5135 /* Stop translation as we may have switched the execution mode */
5136 ctx
->bstate
= BS_STOP
;
5147 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5157 gen_helper_mtc0_performance0(cpu_env
, arg
);
5158 rn
= "Performance0";
5161 // gen_helper_mtc0_performance1(arg);
5162 rn
= "Performance1";
5165 // gen_helper_mtc0_performance2(arg);
5166 rn
= "Performance2";
5169 // gen_helper_mtc0_performance3(arg);
5170 rn
= "Performance3";
5173 // gen_helper_mtc0_performance4(arg);
5174 rn
= "Performance4";
5177 // gen_helper_mtc0_performance5(arg);
5178 rn
= "Performance5";
5181 // gen_helper_mtc0_performance6(arg);
5182 rn
= "Performance6";
5185 // gen_helper_mtc0_performance7(arg);
5186 rn
= "Performance7";
5212 gen_helper_mtc0_taglo(cpu_env
, arg
);
5219 gen_helper_mtc0_datalo(cpu_env
, arg
);
5232 gen_helper_mtc0_taghi(cpu_env
, arg
);
5239 gen_helper_mtc0_datahi(cpu_env
, arg
);
5250 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5261 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5267 /* Stop translation as we may have switched the execution mode */
5268 ctx
->bstate
= BS_STOP
;
5273 (void)rn
; /* avoid a compiler warning */
5274 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5275 /* For simplicity assume that all writes can cause interrupts. */
5278 ctx
->bstate
= BS_STOP
;
5283 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5284 generate_exception(ctx
, EXCP_RI
);
5287 #if defined(TARGET_MIPS64)
5288 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5290 const char *rn
= "invalid";
5293 check_insn(ctx
, ISA_MIPS64
);
5299 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5303 check_insn(ctx
, ASE_MT
);
5304 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5308 check_insn(ctx
, ASE_MT
);
5309 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5313 check_insn(ctx
, ASE_MT
);
5314 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5324 gen_helper_mfc0_random(arg
, cpu_env
);
5328 check_insn(ctx
, ASE_MT
);
5329 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5333 check_insn(ctx
, ASE_MT
);
5334 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5338 check_insn(ctx
, ASE_MT
);
5339 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5343 check_insn(ctx
, ASE_MT
);
5344 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5348 check_insn(ctx
, ASE_MT
);
5349 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5353 check_insn(ctx
, ASE_MT
);
5354 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5355 rn
= "VPEScheFBack";
5358 check_insn(ctx
, ASE_MT
);
5359 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5369 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5373 check_insn(ctx
, ASE_MT
);
5374 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5378 check_insn(ctx
, ASE_MT
);
5379 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5383 check_insn(ctx
, ASE_MT
);
5384 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5388 check_insn(ctx
, ASE_MT
);
5389 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5393 check_insn(ctx
, ASE_MT
);
5394 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5398 check_insn(ctx
, ASE_MT
);
5399 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5403 check_insn(ctx
, ASE_MT
);
5404 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5414 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5424 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5428 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5429 rn
= "ContextConfig";
5438 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5442 check_insn(ctx
, ISA_MIPS32R2
);
5443 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5453 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5457 check_insn(ctx
, ISA_MIPS32R2
);
5458 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5462 check_insn(ctx
, ISA_MIPS32R2
);
5463 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5467 check_insn(ctx
, ISA_MIPS32R2
);
5468 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5472 check_insn(ctx
, ISA_MIPS32R2
);
5473 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5477 check_insn(ctx
, ISA_MIPS32R2
);
5478 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5488 check_insn(ctx
, ISA_MIPS32R2
);
5489 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5499 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5509 /* Mark as an IO operation because we read the time. */
5512 gen_helper_mfc0_count(arg
, cpu_env
);
5516 /* Break the TB to be able to take timer interrupts immediately
5517 after reading count. */
5518 ctx
->bstate
= BS_STOP
;
5521 /* 6,7 are implementation dependent */
5529 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5539 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5542 /* 6,7 are implementation dependent */
5550 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5554 check_insn(ctx
, ISA_MIPS32R2
);
5555 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5559 check_insn(ctx
, ISA_MIPS32R2
);
5560 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5564 check_insn(ctx
, ISA_MIPS32R2
);
5565 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5575 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5585 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5595 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5599 check_insn(ctx
, ISA_MIPS32R2
);
5600 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5610 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5614 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5618 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5622 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5625 /* 6,7 are implementation dependent */
5627 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5631 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5641 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5651 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5661 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5671 check_insn(ctx
, ISA_MIPS3
);
5672 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5680 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5683 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5691 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5692 rn
= "'Diagnostic"; /* implementation dependent */
5697 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5701 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5702 rn
= "TraceControl";
5705 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5706 rn
= "TraceControl2";
5709 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5710 rn
= "UserTraceData";
5713 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5724 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5734 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5735 rn
= "Performance0";
5738 // gen_helper_dmfc0_performance1(arg);
5739 rn
= "Performance1";
5742 // gen_helper_dmfc0_performance2(arg);
5743 rn
= "Performance2";
5746 // gen_helper_dmfc0_performance3(arg);
5747 rn
= "Performance3";
5750 // gen_helper_dmfc0_performance4(arg);
5751 rn
= "Performance4";
5754 // gen_helper_dmfc0_performance5(arg);
5755 rn
= "Performance5";
5758 // gen_helper_dmfc0_performance6(arg);
5759 rn
= "Performance6";
5762 // gen_helper_dmfc0_performance7(arg);
5763 rn
= "Performance7";
5770 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5777 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5790 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5797 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5810 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5817 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5827 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5838 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5848 (void)rn
; /* avoid a compiler warning */
5849 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5853 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5854 generate_exception(ctx
, EXCP_RI
);
5857 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5859 const char *rn
= "invalid";
5862 check_insn(ctx
, ISA_MIPS64
);
5871 gen_helper_mtc0_index(cpu_env
, arg
);
5875 check_insn(ctx
, ASE_MT
);
5876 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5880 check_insn(ctx
, ASE_MT
);
5885 check_insn(ctx
, ASE_MT
);
5900 check_insn(ctx
, ASE_MT
);
5901 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5905 check_insn(ctx
, ASE_MT
);
5906 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5910 check_insn(ctx
, ASE_MT
);
5911 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5915 check_insn(ctx
, ASE_MT
);
5916 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5920 check_insn(ctx
, ASE_MT
);
5921 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5925 check_insn(ctx
, ASE_MT
);
5926 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5927 rn
= "VPEScheFBack";
5930 check_insn(ctx
, ASE_MT
);
5931 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5941 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5945 check_insn(ctx
, ASE_MT
);
5946 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5950 check_insn(ctx
, ASE_MT
);
5951 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5955 check_insn(ctx
, ASE_MT
);
5956 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5960 check_insn(ctx
, ASE_MT
);
5961 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5965 check_insn(ctx
, ASE_MT
);
5966 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5970 check_insn(ctx
, ASE_MT
);
5971 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5975 check_insn(ctx
, ASE_MT
);
5976 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5986 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5996 gen_helper_mtc0_context(cpu_env
, arg
);
6000 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6001 rn
= "ContextConfig";
6010 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6014 check_insn(ctx
, ISA_MIPS32R2
);
6015 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6025 gen_helper_mtc0_wired(cpu_env
, arg
);
6029 check_insn(ctx
, ISA_MIPS32R2
);
6030 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6034 check_insn(ctx
, ISA_MIPS32R2
);
6035 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6039 check_insn(ctx
, ISA_MIPS32R2
);
6040 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6044 check_insn(ctx
, ISA_MIPS32R2
);
6045 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6049 check_insn(ctx
, ISA_MIPS32R2
);
6050 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6060 check_insn(ctx
, ISA_MIPS32R2
);
6061 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6075 gen_helper_mtc0_count(cpu_env
, arg
);
6078 /* 6,7 are implementation dependent */
6082 /* Stop translation as we may have switched the execution mode */
6083 ctx
->bstate
= BS_STOP
;
6088 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6098 gen_helper_mtc0_compare(cpu_env
, arg
);
6101 /* 6,7 are implementation dependent */
6105 /* Stop translation as we may have switched the execution mode */
6106 ctx
->bstate
= BS_STOP
;
6111 save_cpu_state(ctx
, 1);
6112 gen_helper_mtc0_status(cpu_env
, arg
);
6113 /* BS_STOP isn't good enough here, hflags may have changed. */
6114 gen_save_pc(ctx
->pc
+ 4);
6115 ctx
->bstate
= BS_EXCP
;
6119 check_insn(ctx
, ISA_MIPS32R2
);
6120 gen_helper_mtc0_intctl(cpu_env
, arg
);
6121 /* Stop translation as we may have switched the execution mode */
6122 ctx
->bstate
= BS_STOP
;
6126 check_insn(ctx
, ISA_MIPS32R2
);
6127 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6128 /* Stop translation as we may have switched the execution mode */
6129 ctx
->bstate
= BS_STOP
;
6133 check_insn(ctx
, ISA_MIPS32R2
);
6134 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6135 /* Stop translation as we may have switched the execution mode */
6136 ctx
->bstate
= BS_STOP
;
6146 save_cpu_state(ctx
, 1);
6147 /* Mark as an IO operation because we may trigger a software
6152 gen_helper_mtc0_cause(cpu_env
, arg
);
6156 /* Stop translation as we may have triggered an intetrupt */
6157 ctx
->bstate
= BS_STOP
;
6167 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6181 check_insn(ctx
, ISA_MIPS32R2
);
6182 gen_helper_mtc0_ebase(cpu_env
, arg
);
6192 gen_helper_mtc0_config0(cpu_env
, arg
);
6194 /* Stop translation as we may have switched the execution mode */
6195 ctx
->bstate
= BS_STOP
;
6198 /* ignored, read only */
6202 gen_helper_mtc0_config2(cpu_env
, arg
);
6204 /* Stop translation as we may have switched the execution mode */
6205 ctx
->bstate
= BS_STOP
;
6211 /* 6,7 are implementation dependent */
6213 rn
= "Invalid config selector";
6220 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6230 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6240 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6250 check_insn(ctx
, ISA_MIPS3
);
6251 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6259 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6262 gen_helper_mtc0_framemask(cpu_env
, arg
);
6271 rn
= "Diagnostic"; /* implementation dependent */
6276 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6277 /* BS_STOP isn't good enough here, hflags may have changed. */
6278 gen_save_pc(ctx
->pc
+ 4);
6279 ctx
->bstate
= BS_EXCP
;
6283 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6284 /* Stop translation as we may have switched the execution mode */
6285 ctx
->bstate
= BS_STOP
;
6286 rn
= "TraceControl";
6289 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6290 /* Stop translation as we may have switched the execution mode */
6291 ctx
->bstate
= BS_STOP
;
6292 rn
= "TraceControl2";
6295 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6296 /* Stop translation as we may have switched the execution mode */
6297 ctx
->bstate
= BS_STOP
;
6298 rn
= "UserTraceData";
6301 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6302 /* Stop translation as we may have switched the execution mode */
6303 ctx
->bstate
= BS_STOP
;
6314 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6324 gen_helper_mtc0_performance0(cpu_env
, arg
);
6325 rn
= "Performance0";
6328 // gen_helper_mtc0_performance1(cpu_env, arg);
6329 rn
= "Performance1";
6332 // gen_helper_mtc0_performance2(cpu_env, arg);
6333 rn
= "Performance2";
6336 // gen_helper_mtc0_performance3(cpu_env, arg);
6337 rn
= "Performance3";
6340 // gen_helper_mtc0_performance4(cpu_env, arg);
6341 rn
= "Performance4";
6344 // gen_helper_mtc0_performance5(cpu_env, arg);
6345 rn
= "Performance5";
6348 // gen_helper_mtc0_performance6(cpu_env, arg);
6349 rn
= "Performance6";
6352 // gen_helper_mtc0_performance7(cpu_env, arg);
6353 rn
= "Performance7";
6379 gen_helper_mtc0_taglo(cpu_env
, arg
);
6386 gen_helper_mtc0_datalo(cpu_env
, arg
);
6399 gen_helper_mtc0_taghi(cpu_env
, arg
);
6406 gen_helper_mtc0_datahi(cpu_env
, arg
);
6417 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6428 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6434 /* Stop translation as we may have switched the execution mode */
6435 ctx
->bstate
= BS_STOP
;
6440 (void)rn
; /* avoid a compiler warning */
6441 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6442 /* For simplicity assume that all writes can cause interrupts. */
6445 ctx
->bstate
= BS_STOP
;
6450 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6451 generate_exception(ctx
, EXCP_RI
);
6453 #endif /* TARGET_MIPS64 */
6455 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6456 int u
, int sel
, int h
)
6458 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6459 TCGv t0
= tcg_temp_local_new();
6461 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6462 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6463 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6464 tcg_gen_movi_tl(t0
, -1);
6465 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6466 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6467 tcg_gen_movi_tl(t0
, -1);
6473 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6476 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6486 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6489 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6492 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6495 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6498 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6501 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6504 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6507 gen_mfc0(ctx
, t0
, rt
, sel
);
6514 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6517 gen_mfc0(ctx
, t0
, rt
, sel
);
6523 gen_helper_mftc0_status(t0
, cpu_env
);
6526 gen_mfc0(ctx
, t0
, rt
, sel
);
6532 gen_helper_mftc0_cause(t0
, cpu_env
);
6542 gen_helper_mftc0_epc(t0
, cpu_env
);
6552 gen_helper_mftc0_ebase(t0
, cpu_env
);
6562 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6572 gen_helper_mftc0_debug(t0
, cpu_env
);
6575 gen_mfc0(ctx
, t0
, rt
, sel
);
6580 gen_mfc0(ctx
, t0
, rt
, sel
);
6582 } else switch (sel
) {
6583 /* GPR registers. */
6585 gen_helper_1e0i(mftgpr
, t0
, rt
);
6587 /* Auxiliary CPU registers */
6591 gen_helper_1e0i(mftlo
, t0
, 0);
6594 gen_helper_1e0i(mfthi
, t0
, 0);
6597 gen_helper_1e0i(mftacx
, t0
, 0);
6600 gen_helper_1e0i(mftlo
, t0
, 1);
6603 gen_helper_1e0i(mfthi
, t0
, 1);
6606 gen_helper_1e0i(mftacx
, t0
, 1);
6609 gen_helper_1e0i(mftlo
, t0
, 2);
6612 gen_helper_1e0i(mfthi
, t0
, 2);
6615 gen_helper_1e0i(mftacx
, t0
, 2);
6618 gen_helper_1e0i(mftlo
, t0
, 3);
6621 gen_helper_1e0i(mfthi
, t0
, 3);
6624 gen_helper_1e0i(mftacx
, t0
, 3);
6627 gen_helper_mftdsp(t0
, cpu_env
);
6633 /* Floating point (COP1). */
6635 /* XXX: For now we support only a single FPU context. */
6637 TCGv_i32 fp0
= tcg_temp_new_i32();
6639 gen_load_fpr32(fp0
, rt
);
6640 tcg_gen_ext_i32_tl(t0
, fp0
);
6641 tcg_temp_free_i32(fp0
);
6643 TCGv_i32 fp0
= tcg_temp_new_i32();
6645 gen_load_fpr32h(fp0
, rt
);
6646 tcg_gen_ext_i32_tl(t0
, fp0
);
6647 tcg_temp_free_i32(fp0
);
6651 /* XXX: For now we support only a single FPU context. */
6652 gen_helper_1e0i(cfc1
, t0
, rt
);
6654 /* COP2: Not implemented. */
6661 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6662 gen_store_gpr(t0
, rd
);
6668 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6669 generate_exception(ctx
, EXCP_RI
);
6672 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6673 int u
, int sel
, int h
)
6675 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6676 TCGv t0
= tcg_temp_local_new();
6678 gen_load_gpr(t0
, rt
);
6679 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6680 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6681 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6683 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6684 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6691 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6694 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6704 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6707 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6710 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6713 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6716 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6719 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6722 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6725 gen_mtc0(ctx
, t0
, rd
, sel
);
6732 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6735 gen_mtc0(ctx
, t0
, rd
, sel
);
6741 gen_helper_mttc0_status(cpu_env
, t0
);
6744 gen_mtc0(ctx
, t0
, rd
, sel
);
6750 gen_helper_mttc0_cause(cpu_env
, t0
);
6760 gen_helper_mttc0_ebase(cpu_env
, t0
);
6770 gen_helper_mttc0_debug(cpu_env
, t0
);
6773 gen_mtc0(ctx
, t0
, rd
, sel
);
6778 gen_mtc0(ctx
, t0
, rd
, sel
);
6780 } else switch (sel
) {
6781 /* GPR registers. */
6783 gen_helper_0e1i(mttgpr
, t0
, rd
);
6785 /* Auxiliary CPU registers */
6789 gen_helper_0e1i(mttlo
, t0
, 0);
6792 gen_helper_0e1i(mtthi
, t0
, 0);
6795 gen_helper_0e1i(mttacx
, t0
, 0);
6798 gen_helper_0e1i(mttlo
, t0
, 1);
6801 gen_helper_0e1i(mtthi
, t0
, 1);
6804 gen_helper_0e1i(mttacx
, t0
, 1);
6807 gen_helper_0e1i(mttlo
, t0
, 2);
6810 gen_helper_0e1i(mtthi
, t0
, 2);
6813 gen_helper_0e1i(mttacx
, t0
, 2);
6816 gen_helper_0e1i(mttlo
, t0
, 3);
6819 gen_helper_0e1i(mtthi
, t0
, 3);
6822 gen_helper_0e1i(mttacx
, t0
, 3);
6825 gen_helper_mttdsp(cpu_env
, t0
);
6831 /* Floating point (COP1). */
6833 /* XXX: For now we support only a single FPU context. */
6835 TCGv_i32 fp0
= tcg_temp_new_i32();
6837 tcg_gen_trunc_tl_i32(fp0
, t0
);
6838 gen_store_fpr32(fp0
, rd
);
6839 tcg_temp_free_i32(fp0
);
6841 TCGv_i32 fp0
= tcg_temp_new_i32();
6843 tcg_gen_trunc_tl_i32(fp0
, t0
);
6844 gen_store_fpr32h(fp0
, rd
);
6845 tcg_temp_free_i32(fp0
);
6849 /* XXX: For now we support only a single FPU context. */
6850 gen_helper_0e1i(ctc1
, t0
, rd
);
6852 /* COP2: Not implemented. */
6859 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6865 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6866 generate_exception(ctx
, EXCP_RI
);
6869 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6871 const char *opn
= "ldst";
6873 check_cp0_enabled(ctx
);
6880 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6885 TCGv t0
= tcg_temp_new();
6887 gen_load_gpr(t0
, rt
);
6888 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6893 #if defined(TARGET_MIPS64)
6895 check_insn(ctx
, ISA_MIPS3
);
6900 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6904 check_insn(ctx
, ISA_MIPS3
);
6906 TCGv t0
= tcg_temp_new();
6908 gen_load_gpr(t0
, rt
);
6909 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6916 check_insn(ctx
, ASE_MT
);
6921 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6922 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6926 check_insn(ctx
, ASE_MT
);
6927 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6928 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6933 if (!env
->tlb
->helper_tlbwi
)
6935 gen_helper_tlbwi(cpu_env
);
6939 if (!env
->tlb
->helper_tlbwr
)
6941 gen_helper_tlbwr(cpu_env
);
6945 if (!env
->tlb
->helper_tlbp
)
6947 gen_helper_tlbp(cpu_env
);
6951 if (!env
->tlb
->helper_tlbr
)
6953 gen_helper_tlbr(cpu_env
);
6957 check_insn(ctx
, ISA_MIPS2
);
6958 gen_helper_eret(cpu_env
);
6959 ctx
->bstate
= BS_EXCP
;
6963 check_insn(ctx
, ISA_MIPS32
);
6964 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6966 generate_exception(ctx
, EXCP_RI
);
6968 gen_helper_deret(cpu_env
);
6969 ctx
->bstate
= BS_EXCP
;
6974 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
6975 /* If we get an exception, we want to restart at next instruction */
6977 save_cpu_state(ctx
, 1);
6979 gen_helper_wait(cpu_env
);
6980 ctx
->bstate
= BS_EXCP
;
6985 generate_exception(ctx
, EXCP_RI
);
6988 (void)opn
; /* avoid a compiler warning */
6989 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
6991 #endif /* !CONFIG_USER_ONLY */
6993 /* CP1 Branches (before delay slot) */
6994 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
6995 int32_t cc
, int32_t offset
)
6997 target_ulong btarget
;
6998 const char *opn
= "cp1 cond branch";
6999 TCGv_i32 t0
= tcg_temp_new_i32();
7002 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
7004 btarget
= ctx
->pc
+ 4 + offset
;
7008 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7009 tcg_gen_not_i32(t0
, t0
);
7010 tcg_gen_andi_i32(t0
, t0
, 1);
7011 tcg_gen_extu_i32_tl(bcond
, t0
);
7015 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7016 tcg_gen_not_i32(t0
, t0
);
7017 tcg_gen_andi_i32(t0
, t0
, 1);
7018 tcg_gen_extu_i32_tl(bcond
, t0
);
7022 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7023 tcg_gen_andi_i32(t0
, t0
, 1);
7024 tcg_gen_extu_i32_tl(bcond
, t0
);
7028 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7029 tcg_gen_andi_i32(t0
, t0
, 1);
7030 tcg_gen_extu_i32_tl(bcond
, t0
);
7033 ctx
->hflags
|= MIPS_HFLAG_BL
;
7037 TCGv_i32 t1
= tcg_temp_new_i32();
7038 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7039 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7040 tcg_gen_nand_i32(t0
, t0
, t1
);
7041 tcg_temp_free_i32(t1
);
7042 tcg_gen_andi_i32(t0
, t0
, 1);
7043 tcg_gen_extu_i32_tl(bcond
, t0
);
7049 TCGv_i32 t1
= tcg_temp_new_i32();
7050 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7051 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7052 tcg_gen_or_i32(t0
, t0
, t1
);
7053 tcg_temp_free_i32(t1
);
7054 tcg_gen_andi_i32(t0
, t0
, 1);
7055 tcg_gen_extu_i32_tl(bcond
, t0
);
7061 TCGv_i32 t1
= tcg_temp_new_i32();
7062 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7063 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7064 tcg_gen_and_i32(t0
, t0
, t1
);
7065 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7066 tcg_gen_and_i32(t0
, t0
, t1
);
7067 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7068 tcg_gen_nand_i32(t0
, t0
, t1
);
7069 tcg_temp_free_i32(t1
);
7070 tcg_gen_andi_i32(t0
, t0
, 1);
7071 tcg_gen_extu_i32_tl(bcond
, t0
);
7077 TCGv_i32 t1
= tcg_temp_new_i32();
7078 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7079 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7080 tcg_gen_or_i32(t0
, t0
, t1
);
7081 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7082 tcg_gen_or_i32(t0
, t0
, t1
);
7083 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7084 tcg_gen_or_i32(t0
, t0
, t1
);
7085 tcg_temp_free_i32(t1
);
7086 tcg_gen_andi_i32(t0
, t0
, 1);
7087 tcg_gen_extu_i32_tl(bcond
, t0
);
7091 ctx
->hflags
|= MIPS_HFLAG_BC
;
7095 generate_exception (ctx
, EXCP_RI
);
7098 (void)opn
; /* avoid a compiler warning */
7099 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7100 ctx
->hflags
, btarget
);
7101 ctx
->btarget
= btarget
;
7104 tcg_temp_free_i32(t0
);
7107 /* Coprocessor 1 (FPU) */
7109 #define FOP(func, fmt) (((fmt) << 21) | (func))
7112 OPC_ADD_S
= FOP(0, FMT_S
),
7113 OPC_SUB_S
= FOP(1, FMT_S
),
7114 OPC_MUL_S
= FOP(2, FMT_S
),
7115 OPC_DIV_S
= FOP(3, FMT_S
),
7116 OPC_SQRT_S
= FOP(4, FMT_S
),
7117 OPC_ABS_S
= FOP(5, FMT_S
),
7118 OPC_MOV_S
= FOP(6, FMT_S
),
7119 OPC_NEG_S
= FOP(7, FMT_S
),
7120 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7121 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7122 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7123 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7124 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7125 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7126 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7127 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7128 OPC_MOVCF_S
= FOP(17, FMT_S
),
7129 OPC_MOVZ_S
= FOP(18, FMT_S
),
7130 OPC_MOVN_S
= FOP(19, FMT_S
),
7131 OPC_RECIP_S
= FOP(21, FMT_S
),
7132 OPC_RSQRT_S
= FOP(22, FMT_S
),
7133 OPC_RECIP2_S
= FOP(28, FMT_S
),
7134 OPC_RECIP1_S
= FOP(29, FMT_S
),
7135 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7136 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7137 OPC_CVT_D_S
= FOP(33, FMT_S
),
7138 OPC_CVT_W_S
= FOP(36, FMT_S
),
7139 OPC_CVT_L_S
= FOP(37, FMT_S
),
7140 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7141 OPC_CMP_F_S
= FOP (48, FMT_S
),
7142 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7143 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7144 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7145 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7146 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7147 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7148 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7149 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7150 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7151 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7152 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7153 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7154 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7155 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7156 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7158 OPC_ADD_D
= FOP(0, FMT_D
),
7159 OPC_SUB_D
= FOP(1, FMT_D
),
7160 OPC_MUL_D
= FOP(2, FMT_D
),
7161 OPC_DIV_D
= FOP(3, FMT_D
),
7162 OPC_SQRT_D
= FOP(4, FMT_D
),
7163 OPC_ABS_D
= FOP(5, FMT_D
),
7164 OPC_MOV_D
= FOP(6, FMT_D
),
7165 OPC_NEG_D
= FOP(7, FMT_D
),
7166 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7167 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7168 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7169 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7170 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7171 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7172 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7173 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7174 OPC_MOVCF_D
= FOP(17, FMT_D
),
7175 OPC_MOVZ_D
= FOP(18, FMT_D
),
7176 OPC_MOVN_D
= FOP(19, FMT_D
),
7177 OPC_RECIP_D
= FOP(21, FMT_D
),
7178 OPC_RSQRT_D
= FOP(22, FMT_D
),
7179 OPC_RECIP2_D
= FOP(28, FMT_D
),
7180 OPC_RECIP1_D
= FOP(29, FMT_D
),
7181 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7182 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7183 OPC_CVT_S_D
= FOP(32, FMT_D
),
7184 OPC_CVT_W_D
= FOP(36, FMT_D
),
7185 OPC_CVT_L_D
= FOP(37, FMT_D
),
7186 OPC_CMP_F_D
= FOP (48, FMT_D
),
7187 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7188 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7189 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7190 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7191 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7192 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7193 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7194 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7195 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7196 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7197 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7198 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7199 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7200 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7201 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7203 OPC_CVT_S_W
= FOP(32, FMT_W
),
7204 OPC_CVT_D_W
= FOP(33, FMT_W
),
7205 OPC_CVT_S_L
= FOP(32, FMT_L
),
7206 OPC_CVT_D_L
= FOP(33, FMT_L
),
7207 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7209 OPC_ADD_PS
= FOP(0, FMT_PS
),
7210 OPC_SUB_PS
= FOP(1, FMT_PS
),
7211 OPC_MUL_PS
= FOP(2, FMT_PS
),
7212 OPC_DIV_PS
= FOP(3, FMT_PS
),
7213 OPC_ABS_PS
= FOP(5, FMT_PS
),
7214 OPC_MOV_PS
= FOP(6, FMT_PS
),
7215 OPC_NEG_PS
= FOP(7, FMT_PS
),
7216 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7217 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7218 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7219 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7220 OPC_MULR_PS
= FOP(26, FMT_PS
),
7221 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7222 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7223 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7224 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7226 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7227 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7228 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7229 OPC_PLL_PS
= FOP(44, FMT_PS
),
7230 OPC_PLU_PS
= FOP(45, FMT_PS
),
7231 OPC_PUL_PS
= FOP(46, FMT_PS
),
7232 OPC_PUU_PS
= FOP(47, FMT_PS
),
7233 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7234 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7235 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7236 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7237 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7238 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7239 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7240 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7241 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7242 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7243 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7244 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7245 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7246 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7247 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7248 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7251 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7253 const char *opn
= "cp1 move";
7254 TCGv t0
= tcg_temp_new();
7259 TCGv_i32 fp0
= tcg_temp_new_i32();
7261 gen_load_fpr32(fp0
, fs
);
7262 tcg_gen_ext_i32_tl(t0
, fp0
);
7263 tcg_temp_free_i32(fp0
);
7265 gen_store_gpr(t0
, rt
);
7269 gen_load_gpr(t0
, rt
);
7271 TCGv_i32 fp0
= tcg_temp_new_i32();
7273 tcg_gen_trunc_tl_i32(fp0
, t0
);
7274 gen_store_fpr32(fp0
, fs
);
7275 tcg_temp_free_i32(fp0
);
7280 gen_helper_1e0i(cfc1
, t0
, fs
);
7281 gen_store_gpr(t0
, rt
);
7285 gen_load_gpr(t0
, rt
);
7286 gen_helper_0e1i(ctc1
, t0
, fs
);
7289 #if defined(TARGET_MIPS64)
7291 gen_load_fpr64(ctx
, t0
, fs
);
7292 gen_store_gpr(t0
, rt
);
7296 gen_load_gpr(t0
, rt
);
7297 gen_store_fpr64(ctx
, t0
, fs
);
7303 TCGv_i32 fp0
= tcg_temp_new_i32();
7305 gen_load_fpr32h(fp0
, fs
);
7306 tcg_gen_ext_i32_tl(t0
, fp0
);
7307 tcg_temp_free_i32(fp0
);
7309 gen_store_gpr(t0
, rt
);
7313 gen_load_gpr(t0
, rt
);
7315 TCGv_i32 fp0
= tcg_temp_new_i32();
7317 tcg_gen_trunc_tl_i32(fp0
, t0
);
7318 gen_store_fpr32h(fp0
, fs
);
7319 tcg_temp_free_i32(fp0
);
7325 generate_exception (ctx
, EXCP_RI
);
7328 (void)opn
; /* avoid a compiler warning */
7329 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7335 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7351 l1
= gen_new_label();
7352 t0
= tcg_temp_new_i32();
7353 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7354 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7355 tcg_temp_free_i32(t0
);
7357 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7359 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7364 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7367 TCGv_i32 t0
= tcg_temp_new_i32();
7368 int l1
= gen_new_label();
7375 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7376 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7377 gen_load_fpr32(t0
, fs
);
7378 gen_store_fpr32(t0
, fd
);
7380 tcg_temp_free_i32(t0
);
7383 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7386 TCGv_i32 t0
= tcg_temp_new_i32();
7388 int l1
= gen_new_label();
7395 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7396 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7397 tcg_temp_free_i32(t0
);
7398 fp0
= tcg_temp_new_i64();
7399 gen_load_fpr64(ctx
, fp0
, fs
);
7400 gen_store_fpr64(ctx
, fp0
, fd
);
7401 tcg_temp_free_i64(fp0
);
7405 static inline void gen_movcf_ps (int fs
, int fd
, int cc
, int tf
)
7408 TCGv_i32 t0
= tcg_temp_new_i32();
7409 int l1
= gen_new_label();
7410 int l2
= gen_new_label();
7417 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7418 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7419 gen_load_fpr32(t0
, fs
);
7420 gen_store_fpr32(t0
, fd
);
7423 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7424 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7425 gen_load_fpr32h(t0
, fs
);
7426 gen_store_fpr32h(t0
, fd
);
7427 tcg_temp_free_i32(t0
);
7432 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7433 int ft
, int fs
, int fd
, int cc
)
7435 const char *opn
= "farith";
7436 const char *condnames
[] = {
7454 const char *condnames_abs
[] = {
7472 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7473 uint32_t func
= ctx
->opcode
& 0x3f;
7478 TCGv_i32 fp0
= tcg_temp_new_i32();
7479 TCGv_i32 fp1
= tcg_temp_new_i32();
7481 gen_load_fpr32(fp0
, fs
);
7482 gen_load_fpr32(fp1
, ft
);
7483 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7484 tcg_temp_free_i32(fp1
);
7485 gen_store_fpr32(fp0
, fd
);
7486 tcg_temp_free_i32(fp0
);
7493 TCGv_i32 fp0
= tcg_temp_new_i32();
7494 TCGv_i32 fp1
= tcg_temp_new_i32();
7496 gen_load_fpr32(fp0
, fs
);
7497 gen_load_fpr32(fp1
, ft
);
7498 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7499 tcg_temp_free_i32(fp1
);
7500 gen_store_fpr32(fp0
, fd
);
7501 tcg_temp_free_i32(fp0
);
7508 TCGv_i32 fp0
= tcg_temp_new_i32();
7509 TCGv_i32 fp1
= tcg_temp_new_i32();
7511 gen_load_fpr32(fp0
, fs
);
7512 gen_load_fpr32(fp1
, ft
);
7513 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7514 tcg_temp_free_i32(fp1
);
7515 gen_store_fpr32(fp0
, fd
);
7516 tcg_temp_free_i32(fp0
);
7523 TCGv_i32 fp0
= tcg_temp_new_i32();
7524 TCGv_i32 fp1
= tcg_temp_new_i32();
7526 gen_load_fpr32(fp0
, fs
);
7527 gen_load_fpr32(fp1
, ft
);
7528 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7529 tcg_temp_free_i32(fp1
);
7530 gen_store_fpr32(fp0
, fd
);
7531 tcg_temp_free_i32(fp0
);
7538 TCGv_i32 fp0
= tcg_temp_new_i32();
7540 gen_load_fpr32(fp0
, fs
);
7541 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7542 gen_store_fpr32(fp0
, fd
);
7543 tcg_temp_free_i32(fp0
);
7549 TCGv_i32 fp0
= tcg_temp_new_i32();
7551 gen_load_fpr32(fp0
, fs
);
7552 gen_helper_float_abs_s(fp0
, fp0
);
7553 gen_store_fpr32(fp0
, fd
);
7554 tcg_temp_free_i32(fp0
);
7560 TCGv_i32 fp0
= tcg_temp_new_i32();
7562 gen_load_fpr32(fp0
, fs
);
7563 gen_store_fpr32(fp0
, fd
);
7564 tcg_temp_free_i32(fp0
);
7570 TCGv_i32 fp0
= tcg_temp_new_i32();
7572 gen_load_fpr32(fp0
, fs
);
7573 gen_helper_float_chs_s(fp0
, fp0
);
7574 gen_store_fpr32(fp0
, fd
);
7575 tcg_temp_free_i32(fp0
);
7580 check_cp1_64bitmode(ctx
);
7582 TCGv_i32 fp32
= tcg_temp_new_i32();
7583 TCGv_i64 fp64
= tcg_temp_new_i64();
7585 gen_load_fpr32(fp32
, fs
);
7586 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7587 tcg_temp_free_i32(fp32
);
7588 gen_store_fpr64(ctx
, fp64
, fd
);
7589 tcg_temp_free_i64(fp64
);
7594 check_cp1_64bitmode(ctx
);
7596 TCGv_i32 fp32
= tcg_temp_new_i32();
7597 TCGv_i64 fp64
= tcg_temp_new_i64();
7599 gen_load_fpr32(fp32
, fs
);
7600 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7601 tcg_temp_free_i32(fp32
);
7602 gen_store_fpr64(ctx
, fp64
, fd
);
7603 tcg_temp_free_i64(fp64
);
7608 check_cp1_64bitmode(ctx
);
7610 TCGv_i32 fp32
= tcg_temp_new_i32();
7611 TCGv_i64 fp64
= tcg_temp_new_i64();
7613 gen_load_fpr32(fp32
, fs
);
7614 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7615 tcg_temp_free_i32(fp32
);
7616 gen_store_fpr64(ctx
, fp64
, fd
);
7617 tcg_temp_free_i64(fp64
);
7622 check_cp1_64bitmode(ctx
);
7624 TCGv_i32 fp32
= tcg_temp_new_i32();
7625 TCGv_i64 fp64
= tcg_temp_new_i64();
7627 gen_load_fpr32(fp32
, fs
);
7628 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7629 tcg_temp_free_i32(fp32
);
7630 gen_store_fpr64(ctx
, fp64
, fd
);
7631 tcg_temp_free_i64(fp64
);
7637 TCGv_i32 fp0
= tcg_temp_new_i32();
7639 gen_load_fpr32(fp0
, fs
);
7640 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7641 gen_store_fpr32(fp0
, fd
);
7642 tcg_temp_free_i32(fp0
);
7648 TCGv_i32 fp0
= tcg_temp_new_i32();
7650 gen_load_fpr32(fp0
, fs
);
7651 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7652 gen_store_fpr32(fp0
, fd
);
7653 tcg_temp_free_i32(fp0
);
7659 TCGv_i32 fp0
= tcg_temp_new_i32();
7661 gen_load_fpr32(fp0
, fs
);
7662 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7663 gen_store_fpr32(fp0
, fd
);
7664 tcg_temp_free_i32(fp0
);
7670 TCGv_i32 fp0
= tcg_temp_new_i32();
7672 gen_load_fpr32(fp0
, fs
);
7673 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7674 gen_store_fpr32(fp0
, fd
);
7675 tcg_temp_free_i32(fp0
);
7680 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7685 int l1
= gen_new_label();
7689 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7691 fp0
= tcg_temp_new_i32();
7692 gen_load_fpr32(fp0
, fs
);
7693 gen_store_fpr32(fp0
, fd
);
7694 tcg_temp_free_i32(fp0
);
7701 int l1
= gen_new_label();
7705 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7706 fp0
= tcg_temp_new_i32();
7707 gen_load_fpr32(fp0
, fs
);
7708 gen_store_fpr32(fp0
, fd
);
7709 tcg_temp_free_i32(fp0
);
7718 TCGv_i32 fp0
= tcg_temp_new_i32();
7720 gen_load_fpr32(fp0
, fs
);
7721 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7722 gen_store_fpr32(fp0
, fd
);
7723 tcg_temp_free_i32(fp0
);
7730 TCGv_i32 fp0
= tcg_temp_new_i32();
7732 gen_load_fpr32(fp0
, fs
);
7733 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7734 gen_store_fpr32(fp0
, fd
);
7735 tcg_temp_free_i32(fp0
);
7740 check_cp1_64bitmode(ctx
);
7742 TCGv_i32 fp0
= tcg_temp_new_i32();
7743 TCGv_i32 fp1
= tcg_temp_new_i32();
7745 gen_load_fpr32(fp0
, fs
);
7746 gen_load_fpr32(fp1
, ft
);
7747 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7748 tcg_temp_free_i32(fp1
);
7749 gen_store_fpr32(fp0
, fd
);
7750 tcg_temp_free_i32(fp0
);
7755 check_cp1_64bitmode(ctx
);
7757 TCGv_i32 fp0
= tcg_temp_new_i32();
7759 gen_load_fpr32(fp0
, fs
);
7760 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7761 gen_store_fpr32(fp0
, fd
);
7762 tcg_temp_free_i32(fp0
);
7767 check_cp1_64bitmode(ctx
);
7769 TCGv_i32 fp0
= tcg_temp_new_i32();
7771 gen_load_fpr32(fp0
, fs
);
7772 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7773 gen_store_fpr32(fp0
, fd
);
7774 tcg_temp_free_i32(fp0
);
7779 check_cp1_64bitmode(ctx
);
7781 TCGv_i32 fp0
= tcg_temp_new_i32();
7782 TCGv_i32 fp1
= tcg_temp_new_i32();
7784 gen_load_fpr32(fp0
, fs
);
7785 gen_load_fpr32(fp1
, ft
);
7786 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7787 tcg_temp_free_i32(fp1
);
7788 gen_store_fpr32(fp0
, fd
);
7789 tcg_temp_free_i32(fp0
);
7794 check_cp1_registers(ctx
, fd
);
7796 TCGv_i32 fp32
= tcg_temp_new_i32();
7797 TCGv_i64 fp64
= tcg_temp_new_i64();
7799 gen_load_fpr32(fp32
, fs
);
7800 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7801 tcg_temp_free_i32(fp32
);
7802 gen_store_fpr64(ctx
, fp64
, fd
);
7803 tcg_temp_free_i64(fp64
);
7809 TCGv_i32 fp0
= tcg_temp_new_i32();
7811 gen_load_fpr32(fp0
, fs
);
7812 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7813 gen_store_fpr32(fp0
, fd
);
7814 tcg_temp_free_i32(fp0
);
7819 check_cp1_64bitmode(ctx
);
7821 TCGv_i32 fp32
= tcg_temp_new_i32();
7822 TCGv_i64 fp64
= tcg_temp_new_i64();
7824 gen_load_fpr32(fp32
, fs
);
7825 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7826 tcg_temp_free_i32(fp32
);
7827 gen_store_fpr64(ctx
, fp64
, fd
);
7828 tcg_temp_free_i64(fp64
);
7833 check_cp1_64bitmode(ctx
);
7835 TCGv_i64 fp64
= tcg_temp_new_i64();
7836 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7837 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7839 gen_load_fpr32(fp32_0
, fs
);
7840 gen_load_fpr32(fp32_1
, ft
);
7841 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7842 tcg_temp_free_i32(fp32_1
);
7843 tcg_temp_free_i32(fp32_0
);
7844 gen_store_fpr64(ctx
, fp64
, fd
);
7845 tcg_temp_free_i64(fp64
);
7858 case OPC_CMP_NGLE_S
:
7865 if (ctx
->opcode
& (1 << 6)) {
7866 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7867 opn
= condnames_abs
[func
-48];
7869 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7870 opn
= condnames
[func
-48];
7874 check_cp1_registers(ctx
, fs
| ft
| fd
);
7876 TCGv_i64 fp0
= tcg_temp_new_i64();
7877 TCGv_i64 fp1
= tcg_temp_new_i64();
7879 gen_load_fpr64(ctx
, fp0
, fs
);
7880 gen_load_fpr64(ctx
, fp1
, ft
);
7881 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7882 tcg_temp_free_i64(fp1
);
7883 gen_store_fpr64(ctx
, fp0
, fd
);
7884 tcg_temp_free_i64(fp0
);
7890 check_cp1_registers(ctx
, fs
| ft
| fd
);
7892 TCGv_i64 fp0
= tcg_temp_new_i64();
7893 TCGv_i64 fp1
= tcg_temp_new_i64();
7895 gen_load_fpr64(ctx
, fp0
, fs
);
7896 gen_load_fpr64(ctx
, fp1
, ft
);
7897 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7898 tcg_temp_free_i64(fp1
);
7899 gen_store_fpr64(ctx
, fp0
, fd
);
7900 tcg_temp_free_i64(fp0
);
7906 check_cp1_registers(ctx
, fs
| ft
| fd
);
7908 TCGv_i64 fp0
= tcg_temp_new_i64();
7909 TCGv_i64 fp1
= tcg_temp_new_i64();
7911 gen_load_fpr64(ctx
, fp0
, fs
);
7912 gen_load_fpr64(ctx
, fp1
, ft
);
7913 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7914 tcg_temp_free_i64(fp1
);
7915 gen_store_fpr64(ctx
, fp0
, fd
);
7916 tcg_temp_free_i64(fp0
);
7922 check_cp1_registers(ctx
, fs
| ft
| fd
);
7924 TCGv_i64 fp0
= tcg_temp_new_i64();
7925 TCGv_i64 fp1
= tcg_temp_new_i64();
7927 gen_load_fpr64(ctx
, fp0
, fs
);
7928 gen_load_fpr64(ctx
, fp1
, ft
);
7929 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7930 tcg_temp_free_i64(fp1
);
7931 gen_store_fpr64(ctx
, fp0
, fd
);
7932 tcg_temp_free_i64(fp0
);
7938 check_cp1_registers(ctx
, fs
| fd
);
7940 TCGv_i64 fp0
= tcg_temp_new_i64();
7942 gen_load_fpr64(ctx
, fp0
, fs
);
7943 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7944 gen_store_fpr64(ctx
, fp0
, fd
);
7945 tcg_temp_free_i64(fp0
);
7950 check_cp1_registers(ctx
, fs
| fd
);
7952 TCGv_i64 fp0
= tcg_temp_new_i64();
7954 gen_load_fpr64(ctx
, fp0
, fs
);
7955 gen_helper_float_abs_d(fp0
, fp0
);
7956 gen_store_fpr64(ctx
, fp0
, fd
);
7957 tcg_temp_free_i64(fp0
);
7962 check_cp1_registers(ctx
, fs
| fd
);
7964 TCGv_i64 fp0
= tcg_temp_new_i64();
7966 gen_load_fpr64(ctx
, fp0
, fs
);
7967 gen_store_fpr64(ctx
, fp0
, fd
);
7968 tcg_temp_free_i64(fp0
);
7973 check_cp1_registers(ctx
, fs
| fd
);
7975 TCGv_i64 fp0
= tcg_temp_new_i64();
7977 gen_load_fpr64(ctx
, fp0
, fs
);
7978 gen_helper_float_chs_d(fp0
, fp0
);
7979 gen_store_fpr64(ctx
, fp0
, fd
);
7980 tcg_temp_free_i64(fp0
);
7985 check_cp1_64bitmode(ctx
);
7987 TCGv_i64 fp0
= tcg_temp_new_i64();
7989 gen_load_fpr64(ctx
, fp0
, fs
);
7990 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
7991 gen_store_fpr64(ctx
, fp0
, fd
);
7992 tcg_temp_free_i64(fp0
);
7997 check_cp1_64bitmode(ctx
);
7999 TCGv_i64 fp0
= tcg_temp_new_i64();
8001 gen_load_fpr64(ctx
, fp0
, fs
);
8002 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
8003 gen_store_fpr64(ctx
, fp0
, fd
);
8004 tcg_temp_free_i64(fp0
);
8009 check_cp1_64bitmode(ctx
);
8011 TCGv_i64 fp0
= tcg_temp_new_i64();
8013 gen_load_fpr64(ctx
, fp0
, fs
);
8014 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
8015 gen_store_fpr64(ctx
, fp0
, fd
);
8016 tcg_temp_free_i64(fp0
);
8021 check_cp1_64bitmode(ctx
);
8023 TCGv_i64 fp0
= tcg_temp_new_i64();
8025 gen_load_fpr64(ctx
, fp0
, fs
);
8026 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8027 gen_store_fpr64(ctx
, fp0
, fd
);
8028 tcg_temp_free_i64(fp0
);
8033 check_cp1_registers(ctx
, fs
);
8035 TCGv_i32 fp32
= tcg_temp_new_i32();
8036 TCGv_i64 fp64
= tcg_temp_new_i64();
8038 gen_load_fpr64(ctx
, fp64
, fs
);
8039 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8040 tcg_temp_free_i64(fp64
);
8041 gen_store_fpr32(fp32
, fd
);
8042 tcg_temp_free_i32(fp32
);
8047 check_cp1_registers(ctx
, fs
);
8049 TCGv_i32 fp32
= tcg_temp_new_i32();
8050 TCGv_i64 fp64
= tcg_temp_new_i64();
8052 gen_load_fpr64(ctx
, fp64
, fs
);
8053 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8054 tcg_temp_free_i64(fp64
);
8055 gen_store_fpr32(fp32
, fd
);
8056 tcg_temp_free_i32(fp32
);
8061 check_cp1_registers(ctx
, fs
);
8063 TCGv_i32 fp32
= tcg_temp_new_i32();
8064 TCGv_i64 fp64
= tcg_temp_new_i64();
8066 gen_load_fpr64(ctx
, fp64
, fs
);
8067 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8068 tcg_temp_free_i64(fp64
);
8069 gen_store_fpr32(fp32
, fd
);
8070 tcg_temp_free_i32(fp32
);
8075 check_cp1_registers(ctx
, fs
);
8077 TCGv_i32 fp32
= tcg_temp_new_i32();
8078 TCGv_i64 fp64
= tcg_temp_new_i64();
8080 gen_load_fpr64(ctx
, fp64
, fs
);
8081 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8082 tcg_temp_free_i64(fp64
);
8083 gen_store_fpr32(fp32
, fd
);
8084 tcg_temp_free_i32(fp32
);
8089 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8094 int l1
= gen_new_label();
8098 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8100 fp0
= tcg_temp_new_i64();
8101 gen_load_fpr64(ctx
, fp0
, fs
);
8102 gen_store_fpr64(ctx
, fp0
, fd
);
8103 tcg_temp_free_i64(fp0
);
8110 int l1
= gen_new_label();
8114 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8115 fp0
= tcg_temp_new_i64();
8116 gen_load_fpr64(ctx
, fp0
, fs
);
8117 gen_store_fpr64(ctx
, fp0
, fd
);
8118 tcg_temp_free_i64(fp0
);
8125 check_cp1_64bitmode(ctx
);
8127 TCGv_i64 fp0
= tcg_temp_new_i64();
8129 gen_load_fpr64(ctx
, fp0
, fs
);
8130 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8131 gen_store_fpr64(ctx
, fp0
, fd
);
8132 tcg_temp_free_i64(fp0
);
8137 check_cp1_64bitmode(ctx
);
8139 TCGv_i64 fp0
= tcg_temp_new_i64();
8141 gen_load_fpr64(ctx
, fp0
, fs
);
8142 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8143 gen_store_fpr64(ctx
, fp0
, fd
);
8144 tcg_temp_free_i64(fp0
);
8149 check_cp1_64bitmode(ctx
);
8151 TCGv_i64 fp0
= tcg_temp_new_i64();
8152 TCGv_i64 fp1
= tcg_temp_new_i64();
8154 gen_load_fpr64(ctx
, fp0
, fs
);
8155 gen_load_fpr64(ctx
, fp1
, ft
);
8156 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8157 tcg_temp_free_i64(fp1
);
8158 gen_store_fpr64(ctx
, fp0
, fd
);
8159 tcg_temp_free_i64(fp0
);
8164 check_cp1_64bitmode(ctx
);
8166 TCGv_i64 fp0
= tcg_temp_new_i64();
8168 gen_load_fpr64(ctx
, fp0
, fs
);
8169 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8170 gen_store_fpr64(ctx
, fp0
, fd
);
8171 tcg_temp_free_i64(fp0
);
8176 check_cp1_64bitmode(ctx
);
8178 TCGv_i64 fp0
= tcg_temp_new_i64();
8180 gen_load_fpr64(ctx
, fp0
, fs
);
8181 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8182 gen_store_fpr64(ctx
, fp0
, fd
);
8183 tcg_temp_free_i64(fp0
);
8188 check_cp1_64bitmode(ctx
);
8190 TCGv_i64 fp0
= tcg_temp_new_i64();
8191 TCGv_i64 fp1
= tcg_temp_new_i64();
8193 gen_load_fpr64(ctx
, fp0
, fs
);
8194 gen_load_fpr64(ctx
, fp1
, ft
);
8195 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8196 tcg_temp_free_i64(fp1
);
8197 gen_store_fpr64(ctx
, fp0
, fd
);
8198 tcg_temp_free_i64(fp0
);
8211 case OPC_CMP_NGLE_D
:
8218 if (ctx
->opcode
& (1 << 6)) {
8219 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8220 opn
= condnames_abs
[func
-48];
8222 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8223 opn
= condnames
[func
-48];
8227 check_cp1_registers(ctx
, fs
);
8229 TCGv_i32 fp32
= tcg_temp_new_i32();
8230 TCGv_i64 fp64
= tcg_temp_new_i64();
8232 gen_load_fpr64(ctx
, fp64
, fs
);
8233 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8234 tcg_temp_free_i64(fp64
);
8235 gen_store_fpr32(fp32
, fd
);
8236 tcg_temp_free_i32(fp32
);
8241 check_cp1_registers(ctx
, fs
);
8243 TCGv_i32 fp32
= tcg_temp_new_i32();
8244 TCGv_i64 fp64
= tcg_temp_new_i64();
8246 gen_load_fpr64(ctx
, fp64
, fs
);
8247 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8248 tcg_temp_free_i64(fp64
);
8249 gen_store_fpr32(fp32
, fd
);
8250 tcg_temp_free_i32(fp32
);
8255 check_cp1_64bitmode(ctx
);
8257 TCGv_i64 fp0
= tcg_temp_new_i64();
8259 gen_load_fpr64(ctx
, fp0
, fs
);
8260 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8261 gen_store_fpr64(ctx
, fp0
, fd
);
8262 tcg_temp_free_i64(fp0
);
8268 TCGv_i32 fp0
= tcg_temp_new_i32();
8270 gen_load_fpr32(fp0
, fs
);
8271 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8272 gen_store_fpr32(fp0
, fd
);
8273 tcg_temp_free_i32(fp0
);
8278 check_cp1_registers(ctx
, fd
);
8280 TCGv_i32 fp32
= tcg_temp_new_i32();
8281 TCGv_i64 fp64
= tcg_temp_new_i64();
8283 gen_load_fpr32(fp32
, fs
);
8284 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8285 tcg_temp_free_i32(fp32
);
8286 gen_store_fpr64(ctx
, fp64
, fd
);
8287 tcg_temp_free_i64(fp64
);
8292 check_cp1_64bitmode(ctx
);
8294 TCGv_i32 fp32
= tcg_temp_new_i32();
8295 TCGv_i64 fp64
= tcg_temp_new_i64();
8297 gen_load_fpr64(ctx
, fp64
, fs
);
8298 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8299 tcg_temp_free_i64(fp64
);
8300 gen_store_fpr32(fp32
, fd
);
8301 tcg_temp_free_i32(fp32
);
8306 check_cp1_64bitmode(ctx
);
8308 TCGv_i64 fp0
= tcg_temp_new_i64();
8310 gen_load_fpr64(ctx
, fp0
, fs
);
8311 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8312 gen_store_fpr64(ctx
, fp0
, fd
);
8313 tcg_temp_free_i64(fp0
);
8318 check_cp1_64bitmode(ctx
);
8320 TCGv_i64 fp0
= tcg_temp_new_i64();
8322 gen_load_fpr64(ctx
, fp0
, fs
);
8323 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8324 gen_store_fpr64(ctx
, fp0
, fd
);
8325 tcg_temp_free_i64(fp0
);
8330 check_cp1_64bitmode(ctx
);
8332 TCGv_i64 fp0
= tcg_temp_new_i64();
8333 TCGv_i64 fp1
= tcg_temp_new_i64();
8335 gen_load_fpr64(ctx
, fp0
, fs
);
8336 gen_load_fpr64(ctx
, fp1
, ft
);
8337 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8338 tcg_temp_free_i64(fp1
);
8339 gen_store_fpr64(ctx
, fp0
, fd
);
8340 tcg_temp_free_i64(fp0
);
8345 check_cp1_64bitmode(ctx
);
8347 TCGv_i64 fp0
= tcg_temp_new_i64();
8348 TCGv_i64 fp1
= tcg_temp_new_i64();
8350 gen_load_fpr64(ctx
, fp0
, fs
);
8351 gen_load_fpr64(ctx
, fp1
, ft
);
8352 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8353 tcg_temp_free_i64(fp1
);
8354 gen_store_fpr64(ctx
, fp0
, fd
);
8355 tcg_temp_free_i64(fp0
);
8360 check_cp1_64bitmode(ctx
);
8362 TCGv_i64 fp0
= tcg_temp_new_i64();
8363 TCGv_i64 fp1
= tcg_temp_new_i64();
8365 gen_load_fpr64(ctx
, fp0
, fs
);
8366 gen_load_fpr64(ctx
, fp1
, ft
);
8367 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8368 tcg_temp_free_i64(fp1
);
8369 gen_store_fpr64(ctx
, fp0
, fd
);
8370 tcg_temp_free_i64(fp0
);
8375 check_cp1_64bitmode(ctx
);
8377 TCGv_i64 fp0
= tcg_temp_new_i64();
8379 gen_load_fpr64(ctx
, fp0
, fs
);
8380 gen_helper_float_abs_ps(fp0
, fp0
);
8381 gen_store_fpr64(ctx
, fp0
, fd
);
8382 tcg_temp_free_i64(fp0
);
8387 check_cp1_64bitmode(ctx
);
8389 TCGv_i64 fp0
= tcg_temp_new_i64();
8391 gen_load_fpr64(ctx
, fp0
, fs
);
8392 gen_store_fpr64(ctx
, fp0
, fd
);
8393 tcg_temp_free_i64(fp0
);
8398 check_cp1_64bitmode(ctx
);
8400 TCGv_i64 fp0
= tcg_temp_new_i64();
8402 gen_load_fpr64(ctx
, fp0
, fs
);
8403 gen_helper_float_chs_ps(fp0
, fp0
);
8404 gen_store_fpr64(ctx
, fp0
, fd
);
8405 tcg_temp_free_i64(fp0
);
8410 check_cp1_64bitmode(ctx
);
8411 gen_movcf_ps(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8415 check_cp1_64bitmode(ctx
);
8417 int l1
= gen_new_label();
8421 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8422 fp0
= tcg_temp_new_i64();
8423 gen_load_fpr64(ctx
, fp0
, fs
);
8424 gen_store_fpr64(ctx
, fp0
, fd
);
8425 tcg_temp_free_i64(fp0
);
8431 check_cp1_64bitmode(ctx
);
8433 int l1
= gen_new_label();
8437 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8438 fp0
= tcg_temp_new_i64();
8439 gen_load_fpr64(ctx
, fp0
, fs
);
8440 gen_store_fpr64(ctx
, fp0
, fd
);
8441 tcg_temp_free_i64(fp0
);
8448 check_cp1_64bitmode(ctx
);
8450 TCGv_i64 fp0
= tcg_temp_new_i64();
8451 TCGv_i64 fp1
= tcg_temp_new_i64();
8453 gen_load_fpr64(ctx
, fp0
, ft
);
8454 gen_load_fpr64(ctx
, fp1
, fs
);
8455 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8456 tcg_temp_free_i64(fp1
);
8457 gen_store_fpr64(ctx
, fp0
, fd
);
8458 tcg_temp_free_i64(fp0
);
8463 check_cp1_64bitmode(ctx
);
8465 TCGv_i64 fp0
= tcg_temp_new_i64();
8466 TCGv_i64 fp1
= tcg_temp_new_i64();
8468 gen_load_fpr64(ctx
, fp0
, ft
);
8469 gen_load_fpr64(ctx
, fp1
, fs
);
8470 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8471 tcg_temp_free_i64(fp1
);
8472 gen_store_fpr64(ctx
, fp0
, fd
);
8473 tcg_temp_free_i64(fp0
);
8478 check_cp1_64bitmode(ctx
);
8480 TCGv_i64 fp0
= tcg_temp_new_i64();
8481 TCGv_i64 fp1
= tcg_temp_new_i64();
8483 gen_load_fpr64(ctx
, fp0
, fs
);
8484 gen_load_fpr64(ctx
, fp1
, ft
);
8485 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8486 tcg_temp_free_i64(fp1
);
8487 gen_store_fpr64(ctx
, fp0
, fd
);
8488 tcg_temp_free_i64(fp0
);
8493 check_cp1_64bitmode(ctx
);
8495 TCGv_i64 fp0
= tcg_temp_new_i64();
8497 gen_load_fpr64(ctx
, fp0
, fs
);
8498 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
8499 gen_store_fpr64(ctx
, fp0
, fd
);
8500 tcg_temp_free_i64(fp0
);
8505 check_cp1_64bitmode(ctx
);
8507 TCGv_i64 fp0
= tcg_temp_new_i64();
8509 gen_load_fpr64(ctx
, fp0
, fs
);
8510 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8511 gen_store_fpr64(ctx
, fp0
, fd
);
8512 tcg_temp_free_i64(fp0
);
8517 check_cp1_64bitmode(ctx
);
8519 TCGv_i64 fp0
= tcg_temp_new_i64();
8520 TCGv_i64 fp1
= tcg_temp_new_i64();
8522 gen_load_fpr64(ctx
, fp0
, fs
);
8523 gen_load_fpr64(ctx
, fp1
, ft
);
8524 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8525 tcg_temp_free_i64(fp1
);
8526 gen_store_fpr64(ctx
, fp0
, fd
);
8527 tcg_temp_free_i64(fp0
);
8532 check_cp1_64bitmode(ctx
);
8534 TCGv_i32 fp0
= tcg_temp_new_i32();
8536 gen_load_fpr32h(fp0
, fs
);
8537 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8538 gen_store_fpr32(fp0
, fd
);
8539 tcg_temp_free_i32(fp0
);
8544 check_cp1_64bitmode(ctx
);
8546 TCGv_i64 fp0
= tcg_temp_new_i64();
8548 gen_load_fpr64(ctx
, fp0
, fs
);
8549 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8550 gen_store_fpr64(ctx
, fp0
, fd
);
8551 tcg_temp_free_i64(fp0
);
8556 check_cp1_64bitmode(ctx
);
8558 TCGv_i32 fp0
= tcg_temp_new_i32();
8560 gen_load_fpr32(fp0
, fs
);
8561 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8562 gen_store_fpr32(fp0
, fd
);
8563 tcg_temp_free_i32(fp0
);
8568 check_cp1_64bitmode(ctx
);
8570 TCGv_i32 fp0
= tcg_temp_new_i32();
8571 TCGv_i32 fp1
= tcg_temp_new_i32();
8573 gen_load_fpr32(fp0
, fs
);
8574 gen_load_fpr32(fp1
, ft
);
8575 gen_store_fpr32h(fp0
, fd
);
8576 gen_store_fpr32(fp1
, fd
);
8577 tcg_temp_free_i32(fp0
);
8578 tcg_temp_free_i32(fp1
);
8583 check_cp1_64bitmode(ctx
);
8585 TCGv_i32 fp0
= tcg_temp_new_i32();
8586 TCGv_i32 fp1
= tcg_temp_new_i32();
8588 gen_load_fpr32(fp0
, fs
);
8589 gen_load_fpr32h(fp1
, ft
);
8590 gen_store_fpr32(fp1
, fd
);
8591 gen_store_fpr32h(fp0
, fd
);
8592 tcg_temp_free_i32(fp0
);
8593 tcg_temp_free_i32(fp1
);
8598 check_cp1_64bitmode(ctx
);
8600 TCGv_i32 fp0
= tcg_temp_new_i32();
8601 TCGv_i32 fp1
= tcg_temp_new_i32();
8603 gen_load_fpr32h(fp0
, fs
);
8604 gen_load_fpr32(fp1
, ft
);
8605 gen_store_fpr32(fp1
, fd
);
8606 gen_store_fpr32h(fp0
, fd
);
8607 tcg_temp_free_i32(fp0
);
8608 tcg_temp_free_i32(fp1
);
8613 check_cp1_64bitmode(ctx
);
8615 TCGv_i32 fp0
= tcg_temp_new_i32();
8616 TCGv_i32 fp1
= tcg_temp_new_i32();
8618 gen_load_fpr32h(fp0
, fs
);
8619 gen_load_fpr32h(fp1
, ft
);
8620 gen_store_fpr32(fp1
, fd
);
8621 gen_store_fpr32h(fp0
, fd
);
8622 tcg_temp_free_i32(fp0
);
8623 tcg_temp_free_i32(fp1
);
8630 case OPC_CMP_UEQ_PS
:
8631 case OPC_CMP_OLT_PS
:
8632 case OPC_CMP_ULT_PS
:
8633 case OPC_CMP_OLE_PS
:
8634 case OPC_CMP_ULE_PS
:
8636 case OPC_CMP_NGLE_PS
:
8637 case OPC_CMP_SEQ_PS
:
8638 case OPC_CMP_NGL_PS
:
8640 case OPC_CMP_NGE_PS
:
8642 case OPC_CMP_NGT_PS
:
8643 if (ctx
->opcode
& (1 << 6)) {
8644 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8645 opn
= condnames_abs
[func
-48];
8647 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8648 opn
= condnames
[func
-48];
8653 generate_exception (ctx
, EXCP_RI
);
8656 (void)opn
; /* avoid a compiler warning */
8659 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8662 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8665 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8670 /* Coprocessor 3 (FPU) */
8671 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8672 int fd
, int fs
, int base
, int index
)
8674 const char *opn
= "extended float load/store";
8676 TCGv t0
= tcg_temp_new();
8679 gen_load_gpr(t0
, index
);
8680 } else if (index
== 0) {
8681 gen_load_gpr(t0
, base
);
8683 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8685 /* Don't do NOP if destination is zero: we must perform the actual
8691 TCGv_i32 fp0
= tcg_temp_new_i32();
8693 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
8694 tcg_gen_trunc_tl_i32(fp0
, t0
);
8695 gen_store_fpr32(fp0
, fd
);
8696 tcg_temp_free_i32(fp0
);
8702 check_cp1_registers(ctx
, fd
);
8704 TCGv_i64 fp0
= tcg_temp_new_i64();
8706 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8707 gen_store_fpr64(ctx
, fp0
, fd
);
8708 tcg_temp_free_i64(fp0
);
8713 check_cp1_64bitmode(ctx
);
8714 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8716 TCGv_i64 fp0
= tcg_temp_new_i64();
8718 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8719 gen_store_fpr64(ctx
, fp0
, fd
);
8720 tcg_temp_free_i64(fp0
);
8727 TCGv_i32 fp0
= tcg_temp_new_i32();
8728 TCGv t1
= tcg_temp_new();
8730 gen_load_fpr32(fp0
, fs
);
8731 tcg_gen_extu_i32_tl(t1
, fp0
);
8732 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
8733 tcg_temp_free_i32(fp0
);
8741 check_cp1_registers(ctx
, fs
);
8743 TCGv_i64 fp0
= tcg_temp_new_i64();
8745 gen_load_fpr64(ctx
, fp0
, fs
);
8746 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8747 tcg_temp_free_i64(fp0
);
8753 check_cp1_64bitmode(ctx
);
8754 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8756 TCGv_i64 fp0
= tcg_temp_new_i64();
8758 gen_load_fpr64(ctx
, fp0
, fs
);
8759 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8760 tcg_temp_free_i64(fp0
);
8767 (void)opn
; (void)store
; /* avoid compiler warnings */
8768 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8769 regnames
[index
], regnames
[base
]);
8772 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8773 int fd
, int fr
, int fs
, int ft
)
8775 const char *opn
= "flt3_arith";
8779 check_cp1_64bitmode(ctx
);
8781 TCGv t0
= tcg_temp_local_new();
8782 TCGv_i32 fp
= tcg_temp_new_i32();
8783 TCGv_i32 fph
= tcg_temp_new_i32();
8784 int l1
= gen_new_label();
8785 int l2
= gen_new_label();
8787 gen_load_gpr(t0
, fr
);
8788 tcg_gen_andi_tl(t0
, t0
, 0x7);
8790 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8791 gen_load_fpr32(fp
, fs
);
8792 gen_load_fpr32h(fph
, fs
);
8793 gen_store_fpr32(fp
, fd
);
8794 gen_store_fpr32h(fph
, fd
);
8797 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8799 #ifdef TARGET_WORDS_BIGENDIAN
8800 gen_load_fpr32(fp
, fs
);
8801 gen_load_fpr32h(fph
, ft
);
8802 gen_store_fpr32h(fp
, fd
);
8803 gen_store_fpr32(fph
, fd
);
8805 gen_load_fpr32h(fph
, fs
);
8806 gen_load_fpr32(fp
, ft
);
8807 gen_store_fpr32(fph
, fd
);
8808 gen_store_fpr32h(fp
, fd
);
8811 tcg_temp_free_i32(fp
);
8812 tcg_temp_free_i32(fph
);
8819 TCGv_i32 fp0
= tcg_temp_new_i32();
8820 TCGv_i32 fp1
= tcg_temp_new_i32();
8821 TCGv_i32 fp2
= tcg_temp_new_i32();
8823 gen_load_fpr32(fp0
, fs
);
8824 gen_load_fpr32(fp1
, ft
);
8825 gen_load_fpr32(fp2
, fr
);
8826 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8827 tcg_temp_free_i32(fp0
);
8828 tcg_temp_free_i32(fp1
);
8829 gen_store_fpr32(fp2
, fd
);
8830 tcg_temp_free_i32(fp2
);
8836 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8838 TCGv_i64 fp0
= tcg_temp_new_i64();
8839 TCGv_i64 fp1
= tcg_temp_new_i64();
8840 TCGv_i64 fp2
= tcg_temp_new_i64();
8842 gen_load_fpr64(ctx
, fp0
, fs
);
8843 gen_load_fpr64(ctx
, fp1
, ft
);
8844 gen_load_fpr64(ctx
, fp2
, fr
);
8845 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8846 tcg_temp_free_i64(fp0
);
8847 tcg_temp_free_i64(fp1
);
8848 gen_store_fpr64(ctx
, fp2
, fd
);
8849 tcg_temp_free_i64(fp2
);
8854 check_cp1_64bitmode(ctx
);
8856 TCGv_i64 fp0
= tcg_temp_new_i64();
8857 TCGv_i64 fp1
= tcg_temp_new_i64();
8858 TCGv_i64 fp2
= tcg_temp_new_i64();
8860 gen_load_fpr64(ctx
, fp0
, fs
);
8861 gen_load_fpr64(ctx
, fp1
, ft
);
8862 gen_load_fpr64(ctx
, fp2
, fr
);
8863 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8864 tcg_temp_free_i64(fp0
);
8865 tcg_temp_free_i64(fp1
);
8866 gen_store_fpr64(ctx
, fp2
, fd
);
8867 tcg_temp_free_i64(fp2
);
8874 TCGv_i32 fp0
= tcg_temp_new_i32();
8875 TCGv_i32 fp1
= tcg_temp_new_i32();
8876 TCGv_i32 fp2
= tcg_temp_new_i32();
8878 gen_load_fpr32(fp0
, fs
);
8879 gen_load_fpr32(fp1
, ft
);
8880 gen_load_fpr32(fp2
, fr
);
8881 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8882 tcg_temp_free_i32(fp0
);
8883 tcg_temp_free_i32(fp1
);
8884 gen_store_fpr32(fp2
, fd
);
8885 tcg_temp_free_i32(fp2
);
8891 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8893 TCGv_i64 fp0
= tcg_temp_new_i64();
8894 TCGv_i64 fp1
= tcg_temp_new_i64();
8895 TCGv_i64 fp2
= tcg_temp_new_i64();
8897 gen_load_fpr64(ctx
, fp0
, fs
);
8898 gen_load_fpr64(ctx
, fp1
, ft
);
8899 gen_load_fpr64(ctx
, fp2
, fr
);
8900 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8901 tcg_temp_free_i64(fp0
);
8902 tcg_temp_free_i64(fp1
);
8903 gen_store_fpr64(ctx
, fp2
, fd
);
8904 tcg_temp_free_i64(fp2
);
8909 check_cp1_64bitmode(ctx
);
8911 TCGv_i64 fp0
= tcg_temp_new_i64();
8912 TCGv_i64 fp1
= tcg_temp_new_i64();
8913 TCGv_i64 fp2
= tcg_temp_new_i64();
8915 gen_load_fpr64(ctx
, fp0
, fs
);
8916 gen_load_fpr64(ctx
, fp1
, ft
);
8917 gen_load_fpr64(ctx
, fp2
, fr
);
8918 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8919 tcg_temp_free_i64(fp0
);
8920 tcg_temp_free_i64(fp1
);
8921 gen_store_fpr64(ctx
, fp2
, fd
);
8922 tcg_temp_free_i64(fp2
);
8929 TCGv_i32 fp0
= tcg_temp_new_i32();
8930 TCGv_i32 fp1
= tcg_temp_new_i32();
8931 TCGv_i32 fp2
= tcg_temp_new_i32();
8933 gen_load_fpr32(fp0
, fs
);
8934 gen_load_fpr32(fp1
, ft
);
8935 gen_load_fpr32(fp2
, fr
);
8936 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8937 tcg_temp_free_i32(fp0
);
8938 tcg_temp_free_i32(fp1
);
8939 gen_store_fpr32(fp2
, fd
);
8940 tcg_temp_free_i32(fp2
);
8946 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8948 TCGv_i64 fp0
= tcg_temp_new_i64();
8949 TCGv_i64 fp1
= tcg_temp_new_i64();
8950 TCGv_i64 fp2
= tcg_temp_new_i64();
8952 gen_load_fpr64(ctx
, fp0
, fs
);
8953 gen_load_fpr64(ctx
, fp1
, ft
);
8954 gen_load_fpr64(ctx
, fp2
, fr
);
8955 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8956 tcg_temp_free_i64(fp0
);
8957 tcg_temp_free_i64(fp1
);
8958 gen_store_fpr64(ctx
, fp2
, fd
);
8959 tcg_temp_free_i64(fp2
);
8964 check_cp1_64bitmode(ctx
);
8966 TCGv_i64 fp0
= tcg_temp_new_i64();
8967 TCGv_i64 fp1
= tcg_temp_new_i64();
8968 TCGv_i64 fp2
= tcg_temp_new_i64();
8970 gen_load_fpr64(ctx
, fp0
, fs
);
8971 gen_load_fpr64(ctx
, fp1
, ft
);
8972 gen_load_fpr64(ctx
, fp2
, fr
);
8973 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8974 tcg_temp_free_i64(fp0
);
8975 tcg_temp_free_i64(fp1
);
8976 gen_store_fpr64(ctx
, fp2
, fd
);
8977 tcg_temp_free_i64(fp2
);
8984 TCGv_i32 fp0
= tcg_temp_new_i32();
8985 TCGv_i32 fp1
= tcg_temp_new_i32();
8986 TCGv_i32 fp2
= tcg_temp_new_i32();
8988 gen_load_fpr32(fp0
, fs
);
8989 gen_load_fpr32(fp1
, ft
);
8990 gen_load_fpr32(fp2
, fr
);
8991 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8992 tcg_temp_free_i32(fp0
);
8993 tcg_temp_free_i32(fp1
);
8994 gen_store_fpr32(fp2
, fd
);
8995 tcg_temp_free_i32(fp2
);
9001 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9003 TCGv_i64 fp0
= tcg_temp_new_i64();
9004 TCGv_i64 fp1
= tcg_temp_new_i64();
9005 TCGv_i64 fp2
= tcg_temp_new_i64();
9007 gen_load_fpr64(ctx
, fp0
, fs
);
9008 gen_load_fpr64(ctx
, fp1
, ft
);
9009 gen_load_fpr64(ctx
, fp2
, fr
);
9010 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9011 tcg_temp_free_i64(fp0
);
9012 tcg_temp_free_i64(fp1
);
9013 gen_store_fpr64(ctx
, fp2
, fd
);
9014 tcg_temp_free_i64(fp2
);
9019 check_cp1_64bitmode(ctx
);
9021 TCGv_i64 fp0
= tcg_temp_new_i64();
9022 TCGv_i64 fp1
= tcg_temp_new_i64();
9023 TCGv_i64 fp2
= tcg_temp_new_i64();
9025 gen_load_fpr64(ctx
, fp0
, fs
);
9026 gen_load_fpr64(ctx
, fp1
, ft
);
9027 gen_load_fpr64(ctx
, fp2
, fr
);
9028 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9029 tcg_temp_free_i64(fp0
);
9030 tcg_temp_free_i64(fp1
);
9031 gen_store_fpr64(ctx
, fp2
, fd
);
9032 tcg_temp_free_i64(fp2
);
9038 generate_exception (ctx
, EXCP_RI
);
9041 (void)opn
; /* avoid a compiler warning */
9042 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9043 fregnames
[fs
], fregnames
[ft
]);
9046 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
9050 #if !defined(CONFIG_USER_ONLY)
9051 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9052 Therefore only check the ISA in system mode. */
9053 check_insn(ctx
, ISA_MIPS32R2
);
9055 t0
= tcg_temp_new();
9059 save_cpu_state(ctx
, 1);
9060 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9061 gen_store_gpr(t0
, rt
);
9064 save_cpu_state(ctx
, 1);
9065 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9066 gen_store_gpr(t0
, rt
);
9069 save_cpu_state(ctx
, 1);
9070 gen_helper_rdhwr_cc(t0
, cpu_env
);
9071 gen_store_gpr(t0
, rt
);
9074 save_cpu_state(ctx
, 1);
9075 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9076 gen_store_gpr(t0
, rt
);
9079 #if defined(CONFIG_USER_ONLY)
9080 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUMIPSState
, tls_value
));
9081 gen_store_gpr(t0
, rt
);
9084 /* XXX: Some CPUs implement this in hardware.
9085 Not supported yet. */
9087 default: /* Invalid */
9088 MIPS_INVAL("rdhwr");
9089 generate_exception(ctx
, EXCP_RI
);
9095 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9097 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9098 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9099 /* Branches completion */
9100 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9101 ctx
->bstate
= BS_BRANCH
;
9102 save_cpu_state(ctx
, 0);
9103 /* FIXME: Need to clear can_do_io. */
9104 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9106 /* unconditional branch */
9107 MIPS_DEBUG("unconditional branch");
9108 if (proc_hflags
& MIPS_HFLAG_BX
) {
9109 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9111 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9114 /* blikely taken case */
9115 MIPS_DEBUG("blikely branch taken");
9116 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9119 /* Conditional branch */
9120 MIPS_DEBUG("conditional branch");
9122 int l1
= gen_new_label();
9124 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9125 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9127 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9131 /* unconditional branch to register */
9132 MIPS_DEBUG("branch to register");
9133 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9134 TCGv t0
= tcg_temp_new();
9135 TCGv_i32 t1
= tcg_temp_new_i32();
9137 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9138 tcg_gen_trunc_tl_i32(t1
, t0
);
9140 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9141 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9142 tcg_gen_or_i32(hflags
, hflags
, t1
);
9143 tcg_temp_free_i32(t1
);
9145 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9147 tcg_gen_mov_tl(cpu_PC
, btarget
);
9149 if (ctx
->singlestep_enabled
) {
9150 save_cpu_state(ctx
, 0);
9151 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9156 MIPS_DEBUG("unknown branch");
9162 /* ISA extensions (ASEs) */
9163 /* MIPS16 extension to MIPS32 */
9165 /* MIPS16 major opcodes */
9167 M16_OPC_ADDIUSP
= 0x00,
9168 M16_OPC_ADDIUPC
= 0x01,
9171 M16_OPC_BEQZ
= 0x04,
9172 M16_OPC_BNEQZ
= 0x05,
9173 M16_OPC_SHIFT
= 0x06,
9175 M16_OPC_RRIA
= 0x08,
9176 M16_OPC_ADDIU8
= 0x09,
9177 M16_OPC_SLTI
= 0x0a,
9178 M16_OPC_SLTIU
= 0x0b,
9181 M16_OPC_CMPI
= 0x0e,
9185 M16_OPC_LWSP
= 0x12,
9189 M16_OPC_LWPC
= 0x16,
9193 M16_OPC_SWSP
= 0x1a,
9197 M16_OPC_EXTEND
= 0x1e,
9201 /* I8 funct field */
9220 /* RR funct field */
9254 /* I64 funct field */
9266 /* RR ry field for CNVT */
9268 RR_RY_CNVT_ZEB
= 0x0,
9269 RR_RY_CNVT_ZEH
= 0x1,
9270 RR_RY_CNVT_ZEW
= 0x2,
9271 RR_RY_CNVT_SEB
= 0x4,
9272 RR_RY_CNVT_SEH
= 0x5,
9273 RR_RY_CNVT_SEW
= 0x6,
9276 static int xlat (int r
)
9278 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9283 static void gen_mips16_save (DisasContext
*ctx
,
9284 int xsregs
, int aregs
,
9285 int do_ra
, int do_s0
, int do_s1
,
9288 TCGv t0
= tcg_temp_new();
9289 TCGv t1
= tcg_temp_new();
9319 generate_exception(ctx
, EXCP_RI
);
9325 gen_base_offset_addr(ctx
, t0
, 29, 12);
9326 gen_load_gpr(t1
, 7);
9327 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9330 gen_base_offset_addr(ctx
, t0
, 29, 8);
9331 gen_load_gpr(t1
, 6);
9332 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9335 gen_base_offset_addr(ctx
, t0
, 29, 4);
9336 gen_load_gpr(t1
, 5);
9337 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9340 gen_base_offset_addr(ctx
, t0
, 29, 0);
9341 gen_load_gpr(t1
, 4);
9342 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9345 gen_load_gpr(t0
, 29);
9347 #define DECR_AND_STORE(reg) do { \
9348 tcg_gen_subi_tl(t0, t0, 4); \
9349 gen_load_gpr(t1, reg); \
9350 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9414 generate_exception(ctx
, EXCP_RI
);
9430 #undef DECR_AND_STORE
9432 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9437 static void gen_mips16_restore (DisasContext
*ctx
,
9438 int xsregs
, int aregs
,
9439 int do_ra
, int do_s0
, int do_s1
,
9443 TCGv t0
= tcg_temp_new();
9444 TCGv t1
= tcg_temp_new();
9446 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9448 #define DECR_AND_LOAD(reg) do { \
9449 tcg_gen_subi_tl(t0, t0, 4); \
9450 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
9451 gen_store_gpr(t1, reg); \
9515 generate_exception(ctx
, EXCP_RI
);
9531 #undef DECR_AND_LOAD
9533 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9538 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9539 int is_64_bit
, int extended
)
9543 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9544 generate_exception(ctx
, EXCP_RI
);
9548 t0
= tcg_temp_new();
9550 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9551 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9553 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9559 #if defined(TARGET_MIPS64)
9560 static void decode_i64_mips16 (DisasContext
*ctx
,
9561 int ry
, int funct
, int16_t offset
,
9567 offset
= extended
? offset
: offset
<< 3;
9568 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9572 offset
= extended
? offset
: offset
<< 3;
9573 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9577 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9578 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9582 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9583 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9586 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9587 generate_exception(ctx
, EXCP_RI
);
9589 offset
= extended
? offset
: offset
<< 3;
9590 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9595 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9596 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9600 offset
= extended
? offset
: offset
<< 2;
9601 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9605 offset
= extended
? offset
: offset
<< 2;
9606 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9612 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
9615 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9616 int op
, rx
, ry
, funct
, sa
;
9617 int16_t imm
, offset
;
9619 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9620 op
= (ctx
->opcode
>> 11) & 0x1f;
9621 sa
= (ctx
->opcode
>> 22) & 0x1f;
9622 funct
= (ctx
->opcode
>> 8) & 0x7;
9623 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9624 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9625 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9626 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9627 | (ctx
->opcode
& 0x1f));
9629 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9632 case M16_OPC_ADDIUSP
:
9633 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9635 case M16_OPC_ADDIUPC
:
9636 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9639 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9640 /* No delay slot, so just process as a normal instruction */
9643 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9644 /* No delay slot, so just process as a normal instruction */
9647 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9648 /* No delay slot, so just process as a normal instruction */
9651 switch (ctx
->opcode
& 0x3) {
9653 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9656 #if defined(TARGET_MIPS64)
9658 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9660 generate_exception(ctx
, EXCP_RI
);
9664 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9667 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9671 #if defined(TARGET_MIPS64)
9674 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9678 imm
= ctx
->opcode
& 0xf;
9679 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9680 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9681 imm
= (int16_t) (imm
<< 1) >> 1;
9682 if ((ctx
->opcode
>> 4) & 0x1) {
9683 #if defined(TARGET_MIPS64)
9685 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9687 generate_exception(ctx
, EXCP_RI
);
9690 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9693 case M16_OPC_ADDIU8
:
9694 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9697 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9700 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9705 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9708 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9711 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9714 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9718 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9719 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9720 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9721 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9722 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9723 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9724 | (ctx
->opcode
& 0xf)) << 3;
9726 if (ctx
->opcode
& (1 << 7)) {
9727 gen_mips16_save(ctx
, xsregs
, aregs
,
9728 do_ra
, do_s0
, do_s1
,
9731 gen_mips16_restore(ctx
, xsregs
, aregs
,
9732 do_ra
, do_s0
, do_s1
,
9738 generate_exception(ctx
, EXCP_RI
);
9743 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9746 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9748 #if defined(TARGET_MIPS64)
9750 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9754 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9757 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9760 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9763 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9766 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9769 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9772 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9774 #if defined(TARGET_MIPS64)
9776 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9780 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9783 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9786 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9789 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9791 #if defined(TARGET_MIPS64)
9793 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9797 generate_exception(ctx
, EXCP_RI
);
9804 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
9809 int op
, cnvt_op
, op1
, offset
;
9813 op
= (ctx
->opcode
>> 11) & 0x1f;
9814 sa
= (ctx
->opcode
>> 2) & 0x7;
9815 sa
= sa
== 0 ? 8 : sa
;
9816 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9817 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9818 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9819 op1
= offset
= ctx
->opcode
& 0x1f;
9824 case M16_OPC_ADDIUSP
:
9826 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9828 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9831 case M16_OPC_ADDIUPC
:
9832 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9835 offset
= (ctx
->opcode
& 0x7ff) << 1;
9836 offset
= (int16_t)(offset
<< 4) >> 4;
9837 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9838 /* No delay slot, so just process as a normal instruction */
9841 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9842 offset
= (((ctx
->opcode
& 0x1f) << 21)
9843 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9845 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9846 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9851 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9852 /* No delay slot, so just process as a normal instruction */
9855 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9856 /* No delay slot, so just process as a normal instruction */
9859 switch (ctx
->opcode
& 0x3) {
9861 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9864 #if defined(TARGET_MIPS64)
9866 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9868 generate_exception(ctx
, EXCP_RI
);
9872 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9875 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9879 #if defined(TARGET_MIPS64)
9882 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9887 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9889 if ((ctx
->opcode
>> 4) & 1) {
9890 #if defined(TARGET_MIPS64)
9892 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9894 generate_exception(ctx
, EXCP_RI
);
9897 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9901 case M16_OPC_ADDIU8
:
9903 int16_t imm
= (int8_t) ctx
->opcode
;
9905 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9910 int16_t imm
= (uint8_t) ctx
->opcode
;
9911 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9916 int16_t imm
= (uint8_t) ctx
->opcode
;
9917 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9924 funct
= (ctx
->opcode
>> 8) & 0x7;
9927 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9928 ((int8_t)ctx
->opcode
) << 1);
9931 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9932 ((int8_t)ctx
->opcode
) << 1);
9935 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9938 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9939 ((int8_t)ctx
->opcode
) << 3);
9943 int do_ra
= ctx
->opcode
& (1 << 6);
9944 int do_s0
= ctx
->opcode
& (1 << 5);
9945 int do_s1
= ctx
->opcode
& (1 << 4);
9946 int framesize
= ctx
->opcode
& 0xf;
9948 if (framesize
== 0) {
9951 framesize
= framesize
<< 3;
9954 if (ctx
->opcode
& (1 << 7)) {
9955 gen_mips16_save(ctx
, 0, 0,
9956 do_ra
, do_s0
, do_s1
, framesize
);
9958 gen_mips16_restore(ctx
, 0, 0,
9959 do_ra
, do_s0
, do_s1
, framesize
);
9965 int rz
= xlat(ctx
->opcode
& 0x7);
9967 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9968 ((ctx
->opcode
>> 5) & 0x7);
9969 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
9973 reg32
= ctx
->opcode
& 0x1f;
9974 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
9977 generate_exception(ctx
, EXCP_RI
);
9984 int16_t imm
= (uint8_t) ctx
->opcode
;
9986 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
9991 int16_t imm
= (uint8_t) ctx
->opcode
;
9992 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
9995 #if defined(TARGET_MIPS64)
9998 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
10002 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
10005 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
10008 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10011 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
10014 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
10017 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
10020 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
10022 #if defined (TARGET_MIPS64)
10024 check_mips_64(ctx
);
10025 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
10029 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10032 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
10035 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10038 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10042 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10045 switch (ctx
->opcode
& 0x3) {
10047 mips32_op
= OPC_ADDU
;
10050 mips32_op
= OPC_SUBU
;
10052 #if defined(TARGET_MIPS64)
10054 mips32_op
= OPC_DADDU
;
10055 check_mips_64(ctx
);
10058 mips32_op
= OPC_DSUBU
;
10059 check_mips_64(ctx
);
10063 generate_exception(ctx
, EXCP_RI
);
10067 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10076 int nd
= (ctx
->opcode
>> 7) & 0x1;
10077 int link
= (ctx
->opcode
>> 6) & 0x1;
10078 int ra
= (ctx
->opcode
>> 5) & 0x1;
10081 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10086 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10093 /* XXX: not clear which exception should be raised
10094 * when in debug mode...
10096 check_insn(ctx
, ISA_MIPS32
);
10097 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10098 generate_exception(ctx
, EXCP_DBp
);
10100 generate_exception(ctx
, EXCP_DBp
);
10104 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10107 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10110 generate_exception(ctx
, EXCP_BREAK
);
10113 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10116 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10119 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10121 #if defined (TARGET_MIPS64)
10123 check_mips_64(ctx
);
10124 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10128 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10131 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10134 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10137 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10140 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10143 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10146 gen_HILO(ctx
, OPC_MFHI
, rx
);
10150 case RR_RY_CNVT_ZEB
:
10151 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10153 case RR_RY_CNVT_ZEH
:
10154 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10156 case RR_RY_CNVT_SEB
:
10157 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10159 case RR_RY_CNVT_SEH
:
10160 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10162 #if defined (TARGET_MIPS64)
10163 case RR_RY_CNVT_ZEW
:
10164 check_mips_64(ctx
);
10165 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10167 case RR_RY_CNVT_SEW
:
10168 check_mips_64(ctx
);
10169 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10173 generate_exception(ctx
, EXCP_RI
);
10178 gen_HILO(ctx
, OPC_MFLO
, rx
);
10180 #if defined (TARGET_MIPS64)
10182 check_mips_64(ctx
);
10183 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10186 check_mips_64(ctx
);
10187 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10190 check_mips_64(ctx
);
10191 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10194 check_mips_64(ctx
);
10195 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10199 gen_muldiv(ctx
, OPC_MULT
, rx
, ry
);
10202 gen_muldiv(ctx
, OPC_MULTU
, rx
, ry
);
10205 gen_muldiv(ctx
, OPC_DIV
, rx
, ry
);
10208 gen_muldiv(ctx
, OPC_DIVU
, rx
, ry
);
10210 #if defined (TARGET_MIPS64)
10212 check_mips_64(ctx
);
10213 gen_muldiv(ctx
, OPC_DMULT
, rx
, ry
);
10216 check_mips_64(ctx
);
10217 gen_muldiv(ctx
, OPC_DMULTU
, rx
, ry
);
10220 check_mips_64(ctx
);
10221 gen_muldiv(ctx
, OPC_DDIV
, rx
, ry
);
10224 check_mips_64(ctx
);
10225 gen_muldiv(ctx
, OPC_DDIVU
, rx
, ry
);
10229 generate_exception(ctx
, EXCP_RI
);
10233 case M16_OPC_EXTEND
:
10234 decode_extended_mips16_opc(env
, ctx
, is_branch
);
10237 #if defined(TARGET_MIPS64)
10239 funct
= (ctx
->opcode
>> 8) & 0x7;
10240 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10244 generate_exception(ctx
, EXCP_RI
);
10251 /* microMIPS extension to MIPS32/MIPS64 */
10254 * microMIPS32/microMIPS64 major opcodes
10256 * 1. MIPS Architecture for Programmers Volume II-B:
10257 * The microMIPS32 Instruction Set (Revision 3.05)
10259 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10261 * 2. MIPS Architecture For Programmers Volume II-A:
10262 * The MIPS64 Instruction Set (Revision 3.51)
10290 POOL32S
= 0x16, /* MIPS64 */
10291 DADDIU32
= 0x17, /* MIPS64 */
10293 /* 0x1f is reserved */
10302 /* 0x20 is reserved */
10312 /* 0x28 and 0x29 are reserved */
10322 /* 0x30 and 0x31 are reserved */
10329 SD32
= 0x36, /* MIPS64 */
10330 LD32
= 0x37, /* MIPS64 */
10332 /* 0x38 and 0x39 are reserved */
10343 /* POOL32A encoding of minor opcode field */
10346 /* These opcodes are distinguished only by bits 9..6; those bits are
10347 * what are recorded below. */
10373 /* The following can be distinguished by their lower 6 bits. */
10379 /* POOL32AXF encoding of minor opcode field extension */
10382 * 1. MIPS Architecture for Programmers Volume II-B:
10383 * The microMIPS32 Instruction Set (Revision 3.05)
10385 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10387 * 2. MIPS Architecture for Programmers VolumeIV-e:
10388 * The MIPS DSP Application-Specific Extension
10389 * to the microMIPS32 Architecture (Revision 2.34)
10391 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10406 /* begin of microMIPS32 DSP */
10408 /* bits 13..12 for 0x01 */
10414 /* bits 13..12 for 0x2a */
10420 /* bits 13..12 for 0x32 */
10424 /* end of microMIPS32 DSP */
10426 /* bits 15..12 for 0x2c */
10442 /* bits 15..12 for 0x34 */
10450 /* bits 15..12 for 0x3c */
10452 JR
= 0x0, /* alias */
10457 /* bits 15..12 for 0x05 */
10461 /* bits 15..12 for 0x0d */
10471 /* bits 15..12 for 0x15 */
10477 /* bits 15..12 for 0x1d */
10481 /* bits 15..12 for 0x2d */
10486 /* bits 15..12 for 0x35 */
10493 /* POOL32B encoding of minor opcode field (bits 15..12) */
10509 /* POOL32C encoding of minor opcode field (bits 15..12) */
10517 /* 0xa is reserved */
10524 /* 0x6 is reserved */
10530 /* POOL32F encoding of minor opcode field (bits 5..0) */
10533 /* These are the bit 7..6 values */
10544 /* These are the bit 8..6 values */
10588 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10592 /* POOL32Fxf encoding of minor opcode extension field */
10630 /* POOL32I encoding of minor opcode field (bits 25..21) */
10655 /* These overlap and are distinguished by bit16 of the instruction */
10664 /* POOL16A encoding of minor opcode field */
10671 /* POOL16B encoding of minor opcode field */
10678 /* POOL16C encoding of minor opcode field */
10698 /* POOL16D encoding of minor opcode field */
10705 /* POOL16E encoding of minor opcode field */
10712 static int mmreg (int r
)
10714 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10719 /* Used for 16-bit store instructions. */
10720 static int mmreg2 (int r
)
10722 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10727 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10728 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10729 #define uMIPS_RS2(op) uMIPS_RS(op)
10730 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10731 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10732 #define uMIPS_RS5(op) (op & 0x1f)
10734 /* Signed immediate */
10735 #define SIMM(op, start, width) \
10736 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10739 /* Zero-extended immediate */
10740 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10742 static void gen_addiur1sp(DisasContext
*ctx
)
10744 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10746 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10749 static void gen_addiur2(DisasContext
*ctx
)
10751 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10752 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10753 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10755 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10758 static void gen_addiusp(DisasContext
*ctx
)
10760 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10763 if (encoded
<= 1) {
10764 decoded
= 256 + encoded
;
10765 } else if (encoded
<= 255) {
10767 } else if (encoded
<= 509) {
10768 decoded
= encoded
- 512;
10770 decoded
= encoded
- 768;
10773 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10776 static void gen_addius5(DisasContext
*ctx
)
10778 int imm
= SIMM(ctx
->opcode
, 1, 4);
10779 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10781 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10784 static void gen_andi16(DisasContext
*ctx
)
10786 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10787 31, 32, 63, 64, 255, 32768, 65535 };
10788 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10789 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10790 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10792 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10795 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10796 int base
, int16_t offset
)
10798 const char *opn
= "ldst_multiple";
10802 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10803 generate_exception(ctx
, EXCP_RI
);
10807 t0
= tcg_temp_new();
10809 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10811 t1
= tcg_const_tl(reglist
);
10812 t2
= tcg_const_i32(ctx
->mem_idx
);
10814 save_cpu_state(ctx
, 1);
10817 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10821 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10824 #ifdef TARGET_MIPS64
10826 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10830 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10836 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10839 tcg_temp_free_i32(t2
);
10843 static void gen_pool16c_insn(DisasContext
*ctx
, int *is_branch
)
10845 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10846 int rs
= mmreg(ctx
->opcode
& 0x7);
10849 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10854 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10860 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10866 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10872 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10879 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10880 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10882 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10891 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10892 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10894 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10901 int reg
= ctx
->opcode
& 0x1f;
10903 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10910 int reg
= ctx
->opcode
& 0x1f;
10912 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10913 /* Let normal delay slot handling in our caller take us
10914 to the branch target. */
10926 int reg
= ctx
->opcode
& 0x1f;
10928 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10934 gen_HILO(ctx
, OPC_MFHI
, uMIPS_RS5(ctx
->opcode
));
10938 gen_HILO(ctx
, OPC_MFLO
, uMIPS_RS5(ctx
->opcode
));
10941 generate_exception(ctx
, EXCP_BREAK
);
10944 /* XXX: not clear which exception should be raised
10945 * when in debug mode...
10947 check_insn(ctx
, ISA_MIPS32
);
10948 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10949 generate_exception(ctx
, EXCP_DBp
);
10951 generate_exception(ctx
, EXCP_DBp
);
10954 case JRADDIUSP
+ 0:
10955 case JRADDIUSP
+ 1:
10957 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10959 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10960 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10961 /* Let normal delay slot handling in our caller take us
10962 to the branch target. */
10966 generate_exception(ctx
, EXCP_RI
);
10971 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10973 TCGv t0
= tcg_temp_new();
10974 TCGv t1
= tcg_temp_new();
10976 gen_load_gpr(t0
, base
);
10979 gen_load_gpr(t1
, index
);
10980 tcg_gen_shli_tl(t1
, t1
, 2);
10981 gen_op_addr_add(ctx
, t0
, t1
, t0
);
10984 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10985 gen_store_gpr(t1
, rd
);
10991 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
10992 int base
, int16_t offset
)
10994 const char *opn
= "ldst_pair";
10997 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
10998 generate_exception(ctx
, EXCP_RI
);
11002 t0
= tcg_temp_new();
11003 t1
= tcg_temp_new();
11005 gen_base_offset_addr(ctx
, t0
, base
, offset
);
11010 generate_exception(ctx
, EXCP_RI
);
11013 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
11014 gen_store_gpr(t1
, rd
);
11015 tcg_gen_movi_tl(t1
, 4);
11016 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11017 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
11018 gen_store_gpr(t1
, rd
+1);
11022 gen_load_gpr(t1
, rd
);
11023 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
11024 tcg_gen_movi_tl(t1
, 4);
11025 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11026 gen_load_gpr(t1
, rd
+1);
11027 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
11030 #ifdef TARGET_MIPS64
11033 generate_exception(ctx
, EXCP_RI
);
11036 tcg_gen_qemu_ld64(t1
, t0
, ctx
->mem_idx
);
11037 gen_store_gpr(t1
, rd
);
11038 tcg_gen_movi_tl(t1
, 8);
11039 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11040 tcg_gen_qemu_ld64(t1
, t0
, ctx
->mem_idx
);
11041 gen_store_gpr(t1
, rd
+1);
11045 gen_load_gpr(t1
, rd
);
11046 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
11047 tcg_gen_movi_tl(t1
, 8);
11048 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11049 gen_load_gpr(t1
, rd
+1);
11050 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
11055 (void)opn
; /* avoid a compiler warning */
11056 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11061 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
,
11064 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11065 int minor
= (ctx
->opcode
>> 12) & 0xf;
11066 uint32_t mips32_op
;
11068 switch (extension
) {
11070 mips32_op
= OPC_TEQ
;
11073 mips32_op
= OPC_TGE
;
11076 mips32_op
= OPC_TGEU
;
11079 mips32_op
= OPC_TLT
;
11082 mips32_op
= OPC_TLTU
;
11085 mips32_op
= OPC_TNE
;
11087 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11089 #ifndef CONFIG_USER_ONLY
11092 check_cp0_enabled(ctx
);
11094 /* Treat as NOP. */
11097 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11101 check_cp0_enabled(ctx
);
11103 TCGv t0
= tcg_temp_new();
11105 gen_load_gpr(t0
, rt
);
11106 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11114 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11117 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11120 mips32_op
= OPC_CLO
;
11123 mips32_op
= OPC_CLZ
;
11125 check_insn(ctx
, ISA_MIPS32
);
11126 gen_cl(ctx
, mips32_op
, rt
, rs
);
11129 gen_rdhwr(ctx
, rt
, rs
);
11132 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11135 mips32_op
= OPC_MULT
;
11138 mips32_op
= OPC_MULTU
;
11141 mips32_op
= OPC_DIV
;
11144 mips32_op
= OPC_DIVU
;
11147 mips32_op
= OPC_MADD
;
11150 mips32_op
= OPC_MADDU
;
11153 mips32_op
= OPC_MSUB
;
11156 mips32_op
= OPC_MSUBU
;
11158 check_insn(ctx
, ISA_MIPS32
);
11159 gen_muldiv(ctx
, mips32_op
, rs
, rt
);
11162 goto pool32axf_invalid
;
11173 generate_exception_err(ctx
, EXCP_CpU
, 2);
11176 goto pool32axf_invalid
;
11183 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11188 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11192 goto pool32axf_invalid
;
11198 check_cp0_enabled(ctx
);
11199 check_insn(ctx
, ISA_MIPS32R2
);
11200 gen_load_srsgpr(rt
, rs
);
11203 check_cp0_enabled(ctx
);
11204 check_insn(ctx
, ISA_MIPS32R2
);
11205 gen_store_srsgpr(rt
, rs
);
11208 goto pool32axf_invalid
;
11211 #ifndef CONFIG_USER_ONLY
11215 mips32_op
= OPC_TLBP
;
11218 mips32_op
= OPC_TLBR
;
11221 mips32_op
= OPC_TLBWI
;
11224 mips32_op
= OPC_TLBWR
;
11227 mips32_op
= OPC_WAIT
;
11230 mips32_op
= OPC_DERET
;
11233 mips32_op
= OPC_ERET
;
11235 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11238 goto pool32axf_invalid
;
11244 check_cp0_enabled(ctx
);
11246 TCGv t0
= tcg_temp_new();
11248 save_cpu_state(ctx
, 1);
11249 gen_helper_di(t0
, cpu_env
);
11250 gen_store_gpr(t0
, rs
);
11251 /* Stop translation as we may have switched the execution mode */
11252 ctx
->bstate
= BS_STOP
;
11257 check_cp0_enabled(ctx
);
11259 TCGv t0
= tcg_temp_new();
11261 save_cpu_state(ctx
, 1);
11262 gen_helper_ei(t0
, cpu_env
);
11263 gen_store_gpr(t0
, rs
);
11264 /* Stop translation as we may have switched the execution mode */
11265 ctx
->bstate
= BS_STOP
;
11270 goto pool32axf_invalid
;
11280 generate_exception(ctx
, EXCP_SYSCALL
);
11281 ctx
->bstate
= BS_STOP
;
11284 check_insn(ctx
, ISA_MIPS32
);
11285 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11286 generate_exception(ctx
, EXCP_DBp
);
11288 generate_exception(ctx
, EXCP_DBp
);
11292 goto pool32axf_invalid
;
11298 gen_HILO(ctx
, OPC_MFHI
, rs
);
11301 gen_HILO(ctx
, OPC_MFLO
, rs
);
11304 gen_HILO(ctx
, OPC_MTHI
, rs
);
11307 gen_HILO(ctx
, OPC_MTLO
, rs
);
11310 goto pool32axf_invalid
;
11315 MIPS_INVAL("pool32axf");
11316 generate_exception(ctx
, EXCP_RI
);
11321 /* Values for microMIPS fmt field. Variable-width, depending on which
11322 formats the instruction supports. */
11341 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11343 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11344 uint32_t mips32_op
;
11346 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11347 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11348 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11350 switch (extension
) {
11351 case FLOAT_1BIT_FMT(CFC1
, 0):
11352 mips32_op
= OPC_CFC1
;
11354 case FLOAT_1BIT_FMT(CTC1
, 0):
11355 mips32_op
= OPC_CTC1
;
11357 case FLOAT_1BIT_FMT(MFC1
, 0):
11358 mips32_op
= OPC_MFC1
;
11360 case FLOAT_1BIT_FMT(MTC1
, 0):
11361 mips32_op
= OPC_MTC1
;
11363 case FLOAT_1BIT_FMT(MFHC1
, 0):
11364 mips32_op
= OPC_MFHC1
;
11366 case FLOAT_1BIT_FMT(MTHC1
, 0):
11367 mips32_op
= OPC_MTHC1
;
11369 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11372 /* Reciprocal square root */
11373 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11374 mips32_op
= OPC_RSQRT_S
;
11376 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11377 mips32_op
= OPC_RSQRT_D
;
11381 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11382 mips32_op
= OPC_SQRT_S
;
11384 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11385 mips32_op
= OPC_SQRT_D
;
11389 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11390 mips32_op
= OPC_RECIP_S
;
11392 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11393 mips32_op
= OPC_RECIP_D
;
11397 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11398 mips32_op
= OPC_FLOOR_L_S
;
11400 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11401 mips32_op
= OPC_FLOOR_L_D
;
11403 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11404 mips32_op
= OPC_FLOOR_W_S
;
11406 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11407 mips32_op
= OPC_FLOOR_W_D
;
11411 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11412 mips32_op
= OPC_CEIL_L_S
;
11414 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11415 mips32_op
= OPC_CEIL_L_D
;
11417 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11418 mips32_op
= OPC_CEIL_W_S
;
11420 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11421 mips32_op
= OPC_CEIL_W_D
;
11425 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11426 mips32_op
= OPC_TRUNC_L_S
;
11428 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11429 mips32_op
= OPC_TRUNC_L_D
;
11431 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11432 mips32_op
= OPC_TRUNC_W_S
;
11434 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11435 mips32_op
= OPC_TRUNC_W_D
;
11439 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11440 mips32_op
= OPC_ROUND_L_S
;
11442 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11443 mips32_op
= OPC_ROUND_L_D
;
11445 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11446 mips32_op
= OPC_ROUND_W_S
;
11448 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11449 mips32_op
= OPC_ROUND_W_D
;
11452 /* Integer to floating-point conversion */
11453 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11454 mips32_op
= OPC_CVT_L_S
;
11456 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11457 mips32_op
= OPC_CVT_L_D
;
11459 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11460 mips32_op
= OPC_CVT_W_S
;
11462 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11463 mips32_op
= OPC_CVT_W_D
;
11466 /* Paired-foo conversions */
11467 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11468 mips32_op
= OPC_CVT_S_PL
;
11470 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11471 mips32_op
= OPC_CVT_S_PU
;
11473 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11474 mips32_op
= OPC_CVT_PW_PS
;
11476 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11477 mips32_op
= OPC_CVT_PS_PW
;
11480 /* Floating-point moves */
11481 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11482 mips32_op
= OPC_MOV_S
;
11484 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11485 mips32_op
= OPC_MOV_D
;
11487 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11488 mips32_op
= OPC_MOV_PS
;
11491 /* Absolute value */
11492 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11493 mips32_op
= OPC_ABS_S
;
11495 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11496 mips32_op
= OPC_ABS_D
;
11498 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11499 mips32_op
= OPC_ABS_PS
;
11503 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11504 mips32_op
= OPC_NEG_S
;
11506 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11507 mips32_op
= OPC_NEG_D
;
11509 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11510 mips32_op
= OPC_NEG_PS
;
11513 /* Reciprocal square root step */
11514 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11515 mips32_op
= OPC_RSQRT1_S
;
11517 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11518 mips32_op
= OPC_RSQRT1_D
;
11520 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11521 mips32_op
= OPC_RSQRT1_PS
;
11524 /* Reciprocal step */
11525 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11526 mips32_op
= OPC_RECIP1_S
;
11528 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11529 mips32_op
= OPC_RECIP1_S
;
11531 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11532 mips32_op
= OPC_RECIP1_PS
;
11535 /* Conversions from double */
11536 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11537 mips32_op
= OPC_CVT_D_S
;
11539 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11540 mips32_op
= OPC_CVT_D_W
;
11542 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11543 mips32_op
= OPC_CVT_D_L
;
11546 /* Conversions from single */
11547 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11548 mips32_op
= OPC_CVT_S_D
;
11550 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11551 mips32_op
= OPC_CVT_S_W
;
11553 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11554 mips32_op
= OPC_CVT_S_L
;
11556 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11559 /* Conditional moves on floating-point codes */
11560 case COND_FLOAT_MOV(MOVT
, 0):
11561 case COND_FLOAT_MOV(MOVT
, 1):
11562 case COND_FLOAT_MOV(MOVT
, 2):
11563 case COND_FLOAT_MOV(MOVT
, 3):
11564 case COND_FLOAT_MOV(MOVT
, 4):
11565 case COND_FLOAT_MOV(MOVT
, 5):
11566 case COND_FLOAT_MOV(MOVT
, 6):
11567 case COND_FLOAT_MOV(MOVT
, 7):
11568 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11570 case COND_FLOAT_MOV(MOVF
, 0):
11571 case COND_FLOAT_MOV(MOVF
, 1):
11572 case COND_FLOAT_MOV(MOVF
, 2):
11573 case COND_FLOAT_MOV(MOVF
, 3):
11574 case COND_FLOAT_MOV(MOVF
, 4):
11575 case COND_FLOAT_MOV(MOVF
, 5):
11576 case COND_FLOAT_MOV(MOVF
, 6):
11577 case COND_FLOAT_MOV(MOVF
, 7):
11578 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11581 MIPS_INVAL("pool32fxf");
11582 generate_exception(ctx
, EXCP_RI
);
11587 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11588 uint16_t insn_hw1
, int *is_branch
)
11592 int rt
, rs
, rd
, rr
;
11594 uint32_t op
, minor
, mips32_op
;
11595 uint32_t cond
, fmt
, cc
;
11597 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11598 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11600 rt
= (ctx
->opcode
>> 21) & 0x1f;
11601 rs
= (ctx
->opcode
>> 16) & 0x1f;
11602 rd
= (ctx
->opcode
>> 11) & 0x1f;
11603 rr
= (ctx
->opcode
>> 6) & 0x1f;
11604 imm
= (int16_t) ctx
->opcode
;
11606 op
= (ctx
->opcode
>> 26) & 0x3f;
11609 minor
= ctx
->opcode
& 0x3f;
11612 minor
= (ctx
->opcode
>> 6) & 0xf;
11615 mips32_op
= OPC_SLL
;
11618 mips32_op
= OPC_SRA
;
11621 mips32_op
= OPC_SRL
;
11624 mips32_op
= OPC_ROTR
;
11626 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11629 goto pool32a_invalid
;
11633 minor
= (ctx
->opcode
>> 6) & 0xf;
11637 mips32_op
= OPC_ADD
;
11640 mips32_op
= OPC_ADDU
;
11643 mips32_op
= OPC_SUB
;
11646 mips32_op
= OPC_SUBU
;
11649 mips32_op
= OPC_MUL
;
11651 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11655 mips32_op
= OPC_SLLV
;
11658 mips32_op
= OPC_SRLV
;
11661 mips32_op
= OPC_SRAV
;
11664 mips32_op
= OPC_ROTRV
;
11666 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11668 /* Logical operations */
11670 mips32_op
= OPC_AND
;
11673 mips32_op
= OPC_OR
;
11676 mips32_op
= OPC_NOR
;
11679 mips32_op
= OPC_XOR
;
11681 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11683 /* Set less than */
11685 mips32_op
= OPC_SLT
;
11688 mips32_op
= OPC_SLTU
;
11690 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11693 goto pool32a_invalid
;
11697 minor
= (ctx
->opcode
>> 6) & 0xf;
11699 /* Conditional moves */
11701 mips32_op
= OPC_MOVN
;
11704 mips32_op
= OPC_MOVZ
;
11706 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11709 gen_ldxs(ctx
, rs
, rt
, rd
);
11712 goto pool32a_invalid
;
11716 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11719 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11722 gen_pool32axf(env
, ctx
, rt
, rs
, is_branch
);
11725 generate_exception(ctx
, EXCP_BREAK
);
11729 MIPS_INVAL("pool32a");
11730 generate_exception(ctx
, EXCP_RI
);
11735 minor
= (ctx
->opcode
>> 12) & 0xf;
11738 check_cp0_enabled(ctx
);
11739 /* Treat as no-op. */
11743 /* COP2: Not implemented. */
11744 generate_exception_err(ctx
, EXCP_CpU
, 2);
11748 #ifdef TARGET_MIPS64
11752 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11756 #ifdef TARGET_MIPS64
11760 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11763 MIPS_INVAL("pool32b");
11764 generate_exception(ctx
, EXCP_RI
);
11769 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
11770 minor
= ctx
->opcode
& 0x3f;
11771 check_cp1_enabled(ctx
);
11774 mips32_op
= OPC_ALNV_PS
;
11777 mips32_op
= OPC_MADD_S
;
11780 mips32_op
= OPC_MADD_D
;
11783 mips32_op
= OPC_MADD_PS
;
11786 mips32_op
= OPC_MSUB_S
;
11789 mips32_op
= OPC_MSUB_D
;
11792 mips32_op
= OPC_MSUB_PS
;
11795 mips32_op
= OPC_NMADD_S
;
11798 mips32_op
= OPC_NMADD_D
;
11801 mips32_op
= OPC_NMADD_PS
;
11804 mips32_op
= OPC_NMSUB_S
;
11807 mips32_op
= OPC_NMSUB_D
;
11810 mips32_op
= OPC_NMSUB_PS
;
11812 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11814 case CABS_COND_FMT
:
11815 cond
= (ctx
->opcode
>> 6) & 0xf;
11816 cc
= (ctx
->opcode
>> 13) & 0x7;
11817 fmt
= (ctx
->opcode
>> 10) & 0x3;
11820 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11823 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11826 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11829 goto pool32f_invalid
;
11833 cond
= (ctx
->opcode
>> 6) & 0xf;
11834 cc
= (ctx
->opcode
>> 13) & 0x7;
11835 fmt
= (ctx
->opcode
>> 10) & 0x3;
11838 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11841 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11844 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11847 goto pool32f_invalid
;
11851 gen_pool32fxf(ctx
, rt
, rs
);
11855 switch ((ctx
->opcode
>> 6) & 0x7) {
11857 mips32_op
= OPC_PLL_PS
;
11860 mips32_op
= OPC_PLU_PS
;
11863 mips32_op
= OPC_PUL_PS
;
11866 mips32_op
= OPC_PUU_PS
;
11869 mips32_op
= OPC_CVT_PS_S
;
11871 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11874 goto pool32f_invalid
;
11879 switch ((ctx
->opcode
>> 6) & 0x7) {
11881 mips32_op
= OPC_LWXC1
;
11884 mips32_op
= OPC_SWXC1
;
11887 mips32_op
= OPC_LDXC1
;
11890 mips32_op
= OPC_SDXC1
;
11893 mips32_op
= OPC_LUXC1
;
11896 mips32_op
= OPC_SUXC1
;
11898 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11901 goto pool32f_invalid
;
11906 fmt
= (ctx
->opcode
>> 9) & 0x3;
11907 switch ((ctx
->opcode
>> 6) & 0x7) {
11911 mips32_op
= OPC_RSQRT2_S
;
11914 mips32_op
= OPC_RSQRT2_D
;
11917 mips32_op
= OPC_RSQRT2_PS
;
11920 goto pool32f_invalid
;
11926 mips32_op
= OPC_RECIP2_S
;
11929 mips32_op
= OPC_RECIP2_D
;
11932 mips32_op
= OPC_RECIP2_PS
;
11935 goto pool32f_invalid
;
11939 mips32_op
= OPC_ADDR_PS
;
11942 mips32_op
= OPC_MULR_PS
;
11944 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11947 goto pool32f_invalid
;
11951 /* MOV[FT].fmt and PREFX */
11952 cc
= (ctx
->opcode
>> 13) & 0x7;
11953 fmt
= (ctx
->opcode
>> 9) & 0x3;
11954 switch ((ctx
->opcode
>> 6) & 0x7) {
11958 gen_movcf_s(rs
, rt
, cc
, 0);
11961 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
11964 gen_movcf_ps(rs
, rt
, cc
, 0);
11967 goto pool32f_invalid
;
11973 gen_movcf_s(rs
, rt
, cc
, 1);
11976 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
11979 gen_movcf_ps(rs
, rt
, cc
, 1);
11982 goto pool32f_invalid
;
11988 goto pool32f_invalid
;
11991 #define FINSN_3ARG_SDPS(prfx) \
11992 switch ((ctx->opcode >> 8) & 0x3) { \
11994 mips32_op = OPC_##prfx##_S; \
11997 mips32_op = OPC_##prfx##_D; \
11999 case FMT_SDPS_PS: \
12000 mips32_op = OPC_##prfx##_PS; \
12003 goto pool32f_invalid; \
12006 /* regular FP ops */
12007 switch ((ctx
->opcode
>> 6) & 0x3) {
12009 FINSN_3ARG_SDPS(ADD
);
12012 FINSN_3ARG_SDPS(SUB
);
12015 FINSN_3ARG_SDPS(MUL
);
12018 fmt
= (ctx
->opcode
>> 8) & 0x3;
12020 mips32_op
= OPC_DIV_D
;
12021 } else if (fmt
== 0) {
12022 mips32_op
= OPC_DIV_S
;
12024 goto pool32f_invalid
;
12028 goto pool32f_invalid
;
12033 switch ((ctx
->opcode
>> 6) & 0x3) {
12035 FINSN_3ARG_SDPS(MOVN
);
12038 FINSN_3ARG_SDPS(MOVZ
);
12041 goto pool32f_invalid
;
12045 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12049 MIPS_INVAL("pool32f");
12050 generate_exception(ctx
, EXCP_RI
);
12054 generate_exception_err(ctx
, EXCP_CpU
, 1);
12058 minor
= (ctx
->opcode
>> 21) & 0x1f;
12061 mips32_op
= OPC_BLTZ
;
12064 mips32_op
= OPC_BLTZAL
;
12067 mips32_op
= OPC_BLTZALS
;
12070 mips32_op
= OPC_BGEZ
;
12073 mips32_op
= OPC_BGEZAL
;
12076 mips32_op
= OPC_BGEZALS
;
12079 mips32_op
= OPC_BLEZ
;
12082 mips32_op
= OPC_BGTZ
;
12084 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12090 mips32_op
= OPC_TLTI
;
12093 mips32_op
= OPC_TGEI
;
12096 mips32_op
= OPC_TLTIU
;
12099 mips32_op
= OPC_TGEIU
;
12102 mips32_op
= OPC_TNEI
;
12105 mips32_op
= OPC_TEQI
;
12107 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12112 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12113 4, rs
, 0, imm
<< 1);
12114 /* Compact branches don't have a delay slot, so just let
12115 the normal delay slot handling take us to the branch
12119 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12125 /* COP2: Not implemented. */
12126 generate_exception_err(ctx
, EXCP_CpU
, 2);
12129 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12132 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12135 mips32_op
= OPC_BC1FANY4
;
12138 mips32_op
= OPC_BC1TANY4
;
12141 check_insn(ctx
, ASE_MIPS3D
);
12144 gen_compute_branch1(ctx
, mips32_op
,
12145 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12150 /* MIPS DSP: not implemented */
12153 MIPS_INVAL("pool32i");
12154 generate_exception(ctx
, EXCP_RI
);
12159 minor
= (ctx
->opcode
>> 12) & 0xf;
12162 mips32_op
= OPC_LWL
;
12165 mips32_op
= OPC_SWL
;
12168 mips32_op
= OPC_LWR
;
12171 mips32_op
= OPC_SWR
;
12173 #if defined(TARGET_MIPS64)
12175 mips32_op
= OPC_LDL
;
12178 mips32_op
= OPC_SDL
;
12181 mips32_op
= OPC_LDR
;
12184 mips32_op
= OPC_SDR
;
12187 mips32_op
= OPC_LWU
;
12190 mips32_op
= OPC_LLD
;
12194 mips32_op
= OPC_LL
;
12197 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12200 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12203 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12205 #if defined(TARGET_MIPS64)
12207 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12211 /* Treat as no-op */
12214 MIPS_INVAL("pool32c");
12215 generate_exception(ctx
, EXCP_RI
);
12220 mips32_op
= OPC_ADDI
;
12223 mips32_op
= OPC_ADDIU
;
12225 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12228 /* Logical operations */
12230 mips32_op
= OPC_ORI
;
12233 mips32_op
= OPC_XORI
;
12236 mips32_op
= OPC_ANDI
;
12238 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12241 /* Set less than immediate */
12243 mips32_op
= OPC_SLTI
;
12246 mips32_op
= OPC_SLTIU
;
12248 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12251 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12252 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12256 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12257 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12261 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12265 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12269 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12270 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12274 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12275 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12278 /* Floating point (COP1) */
12280 mips32_op
= OPC_LWC1
;
12283 mips32_op
= OPC_LDC1
;
12286 mips32_op
= OPC_SWC1
;
12289 mips32_op
= OPC_SDC1
;
12291 gen_cop1_ldst(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12295 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12296 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12298 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12301 /* Loads and stores */
12303 mips32_op
= OPC_LB
;
12306 mips32_op
= OPC_LBU
;
12309 mips32_op
= OPC_LH
;
12312 mips32_op
= OPC_LHU
;
12315 mips32_op
= OPC_LW
;
12317 #ifdef TARGET_MIPS64
12319 mips32_op
= OPC_LD
;
12322 mips32_op
= OPC_SD
;
12326 mips32_op
= OPC_SB
;
12329 mips32_op
= OPC_SH
;
12332 mips32_op
= OPC_SW
;
12335 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12338 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12341 generate_exception(ctx
, EXCP_RI
);
12346 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
, int *is_branch
)
12350 /* make sure instructions are on a halfword boundary */
12351 if (ctx
->pc
& 0x1) {
12352 env
->CP0_BadVAddr
= ctx
->pc
;
12353 generate_exception(ctx
, EXCP_AdEL
);
12354 ctx
->bstate
= BS_STOP
;
12358 op
= (ctx
->opcode
>> 10) & 0x3f;
12359 /* Enforce properly-sized instructions in a delay slot */
12360 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12361 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12399 if (bits
& MIPS_HFLAG_BDS16
) {
12400 generate_exception(ctx
, EXCP_RI
);
12401 /* Just stop translation; the user is confused. */
12402 ctx
->bstate
= BS_STOP
;
12427 if (bits
& MIPS_HFLAG_BDS32
) {
12428 generate_exception(ctx
, EXCP_RI
);
12429 /* Just stop translation; the user is confused. */
12430 ctx
->bstate
= BS_STOP
;
12441 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12442 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12443 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12446 switch (ctx
->opcode
& 0x1) {
12455 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12460 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12461 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12462 int amount
= (ctx
->opcode
>> 1) & 0x7;
12464 amount
= amount
== 0 ? 8 : amount
;
12466 switch (ctx
->opcode
& 0x1) {
12475 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12479 gen_pool16c_insn(ctx
, is_branch
);
12483 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12484 int rb
= 28; /* GP */
12485 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12487 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12491 if (ctx
->opcode
& 1) {
12492 generate_exception(ctx
, EXCP_RI
);
12495 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12496 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12497 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12498 int rd
, rs
, re
, rt
;
12499 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12500 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12501 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12503 rd
= rd_enc
[enc_dest
];
12504 re
= re_enc
[enc_dest
];
12505 rs
= rs_rt_enc
[enc_rs
];
12506 rt
= rs_rt_enc
[enc_rt
];
12508 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12509 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12514 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12515 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12516 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12517 offset
= (offset
== 0xf ? -1 : offset
);
12519 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12524 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12525 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12526 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12528 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12533 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12534 int rb
= 29; /* SP */
12535 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12537 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12542 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12543 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12544 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12546 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12551 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12552 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12553 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12555 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12560 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12561 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12562 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12564 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12569 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12570 int rb
= 29; /* SP */
12571 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12573 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12578 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12579 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12580 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12582 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12587 int rd
= uMIPS_RD5(ctx
->opcode
);
12588 int rs
= uMIPS_RS5(ctx
->opcode
);
12590 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12597 switch (ctx
->opcode
& 0x1) {
12607 switch (ctx
->opcode
& 0x1) {
12612 gen_addiur1sp(ctx
);
12617 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12618 SIMM(ctx
->opcode
, 0, 10) << 1);
12623 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12624 mmreg(uMIPS_RD(ctx
->opcode
)),
12625 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12630 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12631 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12633 imm
= (imm
== 0x7f ? -1 : imm
);
12634 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12644 generate_exception(ctx
, EXCP_RI
);
12647 decode_micromips32_opc (env
, ctx
, op
, is_branch
);
12654 /* SmartMIPS extension to MIPS32 */
12656 #if defined(TARGET_MIPS64)
12658 /* MDMX extension to MIPS64 */
12662 /* MIPSDSP functions. */
12663 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12664 int rd
, int base
, int offset
)
12666 const char *opn
= "ldx";
12670 t0
= tcg_temp_new();
12673 gen_load_gpr(t0
, offset
);
12674 } else if (offset
== 0) {
12675 gen_load_gpr(t0
, base
);
12677 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12682 tcg_gen_qemu_ld8u(t0
, t0
, ctx
->mem_idx
);
12683 gen_store_gpr(t0
, rd
);
12687 tcg_gen_qemu_ld16s(t0
, t0
, ctx
->mem_idx
);
12688 gen_store_gpr(t0
, rd
);
12692 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
12693 gen_store_gpr(t0
, rd
);
12696 #if defined(TARGET_MIPS64)
12698 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
12699 gen_store_gpr(t0
, rd
);
12704 (void)opn
; /* avoid a compiler warning */
12705 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12706 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12710 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12711 int ret
, int v1
, int v2
)
12713 const char *opn
= "mipsdsp arith";
12718 /* Treat as NOP. */
12723 v1_t
= tcg_temp_new();
12724 v2_t
= tcg_temp_new();
12726 gen_load_gpr(v1_t
, v1
);
12727 gen_load_gpr(v2_t
, v2
);
12730 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12731 case OPC_MULT_G_2E
:
12735 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12737 case OPC_ADDUH_R_QB
:
12738 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12741 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12743 case OPC_ADDQH_R_PH
:
12744 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12747 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12749 case OPC_ADDQH_R_W
:
12750 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12753 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12755 case OPC_SUBUH_R_QB
:
12756 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12759 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12761 case OPC_SUBQH_R_PH
:
12762 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12765 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12767 case OPC_SUBQH_R_W
:
12768 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12772 case OPC_ABSQ_S_PH_DSP
:
12774 case OPC_ABSQ_S_QB
:
12776 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12778 case OPC_ABSQ_S_PH
:
12780 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12784 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12786 case OPC_PRECEQ_W_PHL
:
12788 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12789 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12791 case OPC_PRECEQ_W_PHR
:
12793 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12794 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12795 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12797 case OPC_PRECEQU_PH_QBL
:
12799 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12801 case OPC_PRECEQU_PH_QBR
:
12803 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12805 case OPC_PRECEQU_PH_QBLA
:
12807 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12809 case OPC_PRECEQU_PH_QBRA
:
12811 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12813 case OPC_PRECEU_PH_QBL
:
12815 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12817 case OPC_PRECEU_PH_QBR
:
12819 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12821 case OPC_PRECEU_PH_QBLA
:
12823 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12825 case OPC_PRECEU_PH_QBRA
:
12827 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12831 case OPC_ADDU_QB_DSP
:
12835 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12837 case OPC_ADDQ_S_PH
:
12839 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12843 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12847 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12849 case OPC_ADDU_S_QB
:
12851 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12855 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12857 case OPC_ADDU_S_PH
:
12859 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12863 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12865 case OPC_SUBQ_S_PH
:
12867 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12871 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12875 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12877 case OPC_SUBU_S_QB
:
12879 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12883 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12885 case OPC_SUBU_S_PH
:
12887 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12891 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12895 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12899 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12901 case OPC_RADDU_W_QB
:
12903 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12907 case OPC_CMPU_EQ_QB_DSP
:
12909 case OPC_PRECR_QB_PH
:
12911 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12913 case OPC_PRECRQ_QB_PH
:
12915 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12917 case OPC_PRECR_SRA_PH_W
:
12920 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12921 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12923 tcg_temp_free_i32(sa_t
);
12926 case OPC_PRECR_SRA_R_PH_W
:
12929 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12930 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12932 tcg_temp_free_i32(sa_t
);
12935 case OPC_PRECRQ_PH_W
:
12937 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12939 case OPC_PRECRQ_RS_PH_W
:
12941 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12943 case OPC_PRECRQU_S_QB_PH
:
12945 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12949 #ifdef TARGET_MIPS64
12950 case OPC_ABSQ_S_QH_DSP
:
12952 case OPC_PRECEQ_L_PWL
:
12954 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
12956 case OPC_PRECEQ_L_PWR
:
12958 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
12960 case OPC_PRECEQ_PW_QHL
:
12962 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
12964 case OPC_PRECEQ_PW_QHR
:
12966 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
12968 case OPC_PRECEQ_PW_QHLA
:
12970 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
12972 case OPC_PRECEQ_PW_QHRA
:
12974 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
12976 case OPC_PRECEQU_QH_OBL
:
12978 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
12980 case OPC_PRECEQU_QH_OBR
:
12982 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
12984 case OPC_PRECEQU_QH_OBLA
:
12986 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
12988 case OPC_PRECEQU_QH_OBRA
:
12990 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
12992 case OPC_PRECEU_QH_OBL
:
12994 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
12996 case OPC_PRECEU_QH_OBR
:
12998 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
13000 case OPC_PRECEU_QH_OBLA
:
13002 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
13004 case OPC_PRECEU_QH_OBRA
:
13006 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
13008 case OPC_ABSQ_S_OB
:
13010 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
13012 case OPC_ABSQ_S_PW
:
13014 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
13016 case OPC_ABSQ_S_QH
:
13018 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
13022 case OPC_ADDU_OB_DSP
:
13024 case OPC_RADDU_L_OB
:
13026 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
13030 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13032 case OPC_SUBQ_S_PW
:
13034 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13038 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13040 case OPC_SUBQ_S_QH
:
13042 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13046 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13048 case OPC_SUBU_S_OB
:
13050 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13054 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13056 case OPC_SUBU_S_QH
:
13058 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13062 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13064 case OPC_SUBUH_R_OB
:
13066 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13070 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13072 case OPC_ADDQ_S_PW
:
13074 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13078 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13080 case OPC_ADDQ_S_QH
:
13082 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13086 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13088 case OPC_ADDU_S_OB
:
13090 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13094 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13096 case OPC_ADDU_S_QH
:
13098 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13102 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13104 case OPC_ADDUH_R_OB
:
13106 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13110 case OPC_CMPU_EQ_OB_DSP
:
13112 case OPC_PRECR_OB_QH
:
13114 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13116 case OPC_PRECR_SRA_QH_PW
:
13119 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13120 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13121 tcg_temp_free_i32(ret_t
);
13124 case OPC_PRECR_SRA_R_QH_PW
:
13127 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13128 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13129 tcg_temp_free_i32(sa_v
);
13132 case OPC_PRECRQ_OB_QH
:
13134 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13136 case OPC_PRECRQ_PW_L
:
13138 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13140 case OPC_PRECRQ_QH_PW
:
13142 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13144 case OPC_PRECRQ_RS_QH_PW
:
13146 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13148 case OPC_PRECRQU_S_OB_QH
:
13150 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13157 tcg_temp_free(v1_t
);
13158 tcg_temp_free(v2_t
);
13160 (void)opn
; /* avoid a compiler warning */
13161 MIPS_DEBUG("%s", opn
);
13164 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13165 int ret
, int v1
, int v2
)
13168 const char *opn
= "mipsdsp shift";
13174 /* Treat as NOP. */
13179 t0
= tcg_temp_new();
13180 v1_t
= tcg_temp_new();
13181 v2_t
= tcg_temp_new();
13183 tcg_gen_movi_tl(t0
, v1
);
13184 gen_load_gpr(v1_t
, v1
);
13185 gen_load_gpr(v2_t
, v2
);
13188 case OPC_SHLL_QB_DSP
:
13190 op2
= MASK_SHLL_QB(ctx
->opcode
);
13194 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13198 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13202 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13206 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13208 case OPC_SHLL_S_PH
:
13210 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13212 case OPC_SHLLV_S_PH
:
13214 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13218 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13220 case OPC_SHLLV_S_W
:
13222 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13226 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13230 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13234 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13238 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13242 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13244 case OPC_SHRA_R_QB
:
13246 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13250 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13252 case OPC_SHRAV_R_QB
:
13254 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13258 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13260 case OPC_SHRA_R_PH
:
13262 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13266 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13268 case OPC_SHRAV_R_PH
:
13270 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13274 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13276 case OPC_SHRAV_R_W
:
13278 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13280 default: /* Invalid */
13281 MIPS_INVAL("MASK SHLL.QB");
13282 generate_exception(ctx
, EXCP_RI
);
13287 #ifdef TARGET_MIPS64
13288 case OPC_SHLL_OB_DSP
:
13289 op2
= MASK_SHLL_OB(ctx
->opcode
);
13293 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13297 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13299 case OPC_SHLL_S_PW
:
13301 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13303 case OPC_SHLLV_S_PW
:
13305 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13309 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13313 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13317 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13321 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13323 case OPC_SHLL_S_QH
:
13325 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13327 case OPC_SHLLV_S_QH
:
13329 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13333 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13337 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13339 case OPC_SHRA_R_OB
:
13341 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13343 case OPC_SHRAV_R_OB
:
13345 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13349 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13353 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13355 case OPC_SHRA_R_PW
:
13357 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13359 case OPC_SHRAV_R_PW
:
13361 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13365 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13369 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13371 case OPC_SHRA_R_QH
:
13373 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13375 case OPC_SHRAV_R_QH
:
13377 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13381 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13385 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13389 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13393 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13395 default: /* Invalid */
13396 MIPS_INVAL("MASK SHLL.OB");
13397 generate_exception(ctx
, EXCP_RI
);
13405 tcg_temp_free(v1_t
);
13406 tcg_temp_free(v2_t
);
13407 (void)opn
; /* avoid a compiler warning */
13408 MIPS_DEBUG("%s", opn
);
13411 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13412 int ret
, int v1
, int v2
, int check_ret
)
13414 const char *opn
= "mipsdsp multiply";
13419 if ((ret
== 0) && (check_ret
== 1)) {
13420 /* Treat as NOP. */
13425 t0
= tcg_temp_new_i32();
13426 v1_t
= tcg_temp_new();
13427 v2_t
= tcg_temp_new();
13429 tcg_gen_movi_i32(t0
, ret
);
13430 gen_load_gpr(v1_t
, v1
);
13431 gen_load_gpr(v2_t
, v2
);
13434 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13435 * the same mask and op1. */
13436 case OPC_MULT_G_2E
:
13439 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13442 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13445 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13447 case OPC_MULQ_RS_W
:
13448 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13452 case OPC_DPA_W_PH_DSP
:
13454 case OPC_DPAU_H_QBL
:
13456 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13458 case OPC_DPAU_H_QBR
:
13460 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13462 case OPC_DPSU_H_QBL
:
13464 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13466 case OPC_DPSU_H_QBR
:
13468 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13472 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13474 case OPC_DPAX_W_PH
:
13476 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13478 case OPC_DPAQ_S_W_PH
:
13480 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13482 case OPC_DPAQX_S_W_PH
:
13484 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13486 case OPC_DPAQX_SA_W_PH
:
13488 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13492 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13494 case OPC_DPSX_W_PH
:
13496 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13498 case OPC_DPSQ_S_W_PH
:
13500 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13502 case OPC_DPSQX_S_W_PH
:
13504 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13506 case OPC_DPSQX_SA_W_PH
:
13508 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13510 case OPC_MULSAQ_S_W_PH
:
13512 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13514 case OPC_DPAQ_SA_L_W
:
13516 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13518 case OPC_DPSQ_SA_L_W
:
13520 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13522 case OPC_MAQ_S_W_PHL
:
13524 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13526 case OPC_MAQ_S_W_PHR
:
13528 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13530 case OPC_MAQ_SA_W_PHL
:
13532 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13534 case OPC_MAQ_SA_W_PHR
:
13536 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13538 case OPC_MULSA_W_PH
:
13540 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13544 #ifdef TARGET_MIPS64
13545 case OPC_DPAQ_W_QH_DSP
:
13547 int ac
= ret
& 0x03;
13548 tcg_gen_movi_i32(t0
, ac
);
13553 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13557 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13561 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13565 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13569 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13571 case OPC_DPAQ_S_W_QH
:
13573 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13575 case OPC_DPAQ_SA_L_PW
:
13577 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13579 case OPC_DPAU_H_OBL
:
13581 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13583 case OPC_DPAU_H_OBR
:
13585 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13589 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13591 case OPC_DPSQ_S_W_QH
:
13593 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13595 case OPC_DPSQ_SA_L_PW
:
13597 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13599 case OPC_DPSU_H_OBL
:
13601 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13603 case OPC_DPSU_H_OBR
:
13605 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13607 case OPC_MAQ_S_L_PWL
:
13609 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13611 case OPC_MAQ_S_L_PWR
:
13613 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13615 case OPC_MAQ_S_W_QHLL
:
13617 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13619 case OPC_MAQ_SA_W_QHLL
:
13621 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13623 case OPC_MAQ_S_W_QHLR
:
13625 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13627 case OPC_MAQ_SA_W_QHLR
:
13629 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13631 case OPC_MAQ_S_W_QHRL
:
13633 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13635 case OPC_MAQ_SA_W_QHRL
:
13637 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13639 case OPC_MAQ_S_W_QHRR
:
13641 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13643 case OPC_MAQ_SA_W_QHRR
:
13645 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13647 case OPC_MULSAQ_S_L_PW
:
13649 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13651 case OPC_MULSAQ_S_W_QH
:
13653 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13659 case OPC_ADDU_QB_DSP
:
13661 case OPC_MULEU_S_PH_QBL
:
13663 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13665 case OPC_MULEU_S_PH_QBR
:
13667 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13669 case OPC_MULQ_RS_PH
:
13671 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13673 case OPC_MULEQ_S_W_PHL
:
13675 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13677 case OPC_MULEQ_S_W_PHR
:
13679 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13681 case OPC_MULQ_S_PH
:
13683 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13687 #ifdef TARGET_MIPS64
13688 case OPC_ADDU_OB_DSP
:
13690 case OPC_MULEQ_S_PW_QHL
:
13692 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13694 case OPC_MULEQ_S_PW_QHR
:
13696 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13698 case OPC_MULEU_S_QH_OBL
:
13700 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13702 case OPC_MULEU_S_QH_OBR
:
13704 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13706 case OPC_MULQ_RS_QH
:
13708 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13715 tcg_temp_free_i32(t0
);
13716 tcg_temp_free(v1_t
);
13717 tcg_temp_free(v2_t
);
13719 (void)opn
; /* avoid a compiler warning */
13720 MIPS_DEBUG("%s", opn
);
13724 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13727 const char *opn
= "mipsdsp Bit/ Manipulation";
13733 /* Treat as NOP. */
13738 t0
= tcg_temp_new();
13739 val_t
= tcg_temp_new();
13740 gen_load_gpr(val_t
, val
);
13743 case OPC_ABSQ_S_PH_DSP
:
13747 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13752 target_long result
;
13753 imm
= (ctx
->opcode
>> 16) & 0xFF;
13754 result
= (uint32_t)imm
<< 24 |
13755 (uint32_t)imm
<< 16 |
13756 (uint32_t)imm
<< 8 |
13758 result
= (int32_t)result
;
13759 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13764 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13765 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13766 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13767 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13768 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13769 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13774 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13775 imm
= (int16_t)(imm
<< 6) >> 6;
13776 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13777 (target_long
)((int32_t)imm
<< 16 | \
13783 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13784 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13785 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13786 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13790 #ifdef TARGET_MIPS64
13791 case OPC_ABSQ_S_QH_DSP
:
13798 imm
= (ctx
->opcode
>> 16) & 0xFF;
13799 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13800 temp
= (temp
<< 16) | temp
;
13801 temp
= (temp
<< 32) | temp
;
13802 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13810 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13811 imm
= (int16_t)(imm
<< 6) >> 6;
13812 temp
= ((target_long
)imm
<< 32) \
13813 | ((target_long
)imm
& 0xFFFFFFFF);
13814 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13822 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13823 imm
= (int16_t)(imm
<< 6) >> 6;
13825 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13826 ((uint64_t)(uint16_t)imm
<< 32) |
13827 ((uint64_t)(uint16_t)imm
<< 16) |
13828 (uint64_t)(uint16_t)imm
;
13829 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13834 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13835 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13836 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13837 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13838 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13839 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13840 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13844 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13845 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13846 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13850 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13851 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13852 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13853 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13854 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13861 tcg_temp_free(val_t
);
13863 (void)opn
; /* avoid a compiler warning */
13864 MIPS_DEBUG("%s", opn
);
13867 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13868 uint32_t op1
, uint32_t op2
,
13869 int ret
, int v1
, int v2
, int check_ret
)
13871 const char *opn
= "mipsdsp add compare pick";
13876 if ((ret
== 0) && (check_ret
== 1)) {
13877 /* Treat as NOP. */
13882 t1
= tcg_temp_new();
13883 v1_t
= tcg_temp_new();
13884 v2_t
= tcg_temp_new();
13886 gen_load_gpr(v1_t
, v1
);
13887 gen_load_gpr(v2_t
, v2
);
13890 case OPC_CMPU_EQ_QB_DSP
:
13892 case OPC_CMPU_EQ_QB
:
13894 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13896 case OPC_CMPU_LT_QB
:
13898 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13900 case OPC_CMPU_LE_QB
:
13902 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13904 case OPC_CMPGU_EQ_QB
:
13906 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13908 case OPC_CMPGU_LT_QB
:
13910 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13912 case OPC_CMPGU_LE_QB
:
13914 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13916 case OPC_CMPGDU_EQ_QB
:
13918 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13919 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13920 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13921 tcg_gen_shli_tl(t1
, t1
, 24);
13922 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13924 case OPC_CMPGDU_LT_QB
:
13926 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
13927 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13928 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13929 tcg_gen_shli_tl(t1
, t1
, 24);
13930 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13932 case OPC_CMPGDU_LE_QB
:
13934 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
13935 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13936 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13937 tcg_gen_shli_tl(t1
, t1
, 24);
13938 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13940 case OPC_CMP_EQ_PH
:
13942 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
13944 case OPC_CMP_LT_PH
:
13946 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
13948 case OPC_CMP_LE_PH
:
13950 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
13954 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13958 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13960 case OPC_PACKRL_PH
:
13962 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13966 #ifdef TARGET_MIPS64
13967 case OPC_CMPU_EQ_OB_DSP
:
13969 case OPC_CMP_EQ_PW
:
13971 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
13973 case OPC_CMP_LT_PW
:
13975 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
13977 case OPC_CMP_LE_PW
:
13979 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
13981 case OPC_CMP_EQ_QH
:
13983 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
13985 case OPC_CMP_LT_QH
:
13987 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
13989 case OPC_CMP_LE_QH
:
13991 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
13993 case OPC_CMPGDU_EQ_OB
:
13995 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13997 case OPC_CMPGDU_LT_OB
:
13999 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14001 case OPC_CMPGDU_LE_OB
:
14003 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14005 case OPC_CMPGU_EQ_OB
:
14007 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14009 case OPC_CMPGU_LT_OB
:
14011 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14013 case OPC_CMPGU_LE_OB
:
14015 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14017 case OPC_CMPU_EQ_OB
:
14019 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
14021 case OPC_CMPU_LT_OB
:
14023 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
14025 case OPC_CMPU_LE_OB
:
14027 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
14029 case OPC_PACKRL_PW
:
14031 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14035 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14039 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14043 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14051 tcg_temp_free(v1_t
);
14052 tcg_temp_free(v2_t
);
14054 (void)opn
; /* avoid a compiler warning */
14055 MIPS_DEBUG("%s", opn
);
14058 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14059 uint32_t op1
, int rt
, int rs
, int sa
)
14061 const char *opn
= "mipsdsp append/dappend";
14067 /* Treat as NOP. */
14072 t0
= tcg_temp_new();
14073 gen_load_gpr(t0
, rs
);
14076 case OPC_APPEND_DSP
:
14077 switch (MASK_APPEND(ctx
->opcode
)) {
14080 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14082 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14086 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14087 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14088 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14089 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14091 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14095 if (sa
!= 0 && sa
!= 2) {
14096 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14097 tcg_gen_ext32u_tl(t0
, t0
);
14098 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14099 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14101 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14103 default: /* Invalid */
14104 MIPS_INVAL("MASK APPEND");
14105 generate_exception(ctx
, EXCP_RI
);
14109 #ifdef TARGET_MIPS64
14110 case OPC_DAPPEND_DSP
:
14111 switch (MASK_DAPPEND(ctx
->opcode
)) {
14114 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14118 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14119 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14120 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14124 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14125 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14126 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14131 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14132 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14133 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14134 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14137 default: /* Invalid */
14138 MIPS_INVAL("MASK DAPPEND");
14139 generate_exception(ctx
, EXCP_RI
);
14146 (void)opn
; /* avoid a compiler warning */
14147 MIPS_DEBUG("%s", opn
);
14150 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14151 int ret
, int v1
, int v2
, int check_ret
)
14154 const char *opn
= "mipsdsp accumulator";
14161 if ((ret
== 0) && (check_ret
== 1)) {
14162 /* Treat as NOP. */
14167 t0
= tcg_temp_new();
14168 t1
= tcg_temp_new();
14169 v1_t
= tcg_temp_new();
14170 v2_t
= tcg_temp_new();
14172 gen_load_gpr(v1_t
, v1
);
14173 gen_load_gpr(v2_t
, v2
);
14176 case OPC_EXTR_W_DSP
:
14180 tcg_gen_movi_tl(t0
, v2
);
14181 tcg_gen_movi_tl(t1
, v1
);
14182 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14185 tcg_gen_movi_tl(t0
, v2
);
14186 tcg_gen_movi_tl(t1
, v1
);
14187 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14189 case OPC_EXTR_RS_W
:
14190 tcg_gen_movi_tl(t0
, v2
);
14191 tcg_gen_movi_tl(t1
, v1
);
14192 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14195 tcg_gen_movi_tl(t0
, v2
);
14196 tcg_gen_movi_tl(t1
, v1
);
14197 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14199 case OPC_EXTRV_S_H
:
14200 tcg_gen_movi_tl(t0
, v2
);
14201 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14204 tcg_gen_movi_tl(t0
, v2
);
14205 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14207 case OPC_EXTRV_R_W
:
14208 tcg_gen_movi_tl(t0
, v2
);
14209 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14211 case OPC_EXTRV_RS_W
:
14212 tcg_gen_movi_tl(t0
, v2
);
14213 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14216 tcg_gen_movi_tl(t0
, v2
);
14217 tcg_gen_movi_tl(t1
, v1
);
14218 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14221 tcg_gen_movi_tl(t0
, v2
);
14222 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14225 tcg_gen_movi_tl(t0
, v2
);
14226 tcg_gen_movi_tl(t1
, v1
);
14227 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14230 tcg_gen_movi_tl(t0
, v2
);
14231 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14234 imm
= (ctx
->opcode
>> 20) & 0x3F;
14235 tcg_gen_movi_tl(t0
, ret
);
14236 tcg_gen_movi_tl(t1
, imm
);
14237 gen_helper_shilo(t0
, t1
, cpu_env
);
14240 tcg_gen_movi_tl(t0
, ret
);
14241 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14244 tcg_gen_movi_tl(t0
, ret
);
14245 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14248 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14249 tcg_gen_movi_tl(t0
, imm
);
14250 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14253 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14254 tcg_gen_movi_tl(t0
, imm
);
14255 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14259 #ifdef TARGET_MIPS64
14260 case OPC_DEXTR_W_DSP
:
14264 tcg_gen_movi_tl(t0
, ret
);
14265 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14269 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14270 int ac
= (ctx
->opcode
>> 11) & 0x03;
14271 tcg_gen_movi_tl(t0
, shift
);
14272 tcg_gen_movi_tl(t1
, ac
);
14273 gen_helper_dshilo(t0
, t1
, cpu_env
);
14278 int ac
= (ctx
->opcode
>> 11) & 0x03;
14279 tcg_gen_movi_tl(t0
, ac
);
14280 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14284 tcg_gen_movi_tl(t0
, v2
);
14285 tcg_gen_movi_tl(t1
, v1
);
14287 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14290 tcg_gen_movi_tl(t0
, v2
);
14291 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14294 tcg_gen_movi_tl(t0
, v2
);
14295 tcg_gen_movi_tl(t1
, v1
);
14296 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14299 tcg_gen_movi_tl(t0
, v2
);
14300 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14303 tcg_gen_movi_tl(t0
, v2
);
14304 tcg_gen_movi_tl(t1
, v1
);
14305 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14307 case OPC_DEXTR_R_L
:
14308 tcg_gen_movi_tl(t0
, v2
);
14309 tcg_gen_movi_tl(t1
, v1
);
14310 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14312 case OPC_DEXTR_RS_L
:
14313 tcg_gen_movi_tl(t0
, v2
);
14314 tcg_gen_movi_tl(t1
, v1
);
14315 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14318 tcg_gen_movi_tl(t0
, v2
);
14319 tcg_gen_movi_tl(t1
, v1
);
14320 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14322 case OPC_DEXTR_R_W
:
14323 tcg_gen_movi_tl(t0
, v2
);
14324 tcg_gen_movi_tl(t1
, v1
);
14325 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14327 case OPC_DEXTR_RS_W
:
14328 tcg_gen_movi_tl(t0
, v2
);
14329 tcg_gen_movi_tl(t1
, v1
);
14330 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14332 case OPC_DEXTR_S_H
:
14333 tcg_gen_movi_tl(t0
, v2
);
14334 tcg_gen_movi_tl(t1
, v1
);
14335 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14337 case OPC_DEXTRV_S_H
:
14338 tcg_gen_movi_tl(t0
, v2
);
14339 tcg_gen_movi_tl(t1
, v1
);
14340 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14343 tcg_gen_movi_tl(t0
, v2
);
14344 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14346 case OPC_DEXTRV_R_L
:
14347 tcg_gen_movi_tl(t0
, v2
);
14348 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14350 case OPC_DEXTRV_RS_L
:
14351 tcg_gen_movi_tl(t0
, v2
);
14352 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14355 tcg_gen_movi_tl(t0
, v2
);
14356 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14358 case OPC_DEXTRV_R_W
:
14359 tcg_gen_movi_tl(t0
, v2
);
14360 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14362 case OPC_DEXTRV_RS_W
:
14363 tcg_gen_movi_tl(t0
, v2
);
14364 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14373 tcg_temp_free(v1_t
);
14374 tcg_temp_free(v2_t
);
14376 (void)opn
; /* avoid a compiler warning */
14377 MIPS_DEBUG("%s", opn
);
14380 /* End MIPSDSP functions. */
14382 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
, int *is_branch
)
14385 int rs
, rt
, rd
, sa
;
14386 uint32_t op
, op1
, op2
;
14389 /* make sure instructions are on a word boundary */
14390 if (ctx
->pc
& 0x3) {
14391 env
->CP0_BadVAddr
= ctx
->pc
;
14392 generate_exception(ctx
, EXCP_AdEL
);
14396 /* Handle blikely not taken case */
14397 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14398 int l1
= gen_new_label();
14400 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14401 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14402 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14403 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14407 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14408 tcg_gen_debug_insn_start(ctx
->pc
);
14411 op
= MASK_OP_MAJOR(ctx
->opcode
);
14412 rs
= (ctx
->opcode
>> 21) & 0x1f;
14413 rt
= (ctx
->opcode
>> 16) & 0x1f;
14414 rd
= (ctx
->opcode
>> 11) & 0x1f;
14415 sa
= (ctx
->opcode
>> 6) & 0x1f;
14416 imm
= (int16_t)ctx
->opcode
;
14419 op1
= MASK_SPECIAL(ctx
->opcode
);
14421 case OPC_SLL
: /* Shift with immediate */
14423 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14426 switch ((ctx
->opcode
>> 21) & 0x1f) {
14428 /* rotr is decoded as srl on non-R2 CPUs */
14429 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14434 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14437 generate_exception(ctx
, EXCP_RI
);
14441 case OPC_MOVN
: /* Conditional move */
14443 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14444 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14445 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14447 case OPC_ADD
... OPC_SUBU
:
14448 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14450 case OPC_SLLV
: /* Shifts */
14452 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14455 switch ((ctx
->opcode
>> 6) & 0x1f) {
14457 /* rotrv is decoded as srlv on non-R2 CPUs */
14458 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14463 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14466 generate_exception(ctx
, EXCP_RI
);
14470 case OPC_SLT
: /* Set on less than */
14472 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14474 case OPC_AND
: /* Logic*/
14478 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14480 case OPC_MULT
... OPC_DIVU
:
14482 check_insn(ctx
, INSN_VR54XX
);
14483 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14484 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14486 gen_muldiv(ctx
, op1
, rs
, rt
);
14488 case OPC_JR
... OPC_JALR
:
14489 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14492 case OPC_TGE
... OPC_TEQ
: /* Traps */
14494 gen_trap(ctx
, op1
, rs
, rt
, -1);
14496 case OPC_MFHI
: /* Move from HI/LO */
14498 gen_HILO(ctx
, op1
, rd
);
14501 case OPC_MTLO
: /* Move to HI/LO */
14502 gen_HILO(ctx
, op1
, rs
);
14504 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14505 #ifdef MIPS_STRICT_STANDARD
14506 MIPS_INVAL("PMON / selsl");
14507 generate_exception(ctx
, EXCP_RI
);
14509 gen_helper_0e0i(pmon
, sa
);
14513 generate_exception(ctx
, EXCP_SYSCALL
);
14514 ctx
->bstate
= BS_STOP
;
14517 generate_exception(ctx
, EXCP_BREAK
);
14520 #ifdef MIPS_STRICT_STANDARD
14521 MIPS_INVAL("SPIM");
14522 generate_exception(ctx
, EXCP_RI
);
14524 /* Implemented as RI exception for now. */
14525 MIPS_INVAL("spim (unofficial)");
14526 generate_exception(ctx
, EXCP_RI
);
14530 /* Treat as NOP. */
14534 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14535 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14536 check_cp1_enabled(ctx
);
14537 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14538 (ctx
->opcode
>> 16) & 1);
14540 generate_exception_err(ctx
, EXCP_CpU
, 1);
14544 #if defined(TARGET_MIPS64)
14545 /* MIPS64 specific opcodes */
14550 check_insn(ctx
, ISA_MIPS3
);
14551 check_mips_64(ctx
);
14552 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14555 switch ((ctx
->opcode
>> 21) & 0x1f) {
14557 /* drotr is decoded as dsrl on non-R2 CPUs */
14558 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14563 check_insn(ctx
, ISA_MIPS3
);
14564 check_mips_64(ctx
);
14565 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14568 generate_exception(ctx
, EXCP_RI
);
14573 switch ((ctx
->opcode
>> 21) & 0x1f) {
14575 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14576 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14581 check_insn(ctx
, ISA_MIPS3
);
14582 check_mips_64(ctx
);
14583 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14586 generate_exception(ctx
, EXCP_RI
);
14590 case OPC_DADD
... OPC_DSUBU
:
14591 check_insn(ctx
, ISA_MIPS3
);
14592 check_mips_64(ctx
);
14593 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14597 check_insn(ctx
, ISA_MIPS3
);
14598 check_mips_64(ctx
);
14599 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14602 switch ((ctx
->opcode
>> 6) & 0x1f) {
14604 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14605 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14610 check_insn(ctx
, ISA_MIPS3
);
14611 check_mips_64(ctx
);
14612 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14615 generate_exception(ctx
, EXCP_RI
);
14619 case OPC_DMULT
... OPC_DDIVU
:
14620 check_insn(ctx
, ISA_MIPS3
);
14621 check_mips_64(ctx
);
14622 gen_muldiv(ctx
, op1
, rs
, rt
);
14625 default: /* Invalid */
14626 MIPS_INVAL("special");
14627 generate_exception(ctx
, EXCP_RI
);
14632 op1
= MASK_SPECIAL2(ctx
->opcode
);
14634 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14635 case OPC_MSUB
... OPC_MSUBU
:
14636 check_insn(ctx
, ISA_MIPS32
);
14637 gen_muldiv(ctx
, op1
, rs
, rt
);
14640 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14644 check_insn(ctx
, ISA_MIPS32
);
14645 gen_cl(ctx
, op1
, rd
, rs
);
14648 /* XXX: not clear which exception should be raised
14649 * when in debug mode...
14651 check_insn(ctx
, ISA_MIPS32
);
14652 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14653 generate_exception(ctx
, EXCP_DBp
);
14655 generate_exception(ctx
, EXCP_DBp
);
14657 /* Treat as NOP. */
14660 case OPC_DIVU_G_2F
:
14661 case OPC_MULT_G_2F
:
14662 case OPC_MULTU_G_2F
:
14664 case OPC_MODU_G_2F
:
14665 check_insn(ctx
, INSN_LOONGSON2F
);
14666 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14668 #if defined(TARGET_MIPS64)
14671 check_insn(ctx
, ISA_MIPS64
);
14672 check_mips_64(ctx
);
14673 gen_cl(ctx
, op1
, rd
, rs
);
14675 case OPC_DMULT_G_2F
:
14676 case OPC_DMULTU_G_2F
:
14677 case OPC_DDIV_G_2F
:
14678 case OPC_DDIVU_G_2F
:
14679 case OPC_DMOD_G_2F
:
14680 case OPC_DMODU_G_2F
:
14681 check_insn(ctx
, INSN_LOONGSON2F
);
14682 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14685 default: /* Invalid */
14686 MIPS_INVAL("special2");
14687 generate_exception(ctx
, EXCP_RI
);
14692 op1
= MASK_SPECIAL3(ctx
->opcode
);
14696 check_insn(ctx
, ISA_MIPS32R2
);
14697 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14700 check_insn(ctx
, ISA_MIPS32R2
);
14701 op2
= MASK_BSHFL(ctx
->opcode
);
14702 gen_bshfl(ctx
, op2
, rt
, rd
);
14705 gen_rdhwr(ctx
, rt
, rd
);
14708 check_insn(ctx
, ASE_MT
);
14710 TCGv t0
= tcg_temp_new();
14711 TCGv t1
= tcg_temp_new();
14713 gen_load_gpr(t0
, rt
);
14714 gen_load_gpr(t1
, rs
);
14715 gen_helper_fork(t0
, t1
);
14721 check_insn(ctx
, ASE_MT
);
14723 TCGv t0
= tcg_temp_new();
14725 save_cpu_state(ctx
, 1);
14726 gen_load_gpr(t0
, rs
);
14727 gen_helper_yield(t0
, cpu_env
, t0
);
14728 gen_store_gpr(t0
, rd
);
14732 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14733 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14734 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14735 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14736 * the same mask and op1. */
14737 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14738 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14741 case OPC_ADDUH_R_QB
:
14743 case OPC_ADDQH_R_PH
:
14745 case OPC_ADDQH_R_W
:
14747 case OPC_SUBUH_R_QB
:
14749 case OPC_SUBQH_R_PH
:
14751 case OPC_SUBQH_R_W
:
14752 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14757 case OPC_MULQ_RS_W
:
14758 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14761 MIPS_INVAL("MASK ADDUH.QB");
14762 generate_exception(ctx
, EXCP_RI
);
14765 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14766 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14768 generate_exception(ctx
, EXCP_RI
);
14772 op2
= MASK_LX(ctx
->opcode
);
14774 #if defined(TARGET_MIPS64)
14780 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14782 default: /* Invalid */
14783 MIPS_INVAL("MASK LX");
14784 generate_exception(ctx
, EXCP_RI
);
14788 case OPC_ABSQ_S_PH_DSP
:
14789 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14791 case OPC_ABSQ_S_QB
:
14792 case OPC_ABSQ_S_PH
:
14794 case OPC_PRECEQ_W_PHL
:
14795 case OPC_PRECEQ_W_PHR
:
14796 case OPC_PRECEQU_PH_QBL
:
14797 case OPC_PRECEQU_PH_QBR
:
14798 case OPC_PRECEQU_PH_QBLA
:
14799 case OPC_PRECEQU_PH_QBRA
:
14800 case OPC_PRECEU_PH_QBL
:
14801 case OPC_PRECEU_PH_QBR
:
14802 case OPC_PRECEU_PH_QBLA
:
14803 case OPC_PRECEU_PH_QBRA
:
14804 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14811 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14814 MIPS_INVAL("MASK ABSQ_S.PH");
14815 generate_exception(ctx
, EXCP_RI
);
14819 case OPC_ADDU_QB_DSP
:
14820 op2
= MASK_ADDU_QB(ctx
->opcode
);
14823 case OPC_ADDQ_S_PH
:
14826 case OPC_ADDU_S_QB
:
14828 case OPC_ADDU_S_PH
:
14830 case OPC_SUBQ_S_PH
:
14833 case OPC_SUBU_S_QB
:
14835 case OPC_SUBU_S_PH
:
14839 case OPC_RADDU_W_QB
:
14840 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14842 case OPC_MULEU_S_PH_QBL
:
14843 case OPC_MULEU_S_PH_QBR
:
14844 case OPC_MULQ_RS_PH
:
14845 case OPC_MULEQ_S_W_PHL
:
14846 case OPC_MULEQ_S_W_PHR
:
14847 case OPC_MULQ_S_PH
:
14848 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14850 default: /* Invalid */
14851 MIPS_INVAL("MASK ADDU.QB");
14852 generate_exception(ctx
, EXCP_RI
);
14857 case OPC_CMPU_EQ_QB_DSP
:
14858 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14860 case OPC_PRECR_SRA_PH_W
:
14861 case OPC_PRECR_SRA_R_PH_W
:
14862 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14864 case OPC_PRECR_QB_PH
:
14865 case OPC_PRECRQ_QB_PH
:
14866 case OPC_PRECRQ_PH_W
:
14867 case OPC_PRECRQ_RS_PH_W
:
14868 case OPC_PRECRQU_S_QB_PH
:
14869 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14871 case OPC_CMPU_EQ_QB
:
14872 case OPC_CMPU_LT_QB
:
14873 case OPC_CMPU_LE_QB
:
14874 case OPC_CMP_EQ_PH
:
14875 case OPC_CMP_LT_PH
:
14876 case OPC_CMP_LE_PH
:
14877 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14879 case OPC_CMPGU_EQ_QB
:
14880 case OPC_CMPGU_LT_QB
:
14881 case OPC_CMPGU_LE_QB
:
14882 case OPC_CMPGDU_EQ_QB
:
14883 case OPC_CMPGDU_LT_QB
:
14884 case OPC_CMPGDU_LE_QB
:
14887 case OPC_PACKRL_PH
:
14888 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14890 default: /* Invalid */
14891 MIPS_INVAL("MASK CMPU.EQ.QB");
14892 generate_exception(ctx
, EXCP_RI
);
14896 case OPC_SHLL_QB_DSP
:
14897 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14899 case OPC_DPA_W_PH_DSP
:
14900 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14902 case OPC_DPAU_H_QBL
:
14903 case OPC_DPAU_H_QBR
:
14904 case OPC_DPSU_H_QBL
:
14905 case OPC_DPSU_H_QBR
:
14907 case OPC_DPAX_W_PH
:
14908 case OPC_DPAQ_S_W_PH
:
14909 case OPC_DPAQX_S_W_PH
:
14910 case OPC_DPAQX_SA_W_PH
:
14912 case OPC_DPSX_W_PH
:
14913 case OPC_DPSQ_S_W_PH
:
14914 case OPC_DPSQX_S_W_PH
:
14915 case OPC_DPSQX_SA_W_PH
:
14916 case OPC_MULSAQ_S_W_PH
:
14917 case OPC_DPAQ_SA_L_W
:
14918 case OPC_DPSQ_SA_L_W
:
14919 case OPC_MAQ_S_W_PHL
:
14920 case OPC_MAQ_S_W_PHR
:
14921 case OPC_MAQ_SA_W_PHL
:
14922 case OPC_MAQ_SA_W_PHR
:
14923 case OPC_MULSA_W_PH
:
14924 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14926 default: /* Invalid */
14927 MIPS_INVAL("MASK DPAW.PH");
14928 generate_exception(ctx
, EXCP_RI
);
14933 op2
= MASK_INSV(ctx
->opcode
);
14945 t0
= tcg_temp_new();
14946 t1
= tcg_temp_new();
14948 gen_load_gpr(t0
, rt
);
14949 gen_load_gpr(t1
, rs
);
14951 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
14957 default: /* Invalid */
14958 MIPS_INVAL("MASK INSV");
14959 generate_exception(ctx
, EXCP_RI
);
14963 case OPC_APPEND_DSP
:
14964 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
14966 case OPC_EXTR_W_DSP
:
14967 op2
= MASK_EXTR_W(ctx
->opcode
);
14971 case OPC_EXTR_RS_W
:
14973 case OPC_EXTRV_S_H
:
14975 case OPC_EXTRV_R_W
:
14976 case OPC_EXTRV_RS_W
:
14981 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
14984 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14990 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14992 default: /* Invalid */
14993 MIPS_INVAL("MASK EXTR.W");
14994 generate_exception(ctx
, EXCP_RI
);
14998 #if defined(TARGET_MIPS64)
14999 case OPC_DEXTM
... OPC_DEXT
:
15000 case OPC_DINSM
... OPC_DINS
:
15001 check_insn(ctx
, ISA_MIPS64R2
);
15002 check_mips_64(ctx
);
15003 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
15006 check_insn(ctx
, ISA_MIPS64R2
);
15007 check_mips_64(ctx
);
15008 op2
= MASK_DBSHFL(ctx
->opcode
);
15009 gen_bshfl(ctx
, op2
, rt
, rd
);
15011 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
15012 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
15013 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
15014 check_insn(ctx
, INSN_LOONGSON2E
);
15015 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
15017 case OPC_ABSQ_S_QH_DSP
:
15018 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
15020 case OPC_PRECEQ_L_PWL
:
15021 case OPC_PRECEQ_L_PWR
:
15022 case OPC_PRECEQ_PW_QHL
:
15023 case OPC_PRECEQ_PW_QHR
:
15024 case OPC_PRECEQ_PW_QHLA
:
15025 case OPC_PRECEQ_PW_QHRA
:
15026 case OPC_PRECEQU_QH_OBL
:
15027 case OPC_PRECEQU_QH_OBR
:
15028 case OPC_PRECEQU_QH_OBLA
:
15029 case OPC_PRECEQU_QH_OBRA
:
15030 case OPC_PRECEU_QH_OBL
:
15031 case OPC_PRECEU_QH_OBR
:
15032 case OPC_PRECEU_QH_OBLA
:
15033 case OPC_PRECEU_QH_OBRA
:
15034 case OPC_ABSQ_S_OB
:
15035 case OPC_ABSQ_S_PW
:
15036 case OPC_ABSQ_S_QH
:
15037 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15045 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
15047 default: /* Invalid */
15048 MIPS_INVAL("MASK ABSQ_S.QH");
15049 generate_exception(ctx
, EXCP_RI
);
15053 case OPC_ADDU_OB_DSP
:
15054 op2
= MASK_ADDU_OB(ctx
->opcode
);
15056 case OPC_RADDU_L_OB
:
15058 case OPC_SUBQ_S_PW
:
15060 case OPC_SUBQ_S_QH
:
15062 case OPC_SUBU_S_OB
:
15064 case OPC_SUBU_S_QH
:
15066 case OPC_SUBUH_R_OB
:
15068 case OPC_ADDQ_S_PW
:
15070 case OPC_ADDQ_S_QH
:
15072 case OPC_ADDU_S_OB
:
15074 case OPC_ADDU_S_QH
:
15076 case OPC_ADDUH_R_OB
:
15077 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15079 case OPC_MULEQ_S_PW_QHL
:
15080 case OPC_MULEQ_S_PW_QHR
:
15081 case OPC_MULEU_S_QH_OBL
:
15082 case OPC_MULEU_S_QH_OBR
:
15083 case OPC_MULQ_RS_QH
:
15084 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15086 default: /* Invalid */
15087 MIPS_INVAL("MASK ADDU.OB");
15088 generate_exception(ctx
, EXCP_RI
);
15092 case OPC_CMPU_EQ_OB_DSP
:
15093 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15095 case OPC_PRECR_SRA_QH_PW
:
15096 case OPC_PRECR_SRA_R_QH_PW
:
15097 /* Return value is rt. */
15098 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15100 case OPC_PRECR_OB_QH
:
15101 case OPC_PRECRQ_OB_QH
:
15102 case OPC_PRECRQ_PW_L
:
15103 case OPC_PRECRQ_QH_PW
:
15104 case OPC_PRECRQ_RS_QH_PW
:
15105 case OPC_PRECRQU_S_OB_QH
:
15106 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15108 case OPC_CMPU_EQ_OB
:
15109 case OPC_CMPU_LT_OB
:
15110 case OPC_CMPU_LE_OB
:
15111 case OPC_CMP_EQ_QH
:
15112 case OPC_CMP_LT_QH
:
15113 case OPC_CMP_LE_QH
:
15114 case OPC_CMP_EQ_PW
:
15115 case OPC_CMP_LT_PW
:
15116 case OPC_CMP_LE_PW
:
15117 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15119 case OPC_CMPGDU_EQ_OB
:
15120 case OPC_CMPGDU_LT_OB
:
15121 case OPC_CMPGDU_LE_OB
:
15122 case OPC_CMPGU_EQ_OB
:
15123 case OPC_CMPGU_LT_OB
:
15124 case OPC_CMPGU_LE_OB
:
15125 case OPC_PACKRL_PW
:
15129 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15131 default: /* Invalid */
15132 MIPS_INVAL("MASK CMPU_EQ.OB");
15133 generate_exception(ctx
, EXCP_RI
);
15137 case OPC_DAPPEND_DSP
:
15138 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15140 case OPC_DEXTR_W_DSP
:
15141 op2
= MASK_DEXTR_W(ctx
->opcode
);
15148 case OPC_DEXTR_R_L
:
15149 case OPC_DEXTR_RS_L
:
15151 case OPC_DEXTR_R_W
:
15152 case OPC_DEXTR_RS_W
:
15153 case OPC_DEXTR_S_H
:
15155 case OPC_DEXTRV_R_L
:
15156 case OPC_DEXTRV_RS_L
:
15157 case OPC_DEXTRV_S_H
:
15159 case OPC_DEXTRV_R_W
:
15160 case OPC_DEXTRV_RS_W
:
15161 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15166 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15168 default: /* Invalid */
15169 MIPS_INVAL("MASK EXTR.W");
15170 generate_exception(ctx
, EXCP_RI
);
15174 case OPC_DPAQ_W_QH_DSP
:
15175 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15177 case OPC_DPAU_H_OBL
:
15178 case OPC_DPAU_H_OBR
:
15179 case OPC_DPSU_H_OBL
:
15180 case OPC_DPSU_H_OBR
:
15182 case OPC_DPAQ_S_W_QH
:
15184 case OPC_DPSQ_S_W_QH
:
15185 case OPC_MULSAQ_S_W_QH
:
15186 case OPC_DPAQ_SA_L_PW
:
15187 case OPC_DPSQ_SA_L_PW
:
15188 case OPC_MULSAQ_S_L_PW
:
15189 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15191 case OPC_MAQ_S_W_QHLL
:
15192 case OPC_MAQ_S_W_QHLR
:
15193 case OPC_MAQ_S_W_QHRL
:
15194 case OPC_MAQ_S_W_QHRR
:
15195 case OPC_MAQ_SA_W_QHLL
:
15196 case OPC_MAQ_SA_W_QHLR
:
15197 case OPC_MAQ_SA_W_QHRL
:
15198 case OPC_MAQ_SA_W_QHRR
:
15199 case OPC_MAQ_S_L_PWL
:
15200 case OPC_MAQ_S_L_PWR
:
15205 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15207 default: /* Invalid */
15208 MIPS_INVAL("MASK DPAQ.W.QH");
15209 generate_exception(ctx
, EXCP_RI
);
15213 case OPC_DINSV_DSP
:
15214 op2
= MASK_INSV(ctx
->opcode
);
15226 t0
= tcg_temp_new();
15227 t1
= tcg_temp_new();
15229 gen_load_gpr(t0
, rt
);
15230 gen_load_gpr(t1
, rs
);
15232 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15235 default: /* Invalid */
15236 MIPS_INVAL("MASK DINSV");
15237 generate_exception(ctx
, EXCP_RI
);
15241 case OPC_SHLL_OB_DSP
:
15242 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15245 default: /* Invalid */
15246 MIPS_INVAL("special3");
15247 generate_exception(ctx
, EXCP_RI
);
15252 op1
= MASK_REGIMM(ctx
->opcode
);
15254 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15255 case OPC_BLTZAL
... OPC_BGEZALL
:
15256 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15259 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15261 gen_trap(ctx
, op1
, rs
, -1, imm
);
15264 check_insn(ctx
, ISA_MIPS32R2
);
15265 /* Treat as NOP. */
15267 case OPC_BPOSGE32
: /* MIPS DSP branch */
15268 #if defined(TARGET_MIPS64)
15272 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15275 default: /* Invalid */
15276 MIPS_INVAL("regimm");
15277 generate_exception(ctx
, EXCP_RI
);
15282 check_cp0_enabled(ctx
);
15283 op1
= MASK_CP0(ctx
->opcode
);
15289 #if defined(TARGET_MIPS64)
15293 #ifndef CONFIG_USER_ONLY
15294 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15295 #endif /* !CONFIG_USER_ONLY */
15297 case OPC_C0_FIRST
... OPC_C0_LAST
:
15298 #ifndef CONFIG_USER_ONLY
15299 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15300 #endif /* !CONFIG_USER_ONLY */
15303 #ifndef CONFIG_USER_ONLY
15305 TCGv t0
= tcg_temp_new();
15307 op2
= MASK_MFMC0(ctx
->opcode
);
15310 check_insn(ctx
, ASE_MT
);
15311 gen_helper_dmt(t0
);
15312 gen_store_gpr(t0
, rt
);
15315 check_insn(ctx
, ASE_MT
);
15316 gen_helper_emt(t0
);
15317 gen_store_gpr(t0
, rt
);
15320 check_insn(ctx
, ASE_MT
);
15321 gen_helper_dvpe(t0
, cpu_env
);
15322 gen_store_gpr(t0
, rt
);
15325 check_insn(ctx
, ASE_MT
);
15326 gen_helper_evpe(t0
, cpu_env
);
15327 gen_store_gpr(t0
, rt
);
15330 check_insn(ctx
, ISA_MIPS32R2
);
15331 save_cpu_state(ctx
, 1);
15332 gen_helper_di(t0
, cpu_env
);
15333 gen_store_gpr(t0
, rt
);
15334 /* Stop translation as we may have switched the execution mode */
15335 ctx
->bstate
= BS_STOP
;
15338 check_insn(ctx
, ISA_MIPS32R2
);
15339 save_cpu_state(ctx
, 1);
15340 gen_helper_ei(t0
, cpu_env
);
15341 gen_store_gpr(t0
, rt
);
15342 /* Stop translation as we may have switched the execution mode */
15343 ctx
->bstate
= BS_STOP
;
15345 default: /* Invalid */
15346 MIPS_INVAL("mfmc0");
15347 generate_exception(ctx
, EXCP_RI
);
15352 #endif /* !CONFIG_USER_ONLY */
15355 check_insn(ctx
, ISA_MIPS32R2
);
15356 gen_load_srsgpr(rt
, rd
);
15359 check_insn(ctx
, ISA_MIPS32R2
);
15360 gen_store_srsgpr(rt
, rd
);
15364 generate_exception(ctx
, EXCP_RI
);
15368 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15370 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15372 case OPC_SLTI
: /* Set on less than with immediate opcode */
15374 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15376 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15380 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15382 case OPC_J
... OPC_JAL
: /* Jump */
15383 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15384 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15387 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15388 case OPC_BEQL
... OPC_BGTZL
:
15389 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15392 case OPC_LB
... OPC_LWR
: /* Load and stores */
15394 gen_ld(ctx
, op
, rt
, rs
, imm
);
15396 case OPC_SB
... OPC_SW
:
15398 gen_st(ctx
, op
, rt
, rs
, imm
);
15401 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15404 check_cp0_enabled(ctx
);
15405 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15406 /* Treat as NOP. */
15409 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15410 /* Treat as NOP. */
15413 /* Floating point (COP1). */
15418 gen_cop1_ldst(env
, ctx
, op
, rt
, rs
, imm
);
15422 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15423 check_cp1_enabled(ctx
);
15424 op1
= MASK_CP1(ctx
->opcode
);
15428 check_insn(ctx
, ISA_MIPS32R2
);
15433 gen_cp1(ctx
, op1
, rt
, rd
);
15435 #if defined(TARGET_MIPS64)
15438 check_insn(ctx
, ISA_MIPS3
);
15439 gen_cp1(ctx
, op1
, rt
, rd
);
15445 check_insn(ctx
, ASE_MIPS3D
);
15448 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15449 (rt
>> 2) & 0x7, imm
<< 2);
15457 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15462 generate_exception (ctx
, EXCP_RI
);
15466 generate_exception_err(ctx
, EXCP_CpU
, 1);
15475 /* COP2: Not implemented. */
15476 generate_exception_err(ctx
, EXCP_CpU
, 2);
15479 check_insn(ctx
, INSN_LOONGSON2F
);
15480 /* Note that these instructions use different fields. */
15481 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15485 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15486 check_cp1_enabled(ctx
);
15487 op1
= MASK_CP3(ctx
->opcode
);
15495 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15498 /* Treat as NOP. */
15513 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15517 generate_exception (ctx
, EXCP_RI
);
15521 generate_exception_err(ctx
, EXCP_CpU
, 1);
15525 #if defined(TARGET_MIPS64)
15526 /* MIPS64 opcodes */
15528 case OPC_LDL
... OPC_LDR
:
15531 check_insn(ctx
, ISA_MIPS3
);
15532 check_mips_64(ctx
);
15533 gen_ld(ctx
, op
, rt
, rs
, imm
);
15535 case OPC_SDL
... OPC_SDR
:
15537 check_insn(ctx
, ISA_MIPS3
);
15538 check_mips_64(ctx
);
15539 gen_st(ctx
, op
, rt
, rs
, imm
);
15542 check_insn(ctx
, ISA_MIPS3
);
15543 check_mips_64(ctx
);
15544 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15548 check_insn(ctx
, ISA_MIPS3
);
15549 check_mips_64(ctx
);
15550 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15554 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15555 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15556 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15560 check_insn(ctx
, ASE_MDMX
);
15561 /* MDMX: Not implemented. */
15562 default: /* Invalid */
15563 MIPS_INVAL("major opcode");
15564 generate_exception(ctx
, EXCP_RI
);
15570 gen_intermediate_code_internal (CPUMIPSState
*env
, TranslationBlock
*tb
,
15574 target_ulong pc_start
;
15575 uint16_t *gen_opc_end
;
15584 qemu_log("search pc %d\n", search_pc
);
15587 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15590 ctx
.singlestep_enabled
= env
->singlestep_enabled
;
15591 ctx
.insn_flags
= env
->insn_flags
;
15593 ctx
.bstate
= BS_NONE
;
15594 /* Restore delay slot state from the tb context. */
15595 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15596 restore_cpu_state(env
, &ctx
);
15597 #ifdef CONFIG_USER_ONLY
15598 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15600 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15603 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15604 if (max_insns
== 0)
15605 max_insns
= CF_COUNT_MASK
;
15606 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15607 gen_icount_start();
15608 while (ctx
.bstate
== BS_NONE
) {
15609 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
15610 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
15611 if (bp
->pc
== ctx
.pc
) {
15612 save_cpu_state(&ctx
, 1);
15613 ctx
.bstate
= BS_BRANCH
;
15614 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15615 /* Include the breakpoint location or the tb won't
15616 * be flushed when it must be. */
15618 goto done_generating
;
15624 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15628 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15630 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15631 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15632 gen_opc_btarget
[lj
] = ctx
.btarget
;
15633 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15634 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15636 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15640 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15641 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15643 decode_opc(env
, &ctx
, &is_branch
);
15644 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15645 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15646 insn_bytes
= decode_micromips_opc(env
, &ctx
, &is_branch
);
15647 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15648 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15649 insn_bytes
= decode_mips16_opc(env
, &ctx
, &is_branch
);
15651 generate_exception(&ctx
, EXCP_RI
);
15652 ctx
.bstate
= BS_STOP
;
15656 handle_delay_slot(&ctx
, insn_bytes
);
15658 ctx
.pc
+= insn_bytes
;
15662 /* Execute a branch and its delay slot as a single instruction.
15663 This is what GDB expects and is consistent with what the
15664 hardware does (e.g. if a delay slot instruction faults, the
15665 reported PC is the PC of the branch). */
15666 if (env
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0)
15669 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15672 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15676 if (num_insns
>= max_insns
)
15682 if (tb
->cflags
& CF_LAST_IO
)
15684 if (env
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15685 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15686 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15688 switch (ctx
.bstate
) {
15690 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15693 save_cpu_state(&ctx
, 0);
15694 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15697 tcg_gen_exit_tb(0);
15705 gen_icount_end(tb
, num_insns
);
15706 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15708 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15711 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15713 tb
->size
= ctx
.pc
- pc_start
;
15714 tb
->icount
= num_insns
;
15718 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15719 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15720 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15726 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15728 gen_intermediate_code_internal(env
, tb
, 0);
15731 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15733 gen_intermediate_code_internal(env
, tb
, 1);
15736 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15740 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15742 #define printfpr(fp) \
15745 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15746 " fd:%13g fs:%13g psu: %13g\n", \
15747 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15748 (double)(fp)->fd, \
15749 (double)(fp)->fs[FP_ENDIAN_IDX], \
15750 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15753 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15754 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15755 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15756 " fd:%13g fs:%13g psu:%13g\n", \
15757 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15759 (double)tmp.fs[FP_ENDIAN_IDX], \
15760 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15765 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15766 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15767 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15768 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15769 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15770 printfpr(&env
->active_fpu
.fpr
[i
]);
15776 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15777 /* Debug help: The architecture requires 32bit code to maintain proper
15778 sign-extended values on 64bit machines. */
15780 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15783 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15784 fprintf_function cpu_fprintf
,
15789 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15790 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15791 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15792 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15793 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15794 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15795 if (!SIGN_EXT_P(env
->btarget
))
15796 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15798 for (i
= 0; i
< 32; i
++) {
15799 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15800 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15803 if (!SIGN_EXT_P(env
->CP0_EPC
))
15804 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15805 if (!SIGN_EXT_P(env
->lladdr
))
15806 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15810 void cpu_dump_state (CPUMIPSState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
15815 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15816 " LO=0x" TARGET_FMT_lx
" ds %04x "
15817 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15818 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15819 env
->hflags
, env
->btarget
, env
->bcond
);
15820 for (i
= 0; i
< 32; i
++) {
15822 cpu_fprintf(f
, "GPR%02d:", i
);
15823 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15825 cpu_fprintf(f
, "\n");
15828 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15829 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15830 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15831 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15832 if (env
->hflags
& MIPS_HFLAG_FPU
)
15833 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15834 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15835 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15839 void mips_tcg_init(void)
15844 /* Initialize various static tables. */
15848 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15849 TCGV_UNUSED(cpu_gpr
[0]);
15850 for (i
= 1; i
< 32; i
++)
15851 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15852 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15855 for (i
= 0; i
< 32; i
++) {
15856 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15857 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15860 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15861 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15862 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15863 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15864 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15866 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15867 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15869 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15870 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15873 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15874 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15876 bcond
= tcg_global_mem_new(TCG_AREG0
,
15877 offsetof(CPUMIPSState
, bcond
), "bcond");
15878 btarget
= tcg_global_mem_new(TCG_AREG0
,
15879 offsetof(CPUMIPSState
, btarget
), "btarget");
15880 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15881 offsetof(CPUMIPSState
, hflags
), "hflags");
15883 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15884 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15886 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15887 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15890 /* register helpers */
15891 #define GEN_HELPER 2
15892 #include "helper.h"
15897 #include "translate_init.c"
15899 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15903 const mips_def_t
*def
;
15905 def
= cpu_mips_find_by_name(cpu_model
);
15908 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15910 env
->cpu_model
= def
;
15911 env
->cpu_model_str
= cpu_model
;
15913 #ifndef CONFIG_USER_ONLY
15914 mmu_init(env
, def
);
15916 fpu_init(env
, def
);
15917 mvp_init(env
, def
);
15919 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15924 void cpu_state_reset(CPUMIPSState
*env
)
15926 #ifndef CONFIG_USER_ONLY
15927 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
15928 CPUState
*cs
= CPU(cpu
);
15931 /* Reset registers to their default values */
15932 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15933 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15934 #ifdef TARGET_WORDS_BIGENDIAN
15935 env
->CP0_Config0
|= (1 << CP0C0_BE
);
15937 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
15938 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
15939 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
15940 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
15941 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
15942 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
15943 << env
->cpu_model
->CP0_LLAddr_shift
;
15944 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
15945 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
15946 env
->CCRes
= env
->cpu_model
->CCRes
;
15947 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
15948 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
15949 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
15950 env
->current_tc
= 0;
15951 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
15952 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
15953 #if defined(TARGET_MIPS64)
15954 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
15955 env
->SEGMask
|= 3ULL << 62;
15958 env
->PABITS
= env
->cpu_model
->PABITS
;
15959 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
15960 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
15961 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
15962 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
15963 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
15964 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
15965 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
15966 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
15967 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
15968 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
15969 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
15970 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
15971 env
->insn_flags
= env
->cpu_model
->insn_flags
;
15973 #if defined(CONFIG_USER_ONLY)
15974 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
15975 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15976 hardware registers. */
15977 env
->CP0_HWREna
|= 0x0000000F;
15978 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15979 env
->CP0_Status
|= (1 << CP0St_CU1
);
15981 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
15982 env
->CP0_Status
|= (1 << CP0St_MX
);
15985 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
15986 /* If the exception was raised from a delay slot,
15987 come back to the jump. */
15988 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
15990 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
15992 env
->active_tc
.PC
= (int32_t)0xBFC00000;
15993 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
15994 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
15995 env
->CP0_Wired
= 0;
15996 env
->CP0_EBase
= 0x80000000 | (cs
->cpu_index
& 0x3FF);
15997 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
15998 /* vectored interrupts not implemented, timer on int 7,
15999 no performance counters. */
16000 env
->CP0_IntCtl
= 0xe0000000;
16004 for (i
= 0; i
< 7; i
++) {
16005 env
->CP0_WatchLo
[i
] = 0;
16006 env
->CP0_WatchHi
[i
] = 0x80000000;
16008 env
->CP0_WatchLo
[7] = 0;
16009 env
->CP0_WatchHi
[7] = 0;
16011 /* Count register increments in debug mode, EJTAG version 1 */
16012 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
16014 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
16017 /* Only TC0 on VPE 0 starts as active. */
16018 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
16019 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
16020 env
->tcs
[i
].CP0_TCHalt
= 1;
16022 env
->active_tc
.CP0_TCHalt
= 1;
16025 if (cs
->cpu_index
== 0) {
16026 /* VPE0 starts up enabled. */
16027 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
16028 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
16030 /* TC0 starts up unhalted. */
16032 env
->active_tc
.CP0_TCHalt
= 0;
16033 env
->tcs
[0].CP0_TCHalt
= 0;
16034 /* With thread 0 active. */
16035 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
16036 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16040 compute_hflags(env
);
16041 env
->exception_index
= EXCP_NONE
;
16044 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16046 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16047 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16048 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16049 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16050 case MIPS_HFLAG_BR
:
16052 case MIPS_HFLAG_BC
:
16053 case MIPS_HFLAG_BL
:
16055 env
->btarget
= gen_opc_btarget
[pc_pos
];