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_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1610 gen_store_gpr(t0
, rt
);
1614 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
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_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
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_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
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_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
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_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1680 gen_store_gpr(t0
, rt
);
1684 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1685 gen_store_gpr(t0
, rt
);
1689 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
1690 gen_store_gpr(t0
, rt
);
1694 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
1695 gen_store_gpr(t0
, rt
);
1699 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
1700 gen_store_gpr(t0
, rt
);
1704 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
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_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
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_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
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_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
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_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
1796 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
1800 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
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();
1871 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
1872 gen_store_fpr32(fp0
, ft
);
1873 tcg_temp_free_i32(fp0
);
1879 TCGv_i32 fp0
= tcg_temp_new_i32();
1880 gen_load_fpr32(fp0
, ft
);
1881 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1882 tcg_temp_free_i32(fp0
);
1888 TCGv_i64 fp0
= tcg_temp_new_i64();
1889 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1890 gen_store_fpr64(ctx
, fp0
, ft
);
1891 tcg_temp_free_i64(fp0
);
1897 TCGv_i64 fp0
= tcg_temp_new_i64();
1898 gen_load_fpr64(ctx
, fp0
, ft
);
1899 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1900 tcg_temp_free_i64(fp0
);
1906 generate_exception(ctx
, EXCP_RI
);
1909 (void)opn
; /* avoid a compiler warning */
1910 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
1915 static void gen_cop1_ldst(CPUMIPSState
*env
, DisasContext
*ctx
,
1916 uint32_t op
, int rt
, int rs
, int16_t imm
)
1918 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
1919 check_cp1_enabled(ctx
);
1920 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
1922 generate_exception_err(ctx
, EXCP_CpU
, 1);
1926 /* Arithmetic with immediate operand */
1927 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
1928 int rt
, int rs
, int16_t imm
)
1930 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
1931 const char *opn
= "imm arith";
1933 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
1934 /* If no destination, treat it as a NOP.
1935 For addi, we must generate the overflow exception when needed. */
1942 TCGv t0
= tcg_temp_local_new();
1943 TCGv t1
= tcg_temp_new();
1944 TCGv t2
= tcg_temp_new();
1945 int l1
= gen_new_label();
1947 gen_load_gpr(t1
, rs
);
1948 tcg_gen_addi_tl(t0
, t1
, uimm
);
1949 tcg_gen_ext32s_tl(t0
, t0
);
1951 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1952 tcg_gen_xori_tl(t2
, t0
, uimm
);
1953 tcg_gen_and_tl(t1
, t1
, t2
);
1955 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1957 /* operands of same sign, result different sign */
1958 generate_exception(ctx
, EXCP_OVERFLOW
);
1960 tcg_gen_ext32s_tl(t0
, t0
);
1961 gen_store_gpr(t0
, rt
);
1968 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1969 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
1971 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1975 #if defined(TARGET_MIPS64)
1978 TCGv t0
= tcg_temp_local_new();
1979 TCGv t1
= tcg_temp_new();
1980 TCGv t2
= tcg_temp_new();
1981 int l1
= gen_new_label();
1983 gen_load_gpr(t1
, rs
);
1984 tcg_gen_addi_tl(t0
, t1
, uimm
);
1986 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1987 tcg_gen_xori_tl(t2
, t0
, uimm
);
1988 tcg_gen_and_tl(t1
, t1
, t2
);
1990 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1992 /* operands of same sign, result different sign */
1993 generate_exception(ctx
, EXCP_OVERFLOW
);
1995 gen_store_gpr(t0
, rt
);
2002 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2004 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2010 (void)opn
; /* avoid a compiler warning */
2011 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2014 /* Logic with immediate operand */
2015 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2016 int rt
, int rs
, int16_t imm
)
2021 /* If no destination, treat it as a NOP. */
2025 uimm
= (uint16_t)imm
;
2028 if (likely(rs
!= 0))
2029 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2031 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2032 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2033 regnames
[rs
], uimm
);
2037 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2039 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2040 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2041 regnames
[rs
], uimm
);
2044 if (likely(rs
!= 0))
2045 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2047 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2048 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2049 regnames
[rs
], uimm
);
2052 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2053 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2057 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2062 /* Set on less than with immediate operand */
2063 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2064 int rt
, int rs
, int16_t imm
)
2066 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2067 const char *opn
= "imm arith";
2071 /* If no destination, treat it as a NOP. */
2075 t0
= tcg_temp_new();
2076 gen_load_gpr(t0
, rs
);
2079 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2083 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2087 (void)opn
; /* avoid a compiler warning */
2088 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2092 /* Shifts with immediate operand */
2093 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2094 int rt
, int rs
, int16_t imm
)
2096 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2097 const char *opn
= "imm shift";
2101 /* If no destination, treat it as a NOP. */
2106 t0
= tcg_temp_new();
2107 gen_load_gpr(t0
, rs
);
2110 tcg_gen_shli_tl(t0
, t0
, uimm
);
2111 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2115 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2120 tcg_gen_ext32u_tl(t0
, t0
);
2121 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2123 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2129 TCGv_i32 t1
= tcg_temp_new_i32();
2131 tcg_gen_trunc_tl_i32(t1
, t0
);
2132 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2133 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2134 tcg_temp_free_i32(t1
);
2136 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2140 #if defined(TARGET_MIPS64)
2142 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2146 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2150 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2155 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2157 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2162 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2166 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2170 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2174 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2179 (void)opn
; /* avoid a compiler warning */
2180 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2185 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2186 int rd
, int rs
, int rt
)
2188 const char *opn
= "arith";
2190 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2191 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2192 /* If no destination, treat it as a NOP.
2193 For add & sub, we must generate the overflow exception when needed. */
2201 TCGv t0
= tcg_temp_local_new();
2202 TCGv t1
= tcg_temp_new();
2203 TCGv t2
= tcg_temp_new();
2204 int l1
= gen_new_label();
2206 gen_load_gpr(t1
, rs
);
2207 gen_load_gpr(t2
, rt
);
2208 tcg_gen_add_tl(t0
, t1
, t2
);
2209 tcg_gen_ext32s_tl(t0
, t0
);
2210 tcg_gen_xor_tl(t1
, t1
, t2
);
2211 tcg_gen_xor_tl(t2
, t0
, t2
);
2212 tcg_gen_andc_tl(t1
, t2
, t1
);
2214 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2216 /* operands of same sign, result different sign */
2217 generate_exception(ctx
, EXCP_OVERFLOW
);
2219 gen_store_gpr(t0
, rd
);
2225 if (rs
!= 0 && rt
!= 0) {
2226 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2227 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2228 } else if (rs
== 0 && rt
!= 0) {
2229 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2230 } else if (rs
!= 0 && rt
== 0) {
2231 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2233 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2239 TCGv t0
= tcg_temp_local_new();
2240 TCGv t1
= tcg_temp_new();
2241 TCGv t2
= tcg_temp_new();
2242 int l1
= gen_new_label();
2244 gen_load_gpr(t1
, rs
);
2245 gen_load_gpr(t2
, rt
);
2246 tcg_gen_sub_tl(t0
, t1
, t2
);
2247 tcg_gen_ext32s_tl(t0
, t0
);
2248 tcg_gen_xor_tl(t2
, t1
, t2
);
2249 tcg_gen_xor_tl(t1
, t0
, t1
);
2250 tcg_gen_and_tl(t1
, t1
, t2
);
2252 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2254 /* operands of different sign, first operand and result different sign */
2255 generate_exception(ctx
, EXCP_OVERFLOW
);
2257 gen_store_gpr(t0
, rd
);
2263 if (rs
!= 0 && rt
!= 0) {
2264 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2265 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2266 } else if (rs
== 0 && rt
!= 0) {
2267 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2268 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2269 } else if (rs
!= 0 && rt
== 0) {
2270 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2272 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2276 #if defined(TARGET_MIPS64)
2279 TCGv t0
= tcg_temp_local_new();
2280 TCGv t1
= tcg_temp_new();
2281 TCGv t2
= tcg_temp_new();
2282 int l1
= gen_new_label();
2284 gen_load_gpr(t1
, rs
);
2285 gen_load_gpr(t2
, rt
);
2286 tcg_gen_add_tl(t0
, t1
, t2
);
2287 tcg_gen_xor_tl(t1
, t1
, t2
);
2288 tcg_gen_xor_tl(t2
, t0
, t2
);
2289 tcg_gen_andc_tl(t1
, t2
, t1
);
2291 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2293 /* operands of same sign, result different sign */
2294 generate_exception(ctx
, EXCP_OVERFLOW
);
2296 gen_store_gpr(t0
, rd
);
2302 if (rs
!= 0 && rt
!= 0) {
2303 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2304 } else if (rs
== 0 && rt
!= 0) {
2305 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2306 } else if (rs
!= 0 && rt
== 0) {
2307 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2309 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2315 TCGv t0
= tcg_temp_local_new();
2316 TCGv t1
= tcg_temp_new();
2317 TCGv t2
= tcg_temp_new();
2318 int l1
= gen_new_label();
2320 gen_load_gpr(t1
, rs
);
2321 gen_load_gpr(t2
, rt
);
2322 tcg_gen_sub_tl(t0
, t1
, t2
);
2323 tcg_gen_xor_tl(t2
, t1
, t2
);
2324 tcg_gen_xor_tl(t1
, t0
, t1
);
2325 tcg_gen_and_tl(t1
, t1
, t2
);
2327 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2329 /* operands of different sign, first operand and result different sign */
2330 generate_exception(ctx
, EXCP_OVERFLOW
);
2332 gen_store_gpr(t0
, rd
);
2338 if (rs
!= 0 && rt
!= 0) {
2339 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2340 } else if (rs
== 0 && rt
!= 0) {
2341 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2342 } else if (rs
!= 0 && rt
== 0) {
2343 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2345 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2351 if (likely(rs
!= 0 && rt
!= 0)) {
2352 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2353 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2355 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2360 (void)opn
; /* avoid a compiler warning */
2361 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2364 /* Conditional move */
2365 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2366 int rd
, int rs
, int rt
)
2368 const char *opn
= "cond move";
2372 /* If no destination, treat it as a NOP. */
2377 t0
= tcg_temp_new();
2378 gen_load_gpr(t0
, rt
);
2379 t1
= tcg_const_tl(0);
2380 t2
= tcg_temp_new();
2381 gen_load_gpr(t2
, rs
);
2384 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2388 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2396 (void)opn
; /* avoid a compiler warning */
2397 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2401 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2402 int rd
, int rs
, int rt
)
2404 const char *opn
= "logic";
2407 /* If no destination, treat it as a NOP. */
2414 if (likely(rs
!= 0 && rt
!= 0)) {
2415 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2417 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2422 if (rs
!= 0 && rt
!= 0) {
2423 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2424 } else if (rs
== 0 && rt
!= 0) {
2425 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2426 } else if (rs
!= 0 && rt
== 0) {
2427 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2429 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2434 if (likely(rs
!= 0 && rt
!= 0)) {
2435 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2436 } else if (rs
== 0 && rt
!= 0) {
2437 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2438 } else if (rs
!= 0 && rt
== 0) {
2439 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2441 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2446 if (likely(rs
!= 0 && rt
!= 0)) {
2447 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2448 } else if (rs
== 0 && rt
!= 0) {
2449 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2450 } else if (rs
!= 0 && rt
== 0) {
2451 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2453 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2458 (void)opn
; /* avoid a compiler warning */
2459 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2462 /* Set on lower than */
2463 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2464 int rd
, int rs
, int rt
)
2466 const char *opn
= "slt";
2470 /* If no destination, treat it as a NOP. */
2475 t0
= tcg_temp_new();
2476 t1
= tcg_temp_new();
2477 gen_load_gpr(t0
, rs
);
2478 gen_load_gpr(t1
, rt
);
2481 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2485 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2489 (void)opn
; /* avoid a compiler warning */
2490 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2496 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2497 int rd
, int rs
, int rt
)
2499 const char *opn
= "shifts";
2503 /* If no destination, treat it as a NOP.
2504 For add & sub, we must generate the overflow exception when needed. */
2509 t0
= tcg_temp_new();
2510 t1
= tcg_temp_new();
2511 gen_load_gpr(t0
, rs
);
2512 gen_load_gpr(t1
, rt
);
2515 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2516 tcg_gen_shl_tl(t0
, t1
, t0
);
2517 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2521 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2522 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2526 tcg_gen_ext32u_tl(t1
, t1
);
2527 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2528 tcg_gen_shr_tl(t0
, t1
, t0
);
2529 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2534 TCGv_i32 t2
= tcg_temp_new_i32();
2535 TCGv_i32 t3
= tcg_temp_new_i32();
2537 tcg_gen_trunc_tl_i32(t2
, t0
);
2538 tcg_gen_trunc_tl_i32(t3
, t1
);
2539 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2540 tcg_gen_rotr_i32(t2
, t3
, t2
);
2541 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2542 tcg_temp_free_i32(t2
);
2543 tcg_temp_free_i32(t3
);
2547 #if defined(TARGET_MIPS64)
2549 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2550 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2554 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2555 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2559 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2560 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2564 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2565 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2570 (void)opn
; /* avoid a compiler warning */
2571 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2576 /* Arithmetic on HI/LO registers */
2577 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2579 const char *opn
= "hilo";
2581 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2593 #if defined(TARGET_MIPS64)
2595 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2599 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2604 #if defined(TARGET_MIPS64)
2606 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2610 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2616 #if defined(TARGET_MIPS64)
2618 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2622 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2625 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2631 #if defined(TARGET_MIPS64)
2633 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2637 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2640 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2645 (void)opn
; /* avoid a compiler warning */
2646 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2649 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
2650 int acc
, int rs
, int rt
)
2652 const char *opn
= "mul/div";
2655 t0
= tcg_temp_new();
2656 t1
= tcg_temp_new();
2658 gen_load_gpr(t0
, rs
);
2659 gen_load_gpr(t1
, rt
);
2668 TCGv t2
= tcg_temp_new();
2669 TCGv t3
= tcg_temp_new();
2670 tcg_gen_ext32s_tl(t0
, t0
);
2671 tcg_gen_ext32s_tl(t1
, t1
);
2672 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2673 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2674 tcg_gen_and_tl(t2
, t2
, t3
);
2675 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2676 tcg_gen_or_tl(t2
, t2
, t3
);
2677 tcg_gen_movi_tl(t3
, 0);
2678 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2679 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2680 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2681 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2682 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2690 TCGv t2
= tcg_const_tl(0);
2691 TCGv t3
= tcg_const_tl(1);
2692 tcg_gen_ext32u_tl(t0
, t0
);
2693 tcg_gen_ext32u_tl(t1
, t1
);
2694 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2695 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
2696 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
2697 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2698 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2706 TCGv_i32 t2
= tcg_temp_new_i32();
2707 TCGv_i32 t3
= tcg_temp_new_i32();
2708 tcg_gen_trunc_tl_i32(t2
, t0
);
2709 tcg_gen_trunc_tl_i32(t3
, t1
);
2710 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
2711 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2712 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2713 tcg_temp_free_i32(t2
);
2714 tcg_temp_free_i32(t3
);
2720 TCGv_i32 t2
= tcg_temp_new_i32();
2721 TCGv_i32 t3
= tcg_temp_new_i32();
2722 tcg_gen_trunc_tl_i32(t2
, t0
);
2723 tcg_gen_trunc_tl_i32(t3
, t1
);
2724 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
2725 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2726 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2727 tcg_temp_free_i32(t2
);
2728 tcg_temp_free_i32(t3
);
2732 #if defined(TARGET_MIPS64)
2735 TCGv t2
= tcg_temp_new();
2736 TCGv t3
= tcg_temp_new();
2737 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2738 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2739 tcg_gen_and_tl(t2
, t2
, t3
);
2740 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2741 tcg_gen_or_tl(t2
, t2
, t3
);
2742 tcg_gen_movi_tl(t3
, 0);
2743 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2744 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2745 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2753 TCGv t2
= tcg_const_tl(0);
2754 TCGv t3
= tcg_const_tl(1);
2755 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2756 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
2757 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
2764 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2768 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2774 TCGv_i64 t2
= tcg_temp_new_i64();
2775 TCGv_i64 t3
= tcg_temp_new_i64();
2777 tcg_gen_ext_tl_i64(t2
, t0
);
2778 tcg_gen_ext_tl_i64(t3
, t1
);
2779 tcg_gen_mul_i64(t2
, t2
, t3
);
2780 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2781 tcg_gen_add_i64(t2
, t2
, t3
);
2782 tcg_temp_free_i64(t3
);
2783 tcg_gen_trunc_i64_tl(t0
, t2
);
2784 tcg_gen_shri_i64(t2
, t2
, 32);
2785 tcg_gen_trunc_i64_tl(t1
, t2
);
2786 tcg_temp_free_i64(t2
);
2787 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2788 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2794 TCGv_i64 t2
= tcg_temp_new_i64();
2795 TCGv_i64 t3
= tcg_temp_new_i64();
2797 tcg_gen_ext32u_tl(t0
, t0
);
2798 tcg_gen_ext32u_tl(t1
, t1
);
2799 tcg_gen_extu_tl_i64(t2
, t0
);
2800 tcg_gen_extu_tl_i64(t3
, t1
);
2801 tcg_gen_mul_i64(t2
, t2
, t3
);
2802 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2803 tcg_gen_add_i64(t2
, t2
, t3
);
2804 tcg_temp_free_i64(t3
);
2805 tcg_gen_trunc_i64_tl(t0
, t2
);
2806 tcg_gen_shri_i64(t2
, t2
, 32);
2807 tcg_gen_trunc_i64_tl(t1
, t2
);
2808 tcg_temp_free_i64(t2
);
2809 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2810 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2816 TCGv_i64 t2
= tcg_temp_new_i64();
2817 TCGv_i64 t3
= tcg_temp_new_i64();
2819 tcg_gen_ext_tl_i64(t2
, t0
);
2820 tcg_gen_ext_tl_i64(t3
, t1
);
2821 tcg_gen_mul_i64(t2
, t2
, t3
);
2822 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2823 tcg_gen_sub_i64(t2
, t3
, t2
);
2824 tcg_temp_free_i64(t3
);
2825 tcg_gen_trunc_i64_tl(t0
, t2
);
2826 tcg_gen_shri_i64(t2
, t2
, 32);
2827 tcg_gen_trunc_i64_tl(t1
, t2
);
2828 tcg_temp_free_i64(t2
);
2829 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2830 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2836 TCGv_i64 t2
= tcg_temp_new_i64();
2837 TCGv_i64 t3
= tcg_temp_new_i64();
2839 tcg_gen_ext32u_tl(t0
, t0
);
2840 tcg_gen_ext32u_tl(t1
, t1
);
2841 tcg_gen_extu_tl_i64(t2
, t0
);
2842 tcg_gen_extu_tl_i64(t3
, t1
);
2843 tcg_gen_mul_i64(t2
, t2
, t3
);
2844 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2845 tcg_gen_sub_i64(t2
, t3
, t2
);
2846 tcg_temp_free_i64(t3
);
2847 tcg_gen_trunc_i64_tl(t0
, t2
);
2848 tcg_gen_shri_i64(t2
, t2
, 32);
2849 tcg_gen_trunc_i64_tl(t1
, t2
);
2850 tcg_temp_free_i64(t2
);
2851 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2852 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2858 generate_exception(ctx
, EXCP_RI
);
2861 (void)opn
; /* avoid a compiler warning */
2862 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2868 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2869 int rd
, int rs
, int rt
)
2871 const char *opn
= "mul vr54xx";
2872 TCGv t0
= tcg_temp_new();
2873 TCGv t1
= tcg_temp_new();
2875 gen_load_gpr(t0
, rs
);
2876 gen_load_gpr(t1
, rt
);
2879 case OPC_VR54XX_MULS
:
2880 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2883 case OPC_VR54XX_MULSU
:
2884 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2887 case OPC_VR54XX_MACC
:
2888 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2891 case OPC_VR54XX_MACCU
:
2892 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2895 case OPC_VR54XX_MSAC
:
2896 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2899 case OPC_VR54XX_MSACU
:
2900 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2903 case OPC_VR54XX_MULHI
:
2904 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2907 case OPC_VR54XX_MULHIU
:
2908 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2911 case OPC_VR54XX_MULSHI
:
2912 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2915 case OPC_VR54XX_MULSHIU
:
2916 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2919 case OPC_VR54XX_MACCHI
:
2920 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2923 case OPC_VR54XX_MACCHIU
:
2924 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2927 case OPC_VR54XX_MSACHI
:
2928 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2931 case OPC_VR54XX_MSACHIU
:
2932 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2936 MIPS_INVAL("mul vr54xx");
2937 generate_exception(ctx
, EXCP_RI
);
2940 gen_store_gpr(t0
, rd
);
2941 (void)opn
; /* avoid a compiler warning */
2942 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2949 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2952 const char *opn
= "CLx";
2960 t0
= tcg_temp_new();
2961 gen_load_gpr(t0
, rs
);
2964 gen_helper_clo(cpu_gpr
[rd
], t0
);
2968 gen_helper_clz(cpu_gpr
[rd
], t0
);
2971 #if defined(TARGET_MIPS64)
2973 gen_helper_dclo(cpu_gpr
[rd
], t0
);
2977 gen_helper_dclz(cpu_gpr
[rd
], t0
);
2982 (void)opn
; /* avoid a compiler warning */
2983 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
2987 /* Godson integer instructions */
2988 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
2989 int rd
, int rs
, int rt
)
2991 const char *opn
= "loongson";
3003 case OPC_MULTU_G_2E
:
3004 case OPC_MULTU_G_2F
:
3005 #if defined(TARGET_MIPS64)
3006 case OPC_DMULT_G_2E
:
3007 case OPC_DMULT_G_2F
:
3008 case OPC_DMULTU_G_2E
:
3009 case OPC_DMULTU_G_2F
:
3011 t0
= tcg_temp_new();
3012 t1
= tcg_temp_new();
3015 t0
= tcg_temp_local_new();
3016 t1
= tcg_temp_local_new();
3020 gen_load_gpr(t0
, rs
);
3021 gen_load_gpr(t1
, rt
);
3026 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3027 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3030 case OPC_MULTU_G_2E
:
3031 case OPC_MULTU_G_2F
:
3032 tcg_gen_ext32u_tl(t0
, t0
);
3033 tcg_gen_ext32u_tl(t1
, t1
);
3034 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3035 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3041 int l1
= gen_new_label();
3042 int l2
= gen_new_label();
3043 int l3
= gen_new_label();
3044 tcg_gen_ext32s_tl(t0
, t0
);
3045 tcg_gen_ext32s_tl(t1
, t1
);
3046 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3047 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3050 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3051 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3052 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3055 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3056 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3064 int l1
= gen_new_label();
3065 int l2
= gen_new_label();
3066 tcg_gen_ext32u_tl(t0
, t0
);
3067 tcg_gen_ext32u_tl(t1
, t1
);
3068 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3069 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3072 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3073 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3081 int l1
= gen_new_label();
3082 int l2
= gen_new_label();
3083 int l3
= gen_new_label();
3084 tcg_gen_ext32u_tl(t0
, t0
);
3085 tcg_gen_ext32u_tl(t1
, t1
);
3086 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3087 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3088 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3090 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3093 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3094 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3102 int l1
= gen_new_label();
3103 int l2
= gen_new_label();
3104 tcg_gen_ext32u_tl(t0
, t0
);
3105 tcg_gen_ext32u_tl(t1
, t1
);
3106 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3107 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3110 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3111 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3116 #if defined(TARGET_MIPS64)
3117 case OPC_DMULT_G_2E
:
3118 case OPC_DMULT_G_2F
:
3119 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3122 case OPC_DMULTU_G_2E
:
3123 case OPC_DMULTU_G_2F
:
3124 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3130 int l1
= gen_new_label();
3131 int l2
= gen_new_label();
3132 int l3
= gen_new_label();
3133 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3134 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3137 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3138 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3139 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3142 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3147 case OPC_DDIVU_G_2E
:
3148 case OPC_DDIVU_G_2F
:
3150 int l1
= gen_new_label();
3151 int l2
= gen_new_label();
3152 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3153 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3156 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3164 int l1
= gen_new_label();
3165 int l2
= gen_new_label();
3166 int l3
= gen_new_label();
3167 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3168 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3169 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3171 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3174 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3179 case OPC_DMODU_G_2E
:
3180 case OPC_DMODU_G_2F
:
3182 int l1
= gen_new_label();
3183 int l2
= gen_new_label();
3184 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3185 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3188 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3196 (void)opn
; /* avoid a compiler warning */
3197 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3202 /* Loongson multimedia instructions */
3203 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3205 const char *opn
= "loongson_cp2";
3206 uint32_t opc
, shift_max
;
3209 opc
= MASK_LMI(ctx
->opcode
);
3215 t0
= tcg_temp_local_new_i64();
3216 t1
= tcg_temp_local_new_i64();
3219 t0
= tcg_temp_new_i64();
3220 t1
= tcg_temp_new_i64();
3224 gen_load_fpr64(ctx
, t0
, rs
);
3225 gen_load_fpr64(ctx
, t1
, rt
);
3227 #define LMI_HELPER(UP, LO) \
3228 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3229 #define LMI_HELPER_1(UP, LO) \
3230 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3231 #define LMI_DIRECT(UP, LO, OP) \
3232 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3235 LMI_HELPER(PADDSH
, paddsh
);
3236 LMI_HELPER(PADDUSH
, paddush
);
3237 LMI_HELPER(PADDH
, paddh
);
3238 LMI_HELPER(PADDW
, paddw
);
3239 LMI_HELPER(PADDSB
, paddsb
);
3240 LMI_HELPER(PADDUSB
, paddusb
);
3241 LMI_HELPER(PADDB
, paddb
);
3243 LMI_HELPER(PSUBSH
, psubsh
);
3244 LMI_HELPER(PSUBUSH
, psubush
);
3245 LMI_HELPER(PSUBH
, psubh
);
3246 LMI_HELPER(PSUBW
, psubw
);
3247 LMI_HELPER(PSUBSB
, psubsb
);
3248 LMI_HELPER(PSUBUSB
, psubusb
);
3249 LMI_HELPER(PSUBB
, psubb
);
3251 LMI_HELPER(PSHUFH
, pshufh
);
3252 LMI_HELPER(PACKSSWH
, packsswh
);
3253 LMI_HELPER(PACKSSHB
, packsshb
);
3254 LMI_HELPER(PACKUSHB
, packushb
);
3256 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3257 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3258 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3259 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3260 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3261 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3263 LMI_HELPER(PAVGH
, pavgh
);
3264 LMI_HELPER(PAVGB
, pavgb
);
3265 LMI_HELPER(PMAXSH
, pmaxsh
);
3266 LMI_HELPER(PMINSH
, pminsh
);
3267 LMI_HELPER(PMAXUB
, pmaxub
);
3268 LMI_HELPER(PMINUB
, pminub
);
3270 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3271 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3272 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3273 LMI_HELPER(PCMPGTH
, pcmpgth
);
3274 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3275 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3277 LMI_HELPER(PSLLW
, psllw
);
3278 LMI_HELPER(PSLLH
, psllh
);
3279 LMI_HELPER(PSRLW
, psrlw
);
3280 LMI_HELPER(PSRLH
, psrlh
);
3281 LMI_HELPER(PSRAW
, psraw
);
3282 LMI_HELPER(PSRAH
, psrah
);
3284 LMI_HELPER(PMULLH
, pmullh
);
3285 LMI_HELPER(PMULHH
, pmulhh
);
3286 LMI_HELPER(PMULHUH
, pmulhuh
);
3287 LMI_HELPER(PMADDHW
, pmaddhw
);
3289 LMI_HELPER(PASUBUB
, pasubub
);
3290 LMI_HELPER_1(BIADD
, biadd
);
3291 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3293 LMI_DIRECT(PADDD
, paddd
, add
);
3294 LMI_DIRECT(PSUBD
, psubd
, sub
);
3295 LMI_DIRECT(XOR_CP2
, xor, xor);
3296 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3297 LMI_DIRECT(AND_CP2
, and, and);
3298 LMI_DIRECT(PANDN
, pandn
, andc
);
3299 LMI_DIRECT(OR
, or, or);
3302 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3306 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3310 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3314 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3319 tcg_gen_andi_i64(t1
, t1
, 3);
3320 tcg_gen_shli_i64(t1
, t1
, 4);
3321 tcg_gen_shr_i64(t0
, t0
, t1
);
3322 tcg_gen_ext16u_i64(t0
, t0
);
3327 tcg_gen_add_i64(t0
, t0
, t1
);
3328 tcg_gen_ext32s_i64(t0
, t0
);
3332 tcg_gen_sub_i64(t0
, t0
, t1
);
3333 tcg_gen_ext32s_i64(t0
, t0
);
3362 /* Make sure shift count isn't TCG undefined behaviour. */
3363 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3368 tcg_gen_shl_i64(t0
, t0
, t1
);
3372 /* Since SRA is UndefinedResult without sign-extended inputs,
3373 we can treat SRA and DSRA the same. */
3374 tcg_gen_sar_i64(t0
, t0
, t1
);
3377 /* We want to shift in zeros for SRL; zero-extend first. */
3378 tcg_gen_ext32u_i64(t0
, t0
);
3381 tcg_gen_shr_i64(t0
, t0
, t1
);
3385 if (shift_max
== 32) {
3386 tcg_gen_ext32s_i64(t0
, t0
);
3389 /* Shifts larger than MAX produce zero. */
3390 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3391 tcg_gen_neg_i64(t1
, t1
);
3392 tcg_gen_and_i64(t0
, t0
, t1
);
3398 TCGv_i64 t2
= tcg_temp_new_i64();
3399 int lab
= gen_new_label();
3401 tcg_gen_mov_i64(t2
, t0
);
3402 tcg_gen_add_i64(t0
, t1
, t2
);
3403 if (opc
== OPC_ADD_CP2
) {
3404 tcg_gen_ext32s_i64(t0
, t0
);
3406 tcg_gen_xor_i64(t1
, t1
, t2
);
3407 tcg_gen_xor_i64(t2
, t2
, t0
);
3408 tcg_gen_andc_i64(t1
, t2
, t1
);
3409 tcg_temp_free_i64(t2
);
3410 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3411 generate_exception(ctx
, EXCP_OVERFLOW
);
3414 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3421 TCGv_i64 t2
= tcg_temp_new_i64();
3422 int lab
= gen_new_label();
3424 tcg_gen_mov_i64(t2
, t0
);
3425 tcg_gen_sub_i64(t0
, t1
, t2
);
3426 if (opc
== OPC_SUB_CP2
) {
3427 tcg_gen_ext32s_i64(t0
, t0
);
3429 tcg_gen_xor_i64(t1
, t1
, t2
);
3430 tcg_gen_xor_i64(t2
, t2
, t0
);
3431 tcg_gen_and_i64(t1
, t1
, t2
);
3432 tcg_temp_free_i64(t2
);
3433 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3434 generate_exception(ctx
, EXCP_OVERFLOW
);
3437 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3442 tcg_gen_ext32u_i64(t0
, t0
);
3443 tcg_gen_ext32u_i64(t1
, t1
);
3444 tcg_gen_mul_i64(t0
, t0
, t1
);
3454 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3455 FD field is the CC field? */
3458 generate_exception(ctx
, EXCP_RI
);
3465 gen_store_fpr64(ctx
, t0
, rd
);
3467 (void)opn
; /* avoid a compiler warning */
3468 MIPS_DEBUG("%s %s, %s, %s", opn
,
3469 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3470 tcg_temp_free_i64(t0
);
3471 tcg_temp_free_i64(t1
);
3475 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3476 int rs
, int rt
, int16_t imm
)
3479 TCGv t0
= tcg_temp_new();
3480 TCGv t1
= tcg_temp_new();
3483 /* Load needed operands */
3491 /* Compare two registers */
3493 gen_load_gpr(t0
, rs
);
3494 gen_load_gpr(t1
, rt
);
3504 /* Compare register to immediate */
3505 if (rs
!= 0 || imm
!= 0) {
3506 gen_load_gpr(t0
, rs
);
3507 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3514 case OPC_TEQ
: /* rs == rs */
3515 case OPC_TEQI
: /* r0 == 0 */
3516 case OPC_TGE
: /* rs >= rs */
3517 case OPC_TGEI
: /* r0 >= 0 */
3518 case OPC_TGEU
: /* rs >= rs unsigned */
3519 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3521 generate_exception(ctx
, EXCP_TRAP
);
3523 case OPC_TLT
: /* rs < rs */
3524 case OPC_TLTI
: /* r0 < 0 */
3525 case OPC_TLTU
: /* rs < rs unsigned */
3526 case OPC_TLTIU
: /* r0 < 0 unsigned */
3527 case OPC_TNE
: /* rs != rs */
3528 case OPC_TNEI
: /* r0 != 0 */
3529 /* Never trap: treat as NOP. */
3533 int l1
= gen_new_label();
3538 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3542 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3546 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3550 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3554 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3558 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3561 generate_exception(ctx
, EXCP_TRAP
);
3568 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3570 TranslationBlock
*tb
;
3572 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3573 likely(!ctx
->singlestep_enabled
)) {
3576 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3579 if (ctx
->singlestep_enabled
) {
3580 save_cpu_state(ctx
, 0);
3581 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3587 /* Branches (before delay slot) */
3588 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3590 int rs
, int rt
, int32_t offset
)
3592 target_ulong btgt
= -1;
3594 int bcond_compute
= 0;
3595 TCGv t0
= tcg_temp_new();
3596 TCGv t1
= tcg_temp_new();
3598 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3599 #ifdef MIPS_DEBUG_DISAS
3600 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3602 generate_exception(ctx
, EXCP_RI
);
3606 /* Load needed operands */
3612 /* Compare two registers */
3614 gen_load_gpr(t0
, rs
);
3615 gen_load_gpr(t1
, rt
);
3618 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3634 /* Compare to zero */
3636 gen_load_gpr(t0
, rs
);
3639 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3642 #if defined(TARGET_MIPS64)
3644 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3646 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3649 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3656 /* Jump to immediate */
3657 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3663 /* Jump to register */
3664 if (offset
!= 0 && offset
!= 16) {
3665 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3666 others are reserved. */
3667 MIPS_INVAL("jump hint");
3668 generate_exception(ctx
, EXCP_RI
);
3671 gen_load_gpr(btarget
, rs
);
3674 MIPS_INVAL("branch/jump");
3675 generate_exception(ctx
, EXCP_RI
);
3678 if (bcond_compute
== 0) {
3679 /* No condition to be computed */
3681 case OPC_BEQ
: /* rx == rx */
3682 case OPC_BEQL
: /* rx == rx likely */
3683 case OPC_BGEZ
: /* 0 >= 0 */
3684 case OPC_BGEZL
: /* 0 >= 0 likely */
3685 case OPC_BLEZ
: /* 0 <= 0 */
3686 case OPC_BLEZL
: /* 0 <= 0 likely */
3688 ctx
->hflags
|= MIPS_HFLAG_B
;
3689 MIPS_DEBUG("balways");
3692 case OPC_BGEZAL
: /* 0 >= 0 */
3693 case OPC_BGEZALL
: /* 0 >= 0 likely */
3694 ctx
->hflags
|= (opc
== OPC_BGEZALS
3696 : MIPS_HFLAG_BDS32
);
3697 /* Always take and link */
3699 ctx
->hflags
|= MIPS_HFLAG_B
;
3700 MIPS_DEBUG("balways and link");
3702 case OPC_BNE
: /* rx != rx */
3703 case OPC_BGTZ
: /* 0 > 0 */
3704 case OPC_BLTZ
: /* 0 < 0 */
3706 MIPS_DEBUG("bnever (NOP)");
3709 case OPC_BLTZAL
: /* 0 < 0 */
3710 ctx
->hflags
|= (opc
== OPC_BLTZALS
3712 : MIPS_HFLAG_BDS32
);
3713 /* Handle as an unconditional branch to get correct delay
3716 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3717 ctx
->hflags
|= MIPS_HFLAG_B
;
3718 MIPS_DEBUG("bnever and link");
3720 case OPC_BLTZALL
: /* 0 < 0 likely */
3721 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3722 /* Skip the instruction in the delay slot */
3723 MIPS_DEBUG("bnever, link and skip");
3726 case OPC_BNEL
: /* rx != rx likely */
3727 case OPC_BGTZL
: /* 0 > 0 likely */
3728 case OPC_BLTZL
: /* 0 < 0 likely */
3729 /* Skip the instruction in the delay slot */
3730 MIPS_DEBUG("bnever and skip");
3734 ctx
->hflags
|= MIPS_HFLAG_B
;
3735 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3739 ctx
->hflags
|= MIPS_HFLAG_BX
;
3744 ctx
->hflags
|= MIPS_HFLAG_B
;
3745 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3747 : MIPS_HFLAG_BDS32
);
3748 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3751 ctx
->hflags
|= MIPS_HFLAG_BR
;
3752 if (insn_bytes
== 4)
3753 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3754 MIPS_DEBUG("jr %s", regnames
[rs
]);
3760 ctx
->hflags
|= MIPS_HFLAG_BR
;
3761 ctx
->hflags
|= (opc
== OPC_JALRS
3763 : MIPS_HFLAG_BDS32
);
3764 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3767 MIPS_INVAL("branch/jump");
3768 generate_exception(ctx
, EXCP_RI
);
3774 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3775 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3776 regnames
[rs
], regnames
[rt
], btgt
);
3779 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3780 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3781 regnames
[rs
], regnames
[rt
], btgt
);
3784 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3785 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3786 regnames
[rs
], regnames
[rt
], btgt
);
3789 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3790 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3791 regnames
[rs
], regnames
[rt
], btgt
);
3794 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3795 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3798 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3799 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3803 ctx
->hflags
|= (opc
== OPC_BGEZALS
3805 : MIPS_HFLAG_BDS32
);
3806 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3807 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3811 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3813 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3816 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3817 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3820 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3821 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3824 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3825 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3828 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3829 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3832 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3833 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3836 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3837 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3840 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3841 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3843 #if defined(TARGET_MIPS64)
3845 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3846 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3851 ctx
->hflags
|= (opc
== OPC_BLTZALS
3853 : MIPS_HFLAG_BDS32
);
3854 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3856 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3858 ctx
->hflags
|= MIPS_HFLAG_BC
;
3861 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3863 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3865 ctx
->hflags
|= MIPS_HFLAG_BL
;
3868 MIPS_INVAL("conditional branch/jump");
3869 generate_exception(ctx
, EXCP_RI
);
3873 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3874 blink
, ctx
->hflags
, btgt
);
3876 ctx
->btarget
= btgt
;
3878 int post_delay
= insn_bytes
;
3879 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3881 if (opc
!= OPC_JALRC
)
3882 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3884 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3888 if (insn_bytes
== 2)
3889 ctx
->hflags
|= MIPS_HFLAG_B16
;
3894 /* special3 bitfield operations */
3895 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3896 int rs
, int lsb
, int msb
)
3898 TCGv t0
= tcg_temp_new();
3899 TCGv t1
= tcg_temp_new();
3901 gen_load_gpr(t1
, rs
);
3906 tcg_gen_shri_tl(t0
, t1
, lsb
);
3908 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3910 tcg_gen_ext32s_tl(t0
, t0
);
3913 #if defined(TARGET_MIPS64)
3915 tcg_gen_shri_tl(t0
, t1
, lsb
);
3917 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3921 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3922 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3925 tcg_gen_shri_tl(t0
, t1
, lsb
);
3926 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3932 gen_load_gpr(t0
, rt
);
3933 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3934 tcg_gen_ext32s_tl(t0
, t0
);
3936 #if defined(TARGET_MIPS64)
3938 gen_load_gpr(t0
, rt
);
3939 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3942 gen_load_gpr(t0
, rt
);
3943 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3946 gen_load_gpr(t0
, rt
);
3947 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3952 MIPS_INVAL("bitops");
3953 generate_exception(ctx
, EXCP_RI
);
3958 gen_store_gpr(t0
, rt
);
3963 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
3968 /* If no destination, treat it as a NOP. */
3973 t0
= tcg_temp_new();
3974 gen_load_gpr(t0
, rt
);
3978 TCGv t1
= tcg_temp_new();
3980 tcg_gen_shri_tl(t1
, t0
, 8);
3981 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
3982 tcg_gen_shli_tl(t0
, t0
, 8);
3983 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
3984 tcg_gen_or_tl(t0
, t0
, t1
);
3986 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3990 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
3993 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
3995 #if defined(TARGET_MIPS64)
3998 TCGv t1
= tcg_temp_new();
4000 tcg_gen_shri_tl(t1
, t0
, 8);
4001 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4002 tcg_gen_shli_tl(t0
, t0
, 8);
4003 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4004 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4010 TCGv t1
= tcg_temp_new();
4012 tcg_gen_shri_tl(t1
, t0
, 16);
4013 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4014 tcg_gen_shli_tl(t0
, t0
, 16);
4015 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4016 tcg_gen_or_tl(t0
, t0
, t1
);
4017 tcg_gen_shri_tl(t1
, t0
, 32);
4018 tcg_gen_shli_tl(t0
, t0
, 32);
4019 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4025 MIPS_INVAL("bsfhl");
4026 generate_exception(ctx
, EXCP_RI
);
4033 #ifndef CONFIG_USER_ONLY
4034 /* CP0 (MMU and control) */
4035 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4037 TCGv_i32 t0
= tcg_temp_new_i32();
4039 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4040 tcg_gen_ext_i32_tl(arg
, t0
);
4041 tcg_temp_free_i32(t0
);
4044 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4046 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4047 tcg_gen_ext32s_tl(arg
, arg
);
4050 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4052 TCGv_i32 t0
= tcg_temp_new_i32();
4054 tcg_gen_trunc_tl_i32(t0
, arg
);
4055 tcg_gen_st_i32(t0
, cpu_env
, off
);
4056 tcg_temp_free_i32(t0
);
4059 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4061 tcg_gen_ext32s_tl(arg
, arg
);
4062 tcg_gen_st_tl(arg
, cpu_env
, off
);
4065 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4067 const char *rn
= "invalid";
4070 check_insn(ctx
, ISA_MIPS32
);
4076 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4080 check_insn(ctx
, ASE_MT
);
4081 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4085 check_insn(ctx
, ASE_MT
);
4086 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4090 check_insn(ctx
, ASE_MT
);
4091 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4101 gen_helper_mfc0_random(arg
, cpu_env
);
4105 check_insn(ctx
, ASE_MT
);
4106 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4110 check_insn(ctx
, ASE_MT
);
4111 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4115 check_insn(ctx
, ASE_MT
);
4116 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4120 check_insn(ctx
, ASE_MT
);
4121 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4125 check_insn(ctx
, ASE_MT
);
4126 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4130 check_insn(ctx
, ASE_MT
);
4131 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4132 rn
= "VPEScheFBack";
4135 check_insn(ctx
, ASE_MT
);
4136 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4146 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4147 tcg_gen_ext32s_tl(arg
, arg
);
4151 check_insn(ctx
, ASE_MT
);
4152 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4156 check_insn(ctx
, ASE_MT
);
4157 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4161 check_insn(ctx
, ASE_MT
);
4162 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4166 check_insn(ctx
, ASE_MT
);
4167 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4171 check_insn(ctx
, ASE_MT
);
4172 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4176 check_insn(ctx
, ASE_MT
);
4177 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4181 check_insn(ctx
, ASE_MT
);
4182 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4192 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4193 tcg_gen_ext32s_tl(arg
, arg
);
4203 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4204 tcg_gen_ext32s_tl(arg
, arg
);
4208 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4209 rn
= "ContextConfig";
4218 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4222 check_insn(ctx
, ISA_MIPS32R2
);
4223 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4233 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4237 check_insn(ctx
, ISA_MIPS32R2
);
4238 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4242 check_insn(ctx
, ISA_MIPS32R2
);
4243 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4247 check_insn(ctx
, ISA_MIPS32R2
);
4248 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4252 check_insn(ctx
, ISA_MIPS32R2
);
4253 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4257 check_insn(ctx
, ISA_MIPS32R2
);
4258 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4268 check_insn(ctx
, ISA_MIPS32R2
);
4269 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4279 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4280 tcg_gen_ext32s_tl(arg
, arg
);
4290 /* Mark as an IO operation because we read the time. */
4293 gen_helper_mfc0_count(arg
, cpu_env
);
4297 /* Break the TB to be able to take timer interrupts immediately
4298 after reading count. */
4299 ctx
->bstate
= BS_STOP
;
4302 /* 6,7 are implementation dependent */
4310 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4311 tcg_gen_ext32s_tl(arg
, arg
);
4321 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4324 /* 6,7 are implementation dependent */
4332 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4336 check_insn(ctx
, ISA_MIPS32R2
);
4337 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4341 check_insn(ctx
, ISA_MIPS32R2
);
4342 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4346 check_insn(ctx
, ISA_MIPS32R2
);
4347 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4357 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4367 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4368 tcg_gen_ext32s_tl(arg
, arg
);
4378 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4382 check_insn(ctx
, ISA_MIPS32R2
);
4383 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4393 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4397 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4401 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4405 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4408 /* 4,5 are reserved */
4409 /* 6,7 are implementation dependent */
4411 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4415 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4425 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4435 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4445 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4455 #if defined(TARGET_MIPS64)
4456 check_insn(ctx
, ISA_MIPS3
);
4457 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4458 tcg_gen_ext32s_tl(arg
, arg
);
4467 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4470 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4478 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4479 rn
= "'Diagnostic"; /* implementation dependent */
4484 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4488 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4489 rn
= "TraceControl";
4492 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4493 rn
= "TraceControl2";
4496 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4497 rn
= "UserTraceData";
4500 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4511 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4512 tcg_gen_ext32s_tl(arg
, arg
);
4522 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4523 rn
= "Performance0";
4526 // gen_helper_mfc0_performance1(arg);
4527 rn
= "Performance1";
4530 // gen_helper_mfc0_performance2(arg);
4531 rn
= "Performance2";
4534 // gen_helper_mfc0_performance3(arg);
4535 rn
= "Performance3";
4538 // gen_helper_mfc0_performance4(arg);
4539 rn
= "Performance4";
4542 // gen_helper_mfc0_performance5(arg);
4543 rn
= "Performance5";
4546 // gen_helper_mfc0_performance6(arg);
4547 rn
= "Performance6";
4550 // gen_helper_mfc0_performance7(arg);
4551 rn
= "Performance7";
4558 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4564 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4577 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4584 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4597 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4604 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4614 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4615 tcg_gen_ext32s_tl(arg
, arg
);
4626 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4636 (void)rn
; /* avoid a compiler warning */
4637 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4641 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4642 generate_exception(ctx
, EXCP_RI
);
4645 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4647 const char *rn
= "invalid";
4650 check_insn(ctx
, ISA_MIPS32
);
4659 gen_helper_mtc0_index(cpu_env
, arg
);
4663 check_insn(ctx
, ASE_MT
);
4664 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4668 check_insn(ctx
, ASE_MT
);
4673 check_insn(ctx
, ASE_MT
);
4688 check_insn(ctx
, ASE_MT
);
4689 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4693 check_insn(ctx
, ASE_MT
);
4694 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4698 check_insn(ctx
, ASE_MT
);
4699 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4703 check_insn(ctx
, ASE_MT
);
4704 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4708 check_insn(ctx
, ASE_MT
);
4709 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4713 check_insn(ctx
, ASE_MT
);
4714 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4715 rn
= "VPEScheFBack";
4718 check_insn(ctx
, ASE_MT
);
4719 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4729 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4733 check_insn(ctx
, ASE_MT
);
4734 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4738 check_insn(ctx
, ASE_MT
);
4739 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4743 check_insn(ctx
, ASE_MT
);
4744 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4748 check_insn(ctx
, ASE_MT
);
4749 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4753 check_insn(ctx
, ASE_MT
);
4754 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4758 check_insn(ctx
, ASE_MT
);
4759 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4763 check_insn(ctx
, ASE_MT
);
4764 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4774 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4784 gen_helper_mtc0_context(cpu_env
, arg
);
4788 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4789 rn
= "ContextConfig";
4798 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4802 check_insn(ctx
, ISA_MIPS32R2
);
4803 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4813 gen_helper_mtc0_wired(cpu_env
, arg
);
4817 check_insn(ctx
, ISA_MIPS32R2
);
4818 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4822 check_insn(ctx
, ISA_MIPS32R2
);
4823 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4827 check_insn(ctx
, ISA_MIPS32R2
);
4828 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4832 check_insn(ctx
, ISA_MIPS32R2
);
4833 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4837 check_insn(ctx
, ISA_MIPS32R2
);
4838 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4848 check_insn(ctx
, ISA_MIPS32R2
);
4849 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4863 gen_helper_mtc0_count(cpu_env
, arg
);
4866 /* 6,7 are implementation dependent */
4874 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4884 gen_helper_mtc0_compare(cpu_env
, arg
);
4887 /* 6,7 are implementation dependent */
4895 save_cpu_state(ctx
, 1);
4896 gen_helper_mtc0_status(cpu_env
, arg
);
4897 /* BS_STOP isn't good enough here, hflags may have changed. */
4898 gen_save_pc(ctx
->pc
+ 4);
4899 ctx
->bstate
= BS_EXCP
;
4903 check_insn(ctx
, ISA_MIPS32R2
);
4904 gen_helper_mtc0_intctl(cpu_env
, arg
);
4905 /* Stop translation as we may have switched the execution mode */
4906 ctx
->bstate
= BS_STOP
;
4910 check_insn(ctx
, ISA_MIPS32R2
);
4911 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4912 /* Stop translation as we may have switched the execution mode */
4913 ctx
->bstate
= BS_STOP
;
4917 check_insn(ctx
, ISA_MIPS32R2
);
4918 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4919 /* Stop translation as we may have switched the execution mode */
4920 ctx
->bstate
= BS_STOP
;
4930 save_cpu_state(ctx
, 1);
4931 gen_helper_mtc0_cause(cpu_env
, arg
);
4941 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4955 check_insn(ctx
, ISA_MIPS32R2
);
4956 gen_helper_mtc0_ebase(cpu_env
, arg
);
4966 gen_helper_mtc0_config0(cpu_env
, arg
);
4968 /* Stop translation as we may have switched the execution mode */
4969 ctx
->bstate
= BS_STOP
;
4972 /* ignored, read only */
4976 gen_helper_mtc0_config2(cpu_env
, arg
);
4978 /* Stop translation as we may have switched the execution mode */
4979 ctx
->bstate
= BS_STOP
;
4982 /* ignored, read only */
4985 /* 4,5 are reserved */
4986 /* 6,7 are implementation dependent */
4996 rn
= "Invalid config selector";
5003 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5013 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5023 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5033 #if defined(TARGET_MIPS64)
5034 check_insn(ctx
, ISA_MIPS3
);
5035 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5044 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5047 gen_helper_mtc0_framemask(cpu_env
, arg
);
5056 rn
= "Diagnostic"; /* implementation dependent */
5061 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5062 /* BS_STOP isn't good enough here, hflags may have changed. */
5063 gen_save_pc(ctx
->pc
+ 4);
5064 ctx
->bstate
= BS_EXCP
;
5068 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5069 rn
= "TraceControl";
5070 /* Stop translation as we may have switched the execution mode */
5071 ctx
->bstate
= BS_STOP
;
5074 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5075 rn
= "TraceControl2";
5076 /* Stop translation as we may have switched the execution mode */
5077 ctx
->bstate
= BS_STOP
;
5080 /* Stop translation as we may have switched the execution mode */
5081 ctx
->bstate
= BS_STOP
;
5082 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5083 rn
= "UserTraceData";
5084 /* Stop translation as we may have switched the execution mode */
5085 ctx
->bstate
= BS_STOP
;
5088 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5089 /* Stop translation as we may have switched the execution mode */
5090 ctx
->bstate
= BS_STOP
;
5101 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5111 gen_helper_mtc0_performance0(cpu_env
, arg
);
5112 rn
= "Performance0";
5115 // gen_helper_mtc0_performance1(arg);
5116 rn
= "Performance1";
5119 // gen_helper_mtc0_performance2(arg);
5120 rn
= "Performance2";
5123 // gen_helper_mtc0_performance3(arg);
5124 rn
= "Performance3";
5127 // gen_helper_mtc0_performance4(arg);
5128 rn
= "Performance4";
5131 // gen_helper_mtc0_performance5(arg);
5132 rn
= "Performance5";
5135 // gen_helper_mtc0_performance6(arg);
5136 rn
= "Performance6";
5139 // gen_helper_mtc0_performance7(arg);
5140 rn
= "Performance7";
5166 gen_helper_mtc0_taglo(cpu_env
, arg
);
5173 gen_helper_mtc0_datalo(cpu_env
, arg
);
5186 gen_helper_mtc0_taghi(cpu_env
, arg
);
5193 gen_helper_mtc0_datahi(cpu_env
, arg
);
5204 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5215 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5221 /* Stop translation as we may have switched the execution mode */
5222 ctx
->bstate
= BS_STOP
;
5227 (void)rn
; /* avoid a compiler warning */
5228 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5229 /* For simplicity assume that all writes can cause interrupts. */
5232 ctx
->bstate
= BS_STOP
;
5237 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5238 generate_exception(ctx
, EXCP_RI
);
5241 #if defined(TARGET_MIPS64)
5242 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5244 const char *rn
= "invalid";
5247 check_insn(ctx
, ISA_MIPS64
);
5253 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5257 check_insn(ctx
, ASE_MT
);
5258 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5262 check_insn(ctx
, ASE_MT
);
5263 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5267 check_insn(ctx
, ASE_MT
);
5268 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5278 gen_helper_mfc0_random(arg
, cpu_env
);
5282 check_insn(ctx
, ASE_MT
);
5283 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5287 check_insn(ctx
, ASE_MT
);
5288 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5292 check_insn(ctx
, ASE_MT
);
5293 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5297 check_insn(ctx
, ASE_MT
);
5298 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5302 check_insn(ctx
, ASE_MT
);
5303 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5307 check_insn(ctx
, ASE_MT
);
5308 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5309 rn
= "VPEScheFBack";
5312 check_insn(ctx
, ASE_MT
);
5313 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5323 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5327 check_insn(ctx
, ASE_MT
);
5328 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5332 check_insn(ctx
, ASE_MT
);
5333 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5337 check_insn(ctx
, ASE_MT
);
5338 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5342 check_insn(ctx
, ASE_MT
);
5343 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5347 check_insn(ctx
, ASE_MT
);
5348 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5352 check_insn(ctx
, ASE_MT
);
5353 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5357 check_insn(ctx
, ASE_MT
);
5358 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5368 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5378 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5382 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5383 rn
= "ContextConfig";
5392 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5396 check_insn(ctx
, ISA_MIPS32R2
);
5397 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5407 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5411 check_insn(ctx
, ISA_MIPS32R2
);
5412 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5416 check_insn(ctx
, ISA_MIPS32R2
);
5417 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5421 check_insn(ctx
, ISA_MIPS32R2
);
5422 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5426 check_insn(ctx
, ISA_MIPS32R2
);
5427 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5431 check_insn(ctx
, ISA_MIPS32R2
);
5432 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5442 check_insn(ctx
, ISA_MIPS32R2
);
5443 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5453 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5463 /* Mark as an IO operation because we read the time. */
5466 gen_helper_mfc0_count(arg
, cpu_env
);
5470 /* Break the TB to be able to take timer interrupts immediately
5471 after reading count. */
5472 ctx
->bstate
= BS_STOP
;
5475 /* 6,7 are implementation dependent */
5483 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5493 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5496 /* 6,7 are implementation dependent */
5504 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5508 check_insn(ctx
, ISA_MIPS32R2
);
5509 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5513 check_insn(ctx
, ISA_MIPS32R2
);
5514 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5518 check_insn(ctx
, ISA_MIPS32R2
);
5519 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5529 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5539 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5549 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5553 check_insn(ctx
, ISA_MIPS32R2
);
5554 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5564 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5568 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5572 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5576 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5579 /* 6,7 are implementation dependent */
5581 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5585 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5595 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5605 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5615 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5625 check_insn(ctx
, ISA_MIPS3
);
5626 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5634 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5637 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5645 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5646 rn
= "'Diagnostic"; /* implementation dependent */
5651 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5655 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5656 rn
= "TraceControl";
5659 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5660 rn
= "TraceControl2";
5663 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5664 rn
= "UserTraceData";
5667 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5678 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5688 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5689 rn
= "Performance0";
5692 // gen_helper_dmfc0_performance1(arg);
5693 rn
= "Performance1";
5696 // gen_helper_dmfc0_performance2(arg);
5697 rn
= "Performance2";
5700 // gen_helper_dmfc0_performance3(arg);
5701 rn
= "Performance3";
5704 // gen_helper_dmfc0_performance4(arg);
5705 rn
= "Performance4";
5708 // gen_helper_dmfc0_performance5(arg);
5709 rn
= "Performance5";
5712 // gen_helper_dmfc0_performance6(arg);
5713 rn
= "Performance6";
5716 // gen_helper_dmfc0_performance7(arg);
5717 rn
= "Performance7";
5724 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5731 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5744 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5751 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5764 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5771 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5781 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5792 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5802 (void)rn
; /* avoid a compiler warning */
5803 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5807 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5808 generate_exception(ctx
, EXCP_RI
);
5811 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5813 const char *rn
= "invalid";
5816 check_insn(ctx
, ISA_MIPS64
);
5825 gen_helper_mtc0_index(cpu_env
, arg
);
5829 check_insn(ctx
, ASE_MT
);
5830 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5834 check_insn(ctx
, ASE_MT
);
5839 check_insn(ctx
, ASE_MT
);
5854 check_insn(ctx
, ASE_MT
);
5855 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5859 check_insn(ctx
, ASE_MT
);
5860 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5864 check_insn(ctx
, ASE_MT
);
5865 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5869 check_insn(ctx
, ASE_MT
);
5870 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5874 check_insn(ctx
, ASE_MT
);
5875 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5879 check_insn(ctx
, ASE_MT
);
5880 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5881 rn
= "VPEScheFBack";
5884 check_insn(ctx
, ASE_MT
);
5885 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5895 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5899 check_insn(ctx
, ASE_MT
);
5900 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5904 check_insn(ctx
, ASE_MT
);
5905 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5909 check_insn(ctx
, ASE_MT
);
5910 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5914 check_insn(ctx
, ASE_MT
);
5915 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5919 check_insn(ctx
, ASE_MT
);
5920 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5924 check_insn(ctx
, ASE_MT
);
5925 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5929 check_insn(ctx
, ASE_MT
);
5930 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5940 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5950 gen_helper_mtc0_context(cpu_env
, arg
);
5954 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5955 rn
= "ContextConfig";
5964 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5968 check_insn(ctx
, ISA_MIPS32R2
);
5969 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5979 gen_helper_mtc0_wired(cpu_env
, arg
);
5983 check_insn(ctx
, ISA_MIPS32R2
);
5984 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5988 check_insn(ctx
, ISA_MIPS32R2
);
5989 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
5993 check_insn(ctx
, ISA_MIPS32R2
);
5994 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
5998 check_insn(ctx
, ISA_MIPS32R2
);
5999 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6003 check_insn(ctx
, ISA_MIPS32R2
);
6004 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6014 check_insn(ctx
, ISA_MIPS32R2
);
6015 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6029 gen_helper_mtc0_count(cpu_env
, arg
);
6032 /* 6,7 are implementation dependent */
6036 /* Stop translation as we may have switched the execution mode */
6037 ctx
->bstate
= BS_STOP
;
6042 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6052 gen_helper_mtc0_compare(cpu_env
, arg
);
6055 /* 6,7 are implementation dependent */
6059 /* Stop translation as we may have switched the execution mode */
6060 ctx
->bstate
= BS_STOP
;
6065 save_cpu_state(ctx
, 1);
6066 gen_helper_mtc0_status(cpu_env
, arg
);
6067 /* BS_STOP isn't good enough here, hflags may have changed. */
6068 gen_save_pc(ctx
->pc
+ 4);
6069 ctx
->bstate
= BS_EXCP
;
6073 check_insn(ctx
, ISA_MIPS32R2
);
6074 gen_helper_mtc0_intctl(cpu_env
, arg
);
6075 /* Stop translation as we may have switched the execution mode */
6076 ctx
->bstate
= BS_STOP
;
6080 check_insn(ctx
, ISA_MIPS32R2
);
6081 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6082 /* Stop translation as we may have switched the execution mode */
6083 ctx
->bstate
= BS_STOP
;
6087 check_insn(ctx
, ISA_MIPS32R2
);
6088 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6089 /* Stop translation as we may have switched the execution mode */
6090 ctx
->bstate
= BS_STOP
;
6100 save_cpu_state(ctx
, 1);
6101 /* Mark as an IO operation because we may trigger a software
6106 gen_helper_mtc0_cause(cpu_env
, arg
);
6110 /* Stop translation as we may have triggered an intetrupt */
6111 ctx
->bstate
= BS_STOP
;
6121 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6135 check_insn(ctx
, ISA_MIPS32R2
);
6136 gen_helper_mtc0_ebase(cpu_env
, arg
);
6146 gen_helper_mtc0_config0(cpu_env
, arg
);
6148 /* Stop translation as we may have switched the execution mode */
6149 ctx
->bstate
= BS_STOP
;
6152 /* ignored, read only */
6156 gen_helper_mtc0_config2(cpu_env
, arg
);
6158 /* Stop translation as we may have switched the execution mode */
6159 ctx
->bstate
= BS_STOP
;
6165 /* 6,7 are implementation dependent */
6167 rn
= "Invalid config selector";
6174 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6184 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6194 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6204 check_insn(ctx
, ISA_MIPS3
);
6205 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6213 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6216 gen_helper_mtc0_framemask(cpu_env
, arg
);
6225 rn
= "Diagnostic"; /* implementation dependent */
6230 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6231 /* BS_STOP isn't good enough here, hflags may have changed. */
6232 gen_save_pc(ctx
->pc
+ 4);
6233 ctx
->bstate
= BS_EXCP
;
6237 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6238 /* Stop translation as we may have switched the execution mode */
6239 ctx
->bstate
= BS_STOP
;
6240 rn
= "TraceControl";
6243 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6244 /* Stop translation as we may have switched the execution mode */
6245 ctx
->bstate
= BS_STOP
;
6246 rn
= "TraceControl2";
6249 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6250 /* Stop translation as we may have switched the execution mode */
6251 ctx
->bstate
= BS_STOP
;
6252 rn
= "UserTraceData";
6255 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6256 /* Stop translation as we may have switched the execution mode */
6257 ctx
->bstate
= BS_STOP
;
6268 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6278 gen_helper_mtc0_performance0(cpu_env
, arg
);
6279 rn
= "Performance0";
6282 // gen_helper_mtc0_performance1(cpu_env, arg);
6283 rn
= "Performance1";
6286 // gen_helper_mtc0_performance2(cpu_env, arg);
6287 rn
= "Performance2";
6290 // gen_helper_mtc0_performance3(cpu_env, arg);
6291 rn
= "Performance3";
6294 // gen_helper_mtc0_performance4(cpu_env, arg);
6295 rn
= "Performance4";
6298 // gen_helper_mtc0_performance5(cpu_env, arg);
6299 rn
= "Performance5";
6302 // gen_helper_mtc0_performance6(cpu_env, arg);
6303 rn
= "Performance6";
6306 // gen_helper_mtc0_performance7(cpu_env, arg);
6307 rn
= "Performance7";
6333 gen_helper_mtc0_taglo(cpu_env
, arg
);
6340 gen_helper_mtc0_datalo(cpu_env
, arg
);
6353 gen_helper_mtc0_taghi(cpu_env
, arg
);
6360 gen_helper_mtc0_datahi(cpu_env
, arg
);
6371 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6382 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6388 /* Stop translation as we may have switched the execution mode */
6389 ctx
->bstate
= BS_STOP
;
6394 (void)rn
; /* avoid a compiler warning */
6395 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6396 /* For simplicity assume that all writes can cause interrupts. */
6399 ctx
->bstate
= BS_STOP
;
6404 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6405 generate_exception(ctx
, EXCP_RI
);
6407 #endif /* TARGET_MIPS64 */
6409 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6410 int u
, int sel
, int h
)
6412 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6413 TCGv t0
= tcg_temp_local_new();
6415 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6416 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6417 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6418 tcg_gen_movi_tl(t0
, -1);
6419 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6420 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6421 tcg_gen_movi_tl(t0
, -1);
6427 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6430 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6440 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6443 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6446 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6449 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6452 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6455 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6458 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6461 gen_mfc0(ctx
, t0
, rt
, sel
);
6468 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6471 gen_mfc0(ctx
, t0
, rt
, sel
);
6477 gen_helper_mftc0_status(t0
, cpu_env
);
6480 gen_mfc0(ctx
, t0
, rt
, sel
);
6486 gen_helper_mftc0_cause(t0
, cpu_env
);
6496 gen_helper_mftc0_epc(t0
, cpu_env
);
6506 gen_helper_mftc0_ebase(t0
, cpu_env
);
6516 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6526 gen_helper_mftc0_debug(t0
, cpu_env
);
6529 gen_mfc0(ctx
, t0
, rt
, sel
);
6534 gen_mfc0(ctx
, t0
, rt
, sel
);
6536 } else switch (sel
) {
6537 /* GPR registers. */
6539 gen_helper_1e0i(mftgpr
, t0
, rt
);
6541 /* Auxiliary CPU registers */
6545 gen_helper_1e0i(mftlo
, t0
, 0);
6548 gen_helper_1e0i(mfthi
, t0
, 0);
6551 gen_helper_1e0i(mftacx
, t0
, 0);
6554 gen_helper_1e0i(mftlo
, t0
, 1);
6557 gen_helper_1e0i(mfthi
, t0
, 1);
6560 gen_helper_1e0i(mftacx
, t0
, 1);
6563 gen_helper_1e0i(mftlo
, t0
, 2);
6566 gen_helper_1e0i(mfthi
, t0
, 2);
6569 gen_helper_1e0i(mftacx
, t0
, 2);
6572 gen_helper_1e0i(mftlo
, t0
, 3);
6575 gen_helper_1e0i(mfthi
, t0
, 3);
6578 gen_helper_1e0i(mftacx
, t0
, 3);
6581 gen_helper_mftdsp(t0
, cpu_env
);
6587 /* Floating point (COP1). */
6589 /* XXX: For now we support only a single FPU context. */
6591 TCGv_i32 fp0
= tcg_temp_new_i32();
6593 gen_load_fpr32(fp0
, rt
);
6594 tcg_gen_ext_i32_tl(t0
, fp0
);
6595 tcg_temp_free_i32(fp0
);
6597 TCGv_i32 fp0
= tcg_temp_new_i32();
6599 gen_load_fpr32h(fp0
, rt
);
6600 tcg_gen_ext_i32_tl(t0
, fp0
);
6601 tcg_temp_free_i32(fp0
);
6605 /* XXX: For now we support only a single FPU context. */
6606 gen_helper_1e0i(cfc1
, t0
, rt
);
6608 /* COP2: Not implemented. */
6615 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6616 gen_store_gpr(t0
, rd
);
6622 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6623 generate_exception(ctx
, EXCP_RI
);
6626 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6627 int u
, int sel
, int h
)
6629 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6630 TCGv t0
= tcg_temp_local_new();
6632 gen_load_gpr(t0
, rt
);
6633 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6634 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6635 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6637 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6638 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6645 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6648 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6658 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6661 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6664 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6667 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6670 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6673 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6676 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6679 gen_mtc0(ctx
, t0
, rd
, sel
);
6686 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6689 gen_mtc0(ctx
, t0
, rd
, sel
);
6695 gen_helper_mttc0_status(cpu_env
, t0
);
6698 gen_mtc0(ctx
, t0
, rd
, sel
);
6704 gen_helper_mttc0_cause(cpu_env
, t0
);
6714 gen_helper_mttc0_ebase(cpu_env
, t0
);
6724 gen_helper_mttc0_debug(cpu_env
, t0
);
6727 gen_mtc0(ctx
, t0
, rd
, sel
);
6732 gen_mtc0(ctx
, t0
, rd
, sel
);
6734 } else switch (sel
) {
6735 /* GPR registers. */
6737 gen_helper_0e1i(mttgpr
, t0
, rd
);
6739 /* Auxiliary CPU registers */
6743 gen_helper_0e1i(mttlo
, t0
, 0);
6746 gen_helper_0e1i(mtthi
, t0
, 0);
6749 gen_helper_0e1i(mttacx
, t0
, 0);
6752 gen_helper_0e1i(mttlo
, t0
, 1);
6755 gen_helper_0e1i(mtthi
, t0
, 1);
6758 gen_helper_0e1i(mttacx
, t0
, 1);
6761 gen_helper_0e1i(mttlo
, t0
, 2);
6764 gen_helper_0e1i(mtthi
, t0
, 2);
6767 gen_helper_0e1i(mttacx
, t0
, 2);
6770 gen_helper_0e1i(mttlo
, t0
, 3);
6773 gen_helper_0e1i(mtthi
, t0
, 3);
6776 gen_helper_0e1i(mttacx
, t0
, 3);
6779 gen_helper_mttdsp(cpu_env
, t0
);
6785 /* Floating point (COP1). */
6787 /* XXX: For now we support only a single FPU context. */
6789 TCGv_i32 fp0
= tcg_temp_new_i32();
6791 tcg_gen_trunc_tl_i32(fp0
, t0
);
6792 gen_store_fpr32(fp0
, rd
);
6793 tcg_temp_free_i32(fp0
);
6795 TCGv_i32 fp0
= tcg_temp_new_i32();
6797 tcg_gen_trunc_tl_i32(fp0
, t0
);
6798 gen_store_fpr32h(fp0
, rd
);
6799 tcg_temp_free_i32(fp0
);
6803 /* XXX: For now we support only a single FPU context. */
6804 gen_helper_0e1i(ctc1
, t0
, rd
);
6806 /* COP2: Not implemented. */
6813 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6819 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6820 generate_exception(ctx
, EXCP_RI
);
6823 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6825 const char *opn
= "ldst";
6827 check_cp0_enabled(ctx
);
6834 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6839 TCGv t0
= tcg_temp_new();
6841 gen_load_gpr(t0
, rt
);
6842 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6847 #if defined(TARGET_MIPS64)
6849 check_insn(ctx
, ISA_MIPS3
);
6854 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6858 check_insn(ctx
, ISA_MIPS3
);
6860 TCGv t0
= tcg_temp_new();
6862 gen_load_gpr(t0
, rt
);
6863 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6870 check_insn(ctx
, ASE_MT
);
6875 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6876 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6880 check_insn(ctx
, ASE_MT
);
6881 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6882 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6887 if (!env
->tlb
->helper_tlbwi
)
6889 gen_helper_tlbwi(cpu_env
);
6893 if (!env
->tlb
->helper_tlbwr
)
6895 gen_helper_tlbwr(cpu_env
);
6899 if (!env
->tlb
->helper_tlbp
)
6901 gen_helper_tlbp(cpu_env
);
6905 if (!env
->tlb
->helper_tlbr
)
6907 gen_helper_tlbr(cpu_env
);
6911 check_insn(ctx
, ISA_MIPS2
);
6912 gen_helper_eret(cpu_env
);
6913 ctx
->bstate
= BS_EXCP
;
6917 check_insn(ctx
, ISA_MIPS32
);
6918 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6920 generate_exception(ctx
, EXCP_RI
);
6922 gen_helper_deret(cpu_env
);
6923 ctx
->bstate
= BS_EXCP
;
6928 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
6929 /* If we get an exception, we want to restart at next instruction */
6931 save_cpu_state(ctx
, 1);
6933 gen_helper_wait(cpu_env
);
6934 ctx
->bstate
= BS_EXCP
;
6939 generate_exception(ctx
, EXCP_RI
);
6942 (void)opn
; /* avoid a compiler warning */
6943 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
6945 #endif /* !CONFIG_USER_ONLY */
6947 /* CP1 Branches (before delay slot) */
6948 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
6949 int32_t cc
, int32_t offset
)
6951 target_ulong btarget
;
6952 const char *opn
= "cp1 cond branch";
6953 TCGv_i32 t0
= tcg_temp_new_i32();
6956 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
6958 btarget
= ctx
->pc
+ 4 + offset
;
6962 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6963 tcg_gen_not_i32(t0
, t0
);
6964 tcg_gen_andi_i32(t0
, t0
, 1);
6965 tcg_gen_extu_i32_tl(bcond
, t0
);
6969 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6970 tcg_gen_not_i32(t0
, t0
);
6971 tcg_gen_andi_i32(t0
, t0
, 1);
6972 tcg_gen_extu_i32_tl(bcond
, t0
);
6976 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6977 tcg_gen_andi_i32(t0
, t0
, 1);
6978 tcg_gen_extu_i32_tl(bcond
, t0
);
6982 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6983 tcg_gen_andi_i32(t0
, t0
, 1);
6984 tcg_gen_extu_i32_tl(bcond
, t0
);
6987 ctx
->hflags
|= MIPS_HFLAG_BL
;
6991 TCGv_i32 t1
= tcg_temp_new_i32();
6992 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6993 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
6994 tcg_gen_nand_i32(t0
, t0
, t1
);
6995 tcg_temp_free_i32(t1
);
6996 tcg_gen_andi_i32(t0
, t0
, 1);
6997 tcg_gen_extu_i32_tl(bcond
, t0
);
7003 TCGv_i32 t1
= tcg_temp_new_i32();
7004 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7005 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7006 tcg_gen_or_i32(t0
, t0
, t1
);
7007 tcg_temp_free_i32(t1
);
7008 tcg_gen_andi_i32(t0
, t0
, 1);
7009 tcg_gen_extu_i32_tl(bcond
, t0
);
7015 TCGv_i32 t1
= tcg_temp_new_i32();
7016 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7017 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7018 tcg_gen_and_i32(t0
, t0
, t1
);
7019 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7020 tcg_gen_and_i32(t0
, t0
, t1
);
7021 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7022 tcg_gen_nand_i32(t0
, t0
, t1
);
7023 tcg_temp_free_i32(t1
);
7024 tcg_gen_andi_i32(t0
, t0
, 1);
7025 tcg_gen_extu_i32_tl(bcond
, t0
);
7031 TCGv_i32 t1
= tcg_temp_new_i32();
7032 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7033 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7034 tcg_gen_or_i32(t0
, t0
, t1
);
7035 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7036 tcg_gen_or_i32(t0
, t0
, t1
);
7037 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7038 tcg_gen_or_i32(t0
, t0
, t1
);
7039 tcg_temp_free_i32(t1
);
7040 tcg_gen_andi_i32(t0
, t0
, 1);
7041 tcg_gen_extu_i32_tl(bcond
, t0
);
7045 ctx
->hflags
|= MIPS_HFLAG_BC
;
7049 generate_exception (ctx
, EXCP_RI
);
7052 (void)opn
; /* avoid a compiler warning */
7053 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7054 ctx
->hflags
, btarget
);
7055 ctx
->btarget
= btarget
;
7058 tcg_temp_free_i32(t0
);
7061 /* Coprocessor 1 (FPU) */
7063 #define FOP(func, fmt) (((fmt) << 21) | (func))
7066 OPC_ADD_S
= FOP(0, FMT_S
),
7067 OPC_SUB_S
= FOP(1, FMT_S
),
7068 OPC_MUL_S
= FOP(2, FMT_S
),
7069 OPC_DIV_S
= FOP(3, FMT_S
),
7070 OPC_SQRT_S
= FOP(4, FMT_S
),
7071 OPC_ABS_S
= FOP(5, FMT_S
),
7072 OPC_MOV_S
= FOP(6, FMT_S
),
7073 OPC_NEG_S
= FOP(7, FMT_S
),
7074 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7075 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7076 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7077 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7078 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7079 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7080 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7081 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7082 OPC_MOVCF_S
= FOP(17, FMT_S
),
7083 OPC_MOVZ_S
= FOP(18, FMT_S
),
7084 OPC_MOVN_S
= FOP(19, FMT_S
),
7085 OPC_RECIP_S
= FOP(21, FMT_S
),
7086 OPC_RSQRT_S
= FOP(22, FMT_S
),
7087 OPC_RECIP2_S
= FOP(28, FMT_S
),
7088 OPC_RECIP1_S
= FOP(29, FMT_S
),
7089 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7090 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7091 OPC_CVT_D_S
= FOP(33, FMT_S
),
7092 OPC_CVT_W_S
= FOP(36, FMT_S
),
7093 OPC_CVT_L_S
= FOP(37, FMT_S
),
7094 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7095 OPC_CMP_F_S
= FOP (48, FMT_S
),
7096 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7097 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7098 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7099 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7100 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7101 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7102 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7103 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7104 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7105 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7106 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7107 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7108 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7109 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7110 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7112 OPC_ADD_D
= FOP(0, FMT_D
),
7113 OPC_SUB_D
= FOP(1, FMT_D
),
7114 OPC_MUL_D
= FOP(2, FMT_D
),
7115 OPC_DIV_D
= FOP(3, FMT_D
),
7116 OPC_SQRT_D
= FOP(4, FMT_D
),
7117 OPC_ABS_D
= FOP(5, FMT_D
),
7118 OPC_MOV_D
= FOP(6, FMT_D
),
7119 OPC_NEG_D
= FOP(7, FMT_D
),
7120 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7121 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7122 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7123 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7124 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7125 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7126 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7127 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7128 OPC_MOVCF_D
= FOP(17, FMT_D
),
7129 OPC_MOVZ_D
= FOP(18, FMT_D
),
7130 OPC_MOVN_D
= FOP(19, FMT_D
),
7131 OPC_RECIP_D
= FOP(21, FMT_D
),
7132 OPC_RSQRT_D
= FOP(22, FMT_D
),
7133 OPC_RECIP2_D
= FOP(28, FMT_D
),
7134 OPC_RECIP1_D
= FOP(29, FMT_D
),
7135 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7136 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7137 OPC_CVT_S_D
= FOP(32, FMT_D
),
7138 OPC_CVT_W_D
= FOP(36, FMT_D
),
7139 OPC_CVT_L_D
= FOP(37, FMT_D
),
7140 OPC_CMP_F_D
= FOP (48, FMT_D
),
7141 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7142 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7143 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7144 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7145 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7146 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7147 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7148 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7149 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7150 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7151 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7152 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7153 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7154 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7155 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7157 OPC_CVT_S_W
= FOP(32, FMT_W
),
7158 OPC_CVT_D_W
= FOP(33, FMT_W
),
7159 OPC_CVT_S_L
= FOP(32, FMT_L
),
7160 OPC_CVT_D_L
= FOP(33, FMT_L
),
7161 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7163 OPC_ADD_PS
= FOP(0, FMT_PS
),
7164 OPC_SUB_PS
= FOP(1, FMT_PS
),
7165 OPC_MUL_PS
= FOP(2, FMT_PS
),
7166 OPC_DIV_PS
= FOP(3, FMT_PS
),
7167 OPC_ABS_PS
= FOP(5, FMT_PS
),
7168 OPC_MOV_PS
= FOP(6, FMT_PS
),
7169 OPC_NEG_PS
= FOP(7, FMT_PS
),
7170 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7171 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7172 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7173 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7174 OPC_MULR_PS
= FOP(26, FMT_PS
),
7175 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7176 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7177 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7178 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7180 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7181 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7182 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7183 OPC_PLL_PS
= FOP(44, FMT_PS
),
7184 OPC_PLU_PS
= FOP(45, FMT_PS
),
7185 OPC_PUL_PS
= FOP(46, FMT_PS
),
7186 OPC_PUU_PS
= FOP(47, FMT_PS
),
7187 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7188 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7189 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7190 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7191 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7192 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7193 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7194 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7195 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7196 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7197 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7198 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7199 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7200 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7201 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7202 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7205 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7207 const char *opn
= "cp1 move";
7208 TCGv t0
= tcg_temp_new();
7213 TCGv_i32 fp0
= tcg_temp_new_i32();
7215 gen_load_fpr32(fp0
, fs
);
7216 tcg_gen_ext_i32_tl(t0
, fp0
);
7217 tcg_temp_free_i32(fp0
);
7219 gen_store_gpr(t0
, rt
);
7223 gen_load_gpr(t0
, rt
);
7225 TCGv_i32 fp0
= tcg_temp_new_i32();
7227 tcg_gen_trunc_tl_i32(fp0
, t0
);
7228 gen_store_fpr32(fp0
, fs
);
7229 tcg_temp_free_i32(fp0
);
7234 gen_helper_1e0i(cfc1
, t0
, fs
);
7235 gen_store_gpr(t0
, rt
);
7239 gen_load_gpr(t0
, rt
);
7240 gen_helper_0e1i(ctc1
, t0
, fs
);
7243 #if defined(TARGET_MIPS64)
7245 gen_load_fpr64(ctx
, t0
, fs
);
7246 gen_store_gpr(t0
, rt
);
7250 gen_load_gpr(t0
, rt
);
7251 gen_store_fpr64(ctx
, t0
, fs
);
7257 TCGv_i32 fp0
= tcg_temp_new_i32();
7259 gen_load_fpr32h(fp0
, fs
);
7260 tcg_gen_ext_i32_tl(t0
, fp0
);
7261 tcg_temp_free_i32(fp0
);
7263 gen_store_gpr(t0
, rt
);
7267 gen_load_gpr(t0
, rt
);
7269 TCGv_i32 fp0
= tcg_temp_new_i32();
7271 tcg_gen_trunc_tl_i32(fp0
, t0
);
7272 gen_store_fpr32h(fp0
, fs
);
7273 tcg_temp_free_i32(fp0
);
7279 generate_exception (ctx
, EXCP_RI
);
7282 (void)opn
; /* avoid a compiler warning */
7283 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7289 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7305 l1
= gen_new_label();
7306 t0
= tcg_temp_new_i32();
7307 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7308 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7309 tcg_temp_free_i32(t0
);
7311 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7313 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7318 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7321 TCGv_i32 t0
= tcg_temp_new_i32();
7322 int l1
= gen_new_label();
7329 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7330 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7331 gen_load_fpr32(t0
, fs
);
7332 gen_store_fpr32(t0
, fd
);
7334 tcg_temp_free_i32(t0
);
7337 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7340 TCGv_i32 t0
= tcg_temp_new_i32();
7342 int l1
= gen_new_label();
7349 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7350 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7351 tcg_temp_free_i32(t0
);
7352 fp0
= tcg_temp_new_i64();
7353 gen_load_fpr64(ctx
, fp0
, fs
);
7354 gen_store_fpr64(ctx
, fp0
, fd
);
7355 tcg_temp_free_i64(fp0
);
7359 static inline void gen_movcf_ps (int fs
, int fd
, int cc
, int tf
)
7362 TCGv_i32 t0
= tcg_temp_new_i32();
7363 int l1
= gen_new_label();
7364 int l2
= gen_new_label();
7371 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7372 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7373 gen_load_fpr32(t0
, fs
);
7374 gen_store_fpr32(t0
, fd
);
7377 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7378 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7379 gen_load_fpr32h(t0
, fs
);
7380 gen_store_fpr32h(t0
, fd
);
7381 tcg_temp_free_i32(t0
);
7386 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7387 int ft
, int fs
, int fd
, int cc
)
7389 const char *opn
= "farith";
7390 const char *condnames
[] = {
7408 const char *condnames_abs
[] = {
7426 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7427 uint32_t func
= ctx
->opcode
& 0x3f;
7432 TCGv_i32 fp0
= tcg_temp_new_i32();
7433 TCGv_i32 fp1
= tcg_temp_new_i32();
7435 gen_load_fpr32(fp0
, fs
);
7436 gen_load_fpr32(fp1
, ft
);
7437 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7438 tcg_temp_free_i32(fp1
);
7439 gen_store_fpr32(fp0
, fd
);
7440 tcg_temp_free_i32(fp0
);
7447 TCGv_i32 fp0
= tcg_temp_new_i32();
7448 TCGv_i32 fp1
= tcg_temp_new_i32();
7450 gen_load_fpr32(fp0
, fs
);
7451 gen_load_fpr32(fp1
, ft
);
7452 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7453 tcg_temp_free_i32(fp1
);
7454 gen_store_fpr32(fp0
, fd
);
7455 tcg_temp_free_i32(fp0
);
7462 TCGv_i32 fp0
= tcg_temp_new_i32();
7463 TCGv_i32 fp1
= tcg_temp_new_i32();
7465 gen_load_fpr32(fp0
, fs
);
7466 gen_load_fpr32(fp1
, ft
);
7467 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7468 tcg_temp_free_i32(fp1
);
7469 gen_store_fpr32(fp0
, fd
);
7470 tcg_temp_free_i32(fp0
);
7477 TCGv_i32 fp0
= tcg_temp_new_i32();
7478 TCGv_i32 fp1
= tcg_temp_new_i32();
7480 gen_load_fpr32(fp0
, fs
);
7481 gen_load_fpr32(fp1
, ft
);
7482 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7483 tcg_temp_free_i32(fp1
);
7484 gen_store_fpr32(fp0
, fd
);
7485 tcg_temp_free_i32(fp0
);
7492 TCGv_i32 fp0
= tcg_temp_new_i32();
7494 gen_load_fpr32(fp0
, fs
);
7495 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7496 gen_store_fpr32(fp0
, fd
);
7497 tcg_temp_free_i32(fp0
);
7503 TCGv_i32 fp0
= tcg_temp_new_i32();
7505 gen_load_fpr32(fp0
, fs
);
7506 gen_helper_float_abs_s(fp0
, fp0
);
7507 gen_store_fpr32(fp0
, fd
);
7508 tcg_temp_free_i32(fp0
);
7514 TCGv_i32 fp0
= tcg_temp_new_i32();
7516 gen_load_fpr32(fp0
, fs
);
7517 gen_store_fpr32(fp0
, fd
);
7518 tcg_temp_free_i32(fp0
);
7524 TCGv_i32 fp0
= tcg_temp_new_i32();
7526 gen_load_fpr32(fp0
, fs
);
7527 gen_helper_float_chs_s(fp0
, fp0
);
7528 gen_store_fpr32(fp0
, fd
);
7529 tcg_temp_free_i32(fp0
);
7534 check_cp1_64bitmode(ctx
);
7536 TCGv_i32 fp32
= tcg_temp_new_i32();
7537 TCGv_i64 fp64
= tcg_temp_new_i64();
7539 gen_load_fpr32(fp32
, fs
);
7540 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7541 tcg_temp_free_i32(fp32
);
7542 gen_store_fpr64(ctx
, fp64
, fd
);
7543 tcg_temp_free_i64(fp64
);
7548 check_cp1_64bitmode(ctx
);
7550 TCGv_i32 fp32
= tcg_temp_new_i32();
7551 TCGv_i64 fp64
= tcg_temp_new_i64();
7553 gen_load_fpr32(fp32
, fs
);
7554 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7555 tcg_temp_free_i32(fp32
);
7556 gen_store_fpr64(ctx
, fp64
, fd
);
7557 tcg_temp_free_i64(fp64
);
7562 check_cp1_64bitmode(ctx
);
7564 TCGv_i32 fp32
= tcg_temp_new_i32();
7565 TCGv_i64 fp64
= tcg_temp_new_i64();
7567 gen_load_fpr32(fp32
, fs
);
7568 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7569 tcg_temp_free_i32(fp32
);
7570 gen_store_fpr64(ctx
, fp64
, fd
);
7571 tcg_temp_free_i64(fp64
);
7576 check_cp1_64bitmode(ctx
);
7578 TCGv_i32 fp32
= tcg_temp_new_i32();
7579 TCGv_i64 fp64
= tcg_temp_new_i64();
7581 gen_load_fpr32(fp32
, fs
);
7582 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7583 tcg_temp_free_i32(fp32
);
7584 gen_store_fpr64(ctx
, fp64
, fd
);
7585 tcg_temp_free_i64(fp64
);
7591 TCGv_i32 fp0
= tcg_temp_new_i32();
7593 gen_load_fpr32(fp0
, fs
);
7594 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7595 gen_store_fpr32(fp0
, fd
);
7596 tcg_temp_free_i32(fp0
);
7602 TCGv_i32 fp0
= tcg_temp_new_i32();
7604 gen_load_fpr32(fp0
, fs
);
7605 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7606 gen_store_fpr32(fp0
, fd
);
7607 tcg_temp_free_i32(fp0
);
7613 TCGv_i32 fp0
= tcg_temp_new_i32();
7615 gen_load_fpr32(fp0
, fs
);
7616 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7617 gen_store_fpr32(fp0
, fd
);
7618 tcg_temp_free_i32(fp0
);
7624 TCGv_i32 fp0
= tcg_temp_new_i32();
7626 gen_load_fpr32(fp0
, fs
);
7627 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7628 gen_store_fpr32(fp0
, fd
);
7629 tcg_temp_free_i32(fp0
);
7634 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7639 int l1
= gen_new_label();
7643 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7645 fp0
= tcg_temp_new_i32();
7646 gen_load_fpr32(fp0
, fs
);
7647 gen_store_fpr32(fp0
, fd
);
7648 tcg_temp_free_i32(fp0
);
7655 int l1
= gen_new_label();
7659 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7660 fp0
= tcg_temp_new_i32();
7661 gen_load_fpr32(fp0
, fs
);
7662 gen_store_fpr32(fp0
, fd
);
7663 tcg_temp_free_i32(fp0
);
7672 TCGv_i32 fp0
= tcg_temp_new_i32();
7674 gen_load_fpr32(fp0
, fs
);
7675 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7676 gen_store_fpr32(fp0
, fd
);
7677 tcg_temp_free_i32(fp0
);
7684 TCGv_i32 fp0
= tcg_temp_new_i32();
7686 gen_load_fpr32(fp0
, fs
);
7687 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7688 gen_store_fpr32(fp0
, fd
);
7689 tcg_temp_free_i32(fp0
);
7694 check_cp1_64bitmode(ctx
);
7696 TCGv_i32 fp0
= tcg_temp_new_i32();
7697 TCGv_i32 fp1
= tcg_temp_new_i32();
7699 gen_load_fpr32(fp0
, fs
);
7700 gen_load_fpr32(fp1
, ft
);
7701 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7702 tcg_temp_free_i32(fp1
);
7703 gen_store_fpr32(fp0
, fd
);
7704 tcg_temp_free_i32(fp0
);
7709 check_cp1_64bitmode(ctx
);
7711 TCGv_i32 fp0
= tcg_temp_new_i32();
7713 gen_load_fpr32(fp0
, fs
);
7714 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7715 gen_store_fpr32(fp0
, fd
);
7716 tcg_temp_free_i32(fp0
);
7721 check_cp1_64bitmode(ctx
);
7723 TCGv_i32 fp0
= tcg_temp_new_i32();
7725 gen_load_fpr32(fp0
, fs
);
7726 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7727 gen_store_fpr32(fp0
, fd
);
7728 tcg_temp_free_i32(fp0
);
7733 check_cp1_64bitmode(ctx
);
7735 TCGv_i32 fp0
= tcg_temp_new_i32();
7736 TCGv_i32 fp1
= tcg_temp_new_i32();
7738 gen_load_fpr32(fp0
, fs
);
7739 gen_load_fpr32(fp1
, ft
);
7740 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7741 tcg_temp_free_i32(fp1
);
7742 gen_store_fpr32(fp0
, fd
);
7743 tcg_temp_free_i32(fp0
);
7748 check_cp1_registers(ctx
, fd
);
7750 TCGv_i32 fp32
= tcg_temp_new_i32();
7751 TCGv_i64 fp64
= tcg_temp_new_i64();
7753 gen_load_fpr32(fp32
, fs
);
7754 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7755 tcg_temp_free_i32(fp32
);
7756 gen_store_fpr64(ctx
, fp64
, fd
);
7757 tcg_temp_free_i64(fp64
);
7763 TCGv_i32 fp0
= tcg_temp_new_i32();
7765 gen_load_fpr32(fp0
, fs
);
7766 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7767 gen_store_fpr32(fp0
, fd
);
7768 tcg_temp_free_i32(fp0
);
7773 check_cp1_64bitmode(ctx
);
7775 TCGv_i32 fp32
= tcg_temp_new_i32();
7776 TCGv_i64 fp64
= tcg_temp_new_i64();
7778 gen_load_fpr32(fp32
, fs
);
7779 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7780 tcg_temp_free_i32(fp32
);
7781 gen_store_fpr64(ctx
, fp64
, fd
);
7782 tcg_temp_free_i64(fp64
);
7787 check_cp1_64bitmode(ctx
);
7789 TCGv_i64 fp64
= tcg_temp_new_i64();
7790 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7791 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7793 gen_load_fpr32(fp32_0
, fs
);
7794 gen_load_fpr32(fp32_1
, ft
);
7795 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7796 tcg_temp_free_i32(fp32_1
);
7797 tcg_temp_free_i32(fp32_0
);
7798 gen_store_fpr64(ctx
, fp64
, fd
);
7799 tcg_temp_free_i64(fp64
);
7812 case OPC_CMP_NGLE_S
:
7819 if (ctx
->opcode
& (1 << 6)) {
7820 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7821 opn
= condnames_abs
[func
-48];
7823 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7824 opn
= condnames
[func
-48];
7828 check_cp1_registers(ctx
, fs
| ft
| fd
);
7830 TCGv_i64 fp0
= tcg_temp_new_i64();
7831 TCGv_i64 fp1
= tcg_temp_new_i64();
7833 gen_load_fpr64(ctx
, fp0
, fs
);
7834 gen_load_fpr64(ctx
, fp1
, ft
);
7835 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7836 tcg_temp_free_i64(fp1
);
7837 gen_store_fpr64(ctx
, fp0
, fd
);
7838 tcg_temp_free_i64(fp0
);
7844 check_cp1_registers(ctx
, fs
| ft
| fd
);
7846 TCGv_i64 fp0
= tcg_temp_new_i64();
7847 TCGv_i64 fp1
= tcg_temp_new_i64();
7849 gen_load_fpr64(ctx
, fp0
, fs
);
7850 gen_load_fpr64(ctx
, fp1
, ft
);
7851 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7852 tcg_temp_free_i64(fp1
);
7853 gen_store_fpr64(ctx
, fp0
, fd
);
7854 tcg_temp_free_i64(fp0
);
7860 check_cp1_registers(ctx
, fs
| ft
| fd
);
7862 TCGv_i64 fp0
= tcg_temp_new_i64();
7863 TCGv_i64 fp1
= tcg_temp_new_i64();
7865 gen_load_fpr64(ctx
, fp0
, fs
);
7866 gen_load_fpr64(ctx
, fp1
, ft
);
7867 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7868 tcg_temp_free_i64(fp1
);
7869 gen_store_fpr64(ctx
, fp0
, fd
);
7870 tcg_temp_free_i64(fp0
);
7876 check_cp1_registers(ctx
, fs
| ft
| fd
);
7878 TCGv_i64 fp0
= tcg_temp_new_i64();
7879 TCGv_i64 fp1
= tcg_temp_new_i64();
7881 gen_load_fpr64(ctx
, fp0
, fs
);
7882 gen_load_fpr64(ctx
, fp1
, ft
);
7883 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7884 tcg_temp_free_i64(fp1
);
7885 gen_store_fpr64(ctx
, fp0
, fd
);
7886 tcg_temp_free_i64(fp0
);
7892 check_cp1_registers(ctx
, fs
| fd
);
7894 TCGv_i64 fp0
= tcg_temp_new_i64();
7896 gen_load_fpr64(ctx
, fp0
, fs
);
7897 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7898 gen_store_fpr64(ctx
, fp0
, fd
);
7899 tcg_temp_free_i64(fp0
);
7904 check_cp1_registers(ctx
, fs
| fd
);
7906 TCGv_i64 fp0
= tcg_temp_new_i64();
7908 gen_load_fpr64(ctx
, fp0
, fs
);
7909 gen_helper_float_abs_d(fp0
, fp0
);
7910 gen_store_fpr64(ctx
, fp0
, fd
);
7911 tcg_temp_free_i64(fp0
);
7916 check_cp1_registers(ctx
, fs
| fd
);
7918 TCGv_i64 fp0
= tcg_temp_new_i64();
7920 gen_load_fpr64(ctx
, fp0
, fs
);
7921 gen_store_fpr64(ctx
, fp0
, fd
);
7922 tcg_temp_free_i64(fp0
);
7927 check_cp1_registers(ctx
, fs
| fd
);
7929 TCGv_i64 fp0
= tcg_temp_new_i64();
7931 gen_load_fpr64(ctx
, fp0
, fs
);
7932 gen_helper_float_chs_d(fp0
, fp0
);
7933 gen_store_fpr64(ctx
, fp0
, fd
);
7934 tcg_temp_free_i64(fp0
);
7939 check_cp1_64bitmode(ctx
);
7941 TCGv_i64 fp0
= tcg_temp_new_i64();
7943 gen_load_fpr64(ctx
, fp0
, fs
);
7944 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
7945 gen_store_fpr64(ctx
, fp0
, fd
);
7946 tcg_temp_free_i64(fp0
);
7951 check_cp1_64bitmode(ctx
);
7953 TCGv_i64 fp0
= tcg_temp_new_i64();
7955 gen_load_fpr64(ctx
, fp0
, fs
);
7956 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
7957 gen_store_fpr64(ctx
, fp0
, fd
);
7958 tcg_temp_free_i64(fp0
);
7963 check_cp1_64bitmode(ctx
);
7965 TCGv_i64 fp0
= tcg_temp_new_i64();
7967 gen_load_fpr64(ctx
, fp0
, fs
);
7968 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
7969 gen_store_fpr64(ctx
, fp0
, fd
);
7970 tcg_temp_free_i64(fp0
);
7975 check_cp1_64bitmode(ctx
);
7977 TCGv_i64 fp0
= tcg_temp_new_i64();
7979 gen_load_fpr64(ctx
, fp0
, fs
);
7980 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
7981 gen_store_fpr64(ctx
, fp0
, fd
);
7982 tcg_temp_free_i64(fp0
);
7987 check_cp1_registers(ctx
, fs
);
7989 TCGv_i32 fp32
= tcg_temp_new_i32();
7990 TCGv_i64 fp64
= tcg_temp_new_i64();
7992 gen_load_fpr64(ctx
, fp64
, fs
);
7993 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
7994 tcg_temp_free_i64(fp64
);
7995 gen_store_fpr32(fp32
, fd
);
7996 tcg_temp_free_i32(fp32
);
8001 check_cp1_registers(ctx
, fs
);
8003 TCGv_i32 fp32
= tcg_temp_new_i32();
8004 TCGv_i64 fp64
= tcg_temp_new_i64();
8006 gen_load_fpr64(ctx
, fp64
, fs
);
8007 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8008 tcg_temp_free_i64(fp64
);
8009 gen_store_fpr32(fp32
, fd
);
8010 tcg_temp_free_i32(fp32
);
8015 check_cp1_registers(ctx
, fs
);
8017 TCGv_i32 fp32
= tcg_temp_new_i32();
8018 TCGv_i64 fp64
= tcg_temp_new_i64();
8020 gen_load_fpr64(ctx
, fp64
, fs
);
8021 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8022 tcg_temp_free_i64(fp64
);
8023 gen_store_fpr32(fp32
, fd
);
8024 tcg_temp_free_i32(fp32
);
8029 check_cp1_registers(ctx
, fs
);
8031 TCGv_i32 fp32
= tcg_temp_new_i32();
8032 TCGv_i64 fp64
= tcg_temp_new_i64();
8034 gen_load_fpr64(ctx
, fp64
, fs
);
8035 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8036 tcg_temp_free_i64(fp64
);
8037 gen_store_fpr32(fp32
, fd
);
8038 tcg_temp_free_i32(fp32
);
8043 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8048 int l1
= gen_new_label();
8052 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8054 fp0
= tcg_temp_new_i64();
8055 gen_load_fpr64(ctx
, fp0
, fs
);
8056 gen_store_fpr64(ctx
, fp0
, fd
);
8057 tcg_temp_free_i64(fp0
);
8064 int l1
= gen_new_label();
8068 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8069 fp0
= tcg_temp_new_i64();
8070 gen_load_fpr64(ctx
, fp0
, fs
);
8071 gen_store_fpr64(ctx
, fp0
, fd
);
8072 tcg_temp_free_i64(fp0
);
8079 check_cp1_64bitmode(ctx
);
8081 TCGv_i64 fp0
= tcg_temp_new_i64();
8083 gen_load_fpr64(ctx
, fp0
, fs
);
8084 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8085 gen_store_fpr64(ctx
, fp0
, fd
);
8086 tcg_temp_free_i64(fp0
);
8091 check_cp1_64bitmode(ctx
);
8093 TCGv_i64 fp0
= tcg_temp_new_i64();
8095 gen_load_fpr64(ctx
, fp0
, fs
);
8096 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8097 gen_store_fpr64(ctx
, fp0
, fd
);
8098 tcg_temp_free_i64(fp0
);
8103 check_cp1_64bitmode(ctx
);
8105 TCGv_i64 fp0
= tcg_temp_new_i64();
8106 TCGv_i64 fp1
= tcg_temp_new_i64();
8108 gen_load_fpr64(ctx
, fp0
, fs
);
8109 gen_load_fpr64(ctx
, fp1
, ft
);
8110 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8111 tcg_temp_free_i64(fp1
);
8112 gen_store_fpr64(ctx
, fp0
, fd
);
8113 tcg_temp_free_i64(fp0
);
8118 check_cp1_64bitmode(ctx
);
8120 TCGv_i64 fp0
= tcg_temp_new_i64();
8122 gen_load_fpr64(ctx
, fp0
, fs
);
8123 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8124 gen_store_fpr64(ctx
, fp0
, fd
);
8125 tcg_temp_free_i64(fp0
);
8130 check_cp1_64bitmode(ctx
);
8132 TCGv_i64 fp0
= tcg_temp_new_i64();
8134 gen_load_fpr64(ctx
, fp0
, fs
);
8135 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8136 gen_store_fpr64(ctx
, fp0
, fd
);
8137 tcg_temp_free_i64(fp0
);
8142 check_cp1_64bitmode(ctx
);
8144 TCGv_i64 fp0
= tcg_temp_new_i64();
8145 TCGv_i64 fp1
= tcg_temp_new_i64();
8147 gen_load_fpr64(ctx
, fp0
, fs
);
8148 gen_load_fpr64(ctx
, fp1
, ft
);
8149 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8150 tcg_temp_free_i64(fp1
);
8151 gen_store_fpr64(ctx
, fp0
, fd
);
8152 tcg_temp_free_i64(fp0
);
8165 case OPC_CMP_NGLE_D
:
8172 if (ctx
->opcode
& (1 << 6)) {
8173 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8174 opn
= condnames_abs
[func
-48];
8176 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8177 opn
= condnames
[func
-48];
8181 check_cp1_registers(ctx
, fs
);
8183 TCGv_i32 fp32
= tcg_temp_new_i32();
8184 TCGv_i64 fp64
= tcg_temp_new_i64();
8186 gen_load_fpr64(ctx
, fp64
, fs
);
8187 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8188 tcg_temp_free_i64(fp64
);
8189 gen_store_fpr32(fp32
, fd
);
8190 tcg_temp_free_i32(fp32
);
8195 check_cp1_registers(ctx
, fs
);
8197 TCGv_i32 fp32
= tcg_temp_new_i32();
8198 TCGv_i64 fp64
= tcg_temp_new_i64();
8200 gen_load_fpr64(ctx
, fp64
, fs
);
8201 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8202 tcg_temp_free_i64(fp64
);
8203 gen_store_fpr32(fp32
, fd
);
8204 tcg_temp_free_i32(fp32
);
8209 check_cp1_64bitmode(ctx
);
8211 TCGv_i64 fp0
= tcg_temp_new_i64();
8213 gen_load_fpr64(ctx
, fp0
, fs
);
8214 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8215 gen_store_fpr64(ctx
, fp0
, fd
);
8216 tcg_temp_free_i64(fp0
);
8222 TCGv_i32 fp0
= tcg_temp_new_i32();
8224 gen_load_fpr32(fp0
, fs
);
8225 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8226 gen_store_fpr32(fp0
, fd
);
8227 tcg_temp_free_i32(fp0
);
8232 check_cp1_registers(ctx
, fd
);
8234 TCGv_i32 fp32
= tcg_temp_new_i32();
8235 TCGv_i64 fp64
= tcg_temp_new_i64();
8237 gen_load_fpr32(fp32
, fs
);
8238 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8239 tcg_temp_free_i32(fp32
);
8240 gen_store_fpr64(ctx
, fp64
, fd
);
8241 tcg_temp_free_i64(fp64
);
8246 check_cp1_64bitmode(ctx
);
8248 TCGv_i32 fp32
= tcg_temp_new_i32();
8249 TCGv_i64 fp64
= tcg_temp_new_i64();
8251 gen_load_fpr64(ctx
, fp64
, fs
);
8252 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8253 tcg_temp_free_i64(fp64
);
8254 gen_store_fpr32(fp32
, fd
);
8255 tcg_temp_free_i32(fp32
);
8260 check_cp1_64bitmode(ctx
);
8262 TCGv_i64 fp0
= tcg_temp_new_i64();
8264 gen_load_fpr64(ctx
, fp0
, fs
);
8265 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8266 gen_store_fpr64(ctx
, fp0
, fd
);
8267 tcg_temp_free_i64(fp0
);
8272 check_cp1_64bitmode(ctx
);
8274 TCGv_i64 fp0
= tcg_temp_new_i64();
8276 gen_load_fpr64(ctx
, fp0
, fs
);
8277 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8278 gen_store_fpr64(ctx
, fp0
, fd
);
8279 tcg_temp_free_i64(fp0
);
8284 check_cp1_64bitmode(ctx
);
8286 TCGv_i64 fp0
= tcg_temp_new_i64();
8287 TCGv_i64 fp1
= tcg_temp_new_i64();
8289 gen_load_fpr64(ctx
, fp0
, fs
);
8290 gen_load_fpr64(ctx
, fp1
, ft
);
8291 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8292 tcg_temp_free_i64(fp1
);
8293 gen_store_fpr64(ctx
, fp0
, fd
);
8294 tcg_temp_free_i64(fp0
);
8299 check_cp1_64bitmode(ctx
);
8301 TCGv_i64 fp0
= tcg_temp_new_i64();
8302 TCGv_i64 fp1
= tcg_temp_new_i64();
8304 gen_load_fpr64(ctx
, fp0
, fs
);
8305 gen_load_fpr64(ctx
, fp1
, ft
);
8306 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8307 tcg_temp_free_i64(fp1
);
8308 gen_store_fpr64(ctx
, fp0
, fd
);
8309 tcg_temp_free_i64(fp0
);
8314 check_cp1_64bitmode(ctx
);
8316 TCGv_i64 fp0
= tcg_temp_new_i64();
8317 TCGv_i64 fp1
= tcg_temp_new_i64();
8319 gen_load_fpr64(ctx
, fp0
, fs
);
8320 gen_load_fpr64(ctx
, fp1
, ft
);
8321 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8322 tcg_temp_free_i64(fp1
);
8323 gen_store_fpr64(ctx
, fp0
, fd
);
8324 tcg_temp_free_i64(fp0
);
8329 check_cp1_64bitmode(ctx
);
8331 TCGv_i64 fp0
= tcg_temp_new_i64();
8333 gen_load_fpr64(ctx
, fp0
, fs
);
8334 gen_helper_float_abs_ps(fp0
, fp0
);
8335 gen_store_fpr64(ctx
, fp0
, fd
);
8336 tcg_temp_free_i64(fp0
);
8341 check_cp1_64bitmode(ctx
);
8343 TCGv_i64 fp0
= tcg_temp_new_i64();
8345 gen_load_fpr64(ctx
, fp0
, fs
);
8346 gen_store_fpr64(ctx
, fp0
, fd
);
8347 tcg_temp_free_i64(fp0
);
8352 check_cp1_64bitmode(ctx
);
8354 TCGv_i64 fp0
= tcg_temp_new_i64();
8356 gen_load_fpr64(ctx
, fp0
, fs
);
8357 gen_helper_float_chs_ps(fp0
, fp0
);
8358 gen_store_fpr64(ctx
, fp0
, fd
);
8359 tcg_temp_free_i64(fp0
);
8364 check_cp1_64bitmode(ctx
);
8365 gen_movcf_ps(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8369 check_cp1_64bitmode(ctx
);
8371 int l1
= gen_new_label();
8375 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8376 fp0
= tcg_temp_new_i64();
8377 gen_load_fpr64(ctx
, fp0
, fs
);
8378 gen_store_fpr64(ctx
, fp0
, fd
);
8379 tcg_temp_free_i64(fp0
);
8385 check_cp1_64bitmode(ctx
);
8387 int l1
= gen_new_label();
8391 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8392 fp0
= tcg_temp_new_i64();
8393 gen_load_fpr64(ctx
, fp0
, fs
);
8394 gen_store_fpr64(ctx
, fp0
, fd
);
8395 tcg_temp_free_i64(fp0
);
8402 check_cp1_64bitmode(ctx
);
8404 TCGv_i64 fp0
= tcg_temp_new_i64();
8405 TCGv_i64 fp1
= tcg_temp_new_i64();
8407 gen_load_fpr64(ctx
, fp0
, ft
);
8408 gen_load_fpr64(ctx
, fp1
, fs
);
8409 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8410 tcg_temp_free_i64(fp1
);
8411 gen_store_fpr64(ctx
, fp0
, fd
);
8412 tcg_temp_free_i64(fp0
);
8417 check_cp1_64bitmode(ctx
);
8419 TCGv_i64 fp0
= tcg_temp_new_i64();
8420 TCGv_i64 fp1
= tcg_temp_new_i64();
8422 gen_load_fpr64(ctx
, fp0
, ft
);
8423 gen_load_fpr64(ctx
, fp1
, fs
);
8424 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8425 tcg_temp_free_i64(fp1
);
8426 gen_store_fpr64(ctx
, fp0
, fd
);
8427 tcg_temp_free_i64(fp0
);
8432 check_cp1_64bitmode(ctx
);
8434 TCGv_i64 fp0
= tcg_temp_new_i64();
8435 TCGv_i64 fp1
= tcg_temp_new_i64();
8437 gen_load_fpr64(ctx
, fp0
, fs
);
8438 gen_load_fpr64(ctx
, fp1
, ft
);
8439 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8440 tcg_temp_free_i64(fp1
);
8441 gen_store_fpr64(ctx
, fp0
, fd
);
8442 tcg_temp_free_i64(fp0
);
8447 check_cp1_64bitmode(ctx
);
8449 TCGv_i64 fp0
= tcg_temp_new_i64();
8451 gen_load_fpr64(ctx
, fp0
, fs
);
8452 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
8453 gen_store_fpr64(ctx
, fp0
, fd
);
8454 tcg_temp_free_i64(fp0
);
8459 check_cp1_64bitmode(ctx
);
8461 TCGv_i64 fp0
= tcg_temp_new_i64();
8463 gen_load_fpr64(ctx
, fp0
, fs
);
8464 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8465 gen_store_fpr64(ctx
, fp0
, fd
);
8466 tcg_temp_free_i64(fp0
);
8471 check_cp1_64bitmode(ctx
);
8473 TCGv_i64 fp0
= tcg_temp_new_i64();
8474 TCGv_i64 fp1
= tcg_temp_new_i64();
8476 gen_load_fpr64(ctx
, fp0
, fs
);
8477 gen_load_fpr64(ctx
, fp1
, ft
);
8478 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8479 tcg_temp_free_i64(fp1
);
8480 gen_store_fpr64(ctx
, fp0
, fd
);
8481 tcg_temp_free_i64(fp0
);
8486 check_cp1_64bitmode(ctx
);
8488 TCGv_i32 fp0
= tcg_temp_new_i32();
8490 gen_load_fpr32h(fp0
, fs
);
8491 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8492 gen_store_fpr32(fp0
, fd
);
8493 tcg_temp_free_i32(fp0
);
8498 check_cp1_64bitmode(ctx
);
8500 TCGv_i64 fp0
= tcg_temp_new_i64();
8502 gen_load_fpr64(ctx
, fp0
, fs
);
8503 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8504 gen_store_fpr64(ctx
, fp0
, fd
);
8505 tcg_temp_free_i64(fp0
);
8510 check_cp1_64bitmode(ctx
);
8512 TCGv_i32 fp0
= tcg_temp_new_i32();
8514 gen_load_fpr32(fp0
, fs
);
8515 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8516 gen_store_fpr32(fp0
, fd
);
8517 tcg_temp_free_i32(fp0
);
8522 check_cp1_64bitmode(ctx
);
8524 TCGv_i32 fp0
= tcg_temp_new_i32();
8525 TCGv_i32 fp1
= tcg_temp_new_i32();
8527 gen_load_fpr32(fp0
, fs
);
8528 gen_load_fpr32(fp1
, ft
);
8529 gen_store_fpr32h(fp0
, fd
);
8530 gen_store_fpr32(fp1
, fd
);
8531 tcg_temp_free_i32(fp0
);
8532 tcg_temp_free_i32(fp1
);
8537 check_cp1_64bitmode(ctx
);
8539 TCGv_i32 fp0
= tcg_temp_new_i32();
8540 TCGv_i32 fp1
= tcg_temp_new_i32();
8542 gen_load_fpr32(fp0
, fs
);
8543 gen_load_fpr32h(fp1
, ft
);
8544 gen_store_fpr32(fp1
, fd
);
8545 gen_store_fpr32h(fp0
, fd
);
8546 tcg_temp_free_i32(fp0
);
8547 tcg_temp_free_i32(fp1
);
8552 check_cp1_64bitmode(ctx
);
8554 TCGv_i32 fp0
= tcg_temp_new_i32();
8555 TCGv_i32 fp1
= tcg_temp_new_i32();
8557 gen_load_fpr32h(fp0
, fs
);
8558 gen_load_fpr32(fp1
, ft
);
8559 gen_store_fpr32(fp1
, fd
);
8560 gen_store_fpr32h(fp0
, fd
);
8561 tcg_temp_free_i32(fp0
);
8562 tcg_temp_free_i32(fp1
);
8567 check_cp1_64bitmode(ctx
);
8569 TCGv_i32 fp0
= tcg_temp_new_i32();
8570 TCGv_i32 fp1
= tcg_temp_new_i32();
8572 gen_load_fpr32h(fp0
, fs
);
8573 gen_load_fpr32h(fp1
, ft
);
8574 gen_store_fpr32(fp1
, fd
);
8575 gen_store_fpr32h(fp0
, fd
);
8576 tcg_temp_free_i32(fp0
);
8577 tcg_temp_free_i32(fp1
);
8584 case OPC_CMP_UEQ_PS
:
8585 case OPC_CMP_OLT_PS
:
8586 case OPC_CMP_ULT_PS
:
8587 case OPC_CMP_OLE_PS
:
8588 case OPC_CMP_ULE_PS
:
8590 case OPC_CMP_NGLE_PS
:
8591 case OPC_CMP_SEQ_PS
:
8592 case OPC_CMP_NGL_PS
:
8594 case OPC_CMP_NGE_PS
:
8596 case OPC_CMP_NGT_PS
:
8597 if (ctx
->opcode
& (1 << 6)) {
8598 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8599 opn
= condnames_abs
[func
-48];
8601 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8602 opn
= condnames
[func
-48];
8607 generate_exception (ctx
, EXCP_RI
);
8610 (void)opn
; /* avoid a compiler warning */
8613 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8616 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8619 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8624 /* Coprocessor 3 (FPU) */
8625 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8626 int fd
, int fs
, int base
, int index
)
8628 const char *opn
= "extended float load/store";
8630 TCGv t0
= tcg_temp_new();
8633 gen_load_gpr(t0
, index
);
8634 } else if (index
== 0) {
8635 gen_load_gpr(t0
, base
);
8637 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8639 /* Don't do NOP if destination is zero: we must perform the actual
8645 TCGv_i32 fp0
= tcg_temp_new_i32();
8647 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
8648 tcg_gen_trunc_tl_i32(fp0
, t0
);
8649 gen_store_fpr32(fp0
, fd
);
8650 tcg_temp_free_i32(fp0
);
8656 check_cp1_registers(ctx
, fd
);
8658 TCGv_i64 fp0
= tcg_temp_new_i64();
8659 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8660 gen_store_fpr64(ctx
, fp0
, fd
);
8661 tcg_temp_free_i64(fp0
);
8666 check_cp1_64bitmode(ctx
);
8667 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8669 TCGv_i64 fp0
= tcg_temp_new_i64();
8671 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8672 gen_store_fpr64(ctx
, fp0
, fd
);
8673 tcg_temp_free_i64(fp0
);
8680 TCGv_i32 fp0
= tcg_temp_new_i32();
8681 gen_load_fpr32(fp0
, fs
);
8682 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
8683 tcg_temp_free_i32(fp0
);
8690 check_cp1_registers(ctx
, fs
);
8692 TCGv_i64 fp0
= tcg_temp_new_i64();
8693 gen_load_fpr64(ctx
, fp0
, fs
);
8694 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8695 tcg_temp_free_i64(fp0
);
8701 check_cp1_64bitmode(ctx
);
8702 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8704 TCGv_i64 fp0
= tcg_temp_new_i64();
8705 gen_load_fpr64(ctx
, fp0
, fs
);
8706 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8707 tcg_temp_free_i64(fp0
);
8714 (void)opn
; (void)store
; /* avoid compiler warnings */
8715 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8716 regnames
[index
], regnames
[base
]);
8719 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8720 int fd
, int fr
, int fs
, int ft
)
8722 const char *opn
= "flt3_arith";
8726 check_cp1_64bitmode(ctx
);
8728 TCGv t0
= tcg_temp_local_new();
8729 TCGv_i32 fp
= tcg_temp_new_i32();
8730 TCGv_i32 fph
= tcg_temp_new_i32();
8731 int l1
= gen_new_label();
8732 int l2
= gen_new_label();
8734 gen_load_gpr(t0
, fr
);
8735 tcg_gen_andi_tl(t0
, t0
, 0x7);
8737 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8738 gen_load_fpr32(fp
, fs
);
8739 gen_load_fpr32h(fph
, fs
);
8740 gen_store_fpr32(fp
, fd
);
8741 gen_store_fpr32h(fph
, fd
);
8744 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8746 #ifdef TARGET_WORDS_BIGENDIAN
8747 gen_load_fpr32(fp
, fs
);
8748 gen_load_fpr32h(fph
, ft
);
8749 gen_store_fpr32h(fp
, fd
);
8750 gen_store_fpr32(fph
, fd
);
8752 gen_load_fpr32h(fph
, fs
);
8753 gen_load_fpr32(fp
, ft
);
8754 gen_store_fpr32(fph
, fd
);
8755 gen_store_fpr32h(fp
, fd
);
8758 tcg_temp_free_i32(fp
);
8759 tcg_temp_free_i32(fph
);
8766 TCGv_i32 fp0
= tcg_temp_new_i32();
8767 TCGv_i32 fp1
= tcg_temp_new_i32();
8768 TCGv_i32 fp2
= tcg_temp_new_i32();
8770 gen_load_fpr32(fp0
, fs
);
8771 gen_load_fpr32(fp1
, ft
);
8772 gen_load_fpr32(fp2
, fr
);
8773 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8774 tcg_temp_free_i32(fp0
);
8775 tcg_temp_free_i32(fp1
);
8776 gen_store_fpr32(fp2
, fd
);
8777 tcg_temp_free_i32(fp2
);
8783 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8785 TCGv_i64 fp0
= tcg_temp_new_i64();
8786 TCGv_i64 fp1
= tcg_temp_new_i64();
8787 TCGv_i64 fp2
= tcg_temp_new_i64();
8789 gen_load_fpr64(ctx
, fp0
, fs
);
8790 gen_load_fpr64(ctx
, fp1
, ft
);
8791 gen_load_fpr64(ctx
, fp2
, fr
);
8792 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8793 tcg_temp_free_i64(fp0
);
8794 tcg_temp_free_i64(fp1
);
8795 gen_store_fpr64(ctx
, fp2
, fd
);
8796 tcg_temp_free_i64(fp2
);
8801 check_cp1_64bitmode(ctx
);
8803 TCGv_i64 fp0
= tcg_temp_new_i64();
8804 TCGv_i64 fp1
= tcg_temp_new_i64();
8805 TCGv_i64 fp2
= tcg_temp_new_i64();
8807 gen_load_fpr64(ctx
, fp0
, fs
);
8808 gen_load_fpr64(ctx
, fp1
, ft
);
8809 gen_load_fpr64(ctx
, fp2
, fr
);
8810 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8811 tcg_temp_free_i64(fp0
);
8812 tcg_temp_free_i64(fp1
);
8813 gen_store_fpr64(ctx
, fp2
, fd
);
8814 tcg_temp_free_i64(fp2
);
8821 TCGv_i32 fp0
= tcg_temp_new_i32();
8822 TCGv_i32 fp1
= tcg_temp_new_i32();
8823 TCGv_i32 fp2
= tcg_temp_new_i32();
8825 gen_load_fpr32(fp0
, fs
);
8826 gen_load_fpr32(fp1
, ft
);
8827 gen_load_fpr32(fp2
, fr
);
8828 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8829 tcg_temp_free_i32(fp0
);
8830 tcg_temp_free_i32(fp1
);
8831 gen_store_fpr32(fp2
, fd
);
8832 tcg_temp_free_i32(fp2
);
8838 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8840 TCGv_i64 fp0
= tcg_temp_new_i64();
8841 TCGv_i64 fp1
= tcg_temp_new_i64();
8842 TCGv_i64 fp2
= tcg_temp_new_i64();
8844 gen_load_fpr64(ctx
, fp0
, fs
);
8845 gen_load_fpr64(ctx
, fp1
, ft
);
8846 gen_load_fpr64(ctx
, fp2
, fr
);
8847 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8848 tcg_temp_free_i64(fp0
);
8849 tcg_temp_free_i64(fp1
);
8850 gen_store_fpr64(ctx
, fp2
, fd
);
8851 tcg_temp_free_i64(fp2
);
8856 check_cp1_64bitmode(ctx
);
8858 TCGv_i64 fp0
= tcg_temp_new_i64();
8859 TCGv_i64 fp1
= tcg_temp_new_i64();
8860 TCGv_i64 fp2
= tcg_temp_new_i64();
8862 gen_load_fpr64(ctx
, fp0
, fs
);
8863 gen_load_fpr64(ctx
, fp1
, ft
);
8864 gen_load_fpr64(ctx
, fp2
, fr
);
8865 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8866 tcg_temp_free_i64(fp0
);
8867 tcg_temp_free_i64(fp1
);
8868 gen_store_fpr64(ctx
, fp2
, fd
);
8869 tcg_temp_free_i64(fp2
);
8876 TCGv_i32 fp0
= tcg_temp_new_i32();
8877 TCGv_i32 fp1
= tcg_temp_new_i32();
8878 TCGv_i32 fp2
= tcg_temp_new_i32();
8880 gen_load_fpr32(fp0
, fs
);
8881 gen_load_fpr32(fp1
, ft
);
8882 gen_load_fpr32(fp2
, fr
);
8883 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8884 tcg_temp_free_i32(fp0
);
8885 tcg_temp_free_i32(fp1
);
8886 gen_store_fpr32(fp2
, fd
);
8887 tcg_temp_free_i32(fp2
);
8893 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8895 TCGv_i64 fp0
= tcg_temp_new_i64();
8896 TCGv_i64 fp1
= tcg_temp_new_i64();
8897 TCGv_i64 fp2
= tcg_temp_new_i64();
8899 gen_load_fpr64(ctx
, fp0
, fs
);
8900 gen_load_fpr64(ctx
, fp1
, ft
);
8901 gen_load_fpr64(ctx
, fp2
, fr
);
8902 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8903 tcg_temp_free_i64(fp0
);
8904 tcg_temp_free_i64(fp1
);
8905 gen_store_fpr64(ctx
, fp2
, fd
);
8906 tcg_temp_free_i64(fp2
);
8911 check_cp1_64bitmode(ctx
);
8913 TCGv_i64 fp0
= tcg_temp_new_i64();
8914 TCGv_i64 fp1
= tcg_temp_new_i64();
8915 TCGv_i64 fp2
= tcg_temp_new_i64();
8917 gen_load_fpr64(ctx
, fp0
, fs
);
8918 gen_load_fpr64(ctx
, fp1
, ft
);
8919 gen_load_fpr64(ctx
, fp2
, fr
);
8920 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8921 tcg_temp_free_i64(fp0
);
8922 tcg_temp_free_i64(fp1
);
8923 gen_store_fpr64(ctx
, fp2
, fd
);
8924 tcg_temp_free_i64(fp2
);
8931 TCGv_i32 fp0
= tcg_temp_new_i32();
8932 TCGv_i32 fp1
= tcg_temp_new_i32();
8933 TCGv_i32 fp2
= tcg_temp_new_i32();
8935 gen_load_fpr32(fp0
, fs
);
8936 gen_load_fpr32(fp1
, ft
);
8937 gen_load_fpr32(fp2
, fr
);
8938 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8939 tcg_temp_free_i32(fp0
);
8940 tcg_temp_free_i32(fp1
);
8941 gen_store_fpr32(fp2
, fd
);
8942 tcg_temp_free_i32(fp2
);
8948 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8950 TCGv_i64 fp0
= tcg_temp_new_i64();
8951 TCGv_i64 fp1
= tcg_temp_new_i64();
8952 TCGv_i64 fp2
= tcg_temp_new_i64();
8954 gen_load_fpr64(ctx
, fp0
, fs
);
8955 gen_load_fpr64(ctx
, fp1
, ft
);
8956 gen_load_fpr64(ctx
, fp2
, fr
);
8957 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8958 tcg_temp_free_i64(fp0
);
8959 tcg_temp_free_i64(fp1
);
8960 gen_store_fpr64(ctx
, fp2
, fd
);
8961 tcg_temp_free_i64(fp2
);
8966 check_cp1_64bitmode(ctx
);
8968 TCGv_i64 fp0
= tcg_temp_new_i64();
8969 TCGv_i64 fp1
= tcg_temp_new_i64();
8970 TCGv_i64 fp2
= tcg_temp_new_i64();
8972 gen_load_fpr64(ctx
, fp0
, fs
);
8973 gen_load_fpr64(ctx
, fp1
, ft
);
8974 gen_load_fpr64(ctx
, fp2
, fr
);
8975 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8976 tcg_temp_free_i64(fp0
);
8977 tcg_temp_free_i64(fp1
);
8978 gen_store_fpr64(ctx
, fp2
, fd
);
8979 tcg_temp_free_i64(fp2
);
8985 generate_exception (ctx
, EXCP_RI
);
8988 (void)opn
; /* avoid a compiler warning */
8989 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
8990 fregnames
[fs
], fregnames
[ft
]);
8993 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
8997 #if !defined(CONFIG_USER_ONLY)
8998 /* The Linux kernel will emulate rdhwr if it's not supported natively.
8999 Therefore only check the ISA in system mode. */
9000 check_insn(ctx
, ISA_MIPS32R2
);
9002 t0
= tcg_temp_new();
9006 save_cpu_state(ctx
, 1);
9007 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9008 gen_store_gpr(t0
, rt
);
9011 save_cpu_state(ctx
, 1);
9012 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9013 gen_store_gpr(t0
, rt
);
9016 save_cpu_state(ctx
, 1);
9017 gen_helper_rdhwr_cc(t0
, cpu_env
);
9018 gen_store_gpr(t0
, rt
);
9021 save_cpu_state(ctx
, 1);
9022 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9023 gen_store_gpr(t0
, rt
);
9026 #if defined(CONFIG_USER_ONLY)
9027 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUMIPSState
, tls_value
));
9028 gen_store_gpr(t0
, rt
);
9031 /* XXX: Some CPUs implement this in hardware.
9032 Not supported yet. */
9034 default: /* Invalid */
9035 MIPS_INVAL("rdhwr");
9036 generate_exception(ctx
, EXCP_RI
);
9042 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9044 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9045 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9046 /* Branches completion */
9047 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9048 ctx
->bstate
= BS_BRANCH
;
9049 save_cpu_state(ctx
, 0);
9050 /* FIXME: Need to clear can_do_io. */
9051 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9053 /* unconditional branch */
9054 MIPS_DEBUG("unconditional branch");
9055 if (proc_hflags
& MIPS_HFLAG_BX
) {
9056 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9058 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9061 /* blikely taken case */
9062 MIPS_DEBUG("blikely branch taken");
9063 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9066 /* Conditional branch */
9067 MIPS_DEBUG("conditional branch");
9069 int l1
= gen_new_label();
9071 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9072 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9074 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9078 /* unconditional branch to register */
9079 MIPS_DEBUG("branch to register");
9080 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9081 TCGv t0
= tcg_temp_new();
9082 TCGv_i32 t1
= tcg_temp_new_i32();
9084 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9085 tcg_gen_trunc_tl_i32(t1
, t0
);
9087 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9088 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9089 tcg_gen_or_i32(hflags
, hflags
, t1
);
9090 tcg_temp_free_i32(t1
);
9092 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9094 tcg_gen_mov_tl(cpu_PC
, btarget
);
9096 if (ctx
->singlestep_enabled
) {
9097 save_cpu_state(ctx
, 0);
9098 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9103 MIPS_DEBUG("unknown branch");
9109 /* ISA extensions (ASEs) */
9110 /* MIPS16 extension to MIPS32 */
9112 /* MIPS16 major opcodes */
9114 M16_OPC_ADDIUSP
= 0x00,
9115 M16_OPC_ADDIUPC
= 0x01,
9118 M16_OPC_BEQZ
= 0x04,
9119 M16_OPC_BNEQZ
= 0x05,
9120 M16_OPC_SHIFT
= 0x06,
9122 M16_OPC_RRIA
= 0x08,
9123 M16_OPC_ADDIU8
= 0x09,
9124 M16_OPC_SLTI
= 0x0a,
9125 M16_OPC_SLTIU
= 0x0b,
9128 M16_OPC_CMPI
= 0x0e,
9132 M16_OPC_LWSP
= 0x12,
9136 M16_OPC_LWPC
= 0x16,
9140 M16_OPC_SWSP
= 0x1a,
9144 M16_OPC_EXTEND
= 0x1e,
9148 /* I8 funct field */
9167 /* RR funct field */
9201 /* I64 funct field */
9213 /* RR ry field for CNVT */
9215 RR_RY_CNVT_ZEB
= 0x0,
9216 RR_RY_CNVT_ZEH
= 0x1,
9217 RR_RY_CNVT_ZEW
= 0x2,
9218 RR_RY_CNVT_SEB
= 0x4,
9219 RR_RY_CNVT_SEH
= 0x5,
9220 RR_RY_CNVT_SEW
= 0x6,
9223 static int xlat (int r
)
9225 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9230 static void gen_mips16_save (DisasContext
*ctx
,
9231 int xsregs
, int aregs
,
9232 int do_ra
, int do_s0
, int do_s1
,
9235 TCGv t0
= tcg_temp_new();
9236 TCGv t1
= tcg_temp_new();
9266 generate_exception(ctx
, EXCP_RI
);
9272 gen_base_offset_addr(ctx
, t0
, 29, 12);
9273 gen_load_gpr(t1
, 7);
9274 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9277 gen_base_offset_addr(ctx
, t0
, 29, 8);
9278 gen_load_gpr(t1
, 6);
9279 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9282 gen_base_offset_addr(ctx
, t0
, 29, 4);
9283 gen_load_gpr(t1
, 5);
9284 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9287 gen_base_offset_addr(ctx
, t0
, 29, 0);
9288 gen_load_gpr(t1
, 4);
9289 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9292 gen_load_gpr(t0
, 29);
9294 #define DECR_AND_STORE(reg) do { \
9295 tcg_gen_subi_tl(t0, t0, 4); \
9296 gen_load_gpr(t1, reg); \
9297 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9361 generate_exception(ctx
, EXCP_RI
);
9377 #undef DECR_AND_STORE
9379 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9384 static void gen_mips16_restore (DisasContext
*ctx
,
9385 int xsregs
, int aregs
,
9386 int do_ra
, int do_s0
, int do_s1
,
9390 TCGv t0
= tcg_temp_new();
9391 TCGv t1
= tcg_temp_new();
9393 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9395 #define DECR_AND_LOAD(reg) do { \
9396 tcg_gen_subi_tl(t0, t0, 4); \
9397 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9398 gen_store_gpr(t1, reg); \
9462 generate_exception(ctx
, EXCP_RI
);
9478 #undef DECR_AND_LOAD
9480 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9485 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9486 int is_64_bit
, int extended
)
9490 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9491 generate_exception(ctx
, EXCP_RI
);
9495 t0
= tcg_temp_new();
9497 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9498 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9500 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9506 #if defined(TARGET_MIPS64)
9507 static void decode_i64_mips16 (DisasContext
*ctx
,
9508 int ry
, int funct
, int16_t offset
,
9514 offset
= extended
? offset
: offset
<< 3;
9515 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9519 offset
= extended
? offset
: offset
<< 3;
9520 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9524 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9525 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9529 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9530 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9533 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9534 generate_exception(ctx
, EXCP_RI
);
9536 offset
= extended
? offset
: offset
<< 3;
9537 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9542 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9543 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9547 offset
= extended
? offset
: offset
<< 2;
9548 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9552 offset
= extended
? offset
: offset
<< 2;
9553 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9559 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9561 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9562 int op
, rx
, ry
, funct
, sa
;
9563 int16_t imm
, offset
;
9565 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9566 op
= (ctx
->opcode
>> 11) & 0x1f;
9567 sa
= (ctx
->opcode
>> 22) & 0x1f;
9568 funct
= (ctx
->opcode
>> 8) & 0x7;
9569 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9570 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9571 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9572 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9573 | (ctx
->opcode
& 0x1f));
9575 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9578 case M16_OPC_ADDIUSP
:
9579 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9581 case M16_OPC_ADDIUPC
:
9582 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9585 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9586 /* No delay slot, so just process as a normal instruction */
9589 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9590 /* No delay slot, so just process as a normal instruction */
9593 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9594 /* No delay slot, so just process as a normal instruction */
9597 switch (ctx
->opcode
& 0x3) {
9599 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9602 #if defined(TARGET_MIPS64)
9604 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9606 generate_exception(ctx
, EXCP_RI
);
9610 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9613 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9617 #if defined(TARGET_MIPS64)
9620 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9624 imm
= ctx
->opcode
& 0xf;
9625 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9626 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9627 imm
= (int16_t) (imm
<< 1) >> 1;
9628 if ((ctx
->opcode
>> 4) & 0x1) {
9629 #if defined(TARGET_MIPS64)
9631 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9633 generate_exception(ctx
, EXCP_RI
);
9636 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9639 case M16_OPC_ADDIU8
:
9640 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9643 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9646 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9651 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9654 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9657 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9660 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9664 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9665 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9666 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9667 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9668 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9669 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9670 | (ctx
->opcode
& 0xf)) << 3;
9672 if (ctx
->opcode
& (1 << 7)) {
9673 gen_mips16_save(ctx
, xsregs
, aregs
,
9674 do_ra
, do_s0
, do_s1
,
9677 gen_mips16_restore(ctx
, xsregs
, aregs
,
9678 do_ra
, do_s0
, do_s1
,
9684 generate_exception(ctx
, EXCP_RI
);
9689 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9692 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9694 #if defined(TARGET_MIPS64)
9696 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9700 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9703 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9706 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9709 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9712 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9715 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9718 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9720 #if defined(TARGET_MIPS64)
9722 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9726 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9729 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9732 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9735 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9737 #if defined(TARGET_MIPS64)
9739 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9743 generate_exception(ctx
, EXCP_RI
);
9750 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9754 int op
, cnvt_op
, op1
, offset
;
9758 op
= (ctx
->opcode
>> 11) & 0x1f;
9759 sa
= (ctx
->opcode
>> 2) & 0x7;
9760 sa
= sa
== 0 ? 8 : sa
;
9761 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9762 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9763 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9764 op1
= offset
= ctx
->opcode
& 0x1f;
9769 case M16_OPC_ADDIUSP
:
9771 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9773 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9776 case M16_OPC_ADDIUPC
:
9777 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9780 offset
= (ctx
->opcode
& 0x7ff) << 1;
9781 offset
= (int16_t)(offset
<< 4) >> 4;
9782 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9783 /* No delay slot, so just process as a normal instruction */
9786 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9787 offset
= (((ctx
->opcode
& 0x1f) << 21)
9788 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9790 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9791 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9795 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9796 /* No delay slot, so just process as a normal instruction */
9799 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9800 /* No delay slot, so just process as a normal instruction */
9803 switch (ctx
->opcode
& 0x3) {
9805 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9808 #if defined(TARGET_MIPS64)
9810 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9812 generate_exception(ctx
, EXCP_RI
);
9816 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9819 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9823 #if defined(TARGET_MIPS64)
9826 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9831 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9833 if ((ctx
->opcode
>> 4) & 1) {
9834 #if defined(TARGET_MIPS64)
9836 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9838 generate_exception(ctx
, EXCP_RI
);
9841 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9845 case M16_OPC_ADDIU8
:
9847 int16_t imm
= (int8_t) ctx
->opcode
;
9849 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9854 int16_t imm
= (uint8_t) ctx
->opcode
;
9855 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9860 int16_t imm
= (uint8_t) ctx
->opcode
;
9861 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9868 funct
= (ctx
->opcode
>> 8) & 0x7;
9871 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9872 ((int8_t)ctx
->opcode
) << 1);
9875 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9876 ((int8_t)ctx
->opcode
) << 1);
9879 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9882 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9883 ((int8_t)ctx
->opcode
) << 3);
9887 int do_ra
= ctx
->opcode
& (1 << 6);
9888 int do_s0
= ctx
->opcode
& (1 << 5);
9889 int do_s1
= ctx
->opcode
& (1 << 4);
9890 int framesize
= ctx
->opcode
& 0xf;
9892 if (framesize
== 0) {
9895 framesize
= framesize
<< 3;
9898 if (ctx
->opcode
& (1 << 7)) {
9899 gen_mips16_save(ctx
, 0, 0,
9900 do_ra
, do_s0
, do_s1
, framesize
);
9902 gen_mips16_restore(ctx
, 0, 0,
9903 do_ra
, do_s0
, do_s1
, framesize
);
9909 int rz
= xlat(ctx
->opcode
& 0x7);
9911 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9912 ((ctx
->opcode
>> 5) & 0x7);
9913 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
9917 reg32
= ctx
->opcode
& 0x1f;
9918 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
9921 generate_exception(ctx
, EXCP_RI
);
9928 int16_t imm
= (uint8_t) ctx
->opcode
;
9930 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
9935 int16_t imm
= (uint8_t) ctx
->opcode
;
9936 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
9939 #if defined(TARGET_MIPS64)
9942 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
9946 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9949 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
9952 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
9955 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
9958 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9961 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
9964 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
9966 #if defined (TARGET_MIPS64)
9969 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
9973 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9976 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
9979 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
9982 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
9986 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
9989 switch (ctx
->opcode
& 0x3) {
9991 mips32_op
= OPC_ADDU
;
9994 mips32_op
= OPC_SUBU
;
9996 #if defined(TARGET_MIPS64)
9998 mips32_op
= OPC_DADDU
;
10002 mips32_op
= OPC_DSUBU
;
10003 check_mips_64(ctx
);
10007 generate_exception(ctx
, EXCP_RI
);
10011 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10020 int nd
= (ctx
->opcode
>> 7) & 0x1;
10021 int link
= (ctx
->opcode
>> 6) & 0x1;
10022 int ra
= (ctx
->opcode
>> 5) & 0x1;
10025 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10030 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10034 /* XXX: not clear which exception should be raised
10035 * when in debug mode...
10037 check_insn(ctx
, ISA_MIPS32
);
10038 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10039 generate_exception(ctx
, EXCP_DBp
);
10041 generate_exception(ctx
, EXCP_DBp
);
10045 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10048 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10051 generate_exception(ctx
, EXCP_BREAK
);
10054 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10057 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10060 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10062 #if defined (TARGET_MIPS64)
10064 check_mips_64(ctx
);
10065 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10069 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10072 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10075 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10078 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10081 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10084 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10087 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
10091 case RR_RY_CNVT_ZEB
:
10092 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10094 case RR_RY_CNVT_ZEH
:
10095 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10097 case RR_RY_CNVT_SEB
:
10098 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10100 case RR_RY_CNVT_SEH
:
10101 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10103 #if defined (TARGET_MIPS64)
10104 case RR_RY_CNVT_ZEW
:
10105 check_mips_64(ctx
);
10106 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10108 case RR_RY_CNVT_SEW
:
10109 check_mips_64(ctx
);
10110 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10114 generate_exception(ctx
, EXCP_RI
);
10119 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
10121 #if defined (TARGET_MIPS64)
10123 check_mips_64(ctx
);
10124 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10127 check_mips_64(ctx
);
10128 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10131 check_mips_64(ctx
);
10132 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10135 check_mips_64(ctx
);
10136 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10140 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
10143 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
10146 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
10149 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
10151 #if defined (TARGET_MIPS64)
10153 check_mips_64(ctx
);
10154 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
10157 check_mips_64(ctx
);
10158 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
10161 check_mips_64(ctx
);
10162 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
10165 check_mips_64(ctx
);
10166 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
10170 generate_exception(ctx
, EXCP_RI
);
10174 case M16_OPC_EXTEND
:
10175 decode_extended_mips16_opc(env
, ctx
);
10178 #if defined(TARGET_MIPS64)
10180 funct
= (ctx
->opcode
>> 8) & 0x7;
10181 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10185 generate_exception(ctx
, EXCP_RI
);
10192 /* microMIPS extension to MIPS32/MIPS64 */
10195 * microMIPS32/microMIPS64 major opcodes
10197 * 1. MIPS Architecture for Programmers Volume II-B:
10198 * The microMIPS32 Instruction Set (Revision 3.05)
10200 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10202 * 2. MIPS Architecture For Programmers Volume II-A:
10203 * The MIPS64 Instruction Set (Revision 3.51)
10231 POOL32S
= 0x16, /* MIPS64 */
10232 DADDIU32
= 0x17, /* MIPS64 */
10234 /* 0x1f is reserved */
10243 /* 0x20 is reserved */
10253 /* 0x28 and 0x29 are reserved */
10263 /* 0x30 and 0x31 are reserved */
10270 SD32
= 0x36, /* MIPS64 */
10271 LD32
= 0x37, /* MIPS64 */
10273 /* 0x38 and 0x39 are reserved */
10284 /* POOL32A encoding of minor opcode field */
10287 /* These opcodes are distinguished only by bits 9..6; those bits are
10288 * what are recorded below. */
10314 /* The following can be distinguished by their lower 6 bits. */
10320 /* POOL32AXF encoding of minor opcode field extension */
10323 * 1. MIPS Architecture for Programmers Volume II-B:
10324 * The microMIPS32 Instruction Set (Revision 3.05)
10326 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10328 * 2. MIPS Architecture for Programmers VolumeIV-e:
10329 * The MIPS DSP Application-Specific Extension
10330 * to the microMIPS32 Architecture (Revision 2.34)
10332 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10347 /* begin of microMIPS32 DSP */
10349 /* bits 13..12 for 0x01 */
10355 /* bits 13..12 for 0x2a */
10361 /* bits 13..12 for 0x32 */
10365 /* end of microMIPS32 DSP */
10367 /* bits 15..12 for 0x2c */
10383 /* bits 15..12 for 0x34 */
10391 /* bits 15..12 for 0x3c */
10393 JR
= 0x0, /* alias */
10398 /* bits 15..12 for 0x05 */
10402 /* bits 15..12 for 0x0d */
10412 /* bits 15..12 for 0x15 */
10418 /* bits 15..12 for 0x1d */
10422 /* bits 15..12 for 0x2d */
10427 /* bits 15..12 for 0x35 */
10434 /* POOL32B encoding of minor opcode field (bits 15..12) */
10450 /* POOL32C encoding of minor opcode field (bits 15..12) */
10458 /* 0xa is reserved */
10465 /* 0x6 is reserved */
10471 /* POOL32F encoding of minor opcode field (bits 5..0) */
10474 /* These are the bit 7..6 values */
10485 /* These are the bit 8..6 values */
10529 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10533 /* POOL32Fxf encoding of minor opcode extension field */
10571 /* POOL32I encoding of minor opcode field (bits 25..21) */
10596 /* These overlap and are distinguished by bit16 of the instruction */
10605 /* POOL16A encoding of minor opcode field */
10612 /* POOL16B encoding of minor opcode field */
10619 /* POOL16C encoding of minor opcode field */
10639 /* POOL16D encoding of minor opcode field */
10646 /* POOL16E encoding of minor opcode field */
10653 static int mmreg (int r
)
10655 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10660 /* Used for 16-bit store instructions. */
10661 static int mmreg2 (int r
)
10663 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10668 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10669 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10670 #define uMIPS_RS2(op) uMIPS_RS(op)
10671 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10672 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10673 #define uMIPS_RS5(op) (op & 0x1f)
10675 /* Signed immediate */
10676 #define SIMM(op, start, width) \
10677 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10680 /* Zero-extended immediate */
10681 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10683 static void gen_addiur1sp(DisasContext
*ctx
)
10685 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10687 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10690 static void gen_addiur2(DisasContext
*ctx
)
10692 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10693 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10694 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10696 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10699 static void gen_addiusp(DisasContext
*ctx
)
10701 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10704 if (encoded
<= 1) {
10705 decoded
= 256 + encoded
;
10706 } else if (encoded
<= 255) {
10708 } else if (encoded
<= 509) {
10709 decoded
= encoded
- 512;
10711 decoded
= encoded
- 768;
10714 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10717 static void gen_addius5(DisasContext
*ctx
)
10719 int imm
= SIMM(ctx
->opcode
, 1, 4);
10720 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10722 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10725 static void gen_andi16(DisasContext
*ctx
)
10727 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10728 31, 32, 63, 64, 255, 32768, 65535 };
10729 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10730 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10731 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10733 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10736 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10737 int base
, int16_t offset
)
10739 const char *opn
= "ldst_multiple";
10743 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10744 generate_exception(ctx
, EXCP_RI
);
10748 t0
= tcg_temp_new();
10750 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10752 t1
= tcg_const_tl(reglist
);
10753 t2
= tcg_const_i32(ctx
->mem_idx
);
10755 save_cpu_state(ctx
, 1);
10758 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10762 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10765 #ifdef TARGET_MIPS64
10767 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10771 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10777 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10780 tcg_temp_free_i32(t2
);
10784 static void gen_pool16c_insn(DisasContext
*ctx
)
10786 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10787 int rs
= mmreg(ctx
->opcode
& 0x7);
10790 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10795 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10801 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10807 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10813 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10820 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10821 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10823 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10832 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10833 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10835 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10842 int reg
= ctx
->opcode
& 0x1f;
10844 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10850 int reg
= ctx
->opcode
& 0x1f;
10852 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10853 /* Let normal delay slot handling in our caller take us
10854 to the branch target. */
10866 int reg
= ctx
->opcode
& 0x1f;
10868 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10873 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
10877 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
10880 generate_exception(ctx
, EXCP_BREAK
);
10883 /* XXX: not clear which exception should be raised
10884 * when in debug mode...
10886 check_insn(ctx
, ISA_MIPS32
);
10887 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10888 generate_exception(ctx
, EXCP_DBp
);
10890 generate_exception(ctx
, EXCP_DBp
);
10893 case JRADDIUSP
+ 0:
10894 case JRADDIUSP
+ 1:
10896 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10898 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10899 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10900 /* Let normal delay slot handling in our caller take us
10901 to the branch target. */
10905 generate_exception(ctx
, EXCP_RI
);
10910 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10912 TCGv t0
= tcg_temp_new();
10913 TCGv t1
= tcg_temp_new();
10915 gen_load_gpr(t0
, base
);
10918 gen_load_gpr(t1
, index
);
10919 tcg_gen_shli_tl(t1
, t1
, 2);
10920 gen_op_addr_add(ctx
, t0
, t1
, t0
);
10923 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
10924 gen_store_gpr(t1
, rd
);
10930 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
10931 int base
, int16_t offset
)
10933 const char *opn
= "ldst_pair";
10936 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
10937 generate_exception(ctx
, EXCP_RI
);
10941 t0
= tcg_temp_new();
10942 t1
= tcg_temp_new();
10944 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10949 generate_exception(ctx
, EXCP_RI
);
10952 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
10953 gen_store_gpr(t1
, rd
);
10954 tcg_gen_movi_tl(t1
, 4);
10955 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10956 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
10957 gen_store_gpr(t1
, rd
+1);
10961 gen_load_gpr(t1
, rd
);
10962 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10963 tcg_gen_movi_tl(t1
, 4);
10964 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10965 gen_load_gpr(t1
, rd
+1);
10966 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10969 #ifdef TARGET_MIPS64
10972 generate_exception(ctx
, EXCP_RI
);
10975 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
10976 gen_store_gpr(t1
, rd
);
10977 tcg_gen_movi_tl(t1
, 8);
10978 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10979 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
10980 gen_store_gpr(t1
, rd
+1);
10984 gen_load_gpr(t1
, rd
);
10985 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
10986 tcg_gen_movi_tl(t1
, 8);
10987 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10988 gen_load_gpr(t1
, rd
+1);
10989 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
10994 (void)opn
; /* avoid a compiler warning */
10995 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11000 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
11002 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11003 int minor
= (ctx
->opcode
>> 12) & 0xf;
11004 uint32_t mips32_op
;
11006 switch (extension
) {
11008 mips32_op
= OPC_TEQ
;
11011 mips32_op
= OPC_TGE
;
11014 mips32_op
= OPC_TGEU
;
11017 mips32_op
= OPC_TLT
;
11020 mips32_op
= OPC_TLTU
;
11023 mips32_op
= OPC_TNE
;
11025 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11027 #ifndef CONFIG_USER_ONLY
11030 check_cp0_enabled(ctx
);
11032 /* Treat as NOP. */
11035 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11039 check_cp0_enabled(ctx
);
11041 TCGv t0
= tcg_temp_new();
11043 gen_load_gpr(t0
, rt
);
11044 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11050 switch (minor
& 3) {
11052 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11055 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11058 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11061 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11064 goto pool32axf_invalid
;
11068 switch (minor
& 3) {
11070 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11073 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11076 goto pool32axf_invalid
;
11082 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11085 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11088 mips32_op
= OPC_CLO
;
11091 mips32_op
= OPC_CLZ
;
11093 check_insn(ctx
, ISA_MIPS32
);
11094 gen_cl(ctx
, mips32_op
, rt
, rs
);
11097 gen_rdhwr(ctx
, rt
, rs
);
11100 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11103 mips32_op
= OPC_MULT
;
11106 mips32_op
= OPC_MULTU
;
11109 mips32_op
= OPC_DIV
;
11112 mips32_op
= OPC_DIVU
;
11115 check_insn(ctx
, ISA_MIPS32
);
11116 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11119 mips32_op
= OPC_MADD
;
11122 mips32_op
= OPC_MADDU
;
11125 mips32_op
= OPC_MSUB
;
11128 mips32_op
= OPC_MSUBU
;
11130 check_insn(ctx
, ISA_MIPS32
);
11131 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11134 goto pool32axf_invalid
;
11145 generate_exception_err(ctx
, EXCP_CpU
, 2);
11148 goto pool32axf_invalid
;
11155 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11159 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11162 goto pool32axf_invalid
;
11168 check_cp0_enabled(ctx
);
11169 check_insn(ctx
, ISA_MIPS32R2
);
11170 gen_load_srsgpr(rt
, rs
);
11173 check_cp0_enabled(ctx
);
11174 check_insn(ctx
, ISA_MIPS32R2
);
11175 gen_store_srsgpr(rt
, rs
);
11178 goto pool32axf_invalid
;
11181 #ifndef CONFIG_USER_ONLY
11185 mips32_op
= OPC_TLBP
;
11188 mips32_op
= OPC_TLBR
;
11191 mips32_op
= OPC_TLBWI
;
11194 mips32_op
= OPC_TLBWR
;
11197 mips32_op
= OPC_WAIT
;
11200 mips32_op
= OPC_DERET
;
11203 mips32_op
= OPC_ERET
;
11205 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11208 goto pool32axf_invalid
;
11214 check_cp0_enabled(ctx
);
11216 TCGv t0
= tcg_temp_new();
11218 save_cpu_state(ctx
, 1);
11219 gen_helper_di(t0
, cpu_env
);
11220 gen_store_gpr(t0
, rs
);
11221 /* Stop translation as we may have switched the execution mode */
11222 ctx
->bstate
= BS_STOP
;
11227 check_cp0_enabled(ctx
);
11229 TCGv t0
= tcg_temp_new();
11231 save_cpu_state(ctx
, 1);
11232 gen_helper_ei(t0
, cpu_env
);
11233 gen_store_gpr(t0
, rs
);
11234 /* Stop translation as we may have switched the execution mode */
11235 ctx
->bstate
= BS_STOP
;
11240 goto pool32axf_invalid
;
11250 generate_exception(ctx
, EXCP_SYSCALL
);
11251 ctx
->bstate
= BS_STOP
;
11254 check_insn(ctx
, ISA_MIPS32
);
11255 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11256 generate_exception(ctx
, EXCP_DBp
);
11258 generate_exception(ctx
, EXCP_DBp
);
11262 goto pool32axf_invalid
;
11266 switch (minor
& 3) {
11268 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
11271 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
11274 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
11277 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
11280 goto pool32axf_invalid
;
11286 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
11289 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
11292 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
11295 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
11298 goto pool32axf_invalid
;
11303 MIPS_INVAL("pool32axf");
11304 generate_exception(ctx
, EXCP_RI
);
11309 /* Values for microMIPS fmt field. Variable-width, depending on which
11310 formats the instruction supports. */
11329 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11331 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11332 uint32_t mips32_op
;
11334 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11335 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11336 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11338 switch (extension
) {
11339 case FLOAT_1BIT_FMT(CFC1
, 0):
11340 mips32_op
= OPC_CFC1
;
11342 case FLOAT_1BIT_FMT(CTC1
, 0):
11343 mips32_op
= OPC_CTC1
;
11345 case FLOAT_1BIT_FMT(MFC1
, 0):
11346 mips32_op
= OPC_MFC1
;
11348 case FLOAT_1BIT_FMT(MTC1
, 0):
11349 mips32_op
= OPC_MTC1
;
11351 case FLOAT_1BIT_FMT(MFHC1
, 0):
11352 mips32_op
= OPC_MFHC1
;
11354 case FLOAT_1BIT_FMT(MTHC1
, 0):
11355 mips32_op
= OPC_MTHC1
;
11357 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11360 /* Reciprocal square root */
11361 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11362 mips32_op
= OPC_RSQRT_S
;
11364 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11365 mips32_op
= OPC_RSQRT_D
;
11369 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11370 mips32_op
= OPC_SQRT_S
;
11372 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11373 mips32_op
= OPC_SQRT_D
;
11377 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11378 mips32_op
= OPC_RECIP_S
;
11380 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11381 mips32_op
= OPC_RECIP_D
;
11385 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11386 mips32_op
= OPC_FLOOR_L_S
;
11388 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11389 mips32_op
= OPC_FLOOR_L_D
;
11391 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11392 mips32_op
= OPC_FLOOR_W_S
;
11394 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11395 mips32_op
= OPC_FLOOR_W_D
;
11399 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11400 mips32_op
= OPC_CEIL_L_S
;
11402 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11403 mips32_op
= OPC_CEIL_L_D
;
11405 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11406 mips32_op
= OPC_CEIL_W_S
;
11408 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11409 mips32_op
= OPC_CEIL_W_D
;
11413 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11414 mips32_op
= OPC_TRUNC_L_S
;
11416 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11417 mips32_op
= OPC_TRUNC_L_D
;
11419 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11420 mips32_op
= OPC_TRUNC_W_S
;
11422 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11423 mips32_op
= OPC_TRUNC_W_D
;
11427 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11428 mips32_op
= OPC_ROUND_L_S
;
11430 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11431 mips32_op
= OPC_ROUND_L_D
;
11433 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11434 mips32_op
= OPC_ROUND_W_S
;
11436 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11437 mips32_op
= OPC_ROUND_W_D
;
11440 /* Integer to floating-point conversion */
11441 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11442 mips32_op
= OPC_CVT_L_S
;
11444 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11445 mips32_op
= OPC_CVT_L_D
;
11447 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11448 mips32_op
= OPC_CVT_W_S
;
11450 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11451 mips32_op
= OPC_CVT_W_D
;
11454 /* Paired-foo conversions */
11455 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11456 mips32_op
= OPC_CVT_S_PL
;
11458 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11459 mips32_op
= OPC_CVT_S_PU
;
11461 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11462 mips32_op
= OPC_CVT_PW_PS
;
11464 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11465 mips32_op
= OPC_CVT_PS_PW
;
11468 /* Floating-point moves */
11469 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11470 mips32_op
= OPC_MOV_S
;
11472 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11473 mips32_op
= OPC_MOV_D
;
11475 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11476 mips32_op
= OPC_MOV_PS
;
11479 /* Absolute value */
11480 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11481 mips32_op
= OPC_ABS_S
;
11483 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11484 mips32_op
= OPC_ABS_D
;
11486 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11487 mips32_op
= OPC_ABS_PS
;
11491 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11492 mips32_op
= OPC_NEG_S
;
11494 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11495 mips32_op
= OPC_NEG_D
;
11497 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11498 mips32_op
= OPC_NEG_PS
;
11501 /* Reciprocal square root step */
11502 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11503 mips32_op
= OPC_RSQRT1_S
;
11505 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11506 mips32_op
= OPC_RSQRT1_D
;
11508 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11509 mips32_op
= OPC_RSQRT1_PS
;
11512 /* Reciprocal step */
11513 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11514 mips32_op
= OPC_RECIP1_S
;
11516 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11517 mips32_op
= OPC_RECIP1_S
;
11519 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11520 mips32_op
= OPC_RECIP1_PS
;
11523 /* Conversions from double */
11524 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11525 mips32_op
= OPC_CVT_D_S
;
11527 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11528 mips32_op
= OPC_CVT_D_W
;
11530 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11531 mips32_op
= OPC_CVT_D_L
;
11534 /* Conversions from single */
11535 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11536 mips32_op
= OPC_CVT_S_D
;
11538 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11539 mips32_op
= OPC_CVT_S_W
;
11541 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11542 mips32_op
= OPC_CVT_S_L
;
11544 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11547 /* Conditional moves on floating-point codes */
11548 case COND_FLOAT_MOV(MOVT
, 0):
11549 case COND_FLOAT_MOV(MOVT
, 1):
11550 case COND_FLOAT_MOV(MOVT
, 2):
11551 case COND_FLOAT_MOV(MOVT
, 3):
11552 case COND_FLOAT_MOV(MOVT
, 4):
11553 case COND_FLOAT_MOV(MOVT
, 5):
11554 case COND_FLOAT_MOV(MOVT
, 6):
11555 case COND_FLOAT_MOV(MOVT
, 7):
11556 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11558 case COND_FLOAT_MOV(MOVF
, 0):
11559 case COND_FLOAT_MOV(MOVF
, 1):
11560 case COND_FLOAT_MOV(MOVF
, 2):
11561 case COND_FLOAT_MOV(MOVF
, 3):
11562 case COND_FLOAT_MOV(MOVF
, 4):
11563 case COND_FLOAT_MOV(MOVF
, 5):
11564 case COND_FLOAT_MOV(MOVF
, 6):
11565 case COND_FLOAT_MOV(MOVF
, 7):
11566 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11569 MIPS_INVAL("pool32fxf");
11570 generate_exception(ctx
, EXCP_RI
);
11575 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11580 int rt
, rs
, rd
, rr
;
11582 uint32_t op
, minor
, mips32_op
;
11583 uint32_t cond
, fmt
, cc
;
11585 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11586 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11588 rt
= (ctx
->opcode
>> 21) & 0x1f;
11589 rs
= (ctx
->opcode
>> 16) & 0x1f;
11590 rd
= (ctx
->opcode
>> 11) & 0x1f;
11591 rr
= (ctx
->opcode
>> 6) & 0x1f;
11592 imm
= (int16_t) ctx
->opcode
;
11594 op
= (ctx
->opcode
>> 26) & 0x3f;
11597 minor
= ctx
->opcode
& 0x3f;
11600 minor
= (ctx
->opcode
>> 6) & 0xf;
11603 mips32_op
= OPC_SLL
;
11606 mips32_op
= OPC_SRA
;
11609 mips32_op
= OPC_SRL
;
11612 mips32_op
= OPC_ROTR
;
11614 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11617 goto pool32a_invalid
;
11621 minor
= (ctx
->opcode
>> 6) & 0xf;
11625 mips32_op
= OPC_ADD
;
11628 mips32_op
= OPC_ADDU
;
11631 mips32_op
= OPC_SUB
;
11634 mips32_op
= OPC_SUBU
;
11637 mips32_op
= OPC_MUL
;
11639 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11643 mips32_op
= OPC_SLLV
;
11646 mips32_op
= OPC_SRLV
;
11649 mips32_op
= OPC_SRAV
;
11652 mips32_op
= OPC_ROTRV
;
11654 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11656 /* Logical operations */
11658 mips32_op
= OPC_AND
;
11661 mips32_op
= OPC_OR
;
11664 mips32_op
= OPC_NOR
;
11667 mips32_op
= OPC_XOR
;
11669 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11671 /* Set less than */
11673 mips32_op
= OPC_SLT
;
11676 mips32_op
= OPC_SLTU
;
11678 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11681 goto pool32a_invalid
;
11685 minor
= (ctx
->opcode
>> 6) & 0xf;
11687 /* Conditional moves */
11689 mips32_op
= OPC_MOVN
;
11692 mips32_op
= OPC_MOVZ
;
11694 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11697 gen_ldxs(ctx
, rs
, rt
, rd
);
11700 goto pool32a_invalid
;
11704 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11707 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11710 gen_pool32axf(env
, ctx
, rt
, rs
);
11713 generate_exception(ctx
, EXCP_BREAK
);
11717 MIPS_INVAL("pool32a");
11718 generate_exception(ctx
, EXCP_RI
);
11723 minor
= (ctx
->opcode
>> 12) & 0xf;
11726 check_cp0_enabled(ctx
);
11727 /* Treat as no-op. */
11731 /* COP2: Not implemented. */
11732 generate_exception_err(ctx
, EXCP_CpU
, 2);
11736 #ifdef TARGET_MIPS64
11740 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11744 #ifdef TARGET_MIPS64
11748 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11751 MIPS_INVAL("pool32b");
11752 generate_exception(ctx
, EXCP_RI
);
11757 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
11758 minor
= ctx
->opcode
& 0x3f;
11759 check_cp1_enabled(ctx
);
11762 mips32_op
= OPC_ALNV_PS
;
11765 mips32_op
= OPC_MADD_S
;
11768 mips32_op
= OPC_MADD_D
;
11771 mips32_op
= OPC_MADD_PS
;
11774 mips32_op
= OPC_MSUB_S
;
11777 mips32_op
= OPC_MSUB_D
;
11780 mips32_op
= OPC_MSUB_PS
;
11783 mips32_op
= OPC_NMADD_S
;
11786 mips32_op
= OPC_NMADD_D
;
11789 mips32_op
= OPC_NMADD_PS
;
11792 mips32_op
= OPC_NMSUB_S
;
11795 mips32_op
= OPC_NMSUB_D
;
11798 mips32_op
= OPC_NMSUB_PS
;
11800 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11802 case CABS_COND_FMT
:
11803 cond
= (ctx
->opcode
>> 6) & 0xf;
11804 cc
= (ctx
->opcode
>> 13) & 0x7;
11805 fmt
= (ctx
->opcode
>> 10) & 0x3;
11808 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11811 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11814 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11817 goto pool32f_invalid
;
11821 cond
= (ctx
->opcode
>> 6) & 0xf;
11822 cc
= (ctx
->opcode
>> 13) & 0x7;
11823 fmt
= (ctx
->opcode
>> 10) & 0x3;
11826 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11829 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11832 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11835 goto pool32f_invalid
;
11839 gen_pool32fxf(ctx
, rt
, rs
);
11843 switch ((ctx
->opcode
>> 6) & 0x7) {
11845 mips32_op
= OPC_PLL_PS
;
11848 mips32_op
= OPC_PLU_PS
;
11851 mips32_op
= OPC_PUL_PS
;
11854 mips32_op
= OPC_PUU_PS
;
11857 mips32_op
= OPC_CVT_PS_S
;
11859 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11862 goto pool32f_invalid
;
11867 switch ((ctx
->opcode
>> 6) & 0x7) {
11869 mips32_op
= OPC_LWXC1
;
11872 mips32_op
= OPC_SWXC1
;
11875 mips32_op
= OPC_LDXC1
;
11878 mips32_op
= OPC_SDXC1
;
11881 mips32_op
= OPC_LUXC1
;
11884 mips32_op
= OPC_SUXC1
;
11886 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11889 goto pool32f_invalid
;
11894 fmt
= (ctx
->opcode
>> 9) & 0x3;
11895 switch ((ctx
->opcode
>> 6) & 0x7) {
11899 mips32_op
= OPC_RSQRT2_S
;
11902 mips32_op
= OPC_RSQRT2_D
;
11905 mips32_op
= OPC_RSQRT2_PS
;
11908 goto pool32f_invalid
;
11914 mips32_op
= OPC_RECIP2_S
;
11917 mips32_op
= OPC_RECIP2_D
;
11920 mips32_op
= OPC_RECIP2_PS
;
11923 goto pool32f_invalid
;
11927 mips32_op
= OPC_ADDR_PS
;
11930 mips32_op
= OPC_MULR_PS
;
11932 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11935 goto pool32f_invalid
;
11939 /* MOV[FT].fmt and PREFX */
11940 cc
= (ctx
->opcode
>> 13) & 0x7;
11941 fmt
= (ctx
->opcode
>> 9) & 0x3;
11942 switch ((ctx
->opcode
>> 6) & 0x7) {
11946 gen_movcf_s(rs
, rt
, cc
, 0);
11949 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
11952 gen_movcf_ps(rs
, rt
, cc
, 0);
11955 goto pool32f_invalid
;
11961 gen_movcf_s(rs
, rt
, cc
, 1);
11964 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
11967 gen_movcf_ps(rs
, rt
, cc
, 1);
11970 goto pool32f_invalid
;
11976 goto pool32f_invalid
;
11979 #define FINSN_3ARG_SDPS(prfx) \
11980 switch ((ctx->opcode >> 8) & 0x3) { \
11982 mips32_op = OPC_##prfx##_S; \
11985 mips32_op = OPC_##prfx##_D; \
11987 case FMT_SDPS_PS: \
11988 mips32_op = OPC_##prfx##_PS; \
11991 goto pool32f_invalid; \
11994 /* regular FP ops */
11995 switch ((ctx
->opcode
>> 6) & 0x3) {
11997 FINSN_3ARG_SDPS(ADD
);
12000 FINSN_3ARG_SDPS(SUB
);
12003 FINSN_3ARG_SDPS(MUL
);
12006 fmt
= (ctx
->opcode
>> 8) & 0x3;
12008 mips32_op
= OPC_DIV_D
;
12009 } else if (fmt
== 0) {
12010 mips32_op
= OPC_DIV_S
;
12012 goto pool32f_invalid
;
12016 goto pool32f_invalid
;
12021 switch ((ctx
->opcode
>> 6) & 0x3) {
12023 FINSN_3ARG_SDPS(MOVN
);
12026 FINSN_3ARG_SDPS(MOVZ
);
12029 goto pool32f_invalid
;
12033 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12037 MIPS_INVAL("pool32f");
12038 generate_exception(ctx
, EXCP_RI
);
12042 generate_exception_err(ctx
, EXCP_CpU
, 1);
12046 minor
= (ctx
->opcode
>> 21) & 0x1f;
12049 mips32_op
= OPC_BLTZ
;
12052 mips32_op
= OPC_BLTZAL
;
12055 mips32_op
= OPC_BLTZALS
;
12058 mips32_op
= OPC_BGEZ
;
12061 mips32_op
= OPC_BGEZAL
;
12064 mips32_op
= OPC_BGEZALS
;
12067 mips32_op
= OPC_BLEZ
;
12070 mips32_op
= OPC_BGTZ
;
12072 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12077 mips32_op
= OPC_TLTI
;
12080 mips32_op
= OPC_TGEI
;
12083 mips32_op
= OPC_TLTIU
;
12086 mips32_op
= OPC_TGEIU
;
12089 mips32_op
= OPC_TNEI
;
12092 mips32_op
= OPC_TEQI
;
12094 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12099 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12100 4, rs
, 0, imm
<< 1);
12101 /* Compact branches don't have a delay slot, so just let
12102 the normal delay slot handling take us to the branch
12106 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12112 /* COP2: Not implemented. */
12113 generate_exception_err(ctx
, EXCP_CpU
, 2);
12116 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12119 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12122 mips32_op
= OPC_BC1FANY4
;
12125 mips32_op
= OPC_BC1TANY4
;
12128 check_insn(ctx
, ASE_MIPS3D
);
12131 gen_compute_branch1(ctx
, mips32_op
,
12132 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12136 /* MIPS DSP: not implemented */
12139 MIPS_INVAL("pool32i");
12140 generate_exception(ctx
, EXCP_RI
);
12145 minor
= (ctx
->opcode
>> 12) & 0xf;
12148 mips32_op
= OPC_LWL
;
12151 mips32_op
= OPC_SWL
;
12154 mips32_op
= OPC_LWR
;
12157 mips32_op
= OPC_SWR
;
12159 #if defined(TARGET_MIPS64)
12161 mips32_op
= OPC_LDL
;
12164 mips32_op
= OPC_SDL
;
12167 mips32_op
= OPC_LDR
;
12170 mips32_op
= OPC_SDR
;
12173 mips32_op
= OPC_LWU
;
12176 mips32_op
= OPC_LLD
;
12180 mips32_op
= OPC_LL
;
12183 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12186 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12189 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12191 #if defined(TARGET_MIPS64)
12193 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12197 /* Treat as no-op */
12200 MIPS_INVAL("pool32c");
12201 generate_exception(ctx
, EXCP_RI
);
12206 mips32_op
= OPC_ADDI
;
12209 mips32_op
= OPC_ADDIU
;
12211 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12214 /* Logical operations */
12216 mips32_op
= OPC_ORI
;
12219 mips32_op
= OPC_XORI
;
12222 mips32_op
= OPC_ANDI
;
12224 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12227 /* Set less than immediate */
12229 mips32_op
= OPC_SLTI
;
12232 mips32_op
= OPC_SLTIU
;
12234 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12237 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12238 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12241 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12242 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12245 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12248 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12251 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12252 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12255 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12256 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12258 /* Floating point (COP1) */
12260 mips32_op
= OPC_LWC1
;
12263 mips32_op
= OPC_LDC1
;
12266 mips32_op
= OPC_SWC1
;
12269 mips32_op
= OPC_SDC1
;
12271 gen_cop1_ldst(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12275 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12276 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12278 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12281 /* Loads and stores */
12283 mips32_op
= OPC_LB
;
12286 mips32_op
= OPC_LBU
;
12289 mips32_op
= OPC_LH
;
12292 mips32_op
= OPC_LHU
;
12295 mips32_op
= OPC_LW
;
12297 #ifdef TARGET_MIPS64
12299 mips32_op
= OPC_LD
;
12302 mips32_op
= OPC_SD
;
12306 mips32_op
= OPC_SB
;
12309 mips32_op
= OPC_SH
;
12312 mips32_op
= OPC_SW
;
12315 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12318 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12321 generate_exception(ctx
, EXCP_RI
);
12326 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
12330 /* make sure instructions are on a halfword boundary */
12331 if (ctx
->pc
& 0x1) {
12332 env
->CP0_BadVAddr
= ctx
->pc
;
12333 generate_exception(ctx
, EXCP_AdEL
);
12334 ctx
->bstate
= BS_STOP
;
12338 op
= (ctx
->opcode
>> 10) & 0x3f;
12339 /* Enforce properly-sized instructions in a delay slot */
12340 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12341 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12379 if (bits
& MIPS_HFLAG_BDS16
) {
12380 generate_exception(ctx
, EXCP_RI
);
12381 /* Just stop translation; the user is confused. */
12382 ctx
->bstate
= BS_STOP
;
12407 if (bits
& MIPS_HFLAG_BDS32
) {
12408 generate_exception(ctx
, EXCP_RI
);
12409 /* Just stop translation; the user is confused. */
12410 ctx
->bstate
= BS_STOP
;
12421 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12422 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12423 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12426 switch (ctx
->opcode
& 0x1) {
12435 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12440 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12441 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12442 int amount
= (ctx
->opcode
>> 1) & 0x7;
12444 amount
= amount
== 0 ? 8 : amount
;
12446 switch (ctx
->opcode
& 0x1) {
12455 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12459 gen_pool16c_insn(ctx
);
12463 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12464 int rb
= 28; /* GP */
12465 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12467 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12471 if (ctx
->opcode
& 1) {
12472 generate_exception(ctx
, EXCP_RI
);
12475 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12476 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12477 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12478 int rd
, rs
, re
, rt
;
12479 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12480 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12481 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12483 rd
= rd_enc
[enc_dest
];
12484 re
= re_enc
[enc_dest
];
12485 rs
= rs_rt_enc
[enc_rs
];
12486 rt
= rs_rt_enc
[enc_rt
];
12488 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12489 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12494 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12495 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12496 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12497 offset
= (offset
== 0xf ? -1 : offset
);
12499 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12504 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12505 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12506 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12508 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12513 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12514 int rb
= 29; /* SP */
12515 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12517 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12522 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12523 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12524 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12526 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12531 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12532 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12533 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12535 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12540 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12541 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12542 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12544 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12549 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12550 int rb
= 29; /* SP */
12551 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12553 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12558 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12559 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12560 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12562 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12567 int rd
= uMIPS_RD5(ctx
->opcode
);
12568 int rs
= uMIPS_RS5(ctx
->opcode
);
12570 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12577 switch (ctx
->opcode
& 0x1) {
12587 switch (ctx
->opcode
& 0x1) {
12592 gen_addiur1sp(ctx
);
12597 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12598 SIMM(ctx
->opcode
, 0, 10) << 1);
12602 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12603 mmreg(uMIPS_RD(ctx
->opcode
)),
12604 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12608 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12609 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12611 imm
= (imm
== 0x7f ? -1 : imm
);
12612 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12622 generate_exception(ctx
, EXCP_RI
);
12625 decode_micromips32_opc (env
, ctx
, op
);
12632 /* SmartMIPS extension to MIPS32 */
12634 #if defined(TARGET_MIPS64)
12636 /* MDMX extension to MIPS64 */
12640 /* MIPSDSP functions. */
12641 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12642 int rd
, int base
, int offset
)
12644 const char *opn
= "ldx";
12648 t0
= tcg_temp_new();
12651 gen_load_gpr(t0
, offset
);
12652 } else if (offset
== 0) {
12653 gen_load_gpr(t0
, base
);
12655 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12660 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
12661 gen_store_gpr(t0
, rd
);
12665 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
12666 gen_store_gpr(t0
, rd
);
12670 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12671 gen_store_gpr(t0
, rd
);
12674 #if defined(TARGET_MIPS64)
12676 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12677 gen_store_gpr(t0
, rd
);
12682 (void)opn
; /* avoid a compiler warning */
12683 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12684 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12688 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12689 int ret
, int v1
, int v2
)
12691 const char *opn
= "mipsdsp arith";
12696 /* Treat as NOP. */
12701 v1_t
= tcg_temp_new();
12702 v2_t
= tcg_temp_new();
12704 gen_load_gpr(v1_t
, v1
);
12705 gen_load_gpr(v2_t
, v2
);
12708 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12709 case OPC_MULT_G_2E
:
12713 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12715 case OPC_ADDUH_R_QB
:
12716 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12719 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12721 case OPC_ADDQH_R_PH
:
12722 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12725 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12727 case OPC_ADDQH_R_W
:
12728 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12731 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12733 case OPC_SUBUH_R_QB
:
12734 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12737 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12739 case OPC_SUBQH_R_PH
:
12740 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12743 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12745 case OPC_SUBQH_R_W
:
12746 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12750 case OPC_ABSQ_S_PH_DSP
:
12752 case OPC_ABSQ_S_QB
:
12754 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12756 case OPC_ABSQ_S_PH
:
12758 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12762 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12764 case OPC_PRECEQ_W_PHL
:
12766 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12767 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12769 case OPC_PRECEQ_W_PHR
:
12771 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12772 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12773 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12775 case OPC_PRECEQU_PH_QBL
:
12777 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12779 case OPC_PRECEQU_PH_QBR
:
12781 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12783 case OPC_PRECEQU_PH_QBLA
:
12785 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12787 case OPC_PRECEQU_PH_QBRA
:
12789 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12791 case OPC_PRECEU_PH_QBL
:
12793 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12795 case OPC_PRECEU_PH_QBR
:
12797 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12799 case OPC_PRECEU_PH_QBLA
:
12801 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12803 case OPC_PRECEU_PH_QBRA
:
12805 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12809 case OPC_ADDU_QB_DSP
:
12813 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12815 case OPC_ADDQ_S_PH
:
12817 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12821 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12825 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12827 case OPC_ADDU_S_QB
:
12829 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12833 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12835 case OPC_ADDU_S_PH
:
12837 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12841 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12843 case OPC_SUBQ_S_PH
:
12845 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12849 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12853 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12855 case OPC_SUBU_S_QB
:
12857 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12861 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12863 case OPC_SUBU_S_PH
:
12865 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12869 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12873 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12877 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12879 case OPC_RADDU_W_QB
:
12881 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12885 case OPC_CMPU_EQ_QB_DSP
:
12887 case OPC_PRECR_QB_PH
:
12889 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12891 case OPC_PRECRQ_QB_PH
:
12893 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12895 case OPC_PRECR_SRA_PH_W
:
12898 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12899 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12901 tcg_temp_free_i32(sa_t
);
12904 case OPC_PRECR_SRA_R_PH_W
:
12907 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12908 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12910 tcg_temp_free_i32(sa_t
);
12913 case OPC_PRECRQ_PH_W
:
12915 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12917 case OPC_PRECRQ_RS_PH_W
:
12919 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12921 case OPC_PRECRQU_S_QB_PH
:
12923 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12927 #ifdef TARGET_MIPS64
12928 case OPC_ABSQ_S_QH_DSP
:
12930 case OPC_PRECEQ_L_PWL
:
12932 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
12934 case OPC_PRECEQ_L_PWR
:
12936 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
12938 case OPC_PRECEQ_PW_QHL
:
12940 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
12942 case OPC_PRECEQ_PW_QHR
:
12944 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
12946 case OPC_PRECEQ_PW_QHLA
:
12948 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
12950 case OPC_PRECEQ_PW_QHRA
:
12952 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
12954 case OPC_PRECEQU_QH_OBL
:
12956 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
12958 case OPC_PRECEQU_QH_OBR
:
12960 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
12962 case OPC_PRECEQU_QH_OBLA
:
12964 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
12966 case OPC_PRECEQU_QH_OBRA
:
12968 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
12970 case OPC_PRECEU_QH_OBL
:
12972 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
12974 case OPC_PRECEU_QH_OBR
:
12976 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
12978 case OPC_PRECEU_QH_OBLA
:
12980 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
12982 case OPC_PRECEU_QH_OBRA
:
12984 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
12986 case OPC_ABSQ_S_OB
:
12988 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
12990 case OPC_ABSQ_S_PW
:
12992 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
12994 case OPC_ABSQ_S_QH
:
12996 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
13000 case OPC_ADDU_OB_DSP
:
13002 case OPC_RADDU_L_OB
:
13004 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
13008 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13010 case OPC_SUBQ_S_PW
:
13012 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13016 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13018 case OPC_SUBQ_S_QH
:
13020 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13024 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13026 case OPC_SUBU_S_OB
:
13028 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13032 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13034 case OPC_SUBU_S_QH
:
13036 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13040 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13042 case OPC_SUBUH_R_OB
:
13044 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13048 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13050 case OPC_ADDQ_S_PW
:
13052 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13056 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13058 case OPC_ADDQ_S_QH
:
13060 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13064 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13066 case OPC_ADDU_S_OB
:
13068 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13072 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13074 case OPC_ADDU_S_QH
:
13076 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13080 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13082 case OPC_ADDUH_R_OB
:
13084 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13088 case OPC_CMPU_EQ_OB_DSP
:
13090 case OPC_PRECR_OB_QH
:
13092 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13094 case OPC_PRECR_SRA_QH_PW
:
13097 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13098 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13099 tcg_temp_free_i32(ret_t
);
13102 case OPC_PRECR_SRA_R_QH_PW
:
13105 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13106 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13107 tcg_temp_free_i32(sa_v
);
13110 case OPC_PRECRQ_OB_QH
:
13112 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13114 case OPC_PRECRQ_PW_L
:
13116 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13118 case OPC_PRECRQ_QH_PW
:
13120 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13122 case OPC_PRECRQ_RS_QH_PW
:
13124 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13126 case OPC_PRECRQU_S_OB_QH
:
13128 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13135 tcg_temp_free(v1_t
);
13136 tcg_temp_free(v2_t
);
13138 (void)opn
; /* avoid a compiler warning */
13139 MIPS_DEBUG("%s", opn
);
13142 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13143 int ret
, int v1
, int v2
)
13146 const char *opn
= "mipsdsp shift";
13152 /* Treat as NOP. */
13157 t0
= tcg_temp_new();
13158 v1_t
= tcg_temp_new();
13159 v2_t
= tcg_temp_new();
13161 tcg_gen_movi_tl(t0
, v1
);
13162 gen_load_gpr(v1_t
, v1
);
13163 gen_load_gpr(v2_t
, v2
);
13166 case OPC_SHLL_QB_DSP
:
13168 op2
= MASK_SHLL_QB(ctx
->opcode
);
13172 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13176 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13180 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13184 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13186 case OPC_SHLL_S_PH
:
13188 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13190 case OPC_SHLLV_S_PH
:
13192 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13196 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13198 case OPC_SHLLV_S_W
:
13200 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13204 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13208 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13212 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13216 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13220 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13222 case OPC_SHRA_R_QB
:
13224 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13228 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13230 case OPC_SHRAV_R_QB
:
13232 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13236 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13238 case OPC_SHRA_R_PH
:
13240 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13244 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13246 case OPC_SHRAV_R_PH
:
13248 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13252 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13254 case OPC_SHRAV_R_W
:
13256 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13258 default: /* Invalid */
13259 MIPS_INVAL("MASK SHLL.QB");
13260 generate_exception(ctx
, EXCP_RI
);
13265 #ifdef TARGET_MIPS64
13266 case OPC_SHLL_OB_DSP
:
13267 op2
= MASK_SHLL_OB(ctx
->opcode
);
13271 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13275 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13277 case OPC_SHLL_S_PW
:
13279 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13281 case OPC_SHLLV_S_PW
:
13283 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13287 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13291 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13295 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13299 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13301 case OPC_SHLL_S_QH
:
13303 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13305 case OPC_SHLLV_S_QH
:
13307 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13311 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13315 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13317 case OPC_SHRA_R_OB
:
13319 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13321 case OPC_SHRAV_R_OB
:
13323 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13327 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13331 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13333 case OPC_SHRA_R_PW
:
13335 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13337 case OPC_SHRAV_R_PW
:
13339 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13343 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13347 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13349 case OPC_SHRA_R_QH
:
13351 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13353 case OPC_SHRAV_R_QH
:
13355 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13359 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13363 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13367 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13371 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13373 default: /* Invalid */
13374 MIPS_INVAL("MASK SHLL.OB");
13375 generate_exception(ctx
, EXCP_RI
);
13383 tcg_temp_free(v1_t
);
13384 tcg_temp_free(v2_t
);
13385 (void)opn
; /* avoid a compiler warning */
13386 MIPS_DEBUG("%s", opn
);
13389 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13390 int ret
, int v1
, int v2
, int check_ret
)
13392 const char *opn
= "mipsdsp multiply";
13397 if ((ret
== 0) && (check_ret
== 1)) {
13398 /* Treat as NOP. */
13403 t0
= tcg_temp_new_i32();
13404 v1_t
= tcg_temp_new();
13405 v2_t
= tcg_temp_new();
13407 tcg_gen_movi_i32(t0
, ret
);
13408 gen_load_gpr(v1_t
, v1
);
13409 gen_load_gpr(v2_t
, v2
);
13412 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13413 * the same mask and op1. */
13414 case OPC_MULT_G_2E
:
13418 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13421 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13424 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13426 case OPC_MULQ_RS_W
:
13427 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13431 case OPC_DPA_W_PH_DSP
:
13433 case OPC_DPAU_H_QBL
:
13435 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13437 case OPC_DPAU_H_QBR
:
13439 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13441 case OPC_DPSU_H_QBL
:
13443 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13445 case OPC_DPSU_H_QBR
:
13447 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13451 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13453 case OPC_DPAX_W_PH
:
13455 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13457 case OPC_DPAQ_S_W_PH
:
13459 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13461 case OPC_DPAQX_S_W_PH
:
13463 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13465 case OPC_DPAQX_SA_W_PH
:
13467 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13471 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13473 case OPC_DPSX_W_PH
:
13475 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13477 case OPC_DPSQ_S_W_PH
:
13479 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13481 case OPC_DPSQX_S_W_PH
:
13483 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13485 case OPC_DPSQX_SA_W_PH
:
13487 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13489 case OPC_MULSAQ_S_W_PH
:
13491 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13493 case OPC_DPAQ_SA_L_W
:
13495 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13497 case OPC_DPSQ_SA_L_W
:
13499 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13501 case OPC_MAQ_S_W_PHL
:
13503 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13505 case OPC_MAQ_S_W_PHR
:
13507 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13509 case OPC_MAQ_SA_W_PHL
:
13511 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13513 case OPC_MAQ_SA_W_PHR
:
13515 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13517 case OPC_MULSA_W_PH
:
13519 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13523 #ifdef TARGET_MIPS64
13524 case OPC_DPAQ_W_QH_DSP
:
13526 int ac
= ret
& 0x03;
13527 tcg_gen_movi_i32(t0
, ac
);
13532 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13536 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13540 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13544 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13548 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13550 case OPC_DPAQ_S_W_QH
:
13552 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13554 case OPC_DPAQ_SA_L_PW
:
13556 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13558 case OPC_DPAU_H_OBL
:
13560 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13562 case OPC_DPAU_H_OBR
:
13564 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13568 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13570 case OPC_DPSQ_S_W_QH
:
13572 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13574 case OPC_DPSQ_SA_L_PW
:
13576 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13578 case OPC_DPSU_H_OBL
:
13580 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13582 case OPC_DPSU_H_OBR
:
13584 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13586 case OPC_MAQ_S_L_PWL
:
13588 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13590 case OPC_MAQ_S_L_PWR
:
13592 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13594 case OPC_MAQ_S_W_QHLL
:
13596 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13598 case OPC_MAQ_SA_W_QHLL
:
13600 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13602 case OPC_MAQ_S_W_QHLR
:
13604 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13606 case OPC_MAQ_SA_W_QHLR
:
13608 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13610 case OPC_MAQ_S_W_QHRL
:
13612 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13614 case OPC_MAQ_SA_W_QHRL
:
13616 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13618 case OPC_MAQ_S_W_QHRR
:
13620 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13622 case OPC_MAQ_SA_W_QHRR
:
13624 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13626 case OPC_MULSAQ_S_L_PW
:
13628 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13630 case OPC_MULSAQ_S_W_QH
:
13632 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13638 case OPC_ADDU_QB_DSP
:
13640 case OPC_MULEU_S_PH_QBL
:
13642 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13644 case OPC_MULEU_S_PH_QBR
:
13646 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13648 case OPC_MULQ_RS_PH
:
13650 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13652 case OPC_MULEQ_S_W_PHL
:
13654 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13656 case OPC_MULEQ_S_W_PHR
:
13658 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13660 case OPC_MULQ_S_PH
:
13662 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13666 #ifdef TARGET_MIPS64
13667 case OPC_ADDU_OB_DSP
:
13669 case OPC_MULEQ_S_PW_QHL
:
13671 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13673 case OPC_MULEQ_S_PW_QHR
:
13675 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13677 case OPC_MULEU_S_QH_OBL
:
13679 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13681 case OPC_MULEU_S_QH_OBR
:
13683 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13685 case OPC_MULQ_RS_QH
:
13687 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13694 tcg_temp_free_i32(t0
);
13695 tcg_temp_free(v1_t
);
13696 tcg_temp_free(v2_t
);
13698 (void)opn
; /* avoid a compiler warning */
13699 MIPS_DEBUG("%s", opn
);
13703 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13706 const char *opn
= "mipsdsp Bit/ Manipulation";
13712 /* Treat as NOP. */
13717 t0
= tcg_temp_new();
13718 val_t
= tcg_temp_new();
13719 gen_load_gpr(val_t
, val
);
13722 case OPC_ABSQ_S_PH_DSP
:
13726 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13731 target_long result
;
13732 imm
= (ctx
->opcode
>> 16) & 0xFF;
13733 result
= (uint32_t)imm
<< 24 |
13734 (uint32_t)imm
<< 16 |
13735 (uint32_t)imm
<< 8 |
13737 result
= (int32_t)result
;
13738 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13743 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13744 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13745 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13746 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13747 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13748 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13753 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13754 imm
= (int16_t)(imm
<< 6) >> 6;
13755 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13756 (target_long
)((int32_t)imm
<< 16 | \
13762 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13763 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13764 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13765 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13769 #ifdef TARGET_MIPS64
13770 case OPC_ABSQ_S_QH_DSP
:
13777 imm
= (ctx
->opcode
>> 16) & 0xFF;
13778 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13779 temp
= (temp
<< 16) | temp
;
13780 temp
= (temp
<< 32) | temp
;
13781 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13789 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13790 imm
= (int16_t)(imm
<< 6) >> 6;
13791 temp
= ((target_long
)imm
<< 32) \
13792 | ((target_long
)imm
& 0xFFFFFFFF);
13793 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13801 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13802 imm
= (int16_t)(imm
<< 6) >> 6;
13804 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13805 ((uint64_t)(uint16_t)imm
<< 32) |
13806 ((uint64_t)(uint16_t)imm
<< 16) |
13807 (uint64_t)(uint16_t)imm
;
13808 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13813 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13814 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13815 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13816 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13817 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13818 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13819 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13823 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13824 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13825 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13829 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13830 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13831 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13832 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13833 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13840 tcg_temp_free(val_t
);
13842 (void)opn
; /* avoid a compiler warning */
13843 MIPS_DEBUG("%s", opn
);
13846 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13847 uint32_t op1
, uint32_t op2
,
13848 int ret
, int v1
, int v2
, int check_ret
)
13850 const char *opn
= "mipsdsp add compare pick";
13855 if ((ret
== 0) && (check_ret
== 1)) {
13856 /* Treat as NOP. */
13861 t1
= tcg_temp_new();
13862 v1_t
= tcg_temp_new();
13863 v2_t
= tcg_temp_new();
13865 gen_load_gpr(v1_t
, v1
);
13866 gen_load_gpr(v2_t
, v2
);
13869 case OPC_CMPU_EQ_QB_DSP
:
13871 case OPC_CMPU_EQ_QB
:
13873 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13875 case OPC_CMPU_LT_QB
:
13877 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13879 case OPC_CMPU_LE_QB
:
13881 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13883 case OPC_CMPGU_EQ_QB
:
13885 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13887 case OPC_CMPGU_LT_QB
:
13889 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13891 case OPC_CMPGU_LE_QB
:
13893 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13895 case OPC_CMPGDU_EQ_QB
:
13897 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13898 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13899 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13900 tcg_gen_shli_tl(t1
, t1
, 24);
13901 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13903 case OPC_CMPGDU_LT_QB
:
13905 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
13906 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13907 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13908 tcg_gen_shli_tl(t1
, t1
, 24);
13909 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13911 case OPC_CMPGDU_LE_QB
:
13913 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
13914 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13915 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13916 tcg_gen_shli_tl(t1
, t1
, 24);
13917 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13919 case OPC_CMP_EQ_PH
:
13921 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
13923 case OPC_CMP_LT_PH
:
13925 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
13927 case OPC_CMP_LE_PH
:
13929 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
13933 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13937 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13939 case OPC_PACKRL_PH
:
13941 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13945 #ifdef TARGET_MIPS64
13946 case OPC_CMPU_EQ_OB_DSP
:
13948 case OPC_CMP_EQ_PW
:
13950 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
13952 case OPC_CMP_LT_PW
:
13954 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
13956 case OPC_CMP_LE_PW
:
13958 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
13960 case OPC_CMP_EQ_QH
:
13962 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
13964 case OPC_CMP_LT_QH
:
13966 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
13968 case OPC_CMP_LE_QH
:
13970 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
13972 case OPC_CMPGDU_EQ_OB
:
13974 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13976 case OPC_CMPGDU_LT_OB
:
13978 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13980 case OPC_CMPGDU_LE_OB
:
13982 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13984 case OPC_CMPGU_EQ_OB
:
13986 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13988 case OPC_CMPGU_LT_OB
:
13990 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13992 case OPC_CMPGU_LE_OB
:
13994 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13996 case OPC_CMPU_EQ_OB
:
13998 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
14000 case OPC_CMPU_LT_OB
:
14002 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
14004 case OPC_CMPU_LE_OB
:
14006 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
14008 case OPC_PACKRL_PW
:
14010 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14014 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14018 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14022 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14030 tcg_temp_free(v1_t
);
14031 tcg_temp_free(v2_t
);
14033 (void)opn
; /* avoid a compiler warning */
14034 MIPS_DEBUG("%s", opn
);
14037 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14038 uint32_t op1
, int rt
, int rs
, int sa
)
14040 const char *opn
= "mipsdsp append/dappend";
14046 /* Treat as NOP. */
14051 t0
= tcg_temp_new();
14052 gen_load_gpr(t0
, rs
);
14055 case OPC_APPEND_DSP
:
14056 switch (MASK_APPEND(ctx
->opcode
)) {
14059 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14061 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14065 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14066 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14067 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14068 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14070 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14074 if (sa
!= 0 && sa
!= 2) {
14075 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14076 tcg_gen_ext32u_tl(t0
, t0
);
14077 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14078 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14080 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14082 default: /* Invalid */
14083 MIPS_INVAL("MASK APPEND");
14084 generate_exception(ctx
, EXCP_RI
);
14088 #ifdef TARGET_MIPS64
14089 case OPC_DAPPEND_DSP
:
14090 switch (MASK_DAPPEND(ctx
->opcode
)) {
14093 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14097 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14098 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14099 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14103 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14104 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14105 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14110 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14111 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14112 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14113 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14116 default: /* Invalid */
14117 MIPS_INVAL("MASK DAPPEND");
14118 generate_exception(ctx
, EXCP_RI
);
14125 (void)opn
; /* avoid a compiler warning */
14126 MIPS_DEBUG("%s", opn
);
14129 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14130 int ret
, int v1
, int v2
, int check_ret
)
14133 const char *opn
= "mipsdsp accumulator";
14140 if ((ret
== 0) && (check_ret
== 1)) {
14141 /* Treat as NOP. */
14146 t0
= tcg_temp_new();
14147 t1
= tcg_temp_new();
14148 v1_t
= tcg_temp_new();
14149 v2_t
= tcg_temp_new();
14151 gen_load_gpr(v1_t
, v1
);
14152 gen_load_gpr(v2_t
, v2
);
14155 case OPC_EXTR_W_DSP
:
14159 tcg_gen_movi_tl(t0
, v2
);
14160 tcg_gen_movi_tl(t1
, v1
);
14161 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14164 tcg_gen_movi_tl(t0
, v2
);
14165 tcg_gen_movi_tl(t1
, v1
);
14166 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14168 case OPC_EXTR_RS_W
:
14169 tcg_gen_movi_tl(t0
, v2
);
14170 tcg_gen_movi_tl(t1
, v1
);
14171 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14174 tcg_gen_movi_tl(t0
, v2
);
14175 tcg_gen_movi_tl(t1
, v1
);
14176 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14178 case OPC_EXTRV_S_H
:
14179 tcg_gen_movi_tl(t0
, v2
);
14180 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14183 tcg_gen_movi_tl(t0
, v2
);
14184 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14186 case OPC_EXTRV_R_W
:
14187 tcg_gen_movi_tl(t0
, v2
);
14188 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14190 case OPC_EXTRV_RS_W
:
14191 tcg_gen_movi_tl(t0
, v2
);
14192 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14195 tcg_gen_movi_tl(t0
, v2
);
14196 tcg_gen_movi_tl(t1
, v1
);
14197 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14200 tcg_gen_movi_tl(t0
, v2
);
14201 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14204 tcg_gen_movi_tl(t0
, v2
);
14205 tcg_gen_movi_tl(t1
, v1
);
14206 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14209 tcg_gen_movi_tl(t0
, v2
);
14210 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14213 imm
= (ctx
->opcode
>> 20) & 0x3F;
14214 tcg_gen_movi_tl(t0
, ret
);
14215 tcg_gen_movi_tl(t1
, imm
);
14216 gen_helper_shilo(t0
, t1
, cpu_env
);
14219 tcg_gen_movi_tl(t0
, ret
);
14220 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14223 tcg_gen_movi_tl(t0
, ret
);
14224 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14227 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14228 tcg_gen_movi_tl(t0
, imm
);
14229 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14232 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14233 tcg_gen_movi_tl(t0
, imm
);
14234 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14238 #ifdef TARGET_MIPS64
14239 case OPC_DEXTR_W_DSP
:
14243 tcg_gen_movi_tl(t0
, ret
);
14244 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14248 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14249 int ac
= (ctx
->opcode
>> 11) & 0x03;
14250 tcg_gen_movi_tl(t0
, shift
);
14251 tcg_gen_movi_tl(t1
, ac
);
14252 gen_helper_dshilo(t0
, t1
, cpu_env
);
14257 int ac
= (ctx
->opcode
>> 11) & 0x03;
14258 tcg_gen_movi_tl(t0
, ac
);
14259 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14263 tcg_gen_movi_tl(t0
, v2
);
14264 tcg_gen_movi_tl(t1
, v1
);
14266 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14269 tcg_gen_movi_tl(t0
, v2
);
14270 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14273 tcg_gen_movi_tl(t0
, v2
);
14274 tcg_gen_movi_tl(t1
, v1
);
14275 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14278 tcg_gen_movi_tl(t0
, v2
);
14279 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14282 tcg_gen_movi_tl(t0
, v2
);
14283 tcg_gen_movi_tl(t1
, v1
);
14284 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14286 case OPC_DEXTR_R_L
:
14287 tcg_gen_movi_tl(t0
, v2
);
14288 tcg_gen_movi_tl(t1
, v1
);
14289 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14291 case OPC_DEXTR_RS_L
:
14292 tcg_gen_movi_tl(t0
, v2
);
14293 tcg_gen_movi_tl(t1
, v1
);
14294 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14297 tcg_gen_movi_tl(t0
, v2
);
14298 tcg_gen_movi_tl(t1
, v1
);
14299 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14301 case OPC_DEXTR_R_W
:
14302 tcg_gen_movi_tl(t0
, v2
);
14303 tcg_gen_movi_tl(t1
, v1
);
14304 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14306 case OPC_DEXTR_RS_W
:
14307 tcg_gen_movi_tl(t0
, v2
);
14308 tcg_gen_movi_tl(t1
, v1
);
14309 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14311 case OPC_DEXTR_S_H
:
14312 tcg_gen_movi_tl(t0
, v2
);
14313 tcg_gen_movi_tl(t1
, v1
);
14314 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14316 case OPC_DEXTRV_S_H
:
14317 tcg_gen_movi_tl(t0
, v2
);
14318 tcg_gen_movi_tl(t1
, v1
);
14319 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14322 tcg_gen_movi_tl(t0
, v2
);
14323 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14325 case OPC_DEXTRV_R_L
:
14326 tcg_gen_movi_tl(t0
, v2
);
14327 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14329 case OPC_DEXTRV_RS_L
:
14330 tcg_gen_movi_tl(t0
, v2
);
14331 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14334 tcg_gen_movi_tl(t0
, v2
);
14335 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14337 case OPC_DEXTRV_R_W
:
14338 tcg_gen_movi_tl(t0
, v2
);
14339 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14341 case OPC_DEXTRV_RS_W
:
14342 tcg_gen_movi_tl(t0
, v2
);
14343 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14352 tcg_temp_free(v1_t
);
14353 tcg_temp_free(v2_t
);
14355 (void)opn
; /* avoid a compiler warning */
14356 MIPS_DEBUG("%s", opn
);
14359 /* End MIPSDSP functions. */
14361 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
14364 int rs
, rt
, rd
, sa
;
14365 uint32_t op
, op1
, op2
;
14368 /* make sure instructions are on a word boundary */
14369 if (ctx
->pc
& 0x3) {
14370 env
->CP0_BadVAddr
= ctx
->pc
;
14371 generate_exception(ctx
, EXCP_AdEL
);
14375 /* Handle blikely not taken case */
14376 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14377 int l1
= gen_new_label();
14379 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14380 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14381 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14382 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14386 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14387 tcg_gen_debug_insn_start(ctx
->pc
);
14390 op
= MASK_OP_MAJOR(ctx
->opcode
);
14391 rs
= (ctx
->opcode
>> 21) & 0x1f;
14392 rt
= (ctx
->opcode
>> 16) & 0x1f;
14393 rd
= (ctx
->opcode
>> 11) & 0x1f;
14394 sa
= (ctx
->opcode
>> 6) & 0x1f;
14395 imm
= (int16_t)ctx
->opcode
;
14398 op1
= MASK_SPECIAL(ctx
->opcode
);
14400 case OPC_SLL
: /* Shift with immediate */
14402 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14405 switch ((ctx
->opcode
>> 21) & 0x1f) {
14407 /* rotr is decoded as srl on non-R2 CPUs */
14408 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14413 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14416 generate_exception(ctx
, EXCP_RI
);
14420 case OPC_MOVN
: /* Conditional move */
14422 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14423 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14424 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14426 case OPC_ADD
... OPC_SUBU
:
14427 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14429 case OPC_SLLV
: /* Shifts */
14431 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14434 switch ((ctx
->opcode
>> 6) & 0x1f) {
14436 /* rotrv is decoded as srlv on non-R2 CPUs */
14437 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14442 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14445 generate_exception(ctx
, EXCP_RI
);
14449 case OPC_SLT
: /* Set on less than */
14451 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14453 case OPC_AND
: /* Logic*/
14457 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14462 check_insn(ctx
, INSN_VR54XX
);
14463 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14464 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14466 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14471 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14473 case OPC_JR
... OPC_JALR
:
14474 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14476 case OPC_TGE
... OPC_TEQ
: /* Traps */
14478 gen_trap(ctx
, op1
, rs
, rt
, -1);
14480 case OPC_MFHI
: /* Move from HI/LO */
14482 gen_HILO(ctx
, op1
, rs
& 3, rd
);
14485 case OPC_MTLO
: /* Move to HI/LO */
14486 gen_HILO(ctx
, op1
, rd
& 3, rs
);
14488 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14489 #ifdef MIPS_STRICT_STANDARD
14490 MIPS_INVAL("PMON / selsl");
14491 generate_exception(ctx
, EXCP_RI
);
14493 gen_helper_0e0i(pmon
, sa
);
14497 generate_exception(ctx
, EXCP_SYSCALL
);
14498 ctx
->bstate
= BS_STOP
;
14501 generate_exception(ctx
, EXCP_BREAK
);
14504 #ifdef MIPS_STRICT_STANDARD
14505 MIPS_INVAL("SPIM");
14506 generate_exception(ctx
, EXCP_RI
);
14508 /* Implemented as RI exception for now. */
14509 MIPS_INVAL("spim (unofficial)");
14510 generate_exception(ctx
, EXCP_RI
);
14514 /* Treat as NOP. */
14518 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14519 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14520 check_cp1_enabled(ctx
);
14521 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14522 (ctx
->opcode
>> 16) & 1);
14524 generate_exception_err(ctx
, EXCP_CpU
, 1);
14528 #if defined(TARGET_MIPS64)
14529 /* MIPS64 specific opcodes */
14534 check_insn(ctx
, ISA_MIPS3
);
14535 check_mips_64(ctx
);
14536 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14539 switch ((ctx
->opcode
>> 21) & 0x1f) {
14541 /* drotr is decoded as dsrl on non-R2 CPUs */
14542 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14547 check_insn(ctx
, ISA_MIPS3
);
14548 check_mips_64(ctx
);
14549 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14552 generate_exception(ctx
, EXCP_RI
);
14557 switch ((ctx
->opcode
>> 21) & 0x1f) {
14559 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14560 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14565 check_insn(ctx
, ISA_MIPS3
);
14566 check_mips_64(ctx
);
14567 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14570 generate_exception(ctx
, EXCP_RI
);
14574 case OPC_DADD
... OPC_DSUBU
:
14575 check_insn(ctx
, ISA_MIPS3
);
14576 check_mips_64(ctx
);
14577 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14581 check_insn(ctx
, ISA_MIPS3
);
14582 check_mips_64(ctx
);
14583 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14586 switch ((ctx
->opcode
>> 6) & 0x1f) {
14588 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14589 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14594 check_insn(ctx
, ISA_MIPS3
);
14595 check_mips_64(ctx
);
14596 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14599 generate_exception(ctx
, EXCP_RI
);
14603 case OPC_DMULT
... OPC_DDIVU
:
14604 check_insn(ctx
, ISA_MIPS3
);
14605 check_mips_64(ctx
);
14606 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14609 default: /* Invalid */
14610 MIPS_INVAL("special");
14611 generate_exception(ctx
, EXCP_RI
);
14616 op1
= MASK_SPECIAL2(ctx
->opcode
);
14618 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14619 case OPC_MSUB
... OPC_MSUBU
:
14620 check_insn(ctx
, ISA_MIPS32
);
14621 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14624 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14628 check_insn(ctx
, ISA_MIPS32
);
14629 gen_cl(ctx
, op1
, rd
, rs
);
14632 /* XXX: not clear which exception should be raised
14633 * when in debug mode...
14635 check_insn(ctx
, ISA_MIPS32
);
14636 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14637 generate_exception(ctx
, EXCP_DBp
);
14639 generate_exception(ctx
, EXCP_DBp
);
14641 /* Treat as NOP. */
14644 case OPC_DIVU_G_2F
:
14645 case OPC_MULT_G_2F
:
14646 case OPC_MULTU_G_2F
:
14648 case OPC_MODU_G_2F
:
14649 check_insn(ctx
, INSN_LOONGSON2F
);
14650 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14652 #if defined(TARGET_MIPS64)
14655 check_insn(ctx
, ISA_MIPS64
);
14656 check_mips_64(ctx
);
14657 gen_cl(ctx
, op1
, rd
, rs
);
14659 case OPC_DMULT_G_2F
:
14660 case OPC_DMULTU_G_2F
:
14661 case OPC_DDIV_G_2F
:
14662 case OPC_DDIVU_G_2F
:
14663 case OPC_DMOD_G_2F
:
14664 case OPC_DMODU_G_2F
:
14665 check_insn(ctx
, INSN_LOONGSON2F
);
14666 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14669 default: /* Invalid */
14670 MIPS_INVAL("special2");
14671 generate_exception(ctx
, EXCP_RI
);
14676 op1
= MASK_SPECIAL3(ctx
->opcode
);
14680 check_insn(ctx
, ISA_MIPS32R2
);
14681 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14684 check_insn(ctx
, ISA_MIPS32R2
);
14685 op2
= MASK_BSHFL(ctx
->opcode
);
14686 gen_bshfl(ctx
, op2
, rt
, rd
);
14689 gen_rdhwr(ctx
, rt
, rd
);
14692 check_insn(ctx
, ASE_MT
);
14694 TCGv t0
= tcg_temp_new();
14695 TCGv t1
= tcg_temp_new();
14697 gen_load_gpr(t0
, rt
);
14698 gen_load_gpr(t1
, rs
);
14699 gen_helper_fork(t0
, t1
);
14705 check_insn(ctx
, ASE_MT
);
14707 TCGv t0
= tcg_temp_new();
14709 save_cpu_state(ctx
, 1);
14710 gen_load_gpr(t0
, rs
);
14711 gen_helper_yield(t0
, cpu_env
, t0
);
14712 gen_store_gpr(t0
, rd
);
14716 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14717 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14718 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14719 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14720 * the same mask and op1. */
14721 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14722 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14725 case OPC_ADDUH_R_QB
:
14727 case OPC_ADDQH_R_PH
:
14729 case OPC_ADDQH_R_W
:
14731 case OPC_SUBUH_R_QB
:
14733 case OPC_SUBQH_R_PH
:
14735 case OPC_SUBQH_R_W
:
14736 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14741 case OPC_MULQ_RS_W
:
14742 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14745 MIPS_INVAL("MASK ADDUH.QB");
14746 generate_exception(ctx
, EXCP_RI
);
14749 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14750 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14752 generate_exception(ctx
, EXCP_RI
);
14756 op2
= MASK_LX(ctx
->opcode
);
14758 #if defined(TARGET_MIPS64)
14764 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14766 default: /* Invalid */
14767 MIPS_INVAL("MASK LX");
14768 generate_exception(ctx
, EXCP_RI
);
14772 case OPC_ABSQ_S_PH_DSP
:
14773 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14775 case OPC_ABSQ_S_QB
:
14776 case OPC_ABSQ_S_PH
:
14778 case OPC_PRECEQ_W_PHL
:
14779 case OPC_PRECEQ_W_PHR
:
14780 case OPC_PRECEQU_PH_QBL
:
14781 case OPC_PRECEQU_PH_QBR
:
14782 case OPC_PRECEQU_PH_QBLA
:
14783 case OPC_PRECEQU_PH_QBRA
:
14784 case OPC_PRECEU_PH_QBL
:
14785 case OPC_PRECEU_PH_QBR
:
14786 case OPC_PRECEU_PH_QBLA
:
14787 case OPC_PRECEU_PH_QBRA
:
14788 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14795 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14798 MIPS_INVAL("MASK ABSQ_S.PH");
14799 generate_exception(ctx
, EXCP_RI
);
14803 case OPC_ADDU_QB_DSP
:
14804 op2
= MASK_ADDU_QB(ctx
->opcode
);
14807 case OPC_ADDQ_S_PH
:
14810 case OPC_ADDU_S_QB
:
14812 case OPC_ADDU_S_PH
:
14814 case OPC_SUBQ_S_PH
:
14817 case OPC_SUBU_S_QB
:
14819 case OPC_SUBU_S_PH
:
14823 case OPC_RADDU_W_QB
:
14824 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14826 case OPC_MULEU_S_PH_QBL
:
14827 case OPC_MULEU_S_PH_QBR
:
14828 case OPC_MULQ_RS_PH
:
14829 case OPC_MULEQ_S_W_PHL
:
14830 case OPC_MULEQ_S_W_PHR
:
14831 case OPC_MULQ_S_PH
:
14832 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14834 default: /* Invalid */
14835 MIPS_INVAL("MASK ADDU.QB");
14836 generate_exception(ctx
, EXCP_RI
);
14841 case OPC_CMPU_EQ_QB_DSP
:
14842 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14844 case OPC_PRECR_SRA_PH_W
:
14845 case OPC_PRECR_SRA_R_PH_W
:
14846 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14848 case OPC_PRECR_QB_PH
:
14849 case OPC_PRECRQ_QB_PH
:
14850 case OPC_PRECRQ_PH_W
:
14851 case OPC_PRECRQ_RS_PH_W
:
14852 case OPC_PRECRQU_S_QB_PH
:
14853 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14855 case OPC_CMPU_EQ_QB
:
14856 case OPC_CMPU_LT_QB
:
14857 case OPC_CMPU_LE_QB
:
14858 case OPC_CMP_EQ_PH
:
14859 case OPC_CMP_LT_PH
:
14860 case OPC_CMP_LE_PH
:
14861 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14863 case OPC_CMPGU_EQ_QB
:
14864 case OPC_CMPGU_LT_QB
:
14865 case OPC_CMPGU_LE_QB
:
14866 case OPC_CMPGDU_EQ_QB
:
14867 case OPC_CMPGDU_LT_QB
:
14868 case OPC_CMPGDU_LE_QB
:
14871 case OPC_PACKRL_PH
:
14872 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14874 default: /* Invalid */
14875 MIPS_INVAL("MASK CMPU.EQ.QB");
14876 generate_exception(ctx
, EXCP_RI
);
14880 case OPC_SHLL_QB_DSP
:
14881 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14883 case OPC_DPA_W_PH_DSP
:
14884 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14886 case OPC_DPAU_H_QBL
:
14887 case OPC_DPAU_H_QBR
:
14888 case OPC_DPSU_H_QBL
:
14889 case OPC_DPSU_H_QBR
:
14891 case OPC_DPAX_W_PH
:
14892 case OPC_DPAQ_S_W_PH
:
14893 case OPC_DPAQX_S_W_PH
:
14894 case OPC_DPAQX_SA_W_PH
:
14896 case OPC_DPSX_W_PH
:
14897 case OPC_DPSQ_S_W_PH
:
14898 case OPC_DPSQX_S_W_PH
:
14899 case OPC_DPSQX_SA_W_PH
:
14900 case OPC_MULSAQ_S_W_PH
:
14901 case OPC_DPAQ_SA_L_W
:
14902 case OPC_DPSQ_SA_L_W
:
14903 case OPC_MAQ_S_W_PHL
:
14904 case OPC_MAQ_S_W_PHR
:
14905 case OPC_MAQ_SA_W_PHL
:
14906 case OPC_MAQ_SA_W_PHR
:
14907 case OPC_MULSA_W_PH
:
14908 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14910 default: /* Invalid */
14911 MIPS_INVAL("MASK DPAW.PH");
14912 generate_exception(ctx
, EXCP_RI
);
14917 op2
= MASK_INSV(ctx
->opcode
);
14929 t0
= tcg_temp_new();
14930 t1
= tcg_temp_new();
14932 gen_load_gpr(t0
, rt
);
14933 gen_load_gpr(t1
, rs
);
14935 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
14941 default: /* Invalid */
14942 MIPS_INVAL("MASK INSV");
14943 generate_exception(ctx
, EXCP_RI
);
14947 case OPC_APPEND_DSP
:
14948 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
14950 case OPC_EXTR_W_DSP
:
14951 op2
= MASK_EXTR_W(ctx
->opcode
);
14955 case OPC_EXTR_RS_W
:
14957 case OPC_EXTRV_S_H
:
14959 case OPC_EXTRV_R_W
:
14960 case OPC_EXTRV_RS_W
:
14965 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
14968 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14974 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14976 default: /* Invalid */
14977 MIPS_INVAL("MASK EXTR.W");
14978 generate_exception(ctx
, EXCP_RI
);
14982 #if defined(TARGET_MIPS64)
14983 case OPC_DEXTM
... OPC_DEXT
:
14984 case OPC_DINSM
... OPC_DINS
:
14985 check_insn(ctx
, ISA_MIPS64R2
);
14986 check_mips_64(ctx
);
14987 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14990 check_insn(ctx
, ISA_MIPS64R2
);
14991 check_mips_64(ctx
);
14992 op2
= MASK_DBSHFL(ctx
->opcode
);
14993 gen_bshfl(ctx
, op2
, rt
, rd
);
14995 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
14996 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
14997 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
14998 check_insn(ctx
, INSN_LOONGSON2E
);
14999 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
15001 case OPC_ABSQ_S_QH_DSP
:
15002 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
15004 case OPC_PRECEQ_L_PWL
:
15005 case OPC_PRECEQ_L_PWR
:
15006 case OPC_PRECEQ_PW_QHL
:
15007 case OPC_PRECEQ_PW_QHR
:
15008 case OPC_PRECEQ_PW_QHLA
:
15009 case OPC_PRECEQ_PW_QHRA
:
15010 case OPC_PRECEQU_QH_OBL
:
15011 case OPC_PRECEQU_QH_OBR
:
15012 case OPC_PRECEQU_QH_OBLA
:
15013 case OPC_PRECEQU_QH_OBRA
:
15014 case OPC_PRECEU_QH_OBL
:
15015 case OPC_PRECEU_QH_OBR
:
15016 case OPC_PRECEU_QH_OBLA
:
15017 case OPC_PRECEU_QH_OBRA
:
15018 case OPC_ABSQ_S_OB
:
15019 case OPC_ABSQ_S_PW
:
15020 case OPC_ABSQ_S_QH
:
15021 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15029 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
15031 default: /* Invalid */
15032 MIPS_INVAL("MASK ABSQ_S.QH");
15033 generate_exception(ctx
, EXCP_RI
);
15037 case OPC_ADDU_OB_DSP
:
15038 op2
= MASK_ADDU_OB(ctx
->opcode
);
15040 case OPC_RADDU_L_OB
:
15042 case OPC_SUBQ_S_PW
:
15044 case OPC_SUBQ_S_QH
:
15046 case OPC_SUBU_S_OB
:
15048 case OPC_SUBU_S_QH
:
15050 case OPC_SUBUH_R_OB
:
15052 case OPC_ADDQ_S_PW
:
15054 case OPC_ADDQ_S_QH
:
15056 case OPC_ADDU_S_OB
:
15058 case OPC_ADDU_S_QH
:
15060 case OPC_ADDUH_R_OB
:
15061 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15063 case OPC_MULEQ_S_PW_QHL
:
15064 case OPC_MULEQ_S_PW_QHR
:
15065 case OPC_MULEU_S_QH_OBL
:
15066 case OPC_MULEU_S_QH_OBR
:
15067 case OPC_MULQ_RS_QH
:
15068 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15070 default: /* Invalid */
15071 MIPS_INVAL("MASK ADDU.OB");
15072 generate_exception(ctx
, EXCP_RI
);
15076 case OPC_CMPU_EQ_OB_DSP
:
15077 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15079 case OPC_PRECR_SRA_QH_PW
:
15080 case OPC_PRECR_SRA_R_QH_PW
:
15081 /* Return value is rt. */
15082 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15084 case OPC_PRECR_OB_QH
:
15085 case OPC_PRECRQ_OB_QH
:
15086 case OPC_PRECRQ_PW_L
:
15087 case OPC_PRECRQ_QH_PW
:
15088 case OPC_PRECRQ_RS_QH_PW
:
15089 case OPC_PRECRQU_S_OB_QH
:
15090 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15092 case OPC_CMPU_EQ_OB
:
15093 case OPC_CMPU_LT_OB
:
15094 case OPC_CMPU_LE_OB
:
15095 case OPC_CMP_EQ_QH
:
15096 case OPC_CMP_LT_QH
:
15097 case OPC_CMP_LE_QH
:
15098 case OPC_CMP_EQ_PW
:
15099 case OPC_CMP_LT_PW
:
15100 case OPC_CMP_LE_PW
:
15101 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15103 case OPC_CMPGDU_EQ_OB
:
15104 case OPC_CMPGDU_LT_OB
:
15105 case OPC_CMPGDU_LE_OB
:
15106 case OPC_CMPGU_EQ_OB
:
15107 case OPC_CMPGU_LT_OB
:
15108 case OPC_CMPGU_LE_OB
:
15109 case OPC_PACKRL_PW
:
15113 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15115 default: /* Invalid */
15116 MIPS_INVAL("MASK CMPU_EQ.OB");
15117 generate_exception(ctx
, EXCP_RI
);
15121 case OPC_DAPPEND_DSP
:
15122 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15124 case OPC_DEXTR_W_DSP
:
15125 op2
= MASK_DEXTR_W(ctx
->opcode
);
15132 case OPC_DEXTR_R_L
:
15133 case OPC_DEXTR_RS_L
:
15135 case OPC_DEXTR_R_W
:
15136 case OPC_DEXTR_RS_W
:
15137 case OPC_DEXTR_S_H
:
15139 case OPC_DEXTRV_R_L
:
15140 case OPC_DEXTRV_RS_L
:
15141 case OPC_DEXTRV_S_H
:
15143 case OPC_DEXTRV_R_W
:
15144 case OPC_DEXTRV_RS_W
:
15145 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15150 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15152 default: /* Invalid */
15153 MIPS_INVAL("MASK EXTR.W");
15154 generate_exception(ctx
, EXCP_RI
);
15158 case OPC_DPAQ_W_QH_DSP
:
15159 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15161 case OPC_DPAU_H_OBL
:
15162 case OPC_DPAU_H_OBR
:
15163 case OPC_DPSU_H_OBL
:
15164 case OPC_DPSU_H_OBR
:
15166 case OPC_DPAQ_S_W_QH
:
15168 case OPC_DPSQ_S_W_QH
:
15169 case OPC_MULSAQ_S_W_QH
:
15170 case OPC_DPAQ_SA_L_PW
:
15171 case OPC_DPSQ_SA_L_PW
:
15172 case OPC_MULSAQ_S_L_PW
:
15173 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15175 case OPC_MAQ_S_W_QHLL
:
15176 case OPC_MAQ_S_W_QHLR
:
15177 case OPC_MAQ_S_W_QHRL
:
15178 case OPC_MAQ_S_W_QHRR
:
15179 case OPC_MAQ_SA_W_QHLL
:
15180 case OPC_MAQ_SA_W_QHLR
:
15181 case OPC_MAQ_SA_W_QHRL
:
15182 case OPC_MAQ_SA_W_QHRR
:
15183 case OPC_MAQ_S_L_PWL
:
15184 case OPC_MAQ_S_L_PWR
:
15189 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15191 default: /* Invalid */
15192 MIPS_INVAL("MASK DPAQ.W.QH");
15193 generate_exception(ctx
, EXCP_RI
);
15197 case OPC_DINSV_DSP
:
15198 op2
= MASK_INSV(ctx
->opcode
);
15210 t0
= tcg_temp_new();
15211 t1
= tcg_temp_new();
15213 gen_load_gpr(t0
, rt
);
15214 gen_load_gpr(t1
, rs
);
15216 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15219 default: /* Invalid */
15220 MIPS_INVAL("MASK DINSV");
15221 generate_exception(ctx
, EXCP_RI
);
15225 case OPC_SHLL_OB_DSP
:
15226 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15229 default: /* Invalid */
15230 MIPS_INVAL("special3");
15231 generate_exception(ctx
, EXCP_RI
);
15236 op1
= MASK_REGIMM(ctx
->opcode
);
15238 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15239 case OPC_BLTZAL
... OPC_BGEZALL
:
15240 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15242 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15244 gen_trap(ctx
, op1
, rs
, -1, imm
);
15247 check_insn(ctx
, ISA_MIPS32R2
);
15248 /* Treat as NOP. */
15250 case OPC_BPOSGE32
: /* MIPS DSP branch */
15251 #if defined(TARGET_MIPS64)
15255 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15257 default: /* Invalid */
15258 MIPS_INVAL("regimm");
15259 generate_exception(ctx
, EXCP_RI
);
15264 check_cp0_enabled(ctx
);
15265 op1
= MASK_CP0(ctx
->opcode
);
15271 #if defined(TARGET_MIPS64)
15275 #ifndef CONFIG_USER_ONLY
15276 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15277 #endif /* !CONFIG_USER_ONLY */
15279 case OPC_C0_FIRST
... OPC_C0_LAST
:
15280 #ifndef CONFIG_USER_ONLY
15281 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15282 #endif /* !CONFIG_USER_ONLY */
15285 #ifndef CONFIG_USER_ONLY
15287 TCGv t0
= tcg_temp_new();
15289 op2
= MASK_MFMC0(ctx
->opcode
);
15292 check_insn(ctx
, ASE_MT
);
15293 gen_helper_dmt(t0
);
15294 gen_store_gpr(t0
, rt
);
15297 check_insn(ctx
, ASE_MT
);
15298 gen_helper_emt(t0
);
15299 gen_store_gpr(t0
, rt
);
15302 check_insn(ctx
, ASE_MT
);
15303 gen_helper_dvpe(t0
, cpu_env
);
15304 gen_store_gpr(t0
, rt
);
15307 check_insn(ctx
, ASE_MT
);
15308 gen_helper_evpe(t0
, cpu_env
);
15309 gen_store_gpr(t0
, rt
);
15312 check_insn(ctx
, ISA_MIPS32R2
);
15313 save_cpu_state(ctx
, 1);
15314 gen_helper_di(t0
, cpu_env
);
15315 gen_store_gpr(t0
, rt
);
15316 /* Stop translation as we may have switched the execution mode */
15317 ctx
->bstate
= BS_STOP
;
15320 check_insn(ctx
, ISA_MIPS32R2
);
15321 save_cpu_state(ctx
, 1);
15322 gen_helper_ei(t0
, cpu_env
);
15323 gen_store_gpr(t0
, rt
);
15324 /* Stop translation as we may have switched the execution mode */
15325 ctx
->bstate
= BS_STOP
;
15327 default: /* Invalid */
15328 MIPS_INVAL("mfmc0");
15329 generate_exception(ctx
, EXCP_RI
);
15334 #endif /* !CONFIG_USER_ONLY */
15337 check_insn(ctx
, ISA_MIPS32R2
);
15338 gen_load_srsgpr(rt
, rd
);
15341 check_insn(ctx
, ISA_MIPS32R2
);
15342 gen_store_srsgpr(rt
, rd
);
15346 generate_exception(ctx
, EXCP_RI
);
15350 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15352 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15354 case OPC_SLTI
: /* Set on less than with immediate opcode */
15356 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15358 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15362 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15364 case OPC_J
... OPC_JAL
: /* Jump */
15365 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15366 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15368 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15369 case OPC_BEQL
... OPC_BGTZL
:
15370 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15372 case OPC_LB
... OPC_LWR
: /* Load and stores */
15374 gen_ld(ctx
, op
, rt
, rs
, imm
);
15376 case OPC_SB
... OPC_SW
:
15378 gen_st(ctx
, op
, rt
, rs
, imm
);
15381 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15384 check_cp0_enabled(ctx
);
15385 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15386 /* Treat as NOP. */
15389 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15390 /* Treat as NOP. */
15393 /* Floating point (COP1). */
15398 gen_cop1_ldst(env
, ctx
, op
, rt
, rs
, imm
);
15402 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15403 check_cp1_enabled(ctx
);
15404 op1
= MASK_CP1(ctx
->opcode
);
15408 check_insn(ctx
, ISA_MIPS32R2
);
15413 gen_cp1(ctx
, op1
, rt
, rd
);
15415 #if defined(TARGET_MIPS64)
15418 check_insn(ctx
, ISA_MIPS3
);
15419 gen_cp1(ctx
, op1
, rt
, rd
);
15425 check_insn(ctx
, ASE_MIPS3D
);
15428 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15429 (rt
>> 2) & 0x7, imm
<< 2);
15436 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15441 generate_exception (ctx
, EXCP_RI
);
15445 generate_exception_err(ctx
, EXCP_CpU
, 1);
15454 /* COP2: Not implemented. */
15455 generate_exception_err(ctx
, EXCP_CpU
, 2);
15458 check_insn(ctx
, INSN_LOONGSON2F
);
15459 /* Note that these instructions use different fields. */
15460 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15464 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15465 check_cp1_enabled(ctx
);
15466 op1
= MASK_CP3(ctx
->opcode
);
15474 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15477 /* Treat as NOP. */
15492 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15496 generate_exception (ctx
, EXCP_RI
);
15500 generate_exception_err(ctx
, EXCP_CpU
, 1);
15504 #if defined(TARGET_MIPS64)
15505 /* MIPS64 opcodes */
15507 case OPC_LDL
... OPC_LDR
:
15510 check_insn(ctx
, ISA_MIPS3
);
15511 check_mips_64(ctx
);
15512 gen_ld(ctx
, op
, rt
, rs
, imm
);
15514 case OPC_SDL
... OPC_SDR
:
15516 check_insn(ctx
, ISA_MIPS3
);
15517 check_mips_64(ctx
);
15518 gen_st(ctx
, op
, rt
, rs
, imm
);
15521 check_insn(ctx
, ISA_MIPS3
);
15522 check_mips_64(ctx
);
15523 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15527 check_insn(ctx
, ISA_MIPS3
);
15528 check_mips_64(ctx
);
15529 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15533 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15534 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15535 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15538 check_insn(ctx
, ASE_MDMX
);
15539 /* MDMX: Not implemented. */
15540 default: /* Invalid */
15541 MIPS_INVAL("major opcode");
15542 generate_exception(ctx
, EXCP_RI
);
15548 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
15551 CPUState
*cs
= CPU(cpu
);
15552 CPUMIPSState
*env
= &cpu
->env
;
15554 target_ulong pc_start
;
15555 uint16_t *gen_opc_end
;
15564 qemu_log("search pc %d\n", search_pc
);
15567 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15570 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
15571 ctx
.insn_flags
= env
->insn_flags
;
15573 ctx
.bstate
= BS_NONE
;
15574 /* Restore delay slot state from the tb context. */
15575 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15576 restore_cpu_state(env
, &ctx
);
15577 #ifdef CONFIG_USER_ONLY
15578 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15580 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15583 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15584 if (max_insns
== 0)
15585 max_insns
= CF_COUNT_MASK
;
15586 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15588 while (ctx
.bstate
== BS_NONE
) {
15589 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
15590 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
15591 if (bp
->pc
== ctx
.pc
) {
15592 save_cpu_state(&ctx
, 1);
15593 ctx
.bstate
= BS_BRANCH
;
15594 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15595 /* Include the breakpoint location or the tb won't
15596 * be flushed when it must be. */
15598 goto done_generating
;
15604 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15608 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15610 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15611 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15612 gen_opc_btarget
[lj
] = ctx
.btarget
;
15613 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15614 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15616 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15619 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
15620 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15621 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15623 decode_opc(env
, &ctx
);
15624 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15625 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15626 insn_bytes
= decode_micromips_opc(env
, &ctx
);
15627 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15628 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15629 insn_bytes
= decode_mips16_opc(env
, &ctx
);
15631 generate_exception(&ctx
, EXCP_RI
);
15632 ctx
.bstate
= BS_STOP
;
15636 handle_delay_slot(&ctx
, insn_bytes
);
15638 ctx
.pc
+= insn_bytes
;
15642 /* Execute a branch and its delay slot as a single instruction.
15643 This is what GDB expects and is consistent with what the
15644 hardware does (e.g. if a delay slot instruction faults, the
15645 reported PC is the PC of the branch). */
15646 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
15650 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15653 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15657 if (num_insns
>= max_insns
)
15663 if (tb
->cflags
& CF_LAST_IO
) {
15666 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15667 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15668 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15670 switch (ctx
.bstate
) {
15672 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15675 save_cpu_state(&ctx
, 0);
15676 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15679 tcg_gen_exit_tb(0);
15687 gen_tb_end(tb
, num_insns
);
15688 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15690 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15693 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15695 tb
->size
= ctx
.pc
- pc_start
;
15696 tb
->icount
= num_insns
;
15700 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15701 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15702 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15708 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15710 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
15713 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15715 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
15718 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15722 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15724 #define printfpr(fp) \
15727 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15728 " fd:%13g fs:%13g psu: %13g\n", \
15729 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15730 (double)(fp)->fd, \
15731 (double)(fp)->fs[FP_ENDIAN_IDX], \
15732 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15735 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15736 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15737 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15738 " fd:%13g fs:%13g psu:%13g\n", \
15739 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15741 (double)tmp.fs[FP_ENDIAN_IDX], \
15742 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15747 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15748 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15749 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15750 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15751 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15752 printfpr(&env
->active_fpu
.fpr
[i
]);
15758 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15759 /* Debug help: The architecture requires 32bit code to maintain proper
15760 sign-extended values on 64bit machines. */
15762 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15765 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15766 fprintf_function cpu_fprintf
,
15771 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15772 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15773 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15774 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15775 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15776 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15777 if (!SIGN_EXT_P(env
->btarget
))
15778 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15780 for (i
= 0; i
< 32; i
++) {
15781 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15782 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15785 if (!SIGN_EXT_P(env
->CP0_EPC
))
15786 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15787 if (!SIGN_EXT_P(env
->lladdr
))
15788 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15792 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
15795 MIPSCPU
*cpu
= MIPS_CPU(cs
);
15796 CPUMIPSState
*env
= &cpu
->env
;
15799 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15800 " LO=0x" TARGET_FMT_lx
" ds %04x "
15801 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15802 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15803 env
->hflags
, env
->btarget
, env
->bcond
);
15804 for (i
= 0; i
< 32; i
++) {
15806 cpu_fprintf(f
, "GPR%02d:", i
);
15807 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15809 cpu_fprintf(f
, "\n");
15812 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15813 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15814 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15815 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15816 if (env
->hflags
& MIPS_HFLAG_FPU
)
15817 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15818 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15819 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15823 void mips_tcg_init(void)
15828 /* Initialize various static tables. */
15832 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15833 TCGV_UNUSED(cpu_gpr
[0]);
15834 for (i
= 1; i
< 32; i
++)
15835 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15836 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15839 for (i
= 0; i
< 32; i
++) {
15840 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15841 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15844 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15845 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15846 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15847 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15848 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15850 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15851 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15853 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15854 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15857 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15858 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15860 bcond
= tcg_global_mem_new(TCG_AREG0
,
15861 offsetof(CPUMIPSState
, bcond
), "bcond");
15862 btarget
= tcg_global_mem_new(TCG_AREG0
,
15863 offsetof(CPUMIPSState
, btarget
), "btarget");
15864 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15865 offsetof(CPUMIPSState
, hflags
), "hflags");
15867 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15868 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15870 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15871 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15877 #include "translate_init.c"
15879 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15883 const mips_def_t
*def
;
15885 def
= cpu_mips_find_by_name(cpu_model
);
15888 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15890 env
->cpu_model
= def
;
15892 #ifndef CONFIG_USER_ONLY
15893 mmu_init(env
, def
);
15895 fpu_init(env
, def
);
15896 mvp_init(env
, def
);
15898 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15903 void cpu_state_reset(CPUMIPSState
*env
)
15905 #ifndef CONFIG_USER_ONLY
15906 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
15907 CPUState
*cs
= CPU(cpu
);
15910 /* Reset registers to their default values */
15911 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15912 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15913 #ifdef TARGET_WORDS_BIGENDIAN
15914 env
->CP0_Config0
|= (1 << CP0C0_BE
);
15916 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
15917 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
15918 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
15919 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
15920 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
15921 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
15922 << env
->cpu_model
->CP0_LLAddr_shift
;
15923 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
15924 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
15925 env
->CCRes
= env
->cpu_model
->CCRes
;
15926 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
15927 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
15928 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
15929 env
->current_tc
= 0;
15930 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
15931 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
15932 #if defined(TARGET_MIPS64)
15933 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
15934 env
->SEGMask
|= 3ULL << 62;
15937 env
->PABITS
= env
->cpu_model
->PABITS
;
15938 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
15939 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
15940 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
15941 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
15942 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
15943 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
15944 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
15945 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
15946 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
15947 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
15948 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
15949 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
15950 env
->insn_flags
= env
->cpu_model
->insn_flags
;
15952 #if defined(CONFIG_USER_ONLY)
15953 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
15954 # ifdef TARGET_MIPS64
15955 /* Enable 64-bit register mode. */
15956 env
->CP0_Status
|= (1 << CP0St_PX
);
15958 # ifdef TARGET_ABI_MIPSN64
15959 /* Enable 64-bit address mode. */
15960 env
->CP0_Status
|= (1 << CP0St_UX
);
15962 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15963 hardware registers. */
15964 env
->CP0_HWREna
|= 0x0000000F;
15965 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15966 env
->CP0_Status
|= (1 << CP0St_CU1
);
15968 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
15969 env
->CP0_Status
|= (1 << CP0St_MX
);
15971 # if defined(TARGET_MIPS64)
15972 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
15973 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
15974 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
15975 env
->CP0_Status
|= (1 << CP0St_FR
);
15979 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
15980 /* If the exception was raised from a delay slot,
15981 come back to the jump. */
15982 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
15984 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
15986 env
->active_tc
.PC
= (int32_t)0xBFC00000;
15987 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
15988 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
15989 env
->CP0_Wired
= 0;
15990 env
->CP0_EBase
= 0x80000000 | (cs
->cpu_index
& 0x3FF);
15991 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
15992 /* vectored interrupts not implemented, timer on int 7,
15993 no performance counters. */
15994 env
->CP0_IntCtl
= 0xe0000000;
15998 for (i
= 0; i
< 7; i
++) {
15999 env
->CP0_WatchLo
[i
] = 0;
16000 env
->CP0_WatchHi
[i
] = 0x80000000;
16002 env
->CP0_WatchLo
[7] = 0;
16003 env
->CP0_WatchHi
[7] = 0;
16005 /* Count register increments in debug mode, EJTAG version 1 */
16006 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
16008 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
16011 /* Only TC0 on VPE 0 starts as active. */
16012 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
16013 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
16014 env
->tcs
[i
].CP0_TCHalt
= 1;
16016 env
->active_tc
.CP0_TCHalt
= 1;
16019 if (cs
->cpu_index
== 0) {
16020 /* VPE0 starts up enabled. */
16021 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
16022 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
16024 /* TC0 starts up unhalted. */
16026 env
->active_tc
.CP0_TCHalt
= 0;
16027 env
->tcs
[0].CP0_TCHalt
= 0;
16028 /* With thread 0 active. */
16029 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
16030 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16034 compute_hflags(env
);
16035 env
->exception_index
= EXCP_NONE
;
16038 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16040 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16041 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16042 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16043 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16044 case MIPS_HFLAG_BR
:
16046 case MIPS_HFLAG_BC
:
16047 case MIPS_HFLAG_BL
:
16049 env
->btarget
= gen_opc_btarget
[pc_pos
];