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 acc
, int reg
)
2587 const char *opn
= "hilo";
2589 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2601 #if defined(TARGET_MIPS64)
2603 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2607 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2612 #if defined(TARGET_MIPS64)
2614 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2618 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2624 #if defined(TARGET_MIPS64)
2626 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2630 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2633 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2639 #if defined(TARGET_MIPS64)
2641 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2645 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2648 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2653 (void)opn
; /* avoid a compiler warning */
2654 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2657 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
2658 int acc
, int rs
, int rt
)
2660 const char *opn
= "mul/div";
2663 t0
= tcg_temp_new();
2664 t1
= tcg_temp_new();
2666 gen_load_gpr(t0
, rs
);
2667 gen_load_gpr(t1
, rt
);
2676 TCGv t2
= tcg_temp_new();
2677 TCGv t3
= tcg_temp_new();
2678 tcg_gen_ext32s_tl(t0
, t0
);
2679 tcg_gen_ext32s_tl(t1
, t1
);
2680 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2681 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2682 tcg_gen_and_tl(t2
, t2
, t3
);
2683 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2684 tcg_gen_or_tl(t2
, t2
, t3
);
2685 tcg_gen_movi_tl(t3
, 0);
2686 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2687 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2688 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2689 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2690 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2698 TCGv t2
= tcg_const_tl(0);
2699 TCGv t3
= tcg_const_tl(1);
2700 tcg_gen_ext32u_tl(t0
, t0
);
2701 tcg_gen_ext32u_tl(t1
, t1
);
2702 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2703 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
2704 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
2705 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2706 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2714 TCGv_i32 t2
= tcg_temp_new_i32();
2715 TCGv_i32 t3
= tcg_temp_new_i32();
2716 tcg_gen_trunc_tl_i32(t2
, t0
);
2717 tcg_gen_trunc_tl_i32(t3
, t1
);
2718 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
2719 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2720 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2721 tcg_temp_free_i32(t2
);
2722 tcg_temp_free_i32(t3
);
2728 TCGv_i32 t2
= tcg_temp_new_i32();
2729 TCGv_i32 t3
= tcg_temp_new_i32();
2730 tcg_gen_trunc_tl_i32(t2
, t0
);
2731 tcg_gen_trunc_tl_i32(t3
, t1
);
2732 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
2733 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2734 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2735 tcg_temp_free_i32(t2
);
2736 tcg_temp_free_i32(t3
);
2740 #if defined(TARGET_MIPS64)
2743 TCGv t2
= tcg_temp_new();
2744 TCGv t3
= tcg_temp_new();
2745 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2746 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2747 tcg_gen_and_tl(t2
, t2
, t3
);
2748 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2749 tcg_gen_or_tl(t2
, t2
, t3
);
2750 tcg_gen_movi_tl(t3
, 0);
2751 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2752 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2753 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2761 TCGv t2
= tcg_const_tl(0);
2762 TCGv t3
= tcg_const_tl(1);
2763 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2764 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
2765 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
2772 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2776 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2782 TCGv_i64 t2
= tcg_temp_new_i64();
2783 TCGv_i64 t3
= tcg_temp_new_i64();
2785 tcg_gen_ext_tl_i64(t2
, t0
);
2786 tcg_gen_ext_tl_i64(t3
, t1
);
2787 tcg_gen_mul_i64(t2
, t2
, t3
);
2788 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2789 tcg_gen_add_i64(t2
, t2
, t3
);
2790 tcg_temp_free_i64(t3
);
2791 tcg_gen_trunc_i64_tl(t0
, t2
);
2792 tcg_gen_shri_i64(t2
, t2
, 32);
2793 tcg_gen_trunc_i64_tl(t1
, t2
);
2794 tcg_temp_free_i64(t2
);
2795 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2796 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2802 TCGv_i64 t2
= tcg_temp_new_i64();
2803 TCGv_i64 t3
= tcg_temp_new_i64();
2805 tcg_gen_ext32u_tl(t0
, t0
);
2806 tcg_gen_ext32u_tl(t1
, t1
);
2807 tcg_gen_extu_tl_i64(t2
, t0
);
2808 tcg_gen_extu_tl_i64(t3
, t1
);
2809 tcg_gen_mul_i64(t2
, t2
, t3
);
2810 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2811 tcg_gen_add_i64(t2
, t2
, t3
);
2812 tcg_temp_free_i64(t3
);
2813 tcg_gen_trunc_i64_tl(t0
, t2
);
2814 tcg_gen_shri_i64(t2
, t2
, 32);
2815 tcg_gen_trunc_i64_tl(t1
, t2
);
2816 tcg_temp_free_i64(t2
);
2817 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2818 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2824 TCGv_i64 t2
= tcg_temp_new_i64();
2825 TCGv_i64 t3
= tcg_temp_new_i64();
2827 tcg_gen_ext_tl_i64(t2
, t0
);
2828 tcg_gen_ext_tl_i64(t3
, t1
);
2829 tcg_gen_mul_i64(t2
, t2
, t3
);
2830 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2831 tcg_gen_sub_i64(t2
, t3
, t2
);
2832 tcg_temp_free_i64(t3
);
2833 tcg_gen_trunc_i64_tl(t0
, t2
);
2834 tcg_gen_shri_i64(t2
, t2
, 32);
2835 tcg_gen_trunc_i64_tl(t1
, t2
);
2836 tcg_temp_free_i64(t2
);
2837 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2838 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2844 TCGv_i64 t2
= tcg_temp_new_i64();
2845 TCGv_i64 t3
= tcg_temp_new_i64();
2847 tcg_gen_ext32u_tl(t0
, t0
);
2848 tcg_gen_ext32u_tl(t1
, t1
);
2849 tcg_gen_extu_tl_i64(t2
, t0
);
2850 tcg_gen_extu_tl_i64(t3
, t1
);
2851 tcg_gen_mul_i64(t2
, t2
, t3
);
2852 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2853 tcg_gen_sub_i64(t2
, t3
, t2
);
2854 tcg_temp_free_i64(t3
);
2855 tcg_gen_trunc_i64_tl(t0
, t2
);
2856 tcg_gen_shri_i64(t2
, t2
, 32);
2857 tcg_gen_trunc_i64_tl(t1
, t2
);
2858 tcg_temp_free_i64(t2
);
2859 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2860 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2866 generate_exception(ctx
, EXCP_RI
);
2869 (void)opn
; /* avoid a compiler warning */
2870 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2876 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2877 int rd
, int rs
, int rt
)
2879 const char *opn
= "mul vr54xx";
2880 TCGv t0
= tcg_temp_new();
2881 TCGv t1
= tcg_temp_new();
2883 gen_load_gpr(t0
, rs
);
2884 gen_load_gpr(t1
, rt
);
2887 case OPC_VR54XX_MULS
:
2888 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2891 case OPC_VR54XX_MULSU
:
2892 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2895 case OPC_VR54XX_MACC
:
2896 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2899 case OPC_VR54XX_MACCU
:
2900 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2903 case OPC_VR54XX_MSAC
:
2904 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2907 case OPC_VR54XX_MSACU
:
2908 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2911 case OPC_VR54XX_MULHI
:
2912 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2915 case OPC_VR54XX_MULHIU
:
2916 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2919 case OPC_VR54XX_MULSHI
:
2920 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2923 case OPC_VR54XX_MULSHIU
:
2924 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2927 case OPC_VR54XX_MACCHI
:
2928 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2931 case OPC_VR54XX_MACCHIU
:
2932 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2935 case OPC_VR54XX_MSACHI
:
2936 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2939 case OPC_VR54XX_MSACHIU
:
2940 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2944 MIPS_INVAL("mul vr54xx");
2945 generate_exception(ctx
, EXCP_RI
);
2948 gen_store_gpr(t0
, rd
);
2949 (void)opn
; /* avoid a compiler warning */
2950 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2957 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2960 const char *opn
= "CLx";
2968 t0
= tcg_temp_new();
2969 gen_load_gpr(t0
, rs
);
2972 gen_helper_clo(cpu_gpr
[rd
], t0
);
2976 gen_helper_clz(cpu_gpr
[rd
], t0
);
2979 #if defined(TARGET_MIPS64)
2981 gen_helper_dclo(cpu_gpr
[rd
], t0
);
2985 gen_helper_dclz(cpu_gpr
[rd
], t0
);
2990 (void)opn
; /* avoid a compiler warning */
2991 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
2995 /* Godson integer instructions */
2996 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
2997 int rd
, int rs
, int rt
)
2999 const char *opn
= "loongson";
3011 case OPC_MULTU_G_2E
:
3012 case OPC_MULTU_G_2F
:
3013 #if defined(TARGET_MIPS64)
3014 case OPC_DMULT_G_2E
:
3015 case OPC_DMULT_G_2F
:
3016 case OPC_DMULTU_G_2E
:
3017 case OPC_DMULTU_G_2F
:
3019 t0
= tcg_temp_new();
3020 t1
= tcg_temp_new();
3023 t0
= tcg_temp_local_new();
3024 t1
= tcg_temp_local_new();
3028 gen_load_gpr(t0
, rs
);
3029 gen_load_gpr(t1
, rt
);
3034 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3035 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3038 case OPC_MULTU_G_2E
:
3039 case OPC_MULTU_G_2F
:
3040 tcg_gen_ext32u_tl(t0
, t0
);
3041 tcg_gen_ext32u_tl(t1
, t1
);
3042 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3043 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3049 int l1
= gen_new_label();
3050 int l2
= gen_new_label();
3051 int l3
= gen_new_label();
3052 tcg_gen_ext32s_tl(t0
, t0
);
3053 tcg_gen_ext32s_tl(t1
, t1
);
3054 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3055 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3058 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3059 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3060 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3063 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3064 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3072 int l1
= gen_new_label();
3073 int l2
= gen_new_label();
3074 tcg_gen_ext32u_tl(t0
, t0
);
3075 tcg_gen_ext32u_tl(t1
, t1
);
3076 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3077 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3080 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3081 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3089 int l1
= gen_new_label();
3090 int l2
= gen_new_label();
3091 int l3
= gen_new_label();
3092 tcg_gen_ext32u_tl(t0
, t0
);
3093 tcg_gen_ext32u_tl(t1
, t1
);
3094 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3095 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3096 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3098 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3101 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3102 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3110 int l1
= gen_new_label();
3111 int l2
= gen_new_label();
3112 tcg_gen_ext32u_tl(t0
, t0
);
3113 tcg_gen_ext32u_tl(t1
, t1
);
3114 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3115 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3118 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3119 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3124 #if defined(TARGET_MIPS64)
3125 case OPC_DMULT_G_2E
:
3126 case OPC_DMULT_G_2F
:
3127 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3130 case OPC_DMULTU_G_2E
:
3131 case OPC_DMULTU_G_2F
:
3132 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3138 int l1
= gen_new_label();
3139 int l2
= gen_new_label();
3140 int l3
= gen_new_label();
3141 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3142 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3145 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3146 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3147 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3150 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3155 case OPC_DDIVU_G_2E
:
3156 case OPC_DDIVU_G_2F
:
3158 int l1
= gen_new_label();
3159 int l2
= gen_new_label();
3160 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3161 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3164 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3172 int l1
= gen_new_label();
3173 int l2
= gen_new_label();
3174 int l3
= gen_new_label();
3175 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3176 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3177 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3179 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3182 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3187 case OPC_DMODU_G_2E
:
3188 case OPC_DMODU_G_2F
:
3190 int l1
= gen_new_label();
3191 int l2
= gen_new_label();
3192 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3193 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3196 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3204 (void)opn
; /* avoid a compiler warning */
3205 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3210 /* Loongson multimedia instructions */
3211 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3213 const char *opn
= "loongson_cp2";
3214 uint32_t opc
, shift_max
;
3217 opc
= MASK_LMI(ctx
->opcode
);
3223 t0
= tcg_temp_local_new_i64();
3224 t1
= tcg_temp_local_new_i64();
3227 t0
= tcg_temp_new_i64();
3228 t1
= tcg_temp_new_i64();
3232 gen_load_fpr64(ctx
, t0
, rs
);
3233 gen_load_fpr64(ctx
, t1
, rt
);
3235 #define LMI_HELPER(UP, LO) \
3236 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3237 #define LMI_HELPER_1(UP, LO) \
3238 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3239 #define LMI_DIRECT(UP, LO, OP) \
3240 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3243 LMI_HELPER(PADDSH
, paddsh
);
3244 LMI_HELPER(PADDUSH
, paddush
);
3245 LMI_HELPER(PADDH
, paddh
);
3246 LMI_HELPER(PADDW
, paddw
);
3247 LMI_HELPER(PADDSB
, paddsb
);
3248 LMI_HELPER(PADDUSB
, paddusb
);
3249 LMI_HELPER(PADDB
, paddb
);
3251 LMI_HELPER(PSUBSH
, psubsh
);
3252 LMI_HELPER(PSUBUSH
, psubush
);
3253 LMI_HELPER(PSUBH
, psubh
);
3254 LMI_HELPER(PSUBW
, psubw
);
3255 LMI_HELPER(PSUBSB
, psubsb
);
3256 LMI_HELPER(PSUBUSB
, psubusb
);
3257 LMI_HELPER(PSUBB
, psubb
);
3259 LMI_HELPER(PSHUFH
, pshufh
);
3260 LMI_HELPER(PACKSSWH
, packsswh
);
3261 LMI_HELPER(PACKSSHB
, packsshb
);
3262 LMI_HELPER(PACKUSHB
, packushb
);
3264 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3265 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3266 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3267 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3268 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3269 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3271 LMI_HELPER(PAVGH
, pavgh
);
3272 LMI_HELPER(PAVGB
, pavgb
);
3273 LMI_HELPER(PMAXSH
, pmaxsh
);
3274 LMI_HELPER(PMINSH
, pminsh
);
3275 LMI_HELPER(PMAXUB
, pmaxub
);
3276 LMI_HELPER(PMINUB
, pminub
);
3278 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3279 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3280 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3281 LMI_HELPER(PCMPGTH
, pcmpgth
);
3282 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3283 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3285 LMI_HELPER(PSLLW
, psllw
);
3286 LMI_HELPER(PSLLH
, psllh
);
3287 LMI_HELPER(PSRLW
, psrlw
);
3288 LMI_HELPER(PSRLH
, psrlh
);
3289 LMI_HELPER(PSRAW
, psraw
);
3290 LMI_HELPER(PSRAH
, psrah
);
3292 LMI_HELPER(PMULLH
, pmullh
);
3293 LMI_HELPER(PMULHH
, pmulhh
);
3294 LMI_HELPER(PMULHUH
, pmulhuh
);
3295 LMI_HELPER(PMADDHW
, pmaddhw
);
3297 LMI_HELPER(PASUBUB
, pasubub
);
3298 LMI_HELPER_1(BIADD
, biadd
);
3299 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3301 LMI_DIRECT(PADDD
, paddd
, add
);
3302 LMI_DIRECT(PSUBD
, psubd
, sub
);
3303 LMI_DIRECT(XOR_CP2
, xor, xor);
3304 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3305 LMI_DIRECT(AND_CP2
, and, and);
3306 LMI_DIRECT(PANDN
, pandn
, andc
);
3307 LMI_DIRECT(OR
, or, or);
3310 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3314 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3318 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3322 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3327 tcg_gen_andi_i64(t1
, t1
, 3);
3328 tcg_gen_shli_i64(t1
, t1
, 4);
3329 tcg_gen_shr_i64(t0
, t0
, t1
);
3330 tcg_gen_ext16u_i64(t0
, t0
);
3335 tcg_gen_add_i64(t0
, t0
, t1
);
3336 tcg_gen_ext32s_i64(t0
, t0
);
3340 tcg_gen_sub_i64(t0
, t0
, t1
);
3341 tcg_gen_ext32s_i64(t0
, t0
);
3370 /* Make sure shift count isn't TCG undefined behaviour. */
3371 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3376 tcg_gen_shl_i64(t0
, t0
, t1
);
3380 /* Since SRA is UndefinedResult without sign-extended inputs,
3381 we can treat SRA and DSRA the same. */
3382 tcg_gen_sar_i64(t0
, t0
, t1
);
3385 /* We want to shift in zeros for SRL; zero-extend first. */
3386 tcg_gen_ext32u_i64(t0
, t0
);
3389 tcg_gen_shr_i64(t0
, t0
, t1
);
3393 if (shift_max
== 32) {
3394 tcg_gen_ext32s_i64(t0
, t0
);
3397 /* Shifts larger than MAX produce zero. */
3398 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3399 tcg_gen_neg_i64(t1
, t1
);
3400 tcg_gen_and_i64(t0
, t0
, t1
);
3406 TCGv_i64 t2
= tcg_temp_new_i64();
3407 int lab
= gen_new_label();
3409 tcg_gen_mov_i64(t2
, t0
);
3410 tcg_gen_add_i64(t0
, t1
, t2
);
3411 if (opc
== OPC_ADD_CP2
) {
3412 tcg_gen_ext32s_i64(t0
, t0
);
3414 tcg_gen_xor_i64(t1
, t1
, t2
);
3415 tcg_gen_xor_i64(t2
, t2
, t0
);
3416 tcg_gen_andc_i64(t1
, t2
, t1
);
3417 tcg_temp_free_i64(t2
);
3418 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3419 generate_exception(ctx
, EXCP_OVERFLOW
);
3422 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3429 TCGv_i64 t2
= tcg_temp_new_i64();
3430 int lab
= gen_new_label();
3432 tcg_gen_mov_i64(t2
, t0
);
3433 tcg_gen_sub_i64(t0
, t1
, t2
);
3434 if (opc
== OPC_SUB_CP2
) {
3435 tcg_gen_ext32s_i64(t0
, t0
);
3437 tcg_gen_xor_i64(t1
, t1
, t2
);
3438 tcg_gen_xor_i64(t2
, t2
, t0
);
3439 tcg_gen_and_i64(t1
, t1
, t2
);
3440 tcg_temp_free_i64(t2
);
3441 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3442 generate_exception(ctx
, EXCP_OVERFLOW
);
3445 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3450 tcg_gen_ext32u_i64(t0
, t0
);
3451 tcg_gen_ext32u_i64(t1
, t1
);
3452 tcg_gen_mul_i64(t0
, t0
, t1
);
3462 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3463 FD field is the CC field? */
3466 generate_exception(ctx
, EXCP_RI
);
3473 gen_store_fpr64(ctx
, t0
, rd
);
3475 (void)opn
; /* avoid a compiler warning */
3476 MIPS_DEBUG("%s %s, %s, %s", opn
,
3477 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3478 tcg_temp_free_i64(t0
);
3479 tcg_temp_free_i64(t1
);
3483 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3484 int rs
, int rt
, int16_t imm
)
3487 TCGv t0
= tcg_temp_new();
3488 TCGv t1
= tcg_temp_new();
3491 /* Load needed operands */
3499 /* Compare two registers */
3501 gen_load_gpr(t0
, rs
);
3502 gen_load_gpr(t1
, rt
);
3512 /* Compare register to immediate */
3513 if (rs
!= 0 || imm
!= 0) {
3514 gen_load_gpr(t0
, rs
);
3515 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3522 case OPC_TEQ
: /* rs == rs */
3523 case OPC_TEQI
: /* r0 == 0 */
3524 case OPC_TGE
: /* rs >= rs */
3525 case OPC_TGEI
: /* r0 >= 0 */
3526 case OPC_TGEU
: /* rs >= rs unsigned */
3527 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3529 generate_exception(ctx
, EXCP_TRAP
);
3531 case OPC_TLT
: /* rs < rs */
3532 case OPC_TLTI
: /* r0 < 0 */
3533 case OPC_TLTU
: /* rs < rs unsigned */
3534 case OPC_TLTIU
: /* r0 < 0 unsigned */
3535 case OPC_TNE
: /* rs != rs */
3536 case OPC_TNEI
: /* r0 != 0 */
3537 /* Never trap: treat as NOP. */
3541 int l1
= gen_new_label();
3546 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3550 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3554 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3558 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3562 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3566 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3569 generate_exception(ctx
, EXCP_TRAP
);
3576 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3578 TranslationBlock
*tb
;
3580 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3581 likely(!ctx
->singlestep_enabled
)) {
3584 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3587 if (ctx
->singlestep_enabled
) {
3588 save_cpu_state(ctx
, 0);
3589 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3595 /* Branches (before delay slot) */
3596 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3598 int rs
, int rt
, int32_t offset
)
3600 target_ulong btgt
= -1;
3602 int bcond_compute
= 0;
3603 TCGv t0
= tcg_temp_new();
3604 TCGv t1
= tcg_temp_new();
3606 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3607 #ifdef MIPS_DEBUG_DISAS
3608 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3610 generate_exception(ctx
, EXCP_RI
);
3614 /* Load needed operands */
3620 /* Compare two registers */
3622 gen_load_gpr(t0
, rs
);
3623 gen_load_gpr(t1
, rt
);
3626 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3642 /* Compare to zero */
3644 gen_load_gpr(t0
, rs
);
3647 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3650 #if defined(TARGET_MIPS64)
3652 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3654 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3657 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3664 /* Jump to immediate */
3665 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3671 /* Jump to register */
3672 if (offset
!= 0 && offset
!= 16) {
3673 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3674 others are reserved. */
3675 MIPS_INVAL("jump hint");
3676 generate_exception(ctx
, EXCP_RI
);
3679 gen_load_gpr(btarget
, rs
);
3682 MIPS_INVAL("branch/jump");
3683 generate_exception(ctx
, EXCP_RI
);
3686 if (bcond_compute
== 0) {
3687 /* No condition to be computed */
3689 case OPC_BEQ
: /* rx == rx */
3690 case OPC_BEQL
: /* rx == rx likely */
3691 case OPC_BGEZ
: /* 0 >= 0 */
3692 case OPC_BGEZL
: /* 0 >= 0 likely */
3693 case OPC_BLEZ
: /* 0 <= 0 */
3694 case OPC_BLEZL
: /* 0 <= 0 likely */
3696 ctx
->hflags
|= MIPS_HFLAG_B
;
3697 MIPS_DEBUG("balways");
3700 case OPC_BGEZAL
: /* 0 >= 0 */
3701 case OPC_BGEZALL
: /* 0 >= 0 likely */
3702 ctx
->hflags
|= (opc
== OPC_BGEZALS
3704 : MIPS_HFLAG_BDS32
);
3705 /* Always take and link */
3707 ctx
->hflags
|= MIPS_HFLAG_B
;
3708 MIPS_DEBUG("balways and link");
3710 case OPC_BNE
: /* rx != rx */
3711 case OPC_BGTZ
: /* 0 > 0 */
3712 case OPC_BLTZ
: /* 0 < 0 */
3714 MIPS_DEBUG("bnever (NOP)");
3717 case OPC_BLTZAL
: /* 0 < 0 */
3718 ctx
->hflags
|= (opc
== OPC_BLTZALS
3720 : MIPS_HFLAG_BDS32
);
3721 /* Handle as an unconditional branch to get correct delay
3724 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3725 ctx
->hflags
|= MIPS_HFLAG_B
;
3726 MIPS_DEBUG("bnever and link");
3728 case OPC_BLTZALL
: /* 0 < 0 likely */
3729 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3730 /* Skip the instruction in the delay slot */
3731 MIPS_DEBUG("bnever, link and skip");
3734 case OPC_BNEL
: /* rx != rx likely */
3735 case OPC_BGTZL
: /* 0 > 0 likely */
3736 case OPC_BLTZL
: /* 0 < 0 likely */
3737 /* Skip the instruction in the delay slot */
3738 MIPS_DEBUG("bnever and skip");
3742 ctx
->hflags
|= MIPS_HFLAG_B
;
3743 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3747 ctx
->hflags
|= MIPS_HFLAG_BX
;
3752 ctx
->hflags
|= MIPS_HFLAG_B
;
3753 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3755 : MIPS_HFLAG_BDS32
);
3756 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3759 ctx
->hflags
|= MIPS_HFLAG_BR
;
3760 if (insn_bytes
== 4)
3761 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3762 MIPS_DEBUG("jr %s", regnames
[rs
]);
3768 ctx
->hflags
|= MIPS_HFLAG_BR
;
3769 ctx
->hflags
|= (opc
== OPC_JALRS
3771 : MIPS_HFLAG_BDS32
);
3772 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3775 MIPS_INVAL("branch/jump");
3776 generate_exception(ctx
, EXCP_RI
);
3782 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3783 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3784 regnames
[rs
], regnames
[rt
], btgt
);
3787 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3788 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3789 regnames
[rs
], regnames
[rt
], btgt
);
3792 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3793 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3794 regnames
[rs
], regnames
[rt
], btgt
);
3797 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3798 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3799 regnames
[rs
], regnames
[rt
], btgt
);
3802 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3803 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3806 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3807 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3811 ctx
->hflags
|= (opc
== OPC_BGEZALS
3813 : MIPS_HFLAG_BDS32
);
3814 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3815 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3819 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3821 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3824 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3825 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3828 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3829 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3832 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3833 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3836 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3837 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3840 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3841 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3844 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3845 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3848 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3849 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3851 #if defined(TARGET_MIPS64)
3853 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3854 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3859 ctx
->hflags
|= (opc
== OPC_BLTZALS
3861 : MIPS_HFLAG_BDS32
);
3862 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3864 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3866 ctx
->hflags
|= MIPS_HFLAG_BC
;
3869 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3871 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3873 ctx
->hflags
|= MIPS_HFLAG_BL
;
3876 MIPS_INVAL("conditional branch/jump");
3877 generate_exception(ctx
, EXCP_RI
);
3881 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3882 blink
, ctx
->hflags
, btgt
);
3884 ctx
->btarget
= btgt
;
3886 int post_delay
= insn_bytes
;
3887 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3889 if (opc
!= OPC_JALRC
)
3890 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3892 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3896 if (insn_bytes
== 2)
3897 ctx
->hflags
|= MIPS_HFLAG_B16
;
3902 /* special3 bitfield operations */
3903 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3904 int rs
, int lsb
, int msb
)
3906 TCGv t0
= tcg_temp_new();
3907 TCGv t1
= tcg_temp_new();
3909 gen_load_gpr(t1
, rs
);
3914 tcg_gen_shri_tl(t0
, t1
, lsb
);
3916 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3918 tcg_gen_ext32s_tl(t0
, t0
);
3921 #if defined(TARGET_MIPS64)
3923 tcg_gen_shri_tl(t0
, t1
, lsb
);
3925 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3929 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3930 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3933 tcg_gen_shri_tl(t0
, t1
, lsb
);
3934 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3940 gen_load_gpr(t0
, rt
);
3941 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3942 tcg_gen_ext32s_tl(t0
, t0
);
3944 #if defined(TARGET_MIPS64)
3946 gen_load_gpr(t0
, rt
);
3947 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3950 gen_load_gpr(t0
, rt
);
3951 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3954 gen_load_gpr(t0
, rt
);
3955 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3960 MIPS_INVAL("bitops");
3961 generate_exception(ctx
, EXCP_RI
);
3966 gen_store_gpr(t0
, rt
);
3971 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
3976 /* If no destination, treat it as a NOP. */
3981 t0
= tcg_temp_new();
3982 gen_load_gpr(t0
, rt
);
3986 TCGv t1
= tcg_temp_new();
3988 tcg_gen_shri_tl(t1
, t0
, 8);
3989 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
3990 tcg_gen_shli_tl(t0
, t0
, 8);
3991 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
3992 tcg_gen_or_tl(t0
, t0
, t1
);
3994 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3998 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4001 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4003 #if defined(TARGET_MIPS64)
4006 TCGv t1
= tcg_temp_new();
4008 tcg_gen_shri_tl(t1
, t0
, 8);
4009 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4010 tcg_gen_shli_tl(t0
, t0
, 8);
4011 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4012 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4018 TCGv t1
= tcg_temp_new();
4020 tcg_gen_shri_tl(t1
, t0
, 16);
4021 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4022 tcg_gen_shli_tl(t0
, t0
, 16);
4023 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4024 tcg_gen_or_tl(t0
, t0
, t1
);
4025 tcg_gen_shri_tl(t1
, t0
, 32);
4026 tcg_gen_shli_tl(t0
, t0
, 32);
4027 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4033 MIPS_INVAL("bsfhl");
4034 generate_exception(ctx
, EXCP_RI
);
4041 #ifndef CONFIG_USER_ONLY
4042 /* CP0 (MMU and control) */
4043 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4045 TCGv_i32 t0
= tcg_temp_new_i32();
4047 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4048 tcg_gen_ext_i32_tl(arg
, t0
);
4049 tcg_temp_free_i32(t0
);
4052 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4054 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4055 tcg_gen_ext32s_tl(arg
, arg
);
4058 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4060 TCGv_i32 t0
= tcg_temp_new_i32();
4062 tcg_gen_trunc_tl_i32(t0
, arg
);
4063 tcg_gen_st_i32(t0
, cpu_env
, off
);
4064 tcg_temp_free_i32(t0
);
4067 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4069 tcg_gen_ext32s_tl(arg
, arg
);
4070 tcg_gen_st_tl(arg
, cpu_env
, off
);
4073 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4075 const char *rn
= "invalid";
4078 check_insn(ctx
, ISA_MIPS32
);
4084 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4088 check_insn(ctx
, ASE_MT
);
4089 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4093 check_insn(ctx
, ASE_MT
);
4094 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4098 check_insn(ctx
, ASE_MT
);
4099 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4109 gen_helper_mfc0_random(arg
, cpu_env
);
4113 check_insn(ctx
, ASE_MT
);
4114 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4118 check_insn(ctx
, ASE_MT
);
4119 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4123 check_insn(ctx
, ASE_MT
);
4124 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4128 check_insn(ctx
, ASE_MT
);
4129 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4133 check_insn(ctx
, ASE_MT
);
4134 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4138 check_insn(ctx
, ASE_MT
);
4139 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4140 rn
= "VPEScheFBack";
4143 check_insn(ctx
, ASE_MT
);
4144 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4154 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4155 tcg_gen_ext32s_tl(arg
, arg
);
4159 check_insn(ctx
, ASE_MT
);
4160 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4164 check_insn(ctx
, ASE_MT
);
4165 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4169 check_insn(ctx
, ASE_MT
);
4170 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4174 check_insn(ctx
, ASE_MT
);
4175 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4179 check_insn(ctx
, ASE_MT
);
4180 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4184 check_insn(ctx
, ASE_MT
);
4185 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4189 check_insn(ctx
, ASE_MT
);
4190 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4200 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4201 tcg_gen_ext32s_tl(arg
, arg
);
4211 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4212 tcg_gen_ext32s_tl(arg
, arg
);
4216 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4217 rn
= "ContextConfig";
4226 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4230 check_insn(ctx
, ISA_MIPS32R2
);
4231 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4241 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4245 check_insn(ctx
, ISA_MIPS32R2
);
4246 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4250 check_insn(ctx
, ISA_MIPS32R2
);
4251 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4255 check_insn(ctx
, ISA_MIPS32R2
);
4256 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4260 check_insn(ctx
, ISA_MIPS32R2
);
4261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4265 check_insn(ctx
, ISA_MIPS32R2
);
4266 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4276 check_insn(ctx
, ISA_MIPS32R2
);
4277 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4287 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4288 tcg_gen_ext32s_tl(arg
, arg
);
4298 /* Mark as an IO operation because we read the time. */
4301 gen_helper_mfc0_count(arg
, cpu_env
);
4305 /* Break the TB to be able to take timer interrupts immediately
4306 after reading count. */
4307 ctx
->bstate
= BS_STOP
;
4310 /* 6,7 are implementation dependent */
4318 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4319 tcg_gen_ext32s_tl(arg
, arg
);
4329 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4332 /* 6,7 are implementation dependent */
4340 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4344 check_insn(ctx
, ISA_MIPS32R2
);
4345 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4349 check_insn(ctx
, ISA_MIPS32R2
);
4350 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4354 check_insn(ctx
, ISA_MIPS32R2
);
4355 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4365 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4375 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4376 tcg_gen_ext32s_tl(arg
, arg
);
4386 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4390 check_insn(ctx
, ISA_MIPS32R2
);
4391 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4401 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4405 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4409 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4413 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4416 /* 4,5 are reserved */
4417 /* 6,7 are implementation dependent */
4419 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4423 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4433 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4443 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4453 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4463 #if defined(TARGET_MIPS64)
4464 check_insn(ctx
, ISA_MIPS3
);
4465 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4466 tcg_gen_ext32s_tl(arg
, arg
);
4475 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4478 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4486 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4487 rn
= "'Diagnostic"; /* implementation dependent */
4492 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4496 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4497 rn
= "TraceControl";
4500 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4501 rn
= "TraceControl2";
4504 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4505 rn
= "UserTraceData";
4508 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4519 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4520 tcg_gen_ext32s_tl(arg
, arg
);
4530 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4531 rn
= "Performance0";
4534 // gen_helper_mfc0_performance1(arg);
4535 rn
= "Performance1";
4538 // gen_helper_mfc0_performance2(arg);
4539 rn
= "Performance2";
4542 // gen_helper_mfc0_performance3(arg);
4543 rn
= "Performance3";
4546 // gen_helper_mfc0_performance4(arg);
4547 rn
= "Performance4";
4550 // gen_helper_mfc0_performance5(arg);
4551 rn
= "Performance5";
4554 // gen_helper_mfc0_performance6(arg);
4555 rn
= "Performance6";
4558 // gen_helper_mfc0_performance7(arg);
4559 rn
= "Performance7";
4566 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4572 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4585 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4592 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4605 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4612 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4622 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4623 tcg_gen_ext32s_tl(arg
, arg
);
4634 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4644 (void)rn
; /* avoid a compiler warning */
4645 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4649 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4650 generate_exception(ctx
, EXCP_RI
);
4653 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4655 const char *rn
= "invalid";
4658 check_insn(ctx
, ISA_MIPS32
);
4667 gen_helper_mtc0_index(cpu_env
, arg
);
4671 check_insn(ctx
, ASE_MT
);
4672 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4676 check_insn(ctx
, ASE_MT
);
4681 check_insn(ctx
, ASE_MT
);
4696 check_insn(ctx
, ASE_MT
);
4697 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4701 check_insn(ctx
, ASE_MT
);
4702 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4706 check_insn(ctx
, ASE_MT
);
4707 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4711 check_insn(ctx
, ASE_MT
);
4712 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4716 check_insn(ctx
, ASE_MT
);
4717 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4721 check_insn(ctx
, ASE_MT
);
4722 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4723 rn
= "VPEScheFBack";
4726 check_insn(ctx
, ASE_MT
);
4727 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4737 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4741 check_insn(ctx
, ASE_MT
);
4742 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4746 check_insn(ctx
, ASE_MT
);
4747 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4751 check_insn(ctx
, ASE_MT
);
4752 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4756 check_insn(ctx
, ASE_MT
);
4757 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4761 check_insn(ctx
, ASE_MT
);
4762 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4766 check_insn(ctx
, ASE_MT
);
4767 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4771 check_insn(ctx
, ASE_MT
);
4772 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4782 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4792 gen_helper_mtc0_context(cpu_env
, arg
);
4796 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4797 rn
= "ContextConfig";
4806 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4810 check_insn(ctx
, ISA_MIPS32R2
);
4811 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4821 gen_helper_mtc0_wired(cpu_env
, arg
);
4825 check_insn(ctx
, ISA_MIPS32R2
);
4826 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4830 check_insn(ctx
, ISA_MIPS32R2
);
4831 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4835 check_insn(ctx
, ISA_MIPS32R2
);
4836 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4840 check_insn(ctx
, ISA_MIPS32R2
);
4841 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4845 check_insn(ctx
, ISA_MIPS32R2
);
4846 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4856 check_insn(ctx
, ISA_MIPS32R2
);
4857 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4871 gen_helper_mtc0_count(cpu_env
, arg
);
4874 /* 6,7 are implementation dependent */
4882 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4892 gen_helper_mtc0_compare(cpu_env
, arg
);
4895 /* 6,7 are implementation dependent */
4903 save_cpu_state(ctx
, 1);
4904 gen_helper_mtc0_status(cpu_env
, arg
);
4905 /* BS_STOP isn't good enough here, hflags may have changed. */
4906 gen_save_pc(ctx
->pc
+ 4);
4907 ctx
->bstate
= BS_EXCP
;
4911 check_insn(ctx
, ISA_MIPS32R2
);
4912 gen_helper_mtc0_intctl(cpu_env
, arg
);
4913 /* Stop translation as we may have switched the execution mode */
4914 ctx
->bstate
= BS_STOP
;
4918 check_insn(ctx
, ISA_MIPS32R2
);
4919 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4920 /* Stop translation as we may have switched the execution mode */
4921 ctx
->bstate
= BS_STOP
;
4925 check_insn(ctx
, ISA_MIPS32R2
);
4926 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4927 /* Stop translation as we may have switched the execution mode */
4928 ctx
->bstate
= BS_STOP
;
4938 save_cpu_state(ctx
, 1);
4939 gen_helper_mtc0_cause(cpu_env
, arg
);
4949 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4963 check_insn(ctx
, ISA_MIPS32R2
);
4964 gen_helper_mtc0_ebase(cpu_env
, arg
);
4974 gen_helper_mtc0_config0(cpu_env
, arg
);
4976 /* Stop translation as we may have switched the execution mode */
4977 ctx
->bstate
= BS_STOP
;
4980 /* ignored, read only */
4984 gen_helper_mtc0_config2(cpu_env
, arg
);
4986 /* Stop translation as we may have switched the execution mode */
4987 ctx
->bstate
= BS_STOP
;
4990 /* ignored, read only */
4993 /* 4,5 are reserved */
4994 /* 6,7 are implementation dependent */
5004 rn
= "Invalid config selector";
5011 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5021 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5031 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5041 #if defined(TARGET_MIPS64)
5042 check_insn(ctx
, ISA_MIPS3
);
5043 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5052 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5055 gen_helper_mtc0_framemask(cpu_env
, arg
);
5064 rn
= "Diagnostic"; /* implementation dependent */
5069 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5070 /* BS_STOP isn't good enough here, hflags may have changed. */
5071 gen_save_pc(ctx
->pc
+ 4);
5072 ctx
->bstate
= BS_EXCP
;
5076 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5077 rn
= "TraceControl";
5078 /* Stop translation as we may have switched the execution mode */
5079 ctx
->bstate
= BS_STOP
;
5082 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5083 rn
= "TraceControl2";
5084 /* Stop translation as we may have switched the execution mode */
5085 ctx
->bstate
= BS_STOP
;
5088 /* Stop translation as we may have switched the execution mode */
5089 ctx
->bstate
= BS_STOP
;
5090 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5091 rn
= "UserTraceData";
5092 /* Stop translation as we may have switched the execution mode */
5093 ctx
->bstate
= BS_STOP
;
5096 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5097 /* Stop translation as we may have switched the execution mode */
5098 ctx
->bstate
= BS_STOP
;
5109 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5119 gen_helper_mtc0_performance0(cpu_env
, arg
);
5120 rn
= "Performance0";
5123 // gen_helper_mtc0_performance1(arg);
5124 rn
= "Performance1";
5127 // gen_helper_mtc0_performance2(arg);
5128 rn
= "Performance2";
5131 // gen_helper_mtc0_performance3(arg);
5132 rn
= "Performance3";
5135 // gen_helper_mtc0_performance4(arg);
5136 rn
= "Performance4";
5139 // gen_helper_mtc0_performance5(arg);
5140 rn
= "Performance5";
5143 // gen_helper_mtc0_performance6(arg);
5144 rn
= "Performance6";
5147 // gen_helper_mtc0_performance7(arg);
5148 rn
= "Performance7";
5174 gen_helper_mtc0_taglo(cpu_env
, arg
);
5181 gen_helper_mtc0_datalo(cpu_env
, arg
);
5194 gen_helper_mtc0_taghi(cpu_env
, arg
);
5201 gen_helper_mtc0_datahi(cpu_env
, arg
);
5212 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5223 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5229 /* Stop translation as we may have switched the execution mode */
5230 ctx
->bstate
= BS_STOP
;
5235 (void)rn
; /* avoid a compiler warning */
5236 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5237 /* For simplicity assume that all writes can cause interrupts. */
5240 ctx
->bstate
= BS_STOP
;
5245 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5246 generate_exception(ctx
, EXCP_RI
);
5249 #if defined(TARGET_MIPS64)
5250 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5252 const char *rn
= "invalid";
5255 check_insn(ctx
, ISA_MIPS64
);
5261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5265 check_insn(ctx
, ASE_MT
);
5266 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5270 check_insn(ctx
, ASE_MT
);
5271 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5275 check_insn(ctx
, ASE_MT
);
5276 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5286 gen_helper_mfc0_random(arg
, cpu_env
);
5290 check_insn(ctx
, ASE_MT
);
5291 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5295 check_insn(ctx
, ASE_MT
);
5296 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5300 check_insn(ctx
, ASE_MT
);
5301 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5305 check_insn(ctx
, ASE_MT
);
5306 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5310 check_insn(ctx
, ASE_MT
);
5311 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5315 check_insn(ctx
, ASE_MT
);
5316 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5317 rn
= "VPEScheFBack";
5320 check_insn(ctx
, ASE_MT
);
5321 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5331 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5335 check_insn(ctx
, ASE_MT
);
5336 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5340 check_insn(ctx
, ASE_MT
);
5341 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5345 check_insn(ctx
, ASE_MT
);
5346 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5350 check_insn(ctx
, ASE_MT
);
5351 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5355 check_insn(ctx
, ASE_MT
);
5356 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5360 check_insn(ctx
, ASE_MT
);
5361 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5365 check_insn(ctx
, ASE_MT
);
5366 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5376 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5386 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5390 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5391 rn
= "ContextConfig";
5400 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5404 check_insn(ctx
, ISA_MIPS32R2
);
5405 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5415 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5419 check_insn(ctx
, ISA_MIPS32R2
);
5420 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5424 check_insn(ctx
, ISA_MIPS32R2
);
5425 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5429 check_insn(ctx
, ISA_MIPS32R2
);
5430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5434 check_insn(ctx
, ISA_MIPS32R2
);
5435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5439 check_insn(ctx
, ISA_MIPS32R2
);
5440 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5450 check_insn(ctx
, ISA_MIPS32R2
);
5451 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5461 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5471 /* Mark as an IO operation because we read the time. */
5474 gen_helper_mfc0_count(arg
, cpu_env
);
5478 /* Break the TB to be able to take timer interrupts immediately
5479 after reading count. */
5480 ctx
->bstate
= BS_STOP
;
5483 /* 6,7 are implementation dependent */
5491 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5501 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5504 /* 6,7 are implementation dependent */
5512 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5516 check_insn(ctx
, ISA_MIPS32R2
);
5517 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5521 check_insn(ctx
, ISA_MIPS32R2
);
5522 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5526 check_insn(ctx
, ISA_MIPS32R2
);
5527 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5537 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5547 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5557 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5561 check_insn(ctx
, ISA_MIPS32R2
);
5562 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5572 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5576 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5580 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5584 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5587 /* 6,7 are implementation dependent */
5589 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5593 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5603 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5613 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5623 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5633 check_insn(ctx
, ISA_MIPS3
);
5634 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5642 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5645 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5653 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5654 rn
= "'Diagnostic"; /* implementation dependent */
5659 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5663 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5664 rn
= "TraceControl";
5667 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5668 rn
= "TraceControl2";
5671 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5672 rn
= "UserTraceData";
5675 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5686 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5696 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5697 rn
= "Performance0";
5700 // gen_helper_dmfc0_performance1(arg);
5701 rn
= "Performance1";
5704 // gen_helper_dmfc0_performance2(arg);
5705 rn
= "Performance2";
5708 // gen_helper_dmfc0_performance3(arg);
5709 rn
= "Performance3";
5712 // gen_helper_dmfc0_performance4(arg);
5713 rn
= "Performance4";
5716 // gen_helper_dmfc0_performance5(arg);
5717 rn
= "Performance5";
5720 // gen_helper_dmfc0_performance6(arg);
5721 rn
= "Performance6";
5724 // gen_helper_dmfc0_performance7(arg);
5725 rn
= "Performance7";
5732 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5739 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5752 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5759 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5772 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5779 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5789 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5800 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5810 (void)rn
; /* avoid a compiler warning */
5811 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5815 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5816 generate_exception(ctx
, EXCP_RI
);
5819 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5821 const char *rn
= "invalid";
5824 check_insn(ctx
, ISA_MIPS64
);
5833 gen_helper_mtc0_index(cpu_env
, arg
);
5837 check_insn(ctx
, ASE_MT
);
5838 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5842 check_insn(ctx
, ASE_MT
);
5847 check_insn(ctx
, ASE_MT
);
5862 check_insn(ctx
, ASE_MT
);
5863 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5867 check_insn(ctx
, ASE_MT
);
5868 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5872 check_insn(ctx
, ASE_MT
);
5873 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5877 check_insn(ctx
, ASE_MT
);
5878 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5882 check_insn(ctx
, ASE_MT
);
5883 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5887 check_insn(ctx
, ASE_MT
);
5888 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5889 rn
= "VPEScheFBack";
5892 check_insn(ctx
, ASE_MT
);
5893 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5903 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5907 check_insn(ctx
, ASE_MT
);
5908 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5912 check_insn(ctx
, ASE_MT
);
5913 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5917 check_insn(ctx
, ASE_MT
);
5918 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5922 check_insn(ctx
, ASE_MT
);
5923 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5927 check_insn(ctx
, ASE_MT
);
5928 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5932 check_insn(ctx
, ASE_MT
);
5933 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5937 check_insn(ctx
, ASE_MT
);
5938 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5948 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5958 gen_helper_mtc0_context(cpu_env
, arg
);
5962 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5963 rn
= "ContextConfig";
5972 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5976 check_insn(ctx
, ISA_MIPS32R2
);
5977 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5987 gen_helper_mtc0_wired(cpu_env
, arg
);
5991 check_insn(ctx
, ISA_MIPS32R2
);
5992 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5996 check_insn(ctx
, ISA_MIPS32R2
);
5997 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6001 check_insn(ctx
, ISA_MIPS32R2
);
6002 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6006 check_insn(ctx
, ISA_MIPS32R2
);
6007 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6011 check_insn(ctx
, ISA_MIPS32R2
);
6012 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6022 check_insn(ctx
, ISA_MIPS32R2
);
6023 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6037 gen_helper_mtc0_count(cpu_env
, arg
);
6040 /* 6,7 are implementation dependent */
6044 /* Stop translation as we may have switched the execution mode */
6045 ctx
->bstate
= BS_STOP
;
6050 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6060 gen_helper_mtc0_compare(cpu_env
, arg
);
6063 /* 6,7 are implementation dependent */
6067 /* Stop translation as we may have switched the execution mode */
6068 ctx
->bstate
= BS_STOP
;
6073 save_cpu_state(ctx
, 1);
6074 gen_helper_mtc0_status(cpu_env
, arg
);
6075 /* BS_STOP isn't good enough here, hflags may have changed. */
6076 gen_save_pc(ctx
->pc
+ 4);
6077 ctx
->bstate
= BS_EXCP
;
6081 check_insn(ctx
, ISA_MIPS32R2
);
6082 gen_helper_mtc0_intctl(cpu_env
, arg
);
6083 /* Stop translation as we may have switched the execution mode */
6084 ctx
->bstate
= BS_STOP
;
6088 check_insn(ctx
, ISA_MIPS32R2
);
6089 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6090 /* Stop translation as we may have switched the execution mode */
6091 ctx
->bstate
= BS_STOP
;
6095 check_insn(ctx
, ISA_MIPS32R2
);
6096 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6097 /* Stop translation as we may have switched the execution mode */
6098 ctx
->bstate
= BS_STOP
;
6108 save_cpu_state(ctx
, 1);
6109 /* Mark as an IO operation because we may trigger a software
6114 gen_helper_mtc0_cause(cpu_env
, arg
);
6118 /* Stop translation as we may have triggered an intetrupt */
6119 ctx
->bstate
= BS_STOP
;
6129 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6143 check_insn(ctx
, ISA_MIPS32R2
);
6144 gen_helper_mtc0_ebase(cpu_env
, arg
);
6154 gen_helper_mtc0_config0(cpu_env
, arg
);
6156 /* Stop translation as we may have switched the execution mode */
6157 ctx
->bstate
= BS_STOP
;
6160 /* ignored, read only */
6164 gen_helper_mtc0_config2(cpu_env
, arg
);
6166 /* Stop translation as we may have switched the execution mode */
6167 ctx
->bstate
= BS_STOP
;
6173 /* 6,7 are implementation dependent */
6175 rn
= "Invalid config selector";
6182 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6192 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6202 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6212 check_insn(ctx
, ISA_MIPS3
);
6213 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6221 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6224 gen_helper_mtc0_framemask(cpu_env
, arg
);
6233 rn
= "Diagnostic"; /* implementation dependent */
6238 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6239 /* BS_STOP isn't good enough here, hflags may have changed. */
6240 gen_save_pc(ctx
->pc
+ 4);
6241 ctx
->bstate
= BS_EXCP
;
6245 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6246 /* Stop translation as we may have switched the execution mode */
6247 ctx
->bstate
= BS_STOP
;
6248 rn
= "TraceControl";
6251 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6252 /* Stop translation as we may have switched the execution mode */
6253 ctx
->bstate
= BS_STOP
;
6254 rn
= "TraceControl2";
6257 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6258 /* Stop translation as we may have switched the execution mode */
6259 ctx
->bstate
= BS_STOP
;
6260 rn
= "UserTraceData";
6263 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6264 /* Stop translation as we may have switched the execution mode */
6265 ctx
->bstate
= BS_STOP
;
6276 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6286 gen_helper_mtc0_performance0(cpu_env
, arg
);
6287 rn
= "Performance0";
6290 // gen_helper_mtc0_performance1(cpu_env, arg);
6291 rn
= "Performance1";
6294 // gen_helper_mtc0_performance2(cpu_env, arg);
6295 rn
= "Performance2";
6298 // gen_helper_mtc0_performance3(cpu_env, arg);
6299 rn
= "Performance3";
6302 // gen_helper_mtc0_performance4(cpu_env, arg);
6303 rn
= "Performance4";
6306 // gen_helper_mtc0_performance5(cpu_env, arg);
6307 rn
= "Performance5";
6310 // gen_helper_mtc0_performance6(cpu_env, arg);
6311 rn
= "Performance6";
6314 // gen_helper_mtc0_performance7(cpu_env, arg);
6315 rn
= "Performance7";
6341 gen_helper_mtc0_taglo(cpu_env
, arg
);
6348 gen_helper_mtc0_datalo(cpu_env
, arg
);
6361 gen_helper_mtc0_taghi(cpu_env
, arg
);
6368 gen_helper_mtc0_datahi(cpu_env
, arg
);
6379 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6390 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6396 /* Stop translation as we may have switched the execution mode */
6397 ctx
->bstate
= BS_STOP
;
6402 (void)rn
; /* avoid a compiler warning */
6403 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6404 /* For simplicity assume that all writes can cause interrupts. */
6407 ctx
->bstate
= BS_STOP
;
6412 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6413 generate_exception(ctx
, EXCP_RI
);
6415 #endif /* TARGET_MIPS64 */
6417 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6418 int u
, int sel
, int h
)
6420 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6421 TCGv t0
= tcg_temp_local_new();
6423 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6424 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6425 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6426 tcg_gen_movi_tl(t0
, -1);
6427 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6428 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6429 tcg_gen_movi_tl(t0
, -1);
6435 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6438 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6448 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6451 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6454 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6457 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6460 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6463 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6466 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6469 gen_mfc0(ctx
, t0
, rt
, sel
);
6476 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6479 gen_mfc0(ctx
, t0
, rt
, sel
);
6485 gen_helper_mftc0_status(t0
, cpu_env
);
6488 gen_mfc0(ctx
, t0
, rt
, sel
);
6494 gen_helper_mftc0_cause(t0
, cpu_env
);
6504 gen_helper_mftc0_epc(t0
, cpu_env
);
6514 gen_helper_mftc0_ebase(t0
, cpu_env
);
6524 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6534 gen_helper_mftc0_debug(t0
, cpu_env
);
6537 gen_mfc0(ctx
, t0
, rt
, sel
);
6542 gen_mfc0(ctx
, t0
, rt
, sel
);
6544 } else switch (sel
) {
6545 /* GPR registers. */
6547 gen_helper_1e0i(mftgpr
, t0
, rt
);
6549 /* Auxiliary CPU registers */
6553 gen_helper_1e0i(mftlo
, t0
, 0);
6556 gen_helper_1e0i(mfthi
, t0
, 0);
6559 gen_helper_1e0i(mftacx
, t0
, 0);
6562 gen_helper_1e0i(mftlo
, t0
, 1);
6565 gen_helper_1e0i(mfthi
, t0
, 1);
6568 gen_helper_1e0i(mftacx
, t0
, 1);
6571 gen_helper_1e0i(mftlo
, t0
, 2);
6574 gen_helper_1e0i(mfthi
, t0
, 2);
6577 gen_helper_1e0i(mftacx
, t0
, 2);
6580 gen_helper_1e0i(mftlo
, t0
, 3);
6583 gen_helper_1e0i(mfthi
, t0
, 3);
6586 gen_helper_1e0i(mftacx
, t0
, 3);
6589 gen_helper_mftdsp(t0
, cpu_env
);
6595 /* Floating point (COP1). */
6597 /* XXX: For now we support only a single FPU context. */
6599 TCGv_i32 fp0
= tcg_temp_new_i32();
6601 gen_load_fpr32(fp0
, rt
);
6602 tcg_gen_ext_i32_tl(t0
, fp0
);
6603 tcg_temp_free_i32(fp0
);
6605 TCGv_i32 fp0
= tcg_temp_new_i32();
6607 gen_load_fpr32h(fp0
, rt
);
6608 tcg_gen_ext_i32_tl(t0
, fp0
);
6609 tcg_temp_free_i32(fp0
);
6613 /* XXX: For now we support only a single FPU context. */
6614 gen_helper_1e0i(cfc1
, t0
, rt
);
6616 /* COP2: Not implemented. */
6623 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6624 gen_store_gpr(t0
, rd
);
6630 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6631 generate_exception(ctx
, EXCP_RI
);
6634 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6635 int u
, int sel
, int h
)
6637 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6638 TCGv t0
= tcg_temp_local_new();
6640 gen_load_gpr(t0
, rt
);
6641 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6642 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6643 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6645 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6646 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6653 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6656 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6666 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6669 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6672 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6675 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6678 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6681 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6684 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6687 gen_mtc0(ctx
, t0
, rd
, sel
);
6694 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6697 gen_mtc0(ctx
, t0
, rd
, sel
);
6703 gen_helper_mttc0_status(cpu_env
, t0
);
6706 gen_mtc0(ctx
, t0
, rd
, sel
);
6712 gen_helper_mttc0_cause(cpu_env
, t0
);
6722 gen_helper_mttc0_ebase(cpu_env
, t0
);
6732 gen_helper_mttc0_debug(cpu_env
, t0
);
6735 gen_mtc0(ctx
, t0
, rd
, sel
);
6740 gen_mtc0(ctx
, t0
, rd
, sel
);
6742 } else switch (sel
) {
6743 /* GPR registers. */
6745 gen_helper_0e1i(mttgpr
, t0
, rd
);
6747 /* Auxiliary CPU registers */
6751 gen_helper_0e1i(mttlo
, t0
, 0);
6754 gen_helper_0e1i(mtthi
, t0
, 0);
6757 gen_helper_0e1i(mttacx
, t0
, 0);
6760 gen_helper_0e1i(mttlo
, t0
, 1);
6763 gen_helper_0e1i(mtthi
, t0
, 1);
6766 gen_helper_0e1i(mttacx
, t0
, 1);
6769 gen_helper_0e1i(mttlo
, t0
, 2);
6772 gen_helper_0e1i(mtthi
, t0
, 2);
6775 gen_helper_0e1i(mttacx
, t0
, 2);
6778 gen_helper_0e1i(mttlo
, t0
, 3);
6781 gen_helper_0e1i(mtthi
, t0
, 3);
6784 gen_helper_0e1i(mttacx
, t0
, 3);
6787 gen_helper_mttdsp(cpu_env
, t0
);
6793 /* Floating point (COP1). */
6795 /* XXX: For now we support only a single FPU context. */
6797 TCGv_i32 fp0
= tcg_temp_new_i32();
6799 tcg_gen_trunc_tl_i32(fp0
, t0
);
6800 gen_store_fpr32(fp0
, rd
);
6801 tcg_temp_free_i32(fp0
);
6803 TCGv_i32 fp0
= tcg_temp_new_i32();
6805 tcg_gen_trunc_tl_i32(fp0
, t0
);
6806 gen_store_fpr32h(fp0
, rd
);
6807 tcg_temp_free_i32(fp0
);
6811 /* XXX: For now we support only a single FPU context. */
6812 gen_helper_0e1i(ctc1
, t0
, rd
);
6814 /* COP2: Not implemented. */
6821 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6827 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6828 generate_exception(ctx
, EXCP_RI
);
6831 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6833 const char *opn
= "ldst";
6835 check_cp0_enabled(ctx
);
6842 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6847 TCGv t0
= tcg_temp_new();
6849 gen_load_gpr(t0
, rt
);
6850 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6855 #if defined(TARGET_MIPS64)
6857 check_insn(ctx
, ISA_MIPS3
);
6862 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6866 check_insn(ctx
, ISA_MIPS3
);
6868 TCGv t0
= tcg_temp_new();
6870 gen_load_gpr(t0
, rt
);
6871 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6878 check_insn(ctx
, ASE_MT
);
6883 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6884 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6888 check_insn(ctx
, ASE_MT
);
6889 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6890 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6895 if (!env
->tlb
->helper_tlbwi
)
6897 gen_helper_tlbwi(cpu_env
);
6901 if (!env
->tlb
->helper_tlbwr
)
6903 gen_helper_tlbwr(cpu_env
);
6907 if (!env
->tlb
->helper_tlbp
)
6909 gen_helper_tlbp(cpu_env
);
6913 if (!env
->tlb
->helper_tlbr
)
6915 gen_helper_tlbr(cpu_env
);
6919 check_insn(ctx
, ISA_MIPS2
);
6920 gen_helper_eret(cpu_env
);
6921 ctx
->bstate
= BS_EXCP
;
6925 check_insn(ctx
, ISA_MIPS32
);
6926 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6928 generate_exception(ctx
, EXCP_RI
);
6930 gen_helper_deret(cpu_env
);
6931 ctx
->bstate
= BS_EXCP
;
6936 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
6937 /* If we get an exception, we want to restart at next instruction */
6939 save_cpu_state(ctx
, 1);
6941 gen_helper_wait(cpu_env
);
6942 ctx
->bstate
= BS_EXCP
;
6947 generate_exception(ctx
, EXCP_RI
);
6950 (void)opn
; /* avoid a compiler warning */
6951 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
6953 #endif /* !CONFIG_USER_ONLY */
6955 /* CP1 Branches (before delay slot) */
6956 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
6957 int32_t cc
, int32_t offset
)
6959 target_ulong btarget
;
6960 const char *opn
= "cp1 cond branch";
6961 TCGv_i32 t0
= tcg_temp_new_i32();
6964 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
6966 btarget
= ctx
->pc
+ 4 + offset
;
6970 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6971 tcg_gen_not_i32(t0
, t0
);
6972 tcg_gen_andi_i32(t0
, t0
, 1);
6973 tcg_gen_extu_i32_tl(bcond
, t0
);
6977 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6978 tcg_gen_not_i32(t0
, t0
);
6979 tcg_gen_andi_i32(t0
, t0
, 1);
6980 tcg_gen_extu_i32_tl(bcond
, t0
);
6984 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6985 tcg_gen_andi_i32(t0
, t0
, 1);
6986 tcg_gen_extu_i32_tl(bcond
, t0
);
6990 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6991 tcg_gen_andi_i32(t0
, t0
, 1);
6992 tcg_gen_extu_i32_tl(bcond
, t0
);
6995 ctx
->hflags
|= MIPS_HFLAG_BL
;
6999 TCGv_i32 t1
= tcg_temp_new_i32();
7000 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7001 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7002 tcg_gen_nand_i32(t0
, t0
, t1
);
7003 tcg_temp_free_i32(t1
);
7004 tcg_gen_andi_i32(t0
, t0
, 1);
7005 tcg_gen_extu_i32_tl(bcond
, t0
);
7011 TCGv_i32 t1
= tcg_temp_new_i32();
7012 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7013 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7014 tcg_gen_or_i32(t0
, t0
, t1
);
7015 tcg_temp_free_i32(t1
);
7016 tcg_gen_andi_i32(t0
, t0
, 1);
7017 tcg_gen_extu_i32_tl(bcond
, t0
);
7023 TCGv_i32 t1
= tcg_temp_new_i32();
7024 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7025 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7026 tcg_gen_and_i32(t0
, t0
, t1
);
7027 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7028 tcg_gen_and_i32(t0
, t0
, t1
);
7029 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7030 tcg_gen_nand_i32(t0
, t0
, t1
);
7031 tcg_temp_free_i32(t1
);
7032 tcg_gen_andi_i32(t0
, t0
, 1);
7033 tcg_gen_extu_i32_tl(bcond
, t0
);
7039 TCGv_i32 t1
= tcg_temp_new_i32();
7040 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7041 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7042 tcg_gen_or_i32(t0
, t0
, t1
);
7043 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7044 tcg_gen_or_i32(t0
, t0
, t1
);
7045 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7046 tcg_gen_or_i32(t0
, t0
, t1
);
7047 tcg_temp_free_i32(t1
);
7048 tcg_gen_andi_i32(t0
, t0
, 1);
7049 tcg_gen_extu_i32_tl(bcond
, t0
);
7053 ctx
->hflags
|= MIPS_HFLAG_BC
;
7057 generate_exception (ctx
, EXCP_RI
);
7060 (void)opn
; /* avoid a compiler warning */
7061 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7062 ctx
->hflags
, btarget
);
7063 ctx
->btarget
= btarget
;
7066 tcg_temp_free_i32(t0
);
7069 /* Coprocessor 1 (FPU) */
7071 #define FOP(func, fmt) (((fmt) << 21) | (func))
7074 OPC_ADD_S
= FOP(0, FMT_S
),
7075 OPC_SUB_S
= FOP(1, FMT_S
),
7076 OPC_MUL_S
= FOP(2, FMT_S
),
7077 OPC_DIV_S
= FOP(3, FMT_S
),
7078 OPC_SQRT_S
= FOP(4, FMT_S
),
7079 OPC_ABS_S
= FOP(5, FMT_S
),
7080 OPC_MOV_S
= FOP(6, FMT_S
),
7081 OPC_NEG_S
= FOP(7, FMT_S
),
7082 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7083 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7084 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7085 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7086 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7087 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7088 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7089 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7090 OPC_MOVCF_S
= FOP(17, FMT_S
),
7091 OPC_MOVZ_S
= FOP(18, FMT_S
),
7092 OPC_MOVN_S
= FOP(19, FMT_S
),
7093 OPC_RECIP_S
= FOP(21, FMT_S
),
7094 OPC_RSQRT_S
= FOP(22, FMT_S
),
7095 OPC_RECIP2_S
= FOP(28, FMT_S
),
7096 OPC_RECIP1_S
= FOP(29, FMT_S
),
7097 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7098 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7099 OPC_CVT_D_S
= FOP(33, FMT_S
),
7100 OPC_CVT_W_S
= FOP(36, FMT_S
),
7101 OPC_CVT_L_S
= FOP(37, FMT_S
),
7102 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7103 OPC_CMP_F_S
= FOP (48, FMT_S
),
7104 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7105 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7106 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7107 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7108 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7109 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7110 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7111 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7112 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7113 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7114 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7115 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7116 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7117 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7118 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7120 OPC_ADD_D
= FOP(0, FMT_D
),
7121 OPC_SUB_D
= FOP(1, FMT_D
),
7122 OPC_MUL_D
= FOP(2, FMT_D
),
7123 OPC_DIV_D
= FOP(3, FMT_D
),
7124 OPC_SQRT_D
= FOP(4, FMT_D
),
7125 OPC_ABS_D
= FOP(5, FMT_D
),
7126 OPC_MOV_D
= FOP(6, FMT_D
),
7127 OPC_NEG_D
= FOP(7, FMT_D
),
7128 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7129 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7130 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7131 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7132 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7133 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7134 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7135 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7136 OPC_MOVCF_D
= FOP(17, FMT_D
),
7137 OPC_MOVZ_D
= FOP(18, FMT_D
),
7138 OPC_MOVN_D
= FOP(19, FMT_D
),
7139 OPC_RECIP_D
= FOP(21, FMT_D
),
7140 OPC_RSQRT_D
= FOP(22, FMT_D
),
7141 OPC_RECIP2_D
= FOP(28, FMT_D
),
7142 OPC_RECIP1_D
= FOP(29, FMT_D
),
7143 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7144 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7145 OPC_CVT_S_D
= FOP(32, FMT_D
),
7146 OPC_CVT_W_D
= FOP(36, FMT_D
),
7147 OPC_CVT_L_D
= FOP(37, FMT_D
),
7148 OPC_CMP_F_D
= FOP (48, FMT_D
),
7149 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7150 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7151 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7152 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7153 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7154 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7155 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7156 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7157 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7158 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7159 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7160 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7161 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7162 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7163 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7165 OPC_CVT_S_W
= FOP(32, FMT_W
),
7166 OPC_CVT_D_W
= FOP(33, FMT_W
),
7167 OPC_CVT_S_L
= FOP(32, FMT_L
),
7168 OPC_CVT_D_L
= FOP(33, FMT_L
),
7169 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7171 OPC_ADD_PS
= FOP(0, FMT_PS
),
7172 OPC_SUB_PS
= FOP(1, FMT_PS
),
7173 OPC_MUL_PS
= FOP(2, FMT_PS
),
7174 OPC_DIV_PS
= FOP(3, FMT_PS
),
7175 OPC_ABS_PS
= FOP(5, FMT_PS
),
7176 OPC_MOV_PS
= FOP(6, FMT_PS
),
7177 OPC_NEG_PS
= FOP(7, FMT_PS
),
7178 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7179 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7180 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7181 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7182 OPC_MULR_PS
= FOP(26, FMT_PS
),
7183 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7184 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7185 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7186 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7188 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7189 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7190 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7191 OPC_PLL_PS
= FOP(44, FMT_PS
),
7192 OPC_PLU_PS
= FOP(45, FMT_PS
),
7193 OPC_PUL_PS
= FOP(46, FMT_PS
),
7194 OPC_PUU_PS
= FOP(47, FMT_PS
),
7195 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7196 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7197 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7198 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7199 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7200 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7201 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7202 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7203 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7204 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7205 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7206 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7207 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7208 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7209 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7210 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7213 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7215 const char *opn
= "cp1 move";
7216 TCGv t0
= tcg_temp_new();
7221 TCGv_i32 fp0
= tcg_temp_new_i32();
7223 gen_load_fpr32(fp0
, fs
);
7224 tcg_gen_ext_i32_tl(t0
, fp0
);
7225 tcg_temp_free_i32(fp0
);
7227 gen_store_gpr(t0
, rt
);
7231 gen_load_gpr(t0
, rt
);
7233 TCGv_i32 fp0
= tcg_temp_new_i32();
7235 tcg_gen_trunc_tl_i32(fp0
, t0
);
7236 gen_store_fpr32(fp0
, fs
);
7237 tcg_temp_free_i32(fp0
);
7242 gen_helper_1e0i(cfc1
, t0
, fs
);
7243 gen_store_gpr(t0
, rt
);
7247 gen_load_gpr(t0
, rt
);
7248 gen_helper_0e1i(ctc1
, t0
, fs
);
7251 #if defined(TARGET_MIPS64)
7253 gen_load_fpr64(ctx
, t0
, fs
);
7254 gen_store_gpr(t0
, rt
);
7258 gen_load_gpr(t0
, rt
);
7259 gen_store_fpr64(ctx
, t0
, fs
);
7265 TCGv_i32 fp0
= tcg_temp_new_i32();
7267 gen_load_fpr32h(fp0
, fs
);
7268 tcg_gen_ext_i32_tl(t0
, fp0
);
7269 tcg_temp_free_i32(fp0
);
7271 gen_store_gpr(t0
, rt
);
7275 gen_load_gpr(t0
, rt
);
7277 TCGv_i32 fp0
= tcg_temp_new_i32();
7279 tcg_gen_trunc_tl_i32(fp0
, t0
);
7280 gen_store_fpr32h(fp0
, fs
);
7281 tcg_temp_free_i32(fp0
);
7287 generate_exception (ctx
, EXCP_RI
);
7290 (void)opn
; /* avoid a compiler warning */
7291 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7297 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7313 l1
= gen_new_label();
7314 t0
= tcg_temp_new_i32();
7315 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7316 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7317 tcg_temp_free_i32(t0
);
7319 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7321 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7326 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7329 TCGv_i32 t0
= tcg_temp_new_i32();
7330 int l1
= gen_new_label();
7337 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7338 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7339 gen_load_fpr32(t0
, fs
);
7340 gen_store_fpr32(t0
, fd
);
7342 tcg_temp_free_i32(t0
);
7345 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7348 TCGv_i32 t0
= tcg_temp_new_i32();
7350 int l1
= gen_new_label();
7357 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7358 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7359 tcg_temp_free_i32(t0
);
7360 fp0
= tcg_temp_new_i64();
7361 gen_load_fpr64(ctx
, fp0
, fs
);
7362 gen_store_fpr64(ctx
, fp0
, fd
);
7363 tcg_temp_free_i64(fp0
);
7367 static inline void gen_movcf_ps (int fs
, int fd
, int cc
, int tf
)
7370 TCGv_i32 t0
= tcg_temp_new_i32();
7371 int l1
= gen_new_label();
7372 int l2
= gen_new_label();
7379 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7380 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7381 gen_load_fpr32(t0
, fs
);
7382 gen_store_fpr32(t0
, fd
);
7385 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7386 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7387 gen_load_fpr32h(t0
, fs
);
7388 gen_store_fpr32h(t0
, fd
);
7389 tcg_temp_free_i32(t0
);
7394 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7395 int ft
, int fs
, int fd
, int cc
)
7397 const char *opn
= "farith";
7398 const char *condnames
[] = {
7416 const char *condnames_abs
[] = {
7434 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7435 uint32_t func
= ctx
->opcode
& 0x3f;
7440 TCGv_i32 fp0
= tcg_temp_new_i32();
7441 TCGv_i32 fp1
= tcg_temp_new_i32();
7443 gen_load_fpr32(fp0
, fs
);
7444 gen_load_fpr32(fp1
, ft
);
7445 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7446 tcg_temp_free_i32(fp1
);
7447 gen_store_fpr32(fp0
, fd
);
7448 tcg_temp_free_i32(fp0
);
7455 TCGv_i32 fp0
= tcg_temp_new_i32();
7456 TCGv_i32 fp1
= tcg_temp_new_i32();
7458 gen_load_fpr32(fp0
, fs
);
7459 gen_load_fpr32(fp1
, ft
);
7460 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7461 tcg_temp_free_i32(fp1
);
7462 gen_store_fpr32(fp0
, fd
);
7463 tcg_temp_free_i32(fp0
);
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_mul_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_div_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();
7502 gen_load_fpr32(fp0
, fs
);
7503 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7504 gen_store_fpr32(fp0
, fd
);
7505 tcg_temp_free_i32(fp0
);
7511 TCGv_i32 fp0
= tcg_temp_new_i32();
7513 gen_load_fpr32(fp0
, fs
);
7514 gen_helper_float_abs_s(fp0
, fp0
);
7515 gen_store_fpr32(fp0
, fd
);
7516 tcg_temp_free_i32(fp0
);
7522 TCGv_i32 fp0
= tcg_temp_new_i32();
7524 gen_load_fpr32(fp0
, fs
);
7525 gen_store_fpr32(fp0
, fd
);
7526 tcg_temp_free_i32(fp0
);
7532 TCGv_i32 fp0
= tcg_temp_new_i32();
7534 gen_load_fpr32(fp0
, fs
);
7535 gen_helper_float_chs_s(fp0
, fp0
);
7536 gen_store_fpr32(fp0
, fd
);
7537 tcg_temp_free_i32(fp0
);
7542 check_cp1_64bitmode(ctx
);
7544 TCGv_i32 fp32
= tcg_temp_new_i32();
7545 TCGv_i64 fp64
= tcg_temp_new_i64();
7547 gen_load_fpr32(fp32
, fs
);
7548 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7549 tcg_temp_free_i32(fp32
);
7550 gen_store_fpr64(ctx
, fp64
, fd
);
7551 tcg_temp_free_i64(fp64
);
7556 check_cp1_64bitmode(ctx
);
7558 TCGv_i32 fp32
= tcg_temp_new_i32();
7559 TCGv_i64 fp64
= tcg_temp_new_i64();
7561 gen_load_fpr32(fp32
, fs
);
7562 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7563 tcg_temp_free_i32(fp32
);
7564 gen_store_fpr64(ctx
, fp64
, fd
);
7565 tcg_temp_free_i64(fp64
);
7570 check_cp1_64bitmode(ctx
);
7572 TCGv_i32 fp32
= tcg_temp_new_i32();
7573 TCGv_i64 fp64
= tcg_temp_new_i64();
7575 gen_load_fpr32(fp32
, fs
);
7576 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7577 tcg_temp_free_i32(fp32
);
7578 gen_store_fpr64(ctx
, fp64
, fd
);
7579 tcg_temp_free_i64(fp64
);
7584 check_cp1_64bitmode(ctx
);
7586 TCGv_i32 fp32
= tcg_temp_new_i32();
7587 TCGv_i64 fp64
= tcg_temp_new_i64();
7589 gen_load_fpr32(fp32
, fs
);
7590 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7591 tcg_temp_free_i32(fp32
);
7592 gen_store_fpr64(ctx
, fp64
, fd
);
7593 tcg_temp_free_i64(fp64
);
7599 TCGv_i32 fp0
= tcg_temp_new_i32();
7601 gen_load_fpr32(fp0
, fs
);
7602 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7603 gen_store_fpr32(fp0
, fd
);
7604 tcg_temp_free_i32(fp0
);
7610 TCGv_i32 fp0
= tcg_temp_new_i32();
7612 gen_load_fpr32(fp0
, fs
);
7613 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7614 gen_store_fpr32(fp0
, fd
);
7615 tcg_temp_free_i32(fp0
);
7621 TCGv_i32 fp0
= tcg_temp_new_i32();
7623 gen_load_fpr32(fp0
, fs
);
7624 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7625 gen_store_fpr32(fp0
, fd
);
7626 tcg_temp_free_i32(fp0
);
7632 TCGv_i32 fp0
= tcg_temp_new_i32();
7634 gen_load_fpr32(fp0
, fs
);
7635 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7636 gen_store_fpr32(fp0
, fd
);
7637 tcg_temp_free_i32(fp0
);
7642 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7647 int l1
= gen_new_label();
7651 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7653 fp0
= tcg_temp_new_i32();
7654 gen_load_fpr32(fp0
, fs
);
7655 gen_store_fpr32(fp0
, fd
);
7656 tcg_temp_free_i32(fp0
);
7663 int l1
= gen_new_label();
7667 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7668 fp0
= tcg_temp_new_i32();
7669 gen_load_fpr32(fp0
, fs
);
7670 gen_store_fpr32(fp0
, fd
);
7671 tcg_temp_free_i32(fp0
);
7680 TCGv_i32 fp0
= tcg_temp_new_i32();
7682 gen_load_fpr32(fp0
, fs
);
7683 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7684 gen_store_fpr32(fp0
, fd
);
7685 tcg_temp_free_i32(fp0
);
7692 TCGv_i32 fp0
= tcg_temp_new_i32();
7694 gen_load_fpr32(fp0
, fs
);
7695 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7696 gen_store_fpr32(fp0
, fd
);
7697 tcg_temp_free_i32(fp0
);
7702 check_cp1_64bitmode(ctx
);
7704 TCGv_i32 fp0
= tcg_temp_new_i32();
7705 TCGv_i32 fp1
= tcg_temp_new_i32();
7707 gen_load_fpr32(fp0
, fs
);
7708 gen_load_fpr32(fp1
, ft
);
7709 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7710 tcg_temp_free_i32(fp1
);
7711 gen_store_fpr32(fp0
, fd
);
7712 tcg_temp_free_i32(fp0
);
7717 check_cp1_64bitmode(ctx
);
7719 TCGv_i32 fp0
= tcg_temp_new_i32();
7721 gen_load_fpr32(fp0
, fs
);
7722 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7723 gen_store_fpr32(fp0
, fd
);
7724 tcg_temp_free_i32(fp0
);
7729 check_cp1_64bitmode(ctx
);
7731 TCGv_i32 fp0
= tcg_temp_new_i32();
7733 gen_load_fpr32(fp0
, fs
);
7734 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7735 gen_store_fpr32(fp0
, fd
);
7736 tcg_temp_free_i32(fp0
);
7741 check_cp1_64bitmode(ctx
);
7743 TCGv_i32 fp0
= tcg_temp_new_i32();
7744 TCGv_i32 fp1
= tcg_temp_new_i32();
7746 gen_load_fpr32(fp0
, fs
);
7747 gen_load_fpr32(fp1
, ft
);
7748 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7749 tcg_temp_free_i32(fp1
);
7750 gen_store_fpr32(fp0
, fd
);
7751 tcg_temp_free_i32(fp0
);
7756 check_cp1_registers(ctx
, fd
);
7758 TCGv_i32 fp32
= tcg_temp_new_i32();
7759 TCGv_i64 fp64
= tcg_temp_new_i64();
7761 gen_load_fpr32(fp32
, fs
);
7762 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7763 tcg_temp_free_i32(fp32
);
7764 gen_store_fpr64(ctx
, fp64
, fd
);
7765 tcg_temp_free_i64(fp64
);
7771 TCGv_i32 fp0
= tcg_temp_new_i32();
7773 gen_load_fpr32(fp0
, fs
);
7774 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7775 gen_store_fpr32(fp0
, fd
);
7776 tcg_temp_free_i32(fp0
);
7781 check_cp1_64bitmode(ctx
);
7783 TCGv_i32 fp32
= tcg_temp_new_i32();
7784 TCGv_i64 fp64
= tcg_temp_new_i64();
7786 gen_load_fpr32(fp32
, fs
);
7787 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7788 tcg_temp_free_i32(fp32
);
7789 gen_store_fpr64(ctx
, fp64
, fd
);
7790 tcg_temp_free_i64(fp64
);
7795 check_cp1_64bitmode(ctx
);
7797 TCGv_i64 fp64
= tcg_temp_new_i64();
7798 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7799 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7801 gen_load_fpr32(fp32_0
, fs
);
7802 gen_load_fpr32(fp32_1
, ft
);
7803 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7804 tcg_temp_free_i32(fp32_1
);
7805 tcg_temp_free_i32(fp32_0
);
7806 gen_store_fpr64(ctx
, fp64
, fd
);
7807 tcg_temp_free_i64(fp64
);
7820 case OPC_CMP_NGLE_S
:
7827 if (ctx
->opcode
& (1 << 6)) {
7828 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7829 opn
= condnames_abs
[func
-48];
7831 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7832 opn
= condnames
[func
-48];
7836 check_cp1_registers(ctx
, fs
| ft
| fd
);
7838 TCGv_i64 fp0
= tcg_temp_new_i64();
7839 TCGv_i64 fp1
= tcg_temp_new_i64();
7841 gen_load_fpr64(ctx
, fp0
, fs
);
7842 gen_load_fpr64(ctx
, fp1
, ft
);
7843 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7844 tcg_temp_free_i64(fp1
);
7845 gen_store_fpr64(ctx
, fp0
, fd
);
7846 tcg_temp_free_i64(fp0
);
7852 check_cp1_registers(ctx
, fs
| ft
| fd
);
7854 TCGv_i64 fp0
= tcg_temp_new_i64();
7855 TCGv_i64 fp1
= tcg_temp_new_i64();
7857 gen_load_fpr64(ctx
, fp0
, fs
);
7858 gen_load_fpr64(ctx
, fp1
, ft
);
7859 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7860 tcg_temp_free_i64(fp1
);
7861 gen_store_fpr64(ctx
, fp0
, fd
);
7862 tcg_temp_free_i64(fp0
);
7868 check_cp1_registers(ctx
, fs
| ft
| fd
);
7870 TCGv_i64 fp0
= tcg_temp_new_i64();
7871 TCGv_i64 fp1
= tcg_temp_new_i64();
7873 gen_load_fpr64(ctx
, fp0
, fs
);
7874 gen_load_fpr64(ctx
, fp1
, ft
);
7875 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7876 tcg_temp_free_i64(fp1
);
7877 gen_store_fpr64(ctx
, fp0
, fd
);
7878 tcg_temp_free_i64(fp0
);
7884 check_cp1_registers(ctx
, fs
| ft
| fd
);
7886 TCGv_i64 fp0
= tcg_temp_new_i64();
7887 TCGv_i64 fp1
= tcg_temp_new_i64();
7889 gen_load_fpr64(ctx
, fp0
, fs
);
7890 gen_load_fpr64(ctx
, fp1
, ft
);
7891 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7892 tcg_temp_free_i64(fp1
);
7893 gen_store_fpr64(ctx
, fp0
, fd
);
7894 tcg_temp_free_i64(fp0
);
7900 check_cp1_registers(ctx
, fs
| fd
);
7902 TCGv_i64 fp0
= tcg_temp_new_i64();
7904 gen_load_fpr64(ctx
, fp0
, fs
);
7905 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7906 gen_store_fpr64(ctx
, fp0
, fd
);
7907 tcg_temp_free_i64(fp0
);
7912 check_cp1_registers(ctx
, fs
| fd
);
7914 TCGv_i64 fp0
= tcg_temp_new_i64();
7916 gen_load_fpr64(ctx
, fp0
, fs
);
7917 gen_helper_float_abs_d(fp0
, fp0
);
7918 gen_store_fpr64(ctx
, fp0
, fd
);
7919 tcg_temp_free_i64(fp0
);
7924 check_cp1_registers(ctx
, fs
| fd
);
7926 TCGv_i64 fp0
= tcg_temp_new_i64();
7928 gen_load_fpr64(ctx
, fp0
, fs
);
7929 gen_store_fpr64(ctx
, fp0
, fd
);
7930 tcg_temp_free_i64(fp0
);
7935 check_cp1_registers(ctx
, fs
| fd
);
7937 TCGv_i64 fp0
= tcg_temp_new_i64();
7939 gen_load_fpr64(ctx
, fp0
, fs
);
7940 gen_helper_float_chs_d(fp0
, fp0
);
7941 gen_store_fpr64(ctx
, fp0
, fd
);
7942 tcg_temp_free_i64(fp0
);
7947 check_cp1_64bitmode(ctx
);
7949 TCGv_i64 fp0
= tcg_temp_new_i64();
7951 gen_load_fpr64(ctx
, fp0
, fs
);
7952 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
7953 gen_store_fpr64(ctx
, fp0
, fd
);
7954 tcg_temp_free_i64(fp0
);
7959 check_cp1_64bitmode(ctx
);
7961 TCGv_i64 fp0
= tcg_temp_new_i64();
7963 gen_load_fpr64(ctx
, fp0
, fs
);
7964 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
7965 gen_store_fpr64(ctx
, fp0
, fd
);
7966 tcg_temp_free_i64(fp0
);
7971 check_cp1_64bitmode(ctx
);
7973 TCGv_i64 fp0
= tcg_temp_new_i64();
7975 gen_load_fpr64(ctx
, fp0
, fs
);
7976 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
7977 gen_store_fpr64(ctx
, fp0
, fd
);
7978 tcg_temp_free_i64(fp0
);
7983 check_cp1_64bitmode(ctx
);
7985 TCGv_i64 fp0
= tcg_temp_new_i64();
7987 gen_load_fpr64(ctx
, fp0
, fs
);
7988 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
7989 gen_store_fpr64(ctx
, fp0
, fd
);
7990 tcg_temp_free_i64(fp0
);
7995 check_cp1_registers(ctx
, fs
);
7997 TCGv_i32 fp32
= tcg_temp_new_i32();
7998 TCGv_i64 fp64
= tcg_temp_new_i64();
8000 gen_load_fpr64(ctx
, fp64
, fs
);
8001 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8002 tcg_temp_free_i64(fp64
);
8003 gen_store_fpr32(fp32
, fd
);
8004 tcg_temp_free_i32(fp32
);
8009 check_cp1_registers(ctx
, fs
);
8011 TCGv_i32 fp32
= tcg_temp_new_i32();
8012 TCGv_i64 fp64
= tcg_temp_new_i64();
8014 gen_load_fpr64(ctx
, fp64
, fs
);
8015 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8016 tcg_temp_free_i64(fp64
);
8017 gen_store_fpr32(fp32
, fd
);
8018 tcg_temp_free_i32(fp32
);
8023 check_cp1_registers(ctx
, fs
);
8025 TCGv_i32 fp32
= tcg_temp_new_i32();
8026 TCGv_i64 fp64
= tcg_temp_new_i64();
8028 gen_load_fpr64(ctx
, fp64
, fs
);
8029 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8030 tcg_temp_free_i64(fp64
);
8031 gen_store_fpr32(fp32
, fd
);
8032 tcg_temp_free_i32(fp32
);
8037 check_cp1_registers(ctx
, fs
);
8039 TCGv_i32 fp32
= tcg_temp_new_i32();
8040 TCGv_i64 fp64
= tcg_temp_new_i64();
8042 gen_load_fpr64(ctx
, fp64
, fs
);
8043 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8044 tcg_temp_free_i64(fp64
);
8045 gen_store_fpr32(fp32
, fd
);
8046 tcg_temp_free_i32(fp32
);
8051 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8056 int l1
= gen_new_label();
8060 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8062 fp0
= tcg_temp_new_i64();
8063 gen_load_fpr64(ctx
, fp0
, fs
);
8064 gen_store_fpr64(ctx
, fp0
, fd
);
8065 tcg_temp_free_i64(fp0
);
8072 int l1
= gen_new_label();
8076 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8077 fp0
= tcg_temp_new_i64();
8078 gen_load_fpr64(ctx
, fp0
, fs
);
8079 gen_store_fpr64(ctx
, fp0
, fd
);
8080 tcg_temp_free_i64(fp0
);
8087 check_cp1_64bitmode(ctx
);
8089 TCGv_i64 fp0
= tcg_temp_new_i64();
8091 gen_load_fpr64(ctx
, fp0
, fs
);
8092 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8093 gen_store_fpr64(ctx
, fp0
, fd
);
8094 tcg_temp_free_i64(fp0
);
8099 check_cp1_64bitmode(ctx
);
8101 TCGv_i64 fp0
= tcg_temp_new_i64();
8103 gen_load_fpr64(ctx
, fp0
, fs
);
8104 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8105 gen_store_fpr64(ctx
, fp0
, fd
);
8106 tcg_temp_free_i64(fp0
);
8111 check_cp1_64bitmode(ctx
);
8113 TCGv_i64 fp0
= tcg_temp_new_i64();
8114 TCGv_i64 fp1
= tcg_temp_new_i64();
8116 gen_load_fpr64(ctx
, fp0
, fs
);
8117 gen_load_fpr64(ctx
, fp1
, ft
);
8118 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8119 tcg_temp_free_i64(fp1
);
8120 gen_store_fpr64(ctx
, fp0
, fd
);
8121 tcg_temp_free_i64(fp0
);
8126 check_cp1_64bitmode(ctx
);
8128 TCGv_i64 fp0
= tcg_temp_new_i64();
8130 gen_load_fpr64(ctx
, fp0
, fs
);
8131 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8132 gen_store_fpr64(ctx
, fp0
, fd
);
8133 tcg_temp_free_i64(fp0
);
8138 check_cp1_64bitmode(ctx
);
8140 TCGv_i64 fp0
= tcg_temp_new_i64();
8142 gen_load_fpr64(ctx
, fp0
, fs
);
8143 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8144 gen_store_fpr64(ctx
, fp0
, fd
);
8145 tcg_temp_free_i64(fp0
);
8150 check_cp1_64bitmode(ctx
);
8152 TCGv_i64 fp0
= tcg_temp_new_i64();
8153 TCGv_i64 fp1
= tcg_temp_new_i64();
8155 gen_load_fpr64(ctx
, fp0
, fs
);
8156 gen_load_fpr64(ctx
, fp1
, ft
);
8157 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8158 tcg_temp_free_i64(fp1
);
8159 gen_store_fpr64(ctx
, fp0
, fd
);
8160 tcg_temp_free_i64(fp0
);
8173 case OPC_CMP_NGLE_D
:
8180 if (ctx
->opcode
& (1 << 6)) {
8181 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8182 opn
= condnames_abs
[func
-48];
8184 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8185 opn
= condnames
[func
-48];
8189 check_cp1_registers(ctx
, fs
);
8191 TCGv_i32 fp32
= tcg_temp_new_i32();
8192 TCGv_i64 fp64
= tcg_temp_new_i64();
8194 gen_load_fpr64(ctx
, fp64
, fs
);
8195 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8196 tcg_temp_free_i64(fp64
);
8197 gen_store_fpr32(fp32
, fd
);
8198 tcg_temp_free_i32(fp32
);
8203 check_cp1_registers(ctx
, fs
);
8205 TCGv_i32 fp32
= tcg_temp_new_i32();
8206 TCGv_i64 fp64
= tcg_temp_new_i64();
8208 gen_load_fpr64(ctx
, fp64
, fs
);
8209 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8210 tcg_temp_free_i64(fp64
);
8211 gen_store_fpr32(fp32
, fd
);
8212 tcg_temp_free_i32(fp32
);
8217 check_cp1_64bitmode(ctx
);
8219 TCGv_i64 fp0
= tcg_temp_new_i64();
8221 gen_load_fpr64(ctx
, fp0
, fs
);
8222 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8223 gen_store_fpr64(ctx
, fp0
, fd
);
8224 tcg_temp_free_i64(fp0
);
8230 TCGv_i32 fp0
= tcg_temp_new_i32();
8232 gen_load_fpr32(fp0
, fs
);
8233 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8234 gen_store_fpr32(fp0
, fd
);
8235 tcg_temp_free_i32(fp0
);
8240 check_cp1_registers(ctx
, fd
);
8242 TCGv_i32 fp32
= tcg_temp_new_i32();
8243 TCGv_i64 fp64
= tcg_temp_new_i64();
8245 gen_load_fpr32(fp32
, fs
);
8246 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8247 tcg_temp_free_i32(fp32
);
8248 gen_store_fpr64(ctx
, fp64
, fd
);
8249 tcg_temp_free_i64(fp64
);
8254 check_cp1_64bitmode(ctx
);
8256 TCGv_i32 fp32
= tcg_temp_new_i32();
8257 TCGv_i64 fp64
= tcg_temp_new_i64();
8259 gen_load_fpr64(ctx
, fp64
, fs
);
8260 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8261 tcg_temp_free_i64(fp64
);
8262 gen_store_fpr32(fp32
, fd
);
8263 tcg_temp_free_i32(fp32
);
8268 check_cp1_64bitmode(ctx
);
8270 TCGv_i64 fp0
= tcg_temp_new_i64();
8272 gen_load_fpr64(ctx
, fp0
, fs
);
8273 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8274 gen_store_fpr64(ctx
, fp0
, fd
);
8275 tcg_temp_free_i64(fp0
);
8280 check_cp1_64bitmode(ctx
);
8282 TCGv_i64 fp0
= tcg_temp_new_i64();
8284 gen_load_fpr64(ctx
, fp0
, fs
);
8285 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8286 gen_store_fpr64(ctx
, fp0
, fd
);
8287 tcg_temp_free_i64(fp0
);
8292 check_cp1_64bitmode(ctx
);
8294 TCGv_i64 fp0
= tcg_temp_new_i64();
8295 TCGv_i64 fp1
= tcg_temp_new_i64();
8297 gen_load_fpr64(ctx
, fp0
, fs
);
8298 gen_load_fpr64(ctx
, fp1
, ft
);
8299 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8300 tcg_temp_free_i64(fp1
);
8301 gen_store_fpr64(ctx
, fp0
, fd
);
8302 tcg_temp_free_i64(fp0
);
8307 check_cp1_64bitmode(ctx
);
8309 TCGv_i64 fp0
= tcg_temp_new_i64();
8310 TCGv_i64 fp1
= tcg_temp_new_i64();
8312 gen_load_fpr64(ctx
, fp0
, fs
);
8313 gen_load_fpr64(ctx
, fp1
, ft
);
8314 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8315 tcg_temp_free_i64(fp1
);
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_mul_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();
8341 gen_load_fpr64(ctx
, fp0
, fs
);
8342 gen_helper_float_abs_ps(fp0
, fp0
);
8343 gen_store_fpr64(ctx
, fp0
, fd
);
8344 tcg_temp_free_i64(fp0
);
8349 check_cp1_64bitmode(ctx
);
8351 TCGv_i64 fp0
= tcg_temp_new_i64();
8353 gen_load_fpr64(ctx
, fp0
, fs
);
8354 gen_store_fpr64(ctx
, fp0
, fd
);
8355 tcg_temp_free_i64(fp0
);
8360 check_cp1_64bitmode(ctx
);
8362 TCGv_i64 fp0
= tcg_temp_new_i64();
8364 gen_load_fpr64(ctx
, fp0
, fs
);
8365 gen_helper_float_chs_ps(fp0
, fp0
);
8366 gen_store_fpr64(ctx
, fp0
, fd
);
8367 tcg_temp_free_i64(fp0
);
8372 check_cp1_64bitmode(ctx
);
8373 gen_movcf_ps(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8377 check_cp1_64bitmode(ctx
);
8379 int l1
= gen_new_label();
8383 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8384 fp0
= tcg_temp_new_i64();
8385 gen_load_fpr64(ctx
, fp0
, fs
);
8386 gen_store_fpr64(ctx
, fp0
, fd
);
8387 tcg_temp_free_i64(fp0
);
8393 check_cp1_64bitmode(ctx
);
8395 int l1
= gen_new_label();
8399 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8400 fp0
= tcg_temp_new_i64();
8401 gen_load_fpr64(ctx
, fp0
, fs
);
8402 gen_store_fpr64(ctx
, fp0
, fd
);
8403 tcg_temp_free_i64(fp0
);
8410 check_cp1_64bitmode(ctx
);
8412 TCGv_i64 fp0
= tcg_temp_new_i64();
8413 TCGv_i64 fp1
= tcg_temp_new_i64();
8415 gen_load_fpr64(ctx
, fp0
, ft
);
8416 gen_load_fpr64(ctx
, fp1
, fs
);
8417 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8418 tcg_temp_free_i64(fp1
);
8419 gen_store_fpr64(ctx
, fp0
, fd
);
8420 tcg_temp_free_i64(fp0
);
8425 check_cp1_64bitmode(ctx
);
8427 TCGv_i64 fp0
= tcg_temp_new_i64();
8428 TCGv_i64 fp1
= tcg_temp_new_i64();
8430 gen_load_fpr64(ctx
, fp0
, ft
);
8431 gen_load_fpr64(ctx
, fp1
, fs
);
8432 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8433 tcg_temp_free_i64(fp1
);
8434 gen_store_fpr64(ctx
, fp0
, fd
);
8435 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
, fs
);
8446 gen_load_fpr64(ctx
, fp1
, ft
);
8447 gen_helper_float_recip2_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();
8459 gen_load_fpr64(ctx
, fp0
, fs
);
8460 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
8461 gen_store_fpr64(ctx
, fp0
, fd
);
8462 tcg_temp_free_i64(fp0
);
8467 check_cp1_64bitmode(ctx
);
8469 TCGv_i64 fp0
= tcg_temp_new_i64();
8471 gen_load_fpr64(ctx
, fp0
, fs
);
8472 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8473 gen_store_fpr64(ctx
, fp0
, fd
);
8474 tcg_temp_free_i64(fp0
);
8479 check_cp1_64bitmode(ctx
);
8481 TCGv_i64 fp0
= tcg_temp_new_i64();
8482 TCGv_i64 fp1
= tcg_temp_new_i64();
8484 gen_load_fpr64(ctx
, fp0
, fs
);
8485 gen_load_fpr64(ctx
, fp1
, ft
);
8486 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8487 tcg_temp_free_i64(fp1
);
8488 gen_store_fpr64(ctx
, fp0
, fd
);
8489 tcg_temp_free_i64(fp0
);
8494 check_cp1_64bitmode(ctx
);
8496 TCGv_i32 fp0
= tcg_temp_new_i32();
8498 gen_load_fpr32h(fp0
, fs
);
8499 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8500 gen_store_fpr32(fp0
, fd
);
8501 tcg_temp_free_i32(fp0
);
8506 check_cp1_64bitmode(ctx
);
8508 TCGv_i64 fp0
= tcg_temp_new_i64();
8510 gen_load_fpr64(ctx
, fp0
, fs
);
8511 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8512 gen_store_fpr64(ctx
, fp0
, fd
);
8513 tcg_temp_free_i64(fp0
);
8518 check_cp1_64bitmode(ctx
);
8520 TCGv_i32 fp0
= tcg_temp_new_i32();
8522 gen_load_fpr32(fp0
, fs
);
8523 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8524 gen_store_fpr32(fp0
, fd
);
8525 tcg_temp_free_i32(fp0
);
8530 check_cp1_64bitmode(ctx
);
8532 TCGv_i32 fp0
= tcg_temp_new_i32();
8533 TCGv_i32 fp1
= tcg_temp_new_i32();
8535 gen_load_fpr32(fp0
, fs
);
8536 gen_load_fpr32(fp1
, ft
);
8537 gen_store_fpr32h(fp0
, fd
);
8538 gen_store_fpr32(fp1
, fd
);
8539 tcg_temp_free_i32(fp0
);
8540 tcg_temp_free_i32(fp1
);
8545 check_cp1_64bitmode(ctx
);
8547 TCGv_i32 fp0
= tcg_temp_new_i32();
8548 TCGv_i32 fp1
= tcg_temp_new_i32();
8550 gen_load_fpr32(fp0
, fs
);
8551 gen_load_fpr32h(fp1
, ft
);
8552 gen_store_fpr32(fp1
, fd
);
8553 gen_store_fpr32h(fp0
, fd
);
8554 tcg_temp_free_i32(fp0
);
8555 tcg_temp_free_i32(fp1
);
8560 check_cp1_64bitmode(ctx
);
8562 TCGv_i32 fp0
= tcg_temp_new_i32();
8563 TCGv_i32 fp1
= tcg_temp_new_i32();
8565 gen_load_fpr32h(fp0
, fs
);
8566 gen_load_fpr32(fp1
, ft
);
8567 gen_store_fpr32(fp1
, fd
);
8568 gen_store_fpr32h(fp0
, 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_fpr32h(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
);
8592 case OPC_CMP_UEQ_PS
:
8593 case OPC_CMP_OLT_PS
:
8594 case OPC_CMP_ULT_PS
:
8595 case OPC_CMP_OLE_PS
:
8596 case OPC_CMP_ULE_PS
:
8598 case OPC_CMP_NGLE_PS
:
8599 case OPC_CMP_SEQ_PS
:
8600 case OPC_CMP_NGL_PS
:
8602 case OPC_CMP_NGE_PS
:
8604 case OPC_CMP_NGT_PS
:
8605 if (ctx
->opcode
& (1 << 6)) {
8606 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8607 opn
= condnames_abs
[func
-48];
8609 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8610 opn
= condnames
[func
-48];
8615 generate_exception (ctx
, EXCP_RI
);
8618 (void)opn
; /* avoid a compiler warning */
8621 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8624 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8627 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8632 /* Coprocessor 3 (FPU) */
8633 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8634 int fd
, int fs
, int base
, int index
)
8636 const char *opn
= "extended float load/store";
8638 TCGv t0
= tcg_temp_new();
8641 gen_load_gpr(t0
, index
);
8642 } else if (index
== 0) {
8643 gen_load_gpr(t0
, base
);
8645 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8647 /* Don't do NOP if destination is zero: we must perform the actual
8653 TCGv_i32 fp0
= tcg_temp_new_i32();
8655 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
8656 tcg_gen_trunc_tl_i32(fp0
, t0
);
8657 gen_store_fpr32(fp0
, fd
);
8658 tcg_temp_free_i32(fp0
);
8664 check_cp1_registers(ctx
, fd
);
8666 TCGv_i64 fp0
= tcg_temp_new_i64();
8668 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8669 gen_store_fpr64(ctx
, fp0
, fd
);
8670 tcg_temp_free_i64(fp0
);
8675 check_cp1_64bitmode(ctx
);
8676 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8678 TCGv_i64 fp0
= tcg_temp_new_i64();
8680 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8681 gen_store_fpr64(ctx
, fp0
, fd
);
8682 tcg_temp_free_i64(fp0
);
8689 TCGv_i32 fp0
= tcg_temp_new_i32();
8690 TCGv t1
= tcg_temp_new();
8692 gen_load_fpr32(fp0
, fs
);
8693 tcg_gen_extu_i32_tl(t1
, fp0
);
8694 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
8695 tcg_temp_free_i32(fp0
);
8703 check_cp1_registers(ctx
, fs
);
8705 TCGv_i64 fp0
= tcg_temp_new_i64();
8707 gen_load_fpr64(ctx
, fp0
, fs
);
8708 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8709 tcg_temp_free_i64(fp0
);
8715 check_cp1_64bitmode(ctx
);
8716 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8718 TCGv_i64 fp0
= tcg_temp_new_i64();
8720 gen_load_fpr64(ctx
, fp0
, fs
);
8721 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8722 tcg_temp_free_i64(fp0
);
8729 (void)opn
; (void)store
; /* avoid compiler warnings */
8730 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8731 regnames
[index
], regnames
[base
]);
8734 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8735 int fd
, int fr
, int fs
, int ft
)
8737 const char *opn
= "flt3_arith";
8741 check_cp1_64bitmode(ctx
);
8743 TCGv t0
= tcg_temp_local_new();
8744 TCGv_i32 fp
= tcg_temp_new_i32();
8745 TCGv_i32 fph
= tcg_temp_new_i32();
8746 int l1
= gen_new_label();
8747 int l2
= gen_new_label();
8749 gen_load_gpr(t0
, fr
);
8750 tcg_gen_andi_tl(t0
, t0
, 0x7);
8752 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8753 gen_load_fpr32(fp
, fs
);
8754 gen_load_fpr32h(fph
, fs
);
8755 gen_store_fpr32(fp
, fd
);
8756 gen_store_fpr32h(fph
, fd
);
8759 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8761 #ifdef TARGET_WORDS_BIGENDIAN
8762 gen_load_fpr32(fp
, fs
);
8763 gen_load_fpr32h(fph
, ft
);
8764 gen_store_fpr32h(fp
, fd
);
8765 gen_store_fpr32(fph
, fd
);
8767 gen_load_fpr32h(fph
, fs
);
8768 gen_load_fpr32(fp
, ft
);
8769 gen_store_fpr32(fph
, fd
);
8770 gen_store_fpr32h(fp
, fd
);
8773 tcg_temp_free_i32(fp
);
8774 tcg_temp_free_i32(fph
);
8781 TCGv_i32 fp0
= tcg_temp_new_i32();
8782 TCGv_i32 fp1
= tcg_temp_new_i32();
8783 TCGv_i32 fp2
= tcg_temp_new_i32();
8785 gen_load_fpr32(fp0
, fs
);
8786 gen_load_fpr32(fp1
, ft
);
8787 gen_load_fpr32(fp2
, fr
);
8788 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8789 tcg_temp_free_i32(fp0
);
8790 tcg_temp_free_i32(fp1
);
8791 gen_store_fpr32(fp2
, fd
);
8792 tcg_temp_free_i32(fp2
);
8798 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8800 TCGv_i64 fp0
= tcg_temp_new_i64();
8801 TCGv_i64 fp1
= tcg_temp_new_i64();
8802 TCGv_i64 fp2
= tcg_temp_new_i64();
8804 gen_load_fpr64(ctx
, fp0
, fs
);
8805 gen_load_fpr64(ctx
, fp1
, ft
);
8806 gen_load_fpr64(ctx
, fp2
, fr
);
8807 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8808 tcg_temp_free_i64(fp0
);
8809 tcg_temp_free_i64(fp1
);
8810 gen_store_fpr64(ctx
, fp2
, fd
);
8811 tcg_temp_free_i64(fp2
);
8816 check_cp1_64bitmode(ctx
);
8818 TCGv_i64 fp0
= tcg_temp_new_i64();
8819 TCGv_i64 fp1
= tcg_temp_new_i64();
8820 TCGv_i64 fp2
= tcg_temp_new_i64();
8822 gen_load_fpr64(ctx
, fp0
, fs
);
8823 gen_load_fpr64(ctx
, fp1
, ft
);
8824 gen_load_fpr64(ctx
, fp2
, fr
);
8825 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8826 tcg_temp_free_i64(fp0
);
8827 tcg_temp_free_i64(fp1
);
8828 gen_store_fpr64(ctx
, fp2
, fd
);
8829 tcg_temp_free_i64(fp2
);
8836 TCGv_i32 fp0
= tcg_temp_new_i32();
8837 TCGv_i32 fp1
= tcg_temp_new_i32();
8838 TCGv_i32 fp2
= tcg_temp_new_i32();
8840 gen_load_fpr32(fp0
, fs
);
8841 gen_load_fpr32(fp1
, ft
);
8842 gen_load_fpr32(fp2
, fr
);
8843 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8844 tcg_temp_free_i32(fp0
);
8845 tcg_temp_free_i32(fp1
);
8846 gen_store_fpr32(fp2
, fd
);
8847 tcg_temp_free_i32(fp2
);
8853 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8855 TCGv_i64 fp0
= tcg_temp_new_i64();
8856 TCGv_i64 fp1
= tcg_temp_new_i64();
8857 TCGv_i64 fp2
= tcg_temp_new_i64();
8859 gen_load_fpr64(ctx
, fp0
, fs
);
8860 gen_load_fpr64(ctx
, fp1
, ft
);
8861 gen_load_fpr64(ctx
, fp2
, fr
);
8862 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8863 tcg_temp_free_i64(fp0
);
8864 tcg_temp_free_i64(fp1
);
8865 gen_store_fpr64(ctx
, fp2
, fd
);
8866 tcg_temp_free_i64(fp2
);
8871 check_cp1_64bitmode(ctx
);
8873 TCGv_i64 fp0
= tcg_temp_new_i64();
8874 TCGv_i64 fp1
= tcg_temp_new_i64();
8875 TCGv_i64 fp2
= tcg_temp_new_i64();
8877 gen_load_fpr64(ctx
, fp0
, fs
);
8878 gen_load_fpr64(ctx
, fp1
, ft
);
8879 gen_load_fpr64(ctx
, fp2
, fr
);
8880 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8881 tcg_temp_free_i64(fp0
);
8882 tcg_temp_free_i64(fp1
);
8883 gen_store_fpr64(ctx
, fp2
, fd
);
8884 tcg_temp_free_i64(fp2
);
8891 TCGv_i32 fp0
= tcg_temp_new_i32();
8892 TCGv_i32 fp1
= tcg_temp_new_i32();
8893 TCGv_i32 fp2
= tcg_temp_new_i32();
8895 gen_load_fpr32(fp0
, fs
);
8896 gen_load_fpr32(fp1
, ft
);
8897 gen_load_fpr32(fp2
, fr
);
8898 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8899 tcg_temp_free_i32(fp0
);
8900 tcg_temp_free_i32(fp1
);
8901 gen_store_fpr32(fp2
, fd
);
8902 tcg_temp_free_i32(fp2
);
8908 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8910 TCGv_i64 fp0
= tcg_temp_new_i64();
8911 TCGv_i64 fp1
= tcg_temp_new_i64();
8912 TCGv_i64 fp2
= tcg_temp_new_i64();
8914 gen_load_fpr64(ctx
, fp0
, fs
);
8915 gen_load_fpr64(ctx
, fp1
, ft
);
8916 gen_load_fpr64(ctx
, fp2
, fr
);
8917 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8918 tcg_temp_free_i64(fp0
);
8919 tcg_temp_free_i64(fp1
);
8920 gen_store_fpr64(ctx
, fp2
, fd
);
8921 tcg_temp_free_i64(fp2
);
8926 check_cp1_64bitmode(ctx
);
8928 TCGv_i64 fp0
= tcg_temp_new_i64();
8929 TCGv_i64 fp1
= tcg_temp_new_i64();
8930 TCGv_i64 fp2
= tcg_temp_new_i64();
8932 gen_load_fpr64(ctx
, fp0
, fs
);
8933 gen_load_fpr64(ctx
, fp1
, ft
);
8934 gen_load_fpr64(ctx
, fp2
, fr
);
8935 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8936 tcg_temp_free_i64(fp0
);
8937 tcg_temp_free_i64(fp1
);
8938 gen_store_fpr64(ctx
, fp2
, fd
);
8939 tcg_temp_free_i64(fp2
);
8946 TCGv_i32 fp0
= tcg_temp_new_i32();
8947 TCGv_i32 fp1
= tcg_temp_new_i32();
8948 TCGv_i32 fp2
= tcg_temp_new_i32();
8950 gen_load_fpr32(fp0
, fs
);
8951 gen_load_fpr32(fp1
, ft
);
8952 gen_load_fpr32(fp2
, fr
);
8953 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8954 tcg_temp_free_i32(fp0
);
8955 tcg_temp_free_i32(fp1
);
8956 gen_store_fpr32(fp2
, fd
);
8957 tcg_temp_free_i32(fp2
);
8963 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8965 TCGv_i64 fp0
= tcg_temp_new_i64();
8966 TCGv_i64 fp1
= tcg_temp_new_i64();
8967 TCGv_i64 fp2
= tcg_temp_new_i64();
8969 gen_load_fpr64(ctx
, fp0
, fs
);
8970 gen_load_fpr64(ctx
, fp1
, ft
);
8971 gen_load_fpr64(ctx
, fp2
, fr
);
8972 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8973 tcg_temp_free_i64(fp0
);
8974 tcg_temp_free_i64(fp1
);
8975 gen_store_fpr64(ctx
, fp2
, fd
);
8976 tcg_temp_free_i64(fp2
);
8981 check_cp1_64bitmode(ctx
);
8983 TCGv_i64 fp0
= tcg_temp_new_i64();
8984 TCGv_i64 fp1
= tcg_temp_new_i64();
8985 TCGv_i64 fp2
= tcg_temp_new_i64();
8987 gen_load_fpr64(ctx
, fp0
, fs
);
8988 gen_load_fpr64(ctx
, fp1
, ft
);
8989 gen_load_fpr64(ctx
, fp2
, fr
);
8990 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8991 tcg_temp_free_i64(fp0
);
8992 tcg_temp_free_i64(fp1
);
8993 gen_store_fpr64(ctx
, fp2
, fd
);
8994 tcg_temp_free_i64(fp2
);
9000 generate_exception (ctx
, EXCP_RI
);
9003 (void)opn
; /* avoid a compiler warning */
9004 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9005 fregnames
[fs
], fregnames
[ft
]);
9008 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
9012 #if !defined(CONFIG_USER_ONLY)
9013 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9014 Therefore only check the ISA in system mode. */
9015 check_insn(ctx
, ISA_MIPS32R2
);
9017 t0
= tcg_temp_new();
9021 save_cpu_state(ctx
, 1);
9022 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9023 gen_store_gpr(t0
, rt
);
9026 save_cpu_state(ctx
, 1);
9027 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9028 gen_store_gpr(t0
, rt
);
9031 save_cpu_state(ctx
, 1);
9032 gen_helper_rdhwr_cc(t0
, cpu_env
);
9033 gen_store_gpr(t0
, rt
);
9036 save_cpu_state(ctx
, 1);
9037 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9038 gen_store_gpr(t0
, rt
);
9041 #if defined(CONFIG_USER_ONLY)
9042 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUMIPSState
, tls_value
));
9043 gen_store_gpr(t0
, rt
);
9046 /* XXX: Some CPUs implement this in hardware.
9047 Not supported yet. */
9049 default: /* Invalid */
9050 MIPS_INVAL("rdhwr");
9051 generate_exception(ctx
, EXCP_RI
);
9057 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9059 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9060 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9061 /* Branches completion */
9062 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9063 ctx
->bstate
= BS_BRANCH
;
9064 save_cpu_state(ctx
, 0);
9065 /* FIXME: Need to clear can_do_io. */
9066 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9068 /* unconditional branch */
9069 MIPS_DEBUG("unconditional branch");
9070 if (proc_hflags
& MIPS_HFLAG_BX
) {
9071 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9073 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9076 /* blikely taken case */
9077 MIPS_DEBUG("blikely branch taken");
9078 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9081 /* Conditional branch */
9082 MIPS_DEBUG("conditional branch");
9084 int l1
= gen_new_label();
9086 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9087 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9089 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9093 /* unconditional branch to register */
9094 MIPS_DEBUG("branch to register");
9095 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9096 TCGv t0
= tcg_temp_new();
9097 TCGv_i32 t1
= tcg_temp_new_i32();
9099 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9100 tcg_gen_trunc_tl_i32(t1
, t0
);
9102 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9103 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9104 tcg_gen_or_i32(hflags
, hflags
, t1
);
9105 tcg_temp_free_i32(t1
);
9107 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9109 tcg_gen_mov_tl(cpu_PC
, btarget
);
9111 if (ctx
->singlestep_enabled
) {
9112 save_cpu_state(ctx
, 0);
9113 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9118 MIPS_DEBUG("unknown branch");
9124 /* ISA extensions (ASEs) */
9125 /* MIPS16 extension to MIPS32 */
9127 /* MIPS16 major opcodes */
9129 M16_OPC_ADDIUSP
= 0x00,
9130 M16_OPC_ADDIUPC
= 0x01,
9133 M16_OPC_BEQZ
= 0x04,
9134 M16_OPC_BNEQZ
= 0x05,
9135 M16_OPC_SHIFT
= 0x06,
9137 M16_OPC_RRIA
= 0x08,
9138 M16_OPC_ADDIU8
= 0x09,
9139 M16_OPC_SLTI
= 0x0a,
9140 M16_OPC_SLTIU
= 0x0b,
9143 M16_OPC_CMPI
= 0x0e,
9147 M16_OPC_LWSP
= 0x12,
9151 M16_OPC_LWPC
= 0x16,
9155 M16_OPC_SWSP
= 0x1a,
9159 M16_OPC_EXTEND
= 0x1e,
9163 /* I8 funct field */
9182 /* RR funct field */
9216 /* I64 funct field */
9228 /* RR ry field for CNVT */
9230 RR_RY_CNVT_ZEB
= 0x0,
9231 RR_RY_CNVT_ZEH
= 0x1,
9232 RR_RY_CNVT_ZEW
= 0x2,
9233 RR_RY_CNVT_SEB
= 0x4,
9234 RR_RY_CNVT_SEH
= 0x5,
9235 RR_RY_CNVT_SEW
= 0x6,
9238 static int xlat (int r
)
9240 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9245 static void gen_mips16_save (DisasContext
*ctx
,
9246 int xsregs
, int aregs
,
9247 int do_ra
, int do_s0
, int do_s1
,
9250 TCGv t0
= tcg_temp_new();
9251 TCGv t1
= tcg_temp_new();
9281 generate_exception(ctx
, EXCP_RI
);
9287 gen_base_offset_addr(ctx
, t0
, 29, 12);
9288 gen_load_gpr(t1
, 7);
9289 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9292 gen_base_offset_addr(ctx
, t0
, 29, 8);
9293 gen_load_gpr(t1
, 6);
9294 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9297 gen_base_offset_addr(ctx
, t0
, 29, 4);
9298 gen_load_gpr(t1
, 5);
9299 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9302 gen_base_offset_addr(ctx
, t0
, 29, 0);
9303 gen_load_gpr(t1
, 4);
9304 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9307 gen_load_gpr(t0
, 29);
9309 #define DECR_AND_STORE(reg) do { \
9310 tcg_gen_subi_tl(t0, t0, 4); \
9311 gen_load_gpr(t1, reg); \
9312 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9376 generate_exception(ctx
, EXCP_RI
);
9392 #undef DECR_AND_STORE
9394 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9399 static void gen_mips16_restore (DisasContext
*ctx
,
9400 int xsregs
, int aregs
,
9401 int do_ra
, int do_s0
, int do_s1
,
9405 TCGv t0
= tcg_temp_new();
9406 TCGv t1
= tcg_temp_new();
9408 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9410 #define DECR_AND_LOAD(reg) do { \
9411 tcg_gen_subi_tl(t0, t0, 4); \
9412 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
9413 gen_store_gpr(t1, reg); \
9477 generate_exception(ctx
, EXCP_RI
);
9493 #undef DECR_AND_LOAD
9495 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9500 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9501 int is_64_bit
, int extended
)
9505 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9506 generate_exception(ctx
, EXCP_RI
);
9510 t0
= tcg_temp_new();
9512 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9513 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9515 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9521 #if defined(TARGET_MIPS64)
9522 static void decode_i64_mips16 (DisasContext
*ctx
,
9523 int ry
, int funct
, int16_t offset
,
9529 offset
= extended
? offset
: offset
<< 3;
9530 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9534 offset
= extended
? offset
: offset
<< 3;
9535 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9539 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9540 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9544 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9545 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9548 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9549 generate_exception(ctx
, EXCP_RI
);
9551 offset
= extended
? offset
: offset
<< 3;
9552 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9557 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9558 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9562 offset
= extended
? offset
: offset
<< 2;
9563 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9567 offset
= extended
? offset
: offset
<< 2;
9568 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9574 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9576 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9577 int op
, rx
, ry
, funct
, sa
;
9578 int16_t imm
, offset
;
9580 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9581 op
= (ctx
->opcode
>> 11) & 0x1f;
9582 sa
= (ctx
->opcode
>> 22) & 0x1f;
9583 funct
= (ctx
->opcode
>> 8) & 0x7;
9584 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9585 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9586 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9587 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9588 | (ctx
->opcode
& 0x1f));
9590 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9593 case M16_OPC_ADDIUSP
:
9594 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9596 case M16_OPC_ADDIUPC
:
9597 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9600 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9601 /* No delay slot, so just process as a normal instruction */
9604 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9605 /* No delay slot, so just process as a normal instruction */
9608 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9609 /* No delay slot, so just process as a normal instruction */
9612 switch (ctx
->opcode
& 0x3) {
9614 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9617 #if defined(TARGET_MIPS64)
9619 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9621 generate_exception(ctx
, EXCP_RI
);
9625 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9628 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9632 #if defined(TARGET_MIPS64)
9635 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9639 imm
= ctx
->opcode
& 0xf;
9640 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9641 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9642 imm
= (int16_t) (imm
<< 1) >> 1;
9643 if ((ctx
->opcode
>> 4) & 0x1) {
9644 #if defined(TARGET_MIPS64)
9646 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9648 generate_exception(ctx
, EXCP_RI
);
9651 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9654 case M16_OPC_ADDIU8
:
9655 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9658 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9661 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9666 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9669 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9672 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9675 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9679 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9680 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9681 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9682 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9683 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9684 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9685 | (ctx
->opcode
& 0xf)) << 3;
9687 if (ctx
->opcode
& (1 << 7)) {
9688 gen_mips16_save(ctx
, xsregs
, aregs
,
9689 do_ra
, do_s0
, do_s1
,
9692 gen_mips16_restore(ctx
, xsregs
, aregs
,
9693 do_ra
, do_s0
, do_s1
,
9699 generate_exception(ctx
, EXCP_RI
);
9704 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9707 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9709 #if defined(TARGET_MIPS64)
9711 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9715 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9718 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9721 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9724 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9727 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9730 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9733 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9735 #if defined(TARGET_MIPS64)
9737 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9741 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9744 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9747 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9750 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9752 #if defined(TARGET_MIPS64)
9754 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9758 generate_exception(ctx
, EXCP_RI
);
9765 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9769 int op
, cnvt_op
, op1
, offset
;
9773 op
= (ctx
->opcode
>> 11) & 0x1f;
9774 sa
= (ctx
->opcode
>> 2) & 0x7;
9775 sa
= sa
== 0 ? 8 : sa
;
9776 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9777 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9778 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9779 op1
= offset
= ctx
->opcode
& 0x1f;
9784 case M16_OPC_ADDIUSP
:
9786 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9788 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9791 case M16_OPC_ADDIUPC
:
9792 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9795 offset
= (ctx
->opcode
& 0x7ff) << 1;
9796 offset
= (int16_t)(offset
<< 4) >> 4;
9797 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9798 /* No delay slot, so just process as a normal instruction */
9801 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9802 offset
= (((ctx
->opcode
& 0x1f) << 21)
9803 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9805 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9806 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9810 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9811 /* No delay slot, so just process as a normal instruction */
9814 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9815 /* No delay slot, so just process as a normal instruction */
9818 switch (ctx
->opcode
& 0x3) {
9820 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9823 #if defined(TARGET_MIPS64)
9825 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9827 generate_exception(ctx
, EXCP_RI
);
9831 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9834 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9838 #if defined(TARGET_MIPS64)
9841 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9846 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9848 if ((ctx
->opcode
>> 4) & 1) {
9849 #if defined(TARGET_MIPS64)
9851 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9853 generate_exception(ctx
, EXCP_RI
);
9856 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9860 case M16_OPC_ADDIU8
:
9862 int16_t imm
= (int8_t) ctx
->opcode
;
9864 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9869 int16_t imm
= (uint8_t) ctx
->opcode
;
9870 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9875 int16_t imm
= (uint8_t) ctx
->opcode
;
9876 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9883 funct
= (ctx
->opcode
>> 8) & 0x7;
9886 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9887 ((int8_t)ctx
->opcode
) << 1);
9890 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9891 ((int8_t)ctx
->opcode
) << 1);
9894 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9897 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9898 ((int8_t)ctx
->opcode
) << 3);
9902 int do_ra
= ctx
->opcode
& (1 << 6);
9903 int do_s0
= ctx
->opcode
& (1 << 5);
9904 int do_s1
= ctx
->opcode
& (1 << 4);
9905 int framesize
= ctx
->opcode
& 0xf;
9907 if (framesize
== 0) {
9910 framesize
= framesize
<< 3;
9913 if (ctx
->opcode
& (1 << 7)) {
9914 gen_mips16_save(ctx
, 0, 0,
9915 do_ra
, do_s0
, do_s1
, framesize
);
9917 gen_mips16_restore(ctx
, 0, 0,
9918 do_ra
, do_s0
, do_s1
, framesize
);
9924 int rz
= xlat(ctx
->opcode
& 0x7);
9926 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9927 ((ctx
->opcode
>> 5) & 0x7);
9928 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
9932 reg32
= ctx
->opcode
& 0x1f;
9933 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
9936 generate_exception(ctx
, EXCP_RI
);
9943 int16_t imm
= (uint8_t) ctx
->opcode
;
9945 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
9950 int16_t imm
= (uint8_t) ctx
->opcode
;
9951 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
9954 #if defined(TARGET_MIPS64)
9957 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
9961 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9964 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
9967 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
9970 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
9973 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9976 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
9979 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
9981 #if defined (TARGET_MIPS64)
9984 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
9988 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9991 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
9994 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
9997 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10001 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10004 switch (ctx
->opcode
& 0x3) {
10006 mips32_op
= OPC_ADDU
;
10009 mips32_op
= OPC_SUBU
;
10011 #if defined(TARGET_MIPS64)
10013 mips32_op
= OPC_DADDU
;
10014 check_mips_64(ctx
);
10017 mips32_op
= OPC_DSUBU
;
10018 check_mips_64(ctx
);
10022 generate_exception(ctx
, EXCP_RI
);
10026 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10035 int nd
= (ctx
->opcode
>> 7) & 0x1;
10036 int link
= (ctx
->opcode
>> 6) & 0x1;
10037 int ra
= (ctx
->opcode
>> 5) & 0x1;
10040 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10045 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10049 /* XXX: not clear which exception should be raised
10050 * when in debug mode...
10052 check_insn(ctx
, ISA_MIPS32
);
10053 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10054 generate_exception(ctx
, EXCP_DBp
);
10056 generate_exception(ctx
, EXCP_DBp
);
10060 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10063 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10066 generate_exception(ctx
, EXCP_BREAK
);
10069 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10072 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10075 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10077 #if defined (TARGET_MIPS64)
10079 check_mips_64(ctx
);
10080 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10084 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10087 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10090 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10093 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10096 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10099 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10102 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
10106 case RR_RY_CNVT_ZEB
:
10107 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10109 case RR_RY_CNVT_ZEH
:
10110 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10112 case RR_RY_CNVT_SEB
:
10113 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10115 case RR_RY_CNVT_SEH
:
10116 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10118 #if defined (TARGET_MIPS64)
10119 case RR_RY_CNVT_ZEW
:
10120 check_mips_64(ctx
);
10121 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10123 case RR_RY_CNVT_SEW
:
10124 check_mips_64(ctx
);
10125 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10129 generate_exception(ctx
, EXCP_RI
);
10134 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
10136 #if defined (TARGET_MIPS64)
10138 check_mips_64(ctx
);
10139 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10142 check_mips_64(ctx
);
10143 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10146 check_mips_64(ctx
);
10147 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10150 check_mips_64(ctx
);
10151 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10155 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
10158 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
10161 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
10164 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
10166 #if defined (TARGET_MIPS64)
10168 check_mips_64(ctx
);
10169 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
10172 check_mips_64(ctx
);
10173 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
10176 check_mips_64(ctx
);
10177 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
10180 check_mips_64(ctx
);
10181 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
10185 generate_exception(ctx
, EXCP_RI
);
10189 case M16_OPC_EXTEND
:
10190 decode_extended_mips16_opc(env
, ctx
);
10193 #if defined(TARGET_MIPS64)
10195 funct
= (ctx
->opcode
>> 8) & 0x7;
10196 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10200 generate_exception(ctx
, EXCP_RI
);
10207 /* microMIPS extension to MIPS32/MIPS64 */
10210 * microMIPS32/microMIPS64 major opcodes
10212 * 1. MIPS Architecture for Programmers Volume II-B:
10213 * The microMIPS32 Instruction Set (Revision 3.05)
10215 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10217 * 2. MIPS Architecture For Programmers Volume II-A:
10218 * The MIPS64 Instruction Set (Revision 3.51)
10246 POOL32S
= 0x16, /* MIPS64 */
10247 DADDIU32
= 0x17, /* MIPS64 */
10249 /* 0x1f is reserved */
10258 /* 0x20 is reserved */
10268 /* 0x28 and 0x29 are reserved */
10278 /* 0x30 and 0x31 are reserved */
10285 SD32
= 0x36, /* MIPS64 */
10286 LD32
= 0x37, /* MIPS64 */
10288 /* 0x38 and 0x39 are reserved */
10299 /* POOL32A encoding of minor opcode field */
10302 /* These opcodes are distinguished only by bits 9..6; those bits are
10303 * what are recorded below. */
10329 /* The following can be distinguished by their lower 6 bits. */
10335 /* POOL32AXF encoding of minor opcode field extension */
10338 * 1. MIPS Architecture for Programmers Volume II-B:
10339 * The microMIPS32 Instruction Set (Revision 3.05)
10341 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10343 * 2. MIPS Architecture for Programmers VolumeIV-e:
10344 * The MIPS DSP Application-Specific Extension
10345 * to the microMIPS32 Architecture (Revision 2.34)
10347 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10362 /* begin of microMIPS32 DSP */
10364 /* bits 13..12 for 0x01 */
10370 /* bits 13..12 for 0x2a */
10376 /* bits 13..12 for 0x32 */
10380 /* end of microMIPS32 DSP */
10382 /* bits 15..12 for 0x2c */
10398 /* bits 15..12 for 0x34 */
10406 /* bits 15..12 for 0x3c */
10408 JR
= 0x0, /* alias */
10413 /* bits 15..12 for 0x05 */
10417 /* bits 15..12 for 0x0d */
10427 /* bits 15..12 for 0x15 */
10433 /* bits 15..12 for 0x1d */
10437 /* bits 15..12 for 0x2d */
10442 /* bits 15..12 for 0x35 */
10449 /* POOL32B encoding of minor opcode field (bits 15..12) */
10465 /* POOL32C encoding of minor opcode field (bits 15..12) */
10473 /* 0xa is reserved */
10480 /* 0x6 is reserved */
10486 /* POOL32F encoding of minor opcode field (bits 5..0) */
10489 /* These are the bit 7..6 values */
10500 /* These are the bit 8..6 values */
10544 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10548 /* POOL32Fxf encoding of minor opcode extension field */
10586 /* POOL32I encoding of minor opcode field (bits 25..21) */
10611 /* These overlap and are distinguished by bit16 of the instruction */
10620 /* POOL16A encoding of minor opcode field */
10627 /* POOL16B encoding of minor opcode field */
10634 /* POOL16C encoding of minor opcode field */
10654 /* POOL16D encoding of minor opcode field */
10661 /* POOL16E encoding of minor opcode field */
10668 static int mmreg (int r
)
10670 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10675 /* Used for 16-bit store instructions. */
10676 static int mmreg2 (int r
)
10678 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10683 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10684 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10685 #define uMIPS_RS2(op) uMIPS_RS(op)
10686 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10687 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10688 #define uMIPS_RS5(op) (op & 0x1f)
10690 /* Signed immediate */
10691 #define SIMM(op, start, width) \
10692 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10695 /* Zero-extended immediate */
10696 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10698 static void gen_addiur1sp(DisasContext
*ctx
)
10700 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10702 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10705 static void gen_addiur2(DisasContext
*ctx
)
10707 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10708 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10709 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10711 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10714 static void gen_addiusp(DisasContext
*ctx
)
10716 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10719 if (encoded
<= 1) {
10720 decoded
= 256 + encoded
;
10721 } else if (encoded
<= 255) {
10723 } else if (encoded
<= 509) {
10724 decoded
= encoded
- 512;
10726 decoded
= encoded
- 768;
10729 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10732 static void gen_addius5(DisasContext
*ctx
)
10734 int imm
= SIMM(ctx
->opcode
, 1, 4);
10735 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10737 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10740 static void gen_andi16(DisasContext
*ctx
)
10742 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10743 31, 32, 63, 64, 255, 32768, 65535 };
10744 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10745 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10746 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10748 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10751 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10752 int base
, int16_t offset
)
10754 const char *opn
= "ldst_multiple";
10758 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10759 generate_exception(ctx
, EXCP_RI
);
10763 t0
= tcg_temp_new();
10765 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10767 t1
= tcg_const_tl(reglist
);
10768 t2
= tcg_const_i32(ctx
->mem_idx
);
10770 save_cpu_state(ctx
, 1);
10773 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10777 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10780 #ifdef TARGET_MIPS64
10782 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10786 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10792 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10795 tcg_temp_free_i32(t2
);
10799 static void gen_pool16c_insn(DisasContext
*ctx
)
10801 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10802 int rs
= mmreg(ctx
->opcode
& 0x7);
10805 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10810 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10816 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10822 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10828 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10835 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10836 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10838 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10847 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10848 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10850 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10857 int reg
= ctx
->opcode
& 0x1f;
10859 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10865 int reg
= ctx
->opcode
& 0x1f;
10867 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10868 /* Let normal delay slot handling in our caller take us
10869 to the branch target. */
10881 int reg
= ctx
->opcode
& 0x1f;
10883 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10888 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
10892 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
10895 generate_exception(ctx
, EXCP_BREAK
);
10898 /* XXX: not clear which exception should be raised
10899 * when in debug mode...
10901 check_insn(ctx
, ISA_MIPS32
);
10902 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10903 generate_exception(ctx
, EXCP_DBp
);
10905 generate_exception(ctx
, EXCP_DBp
);
10908 case JRADDIUSP
+ 0:
10909 case JRADDIUSP
+ 1:
10911 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10913 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10914 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10915 /* Let normal delay slot handling in our caller take us
10916 to the branch target. */
10920 generate_exception(ctx
, EXCP_RI
);
10925 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10927 TCGv t0
= tcg_temp_new();
10928 TCGv t1
= tcg_temp_new();
10930 gen_load_gpr(t0
, base
);
10933 gen_load_gpr(t1
, index
);
10934 tcg_gen_shli_tl(t1
, t1
, 2);
10935 gen_op_addr_add(ctx
, t0
, t1
, t0
);
10938 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10939 gen_store_gpr(t1
, rd
);
10945 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
10946 int base
, int16_t offset
)
10948 const char *opn
= "ldst_pair";
10951 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
10952 generate_exception(ctx
, EXCP_RI
);
10956 t0
= tcg_temp_new();
10957 t1
= tcg_temp_new();
10959 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10964 generate_exception(ctx
, EXCP_RI
);
10967 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10968 gen_store_gpr(t1
, rd
);
10969 tcg_gen_movi_tl(t1
, 4);
10970 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10971 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10972 gen_store_gpr(t1
, rd
+1);
10976 gen_load_gpr(t1
, rd
);
10977 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
10978 tcg_gen_movi_tl(t1
, 4);
10979 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10980 gen_load_gpr(t1
, rd
+1);
10981 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
10984 #ifdef TARGET_MIPS64
10987 generate_exception(ctx
, EXCP_RI
);
10990 tcg_gen_qemu_ld64(t1
, t0
, ctx
->mem_idx
);
10991 gen_store_gpr(t1
, rd
);
10992 tcg_gen_movi_tl(t1
, 8);
10993 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10994 tcg_gen_qemu_ld64(t1
, t0
, ctx
->mem_idx
);
10995 gen_store_gpr(t1
, rd
+1);
10999 gen_load_gpr(t1
, rd
);
11000 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
11001 tcg_gen_movi_tl(t1
, 8);
11002 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11003 gen_load_gpr(t1
, rd
+1);
11004 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
11009 (void)opn
; /* avoid a compiler warning */
11010 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11015 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
11017 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11018 int minor
= (ctx
->opcode
>> 12) & 0xf;
11019 uint32_t mips32_op
;
11021 switch (extension
) {
11023 mips32_op
= OPC_TEQ
;
11026 mips32_op
= OPC_TGE
;
11029 mips32_op
= OPC_TGEU
;
11032 mips32_op
= OPC_TLT
;
11035 mips32_op
= OPC_TLTU
;
11038 mips32_op
= OPC_TNE
;
11040 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11042 #ifndef CONFIG_USER_ONLY
11045 check_cp0_enabled(ctx
);
11047 /* Treat as NOP. */
11050 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11054 check_cp0_enabled(ctx
);
11056 TCGv t0
= tcg_temp_new();
11058 gen_load_gpr(t0
, rt
);
11059 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11065 switch (minor
& 3) {
11067 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11070 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11073 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11076 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11079 goto pool32axf_invalid
;
11083 switch (minor
& 3) {
11085 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11088 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11091 goto pool32axf_invalid
;
11097 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11100 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11103 mips32_op
= OPC_CLO
;
11106 mips32_op
= OPC_CLZ
;
11108 check_insn(ctx
, ISA_MIPS32
);
11109 gen_cl(ctx
, mips32_op
, rt
, rs
);
11112 gen_rdhwr(ctx
, rt
, rs
);
11115 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11118 mips32_op
= OPC_MULT
;
11121 mips32_op
= OPC_MULTU
;
11124 mips32_op
= OPC_DIV
;
11127 mips32_op
= OPC_DIVU
;
11130 check_insn(ctx
, ISA_MIPS32
);
11131 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11134 mips32_op
= OPC_MADD
;
11137 mips32_op
= OPC_MADDU
;
11140 mips32_op
= OPC_MSUB
;
11143 mips32_op
= OPC_MSUBU
;
11145 check_insn(ctx
, ISA_MIPS32
);
11146 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11149 goto pool32axf_invalid
;
11160 generate_exception_err(ctx
, EXCP_CpU
, 2);
11163 goto pool32axf_invalid
;
11170 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11174 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11177 goto pool32axf_invalid
;
11183 check_cp0_enabled(ctx
);
11184 check_insn(ctx
, ISA_MIPS32R2
);
11185 gen_load_srsgpr(rt
, rs
);
11188 check_cp0_enabled(ctx
);
11189 check_insn(ctx
, ISA_MIPS32R2
);
11190 gen_store_srsgpr(rt
, rs
);
11193 goto pool32axf_invalid
;
11196 #ifndef CONFIG_USER_ONLY
11200 mips32_op
= OPC_TLBP
;
11203 mips32_op
= OPC_TLBR
;
11206 mips32_op
= OPC_TLBWI
;
11209 mips32_op
= OPC_TLBWR
;
11212 mips32_op
= OPC_WAIT
;
11215 mips32_op
= OPC_DERET
;
11218 mips32_op
= OPC_ERET
;
11220 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11223 goto pool32axf_invalid
;
11229 check_cp0_enabled(ctx
);
11231 TCGv t0
= tcg_temp_new();
11233 save_cpu_state(ctx
, 1);
11234 gen_helper_di(t0
, cpu_env
);
11235 gen_store_gpr(t0
, rs
);
11236 /* Stop translation as we may have switched the execution mode */
11237 ctx
->bstate
= BS_STOP
;
11242 check_cp0_enabled(ctx
);
11244 TCGv t0
= tcg_temp_new();
11246 save_cpu_state(ctx
, 1);
11247 gen_helper_ei(t0
, cpu_env
);
11248 gen_store_gpr(t0
, rs
);
11249 /* Stop translation as we may have switched the execution mode */
11250 ctx
->bstate
= BS_STOP
;
11255 goto pool32axf_invalid
;
11265 generate_exception(ctx
, EXCP_SYSCALL
);
11266 ctx
->bstate
= BS_STOP
;
11269 check_insn(ctx
, ISA_MIPS32
);
11270 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11271 generate_exception(ctx
, EXCP_DBp
);
11273 generate_exception(ctx
, EXCP_DBp
);
11277 goto pool32axf_invalid
;
11281 switch (minor
& 3) {
11283 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
11286 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
11289 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
11292 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
11295 goto pool32axf_invalid
;
11301 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
11304 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
11307 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
11310 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
11313 goto pool32axf_invalid
;
11318 MIPS_INVAL("pool32axf");
11319 generate_exception(ctx
, EXCP_RI
);
11324 /* Values for microMIPS fmt field. Variable-width, depending on which
11325 formats the instruction supports. */
11344 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11346 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11347 uint32_t mips32_op
;
11349 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11350 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11351 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11353 switch (extension
) {
11354 case FLOAT_1BIT_FMT(CFC1
, 0):
11355 mips32_op
= OPC_CFC1
;
11357 case FLOAT_1BIT_FMT(CTC1
, 0):
11358 mips32_op
= OPC_CTC1
;
11360 case FLOAT_1BIT_FMT(MFC1
, 0):
11361 mips32_op
= OPC_MFC1
;
11363 case FLOAT_1BIT_FMT(MTC1
, 0):
11364 mips32_op
= OPC_MTC1
;
11366 case FLOAT_1BIT_FMT(MFHC1
, 0):
11367 mips32_op
= OPC_MFHC1
;
11369 case FLOAT_1BIT_FMT(MTHC1
, 0):
11370 mips32_op
= OPC_MTHC1
;
11372 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11375 /* Reciprocal square root */
11376 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11377 mips32_op
= OPC_RSQRT_S
;
11379 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11380 mips32_op
= OPC_RSQRT_D
;
11384 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11385 mips32_op
= OPC_SQRT_S
;
11387 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11388 mips32_op
= OPC_SQRT_D
;
11392 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11393 mips32_op
= OPC_RECIP_S
;
11395 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11396 mips32_op
= OPC_RECIP_D
;
11400 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11401 mips32_op
= OPC_FLOOR_L_S
;
11403 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11404 mips32_op
= OPC_FLOOR_L_D
;
11406 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11407 mips32_op
= OPC_FLOOR_W_S
;
11409 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11410 mips32_op
= OPC_FLOOR_W_D
;
11414 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11415 mips32_op
= OPC_CEIL_L_S
;
11417 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11418 mips32_op
= OPC_CEIL_L_D
;
11420 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11421 mips32_op
= OPC_CEIL_W_S
;
11423 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11424 mips32_op
= OPC_CEIL_W_D
;
11428 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11429 mips32_op
= OPC_TRUNC_L_S
;
11431 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11432 mips32_op
= OPC_TRUNC_L_D
;
11434 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11435 mips32_op
= OPC_TRUNC_W_S
;
11437 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11438 mips32_op
= OPC_TRUNC_W_D
;
11442 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11443 mips32_op
= OPC_ROUND_L_S
;
11445 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11446 mips32_op
= OPC_ROUND_L_D
;
11448 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11449 mips32_op
= OPC_ROUND_W_S
;
11451 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11452 mips32_op
= OPC_ROUND_W_D
;
11455 /* Integer to floating-point conversion */
11456 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11457 mips32_op
= OPC_CVT_L_S
;
11459 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11460 mips32_op
= OPC_CVT_L_D
;
11462 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11463 mips32_op
= OPC_CVT_W_S
;
11465 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11466 mips32_op
= OPC_CVT_W_D
;
11469 /* Paired-foo conversions */
11470 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11471 mips32_op
= OPC_CVT_S_PL
;
11473 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11474 mips32_op
= OPC_CVT_S_PU
;
11476 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11477 mips32_op
= OPC_CVT_PW_PS
;
11479 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11480 mips32_op
= OPC_CVT_PS_PW
;
11483 /* Floating-point moves */
11484 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11485 mips32_op
= OPC_MOV_S
;
11487 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11488 mips32_op
= OPC_MOV_D
;
11490 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11491 mips32_op
= OPC_MOV_PS
;
11494 /* Absolute value */
11495 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11496 mips32_op
= OPC_ABS_S
;
11498 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11499 mips32_op
= OPC_ABS_D
;
11501 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11502 mips32_op
= OPC_ABS_PS
;
11506 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11507 mips32_op
= OPC_NEG_S
;
11509 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11510 mips32_op
= OPC_NEG_D
;
11512 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11513 mips32_op
= OPC_NEG_PS
;
11516 /* Reciprocal square root step */
11517 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11518 mips32_op
= OPC_RSQRT1_S
;
11520 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11521 mips32_op
= OPC_RSQRT1_D
;
11523 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11524 mips32_op
= OPC_RSQRT1_PS
;
11527 /* Reciprocal step */
11528 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11529 mips32_op
= OPC_RECIP1_S
;
11531 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11532 mips32_op
= OPC_RECIP1_S
;
11534 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11535 mips32_op
= OPC_RECIP1_PS
;
11538 /* Conversions from double */
11539 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11540 mips32_op
= OPC_CVT_D_S
;
11542 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11543 mips32_op
= OPC_CVT_D_W
;
11545 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11546 mips32_op
= OPC_CVT_D_L
;
11549 /* Conversions from single */
11550 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11551 mips32_op
= OPC_CVT_S_D
;
11553 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11554 mips32_op
= OPC_CVT_S_W
;
11556 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11557 mips32_op
= OPC_CVT_S_L
;
11559 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11562 /* Conditional moves on floating-point codes */
11563 case COND_FLOAT_MOV(MOVT
, 0):
11564 case COND_FLOAT_MOV(MOVT
, 1):
11565 case COND_FLOAT_MOV(MOVT
, 2):
11566 case COND_FLOAT_MOV(MOVT
, 3):
11567 case COND_FLOAT_MOV(MOVT
, 4):
11568 case COND_FLOAT_MOV(MOVT
, 5):
11569 case COND_FLOAT_MOV(MOVT
, 6):
11570 case COND_FLOAT_MOV(MOVT
, 7):
11571 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11573 case COND_FLOAT_MOV(MOVF
, 0):
11574 case COND_FLOAT_MOV(MOVF
, 1):
11575 case COND_FLOAT_MOV(MOVF
, 2):
11576 case COND_FLOAT_MOV(MOVF
, 3):
11577 case COND_FLOAT_MOV(MOVF
, 4):
11578 case COND_FLOAT_MOV(MOVF
, 5):
11579 case COND_FLOAT_MOV(MOVF
, 6):
11580 case COND_FLOAT_MOV(MOVF
, 7):
11581 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11584 MIPS_INVAL("pool32fxf");
11585 generate_exception(ctx
, EXCP_RI
);
11590 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11595 int rt
, rs
, rd
, rr
;
11597 uint32_t op
, minor
, mips32_op
;
11598 uint32_t cond
, fmt
, cc
;
11600 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11601 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11603 rt
= (ctx
->opcode
>> 21) & 0x1f;
11604 rs
= (ctx
->opcode
>> 16) & 0x1f;
11605 rd
= (ctx
->opcode
>> 11) & 0x1f;
11606 rr
= (ctx
->opcode
>> 6) & 0x1f;
11607 imm
= (int16_t) ctx
->opcode
;
11609 op
= (ctx
->opcode
>> 26) & 0x3f;
11612 minor
= ctx
->opcode
& 0x3f;
11615 minor
= (ctx
->opcode
>> 6) & 0xf;
11618 mips32_op
= OPC_SLL
;
11621 mips32_op
= OPC_SRA
;
11624 mips32_op
= OPC_SRL
;
11627 mips32_op
= OPC_ROTR
;
11629 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11632 goto pool32a_invalid
;
11636 minor
= (ctx
->opcode
>> 6) & 0xf;
11640 mips32_op
= OPC_ADD
;
11643 mips32_op
= OPC_ADDU
;
11646 mips32_op
= OPC_SUB
;
11649 mips32_op
= OPC_SUBU
;
11652 mips32_op
= OPC_MUL
;
11654 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11658 mips32_op
= OPC_SLLV
;
11661 mips32_op
= OPC_SRLV
;
11664 mips32_op
= OPC_SRAV
;
11667 mips32_op
= OPC_ROTRV
;
11669 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11671 /* Logical operations */
11673 mips32_op
= OPC_AND
;
11676 mips32_op
= OPC_OR
;
11679 mips32_op
= OPC_NOR
;
11682 mips32_op
= OPC_XOR
;
11684 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11686 /* Set less than */
11688 mips32_op
= OPC_SLT
;
11691 mips32_op
= OPC_SLTU
;
11693 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11696 goto pool32a_invalid
;
11700 minor
= (ctx
->opcode
>> 6) & 0xf;
11702 /* Conditional moves */
11704 mips32_op
= OPC_MOVN
;
11707 mips32_op
= OPC_MOVZ
;
11709 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11712 gen_ldxs(ctx
, rs
, rt
, rd
);
11715 goto pool32a_invalid
;
11719 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11722 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11725 gen_pool32axf(env
, ctx
, rt
, rs
);
11728 generate_exception(ctx
, EXCP_BREAK
);
11732 MIPS_INVAL("pool32a");
11733 generate_exception(ctx
, EXCP_RI
);
11738 minor
= (ctx
->opcode
>> 12) & 0xf;
11741 check_cp0_enabled(ctx
);
11742 /* Treat as no-op. */
11746 /* COP2: Not implemented. */
11747 generate_exception_err(ctx
, EXCP_CpU
, 2);
11751 #ifdef TARGET_MIPS64
11755 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11759 #ifdef TARGET_MIPS64
11763 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11766 MIPS_INVAL("pool32b");
11767 generate_exception(ctx
, EXCP_RI
);
11772 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
11773 minor
= ctx
->opcode
& 0x3f;
11774 check_cp1_enabled(ctx
);
11777 mips32_op
= OPC_ALNV_PS
;
11780 mips32_op
= OPC_MADD_S
;
11783 mips32_op
= OPC_MADD_D
;
11786 mips32_op
= OPC_MADD_PS
;
11789 mips32_op
= OPC_MSUB_S
;
11792 mips32_op
= OPC_MSUB_D
;
11795 mips32_op
= OPC_MSUB_PS
;
11798 mips32_op
= OPC_NMADD_S
;
11801 mips32_op
= OPC_NMADD_D
;
11804 mips32_op
= OPC_NMADD_PS
;
11807 mips32_op
= OPC_NMSUB_S
;
11810 mips32_op
= OPC_NMSUB_D
;
11813 mips32_op
= OPC_NMSUB_PS
;
11815 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11817 case CABS_COND_FMT
:
11818 cond
= (ctx
->opcode
>> 6) & 0xf;
11819 cc
= (ctx
->opcode
>> 13) & 0x7;
11820 fmt
= (ctx
->opcode
>> 10) & 0x3;
11823 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11826 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11829 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11832 goto pool32f_invalid
;
11836 cond
= (ctx
->opcode
>> 6) & 0xf;
11837 cc
= (ctx
->opcode
>> 13) & 0x7;
11838 fmt
= (ctx
->opcode
>> 10) & 0x3;
11841 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11844 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11847 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11850 goto pool32f_invalid
;
11854 gen_pool32fxf(ctx
, rt
, rs
);
11858 switch ((ctx
->opcode
>> 6) & 0x7) {
11860 mips32_op
= OPC_PLL_PS
;
11863 mips32_op
= OPC_PLU_PS
;
11866 mips32_op
= OPC_PUL_PS
;
11869 mips32_op
= OPC_PUU_PS
;
11872 mips32_op
= OPC_CVT_PS_S
;
11874 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11877 goto pool32f_invalid
;
11882 switch ((ctx
->opcode
>> 6) & 0x7) {
11884 mips32_op
= OPC_LWXC1
;
11887 mips32_op
= OPC_SWXC1
;
11890 mips32_op
= OPC_LDXC1
;
11893 mips32_op
= OPC_SDXC1
;
11896 mips32_op
= OPC_LUXC1
;
11899 mips32_op
= OPC_SUXC1
;
11901 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11904 goto pool32f_invalid
;
11909 fmt
= (ctx
->opcode
>> 9) & 0x3;
11910 switch ((ctx
->opcode
>> 6) & 0x7) {
11914 mips32_op
= OPC_RSQRT2_S
;
11917 mips32_op
= OPC_RSQRT2_D
;
11920 mips32_op
= OPC_RSQRT2_PS
;
11923 goto pool32f_invalid
;
11929 mips32_op
= OPC_RECIP2_S
;
11932 mips32_op
= OPC_RECIP2_D
;
11935 mips32_op
= OPC_RECIP2_PS
;
11938 goto pool32f_invalid
;
11942 mips32_op
= OPC_ADDR_PS
;
11945 mips32_op
= OPC_MULR_PS
;
11947 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11950 goto pool32f_invalid
;
11954 /* MOV[FT].fmt and PREFX */
11955 cc
= (ctx
->opcode
>> 13) & 0x7;
11956 fmt
= (ctx
->opcode
>> 9) & 0x3;
11957 switch ((ctx
->opcode
>> 6) & 0x7) {
11961 gen_movcf_s(rs
, rt
, cc
, 0);
11964 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
11967 gen_movcf_ps(rs
, rt
, cc
, 0);
11970 goto pool32f_invalid
;
11976 gen_movcf_s(rs
, rt
, cc
, 1);
11979 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
11982 gen_movcf_ps(rs
, rt
, cc
, 1);
11985 goto pool32f_invalid
;
11991 goto pool32f_invalid
;
11994 #define FINSN_3ARG_SDPS(prfx) \
11995 switch ((ctx->opcode >> 8) & 0x3) { \
11997 mips32_op = OPC_##prfx##_S; \
12000 mips32_op = OPC_##prfx##_D; \
12002 case FMT_SDPS_PS: \
12003 mips32_op = OPC_##prfx##_PS; \
12006 goto pool32f_invalid; \
12009 /* regular FP ops */
12010 switch ((ctx
->opcode
>> 6) & 0x3) {
12012 FINSN_3ARG_SDPS(ADD
);
12015 FINSN_3ARG_SDPS(SUB
);
12018 FINSN_3ARG_SDPS(MUL
);
12021 fmt
= (ctx
->opcode
>> 8) & 0x3;
12023 mips32_op
= OPC_DIV_D
;
12024 } else if (fmt
== 0) {
12025 mips32_op
= OPC_DIV_S
;
12027 goto pool32f_invalid
;
12031 goto pool32f_invalid
;
12036 switch ((ctx
->opcode
>> 6) & 0x3) {
12038 FINSN_3ARG_SDPS(MOVN
);
12041 FINSN_3ARG_SDPS(MOVZ
);
12044 goto pool32f_invalid
;
12048 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12052 MIPS_INVAL("pool32f");
12053 generate_exception(ctx
, EXCP_RI
);
12057 generate_exception_err(ctx
, EXCP_CpU
, 1);
12061 minor
= (ctx
->opcode
>> 21) & 0x1f;
12064 mips32_op
= OPC_BLTZ
;
12067 mips32_op
= OPC_BLTZAL
;
12070 mips32_op
= OPC_BLTZALS
;
12073 mips32_op
= OPC_BGEZ
;
12076 mips32_op
= OPC_BGEZAL
;
12079 mips32_op
= OPC_BGEZALS
;
12082 mips32_op
= OPC_BLEZ
;
12085 mips32_op
= OPC_BGTZ
;
12087 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12092 mips32_op
= OPC_TLTI
;
12095 mips32_op
= OPC_TGEI
;
12098 mips32_op
= OPC_TLTIU
;
12101 mips32_op
= OPC_TGEIU
;
12104 mips32_op
= OPC_TNEI
;
12107 mips32_op
= OPC_TEQI
;
12109 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12114 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12115 4, rs
, 0, imm
<< 1);
12116 /* Compact branches don't have a delay slot, so just let
12117 the normal delay slot handling take us to the branch
12121 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12127 /* COP2: Not implemented. */
12128 generate_exception_err(ctx
, EXCP_CpU
, 2);
12131 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12134 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12137 mips32_op
= OPC_BC1FANY4
;
12140 mips32_op
= OPC_BC1TANY4
;
12143 check_insn(ctx
, ASE_MIPS3D
);
12146 gen_compute_branch1(ctx
, mips32_op
,
12147 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12151 /* MIPS DSP: not implemented */
12154 MIPS_INVAL("pool32i");
12155 generate_exception(ctx
, EXCP_RI
);
12160 minor
= (ctx
->opcode
>> 12) & 0xf;
12163 mips32_op
= OPC_LWL
;
12166 mips32_op
= OPC_SWL
;
12169 mips32_op
= OPC_LWR
;
12172 mips32_op
= OPC_SWR
;
12174 #if defined(TARGET_MIPS64)
12176 mips32_op
= OPC_LDL
;
12179 mips32_op
= OPC_SDL
;
12182 mips32_op
= OPC_LDR
;
12185 mips32_op
= OPC_SDR
;
12188 mips32_op
= OPC_LWU
;
12191 mips32_op
= OPC_LLD
;
12195 mips32_op
= OPC_LL
;
12198 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12201 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12204 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12206 #if defined(TARGET_MIPS64)
12208 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12212 /* Treat as no-op */
12215 MIPS_INVAL("pool32c");
12216 generate_exception(ctx
, EXCP_RI
);
12221 mips32_op
= OPC_ADDI
;
12224 mips32_op
= OPC_ADDIU
;
12226 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12229 /* Logical operations */
12231 mips32_op
= OPC_ORI
;
12234 mips32_op
= OPC_XORI
;
12237 mips32_op
= OPC_ANDI
;
12239 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12242 /* Set less than immediate */
12244 mips32_op
= OPC_SLTI
;
12247 mips32_op
= OPC_SLTIU
;
12249 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12252 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12253 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12256 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12257 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12260 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12263 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12266 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12267 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12270 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12271 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12273 /* Floating point (COP1) */
12275 mips32_op
= OPC_LWC1
;
12278 mips32_op
= OPC_LDC1
;
12281 mips32_op
= OPC_SWC1
;
12284 mips32_op
= OPC_SDC1
;
12286 gen_cop1_ldst(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12290 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12291 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12293 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12296 /* Loads and stores */
12298 mips32_op
= OPC_LB
;
12301 mips32_op
= OPC_LBU
;
12304 mips32_op
= OPC_LH
;
12307 mips32_op
= OPC_LHU
;
12310 mips32_op
= OPC_LW
;
12312 #ifdef TARGET_MIPS64
12314 mips32_op
= OPC_LD
;
12317 mips32_op
= OPC_SD
;
12321 mips32_op
= OPC_SB
;
12324 mips32_op
= OPC_SH
;
12327 mips32_op
= OPC_SW
;
12330 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12333 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12336 generate_exception(ctx
, EXCP_RI
);
12341 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
12345 /* make sure instructions are on a halfword boundary */
12346 if (ctx
->pc
& 0x1) {
12347 env
->CP0_BadVAddr
= ctx
->pc
;
12348 generate_exception(ctx
, EXCP_AdEL
);
12349 ctx
->bstate
= BS_STOP
;
12353 op
= (ctx
->opcode
>> 10) & 0x3f;
12354 /* Enforce properly-sized instructions in a delay slot */
12355 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12356 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12394 if (bits
& MIPS_HFLAG_BDS16
) {
12395 generate_exception(ctx
, EXCP_RI
);
12396 /* Just stop translation; the user is confused. */
12397 ctx
->bstate
= BS_STOP
;
12422 if (bits
& MIPS_HFLAG_BDS32
) {
12423 generate_exception(ctx
, EXCP_RI
);
12424 /* Just stop translation; the user is confused. */
12425 ctx
->bstate
= BS_STOP
;
12436 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12437 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12438 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12441 switch (ctx
->opcode
& 0x1) {
12450 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12455 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12456 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12457 int amount
= (ctx
->opcode
>> 1) & 0x7;
12459 amount
= amount
== 0 ? 8 : amount
;
12461 switch (ctx
->opcode
& 0x1) {
12470 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12474 gen_pool16c_insn(ctx
);
12478 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12479 int rb
= 28; /* GP */
12480 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12482 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12486 if (ctx
->opcode
& 1) {
12487 generate_exception(ctx
, EXCP_RI
);
12490 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12491 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12492 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12493 int rd
, rs
, re
, rt
;
12494 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12495 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12496 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12498 rd
= rd_enc
[enc_dest
];
12499 re
= re_enc
[enc_dest
];
12500 rs
= rs_rt_enc
[enc_rs
];
12501 rt
= rs_rt_enc
[enc_rt
];
12503 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12504 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12509 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12510 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12511 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12512 offset
= (offset
== 0xf ? -1 : offset
);
12514 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12519 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12520 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12521 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12523 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12528 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12529 int rb
= 29; /* SP */
12530 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12532 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12537 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12538 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12539 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12541 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12546 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12547 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12548 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12550 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12555 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12556 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12557 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12559 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12564 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12565 int rb
= 29; /* SP */
12566 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12568 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12573 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12574 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12575 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12577 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12582 int rd
= uMIPS_RD5(ctx
->opcode
);
12583 int rs
= uMIPS_RS5(ctx
->opcode
);
12585 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12592 switch (ctx
->opcode
& 0x1) {
12602 switch (ctx
->opcode
& 0x1) {
12607 gen_addiur1sp(ctx
);
12612 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12613 SIMM(ctx
->opcode
, 0, 10) << 1);
12617 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12618 mmreg(uMIPS_RD(ctx
->opcode
)),
12619 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12623 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12624 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12626 imm
= (imm
== 0x7f ? -1 : imm
);
12627 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12637 generate_exception(ctx
, EXCP_RI
);
12640 decode_micromips32_opc (env
, ctx
, op
);
12647 /* SmartMIPS extension to MIPS32 */
12649 #if defined(TARGET_MIPS64)
12651 /* MDMX extension to MIPS64 */
12655 /* MIPSDSP functions. */
12656 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12657 int rd
, int base
, int offset
)
12659 const char *opn
= "ldx";
12663 t0
= tcg_temp_new();
12666 gen_load_gpr(t0
, offset
);
12667 } else if (offset
== 0) {
12668 gen_load_gpr(t0
, base
);
12670 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12675 tcg_gen_qemu_ld8u(t0
, t0
, ctx
->mem_idx
);
12676 gen_store_gpr(t0
, rd
);
12680 tcg_gen_qemu_ld16s(t0
, t0
, ctx
->mem_idx
);
12681 gen_store_gpr(t0
, rd
);
12685 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
12686 gen_store_gpr(t0
, rd
);
12689 #if defined(TARGET_MIPS64)
12691 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
12692 gen_store_gpr(t0
, rd
);
12697 (void)opn
; /* avoid a compiler warning */
12698 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12699 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12703 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12704 int ret
, int v1
, int v2
)
12706 const char *opn
= "mipsdsp arith";
12711 /* Treat as NOP. */
12716 v1_t
= tcg_temp_new();
12717 v2_t
= tcg_temp_new();
12719 gen_load_gpr(v1_t
, v1
);
12720 gen_load_gpr(v2_t
, v2
);
12723 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12724 case OPC_MULT_G_2E
:
12728 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12730 case OPC_ADDUH_R_QB
:
12731 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12734 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12736 case OPC_ADDQH_R_PH
:
12737 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12740 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12742 case OPC_ADDQH_R_W
:
12743 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12746 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12748 case OPC_SUBUH_R_QB
:
12749 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12752 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12754 case OPC_SUBQH_R_PH
:
12755 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12758 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12760 case OPC_SUBQH_R_W
:
12761 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12765 case OPC_ABSQ_S_PH_DSP
:
12767 case OPC_ABSQ_S_QB
:
12769 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12771 case OPC_ABSQ_S_PH
:
12773 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12777 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12779 case OPC_PRECEQ_W_PHL
:
12781 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12782 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12784 case OPC_PRECEQ_W_PHR
:
12786 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12787 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12788 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12790 case OPC_PRECEQU_PH_QBL
:
12792 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12794 case OPC_PRECEQU_PH_QBR
:
12796 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12798 case OPC_PRECEQU_PH_QBLA
:
12800 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12802 case OPC_PRECEQU_PH_QBRA
:
12804 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12806 case OPC_PRECEU_PH_QBL
:
12808 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12810 case OPC_PRECEU_PH_QBR
:
12812 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12814 case OPC_PRECEU_PH_QBLA
:
12816 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12818 case OPC_PRECEU_PH_QBRA
:
12820 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12824 case OPC_ADDU_QB_DSP
:
12828 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12830 case OPC_ADDQ_S_PH
:
12832 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12836 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12840 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12842 case OPC_ADDU_S_QB
:
12844 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12848 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12850 case OPC_ADDU_S_PH
:
12852 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12856 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12858 case OPC_SUBQ_S_PH
:
12860 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12864 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12868 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12870 case OPC_SUBU_S_QB
:
12872 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12876 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12878 case OPC_SUBU_S_PH
:
12880 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12884 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12888 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12892 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12894 case OPC_RADDU_W_QB
:
12896 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12900 case OPC_CMPU_EQ_QB_DSP
:
12902 case OPC_PRECR_QB_PH
:
12904 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12906 case OPC_PRECRQ_QB_PH
:
12908 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12910 case OPC_PRECR_SRA_PH_W
:
12913 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12914 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12916 tcg_temp_free_i32(sa_t
);
12919 case OPC_PRECR_SRA_R_PH_W
:
12922 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12923 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12925 tcg_temp_free_i32(sa_t
);
12928 case OPC_PRECRQ_PH_W
:
12930 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12932 case OPC_PRECRQ_RS_PH_W
:
12934 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12936 case OPC_PRECRQU_S_QB_PH
:
12938 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12942 #ifdef TARGET_MIPS64
12943 case OPC_ABSQ_S_QH_DSP
:
12945 case OPC_PRECEQ_L_PWL
:
12947 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
12949 case OPC_PRECEQ_L_PWR
:
12951 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
12953 case OPC_PRECEQ_PW_QHL
:
12955 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
12957 case OPC_PRECEQ_PW_QHR
:
12959 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
12961 case OPC_PRECEQ_PW_QHLA
:
12963 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
12965 case OPC_PRECEQ_PW_QHRA
:
12967 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
12969 case OPC_PRECEQU_QH_OBL
:
12971 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
12973 case OPC_PRECEQU_QH_OBR
:
12975 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
12977 case OPC_PRECEQU_QH_OBLA
:
12979 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
12981 case OPC_PRECEQU_QH_OBRA
:
12983 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
12985 case OPC_PRECEU_QH_OBL
:
12987 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
12989 case OPC_PRECEU_QH_OBR
:
12991 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
12993 case OPC_PRECEU_QH_OBLA
:
12995 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
12997 case OPC_PRECEU_QH_OBRA
:
12999 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
13001 case OPC_ABSQ_S_OB
:
13003 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
13005 case OPC_ABSQ_S_PW
:
13007 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
13009 case OPC_ABSQ_S_QH
:
13011 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
13015 case OPC_ADDU_OB_DSP
:
13017 case OPC_RADDU_L_OB
:
13019 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
13023 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13025 case OPC_SUBQ_S_PW
:
13027 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13031 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13033 case OPC_SUBQ_S_QH
:
13035 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13039 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13041 case OPC_SUBU_S_OB
:
13043 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13047 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13049 case OPC_SUBU_S_QH
:
13051 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13055 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13057 case OPC_SUBUH_R_OB
:
13059 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13063 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13065 case OPC_ADDQ_S_PW
:
13067 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13071 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13073 case OPC_ADDQ_S_QH
:
13075 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13079 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13081 case OPC_ADDU_S_OB
:
13083 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13087 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13089 case OPC_ADDU_S_QH
:
13091 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13095 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13097 case OPC_ADDUH_R_OB
:
13099 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13103 case OPC_CMPU_EQ_OB_DSP
:
13105 case OPC_PRECR_OB_QH
:
13107 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13109 case OPC_PRECR_SRA_QH_PW
:
13112 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13113 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13114 tcg_temp_free_i32(ret_t
);
13117 case OPC_PRECR_SRA_R_QH_PW
:
13120 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13121 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13122 tcg_temp_free_i32(sa_v
);
13125 case OPC_PRECRQ_OB_QH
:
13127 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13129 case OPC_PRECRQ_PW_L
:
13131 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13133 case OPC_PRECRQ_QH_PW
:
13135 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13137 case OPC_PRECRQ_RS_QH_PW
:
13139 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13141 case OPC_PRECRQU_S_OB_QH
:
13143 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13150 tcg_temp_free(v1_t
);
13151 tcg_temp_free(v2_t
);
13153 (void)opn
; /* avoid a compiler warning */
13154 MIPS_DEBUG("%s", opn
);
13157 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13158 int ret
, int v1
, int v2
)
13161 const char *opn
= "mipsdsp shift";
13167 /* Treat as NOP. */
13172 t0
= tcg_temp_new();
13173 v1_t
= tcg_temp_new();
13174 v2_t
= tcg_temp_new();
13176 tcg_gen_movi_tl(t0
, v1
);
13177 gen_load_gpr(v1_t
, v1
);
13178 gen_load_gpr(v2_t
, v2
);
13181 case OPC_SHLL_QB_DSP
:
13183 op2
= MASK_SHLL_QB(ctx
->opcode
);
13187 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13191 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13195 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13199 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13201 case OPC_SHLL_S_PH
:
13203 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13205 case OPC_SHLLV_S_PH
:
13207 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13211 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13213 case OPC_SHLLV_S_W
:
13215 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13219 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13223 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13227 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13231 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13235 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13237 case OPC_SHRA_R_QB
:
13239 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13243 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13245 case OPC_SHRAV_R_QB
:
13247 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13251 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13253 case OPC_SHRA_R_PH
:
13255 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13259 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13261 case OPC_SHRAV_R_PH
:
13263 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13267 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13269 case OPC_SHRAV_R_W
:
13271 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13273 default: /* Invalid */
13274 MIPS_INVAL("MASK SHLL.QB");
13275 generate_exception(ctx
, EXCP_RI
);
13280 #ifdef TARGET_MIPS64
13281 case OPC_SHLL_OB_DSP
:
13282 op2
= MASK_SHLL_OB(ctx
->opcode
);
13286 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13290 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13292 case OPC_SHLL_S_PW
:
13294 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13296 case OPC_SHLLV_S_PW
:
13298 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13302 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13306 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13310 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13314 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13316 case OPC_SHLL_S_QH
:
13318 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13320 case OPC_SHLLV_S_QH
:
13322 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13326 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13330 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13332 case OPC_SHRA_R_OB
:
13334 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13336 case OPC_SHRAV_R_OB
:
13338 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13342 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13346 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13348 case OPC_SHRA_R_PW
:
13350 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13352 case OPC_SHRAV_R_PW
:
13354 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13358 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13362 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13364 case OPC_SHRA_R_QH
:
13366 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13368 case OPC_SHRAV_R_QH
:
13370 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13374 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13378 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13382 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13386 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13388 default: /* Invalid */
13389 MIPS_INVAL("MASK SHLL.OB");
13390 generate_exception(ctx
, EXCP_RI
);
13398 tcg_temp_free(v1_t
);
13399 tcg_temp_free(v2_t
);
13400 (void)opn
; /* avoid a compiler warning */
13401 MIPS_DEBUG("%s", opn
);
13404 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13405 int ret
, int v1
, int v2
, int check_ret
)
13407 const char *opn
= "mipsdsp multiply";
13412 if ((ret
== 0) && (check_ret
== 1)) {
13413 /* Treat as NOP. */
13418 t0
= tcg_temp_new_i32();
13419 v1_t
= tcg_temp_new();
13420 v2_t
= tcg_temp_new();
13422 tcg_gen_movi_i32(t0
, ret
);
13423 gen_load_gpr(v1_t
, v1
);
13424 gen_load_gpr(v2_t
, v2
);
13427 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13428 * the same mask and op1. */
13429 case OPC_MULT_G_2E
:
13433 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13436 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13439 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13441 case OPC_MULQ_RS_W
:
13442 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13446 case OPC_DPA_W_PH_DSP
:
13448 case OPC_DPAU_H_QBL
:
13450 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13452 case OPC_DPAU_H_QBR
:
13454 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13456 case OPC_DPSU_H_QBL
:
13458 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13460 case OPC_DPSU_H_QBR
:
13462 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13466 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13468 case OPC_DPAX_W_PH
:
13470 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13472 case OPC_DPAQ_S_W_PH
:
13474 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13476 case OPC_DPAQX_S_W_PH
:
13478 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13480 case OPC_DPAQX_SA_W_PH
:
13482 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13486 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13488 case OPC_DPSX_W_PH
:
13490 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13492 case OPC_DPSQ_S_W_PH
:
13494 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13496 case OPC_DPSQX_S_W_PH
:
13498 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13500 case OPC_DPSQX_SA_W_PH
:
13502 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13504 case OPC_MULSAQ_S_W_PH
:
13506 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13508 case OPC_DPAQ_SA_L_W
:
13510 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13512 case OPC_DPSQ_SA_L_W
:
13514 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13516 case OPC_MAQ_S_W_PHL
:
13518 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13520 case OPC_MAQ_S_W_PHR
:
13522 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13524 case OPC_MAQ_SA_W_PHL
:
13526 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13528 case OPC_MAQ_SA_W_PHR
:
13530 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13532 case OPC_MULSA_W_PH
:
13534 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13538 #ifdef TARGET_MIPS64
13539 case OPC_DPAQ_W_QH_DSP
:
13541 int ac
= ret
& 0x03;
13542 tcg_gen_movi_i32(t0
, ac
);
13547 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13551 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13555 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13559 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13563 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13565 case OPC_DPAQ_S_W_QH
:
13567 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13569 case OPC_DPAQ_SA_L_PW
:
13571 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13573 case OPC_DPAU_H_OBL
:
13575 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13577 case OPC_DPAU_H_OBR
:
13579 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13583 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13585 case OPC_DPSQ_S_W_QH
:
13587 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13589 case OPC_DPSQ_SA_L_PW
:
13591 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13593 case OPC_DPSU_H_OBL
:
13595 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13597 case OPC_DPSU_H_OBR
:
13599 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13601 case OPC_MAQ_S_L_PWL
:
13603 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13605 case OPC_MAQ_S_L_PWR
:
13607 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13609 case OPC_MAQ_S_W_QHLL
:
13611 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13613 case OPC_MAQ_SA_W_QHLL
:
13615 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13617 case OPC_MAQ_S_W_QHLR
:
13619 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13621 case OPC_MAQ_SA_W_QHLR
:
13623 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13625 case OPC_MAQ_S_W_QHRL
:
13627 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13629 case OPC_MAQ_SA_W_QHRL
:
13631 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13633 case OPC_MAQ_S_W_QHRR
:
13635 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13637 case OPC_MAQ_SA_W_QHRR
:
13639 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13641 case OPC_MULSAQ_S_L_PW
:
13643 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13645 case OPC_MULSAQ_S_W_QH
:
13647 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13653 case OPC_ADDU_QB_DSP
:
13655 case OPC_MULEU_S_PH_QBL
:
13657 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13659 case OPC_MULEU_S_PH_QBR
:
13661 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13663 case OPC_MULQ_RS_PH
:
13665 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13667 case OPC_MULEQ_S_W_PHL
:
13669 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13671 case OPC_MULEQ_S_W_PHR
:
13673 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13675 case OPC_MULQ_S_PH
:
13677 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13681 #ifdef TARGET_MIPS64
13682 case OPC_ADDU_OB_DSP
:
13684 case OPC_MULEQ_S_PW_QHL
:
13686 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13688 case OPC_MULEQ_S_PW_QHR
:
13690 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13692 case OPC_MULEU_S_QH_OBL
:
13694 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13696 case OPC_MULEU_S_QH_OBR
:
13698 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13700 case OPC_MULQ_RS_QH
:
13702 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13709 tcg_temp_free_i32(t0
);
13710 tcg_temp_free(v1_t
);
13711 tcg_temp_free(v2_t
);
13713 (void)opn
; /* avoid a compiler warning */
13714 MIPS_DEBUG("%s", opn
);
13718 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13721 const char *opn
= "mipsdsp Bit/ Manipulation";
13727 /* Treat as NOP. */
13732 t0
= tcg_temp_new();
13733 val_t
= tcg_temp_new();
13734 gen_load_gpr(val_t
, val
);
13737 case OPC_ABSQ_S_PH_DSP
:
13741 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13746 target_long result
;
13747 imm
= (ctx
->opcode
>> 16) & 0xFF;
13748 result
= (uint32_t)imm
<< 24 |
13749 (uint32_t)imm
<< 16 |
13750 (uint32_t)imm
<< 8 |
13752 result
= (int32_t)result
;
13753 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13758 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13759 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13760 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13761 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13762 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13763 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13768 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13769 imm
= (int16_t)(imm
<< 6) >> 6;
13770 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13771 (target_long
)((int32_t)imm
<< 16 | \
13777 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13778 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13779 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13780 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13784 #ifdef TARGET_MIPS64
13785 case OPC_ABSQ_S_QH_DSP
:
13792 imm
= (ctx
->opcode
>> 16) & 0xFF;
13793 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13794 temp
= (temp
<< 16) | temp
;
13795 temp
= (temp
<< 32) | temp
;
13796 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13804 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13805 imm
= (int16_t)(imm
<< 6) >> 6;
13806 temp
= ((target_long
)imm
<< 32) \
13807 | ((target_long
)imm
& 0xFFFFFFFF);
13808 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13816 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13817 imm
= (int16_t)(imm
<< 6) >> 6;
13819 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13820 ((uint64_t)(uint16_t)imm
<< 32) |
13821 ((uint64_t)(uint16_t)imm
<< 16) |
13822 (uint64_t)(uint16_t)imm
;
13823 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13828 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13829 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13830 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13831 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13832 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13833 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13834 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13838 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13839 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13840 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13844 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13845 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13846 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13847 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13848 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13855 tcg_temp_free(val_t
);
13857 (void)opn
; /* avoid a compiler warning */
13858 MIPS_DEBUG("%s", opn
);
13861 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13862 uint32_t op1
, uint32_t op2
,
13863 int ret
, int v1
, int v2
, int check_ret
)
13865 const char *opn
= "mipsdsp add compare pick";
13870 if ((ret
== 0) && (check_ret
== 1)) {
13871 /* Treat as NOP. */
13876 t1
= tcg_temp_new();
13877 v1_t
= tcg_temp_new();
13878 v2_t
= tcg_temp_new();
13880 gen_load_gpr(v1_t
, v1
);
13881 gen_load_gpr(v2_t
, v2
);
13884 case OPC_CMPU_EQ_QB_DSP
:
13886 case OPC_CMPU_EQ_QB
:
13888 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13890 case OPC_CMPU_LT_QB
:
13892 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13894 case OPC_CMPU_LE_QB
:
13896 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13898 case OPC_CMPGU_EQ_QB
:
13900 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13902 case OPC_CMPGU_LT_QB
:
13904 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13906 case OPC_CMPGU_LE_QB
:
13908 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13910 case OPC_CMPGDU_EQ_QB
:
13912 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13913 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13914 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13915 tcg_gen_shli_tl(t1
, t1
, 24);
13916 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13918 case OPC_CMPGDU_LT_QB
:
13920 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
13921 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13922 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13923 tcg_gen_shli_tl(t1
, t1
, 24);
13924 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13926 case OPC_CMPGDU_LE_QB
:
13928 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
13929 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13930 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13931 tcg_gen_shli_tl(t1
, t1
, 24);
13932 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13934 case OPC_CMP_EQ_PH
:
13936 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
13938 case OPC_CMP_LT_PH
:
13940 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
13942 case OPC_CMP_LE_PH
:
13944 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
13948 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13952 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13954 case OPC_PACKRL_PH
:
13956 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13960 #ifdef TARGET_MIPS64
13961 case OPC_CMPU_EQ_OB_DSP
:
13963 case OPC_CMP_EQ_PW
:
13965 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
13967 case OPC_CMP_LT_PW
:
13969 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
13971 case OPC_CMP_LE_PW
:
13973 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
13975 case OPC_CMP_EQ_QH
:
13977 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
13979 case OPC_CMP_LT_QH
:
13981 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
13983 case OPC_CMP_LE_QH
:
13985 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
13987 case OPC_CMPGDU_EQ_OB
:
13989 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13991 case OPC_CMPGDU_LT_OB
:
13993 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13995 case OPC_CMPGDU_LE_OB
:
13997 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13999 case OPC_CMPGU_EQ_OB
:
14001 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14003 case OPC_CMPGU_LT_OB
:
14005 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14007 case OPC_CMPGU_LE_OB
:
14009 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14011 case OPC_CMPU_EQ_OB
:
14013 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
14015 case OPC_CMPU_LT_OB
:
14017 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
14019 case OPC_CMPU_LE_OB
:
14021 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
14023 case OPC_PACKRL_PW
:
14025 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14029 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14033 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14037 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14045 tcg_temp_free(v1_t
);
14046 tcg_temp_free(v2_t
);
14048 (void)opn
; /* avoid a compiler warning */
14049 MIPS_DEBUG("%s", opn
);
14052 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14053 uint32_t op1
, int rt
, int rs
, int sa
)
14055 const char *opn
= "mipsdsp append/dappend";
14061 /* Treat as NOP. */
14066 t0
= tcg_temp_new();
14067 gen_load_gpr(t0
, rs
);
14070 case OPC_APPEND_DSP
:
14071 switch (MASK_APPEND(ctx
->opcode
)) {
14074 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14076 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14080 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14081 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14082 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14083 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14085 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14089 if (sa
!= 0 && sa
!= 2) {
14090 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14091 tcg_gen_ext32u_tl(t0
, t0
);
14092 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14093 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14095 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14097 default: /* Invalid */
14098 MIPS_INVAL("MASK APPEND");
14099 generate_exception(ctx
, EXCP_RI
);
14103 #ifdef TARGET_MIPS64
14104 case OPC_DAPPEND_DSP
:
14105 switch (MASK_DAPPEND(ctx
->opcode
)) {
14108 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14112 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14113 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14114 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14118 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14119 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14120 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14125 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14126 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14127 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14128 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14131 default: /* Invalid */
14132 MIPS_INVAL("MASK DAPPEND");
14133 generate_exception(ctx
, EXCP_RI
);
14140 (void)opn
; /* avoid a compiler warning */
14141 MIPS_DEBUG("%s", opn
);
14144 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14145 int ret
, int v1
, int v2
, int check_ret
)
14148 const char *opn
= "mipsdsp accumulator";
14155 if ((ret
== 0) && (check_ret
== 1)) {
14156 /* Treat as NOP. */
14161 t0
= tcg_temp_new();
14162 t1
= tcg_temp_new();
14163 v1_t
= tcg_temp_new();
14164 v2_t
= tcg_temp_new();
14166 gen_load_gpr(v1_t
, v1
);
14167 gen_load_gpr(v2_t
, v2
);
14170 case OPC_EXTR_W_DSP
:
14174 tcg_gen_movi_tl(t0
, v2
);
14175 tcg_gen_movi_tl(t1
, v1
);
14176 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14179 tcg_gen_movi_tl(t0
, v2
);
14180 tcg_gen_movi_tl(t1
, v1
);
14181 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14183 case OPC_EXTR_RS_W
:
14184 tcg_gen_movi_tl(t0
, v2
);
14185 tcg_gen_movi_tl(t1
, v1
);
14186 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14189 tcg_gen_movi_tl(t0
, v2
);
14190 tcg_gen_movi_tl(t1
, v1
);
14191 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14193 case OPC_EXTRV_S_H
:
14194 tcg_gen_movi_tl(t0
, v2
);
14195 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14198 tcg_gen_movi_tl(t0
, v2
);
14199 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14201 case OPC_EXTRV_R_W
:
14202 tcg_gen_movi_tl(t0
, v2
);
14203 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14205 case OPC_EXTRV_RS_W
:
14206 tcg_gen_movi_tl(t0
, v2
);
14207 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14210 tcg_gen_movi_tl(t0
, v2
);
14211 tcg_gen_movi_tl(t1
, v1
);
14212 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14215 tcg_gen_movi_tl(t0
, v2
);
14216 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14219 tcg_gen_movi_tl(t0
, v2
);
14220 tcg_gen_movi_tl(t1
, v1
);
14221 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14224 tcg_gen_movi_tl(t0
, v2
);
14225 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14228 imm
= (ctx
->opcode
>> 20) & 0x3F;
14229 tcg_gen_movi_tl(t0
, ret
);
14230 tcg_gen_movi_tl(t1
, imm
);
14231 gen_helper_shilo(t0
, t1
, cpu_env
);
14234 tcg_gen_movi_tl(t0
, ret
);
14235 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14238 tcg_gen_movi_tl(t0
, ret
);
14239 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14242 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14243 tcg_gen_movi_tl(t0
, imm
);
14244 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14247 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14248 tcg_gen_movi_tl(t0
, imm
);
14249 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14253 #ifdef TARGET_MIPS64
14254 case OPC_DEXTR_W_DSP
:
14258 tcg_gen_movi_tl(t0
, ret
);
14259 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14263 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14264 int ac
= (ctx
->opcode
>> 11) & 0x03;
14265 tcg_gen_movi_tl(t0
, shift
);
14266 tcg_gen_movi_tl(t1
, ac
);
14267 gen_helper_dshilo(t0
, t1
, cpu_env
);
14272 int ac
= (ctx
->opcode
>> 11) & 0x03;
14273 tcg_gen_movi_tl(t0
, ac
);
14274 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14278 tcg_gen_movi_tl(t0
, v2
);
14279 tcg_gen_movi_tl(t1
, v1
);
14281 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14284 tcg_gen_movi_tl(t0
, v2
);
14285 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14288 tcg_gen_movi_tl(t0
, v2
);
14289 tcg_gen_movi_tl(t1
, v1
);
14290 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14293 tcg_gen_movi_tl(t0
, v2
);
14294 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14297 tcg_gen_movi_tl(t0
, v2
);
14298 tcg_gen_movi_tl(t1
, v1
);
14299 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14301 case OPC_DEXTR_R_L
:
14302 tcg_gen_movi_tl(t0
, v2
);
14303 tcg_gen_movi_tl(t1
, v1
);
14304 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14306 case OPC_DEXTR_RS_L
:
14307 tcg_gen_movi_tl(t0
, v2
);
14308 tcg_gen_movi_tl(t1
, v1
);
14309 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14312 tcg_gen_movi_tl(t0
, v2
);
14313 tcg_gen_movi_tl(t1
, v1
);
14314 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14316 case OPC_DEXTR_R_W
:
14317 tcg_gen_movi_tl(t0
, v2
);
14318 tcg_gen_movi_tl(t1
, v1
);
14319 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14321 case OPC_DEXTR_RS_W
:
14322 tcg_gen_movi_tl(t0
, v2
);
14323 tcg_gen_movi_tl(t1
, v1
);
14324 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14326 case OPC_DEXTR_S_H
:
14327 tcg_gen_movi_tl(t0
, v2
);
14328 tcg_gen_movi_tl(t1
, v1
);
14329 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14331 case OPC_DEXTRV_S_H
:
14332 tcg_gen_movi_tl(t0
, v2
);
14333 tcg_gen_movi_tl(t1
, v1
);
14334 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14337 tcg_gen_movi_tl(t0
, v2
);
14338 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14340 case OPC_DEXTRV_R_L
:
14341 tcg_gen_movi_tl(t0
, v2
);
14342 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14344 case OPC_DEXTRV_RS_L
:
14345 tcg_gen_movi_tl(t0
, v2
);
14346 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14349 tcg_gen_movi_tl(t0
, v2
);
14350 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14352 case OPC_DEXTRV_R_W
:
14353 tcg_gen_movi_tl(t0
, v2
);
14354 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14356 case OPC_DEXTRV_RS_W
:
14357 tcg_gen_movi_tl(t0
, v2
);
14358 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14367 tcg_temp_free(v1_t
);
14368 tcg_temp_free(v2_t
);
14370 (void)opn
; /* avoid a compiler warning */
14371 MIPS_DEBUG("%s", opn
);
14374 /* End MIPSDSP functions. */
14376 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
14379 int rs
, rt
, rd
, sa
;
14380 uint32_t op
, op1
, op2
;
14383 /* make sure instructions are on a word boundary */
14384 if (ctx
->pc
& 0x3) {
14385 env
->CP0_BadVAddr
= ctx
->pc
;
14386 generate_exception(ctx
, EXCP_AdEL
);
14390 /* Handle blikely not taken case */
14391 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14392 int l1
= gen_new_label();
14394 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14395 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14396 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14397 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14401 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14402 tcg_gen_debug_insn_start(ctx
->pc
);
14405 op
= MASK_OP_MAJOR(ctx
->opcode
);
14406 rs
= (ctx
->opcode
>> 21) & 0x1f;
14407 rt
= (ctx
->opcode
>> 16) & 0x1f;
14408 rd
= (ctx
->opcode
>> 11) & 0x1f;
14409 sa
= (ctx
->opcode
>> 6) & 0x1f;
14410 imm
= (int16_t)ctx
->opcode
;
14413 op1
= MASK_SPECIAL(ctx
->opcode
);
14415 case OPC_SLL
: /* Shift with immediate */
14417 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14420 switch ((ctx
->opcode
>> 21) & 0x1f) {
14422 /* rotr is decoded as srl on non-R2 CPUs */
14423 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14428 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14431 generate_exception(ctx
, EXCP_RI
);
14435 case OPC_MOVN
: /* Conditional move */
14437 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14438 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14439 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14441 case OPC_ADD
... OPC_SUBU
:
14442 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14444 case OPC_SLLV
: /* Shifts */
14446 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14449 switch ((ctx
->opcode
>> 6) & 0x1f) {
14451 /* rotrv is decoded as srlv on non-R2 CPUs */
14452 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14457 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14460 generate_exception(ctx
, EXCP_RI
);
14464 case OPC_SLT
: /* Set on less than */
14466 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14468 case OPC_AND
: /* Logic*/
14472 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14477 check_insn(ctx
, INSN_VR54XX
);
14478 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14479 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14481 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14486 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14488 case OPC_JR
... OPC_JALR
:
14489 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14491 case OPC_TGE
... OPC_TEQ
: /* Traps */
14493 gen_trap(ctx
, op1
, rs
, rt
, -1);
14495 case OPC_MFHI
: /* Move from HI/LO */
14497 gen_HILO(ctx
, op1
, rs
& 3, rd
);
14500 case OPC_MTLO
: /* Move to HI/LO */
14501 gen_HILO(ctx
, op1
, rd
& 3, rs
);
14503 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14504 #ifdef MIPS_STRICT_STANDARD
14505 MIPS_INVAL("PMON / selsl");
14506 generate_exception(ctx
, EXCP_RI
);
14508 gen_helper_0e0i(pmon
, sa
);
14512 generate_exception(ctx
, EXCP_SYSCALL
);
14513 ctx
->bstate
= BS_STOP
;
14516 generate_exception(ctx
, EXCP_BREAK
);
14519 #ifdef MIPS_STRICT_STANDARD
14520 MIPS_INVAL("SPIM");
14521 generate_exception(ctx
, EXCP_RI
);
14523 /* Implemented as RI exception for now. */
14524 MIPS_INVAL("spim (unofficial)");
14525 generate_exception(ctx
, EXCP_RI
);
14529 /* Treat as NOP. */
14533 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14534 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14535 check_cp1_enabled(ctx
);
14536 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14537 (ctx
->opcode
>> 16) & 1);
14539 generate_exception_err(ctx
, EXCP_CpU
, 1);
14543 #if defined(TARGET_MIPS64)
14544 /* MIPS64 specific opcodes */
14549 check_insn(ctx
, ISA_MIPS3
);
14550 check_mips_64(ctx
);
14551 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14554 switch ((ctx
->opcode
>> 21) & 0x1f) {
14556 /* drotr is decoded as dsrl on non-R2 CPUs */
14557 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14562 check_insn(ctx
, ISA_MIPS3
);
14563 check_mips_64(ctx
);
14564 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14567 generate_exception(ctx
, EXCP_RI
);
14572 switch ((ctx
->opcode
>> 21) & 0x1f) {
14574 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14575 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14580 check_insn(ctx
, ISA_MIPS3
);
14581 check_mips_64(ctx
);
14582 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14585 generate_exception(ctx
, EXCP_RI
);
14589 case OPC_DADD
... OPC_DSUBU
:
14590 check_insn(ctx
, ISA_MIPS3
);
14591 check_mips_64(ctx
);
14592 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14596 check_insn(ctx
, ISA_MIPS3
);
14597 check_mips_64(ctx
);
14598 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14601 switch ((ctx
->opcode
>> 6) & 0x1f) {
14603 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14604 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14609 check_insn(ctx
, ISA_MIPS3
);
14610 check_mips_64(ctx
);
14611 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14614 generate_exception(ctx
, EXCP_RI
);
14618 case OPC_DMULT
... OPC_DDIVU
:
14619 check_insn(ctx
, ISA_MIPS3
);
14620 check_mips_64(ctx
);
14621 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14624 default: /* Invalid */
14625 MIPS_INVAL("special");
14626 generate_exception(ctx
, EXCP_RI
);
14631 op1
= MASK_SPECIAL2(ctx
->opcode
);
14633 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14634 case OPC_MSUB
... OPC_MSUBU
:
14635 check_insn(ctx
, ISA_MIPS32
);
14636 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14639 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14643 check_insn(ctx
, ISA_MIPS32
);
14644 gen_cl(ctx
, op1
, rd
, rs
);
14647 /* XXX: not clear which exception should be raised
14648 * when in debug mode...
14650 check_insn(ctx
, ISA_MIPS32
);
14651 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14652 generate_exception(ctx
, EXCP_DBp
);
14654 generate_exception(ctx
, EXCP_DBp
);
14656 /* Treat as NOP. */
14659 case OPC_DIVU_G_2F
:
14660 case OPC_MULT_G_2F
:
14661 case OPC_MULTU_G_2F
:
14663 case OPC_MODU_G_2F
:
14664 check_insn(ctx
, INSN_LOONGSON2F
);
14665 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14667 #if defined(TARGET_MIPS64)
14670 check_insn(ctx
, ISA_MIPS64
);
14671 check_mips_64(ctx
);
14672 gen_cl(ctx
, op1
, rd
, rs
);
14674 case OPC_DMULT_G_2F
:
14675 case OPC_DMULTU_G_2F
:
14676 case OPC_DDIV_G_2F
:
14677 case OPC_DDIVU_G_2F
:
14678 case OPC_DMOD_G_2F
:
14679 case OPC_DMODU_G_2F
:
14680 check_insn(ctx
, INSN_LOONGSON2F
);
14681 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14684 default: /* Invalid */
14685 MIPS_INVAL("special2");
14686 generate_exception(ctx
, EXCP_RI
);
14691 op1
= MASK_SPECIAL3(ctx
->opcode
);
14695 check_insn(ctx
, ISA_MIPS32R2
);
14696 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14699 check_insn(ctx
, ISA_MIPS32R2
);
14700 op2
= MASK_BSHFL(ctx
->opcode
);
14701 gen_bshfl(ctx
, op2
, rt
, rd
);
14704 gen_rdhwr(ctx
, rt
, rd
);
14707 check_insn(ctx
, ASE_MT
);
14709 TCGv t0
= tcg_temp_new();
14710 TCGv t1
= tcg_temp_new();
14712 gen_load_gpr(t0
, rt
);
14713 gen_load_gpr(t1
, rs
);
14714 gen_helper_fork(t0
, t1
);
14720 check_insn(ctx
, ASE_MT
);
14722 TCGv t0
= tcg_temp_new();
14724 save_cpu_state(ctx
, 1);
14725 gen_load_gpr(t0
, rs
);
14726 gen_helper_yield(t0
, cpu_env
, t0
);
14727 gen_store_gpr(t0
, rd
);
14731 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14732 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14733 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14734 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14735 * the same mask and op1. */
14736 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14737 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14740 case OPC_ADDUH_R_QB
:
14742 case OPC_ADDQH_R_PH
:
14744 case OPC_ADDQH_R_W
:
14746 case OPC_SUBUH_R_QB
:
14748 case OPC_SUBQH_R_PH
:
14750 case OPC_SUBQH_R_W
:
14751 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14756 case OPC_MULQ_RS_W
:
14757 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14760 MIPS_INVAL("MASK ADDUH.QB");
14761 generate_exception(ctx
, EXCP_RI
);
14764 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14765 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14767 generate_exception(ctx
, EXCP_RI
);
14771 op2
= MASK_LX(ctx
->opcode
);
14773 #if defined(TARGET_MIPS64)
14779 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14781 default: /* Invalid */
14782 MIPS_INVAL("MASK LX");
14783 generate_exception(ctx
, EXCP_RI
);
14787 case OPC_ABSQ_S_PH_DSP
:
14788 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14790 case OPC_ABSQ_S_QB
:
14791 case OPC_ABSQ_S_PH
:
14793 case OPC_PRECEQ_W_PHL
:
14794 case OPC_PRECEQ_W_PHR
:
14795 case OPC_PRECEQU_PH_QBL
:
14796 case OPC_PRECEQU_PH_QBR
:
14797 case OPC_PRECEQU_PH_QBLA
:
14798 case OPC_PRECEQU_PH_QBRA
:
14799 case OPC_PRECEU_PH_QBL
:
14800 case OPC_PRECEU_PH_QBR
:
14801 case OPC_PRECEU_PH_QBLA
:
14802 case OPC_PRECEU_PH_QBRA
:
14803 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14810 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14813 MIPS_INVAL("MASK ABSQ_S.PH");
14814 generate_exception(ctx
, EXCP_RI
);
14818 case OPC_ADDU_QB_DSP
:
14819 op2
= MASK_ADDU_QB(ctx
->opcode
);
14822 case OPC_ADDQ_S_PH
:
14825 case OPC_ADDU_S_QB
:
14827 case OPC_ADDU_S_PH
:
14829 case OPC_SUBQ_S_PH
:
14832 case OPC_SUBU_S_QB
:
14834 case OPC_SUBU_S_PH
:
14838 case OPC_RADDU_W_QB
:
14839 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14841 case OPC_MULEU_S_PH_QBL
:
14842 case OPC_MULEU_S_PH_QBR
:
14843 case OPC_MULQ_RS_PH
:
14844 case OPC_MULEQ_S_W_PHL
:
14845 case OPC_MULEQ_S_W_PHR
:
14846 case OPC_MULQ_S_PH
:
14847 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14849 default: /* Invalid */
14850 MIPS_INVAL("MASK ADDU.QB");
14851 generate_exception(ctx
, EXCP_RI
);
14856 case OPC_CMPU_EQ_QB_DSP
:
14857 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14859 case OPC_PRECR_SRA_PH_W
:
14860 case OPC_PRECR_SRA_R_PH_W
:
14861 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14863 case OPC_PRECR_QB_PH
:
14864 case OPC_PRECRQ_QB_PH
:
14865 case OPC_PRECRQ_PH_W
:
14866 case OPC_PRECRQ_RS_PH_W
:
14867 case OPC_PRECRQU_S_QB_PH
:
14868 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14870 case OPC_CMPU_EQ_QB
:
14871 case OPC_CMPU_LT_QB
:
14872 case OPC_CMPU_LE_QB
:
14873 case OPC_CMP_EQ_PH
:
14874 case OPC_CMP_LT_PH
:
14875 case OPC_CMP_LE_PH
:
14876 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14878 case OPC_CMPGU_EQ_QB
:
14879 case OPC_CMPGU_LT_QB
:
14880 case OPC_CMPGU_LE_QB
:
14881 case OPC_CMPGDU_EQ_QB
:
14882 case OPC_CMPGDU_LT_QB
:
14883 case OPC_CMPGDU_LE_QB
:
14886 case OPC_PACKRL_PH
:
14887 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14889 default: /* Invalid */
14890 MIPS_INVAL("MASK CMPU.EQ.QB");
14891 generate_exception(ctx
, EXCP_RI
);
14895 case OPC_SHLL_QB_DSP
:
14896 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14898 case OPC_DPA_W_PH_DSP
:
14899 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14901 case OPC_DPAU_H_QBL
:
14902 case OPC_DPAU_H_QBR
:
14903 case OPC_DPSU_H_QBL
:
14904 case OPC_DPSU_H_QBR
:
14906 case OPC_DPAX_W_PH
:
14907 case OPC_DPAQ_S_W_PH
:
14908 case OPC_DPAQX_S_W_PH
:
14909 case OPC_DPAQX_SA_W_PH
:
14911 case OPC_DPSX_W_PH
:
14912 case OPC_DPSQ_S_W_PH
:
14913 case OPC_DPSQX_S_W_PH
:
14914 case OPC_DPSQX_SA_W_PH
:
14915 case OPC_MULSAQ_S_W_PH
:
14916 case OPC_DPAQ_SA_L_W
:
14917 case OPC_DPSQ_SA_L_W
:
14918 case OPC_MAQ_S_W_PHL
:
14919 case OPC_MAQ_S_W_PHR
:
14920 case OPC_MAQ_SA_W_PHL
:
14921 case OPC_MAQ_SA_W_PHR
:
14922 case OPC_MULSA_W_PH
:
14923 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14925 default: /* Invalid */
14926 MIPS_INVAL("MASK DPAW.PH");
14927 generate_exception(ctx
, EXCP_RI
);
14932 op2
= MASK_INSV(ctx
->opcode
);
14944 t0
= tcg_temp_new();
14945 t1
= tcg_temp_new();
14947 gen_load_gpr(t0
, rt
);
14948 gen_load_gpr(t1
, rs
);
14950 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
14956 default: /* Invalid */
14957 MIPS_INVAL("MASK INSV");
14958 generate_exception(ctx
, EXCP_RI
);
14962 case OPC_APPEND_DSP
:
14963 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
14965 case OPC_EXTR_W_DSP
:
14966 op2
= MASK_EXTR_W(ctx
->opcode
);
14970 case OPC_EXTR_RS_W
:
14972 case OPC_EXTRV_S_H
:
14974 case OPC_EXTRV_R_W
:
14975 case OPC_EXTRV_RS_W
:
14980 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
14983 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14989 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14991 default: /* Invalid */
14992 MIPS_INVAL("MASK EXTR.W");
14993 generate_exception(ctx
, EXCP_RI
);
14997 #if defined(TARGET_MIPS64)
14998 case OPC_DEXTM
... OPC_DEXT
:
14999 case OPC_DINSM
... OPC_DINS
:
15000 check_insn(ctx
, ISA_MIPS64R2
);
15001 check_mips_64(ctx
);
15002 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
15005 check_insn(ctx
, ISA_MIPS64R2
);
15006 check_mips_64(ctx
);
15007 op2
= MASK_DBSHFL(ctx
->opcode
);
15008 gen_bshfl(ctx
, op2
, rt
, rd
);
15010 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
15011 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
15012 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
15013 check_insn(ctx
, INSN_LOONGSON2E
);
15014 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
15016 case OPC_ABSQ_S_QH_DSP
:
15017 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
15019 case OPC_PRECEQ_L_PWL
:
15020 case OPC_PRECEQ_L_PWR
:
15021 case OPC_PRECEQ_PW_QHL
:
15022 case OPC_PRECEQ_PW_QHR
:
15023 case OPC_PRECEQ_PW_QHLA
:
15024 case OPC_PRECEQ_PW_QHRA
:
15025 case OPC_PRECEQU_QH_OBL
:
15026 case OPC_PRECEQU_QH_OBR
:
15027 case OPC_PRECEQU_QH_OBLA
:
15028 case OPC_PRECEQU_QH_OBRA
:
15029 case OPC_PRECEU_QH_OBL
:
15030 case OPC_PRECEU_QH_OBR
:
15031 case OPC_PRECEU_QH_OBLA
:
15032 case OPC_PRECEU_QH_OBRA
:
15033 case OPC_ABSQ_S_OB
:
15034 case OPC_ABSQ_S_PW
:
15035 case OPC_ABSQ_S_QH
:
15036 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15044 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
15046 default: /* Invalid */
15047 MIPS_INVAL("MASK ABSQ_S.QH");
15048 generate_exception(ctx
, EXCP_RI
);
15052 case OPC_ADDU_OB_DSP
:
15053 op2
= MASK_ADDU_OB(ctx
->opcode
);
15055 case OPC_RADDU_L_OB
:
15057 case OPC_SUBQ_S_PW
:
15059 case OPC_SUBQ_S_QH
:
15061 case OPC_SUBU_S_OB
:
15063 case OPC_SUBU_S_QH
:
15065 case OPC_SUBUH_R_OB
:
15067 case OPC_ADDQ_S_PW
:
15069 case OPC_ADDQ_S_QH
:
15071 case OPC_ADDU_S_OB
:
15073 case OPC_ADDU_S_QH
:
15075 case OPC_ADDUH_R_OB
:
15076 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15078 case OPC_MULEQ_S_PW_QHL
:
15079 case OPC_MULEQ_S_PW_QHR
:
15080 case OPC_MULEU_S_QH_OBL
:
15081 case OPC_MULEU_S_QH_OBR
:
15082 case OPC_MULQ_RS_QH
:
15083 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15085 default: /* Invalid */
15086 MIPS_INVAL("MASK ADDU.OB");
15087 generate_exception(ctx
, EXCP_RI
);
15091 case OPC_CMPU_EQ_OB_DSP
:
15092 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15094 case OPC_PRECR_SRA_QH_PW
:
15095 case OPC_PRECR_SRA_R_QH_PW
:
15096 /* Return value is rt. */
15097 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15099 case OPC_PRECR_OB_QH
:
15100 case OPC_PRECRQ_OB_QH
:
15101 case OPC_PRECRQ_PW_L
:
15102 case OPC_PRECRQ_QH_PW
:
15103 case OPC_PRECRQ_RS_QH_PW
:
15104 case OPC_PRECRQU_S_OB_QH
:
15105 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15107 case OPC_CMPU_EQ_OB
:
15108 case OPC_CMPU_LT_OB
:
15109 case OPC_CMPU_LE_OB
:
15110 case OPC_CMP_EQ_QH
:
15111 case OPC_CMP_LT_QH
:
15112 case OPC_CMP_LE_QH
:
15113 case OPC_CMP_EQ_PW
:
15114 case OPC_CMP_LT_PW
:
15115 case OPC_CMP_LE_PW
:
15116 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15118 case OPC_CMPGDU_EQ_OB
:
15119 case OPC_CMPGDU_LT_OB
:
15120 case OPC_CMPGDU_LE_OB
:
15121 case OPC_CMPGU_EQ_OB
:
15122 case OPC_CMPGU_LT_OB
:
15123 case OPC_CMPGU_LE_OB
:
15124 case OPC_PACKRL_PW
:
15128 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15130 default: /* Invalid */
15131 MIPS_INVAL("MASK CMPU_EQ.OB");
15132 generate_exception(ctx
, EXCP_RI
);
15136 case OPC_DAPPEND_DSP
:
15137 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15139 case OPC_DEXTR_W_DSP
:
15140 op2
= MASK_DEXTR_W(ctx
->opcode
);
15147 case OPC_DEXTR_R_L
:
15148 case OPC_DEXTR_RS_L
:
15150 case OPC_DEXTR_R_W
:
15151 case OPC_DEXTR_RS_W
:
15152 case OPC_DEXTR_S_H
:
15154 case OPC_DEXTRV_R_L
:
15155 case OPC_DEXTRV_RS_L
:
15156 case OPC_DEXTRV_S_H
:
15158 case OPC_DEXTRV_R_W
:
15159 case OPC_DEXTRV_RS_W
:
15160 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15165 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15167 default: /* Invalid */
15168 MIPS_INVAL("MASK EXTR.W");
15169 generate_exception(ctx
, EXCP_RI
);
15173 case OPC_DPAQ_W_QH_DSP
:
15174 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15176 case OPC_DPAU_H_OBL
:
15177 case OPC_DPAU_H_OBR
:
15178 case OPC_DPSU_H_OBL
:
15179 case OPC_DPSU_H_OBR
:
15181 case OPC_DPAQ_S_W_QH
:
15183 case OPC_DPSQ_S_W_QH
:
15184 case OPC_MULSAQ_S_W_QH
:
15185 case OPC_DPAQ_SA_L_PW
:
15186 case OPC_DPSQ_SA_L_PW
:
15187 case OPC_MULSAQ_S_L_PW
:
15188 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15190 case OPC_MAQ_S_W_QHLL
:
15191 case OPC_MAQ_S_W_QHLR
:
15192 case OPC_MAQ_S_W_QHRL
:
15193 case OPC_MAQ_S_W_QHRR
:
15194 case OPC_MAQ_SA_W_QHLL
:
15195 case OPC_MAQ_SA_W_QHLR
:
15196 case OPC_MAQ_SA_W_QHRL
:
15197 case OPC_MAQ_SA_W_QHRR
:
15198 case OPC_MAQ_S_L_PWL
:
15199 case OPC_MAQ_S_L_PWR
:
15204 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15206 default: /* Invalid */
15207 MIPS_INVAL("MASK DPAQ.W.QH");
15208 generate_exception(ctx
, EXCP_RI
);
15212 case OPC_DINSV_DSP
:
15213 op2
= MASK_INSV(ctx
->opcode
);
15225 t0
= tcg_temp_new();
15226 t1
= tcg_temp_new();
15228 gen_load_gpr(t0
, rt
);
15229 gen_load_gpr(t1
, rs
);
15231 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15234 default: /* Invalid */
15235 MIPS_INVAL("MASK DINSV");
15236 generate_exception(ctx
, EXCP_RI
);
15240 case OPC_SHLL_OB_DSP
:
15241 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15244 default: /* Invalid */
15245 MIPS_INVAL("special3");
15246 generate_exception(ctx
, EXCP_RI
);
15251 op1
= MASK_REGIMM(ctx
->opcode
);
15253 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15254 case OPC_BLTZAL
... OPC_BGEZALL
:
15255 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15257 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15259 gen_trap(ctx
, op1
, rs
, -1, imm
);
15262 check_insn(ctx
, ISA_MIPS32R2
);
15263 /* Treat as NOP. */
15265 case OPC_BPOSGE32
: /* MIPS DSP branch */
15266 #if defined(TARGET_MIPS64)
15270 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15272 default: /* Invalid */
15273 MIPS_INVAL("regimm");
15274 generate_exception(ctx
, EXCP_RI
);
15279 check_cp0_enabled(ctx
);
15280 op1
= MASK_CP0(ctx
->opcode
);
15286 #if defined(TARGET_MIPS64)
15290 #ifndef CONFIG_USER_ONLY
15291 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15292 #endif /* !CONFIG_USER_ONLY */
15294 case OPC_C0_FIRST
... OPC_C0_LAST
:
15295 #ifndef CONFIG_USER_ONLY
15296 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15297 #endif /* !CONFIG_USER_ONLY */
15300 #ifndef CONFIG_USER_ONLY
15302 TCGv t0
= tcg_temp_new();
15304 op2
= MASK_MFMC0(ctx
->opcode
);
15307 check_insn(ctx
, ASE_MT
);
15308 gen_helper_dmt(t0
);
15309 gen_store_gpr(t0
, rt
);
15312 check_insn(ctx
, ASE_MT
);
15313 gen_helper_emt(t0
);
15314 gen_store_gpr(t0
, rt
);
15317 check_insn(ctx
, ASE_MT
);
15318 gen_helper_dvpe(t0
, cpu_env
);
15319 gen_store_gpr(t0
, rt
);
15322 check_insn(ctx
, ASE_MT
);
15323 gen_helper_evpe(t0
, cpu_env
);
15324 gen_store_gpr(t0
, rt
);
15327 check_insn(ctx
, ISA_MIPS32R2
);
15328 save_cpu_state(ctx
, 1);
15329 gen_helper_di(t0
, cpu_env
);
15330 gen_store_gpr(t0
, rt
);
15331 /* Stop translation as we may have switched the execution mode */
15332 ctx
->bstate
= BS_STOP
;
15335 check_insn(ctx
, ISA_MIPS32R2
);
15336 save_cpu_state(ctx
, 1);
15337 gen_helper_ei(t0
, cpu_env
);
15338 gen_store_gpr(t0
, rt
);
15339 /* Stop translation as we may have switched the execution mode */
15340 ctx
->bstate
= BS_STOP
;
15342 default: /* Invalid */
15343 MIPS_INVAL("mfmc0");
15344 generate_exception(ctx
, EXCP_RI
);
15349 #endif /* !CONFIG_USER_ONLY */
15352 check_insn(ctx
, ISA_MIPS32R2
);
15353 gen_load_srsgpr(rt
, rd
);
15356 check_insn(ctx
, ISA_MIPS32R2
);
15357 gen_store_srsgpr(rt
, rd
);
15361 generate_exception(ctx
, EXCP_RI
);
15365 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15367 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15369 case OPC_SLTI
: /* Set on less than with immediate opcode */
15371 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15373 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15377 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15379 case OPC_J
... OPC_JAL
: /* Jump */
15380 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15381 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15383 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15384 case OPC_BEQL
... OPC_BGTZL
:
15385 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15387 case OPC_LB
... OPC_LWR
: /* Load and stores */
15389 gen_ld(ctx
, op
, rt
, rs
, imm
);
15391 case OPC_SB
... OPC_SW
:
15393 gen_st(ctx
, op
, rt
, rs
, imm
);
15396 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15399 check_cp0_enabled(ctx
);
15400 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15401 /* Treat as NOP. */
15404 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15405 /* Treat as NOP. */
15408 /* Floating point (COP1). */
15413 gen_cop1_ldst(env
, ctx
, op
, rt
, rs
, imm
);
15417 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15418 check_cp1_enabled(ctx
);
15419 op1
= MASK_CP1(ctx
->opcode
);
15423 check_insn(ctx
, ISA_MIPS32R2
);
15428 gen_cp1(ctx
, op1
, rt
, rd
);
15430 #if defined(TARGET_MIPS64)
15433 check_insn(ctx
, ISA_MIPS3
);
15434 gen_cp1(ctx
, op1
, rt
, rd
);
15440 check_insn(ctx
, ASE_MIPS3D
);
15443 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15444 (rt
>> 2) & 0x7, imm
<< 2);
15451 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15456 generate_exception (ctx
, EXCP_RI
);
15460 generate_exception_err(ctx
, EXCP_CpU
, 1);
15469 /* COP2: Not implemented. */
15470 generate_exception_err(ctx
, EXCP_CpU
, 2);
15473 check_insn(ctx
, INSN_LOONGSON2F
);
15474 /* Note that these instructions use different fields. */
15475 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15479 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15480 check_cp1_enabled(ctx
);
15481 op1
= MASK_CP3(ctx
->opcode
);
15489 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15492 /* Treat as NOP. */
15507 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15511 generate_exception (ctx
, EXCP_RI
);
15515 generate_exception_err(ctx
, EXCP_CpU
, 1);
15519 #if defined(TARGET_MIPS64)
15520 /* MIPS64 opcodes */
15522 case OPC_LDL
... OPC_LDR
:
15525 check_insn(ctx
, ISA_MIPS3
);
15526 check_mips_64(ctx
);
15527 gen_ld(ctx
, op
, rt
, rs
, imm
);
15529 case OPC_SDL
... OPC_SDR
:
15531 check_insn(ctx
, ISA_MIPS3
);
15532 check_mips_64(ctx
);
15533 gen_st(ctx
, op
, rt
, rs
, imm
);
15536 check_insn(ctx
, ISA_MIPS3
);
15537 check_mips_64(ctx
);
15538 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15542 check_insn(ctx
, ISA_MIPS3
);
15543 check_mips_64(ctx
);
15544 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15548 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15549 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15550 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15553 check_insn(ctx
, ASE_MDMX
);
15554 /* MDMX: Not implemented. */
15555 default: /* Invalid */
15556 MIPS_INVAL("major opcode");
15557 generate_exception(ctx
, EXCP_RI
);
15563 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
15566 CPUState
*cs
= CPU(cpu
);
15567 CPUMIPSState
*env
= &cpu
->env
;
15569 target_ulong pc_start
;
15570 uint16_t *gen_opc_end
;
15579 qemu_log("search pc %d\n", search_pc
);
15582 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15585 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
15586 ctx
.insn_flags
= env
->insn_flags
;
15588 ctx
.bstate
= BS_NONE
;
15589 /* Restore delay slot state from the tb context. */
15590 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15591 restore_cpu_state(env
, &ctx
);
15592 #ifdef CONFIG_USER_ONLY
15593 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15595 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15598 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15599 if (max_insns
== 0)
15600 max_insns
= CF_COUNT_MASK
;
15601 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15603 while (ctx
.bstate
== BS_NONE
) {
15604 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
15605 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
15606 if (bp
->pc
== ctx
.pc
) {
15607 save_cpu_state(&ctx
, 1);
15608 ctx
.bstate
= BS_BRANCH
;
15609 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15610 /* Include the breakpoint location or the tb won't
15611 * be flushed when it must be. */
15613 goto done_generating
;
15619 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15623 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15625 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15626 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15627 gen_opc_btarget
[lj
] = ctx
.btarget
;
15628 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15629 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15631 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15634 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
15635 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15636 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15638 decode_opc(env
, &ctx
);
15639 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15640 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15641 insn_bytes
= decode_micromips_opc(env
, &ctx
);
15642 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15643 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15644 insn_bytes
= decode_mips16_opc(env
, &ctx
);
15646 generate_exception(&ctx
, EXCP_RI
);
15647 ctx
.bstate
= BS_STOP
;
15651 handle_delay_slot(&ctx
, insn_bytes
);
15653 ctx
.pc
+= insn_bytes
;
15657 /* Execute a branch and its delay slot as a single instruction.
15658 This is what GDB expects and is consistent with what the
15659 hardware does (e.g. if a delay slot instruction faults, the
15660 reported PC is the PC of the branch). */
15661 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
15665 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15668 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15672 if (num_insns
>= max_insns
)
15678 if (tb
->cflags
& CF_LAST_IO
) {
15681 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15682 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15683 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15685 switch (ctx
.bstate
) {
15687 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15690 save_cpu_state(&ctx
, 0);
15691 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15694 tcg_gen_exit_tb(0);
15702 gen_tb_end(tb
, num_insns
);
15703 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15705 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15708 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15710 tb
->size
= ctx
.pc
- pc_start
;
15711 tb
->icount
= num_insns
;
15715 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15716 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15717 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15723 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15725 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
15728 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15730 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
15733 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15737 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15739 #define printfpr(fp) \
15742 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15743 " fd:%13g fs:%13g psu: %13g\n", \
15744 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15745 (double)(fp)->fd, \
15746 (double)(fp)->fs[FP_ENDIAN_IDX], \
15747 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15750 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15751 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15752 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15753 " fd:%13g fs:%13g psu:%13g\n", \
15754 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15756 (double)tmp.fs[FP_ENDIAN_IDX], \
15757 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15762 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15763 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15764 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15765 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15766 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15767 printfpr(&env
->active_fpu
.fpr
[i
]);
15773 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15774 /* Debug help: The architecture requires 32bit code to maintain proper
15775 sign-extended values on 64bit machines. */
15777 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15780 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15781 fprintf_function cpu_fprintf
,
15786 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15787 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15788 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15789 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15790 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15791 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15792 if (!SIGN_EXT_P(env
->btarget
))
15793 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15795 for (i
= 0; i
< 32; i
++) {
15796 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15797 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15800 if (!SIGN_EXT_P(env
->CP0_EPC
))
15801 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15802 if (!SIGN_EXT_P(env
->lladdr
))
15803 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15807 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
15810 MIPSCPU
*cpu
= MIPS_CPU(cs
);
15811 CPUMIPSState
*env
= &cpu
->env
;
15814 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15815 " LO=0x" TARGET_FMT_lx
" ds %04x "
15816 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15817 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15818 env
->hflags
, env
->btarget
, env
->bcond
);
15819 for (i
= 0; i
< 32; i
++) {
15821 cpu_fprintf(f
, "GPR%02d:", i
);
15822 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15824 cpu_fprintf(f
, "\n");
15827 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15828 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15829 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15830 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15831 if (env
->hflags
& MIPS_HFLAG_FPU
)
15832 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15833 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15834 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15838 void mips_tcg_init(void)
15843 /* Initialize various static tables. */
15847 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15848 TCGV_UNUSED(cpu_gpr
[0]);
15849 for (i
= 1; i
< 32; i
++)
15850 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15851 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15854 for (i
= 0; i
< 32; i
++) {
15855 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15856 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15859 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15860 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15861 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15862 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15863 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15865 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15866 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15868 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15869 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15872 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15873 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15875 bcond
= tcg_global_mem_new(TCG_AREG0
,
15876 offsetof(CPUMIPSState
, bcond
), "bcond");
15877 btarget
= tcg_global_mem_new(TCG_AREG0
,
15878 offsetof(CPUMIPSState
, btarget
), "btarget");
15879 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15880 offsetof(CPUMIPSState
, hflags
), "hflags");
15882 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15883 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15885 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15886 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15892 #include "translate_init.c"
15894 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15898 const mips_def_t
*def
;
15900 def
= cpu_mips_find_by_name(cpu_model
);
15903 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15905 env
->cpu_model
= def
;
15907 #ifndef CONFIG_USER_ONLY
15908 mmu_init(env
, def
);
15910 fpu_init(env
, def
);
15911 mvp_init(env
, def
);
15913 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15918 void cpu_state_reset(CPUMIPSState
*env
)
15920 #ifndef CONFIG_USER_ONLY
15921 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
15922 CPUState
*cs
= CPU(cpu
);
15925 /* Reset registers to their default values */
15926 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15927 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15928 #ifdef TARGET_WORDS_BIGENDIAN
15929 env
->CP0_Config0
|= (1 << CP0C0_BE
);
15931 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
15932 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
15933 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
15934 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
15935 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
15936 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
15937 << env
->cpu_model
->CP0_LLAddr_shift
;
15938 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
15939 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
15940 env
->CCRes
= env
->cpu_model
->CCRes
;
15941 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
15942 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
15943 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
15944 env
->current_tc
= 0;
15945 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
15946 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
15947 #if defined(TARGET_MIPS64)
15948 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
15949 env
->SEGMask
|= 3ULL << 62;
15952 env
->PABITS
= env
->cpu_model
->PABITS
;
15953 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
15954 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
15955 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
15956 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
15957 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
15958 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
15959 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
15960 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
15961 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
15962 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
15963 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
15964 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
15965 env
->insn_flags
= env
->cpu_model
->insn_flags
;
15967 #if defined(CONFIG_USER_ONLY)
15968 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
15969 # ifdef TARGET_MIPS64
15970 /* Enable 64-bit register mode. */
15971 env
->CP0_Status
|= (1 << CP0St_PX
);
15973 # ifdef TARGET_ABI_MIPSN64
15974 /* Enable 64-bit address mode. */
15975 env
->CP0_Status
|= (1 << CP0St_UX
);
15977 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15978 hardware registers. */
15979 env
->CP0_HWREna
|= 0x0000000F;
15980 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15981 env
->CP0_Status
|= (1 << CP0St_CU1
);
15983 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
15984 env
->CP0_Status
|= (1 << CP0St_MX
);
15986 # if defined(TARGET_MIPS64)
15987 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
15988 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
15989 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
15990 env
->CP0_Status
|= (1 << CP0St_FR
);
15994 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
15995 /* If the exception was raised from a delay slot,
15996 come back to the jump. */
15997 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
15999 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
16001 env
->active_tc
.PC
= (int32_t)0xBFC00000;
16002 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
16003 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
16004 env
->CP0_Wired
= 0;
16005 env
->CP0_EBase
= 0x80000000 | (cs
->cpu_index
& 0x3FF);
16006 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
16007 /* vectored interrupts not implemented, timer on int 7,
16008 no performance counters. */
16009 env
->CP0_IntCtl
= 0xe0000000;
16013 for (i
= 0; i
< 7; i
++) {
16014 env
->CP0_WatchLo
[i
] = 0;
16015 env
->CP0_WatchHi
[i
] = 0x80000000;
16017 env
->CP0_WatchLo
[7] = 0;
16018 env
->CP0_WatchHi
[7] = 0;
16020 /* Count register increments in debug mode, EJTAG version 1 */
16021 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
16023 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
16026 /* Only TC0 on VPE 0 starts as active. */
16027 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
16028 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
16029 env
->tcs
[i
].CP0_TCHalt
= 1;
16031 env
->active_tc
.CP0_TCHalt
= 1;
16034 if (cs
->cpu_index
== 0) {
16035 /* VPE0 starts up enabled. */
16036 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
16037 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
16039 /* TC0 starts up unhalted. */
16041 env
->active_tc
.CP0_TCHalt
= 0;
16042 env
->tcs
[0].CP0_TCHalt
= 0;
16043 /* With thread 0 active. */
16044 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
16045 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16049 compute_hflags(env
);
16050 env
->exception_index
= EXCP_NONE
;
16053 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16055 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16056 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16057 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16058 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16059 case MIPS_HFLAG_BR
:
16061 case MIPS_HFLAG_BC
:
16062 case MIPS_HFLAG_BL
:
16064 env
->btarget
= gen_opc_btarget
[pc_pos
];