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_i32 t2
= tcg_temp_new_i32();
2719 TCGv_i32 t3
= tcg_temp_new_i32();
2720 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2725 tcg_gen_trunc_tl_i32(t2
, t0
);
2726 tcg_gen_trunc_tl_i32(t3
, t1
);
2727 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
2728 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2729 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2730 tcg_temp_free_i32(t2
);
2731 tcg_temp_free_i32(t3
);
2737 TCGv_i32 t2
= tcg_temp_new_i32();
2738 TCGv_i32 t3
= tcg_temp_new_i32();
2739 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2744 tcg_gen_trunc_tl_i32(t2
, t0
);
2745 tcg_gen_trunc_tl_i32(t3
, t1
);
2746 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
2747 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2748 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2749 tcg_temp_free_i32(t2
);
2750 tcg_temp_free_i32(t3
);
2754 #if defined(TARGET_MIPS64)
2757 TCGv t2
= tcg_temp_new();
2758 TCGv t3
= tcg_temp_new();
2759 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2760 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2761 tcg_gen_and_tl(t2
, t2
, t3
);
2762 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2763 tcg_gen_or_tl(t2
, t2
, t3
);
2764 tcg_gen_movi_tl(t3
, 0);
2765 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2766 tcg_gen_div_tl(cpu_LO
[0], t0
, t1
);
2767 tcg_gen_rem_tl(cpu_HI
[0], t0
, t1
);
2775 TCGv t2
= tcg_const_tl(0);
2776 TCGv t3
= tcg_const_tl(1);
2777 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2778 tcg_gen_divu_i64(cpu_LO
[0], t0
, t1
);
2779 tcg_gen_remu_i64(cpu_HI
[0], t0
, t1
);
2786 tcg_gen_muls2_i64(cpu_LO
[0], cpu_HI
[0], t0
, t1
);
2790 tcg_gen_mulu2_i64(cpu_LO
[0], cpu_HI
[0], t0
, t1
);
2796 TCGv_i64 t2
= tcg_temp_new_i64();
2797 TCGv_i64 t3
= tcg_temp_new_i64();
2798 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2803 tcg_gen_ext_tl_i64(t2
, t0
);
2804 tcg_gen_ext_tl_i64(t3
, t1
);
2805 tcg_gen_mul_i64(t2
, t2
, t3
);
2806 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2807 tcg_gen_add_i64(t2
, t2
, t3
);
2808 tcg_temp_free_i64(t3
);
2809 tcg_gen_trunc_i64_tl(t0
, t2
);
2810 tcg_gen_shri_i64(t2
, t2
, 32);
2811 tcg_gen_trunc_i64_tl(t1
, t2
);
2812 tcg_temp_free_i64(t2
);
2813 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2814 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2820 TCGv_i64 t2
= tcg_temp_new_i64();
2821 TCGv_i64 t3
= tcg_temp_new_i64();
2822 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2827 tcg_gen_ext32u_tl(t0
, t0
);
2828 tcg_gen_ext32u_tl(t1
, t1
);
2829 tcg_gen_extu_tl_i64(t2
, t0
);
2830 tcg_gen_extu_tl_i64(t3
, t1
);
2831 tcg_gen_mul_i64(t2
, t2
, t3
);
2832 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2833 tcg_gen_add_i64(t2
, t2
, t3
);
2834 tcg_temp_free_i64(t3
);
2835 tcg_gen_trunc_i64_tl(t0
, t2
);
2836 tcg_gen_shri_i64(t2
, t2
, 32);
2837 tcg_gen_trunc_i64_tl(t1
, t2
);
2838 tcg_temp_free_i64(t2
);
2839 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2840 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2846 TCGv_i64 t2
= tcg_temp_new_i64();
2847 TCGv_i64 t3
= tcg_temp_new_i64();
2848 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2853 tcg_gen_ext_tl_i64(t2
, t0
);
2854 tcg_gen_ext_tl_i64(t3
, t1
);
2855 tcg_gen_mul_i64(t2
, t2
, t3
);
2856 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2857 tcg_gen_sub_i64(t2
, t3
, t2
);
2858 tcg_temp_free_i64(t3
);
2859 tcg_gen_trunc_i64_tl(t0
, t2
);
2860 tcg_gen_shri_i64(t2
, t2
, 32);
2861 tcg_gen_trunc_i64_tl(t1
, t2
);
2862 tcg_temp_free_i64(t2
);
2863 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2864 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2870 TCGv_i64 t2
= tcg_temp_new_i64();
2871 TCGv_i64 t3
= tcg_temp_new_i64();
2872 acc
= ((ctx
->opcode
) >> 11) & 0x03;
2877 tcg_gen_ext32u_tl(t0
, t0
);
2878 tcg_gen_ext32u_tl(t1
, t1
);
2879 tcg_gen_extu_tl_i64(t2
, t0
);
2880 tcg_gen_extu_tl_i64(t3
, t1
);
2881 tcg_gen_mul_i64(t2
, t2
, t3
);
2882 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2883 tcg_gen_sub_i64(t2
, t3
, t2
);
2884 tcg_temp_free_i64(t3
);
2885 tcg_gen_trunc_i64_tl(t0
, t2
);
2886 tcg_gen_shri_i64(t2
, t2
, 32);
2887 tcg_gen_trunc_i64_tl(t1
, t2
);
2888 tcg_temp_free_i64(t2
);
2889 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2890 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2896 generate_exception(ctx
, EXCP_RI
);
2899 (void)opn
; /* avoid a compiler warning */
2900 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2906 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2907 int rd
, int rs
, int rt
)
2909 const char *opn
= "mul vr54xx";
2910 TCGv t0
= tcg_temp_new();
2911 TCGv t1
= tcg_temp_new();
2913 gen_load_gpr(t0
, rs
);
2914 gen_load_gpr(t1
, rt
);
2917 case OPC_VR54XX_MULS
:
2918 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2921 case OPC_VR54XX_MULSU
:
2922 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2925 case OPC_VR54XX_MACC
:
2926 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2929 case OPC_VR54XX_MACCU
:
2930 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2933 case OPC_VR54XX_MSAC
:
2934 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2937 case OPC_VR54XX_MSACU
:
2938 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2941 case OPC_VR54XX_MULHI
:
2942 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2945 case OPC_VR54XX_MULHIU
:
2946 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2949 case OPC_VR54XX_MULSHI
:
2950 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2953 case OPC_VR54XX_MULSHIU
:
2954 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2957 case OPC_VR54XX_MACCHI
:
2958 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2961 case OPC_VR54XX_MACCHIU
:
2962 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2965 case OPC_VR54XX_MSACHI
:
2966 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2969 case OPC_VR54XX_MSACHIU
:
2970 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2974 MIPS_INVAL("mul vr54xx");
2975 generate_exception(ctx
, EXCP_RI
);
2978 gen_store_gpr(t0
, rd
);
2979 (void)opn
; /* avoid a compiler warning */
2980 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2987 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2990 const char *opn
= "CLx";
2998 t0
= tcg_temp_new();
2999 gen_load_gpr(t0
, rs
);
3002 gen_helper_clo(cpu_gpr
[rd
], t0
);
3006 gen_helper_clz(cpu_gpr
[rd
], t0
);
3009 #if defined(TARGET_MIPS64)
3011 gen_helper_dclo(cpu_gpr
[rd
], t0
);
3015 gen_helper_dclz(cpu_gpr
[rd
], t0
);
3020 (void)opn
; /* avoid a compiler warning */
3021 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3025 /* Godson integer instructions */
3026 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3027 int rd
, int rs
, int rt
)
3029 const char *opn
= "loongson";
3041 case OPC_MULTU_G_2E
:
3042 case OPC_MULTU_G_2F
:
3043 #if defined(TARGET_MIPS64)
3044 case OPC_DMULT_G_2E
:
3045 case OPC_DMULT_G_2F
:
3046 case OPC_DMULTU_G_2E
:
3047 case OPC_DMULTU_G_2F
:
3049 t0
= tcg_temp_new();
3050 t1
= tcg_temp_new();
3053 t0
= tcg_temp_local_new();
3054 t1
= tcg_temp_local_new();
3058 gen_load_gpr(t0
, rs
);
3059 gen_load_gpr(t1
, rt
);
3064 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3065 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3068 case OPC_MULTU_G_2E
:
3069 case OPC_MULTU_G_2F
:
3070 tcg_gen_ext32u_tl(t0
, t0
);
3071 tcg_gen_ext32u_tl(t1
, t1
);
3072 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3073 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3079 int l1
= gen_new_label();
3080 int l2
= gen_new_label();
3081 int l3
= gen_new_label();
3082 tcg_gen_ext32s_tl(t0
, t0
);
3083 tcg_gen_ext32s_tl(t1
, t1
);
3084 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3085 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3088 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3089 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3090 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3093 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3094 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3102 int l1
= gen_new_label();
3103 int l2
= gen_new_label();
3104 tcg_gen_ext32u_tl(t0
, t0
);
3105 tcg_gen_ext32u_tl(t1
, t1
);
3106 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3107 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3110 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3111 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3119 int l1
= gen_new_label();
3120 int l2
= gen_new_label();
3121 int l3
= gen_new_label();
3122 tcg_gen_ext32u_tl(t0
, t0
);
3123 tcg_gen_ext32u_tl(t1
, t1
);
3124 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3125 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3126 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3128 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3131 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3132 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3140 int l1
= gen_new_label();
3141 int l2
= gen_new_label();
3142 tcg_gen_ext32u_tl(t0
, t0
);
3143 tcg_gen_ext32u_tl(t1
, t1
);
3144 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3145 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3148 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3149 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3154 #if defined(TARGET_MIPS64)
3155 case OPC_DMULT_G_2E
:
3156 case OPC_DMULT_G_2F
:
3157 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3160 case OPC_DMULTU_G_2E
:
3161 case OPC_DMULTU_G_2F
:
3162 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3168 int l1
= gen_new_label();
3169 int l2
= gen_new_label();
3170 int l3
= gen_new_label();
3171 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3172 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3175 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3176 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3177 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3180 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3185 case OPC_DDIVU_G_2E
:
3186 case OPC_DDIVU_G_2F
:
3188 int l1
= gen_new_label();
3189 int l2
= gen_new_label();
3190 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3191 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3194 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3202 int l1
= gen_new_label();
3203 int l2
= gen_new_label();
3204 int l3
= gen_new_label();
3205 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3206 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3207 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3209 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3212 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3217 case OPC_DMODU_G_2E
:
3218 case OPC_DMODU_G_2F
:
3220 int l1
= gen_new_label();
3221 int l2
= gen_new_label();
3222 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3223 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3226 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3234 (void)opn
; /* avoid a compiler warning */
3235 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3240 /* Loongson multimedia instructions */
3241 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3243 const char *opn
= "loongson_cp2";
3244 uint32_t opc
, shift_max
;
3247 opc
= MASK_LMI(ctx
->opcode
);
3253 t0
= tcg_temp_local_new_i64();
3254 t1
= tcg_temp_local_new_i64();
3257 t0
= tcg_temp_new_i64();
3258 t1
= tcg_temp_new_i64();
3262 gen_load_fpr64(ctx
, t0
, rs
);
3263 gen_load_fpr64(ctx
, t1
, rt
);
3265 #define LMI_HELPER(UP, LO) \
3266 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3267 #define LMI_HELPER_1(UP, LO) \
3268 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3269 #define LMI_DIRECT(UP, LO, OP) \
3270 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3273 LMI_HELPER(PADDSH
, paddsh
);
3274 LMI_HELPER(PADDUSH
, paddush
);
3275 LMI_HELPER(PADDH
, paddh
);
3276 LMI_HELPER(PADDW
, paddw
);
3277 LMI_HELPER(PADDSB
, paddsb
);
3278 LMI_HELPER(PADDUSB
, paddusb
);
3279 LMI_HELPER(PADDB
, paddb
);
3281 LMI_HELPER(PSUBSH
, psubsh
);
3282 LMI_HELPER(PSUBUSH
, psubush
);
3283 LMI_HELPER(PSUBH
, psubh
);
3284 LMI_HELPER(PSUBW
, psubw
);
3285 LMI_HELPER(PSUBSB
, psubsb
);
3286 LMI_HELPER(PSUBUSB
, psubusb
);
3287 LMI_HELPER(PSUBB
, psubb
);
3289 LMI_HELPER(PSHUFH
, pshufh
);
3290 LMI_HELPER(PACKSSWH
, packsswh
);
3291 LMI_HELPER(PACKSSHB
, packsshb
);
3292 LMI_HELPER(PACKUSHB
, packushb
);
3294 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3295 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3296 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3297 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3298 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3299 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3301 LMI_HELPER(PAVGH
, pavgh
);
3302 LMI_HELPER(PAVGB
, pavgb
);
3303 LMI_HELPER(PMAXSH
, pmaxsh
);
3304 LMI_HELPER(PMINSH
, pminsh
);
3305 LMI_HELPER(PMAXUB
, pmaxub
);
3306 LMI_HELPER(PMINUB
, pminub
);
3308 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3309 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3310 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3311 LMI_HELPER(PCMPGTH
, pcmpgth
);
3312 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3313 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3315 LMI_HELPER(PSLLW
, psllw
);
3316 LMI_HELPER(PSLLH
, psllh
);
3317 LMI_HELPER(PSRLW
, psrlw
);
3318 LMI_HELPER(PSRLH
, psrlh
);
3319 LMI_HELPER(PSRAW
, psraw
);
3320 LMI_HELPER(PSRAH
, psrah
);
3322 LMI_HELPER(PMULLH
, pmullh
);
3323 LMI_HELPER(PMULHH
, pmulhh
);
3324 LMI_HELPER(PMULHUH
, pmulhuh
);
3325 LMI_HELPER(PMADDHW
, pmaddhw
);
3327 LMI_HELPER(PASUBUB
, pasubub
);
3328 LMI_HELPER_1(BIADD
, biadd
);
3329 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3331 LMI_DIRECT(PADDD
, paddd
, add
);
3332 LMI_DIRECT(PSUBD
, psubd
, sub
);
3333 LMI_DIRECT(XOR_CP2
, xor, xor);
3334 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3335 LMI_DIRECT(AND_CP2
, and, and);
3336 LMI_DIRECT(PANDN
, pandn
, andc
);
3337 LMI_DIRECT(OR
, or, or);
3340 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3344 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3348 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3352 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3357 tcg_gen_andi_i64(t1
, t1
, 3);
3358 tcg_gen_shli_i64(t1
, t1
, 4);
3359 tcg_gen_shr_i64(t0
, t0
, t1
);
3360 tcg_gen_ext16u_i64(t0
, t0
);
3365 tcg_gen_add_i64(t0
, t0
, t1
);
3366 tcg_gen_ext32s_i64(t0
, t0
);
3370 tcg_gen_sub_i64(t0
, t0
, t1
);
3371 tcg_gen_ext32s_i64(t0
, t0
);
3400 /* Make sure shift count isn't TCG undefined behaviour. */
3401 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3406 tcg_gen_shl_i64(t0
, t0
, t1
);
3410 /* Since SRA is UndefinedResult without sign-extended inputs,
3411 we can treat SRA and DSRA the same. */
3412 tcg_gen_sar_i64(t0
, t0
, t1
);
3415 /* We want to shift in zeros for SRL; zero-extend first. */
3416 tcg_gen_ext32u_i64(t0
, t0
);
3419 tcg_gen_shr_i64(t0
, t0
, t1
);
3423 if (shift_max
== 32) {
3424 tcg_gen_ext32s_i64(t0
, t0
);
3427 /* Shifts larger than MAX produce zero. */
3428 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3429 tcg_gen_neg_i64(t1
, t1
);
3430 tcg_gen_and_i64(t0
, t0
, t1
);
3436 TCGv_i64 t2
= tcg_temp_new_i64();
3437 int lab
= gen_new_label();
3439 tcg_gen_mov_i64(t2
, t0
);
3440 tcg_gen_add_i64(t0
, t1
, t2
);
3441 if (opc
== OPC_ADD_CP2
) {
3442 tcg_gen_ext32s_i64(t0
, t0
);
3444 tcg_gen_xor_i64(t1
, t1
, t2
);
3445 tcg_gen_xor_i64(t2
, t2
, t0
);
3446 tcg_gen_andc_i64(t1
, t2
, t1
);
3447 tcg_temp_free_i64(t2
);
3448 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3449 generate_exception(ctx
, EXCP_OVERFLOW
);
3452 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3459 TCGv_i64 t2
= tcg_temp_new_i64();
3460 int lab
= gen_new_label();
3462 tcg_gen_mov_i64(t2
, t0
);
3463 tcg_gen_sub_i64(t0
, t1
, t2
);
3464 if (opc
== OPC_SUB_CP2
) {
3465 tcg_gen_ext32s_i64(t0
, t0
);
3467 tcg_gen_xor_i64(t1
, t1
, t2
);
3468 tcg_gen_xor_i64(t2
, t2
, t0
);
3469 tcg_gen_and_i64(t1
, t1
, t2
);
3470 tcg_temp_free_i64(t2
);
3471 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3472 generate_exception(ctx
, EXCP_OVERFLOW
);
3475 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3480 tcg_gen_ext32u_i64(t0
, t0
);
3481 tcg_gen_ext32u_i64(t1
, t1
);
3482 tcg_gen_mul_i64(t0
, t0
, t1
);
3492 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3493 FD field is the CC field? */
3496 generate_exception(ctx
, EXCP_RI
);
3503 gen_store_fpr64(ctx
, t0
, rd
);
3505 (void)opn
; /* avoid a compiler warning */
3506 MIPS_DEBUG("%s %s, %s, %s", opn
,
3507 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3508 tcg_temp_free_i64(t0
);
3509 tcg_temp_free_i64(t1
);
3513 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3514 int rs
, int rt
, int16_t imm
)
3517 TCGv t0
= tcg_temp_new();
3518 TCGv t1
= tcg_temp_new();
3521 /* Load needed operands */
3529 /* Compare two registers */
3531 gen_load_gpr(t0
, rs
);
3532 gen_load_gpr(t1
, rt
);
3542 /* Compare register to immediate */
3543 if (rs
!= 0 || imm
!= 0) {
3544 gen_load_gpr(t0
, rs
);
3545 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3552 case OPC_TEQ
: /* rs == rs */
3553 case OPC_TEQI
: /* r0 == 0 */
3554 case OPC_TGE
: /* rs >= rs */
3555 case OPC_TGEI
: /* r0 >= 0 */
3556 case OPC_TGEU
: /* rs >= rs unsigned */
3557 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3559 generate_exception(ctx
, EXCP_TRAP
);
3561 case OPC_TLT
: /* rs < rs */
3562 case OPC_TLTI
: /* r0 < 0 */
3563 case OPC_TLTU
: /* rs < rs unsigned */
3564 case OPC_TLTIU
: /* r0 < 0 unsigned */
3565 case OPC_TNE
: /* rs != rs */
3566 case OPC_TNEI
: /* r0 != 0 */
3567 /* Never trap: treat as NOP. */
3571 int l1
= gen_new_label();
3576 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3580 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3584 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3588 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3592 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3596 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3599 generate_exception(ctx
, EXCP_TRAP
);
3606 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3608 TranslationBlock
*tb
;
3610 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3611 likely(!ctx
->singlestep_enabled
)) {
3614 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3617 if (ctx
->singlestep_enabled
) {
3618 save_cpu_state(ctx
, 0);
3619 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3625 /* Branches (before delay slot) */
3626 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3628 int rs
, int rt
, int32_t offset
)
3630 target_ulong btgt
= -1;
3632 int bcond_compute
= 0;
3633 TCGv t0
= tcg_temp_new();
3634 TCGv t1
= tcg_temp_new();
3636 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3637 #ifdef MIPS_DEBUG_DISAS
3638 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3640 generate_exception(ctx
, EXCP_RI
);
3644 /* Load needed operands */
3650 /* Compare two registers */
3652 gen_load_gpr(t0
, rs
);
3653 gen_load_gpr(t1
, rt
);
3656 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3672 /* Compare to zero */
3674 gen_load_gpr(t0
, rs
);
3677 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3680 #if defined(TARGET_MIPS64)
3682 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3684 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3687 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3694 /* Jump to immediate */
3695 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3701 /* Jump to register */
3702 if (offset
!= 0 && offset
!= 16) {
3703 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3704 others are reserved. */
3705 MIPS_INVAL("jump hint");
3706 generate_exception(ctx
, EXCP_RI
);
3709 gen_load_gpr(btarget
, rs
);
3712 MIPS_INVAL("branch/jump");
3713 generate_exception(ctx
, EXCP_RI
);
3716 if (bcond_compute
== 0) {
3717 /* No condition to be computed */
3719 case OPC_BEQ
: /* rx == rx */
3720 case OPC_BEQL
: /* rx == rx likely */
3721 case OPC_BGEZ
: /* 0 >= 0 */
3722 case OPC_BGEZL
: /* 0 >= 0 likely */
3723 case OPC_BLEZ
: /* 0 <= 0 */
3724 case OPC_BLEZL
: /* 0 <= 0 likely */
3726 ctx
->hflags
|= MIPS_HFLAG_B
;
3727 MIPS_DEBUG("balways");
3730 case OPC_BGEZAL
: /* 0 >= 0 */
3731 case OPC_BGEZALL
: /* 0 >= 0 likely */
3732 ctx
->hflags
|= (opc
== OPC_BGEZALS
3734 : MIPS_HFLAG_BDS32
);
3735 /* Always take and link */
3737 ctx
->hflags
|= MIPS_HFLAG_B
;
3738 MIPS_DEBUG("balways and link");
3740 case OPC_BNE
: /* rx != rx */
3741 case OPC_BGTZ
: /* 0 > 0 */
3742 case OPC_BLTZ
: /* 0 < 0 */
3744 MIPS_DEBUG("bnever (NOP)");
3747 case OPC_BLTZAL
: /* 0 < 0 */
3748 ctx
->hflags
|= (opc
== OPC_BLTZALS
3750 : MIPS_HFLAG_BDS32
);
3751 /* Handle as an unconditional branch to get correct delay
3754 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3755 ctx
->hflags
|= MIPS_HFLAG_B
;
3756 MIPS_DEBUG("bnever and link");
3758 case OPC_BLTZALL
: /* 0 < 0 likely */
3759 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3760 /* Skip the instruction in the delay slot */
3761 MIPS_DEBUG("bnever, link and skip");
3764 case OPC_BNEL
: /* rx != rx likely */
3765 case OPC_BGTZL
: /* 0 > 0 likely */
3766 case OPC_BLTZL
: /* 0 < 0 likely */
3767 /* Skip the instruction in the delay slot */
3768 MIPS_DEBUG("bnever and skip");
3772 ctx
->hflags
|= MIPS_HFLAG_B
;
3773 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3777 ctx
->hflags
|= MIPS_HFLAG_BX
;
3782 ctx
->hflags
|= MIPS_HFLAG_B
;
3783 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3785 : MIPS_HFLAG_BDS32
);
3786 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3789 ctx
->hflags
|= MIPS_HFLAG_BR
;
3790 if (insn_bytes
== 4)
3791 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3792 MIPS_DEBUG("jr %s", regnames
[rs
]);
3798 ctx
->hflags
|= MIPS_HFLAG_BR
;
3799 ctx
->hflags
|= (opc
== OPC_JALRS
3801 : MIPS_HFLAG_BDS32
);
3802 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3805 MIPS_INVAL("branch/jump");
3806 generate_exception(ctx
, EXCP_RI
);
3812 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3813 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3814 regnames
[rs
], regnames
[rt
], btgt
);
3817 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3818 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3819 regnames
[rs
], regnames
[rt
], btgt
);
3822 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3823 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3824 regnames
[rs
], regnames
[rt
], btgt
);
3827 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3828 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3829 regnames
[rs
], regnames
[rt
], btgt
);
3832 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3833 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3836 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3837 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3841 ctx
->hflags
|= (opc
== OPC_BGEZALS
3843 : MIPS_HFLAG_BDS32
);
3844 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3845 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3849 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3851 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3854 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3855 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3858 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3859 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3862 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3863 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3866 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3867 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3870 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3871 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3874 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3875 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3878 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3879 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3881 #if defined(TARGET_MIPS64)
3883 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3884 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3889 ctx
->hflags
|= (opc
== OPC_BLTZALS
3891 : MIPS_HFLAG_BDS32
);
3892 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3894 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3896 ctx
->hflags
|= MIPS_HFLAG_BC
;
3899 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3901 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3903 ctx
->hflags
|= MIPS_HFLAG_BL
;
3906 MIPS_INVAL("conditional branch/jump");
3907 generate_exception(ctx
, EXCP_RI
);
3911 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3912 blink
, ctx
->hflags
, btgt
);
3914 ctx
->btarget
= btgt
;
3916 int post_delay
= insn_bytes
;
3917 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3919 if (opc
!= OPC_JALRC
)
3920 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3922 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3926 if (insn_bytes
== 2)
3927 ctx
->hflags
|= MIPS_HFLAG_B16
;
3932 /* special3 bitfield operations */
3933 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3934 int rs
, int lsb
, int msb
)
3936 TCGv t0
= tcg_temp_new();
3937 TCGv t1
= tcg_temp_new();
3939 gen_load_gpr(t1
, rs
);
3944 tcg_gen_shri_tl(t0
, t1
, lsb
);
3946 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3948 tcg_gen_ext32s_tl(t0
, t0
);
3951 #if defined(TARGET_MIPS64)
3953 tcg_gen_shri_tl(t0
, t1
, lsb
);
3955 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3959 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3960 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3963 tcg_gen_shri_tl(t0
, t1
, lsb
);
3964 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3970 gen_load_gpr(t0
, rt
);
3971 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3972 tcg_gen_ext32s_tl(t0
, t0
);
3974 #if defined(TARGET_MIPS64)
3976 gen_load_gpr(t0
, rt
);
3977 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3980 gen_load_gpr(t0
, rt
);
3981 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3984 gen_load_gpr(t0
, rt
);
3985 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3990 MIPS_INVAL("bitops");
3991 generate_exception(ctx
, EXCP_RI
);
3996 gen_store_gpr(t0
, rt
);
4001 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
4006 /* If no destination, treat it as a NOP. */
4011 t0
= tcg_temp_new();
4012 gen_load_gpr(t0
, rt
);
4016 TCGv t1
= tcg_temp_new();
4018 tcg_gen_shri_tl(t1
, t0
, 8);
4019 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
4020 tcg_gen_shli_tl(t0
, t0
, 8);
4021 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
4022 tcg_gen_or_tl(t0
, t0
, t1
);
4024 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4028 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4031 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4033 #if defined(TARGET_MIPS64)
4036 TCGv t1
= tcg_temp_new();
4038 tcg_gen_shri_tl(t1
, t0
, 8);
4039 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4040 tcg_gen_shli_tl(t0
, t0
, 8);
4041 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4042 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4048 TCGv t1
= tcg_temp_new();
4050 tcg_gen_shri_tl(t1
, t0
, 16);
4051 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4052 tcg_gen_shli_tl(t0
, t0
, 16);
4053 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4054 tcg_gen_or_tl(t0
, t0
, t1
);
4055 tcg_gen_shri_tl(t1
, t0
, 32);
4056 tcg_gen_shli_tl(t0
, t0
, 32);
4057 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4063 MIPS_INVAL("bsfhl");
4064 generate_exception(ctx
, EXCP_RI
);
4071 #ifndef CONFIG_USER_ONLY
4072 /* CP0 (MMU and control) */
4073 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4075 TCGv_i32 t0
= tcg_temp_new_i32();
4077 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4078 tcg_gen_ext_i32_tl(arg
, t0
);
4079 tcg_temp_free_i32(t0
);
4082 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4084 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4085 tcg_gen_ext32s_tl(arg
, arg
);
4088 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4090 TCGv_i32 t0
= tcg_temp_new_i32();
4092 tcg_gen_trunc_tl_i32(t0
, arg
);
4093 tcg_gen_st_i32(t0
, cpu_env
, off
);
4094 tcg_temp_free_i32(t0
);
4097 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4099 tcg_gen_ext32s_tl(arg
, arg
);
4100 tcg_gen_st_tl(arg
, cpu_env
, off
);
4103 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4105 const char *rn
= "invalid";
4108 check_insn(ctx
, ISA_MIPS32
);
4114 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4118 check_insn(ctx
, ASE_MT
);
4119 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4123 check_insn(ctx
, ASE_MT
);
4124 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4128 check_insn(ctx
, ASE_MT
);
4129 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4139 gen_helper_mfc0_random(arg
, cpu_env
);
4143 check_insn(ctx
, ASE_MT
);
4144 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4148 check_insn(ctx
, ASE_MT
);
4149 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4153 check_insn(ctx
, ASE_MT
);
4154 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4158 check_insn(ctx
, ASE_MT
);
4159 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4163 check_insn(ctx
, ASE_MT
);
4164 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4168 check_insn(ctx
, ASE_MT
);
4169 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4170 rn
= "VPEScheFBack";
4173 check_insn(ctx
, ASE_MT
);
4174 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4184 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4185 tcg_gen_ext32s_tl(arg
, arg
);
4189 check_insn(ctx
, ASE_MT
);
4190 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4194 check_insn(ctx
, ASE_MT
);
4195 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4199 check_insn(ctx
, ASE_MT
);
4200 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4204 check_insn(ctx
, ASE_MT
);
4205 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4209 check_insn(ctx
, ASE_MT
);
4210 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4214 check_insn(ctx
, ASE_MT
);
4215 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4219 check_insn(ctx
, ASE_MT
);
4220 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4230 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4231 tcg_gen_ext32s_tl(arg
, arg
);
4241 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4242 tcg_gen_ext32s_tl(arg
, arg
);
4246 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4247 rn
= "ContextConfig";
4256 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4260 check_insn(ctx
, ISA_MIPS32R2
);
4261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4271 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4275 check_insn(ctx
, ISA_MIPS32R2
);
4276 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4280 check_insn(ctx
, ISA_MIPS32R2
);
4281 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4285 check_insn(ctx
, ISA_MIPS32R2
);
4286 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4290 check_insn(ctx
, ISA_MIPS32R2
);
4291 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4295 check_insn(ctx
, ISA_MIPS32R2
);
4296 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4306 check_insn(ctx
, ISA_MIPS32R2
);
4307 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4317 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4318 tcg_gen_ext32s_tl(arg
, arg
);
4328 /* Mark as an IO operation because we read the time. */
4331 gen_helper_mfc0_count(arg
, cpu_env
);
4335 /* Break the TB to be able to take timer interrupts immediately
4336 after reading count. */
4337 ctx
->bstate
= BS_STOP
;
4340 /* 6,7 are implementation dependent */
4348 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4349 tcg_gen_ext32s_tl(arg
, arg
);
4359 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4362 /* 6,7 are implementation dependent */
4370 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4374 check_insn(ctx
, ISA_MIPS32R2
);
4375 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4379 check_insn(ctx
, ISA_MIPS32R2
);
4380 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4384 check_insn(ctx
, ISA_MIPS32R2
);
4385 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4395 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4405 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4406 tcg_gen_ext32s_tl(arg
, arg
);
4416 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4420 check_insn(ctx
, ISA_MIPS32R2
);
4421 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4431 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4439 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4443 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4446 /* 4,5 are reserved */
4447 /* 6,7 are implementation dependent */
4449 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4453 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4463 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4473 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4483 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4493 #if defined(TARGET_MIPS64)
4494 check_insn(ctx
, ISA_MIPS3
);
4495 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4496 tcg_gen_ext32s_tl(arg
, arg
);
4505 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4508 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4516 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4517 rn
= "'Diagnostic"; /* implementation dependent */
4522 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4526 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4527 rn
= "TraceControl";
4530 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4531 rn
= "TraceControl2";
4534 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4535 rn
= "UserTraceData";
4538 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4549 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4550 tcg_gen_ext32s_tl(arg
, arg
);
4560 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4561 rn
= "Performance0";
4564 // gen_helper_mfc0_performance1(arg);
4565 rn
= "Performance1";
4568 // gen_helper_mfc0_performance2(arg);
4569 rn
= "Performance2";
4572 // gen_helper_mfc0_performance3(arg);
4573 rn
= "Performance3";
4576 // gen_helper_mfc0_performance4(arg);
4577 rn
= "Performance4";
4580 // gen_helper_mfc0_performance5(arg);
4581 rn
= "Performance5";
4584 // gen_helper_mfc0_performance6(arg);
4585 rn
= "Performance6";
4588 // gen_helper_mfc0_performance7(arg);
4589 rn
= "Performance7";
4596 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4602 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4615 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4622 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4635 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4642 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4652 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4653 tcg_gen_ext32s_tl(arg
, arg
);
4664 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4674 (void)rn
; /* avoid a compiler warning */
4675 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4679 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4680 generate_exception(ctx
, EXCP_RI
);
4683 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4685 const char *rn
= "invalid";
4688 check_insn(ctx
, ISA_MIPS32
);
4697 gen_helper_mtc0_index(cpu_env
, arg
);
4701 check_insn(ctx
, ASE_MT
);
4702 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4706 check_insn(ctx
, ASE_MT
);
4711 check_insn(ctx
, ASE_MT
);
4726 check_insn(ctx
, ASE_MT
);
4727 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4731 check_insn(ctx
, ASE_MT
);
4732 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4736 check_insn(ctx
, ASE_MT
);
4737 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4741 check_insn(ctx
, ASE_MT
);
4742 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4746 check_insn(ctx
, ASE_MT
);
4747 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4751 check_insn(ctx
, ASE_MT
);
4752 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4753 rn
= "VPEScheFBack";
4756 check_insn(ctx
, ASE_MT
);
4757 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4767 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4771 check_insn(ctx
, ASE_MT
);
4772 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4776 check_insn(ctx
, ASE_MT
);
4777 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4781 check_insn(ctx
, ASE_MT
);
4782 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4786 check_insn(ctx
, ASE_MT
);
4787 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4791 check_insn(ctx
, ASE_MT
);
4792 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4796 check_insn(ctx
, ASE_MT
);
4797 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4801 check_insn(ctx
, ASE_MT
);
4802 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4812 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4822 gen_helper_mtc0_context(cpu_env
, arg
);
4826 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4827 rn
= "ContextConfig";
4836 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4840 check_insn(ctx
, ISA_MIPS32R2
);
4841 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4851 gen_helper_mtc0_wired(cpu_env
, arg
);
4855 check_insn(ctx
, ISA_MIPS32R2
);
4856 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4860 check_insn(ctx
, ISA_MIPS32R2
);
4861 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4865 check_insn(ctx
, ISA_MIPS32R2
);
4866 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4870 check_insn(ctx
, ISA_MIPS32R2
);
4871 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4875 check_insn(ctx
, ISA_MIPS32R2
);
4876 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4886 check_insn(ctx
, ISA_MIPS32R2
);
4887 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4901 gen_helper_mtc0_count(cpu_env
, arg
);
4904 /* 6,7 are implementation dependent */
4912 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4922 gen_helper_mtc0_compare(cpu_env
, arg
);
4925 /* 6,7 are implementation dependent */
4933 save_cpu_state(ctx
, 1);
4934 gen_helper_mtc0_status(cpu_env
, arg
);
4935 /* BS_STOP isn't good enough here, hflags may have changed. */
4936 gen_save_pc(ctx
->pc
+ 4);
4937 ctx
->bstate
= BS_EXCP
;
4941 check_insn(ctx
, ISA_MIPS32R2
);
4942 gen_helper_mtc0_intctl(cpu_env
, arg
);
4943 /* Stop translation as we may have switched the execution mode */
4944 ctx
->bstate
= BS_STOP
;
4948 check_insn(ctx
, ISA_MIPS32R2
);
4949 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4950 /* Stop translation as we may have switched the execution mode */
4951 ctx
->bstate
= BS_STOP
;
4955 check_insn(ctx
, ISA_MIPS32R2
);
4956 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4957 /* Stop translation as we may have switched the execution mode */
4958 ctx
->bstate
= BS_STOP
;
4968 save_cpu_state(ctx
, 1);
4969 gen_helper_mtc0_cause(cpu_env
, arg
);
4979 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4993 check_insn(ctx
, ISA_MIPS32R2
);
4994 gen_helper_mtc0_ebase(cpu_env
, arg
);
5004 gen_helper_mtc0_config0(cpu_env
, arg
);
5006 /* Stop translation as we may have switched the execution mode */
5007 ctx
->bstate
= BS_STOP
;
5010 /* ignored, read only */
5014 gen_helper_mtc0_config2(cpu_env
, arg
);
5016 /* Stop translation as we may have switched the execution mode */
5017 ctx
->bstate
= BS_STOP
;
5020 /* ignored, read only */
5023 /* 4,5 are reserved */
5024 /* 6,7 are implementation dependent */
5034 rn
= "Invalid config selector";
5041 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5051 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5061 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5071 #if defined(TARGET_MIPS64)
5072 check_insn(ctx
, ISA_MIPS3
);
5073 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5082 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5085 gen_helper_mtc0_framemask(cpu_env
, arg
);
5094 rn
= "Diagnostic"; /* implementation dependent */
5099 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5100 /* BS_STOP isn't good enough here, hflags may have changed. */
5101 gen_save_pc(ctx
->pc
+ 4);
5102 ctx
->bstate
= BS_EXCP
;
5106 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5107 rn
= "TraceControl";
5108 /* Stop translation as we may have switched the execution mode */
5109 ctx
->bstate
= BS_STOP
;
5112 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5113 rn
= "TraceControl2";
5114 /* Stop translation as we may have switched the execution mode */
5115 ctx
->bstate
= BS_STOP
;
5118 /* Stop translation as we may have switched the execution mode */
5119 ctx
->bstate
= BS_STOP
;
5120 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5121 rn
= "UserTraceData";
5122 /* Stop translation as we may have switched the execution mode */
5123 ctx
->bstate
= BS_STOP
;
5126 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5127 /* Stop translation as we may have switched the execution mode */
5128 ctx
->bstate
= BS_STOP
;
5139 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5149 gen_helper_mtc0_performance0(cpu_env
, arg
);
5150 rn
= "Performance0";
5153 // gen_helper_mtc0_performance1(arg);
5154 rn
= "Performance1";
5157 // gen_helper_mtc0_performance2(arg);
5158 rn
= "Performance2";
5161 // gen_helper_mtc0_performance3(arg);
5162 rn
= "Performance3";
5165 // gen_helper_mtc0_performance4(arg);
5166 rn
= "Performance4";
5169 // gen_helper_mtc0_performance5(arg);
5170 rn
= "Performance5";
5173 // gen_helper_mtc0_performance6(arg);
5174 rn
= "Performance6";
5177 // gen_helper_mtc0_performance7(arg);
5178 rn
= "Performance7";
5204 gen_helper_mtc0_taglo(cpu_env
, arg
);
5211 gen_helper_mtc0_datalo(cpu_env
, arg
);
5224 gen_helper_mtc0_taghi(cpu_env
, arg
);
5231 gen_helper_mtc0_datahi(cpu_env
, arg
);
5242 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5253 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5259 /* Stop translation as we may have switched the execution mode */
5260 ctx
->bstate
= BS_STOP
;
5265 (void)rn
; /* avoid a compiler warning */
5266 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5267 /* For simplicity assume that all writes can cause interrupts. */
5270 ctx
->bstate
= BS_STOP
;
5275 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5276 generate_exception(ctx
, EXCP_RI
);
5279 #if defined(TARGET_MIPS64)
5280 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5282 const char *rn
= "invalid";
5285 check_insn(ctx
, ISA_MIPS64
);
5291 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5295 check_insn(ctx
, ASE_MT
);
5296 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5300 check_insn(ctx
, ASE_MT
);
5301 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5305 check_insn(ctx
, ASE_MT
);
5306 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5316 gen_helper_mfc0_random(arg
, cpu_env
);
5320 check_insn(ctx
, ASE_MT
);
5321 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5325 check_insn(ctx
, ASE_MT
);
5326 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5330 check_insn(ctx
, ASE_MT
);
5331 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5335 check_insn(ctx
, ASE_MT
);
5336 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5340 check_insn(ctx
, ASE_MT
);
5341 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5345 check_insn(ctx
, ASE_MT
);
5346 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5347 rn
= "VPEScheFBack";
5350 check_insn(ctx
, ASE_MT
);
5351 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5361 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5365 check_insn(ctx
, ASE_MT
);
5366 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5370 check_insn(ctx
, ASE_MT
);
5371 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5375 check_insn(ctx
, ASE_MT
);
5376 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5380 check_insn(ctx
, ASE_MT
);
5381 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5385 check_insn(ctx
, ASE_MT
);
5386 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5390 check_insn(ctx
, ASE_MT
);
5391 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5395 check_insn(ctx
, ASE_MT
);
5396 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5406 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5416 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5420 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5421 rn
= "ContextConfig";
5430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5434 check_insn(ctx
, ISA_MIPS32R2
);
5435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5445 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5449 check_insn(ctx
, ISA_MIPS32R2
);
5450 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5454 check_insn(ctx
, ISA_MIPS32R2
);
5455 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5459 check_insn(ctx
, ISA_MIPS32R2
);
5460 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5464 check_insn(ctx
, ISA_MIPS32R2
);
5465 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5469 check_insn(ctx
, ISA_MIPS32R2
);
5470 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5480 check_insn(ctx
, ISA_MIPS32R2
);
5481 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5491 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5501 /* Mark as an IO operation because we read the time. */
5504 gen_helper_mfc0_count(arg
, cpu_env
);
5508 /* Break the TB to be able to take timer interrupts immediately
5509 after reading count. */
5510 ctx
->bstate
= BS_STOP
;
5513 /* 6,7 are implementation dependent */
5521 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5531 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5534 /* 6,7 are implementation dependent */
5542 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5546 check_insn(ctx
, ISA_MIPS32R2
);
5547 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5551 check_insn(ctx
, ISA_MIPS32R2
);
5552 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5556 check_insn(ctx
, ISA_MIPS32R2
);
5557 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5567 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5577 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5587 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5591 check_insn(ctx
, ISA_MIPS32R2
);
5592 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5602 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5606 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5610 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5614 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5617 /* 6,7 are implementation dependent */
5619 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5623 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5633 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5643 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5653 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5663 check_insn(ctx
, ISA_MIPS3
);
5664 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5672 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5675 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5683 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5684 rn
= "'Diagnostic"; /* implementation dependent */
5689 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5693 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5694 rn
= "TraceControl";
5697 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5698 rn
= "TraceControl2";
5701 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5702 rn
= "UserTraceData";
5705 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5716 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5726 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5727 rn
= "Performance0";
5730 // gen_helper_dmfc0_performance1(arg);
5731 rn
= "Performance1";
5734 // gen_helper_dmfc0_performance2(arg);
5735 rn
= "Performance2";
5738 // gen_helper_dmfc0_performance3(arg);
5739 rn
= "Performance3";
5742 // gen_helper_dmfc0_performance4(arg);
5743 rn
= "Performance4";
5746 // gen_helper_dmfc0_performance5(arg);
5747 rn
= "Performance5";
5750 // gen_helper_dmfc0_performance6(arg);
5751 rn
= "Performance6";
5754 // gen_helper_dmfc0_performance7(arg);
5755 rn
= "Performance7";
5762 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5769 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5782 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5789 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5802 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5809 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5819 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5830 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5840 (void)rn
; /* avoid a compiler warning */
5841 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5845 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5846 generate_exception(ctx
, EXCP_RI
);
5849 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5851 const char *rn
= "invalid";
5854 check_insn(ctx
, ISA_MIPS64
);
5863 gen_helper_mtc0_index(cpu_env
, arg
);
5867 check_insn(ctx
, ASE_MT
);
5868 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5872 check_insn(ctx
, ASE_MT
);
5877 check_insn(ctx
, ASE_MT
);
5892 check_insn(ctx
, ASE_MT
);
5893 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5897 check_insn(ctx
, ASE_MT
);
5898 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5902 check_insn(ctx
, ASE_MT
);
5903 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5907 check_insn(ctx
, ASE_MT
);
5908 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5912 check_insn(ctx
, ASE_MT
);
5913 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5917 check_insn(ctx
, ASE_MT
);
5918 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5919 rn
= "VPEScheFBack";
5922 check_insn(ctx
, ASE_MT
);
5923 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5933 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5937 check_insn(ctx
, ASE_MT
);
5938 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5942 check_insn(ctx
, ASE_MT
);
5943 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5947 check_insn(ctx
, ASE_MT
);
5948 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5952 check_insn(ctx
, ASE_MT
);
5953 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5957 check_insn(ctx
, ASE_MT
);
5958 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5962 check_insn(ctx
, ASE_MT
);
5963 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5967 check_insn(ctx
, ASE_MT
);
5968 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5978 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5988 gen_helper_mtc0_context(cpu_env
, arg
);
5992 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5993 rn
= "ContextConfig";
6002 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6006 check_insn(ctx
, ISA_MIPS32R2
);
6007 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6017 gen_helper_mtc0_wired(cpu_env
, arg
);
6021 check_insn(ctx
, ISA_MIPS32R2
);
6022 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6026 check_insn(ctx
, ISA_MIPS32R2
);
6027 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6031 check_insn(ctx
, ISA_MIPS32R2
);
6032 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6036 check_insn(ctx
, ISA_MIPS32R2
);
6037 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6041 check_insn(ctx
, ISA_MIPS32R2
);
6042 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6052 check_insn(ctx
, ISA_MIPS32R2
);
6053 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6067 gen_helper_mtc0_count(cpu_env
, arg
);
6070 /* 6,7 are implementation dependent */
6074 /* Stop translation as we may have switched the execution mode */
6075 ctx
->bstate
= BS_STOP
;
6080 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6090 gen_helper_mtc0_compare(cpu_env
, arg
);
6093 /* 6,7 are implementation dependent */
6097 /* Stop translation as we may have switched the execution mode */
6098 ctx
->bstate
= BS_STOP
;
6103 save_cpu_state(ctx
, 1);
6104 gen_helper_mtc0_status(cpu_env
, arg
);
6105 /* BS_STOP isn't good enough here, hflags may have changed. */
6106 gen_save_pc(ctx
->pc
+ 4);
6107 ctx
->bstate
= BS_EXCP
;
6111 check_insn(ctx
, ISA_MIPS32R2
);
6112 gen_helper_mtc0_intctl(cpu_env
, arg
);
6113 /* Stop translation as we may have switched the execution mode */
6114 ctx
->bstate
= BS_STOP
;
6118 check_insn(ctx
, ISA_MIPS32R2
);
6119 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6120 /* Stop translation as we may have switched the execution mode */
6121 ctx
->bstate
= BS_STOP
;
6125 check_insn(ctx
, ISA_MIPS32R2
);
6126 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6127 /* Stop translation as we may have switched the execution mode */
6128 ctx
->bstate
= BS_STOP
;
6138 save_cpu_state(ctx
, 1);
6139 /* Mark as an IO operation because we may trigger a software
6144 gen_helper_mtc0_cause(cpu_env
, arg
);
6148 /* Stop translation as we may have triggered an intetrupt */
6149 ctx
->bstate
= BS_STOP
;
6159 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6173 check_insn(ctx
, ISA_MIPS32R2
);
6174 gen_helper_mtc0_ebase(cpu_env
, arg
);
6184 gen_helper_mtc0_config0(cpu_env
, arg
);
6186 /* Stop translation as we may have switched the execution mode */
6187 ctx
->bstate
= BS_STOP
;
6190 /* ignored, read only */
6194 gen_helper_mtc0_config2(cpu_env
, arg
);
6196 /* Stop translation as we may have switched the execution mode */
6197 ctx
->bstate
= BS_STOP
;
6203 /* 6,7 are implementation dependent */
6205 rn
= "Invalid config selector";
6212 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6222 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6232 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6242 check_insn(ctx
, ISA_MIPS3
);
6243 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6251 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6254 gen_helper_mtc0_framemask(cpu_env
, arg
);
6263 rn
= "Diagnostic"; /* implementation dependent */
6268 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6269 /* BS_STOP isn't good enough here, hflags may have changed. */
6270 gen_save_pc(ctx
->pc
+ 4);
6271 ctx
->bstate
= BS_EXCP
;
6275 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6276 /* Stop translation as we may have switched the execution mode */
6277 ctx
->bstate
= BS_STOP
;
6278 rn
= "TraceControl";
6281 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6282 /* Stop translation as we may have switched the execution mode */
6283 ctx
->bstate
= BS_STOP
;
6284 rn
= "TraceControl2";
6287 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6288 /* Stop translation as we may have switched the execution mode */
6289 ctx
->bstate
= BS_STOP
;
6290 rn
= "UserTraceData";
6293 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6294 /* Stop translation as we may have switched the execution mode */
6295 ctx
->bstate
= BS_STOP
;
6306 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6316 gen_helper_mtc0_performance0(cpu_env
, arg
);
6317 rn
= "Performance0";
6320 // gen_helper_mtc0_performance1(cpu_env, arg);
6321 rn
= "Performance1";
6324 // gen_helper_mtc0_performance2(cpu_env, arg);
6325 rn
= "Performance2";
6328 // gen_helper_mtc0_performance3(cpu_env, arg);
6329 rn
= "Performance3";
6332 // gen_helper_mtc0_performance4(cpu_env, arg);
6333 rn
= "Performance4";
6336 // gen_helper_mtc0_performance5(cpu_env, arg);
6337 rn
= "Performance5";
6340 // gen_helper_mtc0_performance6(cpu_env, arg);
6341 rn
= "Performance6";
6344 // gen_helper_mtc0_performance7(cpu_env, arg);
6345 rn
= "Performance7";
6371 gen_helper_mtc0_taglo(cpu_env
, arg
);
6378 gen_helper_mtc0_datalo(cpu_env
, arg
);
6391 gen_helper_mtc0_taghi(cpu_env
, arg
);
6398 gen_helper_mtc0_datahi(cpu_env
, arg
);
6409 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6420 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6426 /* Stop translation as we may have switched the execution mode */
6427 ctx
->bstate
= BS_STOP
;
6432 (void)rn
; /* avoid a compiler warning */
6433 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6434 /* For simplicity assume that all writes can cause interrupts. */
6437 ctx
->bstate
= BS_STOP
;
6442 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6443 generate_exception(ctx
, EXCP_RI
);
6445 #endif /* TARGET_MIPS64 */
6447 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6448 int u
, int sel
, int h
)
6450 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6451 TCGv t0
= tcg_temp_local_new();
6453 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6454 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6455 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6456 tcg_gen_movi_tl(t0
, -1);
6457 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6458 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6459 tcg_gen_movi_tl(t0
, -1);
6465 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6468 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6478 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6481 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6484 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6487 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6490 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6493 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6496 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6499 gen_mfc0(ctx
, t0
, rt
, sel
);
6506 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6509 gen_mfc0(ctx
, t0
, rt
, sel
);
6515 gen_helper_mftc0_status(t0
, cpu_env
);
6518 gen_mfc0(ctx
, t0
, rt
, sel
);
6524 gen_helper_mftc0_cause(t0
, cpu_env
);
6534 gen_helper_mftc0_epc(t0
, cpu_env
);
6544 gen_helper_mftc0_ebase(t0
, cpu_env
);
6554 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6564 gen_helper_mftc0_debug(t0
, cpu_env
);
6567 gen_mfc0(ctx
, t0
, rt
, sel
);
6572 gen_mfc0(ctx
, t0
, rt
, sel
);
6574 } else switch (sel
) {
6575 /* GPR registers. */
6577 gen_helper_1e0i(mftgpr
, t0
, rt
);
6579 /* Auxiliary CPU registers */
6583 gen_helper_1e0i(mftlo
, t0
, 0);
6586 gen_helper_1e0i(mfthi
, t0
, 0);
6589 gen_helper_1e0i(mftacx
, t0
, 0);
6592 gen_helper_1e0i(mftlo
, t0
, 1);
6595 gen_helper_1e0i(mfthi
, t0
, 1);
6598 gen_helper_1e0i(mftacx
, t0
, 1);
6601 gen_helper_1e0i(mftlo
, t0
, 2);
6604 gen_helper_1e0i(mfthi
, t0
, 2);
6607 gen_helper_1e0i(mftacx
, t0
, 2);
6610 gen_helper_1e0i(mftlo
, t0
, 3);
6613 gen_helper_1e0i(mfthi
, t0
, 3);
6616 gen_helper_1e0i(mftacx
, t0
, 3);
6619 gen_helper_mftdsp(t0
, cpu_env
);
6625 /* Floating point (COP1). */
6627 /* XXX: For now we support only a single FPU context. */
6629 TCGv_i32 fp0
= tcg_temp_new_i32();
6631 gen_load_fpr32(fp0
, rt
);
6632 tcg_gen_ext_i32_tl(t0
, fp0
);
6633 tcg_temp_free_i32(fp0
);
6635 TCGv_i32 fp0
= tcg_temp_new_i32();
6637 gen_load_fpr32h(fp0
, rt
);
6638 tcg_gen_ext_i32_tl(t0
, fp0
);
6639 tcg_temp_free_i32(fp0
);
6643 /* XXX: For now we support only a single FPU context. */
6644 gen_helper_1e0i(cfc1
, t0
, rt
);
6646 /* COP2: Not implemented. */
6653 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6654 gen_store_gpr(t0
, rd
);
6660 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6661 generate_exception(ctx
, EXCP_RI
);
6664 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6665 int u
, int sel
, int h
)
6667 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6668 TCGv t0
= tcg_temp_local_new();
6670 gen_load_gpr(t0
, rt
);
6671 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6672 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6673 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6675 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6676 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6683 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6686 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6696 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6699 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6702 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6705 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6708 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6711 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6714 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6717 gen_mtc0(ctx
, t0
, rd
, sel
);
6724 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6727 gen_mtc0(ctx
, t0
, rd
, sel
);
6733 gen_helper_mttc0_status(cpu_env
, t0
);
6736 gen_mtc0(ctx
, t0
, rd
, sel
);
6742 gen_helper_mttc0_cause(cpu_env
, t0
);
6752 gen_helper_mttc0_ebase(cpu_env
, t0
);
6762 gen_helper_mttc0_debug(cpu_env
, t0
);
6765 gen_mtc0(ctx
, t0
, rd
, sel
);
6770 gen_mtc0(ctx
, t0
, rd
, sel
);
6772 } else switch (sel
) {
6773 /* GPR registers. */
6775 gen_helper_0e1i(mttgpr
, t0
, rd
);
6777 /* Auxiliary CPU registers */
6781 gen_helper_0e1i(mttlo
, t0
, 0);
6784 gen_helper_0e1i(mtthi
, t0
, 0);
6787 gen_helper_0e1i(mttacx
, t0
, 0);
6790 gen_helper_0e1i(mttlo
, t0
, 1);
6793 gen_helper_0e1i(mtthi
, t0
, 1);
6796 gen_helper_0e1i(mttacx
, t0
, 1);
6799 gen_helper_0e1i(mttlo
, t0
, 2);
6802 gen_helper_0e1i(mtthi
, t0
, 2);
6805 gen_helper_0e1i(mttacx
, t0
, 2);
6808 gen_helper_0e1i(mttlo
, t0
, 3);
6811 gen_helper_0e1i(mtthi
, t0
, 3);
6814 gen_helper_0e1i(mttacx
, t0
, 3);
6817 gen_helper_mttdsp(cpu_env
, t0
);
6823 /* Floating point (COP1). */
6825 /* XXX: For now we support only a single FPU context. */
6827 TCGv_i32 fp0
= tcg_temp_new_i32();
6829 tcg_gen_trunc_tl_i32(fp0
, t0
);
6830 gen_store_fpr32(fp0
, rd
);
6831 tcg_temp_free_i32(fp0
);
6833 TCGv_i32 fp0
= tcg_temp_new_i32();
6835 tcg_gen_trunc_tl_i32(fp0
, t0
);
6836 gen_store_fpr32h(fp0
, rd
);
6837 tcg_temp_free_i32(fp0
);
6841 /* XXX: For now we support only a single FPU context. */
6842 gen_helper_0e1i(ctc1
, t0
, rd
);
6844 /* COP2: Not implemented. */
6851 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6857 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6858 generate_exception(ctx
, EXCP_RI
);
6861 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6863 const char *opn
= "ldst";
6865 check_cp0_enabled(ctx
);
6872 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6877 TCGv t0
= tcg_temp_new();
6879 gen_load_gpr(t0
, rt
);
6880 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6885 #if defined(TARGET_MIPS64)
6887 check_insn(ctx
, ISA_MIPS3
);
6892 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6896 check_insn(ctx
, ISA_MIPS3
);
6898 TCGv t0
= tcg_temp_new();
6900 gen_load_gpr(t0
, rt
);
6901 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6908 check_insn(ctx
, ASE_MT
);
6913 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6914 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6918 check_insn(ctx
, ASE_MT
);
6919 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6920 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6925 if (!env
->tlb
->helper_tlbwi
)
6927 gen_helper_tlbwi(cpu_env
);
6931 if (!env
->tlb
->helper_tlbwr
)
6933 gen_helper_tlbwr(cpu_env
);
6937 if (!env
->tlb
->helper_tlbp
)
6939 gen_helper_tlbp(cpu_env
);
6943 if (!env
->tlb
->helper_tlbr
)
6945 gen_helper_tlbr(cpu_env
);
6949 check_insn(ctx
, ISA_MIPS2
);
6950 gen_helper_eret(cpu_env
);
6951 ctx
->bstate
= BS_EXCP
;
6955 check_insn(ctx
, ISA_MIPS32
);
6956 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6958 generate_exception(ctx
, EXCP_RI
);
6960 gen_helper_deret(cpu_env
);
6961 ctx
->bstate
= BS_EXCP
;
6966 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
6967 /* If we get an exception, we want to restart at next instruction */
6969 save_cpu_state(ctx
, 1);
6971 gen_helper_wait(cpu_env
);
6972 ctx
->bstate
= BS_EXCP
;
6977 generate_exception(ctx
, EXCP_RI
);
6980 (void)opn
; /* avoid a compiler warning */
6981 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
6983 #endif /* !CONFIG_USER_ONLY */
6985 /* CP1 Branches (before delay slot) */
6986 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
6987 int32_t cc
, int32_t offset
)
6989 target_ulong btarget
;
6990 const char *opn
= "cp1 cond branch";
6991 TCGv_i32 t0
= tcg_temp_new_i32();
6994 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
6996 btarget
= ctx
->pc
+ 4 + offset
;
7000 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7001 tcg_gen_not_i32(t0
, t0
);
7002 tcg_gen_andi_i32(t0
, t0
, 1);
7003 tcg_gen_extu_i32_tl(bcond
, t0
);
7007 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7008 tcg_gen_not_i32(t0
, t0
);
7009 tcg_gen_andi_i32(t0
, t0
, 1);
7010 tcg_gen_extu_i32_tl(bcond
, t0
);
7014 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7015 tcg_gen_andi_i32(t0
, t0
, 1);
7016 tcg_gen_extu_i32_tl(bcond
, t0
);
7020 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7021 tcg_gen_andi_i32(t0
, t0
, 1);
7022 tcg_gen_extu_i32_tl(bcond
, t0
);
7025 ctx
->hflags
|= MIPS_HFLAG_BL
;
7029 TCGv_i32 t1
= tcg_temp_new_i32();
7030 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7031 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7032 tcg_gen_nand_i32(t0
, t0
, t1
);
7033 tcg_temp_free_i32(t1
);
7034 tcg_gen_andi_i32(t0
, t0
, 1);
7035 tcg_gen_extu_i32_tl(bcond
, t0
);
7041 TCGv_i32 t1
= tcg_temp_new_i32();
7042 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7043 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7044 tcg_gen_or_i32(t0
, t0
, t1
);
7045 tcg_temp_free_i32(t1
);
7046 tcg_gen_andi_i32(t0
, t0
, 1);
7047 tcg_gen_extu_i32_tl(bcond
, t0
);
7053 TCGv_i32 t1
= tcg_temp_new_i32();
7054 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7055 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7056 tcg_gen_and_i32(t0
, t0
, t1
);
7057 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7058 tcg_gen_and_i32(t0
, t0
, t1
);
7059 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7060 tcg_gen_nand_i32(t0
, t0
, t1
);
7061 tcg_temp_free_i32(t1
);
7062 tcg_gen_andi_i32(t0
, t0
, 1);
7063 tcg_gen_extu_i32_tl(bcond
, t0
);
7069 TCGv_i32 t1
= tcg_temp_new_i32();
7070 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7071 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7072 tcg_gen_or_i32(t0
, t0
, t1
);
7073 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7074 tcg_gen_or_i32(t0
, t0
, t1
);
7075 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7076 tcg_gen_or_i32(t0
, t0
, t1
);
7077 tcg_temp_free_i32(t1
);
7078 tcg_gen_andi_i32(t0
, t0
, 1);
7079 tcg_gen_extu_i32_tl(bcond
, t0
);
7083 ctx
->hflags
|= MIPS_HFLAG_BC
;
7087 generate_exception (ctx
, EXCP_RI
);
7090 (void)opn
; /* avoid a compiler warning */
7091 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7092 ctx
->hflags
, btarget
);
7093 ctx
->btarget
= btarget
;
7096 tcg_temp_free_i32(t0
);
7099 /* Coprocessor 1 (FPU) */
7101 #define FOP(func, fmt) (((fmt) << 21) | (func))
7104 OPC_ADD_S
= FOP(0, FMT_S
),
7105 OPC_SUB_S
= FOP(1, FMT_S
),
7106 OPC_MUL_S
= FOP(2, FMT_S
),
7107 OPC_DIV_S
= FOP(3, FMT_S
),
7108 OPC_SQRT_S
= FOP(4, FMT_S
),
7109 OPC_ABS_S
= FOP(5, FMT_S
),
7110 OPC_MOV_S
= FOP(6, FMT_S
),
7111 OPC_NEG_S
= FOP(7, FMT_S
),
7112 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7113 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7114 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7115 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7116 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7117 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7118 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7119 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7120 OPC_MOVCF_S
= FOP(17, FMT_S
),
7121 OPC_MOVZ_S
= FOP(18, FMT_S
),
7122 OPC_MOVN_S
= FOP(19, FMT_S
),
7123 OPC_RECIP_S
= FOP(21, FMT_S
),
7124 OPC_RSQRT_S
= FOP(22, FMT_S
),
7125 OPC_RECIP2_S
= FOP(28, FMT_S
),
7126 OPC_RECIP1_S
= FOP(29, FMT_S
),
7127 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7128 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7129 OPC_CVT_D_S
= FOP(33, FMT_S
),
7130 OPC_CVT_W_S
= FOP(36, FMT_S
),
7131 OPC_CVT_L_S
= FOP(37, FMT_S
),
7132 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7133 OPC_CMP_F_S
= FOP (48, FMT_S
),
7134 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7135 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7136 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7137 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7138 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7139 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7140 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7141 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7142 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7143 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7144 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7145 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7146 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7147 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7148 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7150 OPC_ADD_D
= FOP(0, FMT_D
),
7151 OPC_SUB_D
= FOP(1, FMT_D
),
7152 OPC_MUL_D
= FOP(2, FMT_D
),
7153 OPC_DIV_D
= FOP(3, FMT_D
),
7154 OPC_SQRT_D
= FOP(4, FMT_D
),
7155 OPC_ABS_D
= FOP(5, FMT_D
),
7156 OPC_MOV_D
= FOP(6, FMT_D
),
7157 OPC_NEG_D
= FOP(7, FMT_D
),
7158 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7159 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7160 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7161 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7162 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7163 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7164 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7165 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7166 OPC_MOVCF_D
= FOP(17, FMT_D
),
7167 OPC_MOVZ_D
= FOP(18, FMT_D
),
7168 OPC_MOVN_D
= FOP(19, FMT_D
),
7169 OPC_RECIP_D
= FOP(21, FMT_D
),
7170 OPC_RSQRT_D
= FOP(22, FMT_D
),
7171 OPC_RECIP2_D
= FOP(28, FMT_D
),
7172 OPC_RECIP1_D
= FOP(29, FMT_D
),
7173 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7174 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7175 OPC_CVT_S_D
= FOP(32, FMT_D
),
7176 OPC_CVT_W_D
= FOP(36, FMT_D
),
7177 OPC_CVT_L_D
= FOP(37, FMT_D
),
7178 OPC_CMP_F_D
= FOP (48, FMT_D
),
7179 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7180 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7181 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7182 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7183 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7184 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7185 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7186 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7187 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7188 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7189 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7190 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7191 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7192 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7193 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7195 OPC_CVT_S_W
= FOP(32, FMT_W
),
7196 OPC_CVT_D_W
= FOP(33, FMT_W
),
7197 OPC_CVT_S_L
= FOP(32, FMT_L
),
7198 OPC_CVT_D_L
= FOP(33, FMT_L
),
7199 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7201 OPC_ADD_PS
= FOP(0, FMT_PS
),
7202 OPC_SUB_PS
= FOP(1, FMT_PS
),
7203 OPC_MUL_PS
= FOP(2, FMT_PS
),
7204 OPC_DIV_PS
= FOP(3, FMT_PS
),
7205 OPC_ABS_PS
= FOP(5, FMT_PS
),
7206 OPC_MOV_PS
= FOP(6, FMT_PS
),
7207 OPC_NEG_PS
= FOP(7, FMT_PS
),
7208 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7209 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7210 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7211 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7212 OPC_MULR_PS
= FOP(26, FMT_PS
),
7213 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7214 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7215 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7216 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7218 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7219 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7220 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7221 OPC_PLL_PS
= FOP(44, FMT_PS
),
7222 OPC_PLU_PS
= FOP(45, FMT_PS
),
7223 OPC_PUL_PS
= FOP(46, FMT_PS
),
7224 OPC_PUU_PS
= FOP(47, FMT_PS
),
7225 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7226 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7227 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7228 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7229 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7230 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7231 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7232 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7233 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7234 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7235 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7236 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7237 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7238 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7239 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7240 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7243 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7245 const char *opn
= "cp1 move";
7246 TCGv t0
= tcg_temp_new();
7251 TCGv_i32 fp0
= tcg_temp_new_i32();
7253 gen_load_fpr32(fp0
, fs
);
7254 tcg_gen_ext_i32_tl(t0
, fp0
);
7255 tcg_temp_free_i32(fp0
);
7257 gen_store_gpr(t0
, rt
);
7261 gen_load_gpr(t0
, rt
);
7263 TCGv_i32 fp0
= tcg_temp_new_i32();
7265 tcg_gen_trunc_tl_i32(fp0
, t0
);
7266 gen_store_fpr32(fp0
, fs
);
7267 tcg_temp_free_i32(fp0
);
7272 gen_helper_1e0i(cfc1
, t0
, fs
);
7273 gen_store_gpr(t0
, rt
);
7277 gen_load_gpr(t0
, rt
);
7278 gen_helper_0e1i(ctc1
, t0
, fs
);
7281 #if defined(TARGET_MIPS64)
7283 gen_load_fpr64(ctx
, t0
, fs
);
7284 gen_store_gpr(t0
, rt
);
7288 gen_load_gpr(t0
, rt
);
7289 gen_store_fpr64(ctx
, t0
, fs
);
7295 TCGv_i32 fp0
= tcg_temp_new_i32();
7297 gen_load_fpr32h(fp0
, fs
);
7298 tcg_gen_ext_i32_tl(t0
, fp0
);
7299 tcg_temp_free_i32(fp0
);
7301 gen_store_gpr(t0
, rt
);
7305 gen_load_gpr(t0
, rt
);
7307 TCGv_i32 fp0
= tcg_temp_new_i32();
7309 tcg_gen_trunc_tl_i32(fp0
, t0
);
7310 gen_store_fpr32h(fp0
, fs
);
7311 tcg_temp_free_i32(fp0
);
7317 generate_exception (ctx
, EXCP_RI
);
7320 (void)opn
; /* avoid a compiler warning */
7321 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7327 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7343 l1
= gen_new_label();
7344 t0
= tcg_temp_new_i32();
7345 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7346 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7347 tcg_temp_free_i32(t0
);
7349 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7351 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7356 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7359 TCGv_i32 t0
= tcg_temp_new_i32();
7360 int l1
= gen_new_label();
7367 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7368 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7369 gen_load_fpr32(t0
, fs
);
7370 gen_store_fpr32(t0
, fd
);
7372 tcg_temp_free_i32(t0
);
7375 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7378 TCGv_i32 t0
= tcg_temp_new_i32();
7380 int l1
= gen_new_label();
7387 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7388 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7389 tcg_temp_free_i32(t0
);
7390 fp0
= tcg_temp_new_i64();
7391 gen_load_fpr64(ctx
, fp0
, fs
);
7392 gen_store_fpr64(ctx
, fp0
, fd
);
7393 tcg_temp_free_i64(fp0
);
7397 static inline void gen_movcf_ps (int fs
, int fd
, int cc
, int tf
)
7400 TCGv_i32 t0
= tcg_temp_new_i32();
7401 int l1
= gen_new_label();
7402 int l2
= gen_new_label();
7409 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7410 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7411 gen_load_fpr32(t0
, fs
);
7412 gen_store_fpr32(t0
, fd
);
7415 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7416 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7417 gen_load_fpr32h(t0
, fs
);
7418 gen_store_fpr32h(t0
, fd
);
7419 tcg_temp_free_i32(t0
);
7424 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7425 int ft
, int fs
, int fd
, int cc
)
7427 const char *opn
= "farith";
7428 const char *condnames
[] = {
7446 const char *condnames_abs
[] = {
7464 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7465 uint32_t func
= ctx
->opcode
& 0x3f;
7470 TCGv_i32 fp0
= tcg_temp_new_i32();
7471 TCGv_i32 fp1
= tcg_temp_new_i32();
7473 gen_load_fpr32(fp0
, fs
);
7474 gen_load_fpr32(fp1
, ft
);
7475 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7476 tcg_temp_free_i32(fp1
);
7477 gen_store_fpr32(fp0
, fd
);
7478 tcg_temp_free_i32(fp0
);
7485 TCGv_i32 fp0
= tcg_temp_new_i32();
7486 TCGv_i32 fp1
= tcg_temp_new_i32();
7488 gen_load_fpr32(fp0
, fs
);
7489 gen_load_fpr32(fp1
, ft
);
7490 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7491 tcg_temp_free_i32(fp1
);
7492 gen_store_fpr32(fp0
, fd
);
7493 tcg_temp_free_i32(fp0
);
7500 TCGv_i32 fp0
= tcg_temp_new_i32();
7501 TCGv_i32 fp1
= tcg_temp_new_i32();
7503 gen_load_fpr32(fp0
, fs
);
7504 gen_load_fpr32(fp1
, ft
);
7505 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7506 tcg_temp_free_i32(fp1
);
7507 gen_store_fpr32(fp0
, fd
);
7508 tcg_temp_free_i32(fp0
);
7515 TCGv_i32 fp0
= tcg_temp_new_i32();
7516 TCGv_i32 fp1
= tcg_temp_new_i32();
7518 gen_load_fpr32(fp0
, fs
);
7519 gen_load_fpr32(fp1
, ft
);
7520 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7521 tcg_temp_free_i32(fp1
);
7522 gen_store_fpr32(fp0
, fd
);
7523 tcg_temp_free_i32(fp0
);
7530 TCGv_i32 fp0
= tcg_temp_new_i32();
7532 gen_load_fpr32(fp0
, fs
);
7533 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7534 gen_store_fpr32(fp0
, fd
);
7535 tcg_temp_free_i32(fp0
);
7541 TCGv_i32 fp0
= tcg_temp_new_i32();
7543 gen_load_fpr32(fp0
, fs
);
7544 gen_helper_float_abs_s(fp0
, fp0
);
7545 gen_store_fpr32(fp0
, fd
);
7546 tcg_temp_free_i32(fp0
);
7552 TCGv_i32 fp0
= tcg_temp_new_i32();
7554 gen_load_fpr32(fp0
, fs
);
7555 gen_store_fpr32(fp0
, fd
);
7556 tcg_temp_free_i32(fp0
);
7562 TCGv_i32 fp0
= tcg_temp_new_i32();
7564 gen_load_fpr32(fp0
, fs
);
7565 gen_helper_float_chs_s(fp0
, fp0
);
7566 gen_store_fpr32(fp0
, fd
);
7567 tcg_temp_free_i32(fp0
);
7572 check_cp1_64bitmode(ctx
);
7574 TCGv_i32 fp32
= tcg_temp_new_i32();
7575 TCGv_i64 fp64
= tcg_temp_new_i64();
7577 gen_load_fpr32(fp32
, fs
);
7578 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7579 tcg_temp_free_i32(fp32
);
7580 gen_store_fpr64(ctx
, fp64
, fd
);
7581 tcg_temp_free_i64(fp64
);
7586 check_cp1_64bitmode(ctx
);
7588 TCGv_i32 fp32
= tcg_temp_new_i32();
7589 TCGv_i64 fp64
= tcg_temp_new_i64();
7591 gen_load_fpr32(fp32
, fs
);
7592 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7593 tcg_temp_free_i32(fp32
);
7594 gen_store_fpr64(ctx
, fp64
, fd
);
7595 tcg_temp_free_i64(fp64
);
7600 check_cp1_64bitmode(ctx
);
7602 TCGv_i32 fp32
= tcg_temp_new_i32();
7603 TCGv_i64 fp64
= tcg_temp_new_i64();
7605 gen_load_fpr32(fp32
, fs
);
7606 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7607 tcg_temp_free_i32(fp32
);
7608 gen_store_fpr64(ctx
, fp64
, fd
);
7609 tcg_temp_free_i64(fp64
);
7614 check_cp1_64bitmode(ctx
);
7616 TCGv_i32 fp32
= tcg_temp_new_i32();
7617 TCGv_i64 fp64
= tcg_temp_new_i64();
7619 gen_load_fpr32(fp32
, fs
);
7620 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7621 tcg_temp_free_i32(fp32
);
7622 gen_store_fpr64(ctx
, fp64
, fd
);
7623 tcg_temp_free_i64(fp64
);
7629 TCGv_i32 fp0
= tcg_temp_new_i32();
7631 gen_load_fpr32(fp0
, fs
);
7632 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7633 gen_store_fpr32(fp0
, fd
);
7634 tcg_temp_free_i32(fp0
);
7640 TCGv_i32 fp0
= tcg_temp_new_i32();
7642 gen_load_fpr32(fp0
, fs
);
7643 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7644 gen_store_fpr32(fp0
, fd
);
7645 tcg_temp_free_i32(fp0
);
7651 TCGv_i32 fp0
= tcg_temp_new_i32();
7653 gen_load_fpr32(fp0
, fs
);
7654 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7655 gen_store_fpr32(fp0
, fd
);
7656 tcg_temp_free_i32(fp0
);
7662 TCGv_i32 fp0
= tcg_temp_new_i32();
7664 gen_load_fpr32(fp0
, fs
);
7665 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7666 gen_store_fpr32(fp0
, fd
);
7667 tcg_temp_free_i32(fp0
);
7672 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7677 int l1
= gen_new_label();
7681 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7683 fp0
= tcg_temp_new_i32();
7684 gen_load_fpr32(fp0
, fs
);
7685 gen_store_fpr32(fp0
, fd
);
7686 tcg_temp_free_i32(fp0
);
7693 int l1
= gen_new_label();
7697 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7698 fp0
= tcg_temp_new_i32();
7699 gen_load_fpr32(fp0
, fs
);
7700 gen_store_fpr32(fp0
, fd
);
7701 tcg_temp_free_i32(fp0
);
7710 TCGv_i32 fp0
= tcg_temp_new_i32();
7712 gen_load_fpr32(fp0
, fs
);
7713 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7714 gen_store_fpr32(fp0
, fd
);
7715 tcg_temp_free_i32(fp0
);
7722 TCGv_i32 fp0
= tcg_temp_new_i32();
7724 gen_load_fpr32(fp0
, fs
);
7725 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7726 gen_store_fpr32(fp0
, fd
);
7727 tcg_temp_free_i32(fp0
);
7732 check_cp1_64bitmode(ctx
);
7734 TCGv_i32 fp0
= tcg_temp_new_i32();
7735 TCGv_i32 fp1
= tcg_temp_new_i32();
7737 gen_load_fpr32(fp0
, fs
);
7738 gen_load_fpr32(fp1
, ft
);
7739 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7740 tcg_temp_free_i32(fp1
);
7741 gen_store_fpr32(fp0
, fd
);
7742 tcg_temp_free_i32(fp0
);
7747 check_cp1_64bitmode(ctx
);
7749 TCGv_i32 fp0
= tcg_temp_new_i32();
7751 gen_load_fpr32(fp0
, fs
);
7752 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7753 gen_store_fpr32(fp0
, fd
);
7754 tcg_temp_free_i32(fp0
);
7759 check_cp1_64bitmode(ctx
);
7761 TCGv_i32 fp0
= tcg_temp_new_i32();
7763 gen_load_fpr32(fp0
, fs
);
7764 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7765 gen_store_fpr32(fp0
, fd
);
7766 tcg_temp_free_i32(fp0
);
7771 check_cp1_64bitmode(ctx
);
7773 TCGv_i32 fp0
= tcg_temp_new_i32();
7774 TCGv_i32 fp1
= tcg_temp_new_i32();
7776 gen_load_fpr32(fp0
, fs
);
7777 gen_load_fpr32(fp1
, ft
);
7778 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7779 tcg_temp_free_i32(fp1
);
7780 gen_store_fpr32(fp0
, fd
);
7781 tcg_temp_free_i32(fp0
);
7786 check_cp1_registers(ctx
, fd
);
7788 TCGv_i32 fp32
= tcg_temp_new_i32();
7789 TCGv_i64 fp64
= tcg_temp_new_i64();
7791 gen_load_fpr32(fp32
, fs
);
7792 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7793 tcg_temp_free_i32(fp32
);
7794 gen_store_fpr64(ctx
, fp64
, fd
);
7795 tcg_temp_free_i64(fp64
);
7801 TCGv_i32 fp0
= tcg_temp_new_i32();
7803 gen_load_fpr32(fp0
, fs
);
7804 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7805 gen_store_fpr32(fp0
, fd
);
7806 tcg_temp_free_i32(fp0
);
7811 check_cp1_64bitmode(ctx
);
7813 TCGv_i32 fp32
= tcg_temp_new_i32();
7814 TCGv_i64 fp64
= tcg_temp_new_i64();
7816 gen_load_fpr32(fp32
, fs
);
7817 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7818 tcg_temp_free_i32(fp32
);
7819 gen_store_fpr64(ctx
, fp64
, fd
);
7820 tcg_temp_free_i64(fp64
);
7825 check_cp1_64bitmode(ctx
);
7827 TCGv_i64 fp64
= tcg_temp_new_i64();
7828 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7829 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7831 gen_load_fpr32(fp32_0
, fs
);
7832 gen_load_fpr32(fp32_1
, ft
);
7833 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7834 tcg_temp_free_i32(fp32_1
);
7835 tcg_temp_free_i32(fp32_0
);
7836 gen_store_fpr64(ctx
, fp64
, fd
);
7837 tcg_temp_free_i64(fp64
);
7850 case OPC_CMP_NGLE_S
:
7857 if (ctx
->opcode
& (1 << 6)) {
7858 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7859 opn
= condnames_abs
[func
-48];
7861 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7862 opn
= condnames
[func
-48];
7866 check_cp1_registers(ctx
, fs
| ft
| fd
);
7868 TCGv_i64 fp0
= tcg_temp_new_i64();
7869 TCGv_i64 fp1
= tcg_temp_new_i64();
7871 gen_load_fpr64(ctx
, fp0
, fs
);
7872 gen_load_fpr64(ctx
, fp1
, ft
);
7873 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7874 tcg_temp_free_i64(fp1
);
7875 gen_store_fpr64(ctx
, fp0
, fd
);
7876 tcg_temp_free_i64(fp0
);
7882 check_cp1_registers(ctx
, fs
| ft
| fd
);
7884 TCGv_i64 fp0
= tcg_temp_new_i64();
7885 TCGv_i64 fp1
= tcg_temp_new_i64();
7887 gen_load_fpr64(ctx
, fp0
, fs
);
7888 gen_load_fpr64(ctx
, fp1
, ft
);
7889 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7890 tcg_temp_free_i64(fp1
);
7891 gen_store_fpr64(ctx
, fp0
, fd
);
7892 tcg_temp_free_i64(fp0
);
7898 check_cp1_registers(ctx
, fs
| ft
| fd
);
7900 TCGv_i64 fp0
= tcg_temp_new_i64();
7901 TCGv_i64 fp1
= tcg_temp_new_i64();
7903 gen_load_fpr64(ctx
, fp0
, fs
);
7904 gen_load_fpr64(ctx
, fp1
, ft
);
7905 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7906 tcg_temp_free_i64(fp1
);
7907 gen_store_fpr64(ctx
, fp0
, fd
);
7908 tcg_temp_free_i64(fp0
);
7914 check_cp1_registers(ctx
, fs
| ft
| fd
);
7916 TCGv_i64 fp0
= tcg_temp_new_i64();
7917 TCGv_i64 fp1
= tcg_temp_new_i64();
7919 gen_load_fpr64(ctx
, fp0
, fs
);
7920 gen_load_fpr64(ctx
, fp1
, ft
);
7921 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7922 tcg_temp_free_i64(fp1
);
7923 gen_store_fpr64(ctx
, fp0
, fd
);
7924 tcg_temp_free_i64(fp0
);
7930 check_cp1_registers(ctx
, fs
| fd
);
7932 TCGv_i64 fp0
= tcg_temp_new_i64();
7934 gen_load_fpr64(ctx
, fp0
, fs
);
7935 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7936 gen_store_fpr64(ctx
, fp0
, fd
);
7937 tcg_temp_free_i64(fp0
);
7942 check_cp1_registers(ctx
, fs
| fd
);
7944 TCGv_i64 fp0
= tcg_temp_new_i64();
7946 gen_load_fpr64(ctx
, fp0
, fs
);
7947 gen_helper_float_abs_d(fp0
, fp0
);
7948 gen_store_fpr64(ctx
, fp0
, fd
);
7949 tcg_temp_free_i64(fp0
);
7954 check_cp1_registers(ctx
, fs
| fd
);
7956 TCGv_i64 fp0
= tcg_temp_new_i64();
7958 gen_load_fpr64(ctx
, fp0
, fs
);
7959 gen_store_fpr64(ctx
, fp0
, fd
);
7960 tcg_temp_free_i64(fp0
);
7965 check_cp1_registers(ctx
, fs
| fd
);
7967 TCGv_i64 fp0
= tcg_temp_new_i64();
7969 gen_load_fpr64(ctx
, fp0
, fs
);
7970 gen_helper_float_chs_d(fp0
, fp0
);
7971 gen_store_fpr64(ctx
, fp0
, fd
);
7972 tcg_temp_free_i64(fp0
);
7977 check_cp1_64bitmode(ctx
);
7979 TCGv_i64 fp0
= tcg_temp_new_i64();
7981 gen_load_fpr64(ctx
, fp0
, fs
);
7982 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
7983 gen_store_fpr64(ctx
, fp0
, fd
);
7984 tcg_temp_free_i64(fp0
);
7989 check_cp1_64bitmode(ctx
);
7991 TCGv_i64 fp0
= tcg_temp_new_i64();
7993 gen_load_fpr64(ctx
, fp0
, fs
);
7994 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
7995 gen_store_fpr64(ctx
, fp0
, fd
);
7996 tcg_temp_free_i64(fp0
);
8001 check_cp1_64bitmode(ctx
);
8003 TCGv_i64 fp0
= tcg_temp_new_i64();
8005 gen_load_fpr64(ctx
, fp0
, fs
);
8006 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
8007 gen_store_fpr64(ctx
, fp0
, fd
);
8008 tcg_temp_free_i64(fp0
);
8013 check_cp1_64bitmode(ctx
);
8015 TCGv_i64 fp0
= tcg_temp_new_i64();
8017 gen_load_fpr64(ctx
, fp0
, fs
);
8018 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8019 gen_store_fpr64(ctx
, fp0
, fd
);
8020 tcg_temp_free_i64(fp0
);
8025 check_cp1_registers(ctx
, fs
);
8027 TCGv_i32 fp32
= tcg_temp_new_i32();
8028 TCGv_i64 fp64
= tcg_temp_new_i64();
8030 gen_load_fpr64(ctx
, fp64
, fs
);
8031 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8032 tcg_temp_free_i64(fp64
);
8033 gen_store_fpr32(fp32
, fd
);
8034 tcg_temp_free_i32(fp32
);
8039 check_cp1_registers(ctx
, fs
);
8041 TCGv_i32 fp32
= tcg_temp_new_i32();
8042 TCGv_i64 fp64
= tcg_temp_new_i64();
8044 gen_load_fpr64(ctx
, fp64
, fs
);
8045 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8046 tcg_temp_free_i64(fp64
);
8047 gen_store_fpr32(fp32
, fd
);
8048 tcg_temp_free_i32(fp32
);
8053 check_cp1_registers(ctx
, fs
);
8055 TCGv_i32 fp32
= tcg_temp_new_i32();
8056 TCGv_i64 fp64
= tcg_temp_new_i64();
8058 gen_load_fpr64(ctx
, fp64
, fs
);
8059 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8060 tcg_temp_free_i64(fp64
);
8061 gen_store_fpr32(fp32
, fd
);
8062 tcg_temp_free_i32(fp32
);
8067 check_cp1_registers(ctx
, fs
);
8069 TCGv_i32 fp32
= tcg_temp_new_i32();
8070 TCGv_i64 fp64
= tcg_temp_new_i64();
8072 gen_load_fpr64(ctx
, fp64
, fs
);
8073 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8074 tcg_temp_free_i64(fp64
);
8075 gen_store_fpr32(fp32
, fd
);
8076 tcg_temp_free_i32(fp32
);
8081 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8086 int l1
= gen_new_label();
8090 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8092 fp0
= tcg_temp_new_i64();
8093 gen_load_fpr64(ctx
, fp0
, fs
);
8094 gen_store_fpr64(ctx
, fp0
, fd
);
8095 tcg_temp_free_i64(fp0
);
8102 int l1
= gen_new_label();
8106 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8107 fp0
= tcg_temp_new_i64();
8108 gen_load_fpr64(ctx
, fp0
, fs
);
8109 gen_store_fpr64(ctx
, fp0
, fd
);
8110 tcg_temp_free_i64(fp0
);
8117 check_cp1_64bitmode(ctx
);
8119 TCGv_i64 fp0
= tcg_temp_new_i64();
8121 gen_load_fpr64(ctx
, fp0
, fs
);
8122 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8123 gen_store_fpr64(ctx
, fp0
, fd
);
8124 tcg_temp_free_i64(fp0
);
8129 check_cp1_64bitmode(ctx
);
8131 TCGv_i64 fp0
= tcg_temp_new_i64();
8133 gen_load_fpr64(ctx
, fp0
, fs
);
8134 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8135 gen_store_fpr64(ctx
, fp0
, fd
);
8136 tcg_temp_free_i64(fp0
);
8141 check_cp1_64bitmode(ctx
);
8143 TCGv_i64 fp0
= tcg_temp_new_i64();
8144 TCGv_i64 fp1
= tcg_temp_new_i64();
8146 gen_load_fpr64(ctx
, fp0
, fs
);
8147 gen_load_fpr64(ctx
, fp1
, ft
);
8148 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8149 tcg_temp_free_i64(fp1
);
8150 gen_store_fpr64(ctx
, fp0
, fd
);
8151 tcg_temp_free_i64(fp0
);
8156 check_cp1_64bitmode(ctx
);
8158 TCGv_i64 fp0
= tcg_temp_new_i64();
8160 gen_load_fpr64(ctx
, fp0
, fs
);
8161 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8162 gen_store_fpr64(ctx
, fp0
, fd
);
8163 tcg_temp_free_i64(fp0
);
8168 check_cp1_64bitmode(ctx
);
8170 TCGv_i64 fp0
= tcg_temp_new_i64();
8172 gen_load_fpr64(ctx
, fp0
, fs
);
8173 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8174 gen_store_fpr64(ctx
, fp0
, fd
);
8175 tcg_temp_free_i64(fp0
);
8180 check_cp1_64bitmode(ctx
);
8182 TCGv_i64 fp0
= tcg_temp_new_i64();
8183 TCGv_i64 fp1
= tcg_temp_new_i64();
8185 gen_load_fpr64(ctx
, fp0
, fs
);
8186 gen_load_fpr64(ctx
, fp1
, ft
);
8187 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8188 tcg_temp_free_i64(fp1
);
8189 gen_store_fpr64(ctx
, fp0
, fd
);
8190 tcg_temp_free_i64(fp0
);
8203 case OPC_CMP_NGLE_D
:
8210 if (ctx
->opcode
& (1 << 6)) {
8211 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8212 opn
= condnames_abs
[func
-48];
8214 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8215 opn
= condnames
[func
-48];
8219 check_cp1_registers(ctx
, fs
);
8221 TCGv_i32 fp32
= tcg_temp_new_i32();
8222 TCGv_i64 fp64
= tcg_temp_new_i64();
8224 gen_load_fpr64(ctx
, fp64
, fs
);
8225 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8226 tcg_temp_free_i64(fp64
);
8227 gen_store_fpr32(fp32
, fd
);
8228 tcg_temp_free_i32(fp32
);
8233 check_cp1_registers(ctx
, fs
);
8235 TCGv_i32 fp32
= tcg_temp_new_i32();
8236 TCGv_i64 fp64
= tcg_temp_new_i64();
8238 gen_load_fpr64(ctx
, fp64
, fs
);
8239 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8240 tcg_temp_free_i64(fp64
);
8241 gen_store_fpr32(fp32
, fd
);
8242 tcg_temp_free_i32(fp32
);
8247 check_cp1_64bitmode(ctx
);
8249 TCGv_i64 fp0
= tcg_temp_new_i64();
8251 gen_load_fpr64(ctx
, fp0
, fs
);
8252 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8253 gen_store_fpr64(ctx
, fp0
, fd
);
8254 tcg_temp_free_i64(fp0
);
8260 TCGv_i32 fp0
= tcg_temp_new_i32();
8262 gen_load_fpr32(fp0
, fs
);
8263 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8264 gen_store_fpr32(fp0
, fd
);
8265 tcg_temp_free_i32(fp0
);
8270 check_cp1_registers(ctx
, fd
);
8272 TCGv_i32 fp32
= tcg_temp_new_i32();
8273 TCGv_i64 fp64
= tcg_temp_new_i64();
8275 gen_load_fpr32(fp32
, fs
);
8276 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8277 tcg_temp_free_i32(fp32
);
8278 gen_store_fpr64(ctx
, fp64
, fd
);
8279 tcg_temp_free_i64(fp64
);
8284 check_cp1_64bitmode(ctx
);
8286 TCGv_i32 fp32
= tcg_temp_new_i32();
8287 TCGv_i64 fp64
= tcg_temp_new_i64();
8289 gen_load_fpr64(ctx
, fp64
, fs
);
8290 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8291 tcg_temp_free_i64(fp64
);
8292 gen_store_fpr32(fp32
, fd
);
8293 tcg_temp_free_i32(fp32
);
8298 check_cp1_64bitmode(ctx
);
8300 TCGv_i64 fp0
= tcg_temp_new_i64();
8302 gen_load_fpr64(ctx
, fp0
, fs
);
8303 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8304 gen_store_fpr64(ctx
, fp0
, fd
);
8305 tcg_temp_free_i64(fp0
);
8310 check_cp1_64bitmode(ctx
);
8312 TCGv_i64 fp0
= tcg_temp_new_i64();
8314 gen_load_fpr64(ctx
, fp0
, fs
);
8315 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8316 gen_store_fpr64(ctx
, fp0
, fd
);
8317 tcg_temp_free_i64(fp0
);
8322 check_cp1_64bitmode(ctx
);
8324 TCGv_i64 fp0
= tcg_temp_new_i64();
8325 TCGv_i64 fp1
= tcg_temp_new_i64();
8327 gen_load_fpr64(ctx
, fp0
, fs
);
8328 gen_load_fpr64(ctx
, fp1
, ft
);
8329 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8330 tcg_temp_free_i64(fp1
);
8331 gen_store_fpr64(ctx
, fp0
, fd
);
8332 tcg_temp_free_i64(fp0
);
8337 check_cp1_64bitmode(ctx
);
8339 TCGv_i64 fp0
= tcg_temp_new_i64();
8340 TCGv_i64 fp1
= tcg_temp_new_i64();
8342 gen_load_fpr64(ctx
, fp0
, fs
);
8343 gen_load_fpr64(ctx
, fp1
, ft
);
8344 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8345 tcg_temp_free_i64(fp1
);
8346 gen_store_fpr64(ctx
, fp0
, fd
);
8347 tcg_temp_free_i64(fp0
);
8352 check_cp1_64bitmode(ctx
);
8354 TCGv_i64 fp0
= tcg_temp_new_i64();
8355 TCGv_i64 fp1
= tcg_temp_new_i64();
8357 gen_load_fpr64(ctx
, fp0
, fs
);
8358 gen_load_fpr64(ctx
, fp1
, ft
);
8359 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8360 tcg_temp_free_i64(fp1
);
8361 gen_store_fpr64(ctx
, fp0
, fd
);
8362 tcg_temp_free_i64(fp0
);
8367 check_cp1_64bitmode(ctx
);
8369 TCGv_i64 fp0
= tcg_temp_new_i64();
8371 gen_load_fpr64(ctx
, fp0
, fs
);
8372 gen_helper_float_abs_ps(fp0
, fp0
);
8373 gen_store_fpr64(ctx
, fp0
, fd
);
8374 tcg_temp_free_i64(fp0
);
8379 check_cp1_64bitmode(ctx
);
8381 TCGv_i64 fp0
= tcg_temp_new_i64();
8383 gen_load_fpr64(ctx
, fp0
, fs
);
8384 gen_store_fpr64(ctx
, fp0
, fd
);
8385 tcg_temp_free_i64(fp0
);
8390 check_cp1_64bitmode(ctx
);
8392 TCGv_i64 fp0
= tcg_temp_new_i64();
8394 gen_load_fpr64(ctx
, fp0
, fs
);
8395 gen_helper_float_chs_ps(fp0
, fp0
);
8396 gen_store_fpr64(ctx
, fp0
, fd
);
8397 tcg_temp_free_i64(fp0
);
8402 check_cp1_64bitmode(ctx
);
8403 gen_movcf_ps(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8407 check_cp1_64bitmode(ctx
);
8409 int l1
= gen_new_label();
8413 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8414 fp0
= tcg_temp_new_i64();
8415 gen_load_fpr64(ctx
, fp0
, fs
);
8416 gen_store_fpr64(ctx
, fp0
, fd
);
8417 tcg_temp_free_i64(fp0
);
8423 check_cp1_64bitmode(ctx
);
8425 int l1
= gen_new_label();
8429 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8430 fp0
= tcg_temp_new_i64();
8431 gen_load_fpr64(ctx
, fp0
, fs
);
8432 gen_store_fpr64(ctx
, fp0
, fd
);
8433 tcg_temp_free_i64(fp0
);
8440 check_cp1_64bitmode(ctx
);
8442 TCGv_i64 fp0
= tcg_temp_new_i64();
8443 TCGv_i64 fp1
= tcg_temp_new_i64();
8445 gen_load_fpr64(ctx
, fp0
, ft
);
8446 gen_load_fpr64(ctx
, fp1
, fs
);
8447 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8448 tcg_temp_free_i64(fp1
);
8449 gen_store_fpr64(ctx
, fp0
, fd
);
8450 tcg_temp_free_i64(fp0
);
8455 check_cp1_64bitmode(ctx
);
8457 TCGv_i64 fp0
= tcg_temp_new_i64();
8458 TCGv_i64 fp1
= tcg_temp_new_i64();
8460 gen_load_fpr64(ctx
, fp0
, ft
);
8461 gen_load_fpr64(ctx
, fp1
, fs
);
8462 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8463 tcg_temp_free_i64(fp1
);
8464 gen_store_fpr64(ctx
, fp0
, fd
);
8465 tcg_temp_free_i64(fp0
);
8470 check_cp1_64bitmode(ctx
);
8472 TCGv_i64 fp0
= tcg_temp_new_i64();
8473 TCGv_i64 fp1
= tcg_temp_new_i64();
8475 gen_load_fpr64(ctx
, fp0
, fs
);
8476 gen_load_fpr64(ctx
, fp1
, ft
);
8477 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8478 tcg_temp_free_i64(fp1
);
8479 gen_store_fpr64(ctx
, fp0
, fd
);
8480 tcg_temp_free_i64(fp0
);
8485 check_cp1_64bitmode(ctx
);
8487 TCGv_i64 fp0
= tcg_temp_new_i64();
8489 gen_load_fpr64(ctx
, fp0
, fs
);
8490 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
8491 gen_store_fpr64(ctx
, fp0
, fd
);
8492 tcg_temp_free_i64(fp0
);
8497 check_cp1_64bitmode(ctx
);
8499 TCGv_i64 fp0
= tcg_temp_new_i64();
8501 gen_load_fpr64(ctx
, fp0
, fs
);
8502 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8503 gen_store_fpr64(ctx
, fp0
, fd
);
8504 tcg_temp_free_i64(fp0
);
8509 check_cp1_64bitmode(ctx
);
8511 TCGv_i64 fp0
= tcg_temp_new_i64();
8512 TCGv_i64 fp1
= tcg_temp_new_i64();
8514 gen_load_fpr64(ctx
, fp0
, fs
);
8515 gen_load_fpr64(ctx
, fp1
, ft
);
8516 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8517 tcg_temp_free_i64(fp1
);
8518 gen_store_fpr64(ctx
, fp0
, fd
);
8519 tcg_temp_free_i64(fp0
);
8524 check_cp1_64bitmode(ctx
);
8526 TCGv_i32 fp0
= tcg_temp_new_i32();
8528 gen_load_fpr32h(fp0
, fs
);
8529 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8530 gen_store_fpr32(fp0
, fd
);
8531 tcg_temp_free_i32(fp0
);
8536 check_cp1_64bitmode(ctx
);
8538 TCGv_i64 fp0
= tcg_temp_new_i64();
8540 gen_load_fpr64(ctx
, fp0
, fs
);
8541 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8542 gen_store_fpr64(ctx
, fp0
, fd
);
8543 tcg_temp_free_i64(fp0
);
8548 check_cp1_64bitmode(ctx
);
8550 TCGv_i32 fp0
= tcg_temp_new_i32();
8552 gen_load_fpr32(fp0
, fs
);
8553 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8554 gen_store_fpr32(fp0
, fd
);
8555 tcg_temp_free_i32(fp0
);
8560 check_cp1_64bitmode(ctx
);
8562 TCGv_i32 fp0
= tcg_temp_new_i32();
8563 TCGv_i32 fp1
= tcg_temp_new_i32();
8565 gen_load_fpr32(fp0
, fs
);
8566 gen_load_fpr32(fp1
, ft
);
8567 gen_store_fpr32h(fp0
, fd
);
8568 gen_store_fpr32(fp1
, fd
);
8569 tcg_temp_free_i32(fp0
);
8570 tcg_temp_free_i32(fp1
);
8575 check_cp1_64bitmode(ctx
);
8577 TCGv_i32 fp0
= tcg_temp_new_i32();
8578 TCGv_i32 fp1
= tcg_temp_new_i32();
8580 gen_load_fpr32(fp0
, fs
);
8581 gen_load_fpr32h(fp1
, ft
);
8582 gen_store_fpr32(fp1
, fd
);
8583 gen_store_fpr32h(fp0
, fd
);
8584 tcg_temp_free_i32(fp0
);
8585 tcg_temp_free_i32(fp1
);
8590 check_cp1_64bitmode(ctx
);
8592 TCGv_i32 fp0
= tcg_temp_new_i32();
8593 TCGv_i32 fp1
= tcg_temp_new_i32();
8595 gen_load_fpr32h(fp0
, fs
);
8596 gen_load_fpr32(fp1
, ft
);
8597 gen_store_fpr32(fp1
, fd
);
8598 gen_store_fpr32h(fp0
, fd
);
8599 tcg_temp_free_i32(fp0
);
8600 tcg_temp_free_i32(fp1
);
8605 check_cp1_64bitmode(ctx
);
8607 TCGv_i32 fp0
= tcg_temp_new_i32();
8608 TCGv_i32 fp1
= tcg_temp_new_i32();
8610 gen_load_fpr32h(fp0
, fs
);
8611 gen_load_fpr32h(fp1
, ft
);
8612 gen_store_fpr32(fp1
, fd
);
8613 gen_store_fpr32h(fp0
, fd
);
8614 tcg_temp_free_i32(fp0
);
8615 tcg_temp_free_i32(fp1
);
8622 case OPC_CMP_UEQ_PS
:
8623 case OPC_CMP_OLT_PS
:
8624 case OPC_CMP_ULT_PS
:
8625 case OPC_CMP_OLE_PS
:
8626 case OPC_CMP_ULE_PS
:
8628 case OPC_CMP_NGLE_PS
:
8629 case OPC_CMP_SEQ_PS
:
8630 case OPC_CMP_NGL_PS
:
8632 case OPC_CMP_NGE_PS
:
8634 case OPC_CMP_NGT_PS
:
8635 if (ctx
->opcode
& (1 << 6)) {
8636 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8637 opn
= condnames_abs
[func
-48];
8639 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8640 opn
= condnames
[func
-48];
8645 generate_exception (ctx
, EXCP_RI
);
8648 (void)opn
; /* avoid a compiler warning */
8651 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8654 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8657 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8662 /* Coprocessor 3 (FPU) */
8663 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8664 int fd
, int fs
, int base
, int index
)
8666 const char *opn
= "extended float load/store";
8668 TCGv t0
= tcg_temp_new();
8671 gen_load_gpr(t0
, index
);
8672 } else if (index
== 0) {
8673 gen_load_gpr(t0
, base
);
8675 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8677 /* Don't do NOP if destination is zero: we must perform the actual
8683 TCGv_i32 fp0
= tcg_temp_new_i32();
8685 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
8686 tcg_gen_trunc_tl_i32(fp0
, t0
);
8687 gen_store_fpr32(fp0
, fd
);
8688 tcg_temp_free_i32(fp0
);
8694 check_cp1_registers(ctx
, fd
);
8696 TCGv_i64 fp0
= tcg_temp_new_i64();
8698 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8699 gen_store_fpr64(ctx
, fp0
, fd
);
8700 tcg_temp_free_i64(fp0
);
8705 check_cp1_64bitmode(ctx
);
8706 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8708 TCGv_i64 fp0
= tcg_temp_new_i64();
8710 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8711 gen_store_fpr64(ctx
, fp0
, fd
);
8712 tcg_temp_free_i64(fp0
);
8719 TCGv_i32 fp0
= tcg_temp_new_i32();
8720 TCGv t1
= tcg_temp_new();
8722 gen_load_fpr32(fp0
, fs
);
8723 tcg_gen_extu_i32_tl(t1
, fp0
);
8724 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
8725 tcg_temp_free_i32(fp0
);
8733 check_cp1_registers(ctx
, fs
);
8735 TCGv_i64 fp0
= tcg_temp_new_i64();
8737 gen_load_fpr64(ctx
, fp0
, fs
);
8738 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8739 tcg_temp_free_i64(fp0
);
8745 check_cp1_64bitmode(ctx
);
8746 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8748 TCGv_i64 fp0
= tcg_temp_new_i64();
8750 gen_load_fpr64(ctx
, fp0
, fs
);
8751 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8752 tcg_temp_free_i64(fp0
);
8759 (void)opn
; (void)store
; /* avoid compiler warnings */
8760 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8761 regnames
[index
], regnames
[base
]);
8764 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8765 int fd
, int fr
, int fs
, int ft
)
8767 const char *opn
= "flt3_arith";
8771 check_cp1_64bitmode(ctx
);
8773 TCGv t0
= tcg_temp_local_new();
8774 TCGv_i32 fp
= tcg_temp_new_i32();
8775 TCGv_i32 fph
= tcg_temp_new_i32();
8776 int l1
= gen_new_label();
8777 int l2
= gen_new_label();
8779 gen_load_gpr(t0
, fr
);
8780 tcg_gen_andi_tl(t0
, t0
, 0x7);
8782 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8783 gen_load_fpr32(fp
, fs
);
8784 gen_load_fpr32h(fph
, fs
);
8785 gen_store_fpr32(fp
, fd
);
8786 gen_store_fpr32h(fph
, fd
);
8789 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8791 #ifdef TARGET_WORDS_BIGENDIAN
8792 gen_load_fpr32(fp
, fs
);
8793 gen_load_fpr32h(fph
, ft
);
8794 gen_store_fpr32h(fp
, fd
);
8795 gen_store_fpr32(fph
, fd
);
8797 gen_load_fpr32h(fph
, fs
);
8798 gen_load_fpr32(fp
, ft
);
8799 gen_store_fpr32(fph
, fd
);
8800 gen_store_fpr32h(fp
, fd
);
8803 tcg_temp_free_i32(fp
);
8804 tcg_temp_free_i32(fph
);
8811 TCGv_i32 fp0
= tcg_temp_new_i32();
8812 TCGv_i32 fp1
= tcg_temp_new_i32();
8813 TCGv_i32 fp2
= tcg_temp_new_i32();
8815 gen_load_fpr32(fp0
, fs
);
8816 gen_load_fpr32(fp1
, ft
);
8817 gen_load_fpr32(fp2
, fr
);
8818 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8819 tcg_temp_free_i32(fp0
);
8820 tcg_temp_free_i32(fp1
);
8821 gen_store_fpr32(fp2
, fd
);
8822 tcg_temp_free_i32(fp2
);
8828 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8830 TCGv_i64 fp0
= tcg_temp_new_i64();
8831 TCGv_i64 fp1
= tcg_temp_new_i64();
8832 TCGv_i64 fp2
= tcg_temp_new_i64();
8834 gen_load_fpr64(ctx
, fp0
, fs
);
8835 gen_load_fpr64(ctx
, fp1
, ft
);
8836 gen_load_fpr64(ctx
, fp2
, fr
);
8837 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8838 tcg_temp_free_i64(fp0
);
8839 tcg_temp_free_i64(fp1
);
8840 gen_store_fpr64(ctx
, fp2
, fd
);
8841 tcg_temp_free_i64(fp2
);
8846 check_cp1_64bitmode(ctx
);
8848 TCGv_i64 fp0
= tcg_temp_new_i64();
8849 TCGv_i64 fp1
= tcg_temp_new_i64();
8850 TCGv_i64 fp2
= tcg_temp_new_i64();
8852 gen_load_fpr64(ctx
, fp0
, fs
);
8853 gen_load_fpr64(ctx
, fp1
, ft
);
8854 gen_load_fpr64(ctx
, fp2
, fr
);
8855 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8856 tcg_temp_free_i64(fp0
);
8857 tcg_temp_free_i64(fp1
);
8858 gen_store_fpr64(ctx
, fp2
, fd
);
8859 tcg_temp_free_i64(fp2
);
8866 TCGv_i32 fp0
= tcg_temp_new_i32();
8867 TCGv_i32 fp1
= tcg_temp_new_i32();
8868 TCGv_i32 fp2
= tcg_temp_new_i32();
8870 gen_load_fpr32(fp0
, fs
);
8871 gen_load_fpr32(fp1
, ft
);
8872 gen_load_fpr32(fp2
, fr
);
8873 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8874 tcg_temp_free_i32(fp0
);
8875 tcg_temp_free_i32(fp1
);
8876 gen_store_fpr32(fp2
, fd
);
8877 tcg_temp_free_i32(fp2
);
8883 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8885 TCGv_i64 fp0
= tcg_temp_new_i64();
8886 TCGv_i64 fp1
= tcg_temp_new_i64();
8887 TCGv_i64 fp2
= tcg_temp_new_i64();
8889 gen_load_fpr64(ctx
, fp0
, fs
);
8890 gen_load_fpr64(ctx
, fp1
, ft
);
8891 gen_load_fpr64(ctx
, fp2
, fr
);
8892 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8893 tcg_temp_free_i64(fp0
);
8894 tcg_temp_free_i64(fp1
);
8895 gen_store_fpr64(ctx
, fp2
, fd
);
8896 tcg_temp_free_i64(fp2
);
8901 check_cp1_64bitmode(ctx
);
8903 TCGv_i64 fp0
= tcg_temp_new_i64();
8904 TCGv_i64 fp1
= tcg_temp_new_i64();
8905 TCGv_i64 fp2
= tcg_temp_new_i64();
8907 gen_load_fpr64(ctx
, fp0
, fs
);
8908 gen_load_fpr64(ctx
, fp1
, ft
);
8909 gen_load_fpr64(ctx
, fp2
, fr
);
8910 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8911 tcg_temp_free_i64(fp0
);
8912 tcg_temp_free_i64(fp1
);
8913 gen_store_fpr64(ctx
, fp2
, fd
);
8914 tcg_temp_free_i64(fp2
);
8921 TCGv_i32 fp0
= tcg_temp_new_i32();
8922 TCGv_i32 fp1
= tcg_temp_new_i32();
8923 TCGv_i32 fp2
= tcg_temp_new_i32();
8925 gen_load_fpr32(fp0
, fs
);
8926 gen_load_fpr32(fp1
, ft
);
8927 gen_load_fpr32(fp2
, fr
);
8928 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8929 tcg_temp_free_i32(fp0
);
8930 tcg_temp_free_i32(fp1
);
8931 gen_store_fpr32(fp2
, fd
);
8932 tcg_temp_free_i32(fp2
);
8938 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8940 TCGv_i64 fp0
= tcg_temp_new_i64();
8941 TCGv_i64 fp1
= tcg_temp_new_i64();
8942 TCGv_i64 fp2
= tcg_temp_new_i64();
8944 gen_load_fpr64(ctx
, fp0
, fs
);
8945 gen_load_fpr64(ctx
, fp1
, ft
);
8946 gen_load_fpr64(ctx
, fp2
, fr
);
8947 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8948 tcg_temp_free_i64(fp0
);
8949 tcg_temp_free_i64(fp1
);
8950 gen_store_fpr64(ctx
, fp2
, fd
);
8951 tcg_temp_free_i64(fp2
);
8956 check_cp1_64bitmode(ctx
);
8958 TCGv_i64 fp0
= tcg_temp_new_i64();
8959 TCGv_i64 fp1
= tcg_temp_new_i64();
8960 TCGv_i64 fp2
= tcg_temp_new_i64();
8962 gen_load_fpr64(ctx
, fp0
, fs
);
8963 gen_load_fpr64(ctx
, fp1
, ft
);
8964 gen_load_fpr64(ctx
, fp2
, fr
);
8965 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8966 tcg_temp_free_i64(fp0
);
8967 tcg_temp_free_i64(fp1
);
8968 gen_store_fpr64(ctx
, fp2
, fd
);
8969 tcg_temp_free_i64(fp2
);
8976 TCGv_i32 fp0
= tcg_temp_new_i32();
8977 TCGv_i32 fp1
= tcg_temp_new_i32();
8978 TCGv_i32 fp2
= tcg_temp_new_i32();
8980 gen_load_fpr32(fp0
, fs
);
8981 gen_load_fpr32(fp1
, ft
);
8982 gen_load_fpr32(fp2
, fr
);
8983 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8984 tcg_temp_free_i32(fp0
);
8985 tcg_temp_free_i32(fp1
);
8986 gen_store_fpr32(fp2
, fd
);
8987 tcg_temp_free_i32(fp2
);
8993 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8995 TCGv_i64 fp0
= tcg_temp_new_i64();
8996 TCGv_i64 fp1
= tcg_temp_new_i64();
8997 TCGv_i64 fp2
= tcg_temp_new_i64();
8999 gen_load_fpr64(ctx
, fp0
, fs
);
9000 gen_load_fpr64(ctx
, fp1
, ft
);
9001 gen_load_fpr64(ctx
, fp2
, fr
);
9002 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9003 tcg_temp_free_i64(fp0
);
9004 tcg_temp_free_i64(fp1
);
9005 gen_store_fpr64(ctx
, fp2
, fd
);
9006 tcg_temp_free_i64(fp2
);
9011 check_cp1_64bitmode(ctx
);
9013 TCGv_i64 fp0
= tcg_temp_new_i64();
9014 TCGv_i64 fp1
= tcg_temp_new_i64();
9015 TCGv_i64 fp2
= tcg_temp_new_i64();
9017 gen_load_fpr64(ctx
, fp0
, fs
);
9018 gen_load_fpr64(ctx
, fp1
, ft
);
9019 gen_load_fpr64(ctx
, fp2
, fr
);
9020 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9021 tcg_temp_free_i64(fp0
);
9022 tcg_temp_free_i64(fp1
);
9023 gen_store_fpr64(ctx
, fp2
, fd
);
9024 tcg_temp_free_i64(fp2
);
9030 generate_exception (ctx
, EXCP_RI
);
9033 (void)opn
; /* avoid a compiler warning */
9034 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9035 fregnames
[fs
], fregnames
[ft
]);
9038 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
9042 #if !defined(CONFIG_USER_ONLY)
9043 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9044 Therefore only check the ISA in system mode. */
9045 check_insn(ctx
, ISA_MIPS32R2
);
9047 t0
= tcg_temp_new();
9051 save_cpu_state(ctx
, 1);
9052 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9053 gen_store_gpr(t0
, rt
);
9056 save_cpu_state(ctx
, 1);
9057 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9058 gen_store_gpr(t0
, rt
);
9061 save_cpu_state(ctx
, 1);
9062 gen_helper_rdhwr_cc(t0
, cpu_env
);
9063 gen_store_gpr(t0
, rt
);
9066 save_cpu_state(ctx
, 1);
9067 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9068 gen_store_gpr(t0
, rt
);
9071 #if defined(CONFIG_USER_ONLY)
9072 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUMIPSState
, tls_value
));
9073 gen_store_gpr(t0
, rt
);
9076 /* XXX: Some CPUs implement this in hardware.
9077 Not supported yet. */
9079 default: /* Invalid */
9080 MIPS_INVAL("rdhwr");
9081 generate_exception(ctx
, EXCP_RI
);
9087 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9089 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9090 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9091 /* Branches completion */
9092 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9093 ctx
->bstate
= BS_BRANCH
;
9094 save_cpu_state(ctx
, 0);
9095 /* FIXME: Need to clear can_do_io. */
9096 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9098 /* unconditional branch */
9099 MIPS_DEBUG("unconditional branch");
9100 if (proc_hflags
& MIPS_HFLAG_BX
) {
9101 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9103 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9106 /* blikely taken case */
9107 MIPS_DEBUG("blikely branch taken");
9108 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9111 /* Conditional branch */
9112 MIPS_DEBUG("conditional branch");
9114 int l1
= gen_new_label();
9116 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9117 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9119 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9123 /* unconditional branch to register */
9124 MIPS_DEBUG("branch to register");
9125 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9126 TCGv t0
= tcg_temp_new();
9127 TCGv_i32 t1
= tcg_temp_new_i32();
9129 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9130 tcg_gen_trunc_tl_i32(t1
, t0
);
9132 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9133 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9134 tcg_gen_or_i32(hflags
, hflags
, t1
);
9135 tcg_temp_free_i32(t1
);
9137 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9139 tcg_gen_mov_tl(cpu_PC
, btarget
);
9141 if (ctx
->singlestep_enabled
) {
9142 save_cpu_state(ctx
, 0);
9143 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9148 MIPS_DEBUG("unknown branch");
9154 /* ISA extensions (ASEs) */
9155 /* MIPS16 extension to MIPS32 */
9157 /* MIPS16 major opcodes */
9159 M16_OPC_ADDIUSP
= 0x00,
9160 M16_OPC_ADDIUPC
= 0x01,
9163 M16_OPC_BEQZ
= 0x04,
9164 M16_OPC_BNEQZ
= 0x05,
9165 M16_OPC_SHIFT
= 0x06,
9167 M16_OPC_RRIA
= 0x08,
9168 M16_OPC_ADDIU8
= 0x09,
9169 M16_OPC_SLTI
= 0x0a,
9170 M16_OPC_SLTIU
= 0x0b,
9173 M16_OPC_CMPI
= 0x0e,
9177 M16_OPC_LWSP
= 0x12,
9181 M16_OPC_LWPC
= 0x16,
9185 M16_OPC_SWSP
= 0x1a,
9189 M16_OPC_EXTEND
= 0x1e,
9193 /* I8 funct field */
9212 /* RR funct field */
9246 /* I64 funct field */
9258 /* RR ry field for CNVT */
9260 RR_RY_CNVT_ZEB
= 0x0,
9261 RR_RY_CNVT_ZEH
= 0x1,
9262 RR_RY_CNVT_ZEW
= 0x2,
9263 RR_RY_CNVT_SEB
= 0x4,
9264 RR_RY_CNVT_SEH
= 0x5,
9265 RR_RY_CNVT_SEW
= 0x6,
9268 static int xlat (int r
)
9270 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9275 static void gen_mips16_save (DisasContext
*ctx
,
9276 int xsregs
, int aregs
,
9277 int do_ra
, int do_s0
, int do_s1
,
9280 TCGv t0
= tcg_temp_new();
9281 TCGv t1
= tcg_temp_new();
9311 generate_exception(ctx
, EXCP_RI
);
9317 gen_base_offset_addr(ctx
, t0
, 29, 12);
9318 gen_load_gpr(t1
, 7);
9319 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9322 gen_base_offset_addr(ctx
, t0
, 29, 8);
9323 gen_load_gpr(t1
, 6);
9324 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9327 gen_base_offset_addr(ctx
, t0
, 29, 4);
9328 gen_load_gpr(t1
, 5);
9329 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9332 gen_base_offset_addr(ctx
, t0
, 29, 0);
9333 gen_load_gpr(t1
, 4);
9334 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9337 gen_load_gpr(t0
, 29);
9339 #define DECR_AND_STORE(reg) do { \
9340 tcg_gen_subi_tl(t0, t0, 4); \
9341 gen_load_gpr(t1, reg); \
9342 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9406 generate_exception(ctx
, EXCP_RI
);
9422 #undef DECR_AND_STORE
9424 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9429 static void gen_mips16_restore (DisasContext
*ctx
,
9430 int xsregs
, int aregs
,
9431 int do_ra
, int do_s0
, int do_s1
,
9435 TCGv t0
= tcg_temp_new();
9436 TCGv t1
= tcg_temp_new();
9438 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9440 #define DECR_AND_LOAD(reg) do { \
9441 tcg_gen_subi_tl(t0, t0, 4); \
9442 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
9443 gen_store_gpr(t1, reg); \
9507 generate_exception(ctx
, EXCP_RI
);
9523 #undef DECR_AND_LOAD
9525 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9530 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9531 int is_64_bit
, int extended
)
9535 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9536 generate_exception(ctx
, EXCP_RI
);
9540 t0
= tcg_temp_new();
9542 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9543 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9545 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9551 #if defined(TARGET_MIPS64)
9552 static void decode_i64_mips16 (DisasContext
*ctx
,
9553 int ry
, int funct
, int16_t offset
,
9559 offset
= extended
? offset
: offset
<< 3;
9560 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9564 offset
= extended
? offset
: offset
<< 3;
9565 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9569 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9570 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9574 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9575 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9578 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9579 generate_exception(ctx
, EXCP_RI
);
9581 offset
= extended
? offset
: offset
<< 3;
9582 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9587 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9588 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9592 offset
= extended
? offset
: offset
<< 2;
9593 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9597 offset
= extended
? offset
: offset
<< 2;
9598 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9604 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
9607 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9608 int op
, rx
, ry
, funct
, sa
;
9609 int16_t imm
, offset
;
9611 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9612 op
= (ctx
->opcode
>> 11) & 0x1f;
9613 sa
= (ctx
->opcode
>> 22) & 0x1f;
9614 funct
= (ctx
->opcode
>> 8) & 0x7;
9615 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9616 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9617 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9618 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9619 | (ctx
->opcode
& 0x1f));
9621 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9624 case M16_OPC_ADDIUSP
:
9625 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9627 case M16_OPC_ADDIUPC
:
9628 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9631 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9632 /* No delay slot, so just process as a normal instruction */
9635 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9636 /* No delay slot, so just process as a normal instruction */
9639 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9640 /* No delay slot, so just process as a normal instruction */
9643 switch (ctx
->opcode
& 0x3) {
9645 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9648 #if defined(TARGET_MIPS64)
9650 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9652 generate_exception(ctx
, EXCP_RI
);
9656 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9659 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9663 #if defined(TARGET_MIPS64)
9666 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9670 imm
= ctx
->opcode
& 0xf;
9671 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9672 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9673 imm
= (int16_t) (imm
<< 1) >> 1;
9674 if ((ctx
->opcode
>> 4) & 0x1) {
9675 #if defined(TARGET_MIPS64)
9677 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9679 generate_exception(ctx
, EXCP_RI
);
9682 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9685 case M16_OPC_ADDIU8
:
9686 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9689 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9692 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9697 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9700 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9703 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9706 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9710 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9711 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9712 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9713 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9714 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9715 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9716 | (ctx
->opcode
& 0xf)) << 3;
9718 if (ctx
->opcode
& (1 << 7)) {
9719 gen_mips16_save(ctx
, xsregs
, aregs
,
9720 do_ra
, do_s0
, do_s1
,
9723 gen_mips16_restore(ctx
, xsregs
, aregs
,
9724 do_ra
, do_s0
, do_s1
,
9730 generate_exception(ctx
, EXCP_RI
);
9735 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9738 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9740 #if defined(TARGET_MIPS64)
9742 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9746 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9749 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9752 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9755 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9758 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9761 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9764 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9766 #if defined(TARGET_MIPS64)
9768 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9772 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9775 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9778 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9781 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9783 #if defined(TARGET_MIPS64)
9785 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9789 generate_exception(ctx
, EXCP_RI
);
9796 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
9801 int op
, cnvt_op
, op1
, offset
;
9805 op
= (ctx
->opcode
>> 11) & 0x1f;
9806 sa
= (ctx
->opcode
>> 2) & 0x7;
9807 sa
= sa
== 0 ? 8 : sa
;
9808 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9809 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9810 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9811 op1
= offset
= ctx
->opcode
& 0x1f;
9816 case M16_OPC_ADDIUSP
:
9818 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9820 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9823 case M16_OPC_ADDIUPC
:
9824 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9827 offset
= (ctx
->opcode
& 0x7ff) << 1;
9828 offset
= (int16_t)(offset
<< 4) >> 4;
9829 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9830 /* No delay slot, so just process as a normal instruction */
9833 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9834 offset
= (((ctx
->opcode
& 0x1f) << 21)
9835 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9837 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9838 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9843 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9844 /* No delay slot, so just process as a normal instruction */
9847 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9848 /* No delay slot, so just process as a normal instruction */
9851 switch (ctx
->opcode
& 0x3) {
9853 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9856 #if defined(TARGET_MIPS64)
9858 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9860 generate_exception(ctx
, EXCP_RI
);
9864 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9867 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9871 #if defined(TARGET_MIPS64)
9874 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9879 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9881 if ((ctx
->opcode
>> 4) & 1) {
9882 #if defined(TARGET_MIPS64)
9884 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9886 generate_exception(ctx
, EXCP_RI
);
9889 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9893 case M16_OPC_ADDIU8
:
9895 int16_t imm
= (int8_t) ctx
->opcode
;
9897 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9902 int16_t imm
= (uint8_t) ctx
->opcode
;
9903 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9908 int16_t imm
= (uint8_t) ctx
->opcode
;
9909 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9916 funct
= (ctx
->opcode
>> 8) & 0x7;
9919 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9920 ((int8_t)ctx
->opcode
) << 1);
9923 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9924 ((int8_t)ctx
->opcode
) << 1);
9927 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9930 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9931 ((int8_t)ctx
->opcode
) << 3);
9935 int do_ra
= ctx
->opcode
& (1 << 6);
9936 int do_s0
= ctx
->opcode
& (1 << 5);
9937 int do_s1
= ctx
->opcode
& (1 << 4);
9938 int framesize
= ctx
->opcode
& 0xf;
9940 if (framesize
== 0) {
9943 framesize
= framesize
<< 3;
9946 if (ctx
->opcode
& (1 << 7)) {
9947 gen_mips16_save(ctx
, 0, 0,
9948 do_ra
, do_s0
, do_s1
, framesize
);
9950 gen_mips16_restore(ctx
, 0, 0,
9951 do_ra
, do_s0
, do_s1
, framesize
);
9957 int rz
= xlat(ctx
->opcode
& 0x7);
9959 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9960 ((ctx
->opcode
>> 5) & 0x7);
9961 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
9965 reg32
= ctx
->opcode
& 0x1f;
9966 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
9969 generate_exception(ctx
, EXCP_RI
);
9976 int16_t imm
= (uint8_t) ctx
->opcode
;
9978 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
9983 int16_t imm
= (uint8_t) ctx
->opcode
;
9984 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
9987 #if defined(TARGET_MIPS64)
9990 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
9994 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9997 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
10000 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10003 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
10006 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
10009 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
10012 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
10014 #if defined (TARGET_MIPS64)
10016 check_mips_64(ctx
);
10017 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
10021 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10024 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
10027 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10030 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10034 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10037 switch (ctx
->opcode
& 0x3) {
10039 mips32_op
= OPC_ADDU
;
10042 mips32_op
= OPC_SUBU
;
10044 #if defined(TARGET_MIPS64)
10046 mips32_op
= OPC_DADDU
;
10047 check_mips_64(ctx
);
10050 mips32_op
= OPC_DSUBU
;
10051 check_mips_64(ctx
);
10055 generate_exception(ctx
, EXCP_RI
);
10059 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10068 int nd
= (ctx
->opcode
>> 7) & 0x1;
10069 int link
= (ctx
->opcode
>> 6) & 0x1;
10070 int ra
= (ctx
->opcode
>> 5) & 0x1;
10073 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10078 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10085 /* XXX: not clear which exception should be raised
10086 * when in debug mode...
10088 check_insn(ctx
, ISA_MIPS32
);
10089 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10090 generate_exception(ctx
, EXCP_DBp
);
10092 generate_exception(ctx
, EXCP_DBp
);
10096 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10099 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10102 generate_exception(ctx
, EXCP_BREAK
);
10105 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10108 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10111 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10113 #if defined (TARGET_MIPS64)
10115 check_mips_64(ctx
);
10116 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10120 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10123 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10126 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10129 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10132 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10135 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10138 gen_HILO(ctx
, OPC_MFHI
, rx
);
10142 case RR_RY_CNVT_ZEB
:
10143 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10145 case RR_RY_CNVT_ZEH
:
10146 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10148 case RR_RY_CNVT_SEB
:
10149 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10151 case RR_RY_CNVT_SEH
:
10152 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10154 #if defined (TARGET_MIPS64)
10155 case RR_RY_CNVT_ZEW
:
10156 check_mips_64(ctx
);
10157 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10159 case RR_RY_CNVT_SEW
:
10160 check_mips_64(ctx
);
10161 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10165 generate_exception(ctx
, EXCP_RI
);
10170 gen_HILO(ctx
, OPC_MFLO
, rx
);
10172 #if defined (TARGET_MIPS64)
10174 check_mips_64(ctx
);
10175 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10178 check_mips_64(ctx
);
10179 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10182 check_mips_64(ctx
);
10183 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10186 check_mips_64(ctx
);
10187 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10191 gen_muldiv(ctx
, OPC_MULT
, rx
, ry
);
10194 gen_muldiv(ctx
, OPC_MULTU
, rx
, ry
);
10197 gen_muldiv(ctx
, OPC_DIV
, rx
, ry
);
10200 gen_muldiv(ctx
, OPC_DIVU
, rx
, ry
);
10202 #if defined (TARGET_MIPS64)
10204 check_mips_64(ctx
);
10205 gen_muldiv(ctx
, OPC_DMULT
, rx
, ry
);
10208 check_mips_64(ctx
);
10209 gen_muldiv(ctx
, OPC_DMULTU
, rx
, ry
);
10212 check_mips_64(ctx
);
10213 gen_muldiv(ctx
, OPC_DDIV
, rx
, ry
);
10216 check_mips_64(ctx
);
10217 gen_muldiv(ctx
, OPC_DDIVU
, rx
, ry
);
10221 generate_exception(ctx
, EXCP_RI
);
10225 case M16_OPC_EXTEND
:
10226 decode_extended_mips16_opc(env
, ctx
, is_branch
);
10229 #if defined(TARGET_MIPS64)
10231 funct
= (ctx
->opcode
>> 8) & 0x7;
10232 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10236 generate_exception(ctx
, EXCP_RI
);
10243 /* microMIPS extension to MIPS32/MIPS64 */
10246 * microMIPS32/microMIPS64 major opcodes
10248 * 1. MIPS Architecture for Programmers Volume II-B:
10249 * The microMIPS32 Instruction Set (Revision 3.05)
10251 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10253 * 2. MIPS Architecture For Programmers Volume II-A:
10254 * The MIPS64 Instruction Set (Revision 3.51)
10282 POOL32S
= 0x16, /* MIPS64 */
10283 DADDIU32
= 0x17, /* MIPS64 */
10285 /* 0x1f is reserved */
10294 /* 0x20 is reserved */
10304 /* 0x28 and 0x29 are reserved */
10314 /* 0x30 and 0x31 are reserved */
10321 SD32
= 0x36, /* MIPS64 */
10322 LD32
= 0x37, /* MIPS64 */
10324 /* 0x38 and 0x39 are reserved */
10335 /* POOL32A encoding of minor opcode field */
10338 /* These opcodes are distinguished only by bits 9..6; those bits are
10339 * what are recorded below. */
10365 /* The following can be distinguished by their lower 6 bits. */
10371 /* POOL32AXF encoding of minor opcode field extension */
10374 * 1. MIPS Architecture for Programmers Volume II-B:
10375 * The microMIPS32 Instruction Set (Revision 3.05)
10377 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10379 * 2. MIPS Architecture for Programmers VolumeIV-e:
10380 * The MIPS DSP Application-Specific Extension
10381 * to the microMIPS32 Architecture (Revision 2.34)
10383 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10398 /* begin of microMIPS32 DSP */
10400 /* bits 13..12 for 0x01 */
10406 /* bits 13..12 for 0x2a */
10412 /* bits 13..12 for 0x32 */
10416 /* end of microMIPS32 DSP */
10418 /* bits 15..12 for 0x2c */
10434 /* bits 15..12 for 0x34 */
10442 /* bits 15..12 for 0x3c */
10444 JR
= 0x0, /* alias */
10449 /* bits 15..12 for 0x05 */
10453 /* bits 15..12 for 0x0d */
10463 /* bits 15..12 for 0x15 */
10469 /* bits 15..12 for 0x1d */
10473 /* bits 15..12 for 0x2d */
10478 /* bits 15..12 for 0x35 */
10485 /* POOL32B encoding of minor opcode field (bits 15..12) */
10501 /* POOL32C encoding of minor opcode field (bits 15..12) */
10509 /* 0xa is reserved */
10516 /* 0x6 is reserved */
10522 /* POOL32F encoding of minor opcode field (bits 5..0) */
10525 /* These are the bit 7..6 values */
10536 /* These are the bit 8..6 values */
10580 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10584 /* POOL32Fxf encoding of minor opcode extension field */
10622 /* POOL32I encoding of minor opcode field (bits 25..21) */
10647 /* These overlap and are distinguished by bit16 of the instruction */
10656 /* POOL16A encoding of minor opcode field */
10663 /* POOL16B encoding of minor opcode field */
10670 /* POOL16C encoding of minor opcode field */
10690 /* POOL16D encoding of minor opcode field */
10697 /* POOL16E encoding of minor opcode field */
10704 static int mmreg (int r
)
10706 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10711 /* Used for 16-bit store instructions. */
10712 static int mmreg2 (int r
)
10714 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10719 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10720 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10721 #define uMIPS_RS2(op) uMIPS_RS(op)
10722 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10723 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10724 #define uMIPS_RS5(op) (op & 0x1f)
10726 /* Signed immediate */
10727 #define SIMM(op, start, width) \
10728 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10731 /* Zero-extended immediate */
10732 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10734 static void gen_addiur1sp(DisasContext
*ctx
)
10736 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10738 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10741 static void gen_addiur2(DisasContext
*ctx
)
10743 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10744 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10745 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10747 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10750 static void gen_addiusp(DisasContext
*ctx
)
10752 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10755 if (encoded
<= 1) {
10756 decoded
= 256 + encoded
;
10757 } else if (encoded
<= 255) {
10759 } else if (encoded
<= 509) {
10760 decoded
= encoded
- 512;
10762 decoded
= encoded
- 768;
10765 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10768 static void gen_addius5(DisasContext
*ctx
)
10770 int imm
= SIMM(ctx
->opcode
, 1, 4);
10771 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10773 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10776 static void gen_andi16(DisasContext
*ctx
)
10778 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10779 31, 32, 63, 64, 255, 32768, 65535 };
10780 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10781 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10782 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10784 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10787 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10788 int base
, int16_t offset
)
10790 const char *opn
= "ldst_multiple";
10794 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10795 generate_exception(ctx
, EXCP_RI
);
10799 t0
= tcg_temp_new();
10801 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10803 t1
= tcg_const_tl(reglist
);
10804 t2
= tcg_const_i32(ctx
->mem_idx
);
10806 save_cpu_state(ctx
, 1);
10809 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10813 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10816 #ifdef TARGET_MIPS64
10818 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10822 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10828 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10831 tcg_temp_free_i32(t2
);
10835 static void gen_pool16c_insn(DisasContext
*ctx
, int *is_branch
)
10837 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10838 int rs
= mmreg(ctx
->opcode
& 0x7);
10841 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10846 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10852 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10858 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10864 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10871 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10872 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10874 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10883 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10884 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10886 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10893 int reg
= ctx
->opcode
& 0x1f;
10895 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10902 int reg
= ctx
->opcode
& 0x1f;
10904 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10905 /* Let normal delay slot handling in our caller take us
10906 to the branch target. */
10918 int reg
= ctx
->opcode
& 0x1f;
10920 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10926 gen_HILO(ctx
, OPC_MFHI
, uMIPS_RS5(ctx
->opcode
));
10930 gen_HILO(ctx
, OPC_MFLO
, uMIPS_RS5(ctx
->opcode
));
10933 generate_exception(ctx
, EXCP_BREAK
);
10936 /* XXX: not clear which exception should be raised
10937 * when in debug mode...
10939 check_insn(ctx
, ISA_MIPS32
);
10940 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10941 generate_exception(ctx
, EXCP_DBp
);
10943 generate_exception(ctx
, EXCP_DBp
);
10946 case JRADDIUSP
+ 0:
10947 case JRADDIUSP
+ 1:
10949 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10951 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10952 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10953 /* Let normal delay slot handling in our caller take us
10954 to the branch target. */
10958 generate_exception(ctx
, EXCP_RI
);
10963 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10965 TCGv t0
= tcg_temp_new();
10966 TCGv t1
= tcg_temp_new();
10968 gen_load_gpr(t0
, base
);
10971 gen_load_gpr(t1
, index
);
10972 tcg_gen_shli_tl(t1
, t1
, 2);
10973 gen_op_addr_add(ctx
, t0
, t1
, t0
);
10976 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10977 gen_store_gpr(t1
, rd
);
10983 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
10984 int base
, int16_t offset
)
10986 const char *opn
= "ldst_pair";
10989 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
10990 generate_exception(ctx
, EXCP_RI
);
10994 t0
= tcg_temp_new();
10995 t1
= tcg_temp_new();
10997 gen_base_offset_addr(ctx
, t0
, base
, offset
);
11002 generate_exception(ctx
, EXCP_RI
);
11005 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
11006 gen_store_gpr(t1
, rd
);
11007 tcg_gen_movi_tl(t1
, 4);
11008 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11009 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
11010 gen_store_gpr(t1
, rd
+1);
11014 gen_load_gpr(t1
, rd
);
11015 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
11016 tcg_gen_movi_tl(t1
, 4);
11017 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11018 gen_load_gpr(t1
, rd
+1);
11019 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
11022 #ifdef TARGET_MIPS64
11025 generate_exception(ctx
, EXCP_RI
);
11028 tcg_gen_qemu_ld64(t1
, t0
, ctx
->mem_idx
);
11029 gen_store_gpr(t1
, rd
);
11030 tcg_gen_movi_tl(t1
, 8);
11031 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11032 tcg_gen_qemu_ld64(t1
, t0
, ctx
->mem_idx
);
11033 gen_store_gpr(t1
, rd
+1);
11037 gen_load_gpr(t1
, rd
);
11038 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
11039 tcg_gen_movi_tl(t1
, 8);
11040 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11041 gen_load_gpr(t1
, rd
+1);
11042 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
11047 (void)opn
; /* avoid a compiler warning */
11048 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11053 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
,
11056 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11057 int minor
= (ctx
->opcode
>> 12) & 0xf;
11058 uint32_t mips32_op
;
11060 switch (extension
) {
11062 mips32_op
= OPC_TEQ
;
11065 mips32_op
= OPC_TGE
;
11068 mips32_op
= OPC_TGEU
;
11071 mips32_op
= OPC_TLT
;
11074 mips32_op
= OPC_TLTU
;
11077 mips32_op
= OPC_TNE
;
11079 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11081 #ifndef CONFIG_USER_ONLY
11084 check_cp0_enabled(ctx
);
11086 /* Treat as NOP. */
11089 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11093 check_cp0_enabled(ctx
);
11095 TCGv t0
= tcg_temp_new();
11097 gen_load_gpr(t0
, rt
);
11098 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11106 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11109 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11112 mips32_op
= OPC_CLO
;
11115 mips32_op
= OPC_CLZ
;
11117 check_insn(ctx
, ISA_MIPS32
);
11118 gen_cl(ctx
, mips32_op
, rt
, rs
);
11121 gen_rdhwr(ctx
, rt
, rs
);
11124 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11127 mips32_op
= OPC_MULT
;
11130 mips32_op
= OPC_MULTU
;
11133 mips32_op
= OPC_DIV
;
11136 mips32_op
= OPC_DIVU
;
11139 mips32_op
= OPC_MADD
;
11142 mips32_op
= OPC_MADDU
;
11145 mips32_op
= OPC_MSUB
;
11148 mips32_op
= OPC_MSUBU
;
11150 check_insn(ctx
, ISA_MIPS32
);
11151 gen_muldiv(ctx
, mips32_op
, rs
, rt
);
11154 goto pool32axf_invalid
;
11165 generate_exception_err(ctx
, EXCP_CpU
, 2);
11168 goto pool32axf_invalid
;
11175 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11180 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11184 goto pool32axf_invalid
;
11190 check_cp0_enabled(ctx
);
11191 check_insn(ctx
, ISA_MIPS32R2
);
11192 gen_load_srsgpr(rt
, rs
);
11195 check_cp0_enabled(ctx
);
11196 check_insn(ctx
, ISA_MIPS32R2
);
11197 gen_store_srsgpr(rt
, rs
);
11200 goto pool32axf_invalid
;
11203 #ifndef CONFIG_USER_ONLY
11207 mips32_op
= OPC_TLBP
;
11210 mips32_op
= OPC_TLBR
;
11213 mips32_op
= OPC_TLBWI
;
11216 mips32_op
= OPC_TLBWR
;
11219 mips32_op
= OPC_WAIT
;
11222 mips32_op
= OPC_DERET
;
11225 mips32_op
= OPC_ERET
;
11227 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11230 goto pool32axf_invalid
;
11236 check_cp0_enabled(ctx
);
11238 TCGv t0
= tcg_temp_new();
11240 save_cpu_state(ctx
, 1);
11241 gen_helper_di(t0
, cpu_env
);
11242 gen_store_gpr(t0
, rs
);
11243 /* Stop translation as we may have switched the execution mode */
11244 ctx
->bstate
= BS_STOP
;
11249 check_cp0_enabled(ctx
);
11251 TCGv t0
= tcg_temp_new();
11253 save_cpu_state(ctx
, 1);
11254 gen_helper_ei(t0
, cpu_env
);
11255 gen_store_gpr(t0
, rs
);
11256 /* Stop translation as we may have switched the execution mode */
11257 ctx
->bstate
= BS_STOP
;
11262 goto pool32axf_invalid
;
11272 generate_exception(ctx
, EXCP_SYSCALL
);
11273 ctx
->bstate
= BS_STOP
;
11276 check_insn(ctx
, ISA_MIPS32
);
11277 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11278 generate_exception(ctx
, EXCP_DBp
);
11280 generate_exception(ctx
, EXCP_DBp
);
11284 goto pool32axf_invalid
;
11290 gen_HILO(ctx
, OPC_MFHI
, rs
);
11293 gen_HILO(ctx
, OPC_MFLO
, rs
);
11296 gen_HILO(ctx
, OPC_MTHI
, rs
);
11299 gen_HILO(ctx
, OPC_MTLO
, rs
);
11302 goto pool32axf_invalid
;
11307 MIPS_INVAL("pool32axf");
11308 generate_exception(ctx
, EXCP_RI
);
11313 /* Values for microMIPS fmt field. Variable-width, depending on which
11314 formats the instruction supports. */
11333 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11335 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11336 uint32_t mips32_op
;
11338 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11339 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11340 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11342 switch (extension
) {
11343 case FLOAT_1BIT_FMT(CFC1
, 0):
11344 mips32_op
= OPC_CFC1
;
11346 case FLOAT_1BIT_FMT(CTC1
, 0):
11347 mips32_op
= OPC_CTC1
;
11349 case FLOAT_1BIT_FMT(MFC1
, 0):
11350 mips32_op
= OPC_MFC1
;
11352 case FLOAT_1BIT_FMT(MTC1
, 0):
11353 mips32_op
= OPC_MTC1
;
11355 case FLOAT_1BIT_FMT(MFHC1
, 0):
11356 mips32_op
= OPC_MFHC1
;
11358 case FLOAT_1BIT_FMT(MTHC1
, 0):
11359 mips32_op
= OPC_MTHC1
;
11361 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11364 /* Reciprocal square root */
11365 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11366 mips32_op
= OPC_RSQRT_S
;
11368 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11369 mips32_op
= OPC_RSQRT_D
;
11373 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11374 mips32_op
= OPC_SQRT_S
;
11376 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11377 mips32_op
= OPC_SQRT_D
;
11381 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11382 mips32_op
= OPC_RECIP_S
;
11384 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11385 mips32_op
= OPC_RECIP_D
;
11389 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11390 mips32_op
= OPC_FLOOR_L_S
;
11392 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11393 mips32_op
= OPC_FLOOR_L_D
;
11395 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11396 mips32_op
= OPC_FLOOR_W_S
;
11398 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11399 mips32_op
= OPC_FLOOR_W_D
;
11403 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11404 mips32_op
= OPC_CEIL_L_S
;
11406 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11407 mips32_op
= OPC_CEIL_L_D
;
11409 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11410 mips32_op
= OPC_CEIL_W_S
;
11412 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11413 mips32_op
= OPC_CEIL_W_D
;
11417 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11418 mips32_op
= OPC_TRUNC_L_S
;
11420 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11421 mips32_op
= OPC_TRUNC_L_D
;
11423 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11424 mips32_op
= OPC_TRUNC_W_S
;
11426 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11427 mips32_op
= OPC_TRUNC_W_D
;
11431 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11432 mips32_op
= OPC_ROUND_L_S
;
11434 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11435 mips32_op
= OPC_ROUND_L_D
;
11437 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11438 mips32_op
= OPC_ROUND_W_S
;
11440 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11441 mips32_op
= OPC_ROUND_W_D
;
11444 /* Integer to floating-point conversion */
11445 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11446 mips32_op
= OPC_CVT_L_S
;
11448 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11449 mips32_op
= OPC_CVT_L_D
;
11451 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11452 mips32_op
= OPC_CVT_W_S
;
11454 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11455 mips32_op
= OPC_CVT_W_D
;
11458 /* Paired-foo conversions */
11459 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11460 mips32_op
= OPC_CVT_S_PL
;
11462 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11463 mips32_op
= OPC_CVT_S_PU
;
11465 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11466 mips32_op
= OPC_CVT_PW_PS
;
11468 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11469 mips32_op
= OPC_CVT_PS_PW
;
11472 /* Floating-point moves */
11473 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11474 mips32_op
= OPC_MOV_S
;
11476 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11477 mips32_op
= OPC_MOV_D
;
11479 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11480 mips32_op
= OPC_MOV_PS
;
11483 /* Absolute value */
11484 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11485 mips32_op
= OPC_ABS_S
;
11487 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11488 mips32_op
= OPC_ABS_D
;
11490 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11491 mips32_op
= OPC_ABS_PS
;
11495 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11496 mips32_op
= OPC_NEG_S
;
11498 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11499 mips32_op
= OPC_NEG_D
;
11501 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11502 mips32_op
= OPC_NEG_PS
;
11505 /* Reciprocal square root step */
11506 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11507 mips32_op
= OPC_RSQRT1_S
;
11509 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11510 mips32_op
= OPC_RSQRT1_D
;
11512 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11513 mips32_op
= OPC_RSQRT1_PS
;
11516 /* Reciprocal step */
11517 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11518 mips32_op
= OPC_RECIP1_S
;
11520 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11521 mips32_op
= OPC_RECIP1_S
;
11523 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11524 mips32_op
= OPC_RECIP1_PS
;
11527 /* Conversions from double */
11528 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11529 mips32_op
= OPC_CVT_D_S
;
11531 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11532 mips32_op
= OPC_CVT_D_W
;
11534 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11535 mips32_op
= OPC_CVT_D_L
;
11538 /* Conversions from single */
11539 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11540 mips32_op
= OPC_CVT_S_D
;
11542 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11543 mips32_op
= OPC_CVT_S_W
;
11545 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11546 mips32_op
= OPC_CVT_S_L
;
11548 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11551 /* Conditional moves on floating-point codes */
11552 case COND_FLOAT_MOV(MOVT
, 0):
11553 case COND_FLOAT_MOV(MOVT
, 1):
11554 case COND_FLOAT_MOV(MOVT
, 2):
11555 case COND_FLOAT_MOV(MOVT
, 3):
11556 case COND_FLOAT_MOV(MOVT
, 4):
11557 case COND_FLOAT_MOV(MOVT
, 5):
11558 case COND_FLOAT_MOV(MOVT
, 6):
11559 case COND_FLOAT_MOV(MOVT
, 7):
11560 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11562 case COND_FLOAT_MOV(MOVF
, 0):
11563 case COND_FLOAT_MOV(MOVF
, 1):
11564 case COND_FLOAT_MOV(MOVF
, 2):
11565 case COND_FLOAT_MOV(MOVF
, 3):
11566 case COND_FLOAT_MOV(MOVF
, 4):
11567 case COND_FLOAT_MOV(MOVF
, 5):
11568 case COND_FLOAT_MOV(MOVF
, 6):
11569 case COND_FLOAT_MOV(MOVF
, 7):
11570 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11573 MIPS_INVAL("pool32fxf");
11574 generate_exception(ctx
, EXCP_RI
);
11579 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11580 uint16_t insn_hw1
, int *is_branch
)
11584 int rt
, rs
, rd
, rr
;
11586 uint32_t op
, minor
, mips32_op
;
11587 uint32_t cond
, fmt
, cc
;
11589 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11590 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11592 rt
= (ctx
->opcode
>> 21) & 0x1f;
11593 rs
= (ctx
->opcode
>> 16) & 0x1f;
11594 rd
= (ctx
->opcode
>> 11) & 0x1f;
11595 rr
= (ctx
->opcode
>> 6) & 0x1f;
11596 imm
= (int16_t) ctx
->opcode
;
11598 op
= (ctx
->opcode
>> 26) & 0x3f;
11601 minor
= ctx
->opcode
& 0x3f;
11604 minor
= (ctx
->opcode
>> 6) & 0xf;
11607 mips32_op
= OPC_SLL
;
11610 mips32_op
= OPC_SRA
;
11613 mips32_op
= OPC_SRL
;
11616 mips32_op
= OPC_ROTR
;
11618 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11621 goto pool32a_invalid
;
11625 minor
= (ctx
->opcode
>> 6) & 0xf;
11629 mips32_op
= OPC_ADD
;
11632 mips32_op
= OPC_ADDU
;
11635 mips32_op
= OPC_SUB
;
11638 mips32_op
= OPC_SUBU
;
11641 mips32_op
= OPC_MUL
;
11643 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11647 mips32_op
= OPC_SLLV
;
11650 mips32_op
= OPC_SRLV
;
11653 mips32_op
= OPC_SRAV
;
11656 mips32_op
= OPC_ROTRV
;
11658 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11660 /* Logical operations */
11662 mips32_op
= OPC_AND
;
11665 mips32_op
= OPC_OR
;
11668 mips32_op
= OPC_NOR
;
11671 mips32_op
= OPC_XOR
;
11673 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11675 /* Set less than */
11677 mips32_op
= OPC_SLT
;
11680 mips32_op
= OPC_SLTU
;
11682 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11685 goto pool32a_invalid
;
11689 minor
= (ctx
->opcode
>> 6) & 0xf;
11691 /* Conditional moves */
11693 mips32_op
= OPC_MOVN
;
11696 mips32_op
= OPC_MOVZ
;
11698 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11701 gen_ldxs(ctx
, rs
, rt
, rd
);
11704 goto pool32a_invalid
;
11708 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11711 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11714 gen_pool32axf(env
, ctx
, rt
, rs
, is_branch
);
11717 generate_exception(ctx
, EXCP_BREAK
);
11721 MIPS_INVAL("pool32a");
11722 generate_exception(ctx
, EXCP_RI
);
11727 minor
= (ctx
->opcode
>> 12) & 0xf;
11730 check_cp0_enabled(ctx
);
11731 /* Treat as no-op. */
11735 /* COP2: Not implemented. */
11736 generate_exception_err(ctx
, EXCP_CpU
, 2);
11740 #ifdef TARGET_MIPS64
11744 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11748 #ifdef TARGET_MIPS64
11752 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11755 MIPS_INVAL("pool32b");
11756 generate_exception(ctx
, EXCP_RI
);
11761 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
11762 minor
= ctx
->opcode
& 0x3f;
11763 check_cp1_enabled(ctx
);
11766 mips32_op
= OPC_ALNV_PS
;
11769 mips32_op
= OPC_MADD_S
;
11772 mips32_op
= OPC_MADD_D
;
11775 mips32_op
= OPC_MADD_PS
;
11778 mips32_op
= OPC_MSUB_S
;
11781 mips32_op
= OPC_MSUB_D
;
11784 mips32_op
= OPC_MSUB_PS
;
11787 mips32_op
= OPC_NMADD_S
;
11790 mips32_op
= OPC_NMADD_D
;
11793 mips32_op
= OPC_NMADD_PS
;
11796 mips32_op
= OPC_NMSUB_S
;
11799 mips32_op
= OPC_NMSUB_D
;
11802 mips32_op
= OPC_NMSUB_PS
;
11804 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11806 case CABS_COND_FMT
:
11807 cond
= (ctx
->opcode
>> 6) & 0xf;
11808 cc
= (ctx
->opcode
>> 13) & 0x7;
11809 fmt
= (ctx
->opcode
>> 10) & 0x3;
11812 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11815 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11818 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11821 goto pool32f_invalid
;
11825 cond
= (ctx
->opcode
>> 6) & 0xf;
11826 cc
= (ctx
->opcode
>> 13) & 0x7;
11827 fmt
= (ctx
->opcode
>> 10) & 0x3;
11830 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11833 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11836 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11839 goto pool32f_invalid
;
11843 gen_pool32fxf(ctx
, rt
, rs
);
11847 switch ((ctx
->opcode
>> 6) & 0x7) {
11849 mips32_op
= OPC_PLL_PS
;
11852 mips32_op
= OPC_PLU_PS
;
11855 mips32_op
= OPC_PUL_PS
;
11858 mips32_op
= OPC_PUU_PS
;
11861 mips32_op
= OPC_CVT_PS_S
;
11863 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11866 goto pool32f_invalid
;
11871 switch ((ctx
->opcode
>> 6) & 0x7) {
11873 mips32_op
= OPC_LWXC1
;
11876 mips32_op
= OPC_SWXC1
;
11879 mips32_op
= OPC_LDXC1
;
11882 mips32_op
= OPC_SDXC1
;
11885 mips32_op
= OPC_LUXC1
;
11888 mips32_op
= OPC_SUXC1
;
11890 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11893 goto pool32f_invalid
;
11898 fmt
= (ctx
->opcode
>> 9) & 0x3;
11899 switch ((ctx
->opcode
>> 6) & 0x7) {
11903 mips32_op
= OPC_RSQRT2_S
;
11906 mips32_op
= OPC_RSQRT2_D
;
11909 mips32_op
= OPC_RSQRT2_PS
;
11912 goto pool32f_invalid
;
11918 mips32_op
= OPC_RECIP2_S
;
11921 mips32_op
= OPC_RECIP2_D
;
11924 mips32_op
= OPC_RECIP2_PS
;
11927 goto pool32f_invalid
;
11931 mips32_op
= OPC_ADDR_PS
;
11934 mips32_op
= OPC_MULR_PS
;
11936 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11939 goto pool32f_invalid
;
11943 /* MOV[FT].fmt and PREFX */
11944 cc
= (ctx
->opcode
>> 13) & 0x7;
11945 fmt
= (ctx
->opcode
>> 9) & 0x3;
11946 switch ((ctx
->opcode
>> 6) & 0x7) {
11950 gen_movcf_s(rs
, rt
, cc
, 0);
11953 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
11956 gen_movcf_ps(rs
, rt
, cc
, 0);
11959 goto pool32f_invalid
;
11965 gen_movcf_s(rs
, rt
, cc
, 1);
11968 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
11971 gen_movcf_ps(rs
, rt
, cc
, 1);
11974 goto pool32f_invalid
;
11980 goto pool32f_invalid
;
11983 #define FINSN_3ARG_SDPS(prfx) \
11984 switch ((ctx->opcode >> 8) & 0x3) { \
11986 mips32_op = OPC_##prfx##_S; \
11989 mips32_op = OPC_##prfx##_D; \
11991 case FMT_SDPS_PS: \
11992 mips32_op = OPC_##prfx##_PS; \
11995 goto pool32f_invalid; \
11998 /* regular FP ops */
11999 switch ((ctx
->opcode
>> 6) & 0x3) {
12001 FINSN_3ARG_SDPS(ADD
);
12004 FINSN_3ARG_SDPS(SUB
);
12007 FINSN_3ARG_SDPS(MUL
);
12010 fmt
= (ctx
->opcode
>> 8) & 0x3;
12012 mips32_op
= OPC_DIV_D
;
12013 } else if (fmt
== 0) {
12014 mips32_op
= OPC_DIV_S
;
12016 goto pool32f_invalid
;
12020 goto pool32f_invalid
;
12025 switch ((ctx
->opcode
>> 6) & 0x3) {
12027 FINSN_3ARG_SDPS(MOVN
);
12030 FINSN_3ARG_SDPS(MOVZ
);
12033 goto pool32f_invalid
;
12037 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12041 MIPS_INVAL("pool32f");
12042 generate_exception(ctx
, EXCP_RI
);
12046 generate_exception_err(ctx
, EXCP_CpU
, 1);
12050 minor
= (ctx
->opcode
>> 21) & 0x1f;
12053 mips32_op
= OPC_BLTZ
;
12056 mips32_op
= OPC_BLTZAL
;
12059 mips32_op
= OPC_BLTZALS
;
12062 mips32_op
= OPC_BGEZ
;
12065 mips32_op
= OPC_BGEZAL
;
12068 mips32_op
= OPC_BGEZALS
;
12071 mips32_op
= OPC_BLEZ
;
12074 mips32_op
= OPC_BGTZ
;
12076 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12082 mips32_op
= OPC_TLTI
;
12085 mips32_op
= OPC_TGEI
;
12088 mips32_op
= OPC_TLTIU
;
12091 mips32_op
= OPC_TGEIU
;
12094 mips32_op
= OPC_TNEI
;
12097 mips32_op
= OPC_TEQI
;
12099 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12104 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12105 4, rs
, 0, imm
<< 1);
12106 /* Compact branches don't have a delay slot, so just let
12107 the normal delay slot handling take us to the branch
12111 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12117 /* COP2: Not implemented. */
12118 generate_exception_err(ctx
, EXCP_CpU
, 2);
12121 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12124 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12127 mips32_op
= OPC_BC1FANY4
;
12130 mips32_op
= OPC_BC1TANY4
;
12133 check_insn(ctx
, ASE_MIPS3D
);
12136 gen_compute_branch1(ctx
, mips32_op
,
12137 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12142 /* MIPS DSP: not implemented */
12145 MIPS_INVAL("pool32i");
12146 generate_exception(ctx
, EXCP_RI
);
12151 minor
= (ctx
->opcode
>> 12) & 0xf;
12154 mips32_op
= OPC_LWL
;
12157 mips32_op
= OPC_SWL
;
12160 mips32_op
= OPC_LWR
;
12163 mips32_op
= OPC_SWR
;
12165 #if defined(TARGET_MIPS64)
12167 mips32_op
= OPC_LDL
;
12170 mips32_op
= OPC_SDL
;
12173 mips32_op
= OPC_LDR
;
12176 mips32_op
= OPC_SDR
;
12179 mips32_op
= OPC_LWU
;
12182 mips32_op
= OPC_LLD
;
12186 mips32_op
= OPC_LL
;
12189 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12192 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12195 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12197 #if defined(TARGET_MIPS64)
12199 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12203 /* Treat as no-op */
12206 MIPS_INVAL("pool32c");
12207 generate_exception(ctx
, EXCP_RI
);
12212 mips32_op
= OPC_ADDI
;
12215 mips32_op
= OPC_ADDIU
;
12217 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12220 /* Logical operations */
12222 mips32_op
= OPC_ORI
;
12225 mips32_op
= OPC_XORI
;
12228 mips32_op
= OPC_ANDI
;
12230 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12233 /* Set less than immediate */
12235 mips32_op
= OPC_SLTI
;
12238 mips32_op
= OPC_SLTIU
;
12240 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12243 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12244 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12248 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12249 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12253 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12257 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12261 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12262 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12266 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12267 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12270 /* Floating point (COP1) */
12272 mips32_op
= OPC_LWC1
;
12275 mips32_op
= OPC_LDC1
;
12278 mips32_op
= OPC_SWC1
;
12281 mips32_op
= OPC_SDC1
;
12283 gen_cop1_ldst(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12287 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12288 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12290 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12293 /* Loads and stores */
12295 mips32_op
= OPC_LB
;
12298 mips32_op
= OPC_LBU
;
12301 mips32_op
= OPC_LH
;
12304 mips32_op
= OPC_LHU
;
12307 mips32_op
= OPC_LW
;
12309 #ifdef TARGET_MIPS64
12311 mips32_op
= OPC_LD
;
12314 mips32_op
= OPC_SD
;
12318 mips32_op
= OPC_SB
;
12321 mips32_op
= OPC_SH
;
12324 mips32_op
= OPC_SW
;
12327 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12330 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12333 generate_exception(ctx
, EXCP_RI
);
12338 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
, int *is_branch
)
12342 /* make sure instructions are on a halfword boundary */
12343 if (ctx
->pc
& 0x1) {
12344 env
->CP0_BadVAddr
= ctx
->pc
;
12345 generate_exception(ctx
, EXCP_AdEL
);
12346 ctx
->bstate
= BS_STOP
;
12350 op
= (ctx
->opcode
>> 10) & 0x3f;
12351 /* Enforce properly-sized instructions in a delay slot */
12352 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12353 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12391 if (bits
& MIPS_HFLAG_BDS16
) {
12392 generate_exception(ctx
, EXCP_RI
);
12393 /* Just stop translation; the user is confused. */
12394 ctx
->bstate
= BS_STOP
;
12419 if (bits
& MIPS_HFLAG_BDS32
) {
12420 generate_exception(ctx
, EXCP_RI
);
12421 /* Just stop translation; the user is confused. */
12422 ctx
->bstate
= BS_STOP
;
12433 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12434 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12435 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12438 switch (ctx
->opcode
& 0x1) {
12447 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12452 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12453 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12454 int amount
= (ctx
->opcode
>> 1) & 0x7;
12456 amount
= amount
== 0 ? 8 : amount
;
12458 switch (ctx
->opcode
& 0x1) {
12467 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12471 gen_pool16c_insn(ctx
, is_branch
);
12475 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12476 int rb
= 28; /* GP */
12477 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12479 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12483 if (ctx
->opcode
& 1) {
12484 generate_exception(ctx
, EXCP_RI
);
12487 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12488 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12489 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12490 int rd
, rs
, re
, rt
;
12491 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12492 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12493 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12495 rd
= rd_enc
[enc_dest
];
12496 re
= re_enc
[enc_dest
];
12497 rs
= rs_rt_enc
[enc_rs
];
12498 rt
= rs_rt_enc
[enc_rt
];
12500 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12501 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12506 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12507 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12508 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12509 offset
= (offset
== 0xf ? -1 : offset
);
12511 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12516 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12517 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12518 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12520 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12525 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12526 int rb
= 29; /* SP */
12527 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12529 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12534 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12535 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12536 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12538 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12543 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12544 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12545 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12547 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12552 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12553 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12554 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12556 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12561 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12562 int rb
= 29; /* SP */
12563 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12565 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12570 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12571 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12572 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12574 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12579 int rd
= uMIPS_RD5(ctx
->opcode
);
12580 int rs
= uMIPS_RS5(ctx
->opcode
);
12582 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12589 switch (ctx
->opcode
& 0x1) {
12599 switch (ctx
->opcode
& 0x1) {
12604 gen_addiur1sp(ctx
);
12609 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12610 SIMM(ctx
->opcode
, 0, 10) << 1);
12615 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12616 mmreg(uMIPS_RD(ctx
->opcode
)),
12617 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12622 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12623 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12625 imm
= (imm
== 0x7f ? -1 : imm
);
12626 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12636 generate_exception(ctx
, EXCP_RI
);
12639 decode_micromips32_opc (env
, ctx
, op
, is_branch
);
12646 /* SmartMIPS extension to MIPS32 */
12648 #if defined(TARGET_MIPS64)
12650 /* MDMX extension to MIPS64 */
12654 /* MIPSDSP functions. */
12655 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12656 int rd
, int base
, int offset
)
12658 const char *opn
= "ldx";
12662 t0
= tcg_temp_new();
12665 gen_load_gpr(t0
, offset
);
12666 } else if (offset
== 0) {
12667 gen_load_gpr(t0
, base
);
12669 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12674 tcg_gen_qemu_ld8u(t0
, t0
, ctx
->mem_idx
);
12675 gen_store_gpr(t0
, rd
);
12679 tcg_gen_qemu_ld16s(t0
, t0
, ctx
->mem_idx
);
12680 gen_store_gpr(t0
, rd
);
12684 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
12685 gen_store_gpr(t0
, rd
);
12688 #if defined(TARGET_MIPS64)
12690 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
12691 gen_store_gpr(t0
, rd
);
12696 (void)opn
; /* avoid a compiler warning */
12697 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12698 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12702 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12703 int ret
, int v1
, int v2
)
12705 const char *opn
= "mipsdsp arith";
12710 /* Treat as NOP. */
12715 v1_t
= tcg_temp_new();
12716 v2_t
= tcg_temp_new();
12718 gen_load_gpr(v1_t
, v1
);
12719 gen_load_gpr(v2_t
, v2
);
12722 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12723 case OPC_MULT_G_2E
:
12727 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12729 case OPC_ADDUH_R_QB
:
12730 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12733 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12735 case OPC_ADDQH_R_PH
:
12736 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12739 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12741 case OPC_ADDQH_R_W
:
12742 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12745 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12747 case OPC_SUBUH_R_QB
:
12748 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12751 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12753 case OPC_SUBQH_R_PH
:
12754 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12757 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12759 case OPC_SUBQH_R_W
:
12760 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12764 case OPC_ABSQ_S_PH_DSP
:
12766 case OPC_ABSQ_S_QB
:
12768 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12770 case OPC_ABSQ_S_PH
:
12772 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12776 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12778 case OPC_PRECEQ_W_PHL
:
12780 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12781 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12783 case OPC_PRECEQ_W_PHR
:
12785 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12786 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12787 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12789 case OPC_PRECEQU_PH_QBL
:
12791 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12793 case OPC_PRECEQU_PH_QBR
:
12795 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12797 case OPC_PRECEQU_PH_QBLA
:
12799 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12801 case OPC_PRECEQU_PH_QBRA
:
12803 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12805 case OPC_PRECEU_PH_QBL
:
12807 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12809 case OPC_PRECEU_PH_QBR
:
12811 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12813 case OPC_PRECEU_PH_QBLA
:
12815 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12817 case OPC_PRECEU_PH_QBRA
:
12819 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12823 case OPC_ADDU_QB_DSP
:
12827 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12829 case OPC_ADDQ_S_PH
:
12831 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12835 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12839 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12841 case OPC_ADDU_S_QB
:
12843 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12847 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12849 case OPC_ADDU_S_PH
:
12851 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12855 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12857 case OPC_SUBQ_S_PH
:
12859 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12863 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12867 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12869 case OPC_SUBU_S_QB
:
12871 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12875 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12877 case OPC_SUBU_S_PH
:
12879 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12883 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12887 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12891 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12893 case OPC_RADDU_W_QB
:
12895 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12899 case OPC_CMPU_EQ_QB_DSP
:
12901 case OPC_PRECR_QB_PH
:
12903 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12905 case OPC_PRECRQ_QB_PH
:
12907 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12909 case OPC_PRECR_SRA_PH_W
:
12912 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12913 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12915 tcg_temp_free_i32(sa_t
);
12918 case OPC_PRECR_SRA_R_PH_W
:
12921 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12922 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12924 tcg_temp_free_i32(sa_t
);
12927 case OPC_PRECRQ_PH_W
:
12929 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12931 case OPC_PRECRQ_RS_PH_W
:
12933 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12935 case OPC_PRECRQU_S_QB_PH
:
12937 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12941 #ifdef TARGET_MIPS64
12942 case OPC_ABSQ_S_QH_DSP
:
12944 case OPC_PRECEQ_L_PWL
:
12946 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
12948 case OPC_PRECEQ_L_PWR
:
12950 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
12952 case OPC_PRECEQ_PW_QHL
:
12954 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
12956 case OPC_PRECEQ_PW_QHR
:
12958 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
12960 case OPC_PRECEQ_PW_QHLA
:
12962 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
12964 case OPC_PRECEQ_PW_QHRA
:
12966 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
12968 case OPC_PRECEQU_QH_OBL
:
12970 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
12972 case OPC_PRECEQU_QH_OBR
:
12974 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
12976 case OPC_PRECEQU_QH_OBLA
:
12978 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
12980 case OPC_PRECEQU_QH_OBRA
:
12982 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
12984 case OPC_PRECEU_QH_OBL
:
12986 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
12988 case OPC_PRECEU_QH_OBR
:
12990 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
12992 case OPC_PRECEU_QH_OBLA
:
12994 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
12996 case OPC_PRECEU_QH_OBRA
:
12998 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
13000 case OPC_ABSQ_S_OB
:
13002 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
13004 case OPC_ABSQ_S_PW
:
13006 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
13008 case OPC_ABSQ_S_QH
:
13010 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
13014 case OPC_ADDU_OB_DSP
:
13016 case OPC_RADDU_L_OB
:
13018 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
13022 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13024 case OPC_SUBQ_S_PW
:
13026 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13030 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13032 case OPC_SUBQ_S_QH
:
13034 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13038 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13040 case OPC_SUBU_S_OB
:
13042 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13046 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13048 case OPC_SUBU_S_QH
:
13050 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13054 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13056 case OPC_SUBUH_R_OB
:
13058 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13062 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13064 case OPC_ADDQ_S_PW
:
13066 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13070 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13072 case OPC_ADDQ_S_QH
:
13074 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13078 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13080 case OPC_ADDU_S_OB
:
13082 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13086 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13088 case OPC_ADDU_S_QH
:
13090 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13094 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13096 case OPC_ADDUH_R_OB
:
13098 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13102 case OPC_CMPU_EQ_OB_DSP
:
13104 case OPC_PRECR_OB_QH
:
13106 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13108 case OPC_PRECR_SRA_QH_PW
:
13111 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13112 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13113 tcg_temp_free_i32(ret_t
);
13116 case OPC_PRECR_SRA_R_QH_PW
:
13119 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13120 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13121 tcg_temp_free_i32(sa_v
);
13124 case OPC_PRECRQ_OB_QH
:
13126 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13128 case OPC_PRECRQ_PW_L
:
13130 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13132 case OPC_PRECRQ_QH_PW
:
13134 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13136 case OPC_PRECRQ_RS_QH_PW
:
13138 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13140 case OPC_PRECRQU_S_OB_QH
:
13142 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13149 tcg_temp_free(v1_t
);
13150 tcg_temp_free(v2_t
);
13152 (void)opn
; /* avoid a compiler warning */
13153 MIPS_DEBUG("%s", opn
);
13156 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13157 int ret
, int v1
, int v2
)
13160 const char *opn
= "mipsdsp shift";
13166 /* Treat as NOP. */
13171 t0
= tcg_temp_new();
13172 v1_t
= tcg_temp_new();
13173 v2_t
= tcg_temp_new();
13175 tcg_gen_movi_tl(t0
, v1
);
13176 gen_load_gpr(v1_t
, v1
);
13177 gen_load_gpr(v2_t
, v2
);
13180 case OPC_SHLL_QB_DSP
:
13182 op2
= MASK_SHLL_QB(ctx
->opcode
);
13186 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13190 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13194 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13198 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13200 case OPC_SHLL_S_PH
:
13202 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13204 case OPC_SHLLV_S_PH
:
13206 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13210 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13212 case OPC_SHLLV_S_W
:
13214 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13218 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13222 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13226 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13230 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13234 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13236 case OPC_SHRA_R_QB
:
13238 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13242 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13244 case OPC_SHRAV_R_QB
:
13246 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13250 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13252 case OPC_SHRA_R_PH
:
13254 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13258 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13260 case OPC_SHRAV_R_PH
:
13262 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13266 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13268 case OPC_SHRAV_R_W
:
13270 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13272 default: /* Invalid */
13273 MIPS_INVAL("MASK SHLL.QB");
13274 generate_exception(ctx
, EXCP_RI
);
13279 #ifdef TARGET_MIPS64
13280 case OPC_SHLL_OB_DSP
:
13281 op2
= MASK_SHLL_OB(ctx
->opcode
);
13285 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13289 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13291 case OPC_SHLL_S_PW
:
13293 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13295 case OPC_SHLLV_S_PW
:
13297 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13301 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13305 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13309 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13313 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13315 case OPC_SHLL_S_QH
:
13317 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13319 case OPC_SHLLV_S_QH
:
13321 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13325 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13329 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13331 case OPC_SHRA_R_OB
:
13333 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13335 case OPC_SHRAV_R_OB
:
13337 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13341 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13345 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13347 case OPC_SHRA_R_PW
:
13349 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13351 case OPC_SHRAV_R_PW
:
13353 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13357 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13361 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13363 case OPC_SHRA_R_QH
:
13365 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13367 case OPC_SHRAV_R_QH
:
13369 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13373 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13377 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13381 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13385 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13387 default: /* Invalid */
13388 MIPS_INVAL("MASK SHLL.OB");
13389 generate_exception(ctx
, EXCP_RI
);
13397 tcg_temp_free(v1_t
);
13398 tcg_temp_free(v2_t
);
13399 (void)opn
; /* avoid a compiler warning */
13400 MIPS_DEBUG("%s", opn
);
13403 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13404 int ret
, int v1
, int v2
, int check_ret
)
13406 const char *opn
= "mipsdsp multiply";
13411 if ((ret
== 0) && (check_ret
== 1)) {
13412 /* Treat as NOP. */
13417 t0
= tcg_temp_new_i32();
13418 v1_t
= tcg_temp_new();
13419 v2_t
= tcg_temp_new();
13421 tcg_gen_movi_i32(t0
, ret
);
13422 gen_load_gpr(v1_t
, v1
);
13423 gen_load_gpr(v2_t
, v2
);
13426 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13427 * the same mask and op1. */
13428 case OPC_MULT_G_2E
:
13431 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13434 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13437 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13439 case OPC_MULQ_RS_W
:
13440 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13444 case OPC_DPA_W_PH_DSP
:
13446 case OPC_DPAU_H_QBL
:
13448 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13450 case OPC_DPAU_H_QBR
:
13452 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13454 case OPC_DPSU_H_QBL
:
13456 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13458 case OPC_DPSU_H_QBR
:
13460 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13464 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13466 case OPC_DPAX_W_PH
:
13468 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13470 case OPC_DPAQ_S_W_PH
:
13472 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13474 case OPC_DPAQX_S_W_PH
:
13476 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13478 case OPC_DPAQX_SA_W_PH
:
13480 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13484 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13486 case OPC_DPSX_W_PH
:
13488 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13490 case OPC_DPSQ_S_W_PH
:
13492 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13494 case OPC_DPSQX_S_W_PH
:
13496 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13498 case OPC_DPSQX_SA_W_PH
:
13500 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13502 case OPC_MULSAQ_S_W_PH
:
13504 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13506 case OPC_DPAQ_SA_L_W
:
13508 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13510 case OPC_DPSQ_SA_L_W
:
13512 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13514 case OPC_MAQ_S_W_PHL
:
13516 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13518 case OPC_MAQ_S_W_PHR
:
13520 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13522 case OPC_MAQ_SA_W_PHL
:
13524 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13526 case OPC_MAQ_SA_W_PHR
:
13528 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13530 case OPC_MULSA_W_PH
:
13532 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13536 #ifdef TARGET_MIPS64
13537 case OPC_DPAQ_W_QH_DSP
:
13539 int ac
= ret
& 0x03;
13540 tcg_gen_movi_i32(t0
, ac
);
13545 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13549 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13553 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13557 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13561 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13563 case OPC_DPAQ_S_W_QH
:
13565 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13567 case OPC_DPAQ_SA_L_PW
:
13569 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13571 case OPC_DPAU_H_OBL
:
13573 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13575 case OPC_DPAU_H_OBR
:
13577 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13581 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13583 case OPC_DPSQ_S_W_QH
:
13585 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13587 case OPC_DPSQ_SA_L_PW
:
13589 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13591 case OPC_DPSU_H_OBL
:
13593 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13595 case OPC_DPSU_H_OBR
:
13597 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13599 case OPC_MAQ_S_L_PWL
:
13601 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13603 case OPC_MAQ_S_L_PWR
:
13605 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13607 case OPC_MAQ_S_W_QHLL
:
13609 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13611 case OPC_MAQ_SA_W_QHLL
:
13613 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13615 case OPC_MAQ_S_W_QHLR
:
13617 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13619 case OPC_MAQ_SA_W_QHLR
:
13621 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13623 case OPC_MAQ_S_W_QHRL
:
13625 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13627 case OPC_MAQ_SA_W_QHRL
:
13629 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13631 case OPC_MAQ_S_W_QHRR
:
13633 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13635 case OPC_MAQ_SA_W_QHRR
:
13637 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13639 case OPC_MULSAQ_S_L_PW
:
13641 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13643 case OPC_MULSAQ_S_W_QH
:
13645 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13651 case OPC_ADDU_QB_DSP
:
13653 case OPC_MULEU_S_PH_QBL
:
13655 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13657 case OPC_MULEU_S_PH_QBR
:
13659 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13661 case OPC_MULQ_RS_PH
:
13663 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13665 case OPC_MULEQ_S_W_PHL
:
13667 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13669 case OPC_MULEQ_S_W_PHR
:
13671 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13673 case OPC_MULQ_S_PH
:
13675 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13679 #ifdef TARGET_MIPS64
13680 case OPC_ADDU_OB_DSP
:
13682 case OPC_MULEQ_S_PW_QHL
:
13684 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13686 case OPC_MULEQ_S_PW_QHR
:
13688 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13690 case OPC_MULEU_S_QH_OBL
:
13692 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13694 case OPC_MULEU_S_QH_OBR
:
13696 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13698 case OPC_MULQ_RS_QH
:
13700 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13707 tcg_temp_free_i32(t0
);
13708 tcg_temp_free(v1_t
);
13709 tcg_temp_free(v2_t
);
13711 (void)opn
; /* avoid a compiler warning */
13712 MIPS_DEBUG("%s", opn
);
13716 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13719 const char *opn
= "mipsdsp Bit/ Manipulation";
13725 /* Treat as NOP. */
13730 t0
= tcg_temp_new();
13731 val_t
= tcg_temp_new();
13732 gen_load_gpr(val_t
, val
);
13735 case OPC_ABSQ_S_PH_DSP
:
13739 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13744 target_long result
;
13745 imm
= (ctx
->opcode
>> 16) & 0xFF;
13746 result
= (uint32_t)imm
<< 24 |
13747 (uint32_t)imm
<< 16 |
13748 (uint32_t)imm
<< 8 |
13750 result
= (int32_t)result
;
13751 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13756 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13757 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13758 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13759 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13760 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13761 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13766 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13767 imm
= (int16_t)(imm
<< 6) >> 6;
13768 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13769 (target_long
)((int32_t)imm
<< 16 | \
13775 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13776 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13777 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13778 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13782 #ifdef TARGET_MIPS64
13783 case OPC_ABSQ_S_QH_DSP
:
13790 imm
= (ctx
->opcode
>> 16) & 0xFF;
13791 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13792 temp
= (temp
<< 16) | temp
;
13793 temp
= (temp
<< 32) | temp
;
13794 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13802 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13803 imm
= (int16_t)(imm
<< 6) >> 6;
13804 temp
= ((target_long
)imm
<< 32) \
13805 | ((target_long
)imm
& 0xFFFFFFFF);
13806 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13814 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13815 imm
= (int16_t)(imm
<< 6) >> 6;
13817 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13818 ((uint64_t)(uint16_t)imm
<< 32) |
13819 ((uint64_t)(uint16_t)imm
<< 16) |
13820 (uint64_t)(uint16_t)imm
;
13821 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13826 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13827 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13828 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13829 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13830 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13831 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13832 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13836 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13837 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13838 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13842 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13843 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13844 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13845 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13846 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13853 tcg_temp_free(val_t
);
13855 (void)opn
; /* avoid a compiler warning */
13856 MIPS_DEBUG("%s", opn
);
13859 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13860 uint32_t op1
, uint32_t op2
,
13861 int ret
, int v1
, int v2
, int check_ret
)
13863 const char *opn
= "mipsdsp add compare pick";
13868 if ((ret
== 0) && (check_ret
== 1)) {
13869 /* Treat as NOP. */
13874 t1
= tcg_temp_new();
13875 v1_t
= tcg_temp_new();
13876 v2_t
= tcg_temp_new();
13878 gen_load_gpr(v1_t
, v1
);
13879 gen_load_gpr(v2_t
, v2
);
13882 case OPC_CMPU_EQ_QB_DSP
:
13884 case OPC_CMPU_EQ_QB
:
13886 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13888 case OPC_CMPU_LT_QB
:
13890 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13892 case OPC_CMPU_LE_QB
:
13894 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13896 case OPC_CMPGU_EQ_QB
:
13898 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13900 case OPC_CMPGU_LT_QB
:
13902 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13904 case OPC_CMPGU_LE_QB
:
13906 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13908 case OPC_CMPGDU_EQ_QB
:
13910 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13911 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13912 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13913 tcg_gen_shli_tl(t1
, t1
, 24);
13914 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13916 case OPC_CMPGDU_LT_QB
:
13918 gen_helper_cmpgu_lt_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_LE_QB
:
13926 gen_helper_cmpgu_le_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_CMP_EQ_PH
:
13934 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
13936 case OPC_CMP_LT_PH
:
13938 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
13940 case OPC_CMP_LE_PH
:
13942 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
13946 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13950 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13952 case OPC_PACKRL_PH
:
13954 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13958 #ifdef TARGET_MIPS64
13959 case OPC_CMPU_EQ_OB_DSP
:
13961 case OPC_CMP_EQ_PW
:
13963 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
13965 case OPC_CMP_LT_PW
:
13967 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
13969 case OPC_CMP_LE_PW
:
13971 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
13973 case OPC_CMP_EQ_QH
:
13975 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
13977 case OPC_CMP_LT_QH
:
13979 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
13981 case OPC_CMP_LE_QH
:
13983 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
13985 case OPC_CMPGDU_EQ_OB
:
13987 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13989 case OPC_CMPGDU_LT_OB
:
13991 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13993 case OPC_CMPGDU_LE_OB
:
13995 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13997 case OPC_CMPGU_EQ_OB
:
13999 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14001 case OPC_CMPGU_LT_OB
:
14003 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14005 case OPC_CMPGU_LE_OB
:
14007 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14009 case OPC_CMPU_EQ_OB
:
14011 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
14013 case OPC_CMPU_LT_OB
:
14015 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
14017 case OPC_CMPU_LE_OB
:
14019 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
14021 case OPC_PACKRL_PW
:
14023 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14027 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14031 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14035 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14043 tcg_temp_free(v1_t
);
14044 tcg_temp_free(v2_t
);
14046 (void)opn
; /* avoid a compiler warning */
14047 MIPS_DEBUG("%s", opn
);
14050 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14051 uint32_t op1
, int rt
, int rs
, int sa
)
14053 const char *opn
= "mipsdsp append/dappend";
14059 /* Treat as NOP. */
14064 t0
= tcg_temp_new();
14065 gen_load_gpr(t0
, rs
);
14068 case OPC_APPEND_DSP
:
14069 switch (MASK_APPEND(ctx
->opcode
)) {
14072 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14074 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14078 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14079 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14080 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14081 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14083 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14087 if (sa
!= 0 && sa
!= 2) {
14088 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14089 tcg_gen_ext32u_tl(t0
, t0
);
14090 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14091 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14093 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14095 default: /* Invalid */
14096 MIPS_INVAL("MASK APPEND");
14097 generate_exception(ctx
, EXCP_RI
);
14101 #ifdef TARGET_MIPS64
14102 case OPC_DAPPEND_DSP
:
14103 switch (MASK_DAPPEND(ctx
->opcode
)) {
14106 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14110 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14111 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14112 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14116 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14117 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14118 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14123 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14124 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14125 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14126 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14129 default: /* Invalid */
14130 MIPS_INVAL("MASK DAPPEND");
14131 generate_exception(ctx
, EXCP_RI
);
14138 (void)opn
; /* avoid a compiler warning */
14139 MIPS_DEBUG("%s", opn
);
14142 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14143 int ret
, int v1
, int v2
, int check_ret
)
14146 const char *opn
= "mipsdsp accumulator";
14153 if ((ret
== 0) && (check_ret
== 1)) {
14154 /* Treat as NOP. */
14159 t0
= tcg_temp_new();
14160 t1
= tcg_temp_new();
14161 v1_t
= tcg_temp_new();
14162 v2_t
= tcg_temp_new();
14164 gen_load_gpr(v1_t
, v1
);
14165 gen_load_gpr(v2_t
, v2
);
14168 case OPC_EXTR_W_DSP
:
14172 tcg_gen_movi_tl(t0
, v2
);
14173 tcg_gen_movi_tl(t1
, v1
);
14174 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14177 tcg_gen_movi_tl(t0
, v2
);
14178 tcg_gen_movi_tl(t1
, v1
);
14179 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14181 case OPC_EXTR_RS_W
:
14182 tcg_gen_movi_tl(t0
, v2
);
14183 tcg_gen_movi_tl(t1
, v1
);
14184 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14187 tcg_gen_movi_tl(t0
, v2
);
14188 tcg_gen_movi_tl(t1
, v1
);
14189 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14191 case OPC_EXTRV_S_H
:
14192 tcg_gen_movi_tl(t0
, v2
);
14193 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14196 tcg_gen_movi_tl(t0
, v2
);
14197 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14199 case OPC_EXTRV_R_W
:
14200 tcg_gen_movi_tl(t0
, v2
);
14201 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14203 case OPC_EXTRV_RS_W
:
14204 tcg_gen_movi_tl(t0
, v2
);
14205 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14208 tcg_gen_movi_tl(t0
, v2
);
14209 tcg_gen_movi_tl(t1
, v1
);
14210 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14213 tcg_gen_movi_tl(t0
, v2
);
14214 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14217 tcg_gen_movi_tl(t0
, v2
);
14218 tcg_gen_movi_tl(t1
, v1
);
14219 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14222 tcg_gen_movi_tl(t0
, v2
);
14223 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14226 imm
= (ctx
->opcode
>> 20) & 0x3F;
14227 tcg_gen_movi_tl(t0
, ret
);
14228 tcg_gen_movi_tl(t1
, imm
);
14229 gen_helper_shilo(t0
, t1
, cpu_env
);
14232 tcg_gen_movi_tl(t0
, ret
);
14233 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14236 tcg_gen_movi_tl(t0
, ret
);
14237 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14240 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14241 tcg_gen_movi_tl(t0
, imm
);
14242 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14245 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14246 tcg_gen_movi_tl(t0
, imm
);
14247 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14251 #ifdef TARGET_MIPS64
14252 case OPC_DEXTR_W_DSP
:
14256 tcg_gen_movi_tl(t0
, ret
);
14257 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14261 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14262 int ac
= (ctx
->opcode
>> 11) & 0x03;
14263 tcg_gen_movi_tl(t0
, shift
);
14264 tcg_gen_movi_tl(t1
, ac
);
14265 gen_helper_dshilo(t0
, t1
, cpu_env
);
14270 int ac
= (ctx
->opcode
>> 11) & 0x03;
14271 tcg_gen_movi_tl(t0
, ac
);
14272 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14276 tcg_gen_movi_tl(t0
, v2
);
14277 tcg_gen_movi_tl(t1
, v1
);
14279 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14282 tcg_gen_movi_tl(t0
, v2
);
14283 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14286 tcg_gen_movi_tl(t0
, v2
);
14287 tcg_gen_movi_tl(t1
, v1
);
14288 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14291 tcg_gen_movi_tl(t0
, v2
);
14292 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14295 tcg_gen_movi_tl(t0
, v2
);
14296 tcg_gen_movi_tl(t1
, v1
);
14297 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14299 case OPC_DEXTR_R_L
:
14300 tcg_gen_movi_tl(t0
, v2
);
14301 tcg_gen_movi_tl(t1
, v1
);
14302 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14304 case OPC_DEXTR_RS_L
:
14305 tcg_gen_movi_tl(t0
, v2
);
14306 tcg_gen_movi_tl(t1
, v1
);
14307 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14310 tcg_gen_movi_tl(t0
, v2
);
14311 tcg_gen_movi_tl(t1
, v1
);
14312 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14314 case OPC_DEXTR_R_W
:
14315 tcg_gen_movi_tl(t0
, v2
);
14316 tcg_gen_movi_tl(t1
, v1
);
14317 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14319 case OPC_DEXTR_RS_W
:
14320 tcg_gen_movi_tl(t0
, v2
);
14321 tcg_gen_movi_tl(t1
, v1
);
14322 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14324 case OPC_DEXTR_S_H
:
14325 tcg_gen_movi_tl(t0
, v2
);
14326 tcg_gen_movi_tl(t1
, v1
);
14327 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14329 case OPC_DEXTRV_S_H
:
14330 tcg_gen_movi_tl(t0
, v2
);
14331 tcg_gen_movi_tl(t1
, v1
);
14332 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14335 tcg_gen_movi_tl(t0
, v2
);
14336 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14338 case OPC_DEXTRV_R_L
:
14339 tcg_gen_movi_tl(t0
, v2
);
14340 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14342 case OPC_DEXTRV_RS_L
:
14343 tcg_gen_movi_tl(t0
, v2
);
14344 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14347 tcg_gen_movi_tl(t0
, v2
);
14348 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14350 case OPC_DEXTRV_R_W
:
14351 tcg_gen_movi_tl(t0
, v2
);
14352 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14354 case OPC_DEXTRV_RS_W
:
14355 tcg_gen_movi_tl(t0
, v2
);
14356 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14365 tcg_temp_free(v1_t
);
14366 tcg_temp_free(v2_t
);
14368 (void)opn
; /* avoid a compiler warning */
14369 MIPS_DEBUG("%s", opn
);
14372 /* End MIPSDSP functions. */
14374 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
, int *is_branch
)
14377 int rs
, rt
, rd
, sa
;
14378 uint32_t op
, op1
, op2
;
14381 /* make sure instructions are on a word boundary */
14382 if (ctx
->pc
& 0x3) {
14383 env
->CP0_BadVAddr
= ctx
->pc
;
14384 generate_exception(ctx
, EXCP_AdEL
);
14388 /* Handle blikely not taken case */
14389 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14390 int l1
= gen_new_label();
14392 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14393 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14394 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14395 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14399 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14400 tcg_gen_debug_insn_start(ctx
->pc
);
14403 op
= MASK_OP_MAJOR(ctx
->opcode
);
14404 rs
= (ctx
->opcode
>> 21) & 0x1f;
14405 rt
= (ctx
->opcode
>> 16) & 0x1f;
14406 rd
= (ctx
->opcode
>> 11) & 0x1f;
14407 sa
= (ctx
->opcode
>> 6) & 0x1f;
14408 imm
= (int16_t)ctx
->opcode
;
14411 op1
= MASK_SPECIAL(ctx
->opcode
);
14413 case OPC_SLL
: /* Shift with immediate */
14415 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14418 switch ((ctx
->opcode
>> 21) & 0x1f) {
14420 /* rotr is decoded as srl on non-R2 CPUs */
14421 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14426 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14429 generate_exception(ctx
, EXCP_RI
);
14433 case OPC_MOVN
: /* Conditional move */
14435 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14436 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14437 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14439 case OPC_ADD
... OPC_SUBU
:
14440 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14442 case OPC_SLLV
: /* Shifts */
14444 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14447 switch ((ctx
->opcode
>> 6) & 0x1f) {
14449 /* rotrv is decoded as srlv on non-R2 CPUs */
14450 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14455 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14458 generate_exception(ctx
, EXCP_RI
);
14462 case OPC_SLT
: /* Set on less than */
14464 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14466 case OPC_AND
: /* Logic*/
14470 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14472 case OPC_MULT
... OPC_DIVU
:
14474 check_insn(ctx
, INSN_VR54XX
);
14475 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14476 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14478 gen_muldiv(ctx
, op1
, rs
, rt
);
14480 case OPC_JR
... OPC_JALR
:
14481 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14484 case OPC_TGE
... OPC_TEQ
: /* Traps */
14486 gen_trap(ctx
, op1
, rs
, rt
, -1);
14488 case OPC_MFHI
: /* Move from HI/LO */
14490 gen_HILO(ctx
, op1
, rd
);
14493 case OPC_MTLO
: /* Move to HI/LO */
14494 gen_HILO(ctx
, op1
, rs
);
14496 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14497 #ifdef MIPS_STRICT_STANDARD
14498 MIPS_INVAL("PMON / selsl");
14499 generate_exception(ctx
, EXCP_RI
);
14501 gen_helper_0e0i(pmon
, sa
);
14505 generate_exception(ctx
, EXCP_SYSCALL
);
14506 ctx
->bstate
= BS_STOP
;
14509 generate_exception(ctx
, EXCP_BREAK
);
14512 #ifdef MIPS_STRICT_STANDARD
14513 MIPS_INVAL("SPIM");
14514 generate_exception(ctx
, EXCP_RI
);
14516 /* Implemented as RI exception for now. */
14517 MIPS_INVAL("spim (unofficial)");
14518 generate_exception(ctx
, EXCP_RI
);
14522 /* Treat as NOP. */
14526 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14527 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14528 check_cp1_enabled(ctx
);
14529 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14530 (ctx
->opcode
>> 16) & 1);
14532 generate_exception_err(ctx
, EXCP_CpU
, 1);
14536 #if defined(TARGET_MIPS64)
14537 /* MIPS64 specific opcodes */
14542 check_insn(ctx
, ISA_MIPS3
);
14543 check_mips_64(ctx
);
14544 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14547 switch ((ctx
->opcode
>> 21) & 0x1f) {
14549 /* drotr is decoded as dsrl on non-R2 CPUs */
14550 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14555 check_insn(ctx
, ISA_MIPS3
);
14556 check_mips_64(ctx
);
14557 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14560 generate_exception(ctx
, EXCP_RI
);
14565 switch ((ctx
->opcode
>> 21) & 0x1f) {
14567 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14568 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14573 check_insn(ctx
, ISA_MIPS3
);
14574 check_mips_64(ctx
);
14575 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14578 generate_exception(ctx
, EXCP_RI
);
14582 case OPC_DADD
... OPC_DSUBU
:
14583 check_insn(ctx
, ISA_MIPS3
);
14584 check_mips_64(ctx
);
14585 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14589 check_insn(ctx
, ISA_MIPS3
);
14590 check_mips_64(ctx
);
14591 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14594 switch ((ctx
->opcode
>> 6) & 0x1f) {
14596 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14597 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14602 check_insn(ctx
, ISA_MIPS3
);
14603 check_mips_64(ctx
);
14604 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14607 generate_exception(ctx
, EXCP_RI
);
14611 case OPC_DMULT
... OPC_DDIVU
:
14612 check_insn(ctx
, ISA_MIPS3
);
14613 check_mips_64(ctx
);
14614 gen_muldiv(ctx
, op1
, rs
, rt
);
14617 default: /* Invalid */
14618 MIPS_INVAL("special");
14619 generate_exception(ctx
, EXCP_RI
);
14624 op1
= MASK_SPECIAL2(ctx
->opcode
);
14626 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14627 case OPC_MSUB
... OPC_MSUBU
:
14628 check_insn(ctx
, ISA_MIPS32
);
14629 gen_muldiv(ctx
, op1
, rs
, rt
);
14632 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14636 check_insn(ctx
, ISA_MIPS32
);
14637 gen_cl(ctx
, op1
, rd
, rs
);
14640 /* XXX: not clear which exception should be raised
14641 * when in debug mode...
14643 check_insn(ctx
, ISA_MIPS32
);
14644 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14645 generate_exception(ctx
, EXCP_DBp
);
14647 generate_exception(ctx
, EXCP_DBp
);
14649 /* Treat as NOP. */
14652 case OPC_DIVU_G_2F
:
14653 case OPC_MULT_G_2F
:
14654 case OPC_MULTU_G_2F
:
14656 case OPC_MODU_G_2F
:
14657 check_insn(ctx
, INSN_LOONGSON2F
);
14658 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14660 #if defined(TARGET_MIPS64)
14663 check_insn(ctx
, ISA_MIPS64
);
14664 check_mips_64(ctx
);
14665 gen_cl(ctx
, op1
, rd
, rs
);
14667 case OPC_DMULT_G_2F
:
14668 case OPC_DMULTU_G_2F
:
14669 case OPC_DDIV_G_2F
:
14670 case OPC_DDIVU_G_2F
:
14671 case OPC_DMOD_G_2F
:
14672 case OPC_DMODU_G_2F
:
14673 check_insn(ctx
, INSN_LOONGSON2F
);
14674 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14677 default: /* Invalid */
14678 MIPS_INVAL("special2");
14679 generate_exception(ctx
, EXCP_RI
);
14684 op1
= MASK_SPECIAL3(ctx
->opcode
);
14688 check_insn(ctx
, ISA_MIPS32R2
);
14689 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14692 check_insn(ctx
, ISA_MIPS32R2
);
14693 op2
= MASK_BSHFL(ctx
->opcode
);
14694 gen_bshfl(ctx
, op2
, rt
, rd
);
14697 gen_rdhwr(ctx
, rt
, rd
);
14700 check_insn(ctx
, ASE_MT
);
14702 TCGv t0
= tcg_temp_new();
14703 TCGv t1
= tcg_temp_new();
14705 gen_load_gpr(t0
, rt
);
14706 gen_load_gpr(t1
, rs
);
14707 gen_helper_fork(t0
, t1
);
14713 check_insn(ctx
, ASE_MT
);
14715 TCGv t0
= tcg_temp_new();
14717 save_cpu_state(ctx
, 1);
14718 gen_load_gpr(t0
, rs
);
14719 gen_helper_yield(t0
, cpu_env
, t0
);
14720 gen_store_gpr(t0
, rd
);
14724 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14725 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14726 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14727 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14728 * the same mask and op1. */
14729 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14730 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14733 case OPC_ADDUH_R_QB
:
14735 case OPC_ADDQH_R_PH
:
14737 case OPC_ADDQH_R_W
:
14739 case OPC_SUBUH_R_QB
:
14741 case OPC_SUBQH_R_PH
:
14743 case OPC_SUBQH_R_W
:
14744 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14749 case OPC_MULQ_RS_W
:
14750 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14753 MIPS_INVAL("MASK ADDUH.QB");
14754 generate_exception(ctx
, EXCP_RI
);
14757 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14758 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14760 generate_exception(ctx
, EXCP_RI
);
14764 op2
= MASK_LX(ctx
->opcode
);
14766 #if defined(TARGET_MIPS64)
14772 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14774 default: /* Invalid */
14775 MIPS_INVAL("MASK LX");
14776 generate_exception(ctx
, EXCP_RI
);
14780 case OPC_ABSQ_S_PH_DSP
:
14781 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14783 case OPC_ABSQ_S_QB
:
14784 case OPC_ABSQ_S_PH
:
14786 case OPC_PRECEQ_W_PHL
:
14787 case OPC_PRECEQ_W_PHR
:
14788 case OPC_PRECEQU_PH_QBL
:
14789 case OPC_PRECEQU_PH_QBR
:
14790 case OPC_PRECEQU_PH_QBLA
:
14791 case OPC_PRECEQU_PH_QBRA
:
14792 case OPC_PRECEU_PH_QBL
:
14793 case OPC_PRECEU_PH_QBR
:
14794 case OPC_PRECEU_PH_QBLA
:
14795 case OPC_PRECEU_PH_QBRA
:
14796 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14803 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14806 MIPS_INVAL("MASK ABSQ_S.PH");
14807 generate_exception(ctx
, EXCP_RI
);
14811 case OPC_ADDU_QB_DSP
:
14812 op2
= MASK_ADDU_QB(ctx
->opcode
);
14815 case OPC_ADDQ_S_PH
:
14818 case OPC_ADDU_S_QB
:
14820 case OPC_ADDU_S_PH
:
14822 case OPC_SUBQ_S_PH
:
14825 case OPC_SUBU_S_QB
:
14827 case OPC_SUBU_S_PH
:
14831 case OPC_RADDU_W_QB
:
14832 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14834 case OPC_MULEU_S_PH_QBL
:
14835 case OPC_MULEU_S_PH_QBR
:
14836 case OPC_MULQ_RS_PH
:
14837 case OPC_MULEQ_S_W_PHL
:
14838 case OPC_MULEQ_S_W_PHR
:
14839 case OPC_MULQ_S_PH
:
14840 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14842 default: /* Invalid */
14843 MIPS_INVAL("MASK ADDU.QB");
14844 generate_exception(ctx
, EXCP_RI
);
14849 case OPC_CMPU_EQ_QB_DSP
:
14850 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14852 case OPC_PRECR_SRA_PH_W
:
14853 case OPC_PRECR_SRA_R_PH_W
:
14854 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14856 case OPC_PRECR_QB_PH
:
14857 case OPC_PRECRQ_QB_PH
:
14858 case OPC_PRECRQ_PH_W
:
14859 case OPC_PRECRQ_RS_PH_W
:
14860 case OPC_PRECRQU_S_QB_PH
:
14861 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14863 case OPC_CMPU_EQ_QB
:
14864 case OPC_CMPU_LT_QB
:
14865 case OPC_CMPU_LE_QB
:
14866 case OPC_CMP_EQ_PH
:
14867 case OPC_CMP_LT_PH
:
14868 case OPC_CMP_LE_PH
:
14869 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14871 case OPC_CMPGU_EQ_QB
:
14872 case OPC_CMPGU_LT_QB
:
14873 case OPC_CMPGU_LE_QB
:
14874 case OPC_CMPGDU_EQ_QB
:
14875 case OPC_CMPGDU_LT_QB
:
14876 case OPC_CMPGDU_LE_QB
:
14879 case OPC_PACKRL_PH
:
14880 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14882 default: /* Invalid */
14883 MIPS_INVAL("MASK CMPU.EQ.QB");
14884 generate_exception(ctx
, EXCP_RI
);
14888 case OPC_SHLL_QB_DSP
:
14889 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14891 case OPC_DPA_W_PH_DSP
:
14892 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14894 case OPC_DPAU_H_QBL
:
14895 case OPC_DPAU_H_QBR
:
14896 case OPC_DPSU_H_QBL
:
14897 case OPC_DPSU_H_QBR
:
14899 case OPC_DPAX_W_PH
:
14900 case OPC_DPAQ_S_W_PH
:
14901 case OPC_DPAQX_S_W_PH
:
14902 case OPC_DPAQX_SA_W_PH
:
14904 case OPC_DPSX_W_PH
:
14905 case OPC_DPSQ_S_W_PH
:
14906 case OPC_DPSQX_S_W_PH
:
14907 case OPC_DPSQX_SA_W_PH
:
14908 case OPC_MULSAQ_S_W_PH
:
14909 case OPC_DPAQ_SA_L_W
:
14910 case OPC_DPSQ_SA_L_W
:
14911 case OPC_MAQ_S_W_PHL
:
14912 case OPC_MAQ_S_W_PHR
:
14913 case OPC_MAQ_SA_W_PHL
:
14914 case OPC_MAQ_SA_W_PHR
:
14915 case OPC_MULSA_W_PH
:
14916 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14918 default: /* Invalid */
14919 MIPS_INVAL("MASK DPAW.PH");
14920 generate_exception(ctx
, EXCP_RI
);
14925 op2
= MASK_INSV(ctx
->opcode
);
14937 t0
= tcg_temp_new();
14938 t1
= tcg_temp_new();
14940 gen_load_gpr(t0
, rt
);
14941 gen_load_gpr(t1
, rs
);
14943 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
14949 default: /* Invalid */
14950 MIPS_INVAL("MASK INSV");
14951 generate_exception(ctx
, EXCP_RI
);
14955 case OPC_APPEND_DSP
:
14956 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
14958 case OPC_EXTR_W_DSP
:
14959 op2
= MASK_EXTR_W(ctx
->opcode
);
14963 case OPC_EXTR_RS_W
:
14965 case OPC_EXTRV_S_H
:
14967 case OPC_EXTRV_R_W
:
14968 case OPC_EXTRV_RS_W
:
14973 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
14976 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14982 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14984 default: /* Invalid */
14985 MIPS_INVAL("MASK EXTR.W");
14986 generate_exception(ctx
, EXCP_RI
);
14990 #if defined(TARGET_MIPS64)
14991 case OPC_DEXTM
... OPC_DEXT
:
14992 case OPC_DINSM
... OPC_DINS
:
14993 check_insn(ctx
, ISA_MIPS64R2
);
14994 check_mips_64(ctx
);
14995 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14998 check_insn(ctx
, ISA_MIPS64R2
);
14999 check_mips_64(ctx
);
15000 op2
= MASK_DBSHFL(ctx
->opcode
);
15001 gen_bshfl(ctx
, op2
, rt
, rd
);
15003 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
15004 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
15005 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
15006 check_insn(ctx
, INSN_LOONGSON2E
);
15007 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
15009 case OPC_ABSQ_S_QH_DSP
:
15010 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
15012 case OPC_PRECEQ_L_PWL
:
15013 case OPC_PRECEQ_L_PWR
:
15014 case OPC_PRECEQ_PW_QHL
:
15015 case OPC_PRECEQ_PW_QHR
:
15016 case OPC_PRECEQ_PW_QHLA
:
15017 case OPC_PRECEQ_PW_QHRA
:
15018 case OPC_PRECEQU_QH_OBL
:
15019 case OPC_PRECEQU_QH_OBR
:
15020 case OPC_PRECEQU_QH_OBLA
:
15021 case OPC_PRECEQU_QH_OBRA
:
15022 case OPC_PRECEU_QH_OBL
:
15023 case OPC_PRECEU_QH_OBR
:
15024 case OPC_PRECEU_QH_OBLA
:
15025 case OPC_PRECEU_QH_OBRA
:
15026 case OPC_ABSQ_S_OB
:
15027 case OPC_ABSQ_S_PW
:
15028 case OPC_ABSQ_S_QH
:
15029 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15037 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
15039 default: /* Invalid */
15040 MIPS_INVAL("MASK ABSQ_S.QH");
15041 generate_exception(ctx
, EXCP_RI
);
15045 case OPC_ADDU_OB_DSP
:
15046 op2
= MASK_ADDU_OB(ctx
->opcode
);
15048 case OPC_RADDU_L_OB
:
15050 case OPC_SUBQ_S_PW
:
15052 case OPC_SUBQ_S_QH
:
15054 case OPC_SUBU_S_OB
:
15056 case OPC_SUBU_S_QH
:
15058 case OPC_SUBUH_R_OB
:
15060 case OPC_ADDQ_S_PW
:
15062 case OPC_ADDQ_S_QH
:
15064 case OPC_ADDU_S_OB
:
15066 case OPC_ADDU_S_QH
:
15068 case OPC_ADDUH_R_OB
:
15069 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15071 case OPC_MULEQ_S_PW_QHL
:
15072 case OPC_MULEQ_S_PW_QHR
:
15073 case OPC_MULEU_S_QH_OBL
:
15074 case OPC_MULEU_S_QH_OBR
:
15075 case OPC_MULQ_RS_QH
:
15076 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15078 default: /* Invalid */
15079 MIPS_INVAL("MASK ADDU.OB");
15080 generate_exception(ctx
, EXCP_RI
);
15084 case OPC_CMPU_EQ_OB_DSP
:
15085 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15087 case OPC_PRECR_SRA_QH_PW
:
15088 case OPC_PRECR_SRA_R_QH_PW
:
15089 /* Return value is rt. */
15090 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15092 case OPC_PRECR_OB_QH
:
15093 case OPC_PRECRQ_OB_QH
:
15094 case OPC_PRECRQ_PW_L
:
15095 case OPC_PRECRQ_QH_PW
:
15096 case OPC_PRECRQ_RS_QH_PW
:
15097 case OPC_PRECRQU_S_OB_QH
:
15098 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15100 case OPC_CMPU_EQ_OB
:
15101 case OPC_CMPU_LT_OB
:
15102 case OPC_CMPU_LE_OB
:
15103 case OPC_CMP_EQ_QH
:
15104 case OPC_CMP_LT_QH
:
15105 case OPC_CMP_LE_QH
:
15106 case OPC_CMP_EQ_PW
:
15107 case OPC_CMP_LT_PW
:
15108 case OPC_CMP_LE_PW
:
15109 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15111 case OPC_CMPGDU_EQ_OB
:
15112 case OPC_CMPGDU_LT_OB
:
15113 case OPC_CMPGDU_LE_OB
:
15114 case OPC_CMPGU_EQ_OB
:
15115 case OPC_CMPGU_LT_OB
:
15116 case OPC_CMPGU_LE_OB
:
15117 case OPC_PACKRL_PW
:
15121 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15123 default: /* Invalid */
15124 MIPS_INVAL("MASK CMPU_EQ.OB");
15125 generate_exception(ctx
, EXCP_RI
);
15129 case OPC_DAPPEND_DSP
:
15130 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15132 case OPC_DEXTR_W_DSP
:
15133 op2
= MASK_DEXTR_W(ctx
->opcode
);
15140 case OPC_DEXTR_R_L
:
15141 case OPC_DEXTR_RS_L
:
15143 case OPC_DEXTR_R_W
:
15144 case OPC_DEXTR_RS_W
:
15145 case OPC_DEXTR_S_H
:
15147 case OPC_DEXTRV_R_L
:
15148 case OPC_DEXTRV_RS_L
:
15149 case OPC_DEXTRV_S_H
:
15151 case OPC_DEXTRV_R_W
:
15152 case OPC_DEXTRV_RS_W
:
15153 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15158 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15160 default: /* Invalid */
15161 MIPS_INVAL("MASK EXTR.W");
15162 generate_exception(ctx
, EXCP_RI
);
15166 case OPC_DPAQ_W_QH_DSP
:
15167 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15169 case OPC_DPAU_H_OBL
:
15170 case OPC_DPAU_H_OBR
:
15171 case OPC_DPSU_H_OBL
:
15172 case OPC_DPSU_H_OBR
:
15174 case OPC_DPAQ_S_W_QH
:
15176 case OPC_DPSQ_S_W_QH
:
15177 case OPC_MULSAQ_S_W_QH
:
15178 case OPC_DPAQ_SA_L_PW
:
15179 case OPC_DPSQ_SA_L_PW
:
15180 case OPC_MULSAQ_S_L_PW
:
15181 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15183 case OPC_MAQ_S_W_QHLL
:
15184 case OPC_MAQ_S_W_QHLR
:
15185 case OPC_MAQ_S_W_QHRL
:
15186 case OPC_MAQ_S_W_QHRR
:
15187 case OPC_MAQ_SA_W_QHLL
:
15188 case OPC_MAQ_SA_W_QHLR
:
15189 case OPC_MAQ_SA_W_QHRL
:
15190 case OPC_MAQ_SA_W_QHRR
:
15191 case OPC_MAQ_S_L_PWL
:
15192 case OPC_MAQ_S_L_PWR
:
15197 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15199 default: /* Invalid */
15200 MIPS_INVAL("MASK DPAQ.W.QH");
15201 generate_exception(ctx
, EXCP_RI
);
15205 case OPC_DINSV_DSP
:
15206 op2
= MASK_INSV(ctx
->opcode
);
15218 t0
= tcg_temp_new();
15219 t1
= tcg_temp_new();
15221 gen_load_gpr(t0
, rt
);
15222 gen_load_gpr(t1
, rs
);
15224 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15227 default: /* Invalid */
15228 MIPS_INVAL("MASK DINSV");
15229 generate_exception(ctx
, EXCP_RI
);
15233 case OPC_SHLL_OB_DSP
:
15234 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15237 default: /* Invalid */
15238 MIPS_INVAL("special3");
15239 generate_exception(ctx
, EXCP_RI
);
15244 op1
= MASK_REGIMM(ctx
->opcode
);
15246 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15247 case OPC_BLTZAL
... OPC_BGEZALL
:
15248 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15251 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15253 gen_trap(ctx
, op1
, rs
, -1, imm
);
15256 check_insn(ctx
, ISA_MIPS32R2
);
15257 /* Treat as NOP. */
15259 case OPC_BPOSGE32
: /* MIPS DSP branch */
15260 #if defined(TARGET_MIPS64)
15264 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15267 default: /* Invalid */
15268 MIPS_INVAL("regimm");
15269 generate_exception(ctx
, EXCP_RI
);
15274 check_cp0_enabled(ctx
);
15275 op1
= MASK_CP0(ctx
->opcode
);
15281 #if defined(TARGET_MIPS64)
15285 #ifndef CONFIG_USER_ONLY
15286 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15287 #endif /* !CONFIG_USER_ONLY */
15289 case OPC_C0_FIRST
... OPC_C0_LAST
:
15290 #ifndef CONFIG_USER_ONLY
15291 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15292 #endif /* !CONFIG_USER_ONLY */
15295 #ifndef CONFIG_USER_ONLY
15297 TCGv t0
= tcg_temp_new();
15299 op2
= MASK_MFMC0(ctx
->opcode
);
15302 check_insn(ctx
, ASE_MT
);
15303 gen_helper_dmt(t0
);
15304 gen_store_gpr(t0
, rt
);
15307 check_insn(ctx
, ASE_MT
);
15308 gen_helper_emt(t0
);
15309 gen_store_gpr(t0
, rt
);
15312 check_insn(ctx
, ASE_MT
);
15313 gen_helper_dvpe(t0
, cpu_env
);
15314 gen_store_gpr(t0
, rt
);
15317 check_insn(ctx
, ASE_MT
);
15318 gen_helper_evpe(t0
, cpu_env
);
15319 gen_store_gpr(t0
, rt
);
15322 check_insn(ctx
, ISA_MIPS32R2
);
15323 save_cpu_state(ctx
, 1);
15324 gen_helper_di(t0
, cpu_env
);
15325 gen_store_gpr(t0
, rt
);
15326 /* Stop translation as we may have switched the execution mode */
15327 ctx
->bstate
= BS_STOP
;
15330 check_insn(ctx
, ISA_MIPS32R2
);
15331 save_cpu_state(ctx
, 1);
15332 gen_helper_ei(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
;
15337 default: /* Invalid */
15338 MIPS_INVAL("mfmc0");
15339 generate_exception(ctx
, EXCP_RI
);
15344 #endif /* !CONFIG_USER_ONLY */
15347 check_insn(ctx
, ISA_MIPS32R2
);
15348 gen_load_srsgpr(rt
, rd
);
15351 check_insn(ctx
, ISA_MIPS32R2
);
15352 gen_store_srsgpr(rt
, rd
);
15356 generate_exception(ctx
, EXCP_RI
);
15360 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15362 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15364 case OPC_SLTI
: /* Set on less than with immediate opcode */
15366 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15368 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15372 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15374 case OPC_J
... OPC_JAL
: /* Jump */
15375 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15376 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15379 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15380 case OPC_BEQL
... OPC_BGTZL
:
15381 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15384 case OPC_LB
... OPC_LWR
: /* Load and stores */
15386 gen_ld(ctx
, op
, rt
, rs
, imm
);
15388 case OPC_SB
... OPC_SW
:
15390 gen_st(ctx
, op
, rt
, rs
, imm
);
15393 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15396 check_cp0_enabled(ctx
);
15397 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15398 /* Treat as NOP. */
15401 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15402 /* Treat as NOP. */
15405 /* Floating point (COP1). */
15410 gen_cop1_ldst(env
, ctx
, op
, rt
, rs
, imm
);
15414 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15415 check_cp1_enabled(ctx
);
15416 op1
= MASK_CP1(ctx
->opcode
);
15420 check_insn(ctx
, ISA_MIPS32R2
);
15425 gen_cp1(ctx
, op1
, rt
, rd
);
15427 #if defined(TARGET_MIPS64)
15430 check_insn(ctx
, ISA_MIPS3
);
15431 gen_cp1(ctx
, op1
, rt
, rd
);
15437 check_insn(ctx
, ASE_MIPS3D
);
15440 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15441 (rt
>> 2) & 0x7, imm
<< 2);
15449 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15454 generate_exception (ctx
, EXCP_RI
);
15458 generate_exception_err(ctx
, EXCP_CpU
, 1);
15467 /* COP2: Not implemented. */
15468 generate_exception_err(ctx
, EXCP_CpU
, 2);
15471 check_insn(ctx
, INSN_LOONGSON2F
);
15472 /* Note that these instructions use different fields. */
15473 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15477 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15478 check_cp1_enabled(ctx
);
15479 op1
= MASK_CP3(ctx
->opcode
);
15487 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15490 /* Treat as NOP. */
15505 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15509 generate_exception (ctx
, EXCP_RI
);
15513 generate_exception_err(ctx
, EXCP_CpU
, 1);
15517 #if defined(TARGET_MIPS64)
15518 /* MIPS64 opcodes */
15520 case OPC_LDL
... OPC_LDR
:
15523 check_insn(ctx
, ISA_MIPS3
);
15524 check_mips_64(ctx
);
15525 gen_ld(ctx
, op
, rt
, rs
, imm
);
15527 case OPC_SDL
... OPC_SDR
:
15529 check_insn(ctx
, ISA_MIPS3
);
15530 check_mips_64(ctx
);
15531 gen_st(ctx
, op
, rt
, rs
, imm
);
15534 check_insn(ctx
, ISA_MIPS3
);
15535 check_mips_64(ctx
);
15536 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15540 check_insn(ctx
, ISA_MIPS3
);
15541 check_mips_64(ctx
);
15542 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15546 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15547 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15548 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15552 check_insn(ctx
, ASE_MDMX
);
15553 /* MDMX: Not implemented. */
15554 default: /* Invalid */
15555 MIPS_INVAL("major opcode");
15556 generate_exception(ctx
, EXCP_RI
);
15562 gen_intermediate_code_internal (CPUMIPSState
*env
, TranslationBlock
*tb
,
15566 target_ulong pc_start
;
15567 uint16_t *gen_opc_end
;
15576 qemu_log("search pc %d\n", search_pc
);
15579 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15582 ctx
.singlestep_enabled
= env
->singlestep_enabled
;
15583 ctx
.insn_flags
= env
->insn_flags
;
15585 ctx
.bstate
= BS_NONE
;
15586 /* Restore delay slot state from the tb context. */
15587 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15588 restore_cpu_state(env
, &ctx
);
15589 #ifdef CONFIG_USER_ONLY
15590 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15592 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15595 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15596 if (max_insns
== 0)
15597 max_insns
= CF_COUNT_MASK
;
15598 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15599 gen_icount_start();
15600 while (ctx
.bstate
== BS_NONE
) {
15601 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
15602 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
15603 if (bp
->pc
== ctx
.pc
) {
15604 save_cpu_state(&ctx
, 1);
15605 ctx
.bstate
= BS_BRANCH
;
15606 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15607 /* Include the breakpoint location or the tb won't
15608 * be flushed when it must be. */
15610 goto done_generating
;
15616 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15620 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15622 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15623 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15624 gen_opc_btarget
[lj
] = ctx
.btarget
;
15625 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15626 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15628 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15632 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15633 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15635 decode_opc(env
, &ctx
, &is_branch
);
15636 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15637 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15638 insn_bytes
= decode_micromips_opc(env
, &ctx
, &is_branch
);
15639 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15640 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15641 insn_bytes
= decode_mips16_opc(env
, &ctx
, &is_branch
);
15643 generate_exception(&ctx
, EXCP_RI
);
15644 ctx
.bstate
= BS_STOP
;
15648 handle_delay_slot(&ctx
, insn_bytes
);
15650 ctx
.pc
+= insn_bytes
;
15654 /* Execute a branch and its delay slot as a single instruction.
15655 This is what GDB expects and is consistent with what the
15656 hardware does (e.g. if a delay slot instruction faults, the
15657 reported PC is the PC of the branch). */
15658 if (env
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0)
15661 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15664 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15668 if (num_insns
>= max_insns
)
15674 if (tb
->cflags
& CF_LAST_IO
)
15676 if (env
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15677 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15678 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15680 switch (ctx
.bstate
) {
15682 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15685 save_cpu_state(&ctx
, 0);
15686 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15689 tcg_gen_exit_tb(0);
15697 gen_icount_end(tb
, num_insns
);
15698 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15700 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15703 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15705 tb
->size
= ctx
.pc
- pc_start
;
15706 tb
->icount
= num_insns
;
15710 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15711 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15712 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15718 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15720 gen_intermediate_code_internal(env
, tb
, 0);
15723 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15725 gen_intermediate_code_internal(env
, tb
, 1);
15728 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15732 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15734 #define printfpr(fp) \
15737 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15738 " fd:%13g fs:%13g psu: %13g\n", \
15739 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15740 (double)(fp)->fd, \
15741 (double)(fp)->fs[FP_ENDIAN_IDX], \
15742 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15745 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15746 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15747 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15748 " fd:%13g fs:%13g psu:%13g\n", \
15749 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15751 (double)tmp.fs[FP_ENDIAN_IDX], \
15752 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15757 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15758 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15759 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15760 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15761 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15762 printfpr(&env
->active_fpu
.fpr
[i
]);
15768 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15769 /* Debug help: The architecture requires 32bit code to maintain proper
15770 sign-extended values on 64bit machines. */
15772 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15775 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15776 fprintf_function cpu_fprintf
,
15781 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15782 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15783 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15784 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15785 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15786 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15787 if (!SIGN_EXT_P(env
->btarget
))
15788 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15790 for (i
= 0; i
< 32; i
++) {
15791 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15792 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15795 if (!SIGN_EXT_P(env
->CP0_EPC
))
15796 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15797 if (!SIGN_EXT_P(env
->lladdr
))
15798 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15802 void cpu_dump_state (CPUMIPSState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
15807 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15808 " LO=0x" TARGET_FMT_lx
" ds %04x "
15809 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15810 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15811 env
->hflags
, env
->btarget
, env
->bcond
);
15812 for (i
= 0; i
< 32; i
++) {
15814 cpu_fprintf(f
, "GPR%02d:", i
);
15815 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15817 cpu_fprintf(f
, "\n");
15820 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15821 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15822 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15823 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15824 if (env
->hflags
& MIPS_HFLAG_FPU
)
15825 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15826 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15827 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15831 void mips_tcg_init(void)
15836 /* Initialize various static tables. */
15840 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15841 TCGV_UNUSED(cpu_gpr
[0]);
15842 for (i
= 1; i
< 32; i
++)
15843 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15844 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15847 for (i
= 0; i
< 32; i
++) {
15848 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15849 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15852 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15853 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15854 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15855 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15856 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15858 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15859 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15861 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15862 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15865 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15866 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15868 bcond
= tcg_global_mem_new(TCG_AREG0
,
15869 offsetof(CPUMIPSState
, bcond
), "bcond");
15870 btarget
= tcg_global_mem_new(TCG_AREG0
,
15871 offsetof(CPUMIPSState
, btarget
), "btarget");
15872 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15873 offsetof(CPUMIPSState
, hflags
), "hflags");
15875 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15876 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15878 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15879 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15882 /* register helpers */
15883 #define GEN_HELPER 2
15884 #include "helper.h"
15889 #include "translate_init.c"
15891 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15895 const mips_def_t
*def
;
15897 def
= cpu_mips_find_by_name(cpu_model
);
15900 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15902 env
->cpu_model
= def
;
15903 env
->cpu_model_str
= cpu_model
;
15905 #ifndef CONFIG_USER_ONLY
15906 mmu_init(env
, def
);
15908 fpu_init(env
, def
);
15909 mvp_init(env
, def
);
15911 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15916 void cpu_state_reset(CPUMIPSState
*env
)
15918 #ifndef CONFIG_USER_ONLY
15919 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
15920 CPUState
*cs
= CPU(cpu
);
15923 /* Reset registers to their default values */
15924 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15925 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15926 #ifdef TARGET_WORDS_BIGENDIAN
15927 env
->CP0_Config0
|= (1 << CP0C0_BE
);
15929 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
15930 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
15931 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
15932 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
15933 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
15934 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
15935 << env
->cpu_model
->CP0_LLAddr_shift
;
15936 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
15937 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
15938 env
->CCRes
= env
->cpu_model
->CCRes
;
15939 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
15940 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
15941 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
15942 env
->current_tc
= 0;
15943 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
15944 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
15945 #if defined(TARGET_MIPS64)
15946 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
15947 env
->SEGMask
|= 3ULL << 62;
15950 env
->PABITS
= env
->cpu_model
->PABITS
;
15951 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
15952 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
15953 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
15954 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
15955 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
15956 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
15957 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
15958 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
15959 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
15960 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
15961 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
15962 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
15963 env
->insn_flags
= env
->cpu_model
->insn_flags
;
15965 #if defined(CONFIG_USER_ONLY)
15966 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
15967 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15968 hardware registers. */
15969 env
->CP0_HWREna
|= 0x0000000F;
15970 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15971 env
->CP0_Status
|= (1 << CP0St_CU1
);
15973 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
15974 env
->CP0_Status
|= (1 << CP0St_MX
);
15977 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
15978 /* If the exception was raised from a delay slot,
15979 come back to the jump. */
15980 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
15982 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
15984 env
->active_tc
.PC
= (int32_t)0xBFC00000;
15985 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
15986 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
15987 env
->CP0_Wired
= 0;
15988 env
->CP0_EBase
= 0x80000000 | (cs
->cpu_index
& 0x3FF);
15989 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
15990 /* vectored interrupts not implemented, timer on int 7,
15991 no performance counters. */
15992 env
->CP0_IntCtl
= 0xe0000000;
15996 for (i
= 0; i
< 7; i
++) {
15997 env
->CP0_WatchLo
[i
] = 0;
15998 env
->CP0_WatchHi
[i
] = 0x80000000;
16000 env
->CP0_WatchLo
[7] = 0;
16001 env
->CP0_WatchHi
[7] = 0;
16003 /* Count register increments in debug mode, EJTAG version 1 */
16004 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
16006 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
16009 /* Only TC0 on VPE 0 starts as active. */
16010 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
16011 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
16012 env
->tcs
[i
].CP0_TCHalt
= 1;
16014 env
->active_tc
.CP0_TCHalt
= 1;
16017 if (cs
->cpu_index
== 0) {
16018 /* VPE0 starts up enabled. */
16019 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
16020 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
16022 /* TC0 starts up unhalted. */
16024 env
->active_tc
.CP0_TCHalt
= 0;
16025 env
->tcs
[0].CP0_TCHalt
= 0;
16026 /* With thread 0 active. */
16027 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
16028 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16032 compute_hflags(env
);
16033 env
->exception_index
= EXCP_NONE
;
16036 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16038 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16039 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16040 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16041 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16042 case MIPS_HFLAG_BR
:
16044 case MIPS_HFLAG_BC
:
16045 case MIPS_HFLAG_BL
:
16047 env
->btarget
= gen_opc_btarget
[pc_pos
];