2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "disas/disas.h"
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
39 /* indirect opcode tables */
40 OPC_SPECIAL
= (0x00 << 26),
41 OPC_REGIMM
= (0x01 << 26),
42 OPC_CP0
= (0x10 << 26),
43 OPC_CP1
= (0x11 << 26),
44 OPC_CP2
= (0x12 << 26),
45 OPC_CP3
= (0x13 << 26),
46 OPC_SPECIAL2
= (0x1C << 26),
47 OPC_SPECIAL3
= (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI
= (0x08 << 26),
50 OPC_ADDIU
= (0x09 << 26),
51 OPC_SLTI
= (0x0A << 26),
52 OPC_SLTIU
= (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI
= (0x0C << 26),
55 OPC_ORI
= (0x0D << 26),
56 OPC_XORI
= (0x0E << 26),
57 OPC_LUI
= (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI
= (0x18 << 26),
60 OPC_DADDIU
= (0x19 << 26),
61 /* Jump and branches */
63 OPC_JAL
= (0x03 << 26),
64 OPC_JALS
= OPC_JAL
| 0x5,
65 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL
= (0x14 << 26),
67 OPC_BNE
= (0x05 << 26),
68 OPC_BNEL
= (0x15 << 26),
69 OPC_BLEZ
= (0x06 << 26),
70 OPC_BLEZL
= (0x16 << 26),
71 OPC_BGTZ
= (0x07 << 26),
72 OPC_BGTZL
= (0x17 << 26),
73 OPC_JALX
= (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS
= OPC_JALX
| 0x5,
76 OPC_LDL
= (0x1A << 26),
77 OPC_LDR
= (0x1B << 26),
78 OPC_LB
= (0x20 << 26),
79 OPC_LH
= (0x21 << 26),
80 OPC_LWL
= (0x22 << 26),
81 OPC_LW
= (0x23 << 26),
82 OPC_LWPC
= OPC_LW
| 0x5,
83 OPC_LBU
= (0x24 << 26),
84 OPC_LHU
= (0x25 << 26),
85 OPC_LWR
= (0x26 << 26),
86 OPC_LWU
= (0x27 << 26),
87 OPC_SB
= (0x28 << 26),
88 OPC_SH
= (0x29 << 26),
89 OPC_SWL
= (0x2A << 26),
90 OPC_SW
= (0x2B << 26),
91 OPC_SDL
= (0x2C << 26),
92 OPC_SDR
= (0x2D << 26),
93 OPC_SWR
= (0x2E << 26),
94 OPC_LL
= (0x30 << 26),
95 OPC_LLD
= (0x34 << 26),
96 OPC_LD
= (0x37 << 26),
97 OPC_LDPC
= OPC_LD
| 0x5,
98 OPC_SC
= (0x38 << 26),
99 OPC_SCD
= (0x3C << 26),
100 OPC_SD
= (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1
= (0x31 << 26),
103 OPC_LWC2
= (0x32 << 26),
104 OPC_LDC1
= (0x35 << 26),
105 OPC_LDC2
= (0x36 << 26),
106 OPC_SWC1
= (0x39 << 26),
107 OPC_SWC2
= (0x3A << 26),
108 OPC_SDC1
= (0x3D << 26),
109 OPC_SDC2
= (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX
= (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE
= (0x2F << 26),
114 OPC_PREF
= (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED
= (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124 OPC_SLL
= 0x00 | OPC_SPECIAL
,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
129 OPC_ROTR
= OPC_SRL
| (1 << 21),
130 OPC_SRA
= 0x03 | OPC_SPECIAL
,
131 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
132 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
133 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
134 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
135 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
136 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
137 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
138 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
139 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
140 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
141 OPC_DROTR
= OPC_DSRL
| (1 << 21),
142 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
143 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
144 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
145 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
146 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
147 /* Multiplication / division */
148 OPC_MULT
= 0x18 | OPC_SPECIAL
,
149 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
150 OPC_DIV
= 0x1A | OPC_SPECIAL
,
151 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
152 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
153 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
154 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
155 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD
= 0x20 | OPC_SPECIAL
,
158 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
159 OPC_SUB
= 0x22 | OPC_SPECIAL
,
160 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
161 OPC_AND
= 0x24 | OPC_SPECIAL
,
162 OPC_OR
= 0x25 | OPC_SPECIAL
,
163 OPC_XOR
= 0x26 | OPC_SPECIAL
,
164 OPC_NOR
= 0x27 | OPC_SPECIAL
,
165 OPC_SLT
= 0x2A | OPC_SPECIAL
,
166 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
167 OPC_DADD
= 0x2C | OPC_SPECIAL
,
168 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
169 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
170 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
172 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
173 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
174 OPC_JALRC
= OPC_JALR
| (0x5 << 6),
175 OPC_JALRS
= 0x10 | OPC_SPECIAL
| (0x5 << 6),
177 OPC_TGE
= 0x30 | OPC_SPECIAL
,
178 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
179 OPC_TLT
= 0x32 | OPC_SPECIAL
,
180 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
181 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
182 OPC_TNE
= 0x36 | OPC_SPECIAL
,
183 /* HI / LO registers load & stores */
184 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
185 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
186 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
187 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
188 /* Conditional moves */
189 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
190 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
192 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
195 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
196 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
197 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
198 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
199 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
201 OPC_SPECIAL15_RESERVED
= 0x15 | OPC_SPECIAL
,
202 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
203 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
204 OPC_SPECIAL35_RESERVED
= 0x35 | OPC_SPECIAL
,
205 OPC_SPECIAL37_RESERVED
= 0x37 | OPC_SPECIAL
,
206 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
207 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
214 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
215 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
216 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
217 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
218 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
219 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
220 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
221 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
222 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
223 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
224 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
225 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
226 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
227 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
234 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
235 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
236 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
237 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
238 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
239 OPC_BLTZALS
= OPC_BLTZAL
| 0x5, /* microMIPS */
240 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
241 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
242 OPC_BGEZALS
= OPC_BGEZAL
| 0x5, /* microMIPS */
243 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
244 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
245 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
246 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
247 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
248 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
249 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
250 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
257 /* Multiply & xxx operations */
258 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
259 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
260 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
261 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
262 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
264 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
265 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
266 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
267 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
268 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
269 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
270 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
271 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
272 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
273 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
274 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
275 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
277 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
278 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
279 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
280 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
282 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
289 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
290 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
291 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
292 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
293 OPC_INS
= 0x04 | OPC_SPECIAL3
,
294 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
295 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
296 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
297 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
298 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
299 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
300 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
301 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
304 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
305 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
306 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
307 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
308 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
309 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
310 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
311 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
312 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
313 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
314 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
315 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
318 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
321 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
322 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
323 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
327 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
330 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
335 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
338 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
339 /* MIPS DSP Append Sub-class */
340 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
341 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
344 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
352 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
353 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
361 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
367 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
374 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
375 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
376 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
383 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
384 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
385 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
386 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
387 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
388 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
389 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
390 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
391 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
392 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
393 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
394 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
395 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
396 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
397 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
398 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
399 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
402 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
403 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
404 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
405 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
406 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
414 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
415 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
416 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
417 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
418 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
419 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
420 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
421 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
422 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
423 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
424 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
427 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
428 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
429 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
436 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
437 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
438 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
439 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
440 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
441 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
442 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
443 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
444 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
445 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
446 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
447 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
450 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
451 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
452 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
453 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
460 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
461 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
462 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
463 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
464 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
465 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
468 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
469 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
470 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
471 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
472 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
473 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
474 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
475 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
476 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
477 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
478 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
479 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
480 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
481 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
488 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
489 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
490 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
491 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
492 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
493 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
494 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
495 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
496 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
497 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
498 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
499 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
500 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
501 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
502 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
503 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
504 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
505 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
506 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
507 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
508 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
515 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
516 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
517 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
518 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
519 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
520 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
521 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
522 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
523 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
524 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
525 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
526 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
527 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
528 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
529 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
530 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
531 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
532 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
533 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
534 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
535 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Append Sub-class */
547 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
548 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
549 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
556 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
557 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
558 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
559 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
560 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
561 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
562 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
563 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
564 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
565 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
566 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
567 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
568 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
569 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
570 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
571 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
578 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
579 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
580 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
581 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
582 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
583 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
584 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
585 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
586 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
587 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
588 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
589 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
590 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
591 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
592 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
593 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
596 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
597 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
598 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
599 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
600 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
607 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
608 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
609 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
610 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
613 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
614 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
615 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
616 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
617 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
618 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
619 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
620 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
621 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
622 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
623 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
624 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
625 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
626 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
627 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
628 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
629 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
630 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
631 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
632 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
639 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
640 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
641 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
642 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
643 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
644 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
645 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
646 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
647 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
648 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
649 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
650 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
651 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
652 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
653 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
654 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
655 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
656 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
659 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
660 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
661 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
662 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
663 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
664 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
665 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Append Sub-class */
671 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
672 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
673 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
674 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
681 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
682 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
683 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
684 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
685 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
686 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
687 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
688 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
689 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
690 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
691 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
692 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
693 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
694 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
695 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
696 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
697 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
698 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
699 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
700 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
713 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
714 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
715 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
716 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
717 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
718 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
719 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
720 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
721 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
722 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
723 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
724 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
725 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
726 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
727 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
728 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
729 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
730 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
731 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
732 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
733 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
734 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
735 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
736 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
737 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
744 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
745 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
746 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
747 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
748 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
749 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
750 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
751 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
752 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
753 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
754 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
755 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
756 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
757 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
758 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
759 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
760 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
761 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
762 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
763 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
764 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
765 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
766 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
767 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
768 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
776 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
777 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
778 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
779 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
780 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
781 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
782 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
783 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
784 OPC_C0
= (0x10 << 21) | OPC_CP0
,
785 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
786 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
794 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
795 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
796 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
797 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
798 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR
= 0x01 | OPC_C0
,
806 OPC_TLBWI
= 0x02 | OPC_C0
,
807 OPC_TLBWR
= 0x06 | OPC_C0
,
808 OPC_TLBP
= 0x08 | OPC_C0
,
809 OPC_RFE
= 0x10 | OPC_C0
,
810 OPC_ERET
= 0x18 | OPC_C0
,
811 OPC_DERET
= 0x1F | OPC_C0
,
812 OPC_WAIT
= 0x20 | OPC_C0
,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S
= 16, /* single fp */
822 FMT_D
= 17, /* double fp */
823 FMT_E
= 18, /* extended fp */
824 FMT_Q
= 19, /* quad fp */
825 FMT_W
= 20, /* 32-bit fixed */
826 FMT_L
= 21, /* 64-bit fixed */
827 FMT_PS
= 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
833 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
834 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
835 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
836 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
837 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
838 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
839 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
840 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
841 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
842 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
843 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
844 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
845 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
846 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
847 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
848 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
849 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
857 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
858 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
859 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
863 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
864 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
868 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
869 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
876 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
877 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
878 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
879 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
880 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
881 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
882 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
883 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
890 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
891 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
892 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
893 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
894 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
895 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
896 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
898 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
899 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
900 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
901 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
902 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
903 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
904 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
905 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
907 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
908 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
909 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
910 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
911 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
912 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
913 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
914 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
916 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
917 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
918 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
919 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
920 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
921 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
922 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
923 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
925 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
926 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
927 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
928 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
929 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
930 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
932 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
933 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
934 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
935 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
936 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
937 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
939 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
940 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
941 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
942 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
943 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
944 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
946 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
947 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
948 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
949 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
950 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
951 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
953 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
954 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
955 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
956 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
957 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
958 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
960 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
961 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
962 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
963 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
964 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
965 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
967 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
968 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
969 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
970 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
971 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
972 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
974 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
975 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
976 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
977 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
978 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
979 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1
= 0x00 | OPC_CP3
,
987 OPC_LDXC1
= 0x01 | OPC_CP3
,
988 OPC_LUXC1
= 0x05 | OPC_CP3
,
989 OPC_SWXC1
= 0x08 | OPC_CP3
,
990 OPC_SDXC1
= 0x09 | OPC_CP3
,
991 OPC_SUXC1
= 0x0D | OPC_CP3
,
992 OPC_PREFX
= 0x0F | OPC_CP3
,
993 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
994 OPC_MADD_S
= 0x20 | OPC_CP3
,
995 OPC_MADD_D
= 0x21 | OPC_CP3
,
996 OPC_MADD_PS
= 0x26 | OPC_CP3
,
997 OPC_MSUB_S
= 0x28 | OPC_CP3
,
998 OPC_MSUB_D
= 0x29 | OPC_CP3
,
999 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1000 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1001 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1002 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1003 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1004 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1005 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env
;
1010 static TCGv cpu_gpr
[32], cpu_PC
;
1011 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
], cpu_ACX
[MIPS_DSP_ACC
];
1012 static TCGv cpu_dspctrl
, btarget
, bcond
;
1013 static TCGv_i32 hflags
;
1014 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1015 static TCGv_i64 fpu_f64
[32];
1017 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1018 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1020 #include "exec/gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext
{
1065 struct TranslationBlock
*tb
;
1066 target_ulong pc
, saved_pc
;
1068 int singlestep_enabled
;
1070 /* Routine used to access memory */
1072 uint32_t hflags
, saved_hflags
;
1074 target_ulong btarget
;
1078 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1079 * exception condition */
1080 BS_STOP
= 1, /* We want to stop translation for any reason */
1081 BS_BRANCH
= 2, /* We reached a branch condition */
1082 BS_EXCP
= 3, /* We reached an exception condition */
1085 static const char * const regnames
[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1092 static const char * const regnames_HI
[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1096 static const char * const regnames_LO
[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1100 static const char * const regnames_ACX
[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1104 static const char * const fregnames
[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1111 #define MIPS_DEBUG(fmt, ...) \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1120 #define LOG_DISAS(...) \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1127 #define MIPS_INVAL(op) \
1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1131 /* General purpose registers moves. */
1132 static inline void gen_load_gpr (TCGv t
, int reg
)
1135 tcg_gen_movi_tl(t
, 0);
1137 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1140 static inline void gen_store_gpr (TCGv t
, int reg
)
1143 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1146 /* Moves to/from ACX register. */
1147 static inline void gen_load_ACX (TCGv t
, int reg
)
1149 tcg_gen_mov_tl(t
, cpu_ACX
[reg
]);
1152 static inline void gen_store_ACX (TCGv t
, int reg
)
1154 tcg_gen_mov_tl(cpu_ACX
[reg
], t
);
1157 /* Moves to/from shadow registers. */
1158 static inline void gen_load_srsgpr (int from
, int to
)
1160 TCGv t0
= tcg_temp_new();
1163 tcg_gen_movi_tl(t0
, 0);
1165 TCGv_i32 t2
= tcg_temp_new_i32();
1166 TCGv_ptr addr
= tcg_temp_new_ptr();
1168 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1169 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1170 tcg_gen_andi_i32(t2
, t2
, 0xf);
1171 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1172 tcg_gen_ext_i32_ptr(addr
, t2
);
1173 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1175 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1176 tcg_temp_free_ptr(addr
);
1177 tcg_temp_free_i32(t2
);
1179 gen_store_gpr(t0
, to
);
1183 static inline void gen_store_srsgpr (int from
, int to
)
1186 TCGv t0
= tcg_temp_new();
1187 TCGv_i32 t2
= tcg_temp_new_i32();
1188 TCGv_ptr addr
= tcg_temp_new_ptr();
1190 gen_load_gpr(t0
, from
);
1191 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1192 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1193 tcg_gen_andi_i32(t2
, t2
, 0xf);
1194 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1195 tcg_gen_ext_i32_ptr(addr
, t2
);
1196 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1198 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1199 tcg_temp_free_ptr(addr
);
1200 tcg_temp_free_i32(t2
);
1205 /* Floating point register moves. */
1206 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1208 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1211 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1213 TCGv_i64 t64
= tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64
, t
);
1215 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1216 tcg_temp_free_i64(t64
);
1219 static void gen_load_fpr32h(TCGv_i32 t
, int reg
)
1221 TCGv_i64 t64
= tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1223 tcg_gen_trunc_i64_i32(t
, t64
);
1224 tcg_temp_free_i64(t64
);
1227 static void gen_store_fpr32h(TCGv_i32 t
, int reg
)
1229 TCGv_i64 t64
= tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64
, t
);
1231 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1232 tcg_temp_free_i64(t64
);
1235 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1237 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1238 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1240 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1244 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1246 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1247 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1250 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1251 t0
= tcg_temp_new_i64();
1252 tcg_gen_shri_i64(t0
, t
, 32);
1253 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1254 tcg_temp_free_i64(t0
);
1258 static inline int get_fp_bit (int cc
)
1267 static inline void gen_save_pc(target_ulong pc
)
1269 tcg_gen_movi_tl(cpu_PC
, pc
);
1272 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1274 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1275 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1276 gen_save_pc(ctx
->pc
);
1277 ctx
->saved_pc
= ctx
->pc
;
1279 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1280 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1281 ctx
->saved_hflags
= ctx
->hflags
;
1282 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1288 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1294 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1296 ctx
->saved_hflags
= ctx
->hflags
;
1297 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1303 ctx
->btarget
= env
->btarget
;
1309 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1311 TCGv_i32 texcp
= tcg_const_i32(excp
);
1312 TCGv_i32 terr
= tcg_const_i32(err
);
1313 save_cpu_state(ctx
, 1);
1314 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1315 tcg_temp_free_i32(terr
);
1316 tcg_temp_free_i32(texcp
);
1320 generate_exception (DisasContext
*ctx
, int excp
)
1322 save_cpu_state(ctx
, 1);
1323 gen_helper_0e0i(raise_exception
, excp
);
1326 /* Addresses computation */
1327 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1329 tcg_gen_add_tl(ret
, arg0
, arg1
);
1331 #if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
1335 if (((ctx
->hflags
& MIPS_HFLAG_KSU
) == MIPS_HFLAG_UM
) &&
1336 !(ctx
->hflags
& MIPS_HFLAG_UX
)) {
1337 tcg_gen_ext32s_i64(ret
, ret
);
1342 static inline void check_cp0_enabled(DisasContext
*ctx
)
1344 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1345 generate_exception_err(ctx
, EXCP_CpU
, 0);
1348 static inline void check_cp1_enabled(DisasContext
*ctx
)
1350 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1351 generate_exception_err(ctx
, EXCP_CpU
, 1);
1354 /* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1358 static inline void check_cop1x(DisasContext
*ctx
)
1360 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1361 generate_exception(ctx
, EXCP_RI
);
1364 /* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1367 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1369 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1370 generate_exception(ctx
, EXCP_RI
);
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1384 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1386 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1387 generate_exception(ctx
, EXCP_RI
);
1390 /* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1394 static inline void check_dsp(DisasContext
*ctx
)
1396 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1397 if (ctx
->insn_flags
& ASE_DSP
) {
1398 generate_exception(ctx
, EXCP_DSPDIS
);
1400 generate_exception(ctx
, EXCP_RI
);
1405 static inline void check_dspr2(DisasContext
*ctx
)
1407 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1408 if (ctx
->insn_flags
& ASE_DSP
) {
1409 generate_exception(ctx
, EXCP_DSPDIS
);
1411 generate_exception(ctx
, EXCP_RI
);
1416 /* This code generates a "reserved instruction" exception if the
1417 CPU does not support the instruction set corresponding to flags. */
1418 static inline void check_insn(DisasContext
*ctx
, int flags
)
1420 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1421 generate_exception(ctx
, EXCP_RI
);
1425 /* This code generates a "reserved instruction" exception if 64-bit
1426 instructions are not enabled. */
1427 static inline void check_mips_64(DisasContext
*ctx
)
1429 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1430 generate_exception(ctx
, EXCP_RI
);
1433 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1434 calling interface for 32 and 64-bit FPRs. No sense in changing
1435 all callers for gen_load_fpr32 when we need the CTX parameter for
1437 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1440 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1441 int ft, int fs, int cc) \
1443 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1444 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1447 check_cp1_64bitmode(ctx); \
1453 check_cp1_registers(ctx, fs | ft); \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1464 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1465 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1466 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1467 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1468 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1469 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1470 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1471 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1472 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1473 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1475 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1476 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1477 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1478 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1479 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1482 tcg_temp_free_i##bits (fp0); \
1483 tcg_temp_free_i##bits (fp1); \
1486 FOP_CONDS(, 0, d
, FMT_D
, 64)
1487 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1488 FOP_CONDS(, 0, s
, FMT_S
, 32)
1489 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1490 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1491 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1493 #undef gen_ldcmp_fpr32
1494 #undef gen_ldcmp_fpr64
1496 /* load/store instructions. */
1497 #ifdef CONFIG_USER_ONLY
1498 #define OP_LD_ATOMIC(insn,fname) \
1499 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1501 TCGv t0 = tcg_temp_new(); \
1502 tcg_gen_mov_tl(t0, arg1); \
1503 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1504 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1505 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1506 tcg_temp_free(t0); \
1509 #define OP_LD_ATOMIC(insn,fname) \
1510 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1512 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1515 OP_LD_ATOMIC(ll
,ld32s
);
1516 #if defined(TARGET_MIPS64)
1517 OP_LD_ATOMIC(lld
,ld64
);
1521 #ifdef CONFIG_USER_ONLY
1522 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1523 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1525 TCGv t0 = tcg_temp_new(); \
1526 int l1 = gen_new_label(); \
1527 int l2 = gen_new_label(); \
1529 tcg_gen_andi_tl(t0, arg2, almask); \
1530 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1531 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1532 generate_exception(ctx, EXCP_AdES); \
1533 gen_set_label(l1); \
1534 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1535 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1536 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1537 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1538 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1539 gen_helper_0e0i(raise_exception, EXCP_SC); \
1540 gen_set_label(l2); \
1541 tcg_gen_movi_tl(t0, 0); \
1542 gen_store_gpr(t0, rt); \
1543 tcg_temp_free(t0); \
1546 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1547 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1549 TCGv t0 = tcg_temp_new(); \
1550 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1551 gen_store_gpr(t0, rt); \
1552 tcg_temp_free(t0); \
1555 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1556 #if defined(TARGET_MIPS64)
1557 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1561 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1562 int base
, int16_t offset
)
1565 tcg_gen_movi_tl(addr
, offset
);
1566 } else if (offset
== 0) {
1567 gen_load_gpr(addr
, base
);
1569 tcg_gen_movi_tl(addr
, offset
);
1570 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1574 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1576 target_ulong pc
= ctx
->pc
;
1578 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1579 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1584 pc
&= ~(target_ulong
)3;
1589 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1590 int rt
, int base
, int16_t offset
)
1592 const char *opn
= "ld";
1595 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1596 /* Loongson CPU uses a load to zero register for prefetch.
1597 We emulate it as a NOP. On other CPU we must perform the
1598 actual memory access. */
1603 t0
= tcg_temp_new();
1604 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1607 #if defined(TARGET_MIPS64)
1609 tcg_gen_qemu_ld32u(t0
, t0
, ctx
->mem_idx
);
1610 gen_store_gpr(t0
, rt
);
1614 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1615 gen_store_gpr(t0
, rt
);
1619 save_cpu_state(ctx
, 1);
1620 op_ld_lld(t0
, t0
, ctx
);
1621 gen_store_gpr(t0
, rt
);
1625 t1
= tcg_temp_new();
1626 tcg_gen_andi_tl(t1
, t0
, 7);
1627 #ifndef TARGET_WORDS_BIGENDIAN
1628 tcg_gen_xori_tl(t1
, t1
, 7);
1630 tcg_gen_shli_tl(t1
, t1
, 3);
1631 tcg_gen_andi_tl(t0
, t0
, ~7);
1632 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1633 tcg_gen_shl_tl(t0
, t0
, t1
);
1634 tcg_gen_xori_tl(t1
, t1
, 63);
1635 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1636 tcg_gen_shr_tl(t2
, t2
, t1
);
1637 gen_load_gpr(t1
, rt
);
1638 tcg_gen_and_tl(t1
, t1
, t2
);
1640 tcg_gen_or_tl(t0
, t0
, t1
);
1642 gen_store_gpr(t0
, rt
);
1646 t1
= tcg_temp_new();
1647 tcg_gen_andi_tl(t1
, t0
, 7);
1648 #ifdef TARGET_WORDS_BIGENDIAN
1649 tcg_gen_xori_tl(t1
, t1
, 7);
1651 tcg_gen_shli_tl(t1
, t1
, 3);
1652 tcg_gen_andi_tl(t0
, t0
, ~7);
1653 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1654 tcg_gen_shr_tl(t0
, t0
, t1
);
1655 tcg_gen_xori_tl(t1
, t1
, 63);
1656 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1657 tcg_gen_shl_tl(t2
, t2
, t1
);
1658 gen_load_gpr(t1
, rt
);
1659 tcg_gen_and_tl(t1
, t1
, t2
);
1661 tcg_gen_or_tl(t0
, t0
, t1
);
1663 gen_store_gpr(t0
, rt
);
1667 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1668 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1670 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
1671 gen_store_gpr(t0
, rt
);
1676 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1677 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1679 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
1680 gen_store_gpr(t0
, rt
);
1684 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
1685 gen_store_gpr(t0
, rt
);
1689 tcg_gen_qemu_ld16s(t0
, t0
, ctx
->mem_idx
);
1690 gen_store_gpr(t0
, rt
);
1694 tcg_gen_qemu_ld16u(t0
, t0
, ctx
->mem_idx
);
1695 gen_store_gpr(t0
, rt
);
1699 tcg_gen_qemu_ld8s(t0
, t0
, ctx
->mem_idx
);
1700 gen_store_gpr(t0
, rt
);
1704 tcg_gen_qemu_ld8u(t0
, t0
, ctx
->mem_idx
);
1705 gen_store_gpr(t0
, rt
);
1709 t1
= tcg_temp_new();
1710 tcg_gen_andi_tl(t1
, t0
, 3);
1711 #ifndef TARGET_WORDS_BIGENDIAN
1712 tcg_gen_xori_tl(t1
, t1
, 3);
1714 tcg_gen_shli_tl(t1
, t1
, 3);
1715 tcg_gen_andi_tl(t0
, t0
, ~3);
1716 tcg_gen_qemu_ld32u(t0
, t0
, ctx
->mem_idx
);
1717 tcg_gen_shl_tl(t0
, t0
, t1
);
1718 tcg_gen_xori_tl(t1
, t1
, 31);
1719 t2
= tcg_const_tl(0x7fffffffull
);
1720 tcg_gen_shr_tl(t2
, t2
, t1
);
1721 gen_load_gpr(t1
, rt
);
1722 tcg_gen_and_tl(t1
, t1
, t2
);
1724 tcg_gen_or_tl(t0
, t0
, t1
);
1726 tcg_gen_ext32s_tl(t0
, t0
);
1727 gen_store_gpr(t0
, rt
);
1731 t1
= tcg_temp_new();
1732 tcg_gen_andi_tl(t1
, t0
, 3);
1733 #ifdef TARGET_WORDS_BIGENDIAN
1734 tcg_gen_xori_tl(t1
, t1
, 3);
1736 tcg_gen_shli_tl(t1
, t1
, 3);
1737 tcg_gen_andi_tl(t0
, t0
, ~3);
1738 tcg_gen_qemu_ld32u(t0
, t0
, ctx
->mem_idx
);
1739 tcg_gen_shr_tl(t0
, t0
, t1
);
1740 tcg_gen_xori_tl(t1
, t1
, 31);
1741 t2
= tcg_const_tl(0xfffffffeull
);
1742 tcg_gen_shl_tl(t2
, t2
, t1
);
1743 gen_load_gpr(t1
, rt
);
1744 tcg_gen_and_tl(t1
, t1
, t2
);
1746 tcg_gen_or_tl(t0
, t0
, t1
);
1748 tcg_gen_ext32s_tl(t0
, t0
);
1749 gen_store_gpr(t0
, rt
);
1753 save_cpu_state(ctx
, 1);
1754 op_ld_ll(t0
, t0
, ctx
);
1755 gen_store_gpr(t0
, rt
);
1759 (void)opn
; /* avoid a compiler warning */
1760 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1765 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1766 int base
, int16_t offset
)
1768 const char *opn
= "st";
1769 TCGv t0
= tcg_temp_new();
1770 TCGv t1
= tcg_temp_new();
1772 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1773 gen_load_gpr(t1
, rt
);
1775 #if defined(TARGET_MIPS64)
1777 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
1781 save_cpu_state(ctx
, 1);
1782 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1786 save_cpu_state(ctx
, 1);
1787 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
1792 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
1796 tcg_gen_qemu_st16(t1
, t0
, ctx
->mem_idx
);
1800 tcg_gen_qemu_st8(t1
, t0
, ctx
->mem_idx
);
1804 save_cpu_state(ctx
, 1);
1805 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
1809 save_cpu_state(ctx
, 1);
1810 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
1814 (void)opn
; /* avoid a compiler warning */
1815 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1821 /* Store conditional */
1822 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
1823 int base
, int16_t offset
)
1825 const char *opn
= "st_cond";
1828 #ifdef CONFIG_USER_ONLY
1829 t0
= tcg_temp_local_new();
1830 t1
= tcg_temp_local_new();
1832 t0
= tcg_temp_new();
1833 t1
= tcg_temp_new();
1835 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1836 gen_load_gpr(t1
, rt
);
1838 #if defined(TARGET_MIPS64)
1840 save_cpu_state(ctx
, 1);
1841 op_st_scd(t1
, t0
, rt
, ctx
);
1846 save_cpu_state(ctx
, 1);
1847 op_st_sc(t1
, t0
, rt
, ctx
);
1851 (void)opn
; /* avoid a compiler warning */
1852 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1857 /* Load and store */
1858 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
1859 int base
, int16_t offset
)
1861 const char *opn
= "flt_ldst";
1862 TCGv t0
= tcg_temp_new();
1864 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1865 /* Don't do NOP if destination is zero: we must perform the actual
1870 TCGv_i32 fp0
= tcg_temp_new_i32();
1872 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
1873 tcg_gen_trunc_tl_i32(fp0
, t0
);
1874 gen_store_fpr32(fp0
, ft
);
1875 tcg_temp_free_i32(fp0
);
1881 TCGv_i32 fp0
= tcg_temp_new_i32();
1882 TCGv t1
= tcg_temp_new();
1884 gen_load_fpr32(fp0
, ft
);
1885 tcg_gen_extu_i32_tl(t1
, fp0
);
1886 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
1888 tcg_temp_free_i32(fp0
);
1894 TCGv_i64 fp0
= tcg_temp_new_i64();
1896 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
1897 gen_store_fpr64(ctx
, fp0
, ft
);
1898 tcg_temp_free_i64(fp0
);
1904 TCGv_i64 fp0
= tcg_temp_new_i64();
1906 gen_load_fpr64(ctx
, fp0
, ft
);
1907 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
1908 tcg_temp_free_i64(fp0
);
1914 generate_exception(ctx
, EXCP_RI
);
1917 (void)opn
; /* avoid a compiler warning */
1918 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
1923 static void gen_cop1_ldst(CPUMIPSState
*env
, DisasContext
*ctx
,
1924 uint32_t op
, int rt
, int rs
, int16_t imm
)
1926 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
1927 check_cp1_enabled(ctx
);
1928 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
1930 generate_exception_err(ctx
, EXCP_CpU
, 1);
1934 /* Arithmetic with immediate operand */
1935 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
1936 int rt
, int rs
, int16_t imm
)
1938 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
1939 const char *opn
= "imm arith";
1941 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
1942 /* If no destination, treat it as a NOP.
1943 For addi, we must generate the overflow exception when needed. */
1950 TCGv t0
= tcg_temp_local_new();
1951 TCGv t1
= tcg_temp_new();
1952 TCGv t2
= tcg_temp_new();
1953 int l1
= gen_new_label();
1955 gen_load_gpr(t1
, rs
);
1956 tcg_gen_addi_tl(t0
, t1
, uimm
);
1957 tcg_gen_ext32s_tl(t0
, t0
);
1959 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1960 tcg_gen_xori_tl(t2
, t0
, uimm
);
1961 tcg_gen_and_tl(t1
, t1
, t2
);
1963 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1965 /* operands of same sign, result different sign */
1966 generate_exception(ctx
, EXCP_OVERFLOW
);
1968 tcg_gen_ext32s_tl(t0
, t0
);
1969 gen_store_gpr(t0
, rt
);
1976 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1977 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
1979 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1983 #if defined(TARGET_MIPS64)
1986 TCGv t0
= tcg_temp_local_new();
1987 TCGv t1
= tcg_temp_new();
1988 TCGv t2
= tcg_temp_new();
1989 int l1
= gen_new_label();
1991 gen_load_gpr(t1
, rs
);
1992 tcg_gen_addi_tl(t0
, t1
, uimm
);
1994 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1995 tcg_gen_xori_tl(t2
, t0
, uimm
);
1996 tcg_gen_and_tl(t1
, t1
, t2
);
1998 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2000 /* operands of same sign, result different sign */
2001 generate_exception(ctx
, EXCP_OVERFLOW
);
2003 gen_store_gpr(t0
, rt
);
2010 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2012 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2018 (void)opn
; /* avoid a compiler warning */
2019 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2022 /* Logic with immediate operand */
2023 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2024 int rt
, int rs
, int16_t imm
)
2029 /* If no destination, treat it as a NOP. */
2033 uimm
= (uint16_t)imm
;
2036 if (likely(rs
!= 0))
2037 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2039 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2040 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2041 regnames
[rs
], uimm
);
2045 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2047 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2048 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2049 regnames
[rs
], uimm
);
2052 if (likely(rs
!= 0))
2053 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2055 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2056 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2057 regnames
[rs
], uimm
);
2060 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2061 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2065 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2070 /* Set on less than with immediate operand */
2071 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2072 int rt
, int rs
, int16_t imm
)
2074 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2075 const char *opn
= "imm arith";
2079 /* If no destination, treat it as a NOP. */
2083 t0
= tcg_temp_new();
2084 gen_load_gpr(t0
, rs
);
2087 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2091 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2095 (void)opn
; /* avoid a compiler warning */
2096 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2100 /* Shifts with immediate operand */
2101 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2102 int rt
, int rs
, int16_t imm
)
2104 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2105 const char *opn
= "imm shift";
2109 /* If no destination, treat it as a NOP. */
2114 t0
= tcg_temp_new();
2115 gen_load_gpr(t0
, rs
);
2118 tcg_gen_shli_tl(t0
, t0
, uimm
);
2119 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2123 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2128 tcg_gen_ext32u_tl(t0
, t0
);
2129 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2131 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2137 TCGv_i32 t1
= tcg_temp_new_i32();
2139 tcg_gen_trunc_tl_i32(t1
, t0
);
2140 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2141 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2142 tcg_temp_free_i32(t1
);
2144 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2148 #if defined(TARGET_MIPS64)
2150 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2154 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2158 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2163 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2165 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2170 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2174 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2178 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2182 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2187 (void)opn
; /* avoid a compiler warning */
2188 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2193 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2194 int rd
, int rs
, int rt
)
2196 const char *opn
= "arith";
2198 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2199 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2200 /* If no destination, treat it as a NOP.
2201 For add & sub, we must generate the overflow exception when needed. */
2209 TCGv t0
= tcg_temp_local_new();
2210 TCGv t1
= tcg_temp_new();
2211 TCGv t2
= tcg_temp_new();
2212 int l1
= gen_new_label();
2214 gen_load_gpr(t1
, rs
);
2215 gen_load_gpr(t2
, rt
);
2216 tcg_gen_add_tl(t0
, t1
, t2
);
2217 tcg_gen_ext32s_tl(t0
, t0
);
2218 tcg_gen_xor_tl(t1
, t1
, t2
);
2219 tcg_gen_xor_tl(t2
, t0
, t2
);
2220 tcg_gen_andc_tl(t1
, t2
, t1
);
2222 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2224 /* operands of same sign, result different sign */
2225 generate_exception(ctx
, EXCP_OVERFLOW
);
2227 gen_store_gpr(t0
, rd
);
2233 if (rs
!= 0 && rt
!= 0) {
2234 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2235 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2236 } else if (rs
== 0 && rt
!= 0) {
2237 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2238 } else if (rs
!= 0 && rt
== 0) {
2239 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2241 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2247 TCGv t0
= tcg_temp_local_new();
2248 TCGv t1
= tcg_temp_new();
2249 TCGv t2
= tcg_temp_new();
2250 int l1
= gen_new_label();
2252 gen_load_gpr(t1
, rs
);
2253 gen_load_gpr(t2
, rt
);
2254 tcg_gen_sub_tl(t0
, t1
, t2
);
2255 tcg_gen_ext32s_tl(t0
, t0
);
2256 tcg_gen_xor_tl(t2
, t1
, t2
);
2257 tcg_gen_xor_tl(t1
, t0
, t1
);
2258 tcg_gen_and_tl(t1
, t1
, t2
);
2260 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2262 /* operands of different sign, first operand and result different sign */
2263 generate_exception(ctx
, EXCP_OVERFLOW
);
2265 gen_store_gpr(t0
, rd
);
2271 if (rs
!= 0 && rt
!= 0) {
2272 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2273 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2274 } else if (rs
== 0 && rt
!= 0) {
2275 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2276 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2277 } else if (rs
!= 0 && rt
== 0) {
2278 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2280 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2284 #if defined(TARGET_MIPS64)
2287 TCGv t0
= tcg_temp_local_new();
2288 TCGv t1
= tcg_temp_new();
2289 TCGv t2
= tcg_temp_new();
2290 int l1
= gen_new_label();
2292 gen_load_gpr(t1
, rs
);
2293 gen_load_gpr(t2
, rt
);
2294 tcg_gen_add_tl(t0
, t1
, t2
);
2295 tcg_gen_xor_tl(t1
, t1
, t2
);
2296 tcg_gen_xor_tl(t2
, t0
, t2
);
2297 tcg_gen_andc_tl(t1
, t2
, t1
);
2299 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2301 /* operands of same sign, result different sign */
2302 generate_exception(ctx
, EXCP_OVERFLOW
);
2304 gen_store_gpr(t0
, rd
);
2310 if (rs
!= 0 && rt
!= 0) {
2311 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2312 } else if (rs
== 0 && rt
!= 0) {
2313 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2314 } else if (rs
!= 0 && rt
== 0) {
2315 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2317 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2323 TCGv t0
= tcg_temp_local_new();
2324 TCGv t1
= tcg_temp_new();
2325 TCGv t2
= tcg_temp_new();
2326 int l1
= gen_new_label();
2328 gen_load_gpr(t1
, rs
);
2329 gen_load_gpr(t2
, rt
);
2330 tcg_gen_sub_tl(t0
, t1
, t2
);
2331 tcg_gen_xor_tl(t2
, t1
, t2
);
2332 tcg_gen_xor_tl(t1
, t0
, t1
);
2333 tcg_gen_and_tl(t1
, t1
, t2
);
2335 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2337 /* operands of different sign, first operand and result different sign */
2338 generate_exception(ctx
, EXCP_OVERFLOW
);
2340 gen_store_gpr(t0
, rd
);
2346 if (rs
!= 0 && rt
!= 0) {
2347 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2348 } else if (rs
== 0 && rt
!= 0) {
2349 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2350 } else if (rs
!= 0 && rt
== 0) {
2351 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2353 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2359 if (likely(rs
!= 0 && rt
!= 0)) {
2360 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2361 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2363 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2368 (void)opn
; /* avoid a compiler warning */
2369 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2372 /* Conditional move */
2373 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2374 int rd
, int rs
, int rt
)
2376 const char *opn
= "cond move";
2380 /* If no destination, treat it as a NOP. */
2385 t0
= tcg_temp_new();
2386 gen_load_gpr(t0
, rt
);
2387 t1
= tcg_const_tl(0);
2388 t2
= tcg_temp_new();
2389 gen_load_gpr(t2
, rs
);
2392 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2396 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2404 (void)opn
; /* avoid a compiler warning */
2405 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2409 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2410 int rd
, int rs
, int rt
)
2412 const char *opn
= "logic";
2415 /* If no destination, treat it as a NOP. */
2422 if (likely(rs
!= 0 && rt
!= 0)) {
2423 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2425 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2430 if (rs
!= 0 && rt
!= 0) {
2431 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2432 } else if (rs
== 0 && rt
!= 0) {
2433 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2434 } else if (rs
!= 0 && rt
== 0) {
2435 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2437 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2442 if (likely(rs
!= 0 && rt
!= 0)) {
2443 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2444 } else if (rs
== 0 && rt
!= 0) {
2445 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2446 } else if (rs
!= 0 && rt
== 0) {
2447 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2449 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2454 if (likely(rs
!= 0 && rt
!= 0)) {
2455 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2456 } else if (rs
== 0 && rt
!= 0) {
2457 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2458 } else if (rs
!= 0 && rt
== 0) {
2459 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2461 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2466 (void)opn
; /* avoid a compiler warning */
2467 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2470 /* Set on lower than */
2471 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2472 int rd
, int rs
, int rt
)
2474 const char *opn
= "slt";
2478 /* If no destination, treat it as a NOP. */
2483 t0
= tcg_temp_new();
2484 t1
= tcg_temp_new();
2485 gen_load_gpr(t0
, rs
);
2486 gen_load_gpr(t1
, rt
);
2489 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2493 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2497 (void)opn
; /* avoid a compiler warning */
2498 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2504 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2505 int rd
, int rs
, int rt
)
2507 const char *opn
= "shifts";
2511 /* If no destination, treat it as a NOP.
2512 For add & sub, we must generate the overflow exception when needed. */
2517 t0
= tcg_temp_new();
2518 t1
= tcg_temp_new();
2519 gen_load_gpr(t0
, rs
);
2520 gen_load_gpr(t1
, rt
);
2523 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2524 tcg_gen_shl_tl(t0
, t1
, t0
);
2525 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2529 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2530 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2534 tcg_gen_ext32u_tl(t1
, t1
);
2535 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2536 tcg_gen_shr_tl(t0
, t1
, t0
);
2537 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2542 TCGv_i32 t2
= tcg_temp_new_i32();
2543 TCGv_i32 t3
= tcg_temp_new_i32();
2545 tcg_gen_trunc_tl_i32(t2
, t0
);
2546 tcg_gen_trunc_tl_i32(t3
, t1
);
2547 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2548 tcg_gen_rotr_i32(t2
, t3
, t2
);
2549 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2550 tcg_temp_free_i32(t2
);
2551 tcg_temp_free_i32(t3
);
2555 #if defined(TARGET_MIPS64)
2557 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2558 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2562 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2563 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2567 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2568 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2572 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2573 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2578 (void)opn
; /* avoid a compiler warning */
2579 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2584 /* Arithmetic on HI/LO registers */
2585 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2587 const char *opn
= "hilo";
2589 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2601 #if defined(TARGET_MIPS64)
2603 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2607 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2612 #if defined(TARGET_MIPS64)
2614 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2618 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2624 #if defined(TARGET_MIPS64)
2626 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2630 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2633 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2639 #if defined(TARGET_MIPS64)
2641 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2645 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2648 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2653 (void)opn
; /* avoid a compiler warning */
2654 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2657 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
2658 int acc
, int rs
, int rt
)
2660 const char *opn
= "mul/div";
2663 t0
= tcg_temp_new();
2664 t1
= tcg_temp_new();
2666 gen_load_gpr(t0
, rs
);
2667 gen_load_gpr(t1
, rt
);
2676 TCGv t2
= tcg_temp_new();
2677 TCGv t3
= tcg_temp_new();
2678 tcg_gen_ext32s_tl(t0
, t0
);
2679 tcg_gen_ext32s_tl(t1
, t1
);
2680 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2681 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2682 tcg_gen_and_tl(t2
, t2
, t3
);
2683 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2684 tcg_gen_or_tl(t2
, t2
, t3
);
2685 tcg_gen_movi_tl(t3
, 0);
2686 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2687 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2688 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2689 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2690 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2698 TCGv t2
= tcg_const_tl(0);
2699 TCGv t3
= tcg_const_tl(1);
2700 tcg_gen_ext32u_tl(t0
, t0
);
2701 tcg_gen_ext32u_tl(t1
, t1
);
2702 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2703 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
2704 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
2705 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2706 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2714 TCGv_i32 t2
= tcg_temp_new_i32();
2715 TCGv_i32 t3
= tcg_temp_new_i32();
2716 tcg_gen_trunc_tl_i32(t2
, t0
);
2717 tcg_gen_trunc_tl_i32(t3
, t1
);
2718 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
2719 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2720 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2721 tcg_temp_free_i32(t2
);
2722 tcg_temp_free_i32(t3
);
2728 TCGv_i32 t2
= tcg_temp_new_i32();
2729 TCGv_i32 t3
= tcg_temp_new_i32();
2730 tcg_gen_trunc_tl_i32(t2
, t0
);
2731 tcg_gen_trunc_tl_i32(t3
, t1
);
2732 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
2733 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2734 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2735 tcg_temp_free_i32(t2
);
2736 tcg_temp_free_i32(t3
);
2740 #if defined(TARGET_MIPS64)
2743 TCGv t2
= tcg_temp_new();
2744 TCGv t3
= tcg_temp_new();
2745 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2746 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2747 tcg_gen_and_tl(t2
, t2
, t3
);
2748 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2749 tcg_gen_or_tl(t2
, t2
, t3
);
2750 tcg_gen_movi_tl(t3
, 0);
2751 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2752 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2753 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2761 TCGv t2
= tcg_const_tl(0);
2762 TCGv t3
= tcg_const_tl(1);
2763 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2764 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
2765 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
2772 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2776 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2782 TCGv_i64 t2
= tcg_temp_new_i64();
2783 TCGv_i64 t3
= tcg_temp_new_i64();
2785 tcg_gen_ext_tl_i64(t2
, t0
);
2786 tcg_gen_ext_tl_i64(t3
, t1
);
2787 tcg_gen_mul_i64(t2
, t2
, t3
);
2788 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2789 tcg_gen_add_i64(t2
, t2
, t3
);
2790 tcg_temp_free_i64(t3
);
2791 tcg_gen_trunc_i64_tl(t0
, t2
);
2792 tcg_gen_shri_i64(t2
, t2
, 32);
2793 tcg_gen_trunc_i64_tl(t1
, t2
);
2794 tcg_temp_free_i64(t2
);
2795 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2796 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2802 TCGv_i64 t2
= tcg_temp_new_i64();
2803 TCGv_i64 t3
= tcg_temp_new_i64();
2805 tcg_gen_ext32u_tl(t0
, t0
);
2806 tcg_gen_ext32u_tl(t1
, t1
);
2807 tcg_gen_extu_tl_i64(t2
, t0
);
2808 tcg_gen_extu_tl_i64(t3
, t1
);
2809 tcg_gen_mul_i64(t2
, t2
, t3
);
2810 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2811 tcg_gen_add_i64(t2
, t2
, t3
);
2812 tcg_temp_free_i64(t3
);
2813 tcg_gen_trunc_i64_tl(t0
, t2
);
2814 tcg_gen_shri_i64(t2
, t2
, 32);
2815 tcg_gen_trunc_i64_tl(t1
, t2
);
2816 tcg_temp_free_i64(t2
);
2817 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2818 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2824 TCGv_i64 t2
= tcg_temp_new_i64();
2825 TCGv_i64 t3
= tcg_temp_new_i64();
2827 tcg_gen_ext_tl_i64(t2
, t0
);
2828 tcg_gen_ext_tl_i64(t3
, t1
);
2829 tcg_gen_mul_i64(t2
, t2
, t3
);
2830 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2831 tcg_gen_sub_i64(t2
, t3
, t2
);
2832 tcg_temp_free_i64(t3
);
2833 tcg_gen_trunc_i64_tl(t0
, t2
);
2834 tcg_gen_shri_i64(t2
, t2
, 32);
2835 tcg_gen_trunc_i64_tl(t1
, t2
);
2836 tcg_temp_free_i64(t2
);
2837 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2838 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2844 TCGv_i64 t2
= tcg_temp_new_i64();
2845 TCGv_i64 t3
= tcg_temp_new_i64();
2847 tcg_gen_ext32u_tl(t0
, t0
);
2848 tcg_gen_ext32u_tl(t1
, t1
);
2849 tcg_gen_extu_tl_i64(t2
, t0
);
2850 tcg_gen_extu_tl_i64(t3
, t1
);
2851 tcg_gen_mul_i64(t2
, t2
, t3
);
2852 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2853 tcg_gen_sub_i64(t2
, t3
, t2
);
2854 tcg_temp_free_i64(t3
);
2855 tcg_gen_trunc_i64_tl(t0
, t2
);
2856 tcg_gen_shri_i64(t2
, t2
, 32);
2857 tcg_gen_trunc_i64_tl(t1
, t2
);
2858 tcg_temp_free_i64(t2
);
2859 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2860 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2866 generate_exception(ctx
, EXCP_RI
);
2869 (void)opn
; /* avoid a compiler warning */
2870 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2876 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2877 int rd
, int rs
, int rt
)
2879 const char *opn
= "mul vr54xx";
2880 TCGv t0
= tcg_temp_new();
2881 TCGv t1
= tcg_temp_new();
2883 gen_load_gpr(t0
, rs
);
2884 gen_load_gpr(t1
, rt
);
2887 case OPC_VR54XX_MULS
:
2888 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2891 case OPC_VR54XX_MULSU
:
2892 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2895 case OPC_VR54XX_MACC
:
2896 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2899 case OPC_VR54XX_MACCU
:
2900 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2903 case OPC_VR54XX_MSAC
:
2904 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2907 case OPC_VR54XX_MSACU
:
2908 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2911 case OPC_VR54XX_MULHI
:
2912 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2915 case OPC_VR54XX_MULHIU
:
2916 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2919 case OPC_VR54XX_MULSHI
:
2920 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2923 case OPC_VR54XX_MULSHIU
:
2924 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2927 case OPC_VR54XX_MACCHI
:
2928 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2931 case OPC_VR54XX_MACCHIU
:
2932 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2935 case OPC_VR54XX_MSACHI
:
2936 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2939 case OPC_VR54XX_MSACHIU
:
2940 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2944 MIPS_INVAL("mul vr54xx");
2945 generate_exception(ctx
, EXCP_RI
);
2948 gen_store_gpr(t0
, rd
);
2949 (void)opn
; /* avoid a compiler warning */
2950 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2957 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2960 const char *opn
= "CLx";
2968 t0
= tcg_temp_new();
2969 gen_load_gpr(t0
, rs
);
2972 gen_helper_clo(cpu_gpr
[rd
], t0
);
2976 gen_helper_clz(cpu_gpr
[rd
], t0
);
2979 #if defined(TARGET_MIPS64)
2981 gen_helper_dclo(cpu_gpr
[rd
], t0
);
2985 gen_helper_dclz(cpu_gpr
[rd
], t0
);
2990 (void)opn
; /* avoid a compiler warning */
2991 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
2995 /* Godson integer instructions */
2996 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
2997 int rd
, int rs
, int rt
)
2999 const char *opn
= "loongson";
3011 case OPC_MULTU_G_2E
:
3012 case OPC_MULTU_G_2F
:
3013 #if defined(TARGET_MIPS64)
3014 case OPC_DMULT_G_2E
:
3015 case OPC_DMULT_G_2F
:
3016 case OPC_DMULTU_G_2E
:
3017 case OPC_DMULTU_G_2F
:
3019 t0
= tcg_temp_new();
3020 t1
= tcg_temp_new();
3023 t0
= tcg_temp_local_new();
3024 t1
= tcg_temp_local_new();
3028 gen_load_gpr(t0
, rs
);
3029 gen_load_gpr(t1
, rt
);
3034 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3035 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3038 case OPC_MULTU_G_2E
:
3039 case OPC_MULTU_G_2F
:
3040 tcg_gen_ext32u_tl(t0
, t0
);
3041 tcg_gen_ext32u_tl(t1
, t1
);
3042 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3043 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3049 int l1
= gen_new_label();
3050 int l2
= gen_new_label();
3051 int l3
= gen_new_label();
3052 tcg_gen_ext32s_tl(t0
, t0
);
3053 tcg_gen_ext32s_tl(t1
, t1
);
3054 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3055 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3058 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3059 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3060 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3063 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3064 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3072 int l1
= gen_new_label();
3073 int l2
= gen_new_label();
3074 tcg_gen_ext32u_tl(t0
, t0
);
3075 tcg_gen_ext32u_tl(t1
, t1
);
3076 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3077 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3080 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3081 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3089 int l1
= gen_new_label();
3090 int l2
= gen_new_label();
3091 int l3
= gen_new_label();
3092 tcg_gen_ext32u_tl(t0
, t0
);
3093 tcg_gen_ext32u_tl(t1
, t1
);
3094 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3095 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3096 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3098 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3101 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3102 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3110 int l1
= gen_new_label();
3111 int l2
= gen_new_label();
3112 tcg_gen_ext32u_tl(t0
, t0
);
3113 tcg_gen_ext32u_tl(t1
, t1
);
3114 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3115 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3118 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3119 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3124 #if defined(TARGET_MIPS64)
3125 case OPC_DMULT_G_2E
:
3126 case OPC_DMULT_G_2F
:
3127 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3130 case OPC_DMULTU_G_2E
:
3131 case OPC_DMULTU_G_2F
:
3132 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3138 int l1
= gen_new_label();
3139 int l2
= gen_new_label();
3140 int l3
= gen_new_label();
3141 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3142 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3145 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3146 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3147 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3150 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3155 case OPC_DDIVU_G_2E
:
3156 case OPC_DDIVU_G_2F
:
3158 int l1
= gen_new_label();
3159 int l2
= gen_new_label();
3160 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3161 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3164 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3172 int l1
= gen_new_label();
3173 int l2
= gen_new_label();
3174 int l3
= gen_new_label();
3175 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3176 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3177 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3179 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3182 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3187 case OPC_DMODU_G_2E
:
3188 case OPC_DMODU_G_2F
:
3190 int l1
= gen_new_label();
3191 int l2
= gen_new_label();
3192 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3193 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3196 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3204 (void)opn
; /* avoid a compiler warning */
3205 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3210 /* Loongson multimedia instructions */
3211 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3213 const char *opn
= "loongson_cp2";
3214 uint32_t opc
, shift_max
;
3217 opc
= MASK_LMI(ctx
->opcode
);
3223 t0
= tcg_temp_local_new_i64();
3224 t1
= tcg_temp_local_new_i64();
3227 t0
= tcg_temp_new_i64();
3228 t1
= tcg_temp_new_i64();
3232 gen_load_fpr64(ctx
, t0
, rs
);
3233 gen_load_fpr64(ctx
, t1
, rt
);
3235 #define LMI_HELPER(UP, LO) \
3236 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3237 #define LMI_HELPER_1(UP, LO) \
3238 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3239 #define LMI_DIRECT(UP, LO, OP) \
3240 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3243 LMI_HELPER(PADDSH
, paddsh
);
3244 LMI_HELPER(PADDUSH
, paddush
);
3245 LMI_HELPER(PADDH
, paddh
);
3246 LMI_HELPER(PADDW
, paddw
);
3247 LMI_HELPER(PADDSB
, paddsb
);
3248 LMI_HELPER(PADDUSB
, paddusb
);
3249 LMI_HELPER(PADDB
, paddb
);
3251 LMI_HELPER(PSUBSH
, psubsh
);
3252 LMI_HELPER(PSUBUSH
, psubush
);
3253 LMI_HELPER(PSUBH
, psubh
);
3254 LMI_HELPER(PSUBW
, psubw
);
3255 LMI_HELPER(PSUBSB
, psubsb
);
3256 LMI_HELPER(PSUBUSB
, psubusb
);
3257 LMI_HELPER(PSUBB
, psubb
);
3259 LMI_HELPER(PSHUFH
, pshufh
);
3260 LMI_HELPER(PACKSSWH
, packsswh
);
3261 LMI_HELPER(PACKSSHB
, packsshb
);
3262 LMI_HELPER(PACKUSHB
, packushb
);
3264 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3265 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3266 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3267 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3268 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3269 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3271 LMI_HELPER(PAVGH
, pavgh
);
3272 LMI_HELPER(PAVGB
, pavgb
);
3273 LMI_HELPER(PMAXSH
, pmaxsh
);
3274 LMI_HELPER(PMINSH
, pminsh
);
3275 LMI_HELPER(PMAXUB
, pmaxub
);
3276 LMI_HELPER(PMINUB
, pminub
);
3278 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3279 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3280 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3281 LMI_HELPER(PCMPGTH
, pcmpgth
);
3282 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3283 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3285 LMI_HELPER(PSLLW
, psllw
);
3286 LMI_HELPER(PSLLH
, psllh
);
3287 LMI_HELPER(PSRLW
, psrlw
);
3288 LMI_HELPER(PSRLH
, psrlh
);
3289 LMI_HELPER(PSRAW
, psraw
);
3290 LMI_HELPER(PSRAH
, psrah
);
3292 LMI_HELPER(PMULLH
, pmullh
);
3293 LMI_HELPER(PMULHH
, pmulhh
);
3294 LMI_HELPER(PMULHUH
, pmulhuh
);
3295 LMI_HELPER(PMADDHW
, pmaddhw
);
3297 LMI_HELPER(PASUBUB
, pasubub
);
3298 LMI_HELPER_1(BIADD
, biadd
);
3299 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3301 LMI_DIRECT(PADDD
, paddd
, add
);
3302 LMI_DIRECT(PSUBD
, psubd
, sub
);
3303 LMI_DIRECT(XOR_CP2
, xor, xor);
3304 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3305 LMI_DIRECT(AND_CP2
, and, and);
3306 LMI_DIRECT(PANDN
, pandn
, andc
);
3307 LMI_DIRECT(OR
, or, or);
3310 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3314 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3318 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3322 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3327 tcg_gen_andi_i64(t1
, t1
, 3);
3328 tcg_gen_shli_i64(t1
, t1
, 4);
3329 tcg_gen_shr_i64(t0
, t0
, t1
);
3330 tcg_gen_ext16u_i64(t0
, t0
);
3335 tcg_gen_add_i64(t0
, t0
, t1
);
3336 tcg_gen_ext32s_i64(t0
, t0
);
3340 tcg_gen_sub_i64(t0
, t0
, t1
);
3341 tcg_gen_ext32s_i64(t0
, t0
);
3370 /* Make sure shift count isn't TCG undefined behaviour. */
3371 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3376 tcg_gen_shl_i64(t0
, t0
, t1
);
3380 /* Since SRA is UndefinedResult without sign-extended inputs,
3381 we can treat SRA and DSRA the same. */
3382 tcg_gen_sar_i64(t0
, t0
, t1
);
3385 /* We want to shift in zeros for SRL; zero-extend first. */
3386 tcg_gen_ext32u_i64(t0
, t0
);
3389 tcg_gen_shr_i64(t0
, t0
, t1
);
3393 if (shift_max
== 32) {
3394 tcg_gen_ext32s_i64(t0
, t0
);
3397 /* Shifts larger than MAX produce zero. */
3398 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3399 tcg_gen_neg_i64(t1
, t1
);
3400 tcg_gen_and_i64(t0
, t0
, t1
);
3406 TCGv_i64 t2
= tcg_temp_new_i64();
3407 int lab
= gen_new_label();
3409 tcg_gen_mov_i64(t2
, t0
);
3410 tcg_gen_add_i64(t0
, t1
, t2
);
3411 if (opc
== OPC_ADD_CP2
) {
3412 tcg_gen_ext32s_i64(t0
, t0
);
3414 tcg_gen_xor_i64(t1
, t1
, t2
);
3415 tcg_gen_xor_i64(t2
, t2
, t0
);
3416 tcg_gen_andc_i64(t1
, t2
, t1
);
3417 tcg_temp_free_i64(t2
);
3418 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3419 generate_exception(ctx
, EXCP_OVERFLOW
);
3422 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3429 TCGv_i64 t2
= tcg_temp_new_i64();
3430 int lab
= gen_new_label();
3432 tcg_gen_mov_i64(t2
, t0
);
3433 tcg_gen_sub_i64(t0
, t1
, t2
);
3434 if (opc
== OPC_SUB_CP2
) {
3435 tcg_gen_ext32s_i64(t0
, t0
);
3437 tcg_gen_xor_i64(t1
, t1
, t2
);
3438 tcg_gen_xor_i64(t2
, t2
, t0
);
3439 tcg_gen_and_i64(t1
, t1
, t2
);
3440 tcg_temp_free_i64(t2
);
3441 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3442 generate_exception(ctx
, EXCP_OVERFLOW
);
3445 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3450 tcg_gen_ext32u_i64(t0
, t0
);
3451 tcg_gen_ext32u_i64(t1
, t1
);
3452 tcg_gen_mul_i64(t0
, t0
, t1
);
3462 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3463 FD field is the CC field? */
3466 generate_exception(ctx
, EXCP_RI
);
3473 gen_store_fpr64(ctx
, t0
, rd
);
3475 (void)opn
; /* avoid a compiler warning */
3476 MIPS_DEBUG("%s %s, %s, %s", opn
,
3477 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3478 tcg_temp_free_i64(t0
);
3479 tcg_temp_free_i64(t1
);
3483 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3484 int rs
, int rt
, int16_t imm
)
3487 TCGv t0
= tcg_temp_new();
3488 TCGv t1
= tcg_temp_new();
3491 /* Load needed operands */
3499 /* Compare two registers */
3501 gen_load_gpr(t0
, rs
);
3502 gen_load_gpr(t1
, rt
);
3512 /* Compare register to immediate */
3513 if (rs
!= 0 || imm
!= 0) {
3514 gen_load_gpr(t0
, rs
);
3515 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3522 case OPC_TEQ
: /* rs == rs */
3523 case OPC_TEQI
: /* r0 == 0 */
3524 case OPC_TGE
: /* rs >= rs */
3525 case OPC_TGEI
: /* r0 >= 0 */
3526 case OPC_TGEU
: /* rs >= rs unsigned */
3527 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3529 generate_exception(ctx
, EXCP_TRAP
);
3531 case OPC_TLT
: /* rs < rs */
3532 case OPC_TLTI
: /* r0 < 0 */
3533 case OPC_TLTU
: /* rs < rs unsigned */
3534 case OPC_TLTIU
: /* r0 < 0 unsigned */
3535 case OPC_TNE
: /* rs != rs */
3536 case OPC_TNEI
: /* r0 != 0 */
3537 /* Never trap: treat as NOP. */
3541 int l1
= gen_new_label();
3546 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3550 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3554 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3558 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3562 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3566 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3569 generate_exception(ctx
, EXCP_TRAP
);
3576 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3578 TranslationBlock
*tb
;
3580 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3581 likely(!ctx
->singlestep_enabled
)) {
3584 tcg_gen_exit_tb((tcg_target_long
)tb
+ n
);
3587 if (ctx
->singlestep_enabled
) {
3588 save_cpu_state(ctx
, 0);
3589 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3595 /* Branches (before delay slot) */
3596 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3598 int rs
, int rt
, int32_t offset
)
3600 target_ulong btgt
= -1;
3602 int bcond_compute
= 0;
3603 TCGv t0
= tcg_temp_new();
3604 TCGv t1
= tcg_temp_new();
3606 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3607 #ifdef MIPS_DEBUG_DISAS
3608 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3610 generate_exception(ctx
, EXCP_RI
);
3614 /* Load needed operands */
3620 /* Compare two registers */
3622 gen_load_gpr(t0
, rs
);
3623 gen_load_gpr(t1
, rt
);
3626 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3642 /* Compare to zero */
3644 gen_load_gpr(t0
, rs
);
3647 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3650 #if defined(TARGET_MIPS64)
3652 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3654 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3657 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3664 /* Jump to immediate */
3665 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3671 /* Jump to register */
3672 if (offset
!= 0 && offset
!= 16) {
3673 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3674 others are reserved. */
3675 MIPS_INVAL("jump hint");
3676 generate_exception(ctx
, EXCP_RI
);
3679 gen_load_gpr(btarget
, rs
);
3682 MIPS_INVAL("branch/jump");
3683 generate_exception(ctx
, EXCP_RI
);
3686 if (bcond_compute
== 0) {
3687 /* No condition to be computed */
3689 case OPC_BEQ
: /* rx == rx */
3690 case OPC_BEQL
: /* rx == rx likely */
3691 case OPC_BGEZ
: /* 0 >= 0 */
3692 case OPC_BGEZL
: /* 0 >= 0 likely */
3693 case OPC_BLEZ
: /* 0 <= 0 */
3694 case OPC_BLEZL
: /* 0 <= 0 likely */
3696 ctx
->hflags
|= MIPS_HFLAG_B
;
3697 MIPS_DEBUG("balways");
3700 case OPC_BGEZAL
: /* 0 >= 0 */
3701 case OPC_BGEZALL
: /* 0 >= 0 likely */
3702 ctx
->hflags
|= (opc
== OPC_BGEZALS
3704 : MIPS_HFLAG_BDS32
);
3705 /* Always take and link */
3707 ctx
->hflags
|= MIPS_HFLAG_B
;
3708 MIPS_DEBUG("balways and link");
3710 case OPC_BNE
: /* rx != rx */
3711 case OPC_BGTZ
: /* 0 > 0 */
3712 case OPC_BLTZ
: /* 0 < 0 */
3714 MIPS_DEBUG("bnever (NOP)");
3717 case OPC_BLTZAL
: /* 0 < 0 */
3718 ctx
->hflags
|= (opc
== OPC_BLTZALS
3720 : MIPS_HFLAG_BDS32
);
3721 /* Handle as an unconditional branch to get correct delay
3724 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3725 ctx
->hflags
|= MIPS_HFLAG_B
;
3726 MIPS_DEBUG("bnever and link");
3728 case OPC_BLTZALL
: /* 0 < 0 likely */
3729 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3730 /* Skip the instruction in the delay slot */
3731 MIPS_DEBUG("bnever, link and skip");
3734 case OPC_BNEL
: /* rx != rx likely */
3735 case OPC_BGTZL
: /* 0 > 0 likely */
3736 case OPC_BLTZL
: /* 0 < 0 likely */
3737 /* Skip the instruction in the delay slot */
3738 MIPS_DEBUG("bnever and skip");
3742 ctx
->hflags
|= MIPS_HFLAG_B
;
3743 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3747 ctx
->hflags
|= MIPS_HFLAG_BX
;
3752 ctx
->hflags
|= MIPS_HFLAG_B
;
3753 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3755 : MIPS_HFLAG_BDS32
);
3756 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3759 ctx
->hflags
|= MIPS_HFLAG_BR
;
3760 if (insn_bytes
== 4)
3761 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3762 MIPS_DEBUG("jr %s", regnames
[rs
]);
3768 ctx
->hflags
|= MIPS_HFLAG_BR
;
3769 ctx
->hflags
|= (opc
== OPC_JALRS
3771 : MIPS_HFLAG_BDS32
);
3772 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3775 MIPS_INVAL("branch/jump");
3776 generate_exception(ctx
, EXCP_RI
);
3782 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3783 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3784 regnames
[rs
], regnames
[rt
], btgt
);
3787 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3788 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3789 regnames
[rs
], regnames
[rt
], btgt
);
3792 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3793 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3794 regnames
[rs
], regnames
[rt
], btgt
);
3797 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3798 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3799 regnames
[rs
], regnames
[rt
], btgt
);
3802 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3803 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3806 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3807 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3811 ctx
->hflags
|= (opc
== OPC_BGEZALS
3813 : MIPS_HFLAG_BDS32
);
3814 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3815 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3819 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3821 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3824 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3825 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3828 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3829 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3832 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3833 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3836 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3837 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3840 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3841 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3844 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3845 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3848 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3849 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3851 #if defined(TARGET_MIPS64)
3853 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3854 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3859 ctx
->hflags
|= (opc
== OPC_BLTZALS
3861 : MIPS_HFLAG_BDS32
);
3862 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3864 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3866 ctx
->hflags
|= MIPS_HFLAG_BC
;
3869 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3871 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3873 ctx
->hflags
|= MIPS_HFLAG_BL
;
3876 MIPS_INVAL("conditional branch/jump");
3877 generate_exception(ctx
, EXCP_RI
);
3881 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3882 blink
, ctx
->hflags
, btgt
);
3884 ctx
->btarget
= btgt
;
3886 int post_delay
= insn_bytes
;
3887 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3889 if (opc
!= OPC_JALRC
)
3890 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3892 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3896 if (insn_bytes
== 2)
3897 ctx
->hflags
|= MIPS_HFLAG_B16
;
3902 /* special3 bitfield operations */
3903 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3904 int rs
, int lsb
, int msb
)
3906 TCGv t0
= tcg_temp_new();
3907 TCGv t1
= tcg_temp_new();
3909 gen_load_gpr(t1
, rs
);
3914 tcg_gen_shri_tl(t0
, t1
, lsb
);
3916 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3918 tcg_gen_ext32s_tl(t0
, t0
);
3921 #if defined(TARGET_MIPS64)
3923 tcg_gen_shri_tl(t0
, t1
, lsb
);
3925 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3929 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3930 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3933 tcg_gen_shri_tl(t0
, t1
, lsb
);
3934 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3940 gen_load_gpr(t0
, rt
);
3941 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3942 tcg_gen_ext32s_tl(t0
, t0
);
3944 #if defined(TARGET_MIPS64)
3946 gen_load_gpr(t0
, rt
);
3947 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3950 gen_load_gpr(t0
, rt
);
3951 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3954 gen_load_gpr(t0
, rt
);
3955 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3960 MIPS_INVAL("bitops");
3961 generate_exception(ctx
, EXCP_RI
);
3966 gen_store_gpr(t0
, rt
);
3971 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
3976 /* If no destination, treat it as a NOP. */
3981 t0
= tcg_temp_new();
3982 gen_load_gpr(t0
, rt
);
3986 TCGv t1
= tcg_temp_new();
3988 tcg_gen_shri_tl(t1
, t0
, 8);
3989 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
3990 tcg_gen_shli_tl(t0
, t0
, 8);
3991 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
3992 tcg_gen_or_tl(t0
, t0
, t1
);
3994 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3998 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4001 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4003 #if defined(TARGET_MIPS64)
4006 TCGv t1
= tcg_temp_new();
4008 tcg_gen_shri_tl(t1
, t0
, 8);
4009 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4010 tcg_gen_shli_tl(t0
, t0
, 8);
4011 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4012 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4018 TCGv t1
= tcg_temp_new();
4020 tcg_gen_shri_tl(t1
, t0
, 16);
4021 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4022 tcg_gen_shli_tl(t0
, t0
, 16);
4023 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4024 tcg_gen_or_tl(t0
, t0
, t1
);
4025 tcg_gen_shri_tl(t1
, t0
, 32);
4026 tcg_gen_shli_tl(t0
, t0
, 32);
4027 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4033 MIPS_INVAL("bsfhl");
4034 generate_exception(ctx
, EXCP_RI
);
4041 #ifndef CONFIG_USER_ONLY
4042 /* CP0 (MMU and control) */
4043 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4045 TCGv_i32 t0
= tcg_temp_new_i32();
4047 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4048 tcg_gen_ext_i32_tl(arg
, t0
);
4049 tcg_temp_free_i32(t0
);
4052 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4054 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4055 tcg_gen_ext32s_tl(arg
, arg
);
4058 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4060 TCGv_i32 t0
= tcg_temp_new_i32();
4062 tcg_gen_trunc_tl_i32(t0
, arg
);
4063 tcg_gen_st_i32(t0
, cpu_env
, off
);
4064 tcg_temp_free_i32(t0
);
4067 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4069 tcg_gen_ext32s_tl(arg
, arg
);
4070 tcg_gen_st_tl(arg
, cpu_env
, off
);
4073 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4075 const char *rn
= "invalid";
4078 check_insn(ctx
, ISA_MIPS32
);
4084 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4088 check_insn(ctx
, ASE_MT
);
4089 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4093 check_insn(ctx
, ASE_MT
);
4094 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4098 check_insn(ctx
, ASE_MT
);
4099 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4109 gen_helper_mfc0_random(arg
, cpu_env
);
4113 check_insn(ctx
, ASE_MT
);
4114 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4118 check_insn(ctx
, ASE_MT
);
4119 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4123 check_insn(ctx
, ASE_MT
);
4124 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4128 check_insn(ctx
, ASE_MT
);
4129 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4133 check_insn(ctx
, ASE_MT
);
4134 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4138 check_insn(ctx
, ASE_MT
);
4139 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4140 rn
= "VPEScheFBack";
4143 check_insn(ctx
, ASE_MT
);
4144 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4154 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4155 tcg_gen_ext32s_tl(arg
, arg
);
4159 check_insn(ctx
, ASE_MT
);
4160 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4164 check_insn(ctx
, ASE_MT
);
4165 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4169 check_insn(ctx
, ASE_MT
);
4170 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4174 check_insn(ctx
, ASE_MT
);
4175 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4179 check_insn(ctx
, ASE_MT
);
4180 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4184 check_insn(ctx
, ASE_MT
);
4185 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4189 check_insn(ctx
, ASE_MT
);
4190 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4200 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4201 tcg_gen_ext32s_tl(arg
, arg
);
4211 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4212 tcg_gen_ext32s_tl(arg
, arg
);
4216 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4217 rn
= "ContextConfig";
4226 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4230 check_insn(ctx
, ISA_MIPS32R2
);
4231 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4241 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4245 check_insn(ctx
, ISA_MIPS32R2
);
4246 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4250 check_insn(ctx
, ISA_MIPS32R2
);
4251 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4255 check_insn(ctx
, ISA_MIPS32R2
);
4256 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4260 check_insn(ctx
, ISA_MIPS32R2
);
4261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4265 check_insn(ctx
, ISA_MIPS32R2
);
4266 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4276 check_insn(ctx
, ISA_MIPS32R2
);
4277 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4287 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4288 tcg_gen_ext32s_tl(arg
, arg
);
4298 /* Mark as an IO operation because we read the time. */
4301 gen_helper_mfc0_count(arg
, cpu_env
);
4305 /* Break the TB to be able to take timer interrupts immediately
4306 after reading count. */
4307 ctx
->bstate
= BS_STOP
;
4310 /* 6,7 are implementation dependent */
4318 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4319 tcg_gen_ext32s_tl(arg
, arg
);
4329 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4332 /* 6,7 are implementation dependent */
4340 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4344 check_insn(ctx
, ISA_MIPS32R2
);
4345 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4349 check_insn(ctx
, ISA_MIPS32R2
);
4350 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4354 check_insn(ctx
, ISA_MIPS32R2
);
4355 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4365 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4375 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4376 tcg_gen_ext32s_tl(arg
, arg
);
4386 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4390 check_insn(ctx
, ISA_MIPS32R2
);
4391 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4401 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4405 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4409 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4413 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4416 /* 4,5 are reserved */
4417 /* 6,7 are implementation dependent */
4419 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4423 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4433 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4443 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4453 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4463 #if defined(TARGET_MIPS64)
4464 check_insn(ctx
, ISA_MIPS3
);
4465 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4466 tcg_gen_ext32s_tl(arg
, arg
);
4475 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4478 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4486 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4487 rn
= "'Diagnostic"; /* implementation dependent */
4492 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4496 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4497 rn
= "TraceControl";
4500 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4501 rn
= "TraceControl2";
4504 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4505 rn
= "UserTraceData";
4508 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4519 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4520 tcg_gen_ext32s_tl(arg
, arg
);
4530 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4531 rn
= "Performance0";
4534 // gen_helper_mfc0_performance1(arg);
4535 rn
= "Performance1";
4538 // gen_helper_mfc0_performance2(arg);
4539 rn
= "Performance2";
4542 // gen_helper_mfc0_performance3(arg);
4543 rn
= "Performance3";
4546 // gen_helper_mfc0_performance4(arg);
4547 rn
= "Performance4";
4550 // gen_helper_mfc0_performance5(arg);
4551 rn
= "Performance5";
4554 // gen_helper_mfc0_performance6(arg);
4555 rn
= "Performance6";
4558 // gen_helper_mfc0_performance7(arg);
4559 rn
= "Performance7";
4566 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4572 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4585 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4592 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4605 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4612 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4622 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4623 tcg_gen_ext32s_tl(arg
, arg
);
4634 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4644 (void)rn
; /* avoid a compiler warning */
4645 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4649 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4650 generate_exception(ctx
, EXCP_RI
);
4653 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4655 const char *rn
= "invalid";
4658 check_insn(ctx
, ISA_MIPS32
);
4667 gen_helper_mtc0_index(cpu_env
, arg
);
4671 check_insn(ctx
, ASE_MT
);
4672 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4676 check_insn(ctx
, ASE_MT
);
4681 check_insn(ctx
, ASE_MT
);
4696 check_insn(ctx
, ASE_MT
);
4697 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4701 check_insn(ctx
, ASE_MT
);
4702 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4706 check_insn(ctx
, ASE_MT
);
4707 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4711 check_insn(ctx
, ASE_MT
);
4712 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4716 check_insn(ctx
, ASE_MT
);
4717 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4721 check_insn(ctx
, ASE_MT
);
4722 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4723 rn
= "VPEScheFBack";
4726 check_insn(ctx
, ASE_MT
);
4727 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4737 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4741 check_insn(ctx
, ASE_MT
);
4742 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4746 check_insn(ctx
, ASE_MT
);
4747 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4751 check_insn(ctx
, ASE_MT
);
4752 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4756 check_insn(ctx
, ASE_MT
);
4757 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4761 check_insn(ctx
, ASE_MT
);
4762 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4766 check_insn(ctx
, ASE_MT
);
4767 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4771 check_insn(ctx
, ASE_MT
);
4772 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4782 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4792 gen_helper_mtc0_context(cpu_env
, arg
);
4796 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4797 rn
= "ContextConfig";
4806 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4810 check_insn(ctx
, ISA_MIPS32R2
);
4811 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4821 gen_helper_mtc0_wired(cpu_env
, arg
);
4825 check_insn(ctx
, ISA_MIPS32R2
);
4826 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4830 check_insn(ctx
, ISA_MIPS32R2
);
4831 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4835 check_insn(ctx
, ISA_MIPS32R2
);
4836 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4840 check_insn(ctx
, ISA_MIPS32R2
);
4841 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4845 check_insn(ctx
, ISA_MIPS32R2
);
4846 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4856 check_insn(ctx
, ISA_MIPS32R2
);
4857 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4871 gen_helper_mtc0_count(cpu_env
, arg
);
4874 /* 6,7 are implementation dependent */
4882 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4892 gen_helper_mtc0_compare(cpu_env
, arg
);
4895 /* 6,7 are implementation dependent */
4903 save_cpu_state(ctx
, 1);
4904 gen_helper_mtc0_status(cpu_env
, arg
);
4905 /* BS_STOP isn't good enough here, hflags may have changed. */
4906 gen_save_pc(ctx
->pc
+ 4);
4907 ctx
->bstate
= BS_EXCP
;
4911 check_insn(ctx
, ISA_MIPS32R2
);
4912 gen_helper_mtc0_intctl(cpu_env
, arg
);
4913 /* Stop translation as we may have switched the execution mode */
4914 ctx
->bstate
= BS_STOP
;
4918 check_insn(ctx
, ISA_MIPS32R2
);
4919 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4920 /* Stop translation as we may have switched the execution mode */
4921 ctx
->bstate
= BS_STOP
;
4925 check_insn(ctx
, ISA_MIPS32R2
);
4926 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4927 /* Stop translation as we may have switched the execution mode */
4928 ctx
->bstate
= BS_STOP
;
4938 save_cpu_state(ctx
, 1);
4939 gen_helper_mtc0_cause(cpu_env
, arg
);
4949 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4963 check_insn(ctx
, ISA_MIPS32R2
);
4964 gen_helper_mtc0_ebase(cpu_env
, arg
);
4974 gen_helper_mtc0_config0(cpu_env
, arg
);
4976 /* Stop translation as we may have switched the execution mode */
4977 ctx
->bstate
= BS_STOP
;
4980 /* ignored, read only */
4984 gen_helper_mtc0_config2(cpu_env
, arg
);
4986 /* Stop translation as we may have switched the execution mode */
4987 ctx
->bstate
= BS_STOP
;
4990 /* ignored, read only */
4993 /* 4,5 are reserved */
4994 /* 6,7 are implementation dependent */
5004 rn
= "Invalid config selector";
5011 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5021 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5031 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5041 #if defined(TARGET_MIPS64)
5042 check_insn(ctx
, ISA_MIPS3
);
5043 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5052 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5055 gen_helper_mtc0_framemask(cpu_env
, arg
);
5064 rn
= "Diagnostic"; /* implementation dependent */
5069 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5070 /* BS_STOP isn't good enough here, hflags may have changed. */
5071 gen_save_pc(ctx
->pc
+ 4);
5072 ctx
->bstate
= BS_EXCP
;
5076 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5077 rn
= "TraceControl";
5078 /* Stop translation as we may have switched the execution mode */
5079 ctx
->bstate
= BS_STOP
;
5082 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5083 rn
= "TraceControl2";
5084 /* Stop translation as we may have switched the execution mode */
5085 ctx
->bstate
= BS_STOP
;
5088 /* Stop translation as we may have switched the execution mode */
5089 ctx
->bstate
= BS_STOP
;
5090 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5091 rn
= "UserTraceData";
5092 /* Stop translation as we may have switched the execution mode */
5093 ctx
->bstate
= BS_STOP
;
5096 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5097 /* Stop translation as we may have switched the execution mode */
5098 ctx
->bstate
= BS_STOP
;
5109 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5119 gen_helper_mtc0_performance0(cpu_env
, arg
);
5120 rn
= "Performance0";
5123 // gen_helper_mtc0_performance1(arg);
5124 rn
= "Performance1";
5127 // gen_helper_mtc0_performance2(arg);
5128 rn
= "Performance2";
5131 // gen_helper_mtc0_performance3(arg);
5132 rn
= "Performance3";
5135 // gen_helper_mtc0_performance4(arg);
5136 rn
= "Performance4";
5139 // gen_helper_mtc0_performance5(arg);
5140 rn
= "Performance5";
5143 // gen_helper_mtc0_performance6(arg);
5144 rn
= "Performance6";
5147 // gen_helper_mtc0_performance7(arg);
5148 rn
= "Performance7";
5174 gen_helper_mtc0_taglo(cpu_env
, arg
);
5181 gen_helper_mtc0_datalo(cpu_env
, arg
);
5194 gen_helper_mtc0_taghi(cpu_env
, arg
);
5201 gen_helper_mtc0_datahi(cpu_env
, arg
);
5212 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5223 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5229 /* Stop translation as we may have switched the execution mode */
5230 ctx
->bstate
= BS_STOP
;
5235 (void)rn
; /* avoid a compiler warning */
5236 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5237 /* For simplicity assume that all writes can cause interrupts. */
5240 ctx
->bstate
= BS_STOP
;
5245 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5246 generate_exception(ctx
, EXCP_RI
);
5249 #if defined(TARGET_MIPS64)
5250 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5252 const char *rn
= "invalid";
5255 check_insn(ctx
, ISA_MIPS64
);
5261 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5265 check_insn(ctx
, ASE_MT
);
5266 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5270 check_insn(ctx
, ASE_MT
);
5271 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5275 check_insn(ctx
, ASE_MT
);
5276 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5286 gen_helper_mfc0_random(arg
, cpu_env
);
5290 check_insn(ctx
, ASE_MT
);
5291 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5295 check_insn(ctx
, ASE_MT
);
5296 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5300 check_insn(ctx
, ASE_MT
);
5301 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5305 check_insn(ctx
, ASE_MT
);
5306 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5310 check_insn(ctx
, ASE_MT
);
5311 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5315 check_insn(ctx
, ASE_MT
);
5316 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5317 rn
= "VPEScheFBack";
5320 check_insn(ctx
, ASE_MT
);
5321 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5331 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5335 check_insn(ctx
, ASE_MT
);
5336 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5340 check_insn(ctx
, ASE_MT
);
5341 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5345 check_insn(ctx
, ASE_MT
);
5346 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5350 check_insn(ctx
, ASE_MT
);
5351 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5355 check_insn(ctx
, ASE_MT
);
5356 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5360 check_insn(ctx
, ASE_MT
);
5361 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5365 check_insn(ctx
, ASE_MT
);
5366 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5376 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5386 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5390 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5391 rn
= "ContextConfig";
5400 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5404 check_insn(ctx
, ISA_MIPS32R2
);
5405 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5415 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5419 check_insn(ctx
, ISA_MIPS32R2
);
5420 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5424 check_insn(ctx
, ISA_MIPS32R2
);
5425 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5429 check_insn(ctx
, ISA_MIPS32R2
);
5430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5434 check_insn(ctx
, ISA_MIPS32R2
);
5435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5439 check_insn(ctx
, ISA_MIPS32R2
);
5440 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5450 check_insn(ctx
, ISA_MIPS32R2
);
5451 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5461 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5471 /* Mark as an IO operation because we read the time. */
5474 gen_helper_mfc0_count(arg
, cpu_env
);
5478 /* Break the TB to be able to take timer interrupts immediately
5479 after reading count. */
5480 ctx
->bstate
= BS_STOP
;
5483 /* 6,7 are implementation dependent */
5491 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5501 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5504 /* 6,7 are implementation dependent */
5512 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5516 check_insn(ctx
, ISA_MIPS32R2
);
5517 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5521 check_insn(ctx
, ISA_MIPS32R2
);
5522 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5526 check_insn(ctx
, ISA_MIPS32R2
);
5527 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5537 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5547 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5557 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5561 check_insn(ctx
, ISA_MIPS32R2
);
5562 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5572 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5576 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5580 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5584 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5587 /* 6,7 are implementation dependent */
5589 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5593 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5603 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5613 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5623 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5633 check_insn(ctx
, ISA_MIPS3
);
5634 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5642 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5645 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5653 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5654 rn
= "'Diagnostic"; /* implementation dependent */
5659 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5663 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5664 rn
= "TraceControl";
5667 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5668 rn
= "TraceControl2";
5671 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5672 rn
= "UserTraceData";
5675 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5686 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5696 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5697 rn
= "Performance0";
5700 // gen_helper_dmfc0_performance1(arg);
5701 rn
= "Performance1";
5704 // gen_helper_dmfc0_performance2(arg);
5705 rn
= "Performance2";
5708 // gen_helper_dmfc0_performance3(arg);
5709 rn
= "Performance3";
5712 // gen_helper_dmfc0_performance4(arg);
5713 rn
= "Performance4";
5716 // gen_helper_dmfc0_performance5(arg);
5717 rn
= "Performance5";
5720 // gen_helper_dmfc0_performance6(arg);
5721 rn
= "Performance6";
5724 // gen_helper_dmfc0_performance7(arg);
5725 rn
= "Performance7";
5732 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5739 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5752 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5759 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5772 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5779 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5789 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5800 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5810 (void)rn
; /* avoid a compiler warning */
5811 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5815 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5816 generate_exception(ctx
, EXCP_RI
);
5819 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5821 const char *rn
= "invalid";
5824 check_insn(ctx
, ISA_MIPS64
);
5833 gen_helper_mtc0_index(cpu_env
, arg
);
5837 check_insn(ctx
, ASE_MT
);
5838 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5842 check_insn(ctx
, ASE_MT
);
5847 check_insn(ctx
, ASE_MT
);
5862 check_insn(ctx
, ASE_MT
);
5863 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5867 check_insn(ctx
, ASE_MT
);
5868 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5872 check_insn(ctx
, ASE_MT
);
5873 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5877 check_insn(ctx
, ASE_MT
);
5878 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5882 check_insn(ctx
, ASE_MT
);
5883 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5887 check_insn(ctx
, ASE_MT
);
5888 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5889 rn
= "VPEScheFBack";
5892 check_insn(ctx
, ASE_MT
);
5893 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5903 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5907 check_insn(ctx
, ASE_MT
);
5908 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5912 check_insn(ctx
, ASE_MT
);
5913 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5917 check_insn(ctx
, ASE_MT
);
5918 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5922 check_insn(ctx
, ASE_MT
);
5923 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5927 check_insn(ctx
, ASE_MT
);
5928 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5932 check_insn(ctx
, ASE_MT
);
5933 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5937 check_insn(ctx
, ASE_MT
);
5938 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5948 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5958 gen_helper_mtc0_context(cpu_env
, arg
);
5962 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5963 rn
= "ContextConfig";
5972 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5976 check_insn(ctx
, ISA_MIPS32R2
);
5977 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5987 gen_helper_mtc0_wired(cpu_env
, arg
);
5991 check_insn(ctx
, ISA_MIPS32R2
);
5992 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
5996 check_insn(ctx
, ISA_MIPS32R2
);
5997 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6001 check_insn(ctx
, ISA_MIPS32R2
);
6002 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6006 check_insn(ctx
, ISA_MIPS32R2
);
6007 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6011 check_insn(ctx
, ISA_MIPS32R2
);
6012 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6022 check_insn(ctx
, ISA_MIPS32R2
);
6023 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6037 gen_helper_mtc0_count(cpu_env
, arg
);
6040 /* 6,7 are implementation dependent */
6044 /* Stop translation as we may have switched the execution mode */
6045 ctx
->bstate
= BS_STOP
;
6050 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6060 gen_helper_mtc0_compare(cpu_env
, arg
);
6063 /* 6,7 are implementation dependent */
6067 /* Stop translation as we may have switched the execution mode */
6068 ctx
->bstate
= BS_STOP
;
6073 save_cpu_state(ctx
, 1);
6074 gen_helper_mtc0_status(cpu_env
, arg
);
6075 /* BS_STOP isn't good enough here, hflags may have changed. */
6076 gen_save_pc(ctx
->pc
+ 4);
6077 ctx
->bstate
= BS_EXCP
;
6081 check_insn(ctx
, ISA_MIPS32R2
);
6082 gen_helper_mtc0_intctl(cpu_env
, arg
);
6083 /* Stop translation as we may have switched the execution mode */
6084 ctx
->bstate
= BS_STOP
;
6088 check_insn(ctx
, ISA_MIPS32R2
);
6089 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6090 /* Stop translation as we may have switched the execution mode */
6091 ctx
->bstate
= BS_STOP
;
6095 check_insn(ctx
, ISA_MIPS32R2
);
6096 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6097 /* Stop translation as we may have switched the execution mode */
6098 ctx
->bstate
= BS_STOP
;
6108 save_cpu_state(ctx
, 1);
6109 /* Mark as an IO operation because we may trigger a software
6114 gen_helper_mtc0_cause(cpu_env
, arg
);
6118 /* Stop translation as we may have triggered an intetrupt */
6119 ctx
->bstate
= BS_STOP
;
6129 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6143 check_insn(ctx
, ISA_MIPS32R2
);
6144 gen_helper_mtc0_ebase(cpu_env
, arg
);
6154 gen_helper_mtc0_config0(cpu_env
, arg
);
6156 /* Stop translation as we may have switched the execution mode */
6157 ctx
->bstate
= BS_STOP
;
6160 /* ignored, read only */
6164 gen_helper_mtc0_config2(cpu_env
, arg
);
6166 /* Stop translation as we may have switched the execution mode */
6167 ctx
->bstate
= BS_STOP
;
6173 /* 6,7 are implementation dependent */
6175 rn
= "Invalid config selector";
6182 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6192 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6202 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6212 check_insn(ctx
, ISA_MIPS3
);
6213 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6221 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6224 gen_helper_mtc0_framemask(cpu_env
, arg
);
6233 rn
= "Diagnostic"; /* implementation dependent */
6238 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6239 /* BS_STOP isn't good enough here, hflags may have changed. */
6240 gen_save_pc(ctx
->pc
+ 4);
6241 ctx
->bstate
= BS_EXCP
;
6245 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6246 /* Stop translation as we may have switched the execution mode */
6247 ctx
->bstate
= BS_STOP
;
6248 rn
= "TraceControl";
6251 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6252 /* Stop translation as we may have switched the execution mode */
6253 ctx
->bstate
= BS_STOP
;
6254 rn
= "TraceControl2";
6257 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6258 /* Stop translation as we may have switched the execution mode */
6259 ctx
->bstate
= BS_STOP
;
6260 rn
= "UserTraceData";
6263 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6264 /* Stop translation as we may have switched the execution mode */
6265 ctx
->bstate
= BS_STOP
;
6276 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6286 gen_helper_mtc0_performance0(cpu_env
, arg
);
6287 rn
= "Performance0";
6290 // gen_helper_mtc0_performance1(cpu_env, arg);
6291 rn
= "Performance1";
6294 // gen_helper_mtc0_performance2(cpu_env, arg);
6295 rn
= "Performance2";
6298 // gen_helper_mtc0_performance3(cpu_env, arg);
6299 rn
= "Performance3";
6302 // gen_helper_mtc0_performance4(cpu_env, arg);
6303 rn
= "Performance4";
6306 // gen_helper_mtc0_performance5(cpu_env, arg);
6307 rn
= "Performance5";
6310 // gen_helper_mtc0_performance6(cpu_env, arg);
6311 rn
= "Performance6";
6314 // gen_helper_mtc0_performance7(cpu_env, arg);
6315 rn
= "Performance7";
6341 gen_helper_mtc0_taglo(cpu_env
, arg
);
6348 gen_helper_mtc0_datalo(cpu_env
, arg
);
6361 gen_helper_mtc0_taghi(cpu_env
, arg
);
6368 gen_helper_mtc0_datahi(cpu_env
, arg
);
6379 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6390 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6396 /* Stop translation as we may have switched the execution mode */
6397 ctx
->bstate
= BS_STOP
;
6402 (void)rn
; /* avoid a compiler warning */
6403 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6404 /* For simplicity assume that all writes can cause interrupts. */
6407 ctx
->bstate
= BS_STOP
;
6412 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6413 generate_exception(ctx
, EXCP_RI
);
6415 #endif /* TARGET_MIPS64 */
6417 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6418 int u
, int sel
, int h
)
6420 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6421 TCGv t0
= tcg_temp_local_new();
6423 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6424 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6425 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6426 tcg_gen_movi_tl(t0
, -1);
6427 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6428 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6429 tcg_gen_movi_tl(t0
, -1);
6435 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6438 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6448 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6451 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6454 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6457 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6460 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6463 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6466 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6469 gen_mfc0(ctx
, t0
, rt
, sel
);
6476 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6479 gen_mfc0(ctx
, t0
, rt
, sel
);
6485 gen_helper_mftc0_status(t0
, cpu_env
);
6488 gen_mfc0(ctx
, t0
, rt
, sel
);
6494 gen_helper_mftc0_cause(t0
, cpu_env
);
6504 gen_helper_mftc0_epc(t0
, cpu_env
);
6514 gen_helper_mftc0_ebase(t0
, cpu_env
);
6524 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6534 gen_helper_mftc0_debug(t0
, cpu_env
);
6537 gen_mfc0(ctx
, t0
, rt
, sel
);
6542 gen_mfc0(ctx
, t0
, rt
, sel
);
6544 } else switch (sel
) {
6545 /* GPR registers. */
6547 gen_helper_1e0i(mftgpr
, t0
, rt
);
6549 /* Auxiliary CPU registers */
6553 gen_helper_1e0i(mftlo
, t0
, 0);
6556 gen_helper_1e0i(mfthi
, t0
, 0);
6559 gen_helper_1e0i(mftacx
, t0
, 0);
6562 gen_helper_1e0i(mftlo
, t0
, 1);
6565 gen_helper_1e0i(mfthi
, t0
, 1);
6568 gen_helper_1e0i(mftacx
, t0
, 1);
6571 gen_helper_1e0i(mftlo
, t0
, 2);
6574 gen_helper_1e0i(mfthi
, t0
, 2);
6577 gen_helper_1e0i(mftacx
, t0
, 2);
6580 gen_helper_1e0i(mftlo
, t0
, 3);
6583 gen_helper_1e0i(mfthi
, t0
, 3);
6586 gen_helper_1e0i(mftacx
, t0
, 3);
6589 gen_helper_mftdsp(t0
, cpu_env
);
6595 /* Floating point (COP1). */
6597 /* XXX: For now we support only a single FPU context. */
6599 TCGv_i32 fp0
= tcg_temp_new_i32();
6601 gen_load_fpr32(fp0
, rt
);
6602 tcg_gen_ext_i32_tl(t0
, fp0
);
6603 tcg_temp_free_i32(fp0
);
6605 TCGv_i32 fp0
= tcg_temp_new_i32();
6607 gen_load_fpr32h(fp0
, rt
);
6608 tcg_gen_ext_i32_tl(t0
, fp0
);
6609 tcg_temp_free_i32(fp0
);
6613 /* XXX: For now we support only a single FPU context. */
6614 gen_helper_1e0i(cfc1
, t0
, rt
);
6616 /* COP2: Not implemented. */
6623 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6624 gen_store_gpr(t0
, rd
);
6630 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6631 generate_exception(ctx
, EXCP_RI
);
6634 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6635 int u
, int sel
, int h
)
6637 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6638 TCGv t0
= tcg_temp_local_new();
6640 gen_load_gpr(t0
, rt
);
6641 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6642 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6643 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6645 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6646 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6653 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6656 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6666 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6669 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6672 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6675 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6678 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6681 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6684 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6687 gen_mtc0(ctx
, t0
, rd
, sel
);
6694 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6697 gen_mtc0(ctx
, t0
, rd
, sel
);
6703 gen_helper_mttc0_status(cpu_env
, t0
);
6706 gen_mtc0(ctx
, t0
, rd
, sel
);
6712 gen_helper_mttc0_cause(cpu_env
, t0
);
6722 gen_helper_mttc0_ebase(cpu_env
, t0
);
6732 gen_helper_mttc0_debug(cpu_env
, t0
);
6735 gen_mtc0(ctx
, t0
, rd
, sel
);
6740 gen_mtc0(ctx
, t0
, rd
, sel
);
6742 } else switch (sel
) {
6743 /* GPR registers. */
6745 gen_helper_0e1i(mttgpr
, t0
, rd
);
6747 /* Auxiliary CPU registers */
6751 gen_helper_0e1i(mttlo
, t0
, 0);
6754 gen_helper_0e1i(mtthi
, t0
, 0);
6757 gen_helper_0e1i(mttacx
, t0
, 0);
6760 gen_helper_0e1i(mttlo
, t0
, 1);
6763 gen_helper_0e1i(mtthi
, t0
, 1);
6766 gen_helper_0e1i(mttacx
, t0
, 1);
6769 gen_helper_0e1i(mttlo
, t0
, 2);
6772 gen_helper_0e1i(mtthi
, t0
, 2);
6775 gen_helper_0e1i(mttacx
, t0
, 2);
6778 gen_helper_0e1i(mttlo
, t0
, 3);
6781 gen_helper_0e1i(mtthi
, t0
, 3);
6784 gen_helper_0e1i(mttacx
, t0
, 3);
6787 gen_helper_mttdsp(cpu_env
, t0
);
6793 /* Floating point (COP1). */
6795 /* XXX: For now we support only a single FPU context. */
6797 TCGv_i32 fp0
= tcg_temp_new_i32();
6799 tcg_gen_trunc_tl_i32(fp0
, t0
);
6800 gen_store_fpr32(fp0
, rd
);
6801 tcg_temp_free_i32(fp0
);
6803 TCGv_i32 fp0
= tcg_temp_new_i32();
6805 tcg_gen_trunc_tl_i32(fp0
, t0
);
6806 gen_store_fpr32h(fp0
, rd
);
6807 tcg_temp_free_i32(fp0
);
6811 /* XXX: For now we support only a single FPU context. */
6812 gen_helper_0e1i(ctc1
, t0
, rd
);
6814 /* COP2: Not implemented. */
6821 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6827 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6828 generate_exception(ctx
, EXCP_RI
);
6831 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6833 const char *opn
= "ldst";
6835 check_cp0_enabled(ctx
);
6842 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6847 TCGv t0
= tcg_temp_new();
6849 gen_load_gpr(t0
, rt
);
6850 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6855 #if defined(TARGET_MIPS64)
6857 check_insn(ctx
, ISA_MIPS3
);
6862 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6866 check_insn(ctx
, ISA_MIPS3
);
6868 TCGv t0
= tcg_temp_new();
6870 gen_load_gpr(t0
, rt
);
6871 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6878 check_insn(ctx
, ASE_MT
);
6883 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6884 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6888 check_insn(ctx
, ASE_MT
);
6889 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6890 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6895 if (!env
->tlb
->helper_tlbwi
)
6897 gen_helper_tlbwi(cpu_env
);
6901 if (!env
->tlb
->helper_tlbwr
)
6903 gen_helper_tlbwr(cpu_env
);
6907 if (!env
->tlb
->helper_tlbp
)
6909 gen_helper_tlbp(cpu_env
);
6913 if (!env
->tlb
->helper_tlbr
)
6915 gen_helper_tlbr(cpu_env
);
6919 check_insn(ctx
, ISA_MIPS2
);
6920 gen_helper_eret(cpu_env
);
6921 ctx
->bstate
= BS_EXCP
;
6925 check_insn(ctx
, ISA_MIPS32
);
6926 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6928 generate_exception(ctx
, EXCP_RI
);
6930 gen_helper_deret(cpu_env
);
6931 ctx
->bstate
= BS_EXCP
;
6936 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
6937 /* If we get an exception, we want to restart at next instruction */
6939 save_cpu_state(ctx
, 1);
6941 gen_helper_wait(cpu_env
);
6942 ctx
->bstate
= BS_EXCP
;
6947 generate_exception(ctx
, EXCP_RI
);
6950 (void)opn
; /* avoid a compiler warning */
6951 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
6953 #endif /* !CONFIG_USER_ONLY */
6955 /* CP1 Branches (before delay slot) */
6956 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
6957 int32_t cc
, int32_t offset
)
6959 target_ulong btarget
;
6960 const char *opn
= "cp1 cond branch";
6961 TCGv_i32 t0
= tcg_temp_new_i32();
6964 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
6966 btarget
= ctx
->pc
+ 4 + offset
;
6970 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6971 tcg_gen_not_i32(t0
, t0
);
6972 tcg_gen_andi_i32(t0
, t0
, 1);
6973 tcg_gen_extu_i32_tl(bcond
, t0
);
6977 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6978 tcg_gen_not_i32(t0
, t0
);
6979 tcg_gen_andi_i32(t0
, t0
, 1);
6980 tcg_gen_extu_i32_tl(bcond
, t0
);
6984 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6985 tcg_gen_andi_i32(t0
, t0
, 1);
6986 tcg_gen_extu_i32_tl(bcond
, t0
);
6990 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6991 tcg_gen_andi_i32(t0
, t0
, 1);
6992 tcg_gen_extu_i32_tl(bcond
, t0
);
6995 ctx
->hflags
|= MIPS_HFLAG_BL
;
6999 TCGv_i32 t1
= tcg_temp_new_i32();
7000 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7001 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7002 tcg_gen_nand_i32(t0
, t0
, t1
);
7003 tcg_temp_free_i32(t1
);
7004 tcg_gen_andi_i32(t0
, t0
, 1);
7005 tcg_gen_extu_i32_tl(bcond
, t0
);
7011 TCGv_i32 t1
= tcg_temp_new_i32();
7012 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7013 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7014 tcg_gen_or_i32(t0
, t0
, t1
);
7015 tcg_temp_free_i32(t1
);
7016 tcg_gen_andi_i32(t0
, t0
, 1);
7017 tcg_gen_extu_i32_tl(bcond
, t0
);
7023 TCGv_i32 t1
= tcg_temp_new_i32();
7024 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7025 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7026 tcg_gen_and_i32(t0
, t0
, t1
);
7027 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7028 tcg_gen_and_i32(t0
, t0
, t1
);
7029 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7030 tcg_gen_nand_i32(t0
, t0
, t1
);
7031 tcg_temp_free_i32(t1
);
7032 tcg_gen_andi_i32(t0
, t0
, 1);
7033 tcg_gen_extu_i32_tl(bcond
, t0
);
7039 TCGv_i32 t1
= tcg_temp_new_i32();
7040 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7041 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7042 tcg_gen_or_i32(t0
, t0
, t1
);
7043 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7044 tcg_gen_or_i32(t0
, t0
, t1
);
7045 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7046 tcg_gen_or_i32(t0
, t0
, t1
);
7047 tcg_temp_free_i32(t1
);
7048 tcg_gen_andi_i32(t0
, t0
, 1);
7049 tcg_gen_extu_i32_tl(bcond
, t0
);
7053 ctx
->hflags
|= MIPS_HFLAG_BC
;
7057 generate_exception (ctx
, EXCP_RI
);
7060 (void)opn
; /* avoid a compiler warning */
7061 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7062 ctx
->hflags
, btarget
);
7063 ctx
->btarget
= btarget
;
7066 tcg_temp_free_i32(t0
);
7069 /* Coprocessor 1 (FPU) */
7071 #define FOP(func, fmt) (((fmt) << 21) | (func))
7074 OPC_ADD_S
= FOP(0, FMT_S
),
7075 OPC_SUB_S
= FOP(1, FMT_S
),
7076 OPC_MUL_S
= FOP(2, FMT_S
),
7077 OPC_DIV_S
= FOP(3, FMT_S
),
7078 OPC_SQRT_S
= FOP(4, FMT_S
),
7079 OPC_ABS_S
= FOP(5, FMT_S
),
7080 OPC_MOV_S
= FOP(6, FMT_S
),
7081 OPC_NEG_S
= FOP(7, FMT_S
),
7082 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7083 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7084 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7085 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7086 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7087 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7088 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7089 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7090 OPC_MOVCF_S
= FOP(17, FMT_S
),
7091 OPC_MOVZ_S
= FOP(18, FMT_S
),
7092 OPC_MOVN_S
= FOP(19, FMT_S
),
7093 OPC_RECIP_S
= FOP(21, FMT_S
),
7094 OPC_RSQRT_S
= FOP(22, FMT_S
),
7095 OPC_RECIP2_S
= FOP(28, FMT_S
),
7096 OPC_RECIP1_S
= FOP(29, FMT_S
),
7097 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7098 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7099 OPC_CVT_D_S
= FOP(33, FMT_S
),
7100 OPC_CVT_W_S
= FOP(36, FMT_S
),
7101 OPC_CVT_L_S
= FOP(37, FMT_S
),
7102 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7103 OPC_CMP_F_S
= FOP (48, FMT_S
),
7104 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7105 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7106 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7107 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7108 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7109 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7110 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7111 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7112 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7113 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7114 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7115 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7116 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7117 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7118 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7120 OPC_ADD_D
= FOP(0, FMT_D
),
7121 OPC_SUB_D
= FOP(1, FMT_D
),
7122 OPC_MUL_D
= FOP(2, FMT_D
),
7123 OPC_DIV_D
= FOP(3, FMT_D
),
7124 OPC_SQRT_D
= FOP(4, FMT_D
),
7125 OPC_ABS_D
= FOP(5, FMT_D
),
7126 OPC_MOV_D
= FOP(6, FMT_D
),
7127 OPC_NEG_D
= FOP(7, FMT_D
),
7128 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7129 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7130 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7131 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7132 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7133 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7134 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7135 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7136 OPC_MOVCF_D
= FOP(17, FMT_D
),
7137 OPC_MOVZ_D
= FOP(18, FMT_D
),
7138 OPC_MOVN_D
= FOP(19, FMT_D
),
7139 OPC_RECIP_D
= FOP(21, FMT_D
),
7140 OPC_RSQRT_D
= FOP(22, FMT_D
),
7141 OPC_RECIP2_D
= FOP(28, FMT_D
),
7142 OPC_RECIP1_D
= FOP(29, FMT_D
),
7143 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7144 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7145 OPC_CVT_S_D
= FOP(32, FMT_D
),
7146 OPC_CVT_W_D
= FOP(36, FMT_D
),
7147 OPC_CVT_L_D
= FOP(37, FMT_D
),
7148 OPC_CMP_F_D
= FOP (48, FMT_D
),
7149 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7150 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7151 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7152 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7153 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7154 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7155 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7156 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7157 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7158 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7159 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7160 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7161 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7162 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7163 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7165 OPC_CVT_S_W
= FOP(32, FMT_W
),
7166 OPC_CVT_D_W
= FOP(33, FMT_W
),
7167 OPC_CVT_S_L
= FOP(32, FMT_L
),
7168 OPC_CVT_D_L
= FOP(33, FMT_L
),
7169 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7171 OPC_ADD_PS
= FOP(0, FMT_PS
),
7172 OPC_SUB_PS
= FOP(1, FMT_PS
),
7173 OPC_MUL_PS
= FOP(2, FMT_PS
),
7174 OPC_DIV_PS
= FOP(3, FMT_PS
),
7175 OPC_ABS_PS
= FOP(5, FMT_PS
),
7176 OPC_MOV_PS
= FOP(6, FMT_PS
),
7177 OPC_NEG_PS
= FOP(7, FMT_PS
),
7178 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7179 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7180 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7181 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7182 OPC_MULR_PS
= FOP(26, FMT_PS
),
7183 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7184 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7185 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7186 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7188 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7189 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7190 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7191 OPC_PLL_PS
= FOP(44, FMT_PS
),
7192 OPC_PLU_PS
= FOP(45, FMT_PS
),
7193 OPC_PUL_PS
= FOP(46, FMT_PS
),
7194 OPC_PUU_PS
= FOP(47, FMT_PS
),
7195 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7196 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7197 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7198 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7199 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7200 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7201 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7202 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7203 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7204 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7205 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7206 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7207 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7208 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7209 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7210 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7213 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7215 const char *opn
= "cp1 move";
7216 TCGv t0
= tcg_temp_new();
7221 TCGv_i32 fp0
= tcg_temp_new_i32();
7223 gen_load_fpr32(fp0
, fs
);
7224 tcg_gen_ext_i32_tl(t0
, fp0
);
7225 tcg_temp_free_i32(fp0
);
7227 gen_store_gpr(t0
, rt
);
7231 gen_load_gpr(t0
, rt
);
7233 TCGv_i32 fp0
= tcg_temp_new_i32();
7235 tcg_gen_trunc_tl_i32(fp0
, t0
);
7236 gen_store_fpr32(fp0
, fs
);
7237 tcg_temp_free_i32(fp0
);
7242 gen_helper_1e0i(cfc1
, t0
, fs
);
7243 gen_store_gpr(t0
, rt
);
7247 gen_load_gpr(t0
, rt
);
7248 gen_helper_0e1i(ctc1
, t0
, fs
);
7251 #if defined(TARGET_MIPS64)
7253 gen_load_fpr64(ctx
, t0
, fs
);
7254 gen_store_gpr(t0
, rt
);
7258 gen_load_gpr(t0
, rt
);
7259 gen_store_fpr64(ctx
, t0
, fs
);
7265 TCGv_i32 fp0
= tcg_temp_new_i32();
7267 gen_load_fpr32h(fp0
, fs
);
7268 tcg_gen_ext_i32_tl(t0
, fp0
);
7269 tcg_temp_free_i32(fp0
);
7271 gen_store_gpr(t0
, rt
);
7275 gen_load_gpr(t0
, rt
);
7277 TCGv_i32 fp0
= tcg_temp_new_i32();
7279 tcg_gen_trunc_tl_i32(fp0
, t0
);
7280 gen_store_fpr32h(fp0
, fs
);
7281 tcg_temp_free_i32(fp0
);
7287 generate_exception (ctx
, EXCP_RI
);
7290 (void)opn
; /* avoid a compiler warning */
7291 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7297 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7313 l1
= gen_new_label();
7314 t0
= tcg_temp_new_i32();
7315 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7316 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7317 tcg_temp_free_i32(t0
);
7319 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7321 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7326 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7329 TCGv_i32 t0
= tcg_temp_new_i32();
7330 int l1
= gen_new_label();
7337 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7338 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7339 gen_load_fpr32(t0
, fs
);
7340 gen_store_fpr32(t0
, fd
);
7342 tcg_temp_free_i32(t0
);
7345 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7348 TCGv_i32 t0
= tcg_temp_new_i32();
7350 int l1
= gen_new_label();
7357 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7358 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7359 tcg_temp_free_i32(t0
);
7360 fp0
= tcg_temp_new_i64();
7361 gen_load_fpr64(ctx
, fp0
, fs
);
7362 gen_store_fpr64(ctx
, fp0
, fd
);
7363 tcg_temp_free_i64(fp0
);
7367 static inline void gen_movcf_ps (int fs
, int fd
, int cc
, int tf
)
7370 TCGv_i32 t0
= tcg_temp_new_i32();
7371 int l1
= gen_new_label();
7372 int l2
= gen_new_label();
7379 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7380 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7381 gen_load_fpr32(t0
, fs
);
7382 gen_store_fpr32(t0
, fd
);
7385 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7386 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7387 gen_load_fpr32h(t0
, fs
);
7388 gen_store_fpr32h(t0
, fd
);
7389 tcg_temp_free_i32(t0
);
7394 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7395 int ft
, int fs
, int fd
, int cc
)
7397 const char *opn
= "farith";
7398 const char *condnames
[] = {
7416 const char *condnames_abs
[] = {
7434 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7435 uint32_t func
= ctx
->opcode
& 0x3f;
7440 TCGv_i32 fp0
= tcg_temp_new_i32();
7441 TCGv_i32 fp1
= tcg_temp_new_i32();
7443 gen_load_fpr32(fp0
, fs
);
7444 gen_load_fpr32(fp1
, ft
);
7445 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7446 tcg_temp_free_i32(fp1
);
7447 gen_store_fpr32(fp0
, fd
);
7448 tcg_temp_free_i32(fp0
);
7455 TCGv_i32 fp0
= tcg_temp_new_i32();
7456 TCGv_i32 fp1
= tcg_temp_new_i32();
7458 gen_load_fpr32(fp0
, fs
);
7459 gen_load_fpr32(fp1
, ft
);
7460 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7461 tcg_temp_free_i32(fp1
);
7462 gen_store_fpr32(fp0
, fd
);
7463 tcg_temp_free_i32(fp0
);
7470 TCGv_i32 fp0
= tcg_temp_new_i32();
7471 TCGv_i32 fp1
= tcg_temp_new_i32();
7473 gen_load_fpr32(fp0
, fs
);
7474 gen_load_fpr32(fp1
, ft
);
7475 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7476 tcg_temp_free_i32(fp1
);
7477 gen_store_fpr32(fp0
, fd
);
7478 tcg_temp_free_i32(fp0
);
7485 TCGv_i32 fp0
= tcg_temp_new_i32();
7486 TCGv_i32 fp1
= tcg_temp_new_i32();
7488 gen_load_fpr32(fp0
, fs
);
7489 gen_load_fpr32(fp1
, ft
);
7490 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7491 tcg_temp_free_i32(fp1
);
7492 gen_store_fpr32(fp0
, fd
);
7493 tcg_temp_free_i32(fp0
);
7500 TCGv_i32 fp0
= tcg_temp_new_i32();
7502 gen_load_fpr32(fp0
, fs
);
7503 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7504 gen_store_fpr32(fp0
, fd
);
7505 tcg_temp_free_i32(fp0
);
7511 TCGv_i32 fp0
= tcg_temp_new_i32();
7513 gen_load_fpr32(fp0
, fs
);
7514 gen_helper_float_abs_s(fp0
, fp0
);
7515 gen_store_fpr32(fp0
, fd
);
7516 tcg_temp_free_i32(fp0
);
7522 TCGv_i32 fp0
= tcg_temp_new_i32();
7524 gen_load_fpr32(fp0
, fs
);
7525 gen_store_fpr32(fp0
, fd
);
7526 tcg_temp_free_i32(fp0
);
7532 TCGv_i32 fp0
= tcg_temp_new_i32();
7534 gen_load_fpr32(fp0
, fs
);
7535 gen_helper_float_chs_s(fp0
, fp0
);
7536 gen_store_fpr32(fp0
, fd
);
7537 tcg_temp_free_i32(fp0
);
7542 check_cp1_64bitmode(ctx
);
7544 TCGv_i32 fp32
= tcg_temp_new_i32();
7545 TCGv_i64 fp64
= tcg_temp_new_i64();
7547 gen_load_fpr32(fp32
, fs
);
7548 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7549 tcg_temp_free_i32(fp32
);
7550 gen_store_fpr64(ctx
, fp64
, fd
);
7551 tcg_temp_free_i64(fp64
);
7556 check_cp1_64bitmode(ctx
);
7558 TCGv_i32 fp32
= tcg_temp_new_i32();
7559 TCGv_i64 fp64
= tcg_temp_new_i64();
7561 gen_load_fpr32(fp32
, fs
);
7562 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7563 tcg_temp_free_i32(fp32
);
7564 gen_store_fpr64(ctx
, fp64
, fd
);
7565 tcg_temp_free_i64(fp64
);
7570 check_cp1_64bitmode(ctx
);
7572 TCGv_i32 fp32
= tcg_temp_new_i32();
7573 TCGv_i64 fp64
= tcg_temp_new_i64();
7575 gen_load_fpr32(fp32
, fs
);
7576 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7577 tcg_temp_free_i32(fp32
);
7578 gen_store_fpr64(ctx
, fp64
, fd
);
7579 tcg_temp_free_i64(fp64
);
7584 check_cp1_64bitmode(ctx
);
7586 TCGv_i32 fp32
= tcg_temp_new_i32();
7587 TCGv_i64 fp64
= tcg_temp_new_i64();
7589 gen_load_fpr32(fp32
, fs
);
7590 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7591 tcg_temp_free_i32(fp32
);
7592 gen_store_fpr64(ctx
, fp64
, fd
);
7593 tcg_temp_free_i64(fp64
);
7599 TCGv_i32 fp0
= tcg_temp_new_i32();
7601 gen_load_fpr32(fp0
, fs
);
7602 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7603 gen_store_fpr32(fp0
, fd
);
7604 tcg_temp_free_i32(fp0
);
7610 TCGv_i32 fp0
= tcg_temp_new_i32();
7612 gen_load_fpr32(fp0
, fs
);
7613 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7614 gen_store_fpr32(fp0
, fd
);
7615 tcg_temp_free_i32(fp0
);
7621 TCGv_i32 fp0
= tcg_temp_new_i32();
7623 gen_load_fpr32(fp0
, fs
);
7624 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7625 gen_store_fpr32(fp0
, fd
);
7626 tcg_temp_free_i32(fp0
);
7632 TCGv_i32 fp0
= tcg_temp_new_i32();
7634 gen_load_fpr32(fp0
, fs
);
7635 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7636 gen_store_fpr32(fp0
, fd
);
7637 tcg_temp_free_i32(fp0
);
7642 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7647 int l1
= gen_new_label();
7651 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7653 fp0
= tcg_temp_new_i32();
7654 gen_load_fpr32(fp0
, fs
);
7655 gen_store_fpr32(fp0
, fd
);
7656 tcg_temp_free_i32(fp0
);
7663 int l1
= gen_new_label();
7667 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7668 fp0
= tcg_temp_new_i32();
7669 gen_load_fpr32(fp0
, fs
);
7670 gen_store_fpr32(fp0
, fd
);
7671 tcg_temp_free_i32(fp0
);
7680 TCGv_i32 fp0
= tcg_temp_new_i32();
7682 gen_load_fpr32(fp0
, fs
);
7683 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7684 gen_store_fpr32(fp0
, fd
);
7685 tcg_temp_free_i32(fp0
);
7692 TCGv_i32 fp0
= tcg_temp_new_i32();
7694 gen_load_fpr32(fp0
, fs
);
7695 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7696 gen_store_fpr32(fp0
, fd
);
7697 tcg_temp_free_i32(fp0
);
7702 check_cp1_64bitmode(ctx
);
7704 TCGv_i32 fp0
= tcg_temp_new_i32();
7705 TCGv_i32 fp1
= tcg_temp_new_i32();
7707 gen_load_fpr32(fp0
, fs
);
7708 gen_load_fpr32(fp1
, ft
);
7709 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7710 tcg_temp_free_i32(fp1
);
7711 gen_store_fpr32(fp0
, fd
);
7712 tcg_temp_free_i32(fp0
);
7717 check_cp1_64bitmode(ctx
);
7719 TCGv_i32 fp0
= tcg_temp_new_i32();
7721 gen_load_fpr32(fp0
, fs
);
7722 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7723 gen_store_fpr32(fp0
, fd
);
7724 tcg_temp_free_i32(fp0
);
7729 check_cp1_64bitmode(ctx
);
7731 TCGv_i32 fp0
= tcg_temp_new_i32();
7733 gen_load_fpr32(fp0
, fs
);
7734 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7735 gen_store_fpr32(fp0
, fd
);
7736 tcg_temp_free_i32(fp0
);
7741 check_cp1_64bitmode(ctx
);
7743 TCGv_i32 fp0
= tcg_temp_new_i32();
7744 TCGv_i32 fp1
= tcg_temp_new_i32();
7746 gen_load_fpr32(fp0
, fs
);
7747 gen_load_fpr32(fp1
, ft
);
7748 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7749 tcg_temp_free_i32(fp1
);
7750 gen_store_fpr32(fp0
, fd
);
7751 tcg_temp_free_i32(fp0
);
7756 check_cp1_registers(ctx
, fd
);
7758 TCGv_i32 fp32
= tcg_temp_new_i32();
7759 TCGv_i64 fp64
= tcg_temp_new_i64();
7761 gen_load_fpr32(fp32
, fs
);
7762 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7763 tcg_temp_free_i32(fp32
);
7764 gen_store_fpr64(ctx
, fp64
, fd
);
7765 tcg_temp_free_i64(fp64
);
7771 TCGv_i32 fp0
= tcg_temp_new_i32();
7773 gen_load_fpr32(fp0
, fs
);
7774 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7775 gen_store_fpr32(fp0
, fd
);
7776 tcg_temp_free_i32(fp0
);
7781 check_cp1_64bitmode(ctx
);
7783 TCGv_i32 fp32
= tcg_temp_new_i32();
7784 TCGv_i64 fp64
= tcg_temp_new_i64();
7786 gen_load_fpr32(fp32
, fs
);
7787 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7788 tcg_temp_free_i32(fp32
);
7789 gen_store_fpr64(ctx
, fp64
, fd
);
7790 tcg_temp_free_i64(fp64
);
7795 check_cp1_64bitmode(ctx
);
7797 TCGv_i64 fp64
= tcg_temp_new_i64();
7798 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7799 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7801 gen_load_fpr32(fp32_0
, fs
);
7802 gen_load_fpr32(fp32_1
, ft
);
7803 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7804 tcg_temp_free_i32(fp32_1
);
7805 tcg_temp_free_i32(fp32_0
);
7806 gen_store_fpr64(ctx
, fp64
, fd
);
7807 tcg_temp_free_i64(fp64
);
7820 case OPC_CMP_NGLE_S
:
7827 if (ctx
->opcode
& (1 << 6)) {
7828 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7829 opn
= condnames_abs
[func
-48];
7831 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7832 opn
= condnames
[func
-48];
7836 check_cp1_registers(ctx
, fs
| ft
| fd
);
7838 TCGv_i64 fp0
= tcg_temp_new_i64();
7839 TCGv_i64 fp1
= tcg_temp_new_i64();
7841 gen_load_fpr64(ctx
, fp0
, fs
);
7842 gen_load_fpr64(ctx
, fp1
, ft
);
7843 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7844 tcg_temp_free_i64(fp1
);
7845 gen_store_fpr64(ctx
, fp0
, fd
);
7846 tcg_temp_free_i64(fp0
);
7852 check_cp1_registers(ctx
, fs
| ft
| fd
);
7854 TCGv_i64 fp0
= tcg_temp_new_i64();
7855 TCGv_i64 fp1
= tcg_temp_new_i64();
7857 gen_load_fpr64(ctx
, fp0
, fs
);
7858 gen_load_fpr64(ctx
, fp1
, ft
);
7859 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7860 tcg_temp_free_i64(fp1
);
7861 gen_store_fpr64(ctx
, fp0
, fd
);
7862 tcg_temp_free_i64(fp0
);
7868 check_cp1_registers(ctx
, fs
| ft
| fd
);
7870 TCGv_i64 fp0
= tcg_temp_new_i64();
7871 TCGv_i64 fp1
= tcg_temp_new_i64();
7873 gen_load_fpr64(ctx
, fp0
, fs
);
7874 gen_load_fpr64(ctx
, fp1
, ft
);
7875 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7876 tcg_temp_free_i64(fp1
);
7877 gen_store_fpr64(ctx
, fp0
, fd
);
7878 tcg_temp_free_i64(fp0
);
7884 check_cp1_registers(ctx
, fs
| ft
| fd
);
7886 TCGv_i64 fp0
= tcg_temp_new_i64();
7887 TCGv_i64 fp1
= tcg_temp_new_i64();
7889 gen_load_fpr64(ctx
, fp0
, fs
);
7890 gen_load_fpr64(ctx
, fp1
, ft
);
7891 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7892 tcg_temp_free_i64(fp1
);
7893 gen_store_fpr64(ctx
, fp0
, fd
);
7894 tcg_temp_free_i64(fp0
);
7900 check_cp1_registers(ctx
, fs
| fd
);
7902 TCGv_i64 fp0
= tcg_temp_new_i64();
7904 gen_load_fpr64(ctx
, fp0
, fs
);
7905 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7906 gen_store_fpr64(ctx
, fp0
, fd
);
7907 tcg_temp_free_i64(fp0
);
7912 check_cp1_registers(ctx
, fs
| fd
);
7914 TCGv_i64 fp0
= tcg_temp_new_i64();
7916 gen_load_fpr64(ctx
, fp0
, fs
);
7917 gen_helper_float_abs_d(fp0
, fp0
);
7918 gen_store_fpr64(ctx
, fp0
, fd
);
7919 tcg_temp_free_i64(fp0
);
7924 check_cp1_registers(ctx
, fs
| fd
);
7926 TCGv_i64 fp0
= tcg_temp_new_i64();
7928 gen_load_fpr64(ctx
, fp0
, fs
);
7929 gen_store_fpr64(ctx
, fp0
, fd
);
7930 tcg_temp_free_i64(fp0
);
7935 check_cp1_registers(ctx
, fs
| fd
);
7937 TCGv_i64 fp0
= tcg_temp_new_i64();
7939 gen_load_fpr64(ctx
, fp0
, fs
);
7940 gen_helper_float_chs_d(fp0
, fp0
);
7941 gen_store_fpr64(ctx
, fp0
, fd
);
7942 tcg_temp_free_i64(fp0
);
7947 check_cp1_64bitmode(ctx
);
7949 TCGv_i64 fp0
= tcg_temp_new_i64();
7951 gen_load_fpr64(ctx
, fp0
, fs
);
7952 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
7953 gen_store_fpr64(ctx
, fp0
, fd
);
7954 tcg_temp_free_i64(fp0
);
7959 check_cp1_64bitmode(ctx
);
7961 TCGv_i64 fp0
= tcg_temp_new_i64();
7963 gen_load_fpr64(ctx
, fp0
, fs
);
7964 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
7965 gen_store_fpr64(ctx
, fp0
, fd
);
7966 tcg_temp_free_i64(fp0
);
7971 check_cp1_64bitmode(ctx
);
7973 TCGv_i64 fp0
= tcg_temp_new_i64();
7975 gen_load_fpr64(ctx
, fp0
, fs
);
7976 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
7977 gen_store_fpr64(ctx
, fp0
, fd
);
7978 tcg_temp_free_i64(fp0
);
7983 check_cp1_64bitmode(ctx
);
7985 TCGv_i64 fp0
= tcg_temp_new_i64();
7987 gen_load_fpr64(ctx
, fp0
, fs
);
7988 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
7989 gen_store_fpr64(ctx
, fp0
, fd
);
7990 tcg_temp_free_i64(fp0
);
7995 check_cp1_registers(ctx
, fs
);
7997 TCGv_i32 fp32
= tcg_temp_new_i32();
7998 TCGv_i64 fp64
= tcg_temp_new_i64();
8000 gen_load_fpr64(ctx
, fp64
, fs
);
8001 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8002 tcg_temp_free_i64(fp64
);
8003 gen_store_fpr32(fp32
, fd
);
8004 tcg_temp_free_i32(fp32
);
8009 check_cp1_registers(ctx
, fs
);
8011 TCGv_i32 fp32
= tcg_temp_new_i32();
8012 TCGv_i64 fp64
= tcg_temp_new_i64();
8014 gen_load_fpr64(ctx
, fp64
, fs
);
8015 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8016 tcg_temp_free_i64(fp64
);
8017 gen_store_fpr32(fp32
, fd
);
8018 tcg_temp_free_i32(fp32
);
8023 check_cp1_registers(ctx
, fs
);
8025 TCGv_i32 fp32
= tcg_temp_new_i32();
8026 TCGv_i64 fp64
= tcg_temp_new_i64();
8028 gen_load_fpr64(ctx
, fp64
, fs
);
8029 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8030 tcg_temp_free_i64(fp64
);
8031 gen_store_fpr32(fp32
, fd
);
8032 tcg_temp_free_i32(fp32
);
8037 check_cp1_registers(ctx
, fs
);
8039 TCGv_i32 fp32
= tcg_temp_new_i32();
8040 TCGv_i64 fp64
= tcg_temp_new_i64();
8042 gen_load_fpr64(ctx
, fp64
, fs
);
8043 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8044 tcg_temp_free_i64(fp64
);
8045 gen_store_fpr32(fp32
, fd
);
8046 tcg_temp_free_i32(fp32
);
8051 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8056 int l1
= gen_new_label();
8060 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8062 fp0
= tcg_temp_new_i64();
8063 gen_load_fpr64(ctx
, fp0
, fs
);
8064 gen_store_fpr64(ctx
, fp0
, fd
);
8065 tcg_temp_free_i64(fp0
);
8072 int l1
= gen_new_label();
8076 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8077 fp0
= tcg_temp_new_i64();
8078 gen_load_fpr64(ctx
, fp0
, fs
);
8079 gen_store_fpr64(ctx
, fp0
, fd
);
8080 tcg_temp_free_i64(fp0
);
8087 check_cp1_64bitmode(ctx
);
8089 TCGv_i64 fp0
= tcg_temp_new_i64();
8091 gen_load_fpr64(ctx
, fp0
, fs
);
8092 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8093 gen_store_fpr64(ctx
, fp0
, fd
);
8094 tcg_temp_free_i64(fp0
);
8099 check_cp1_64bitmode(ctx
);
8101 TCGv_i64 fp0
= tcg_temp_new_i64();
8103 gen_load_fpr64(ctx
, fp0
, fs
);
8104 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8105 gen_store_fpr64(ctx
, fp0
, fd
);
8106 tcg_temp_free_i64(fp0
);
8111 check_cp1_64bitmode(ctx
);
8113 TCGv_i64 fp0
= tcg_temp_new_i64();
8114 TCGv_i64 fp1
= tcg_temp_new_i64();
8116 gen_load_fpr64(ctx
, fp0
, fs
);
8117 gen_load_fpr64(ctx
, fp1
, ft
);
8118 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8119 tcg_temp_free_i64(fp1
);
8120 gen_store_fpr64(ctx
, fp0
, fd
);
8121 tcg_temp_free_i64(fp0
);
8126 check_cp1_64bitmode(ctx
);
8128 TCGv_i64 fp0
= tcg_temp_new_i64();
8130 gen_load_fpr64(ctx
, fp0
, fs
);
8131 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8132 gen_store_fpr64(ctx
, fp0
, fd
);
8133 tcg_temp_free_i64(fp0
);
8138 check_cp1_64bitmode(ctx
);
8140 TCGv_i64 fp0
= tcg_temp_new_i64();
8142 gen_load_fpr64(ctx
, fp0
, fs
);
8143 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8144 gen_store_fpr64(ctx
, fp0
, fd
);
8145 tcg_temp_free_i64(fp0
);
8150 check_cp1_64bitmode(ctx
);
8152 TCGv_i64 fp0
= tcg_temp_new_i64();
8153 TCGv_i64 fp1
= tcg_temp_new_i64();
8155 gen_load_fpr64(ctx
, fp0
, fs
);
8156 gen_load_fpr64(ctx
, fp1
, ft
);
8157 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8158 tcg_temp_free_i64(fp1
);
8159 gen_store_fpr64(ctx
, fp0
, fd
);
8160 tcg_temp_free_i64(fp0
);
8173 case OPC_CMP_NGLE_D
:
8180 if (ctx
->opcode
& (1 << 6)) {
8181 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8182 opn
= condnames_abs
[func
-48];
8184 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8185 opn
= condnames
[func
-48];
8189 check_cp1_registers(ctx
, fs
);
8191 TCGv_i32 fp32
= tcg_temp_new_i32();
8192 TCGv_i64 fp64
= tcg_temp_new_i64();
8194 gen_load_fpr64(ctx
, fp64
, fs
);
8195 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8196 tcg_temp_free_i64(fp64
);
8197 gen_store_fpr32(fp32
, fd
);
8198 tcg_temp_free_i32(fp32
);
8203 check_cp1_registers(ctx
, fs
);
8205 TCGv_i32 fp32
= tcg_temp_new_i32();
8206 TCGv_i64 fp64
= tcg_temp_new_i64();
8208 gen_load_fpr64(ctx
, fp64
, fs
);
8209 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8210 tcg_temp_free_i64(fp64
);
8211 gen_store_fpr32(fp32
, fd
);
8212 tcg_temp_free_i32(fp32
);
8217 check_cp1_64bitmode(ctx
);
8219 TCGv_i64 fp0
= tcg_temp_new_i64();
8221 gen_load_fpr64(ctx
, fp0
, fs
);
8222 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8223 gen_store_fpr64(ctx
, fp0
, fd
);
8224 tcg_temp_free_i64(fp0
);
8230 TCGv_i32 fp0
= tcg_temp_new_i32();
8232 gen_load_fpr32(fp0
, fs
);
8233 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8234 gen_store_fpr32(fp0
, fd
);
8235 tcg_temp_free_i32(fp0
);
8240 check_cp1_registers(ctx
, fd
);
8242 TCGv_i32 fp32
= tcg_temp_new_i32();
8243 TCGv_i64 fp64
= tcg_temp_new_i64();
8245 gen_load_fpr32(fp32
, fs
);
8246 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8247 tcg_temp_free_i32(fp32
);
8248 gen_store_fpr64(ctx
, fp64
, fd
);
8249 tcg_temp_free_i64(fp64
);
8254 check_cp1_64bitmode(ctx
);
8256 TCGv_i32 fp32
= tcg_temp_new_i32();
8257 TCGv_i64 fp64
= tcg_temp_new_i64();
8259 gen_load_fpr64(ctx
, fp64
, fs
);
8260 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8261 tcg_temp_free_i64(fp64
);
8262 gen_store_fpr32(fp32
, fd
);
8263 tcg_temp_free_i32(fp32
);
8268 check_cp1_64bitmode(ctx
);
8270 TCGv_i64 fp0
= tcg_temp_new_i64();
8272 gen_load_fpr64(ctx
, fp0
, fs
);
8273 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8274 gen_store_fpr64(ctx
, fp0
, fd
);
8275 tcg_temp_free_i64(fp0
);
8280 check_cp1_64bitmode(ctx
);
8282 TCGv_i64 fp0
= tcg_temp_new_i64();
8284 gen_load_fpr64(ctx
, fp0
, fs
);
8285 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8286 gen_store_fpr64(ctx
, fp0
, fd
);
8287 tcg_temp_free_i64(fp0
);
8292 check_cp1_64bitmode(ctx
);
8294 TCGv_i64 fp0
= tcg_temp_new_i64();
8295 TCGv_i64 fp1
= tcg_temp_new_i64();
8297 gen_load_fpr64(ctx
, fp0
, fs
);
8298 gen_load_fpr64(ctx
, fp1
, ft
);
8299 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8300 tcg_temp_free_i64(fp1
);
8301 gen_store_fpr64(ctx
, fp0
, fd
);
8302 tcg_temp_free_i64(fp0
);
8307 check_cp1_64bitmode(ctx
);
8309 TCGv_i64 fp0
= tcg_temp_new_i64();
8310 TCGv_i64 fp1
= tcg_temp_new_i64();
8312 gen_load_fpr64(ctx
, fp0
, fs
);
8313 gen_load_fpr64(ctx
, fp1
, ft
);
8314 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8315 tcg_temp_free_i64(fp1
);
8316 gen_store_fpr64(ctx
, fp0
, fd
);
8317 tcg_temp_free_i64(fp0
);
8322 check_cp1_64bitmode(ctx
);
8324 TCGv_i64 fp0
= tcg_temp_new_i64();
8325 TCGv_i64 fp1
= tcg_temp_new_i64();
8327 gen_load_fpr64(ctx
, fp0
, fs
);
8328 gen_load_fpr64(ctx
, fp1
, ft
);
8329 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8330 tcg_temp_free_i64(fp1
);
8331 gen_store_fpr64(ctx
, fp0
, fd
);
8332 tcg_temp_free_i64(fp0
);
8337 check_cp1_64bitmode(ctx
);
8339 TCGv_i64 fp0
= tcg_temp_new_i64();
8341 gen_load_fpr64(ctx
, fp0
, fs
);
8342 gen_helper_float_abs_ps(fp0
, fp0
);
8343 gen_store_fpr64(ctx
, fp0
, fd
);
8344 tcg_temp_free_i64(fp0
);
8349 check_cp1_64bitmode(ctx
);
8351 TCGv_i64 fp0
= tcg_temp_new_i64();
8353 gen_load_fpr64(ctx
, fp0
, fs
);
8354 gen_store_fpr64(ctx
, fp0
, fd
);
8355 tcg_temp_free_i64(fp0
);
8360 check_cp1_64bitmode(ctx
);
8362 TCGv_i64 fp0
= tcg_temp_new_i64();
8364 gen_load_fpr64(ctx
, fp0
, fs
);
8365 gen_helper_float_chs_ps(fp0
, fp0
);
8366 gen_store_fpr64(ctx
, fp0
, fd
);
8367 tcg_temp_free_i64(fp0
);
8372 check_cp1_64bitmode(ctx
);
8373 gen_movcf_ps(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8377 check_cp1_64bitmode(ctx
);
8379 int l1
= gen_new_label();
8383 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8384 fp0
= tcg_temp_new_i64();
8385 gen_load_fpr64(ctx
, fp0
, fs
);
8386 gen_store_fpr64(ctx
, fp0
, fd
);
8387 tcg_temp_free_i64(fp0
);
8393 check_cp1_64bitmode(ctx
);
8395 int l1
= gen_new_label();
8399 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8400 fp0
= tcg_temp_new_i64();
8401 gen_load_fpr64(ctx
, fp0
, fs
);
8402 gen_store_fpr64(ctx
, fp0
, fd
);
8403 tcg_temp_free_i64(fp0
);
8410 check_cp1_64bitmode(ctx
);
8412 TCGv_i64 fp0
= tcg_temp_new_i64();
8413 TCGv_i64 fp1
= tcg_temp_new_i64();
8415 gen_load_fpr64(ctx
, fp0
, ft
);
8416 gen_load_fpr64(ctx
, fp1
, fs
);
8417 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8418 tcg_temp_free_i64(fp1
);
8419 gen_store_fpr64(ctx
, fp0
, fd
);
8420 tcg_temp_free_i64(fp0
);
8425 check_cp1_64bitmode(ctx
);
8427 TCGv_i64 fp0
= tcg_temp_new_i64();
8428 TCGv_i64 fp1
= tcg_temp_new_i64();
8430 gen_load_fpr64(ctx
, fp0
, ft
);
8431 gen_load_fpr64(ctx
, fp1
, fs
);
8432 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8433 tcg_temp_free_i64(fp1
);
8434 gen_store_fpr64(ctx
, fp0
, fd
);
8435 tcg_temp_free_i64(fp0
);
8440 check_cp1_64bitmode(ctx
);
8442 TCGv_i64 fp0
= tcg_temp_new_i64();
8443 TCGv_i64 fp1
= tcg_temp_new_i64();
8445 gen_load_fpr64(ctx
, fp0
, fs
);
8446 gen_load_fpr64(ctx
, fp1
, ft
);
8447 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8448 tcg_temp_free_i64(fp1
);
8449 gen_store_fpr64(ctx
, fp0
, fd
);
8450 tcg_temp_free_i64(fp0
);
8455 check_cp1_64bitmode(ctx
);
8457 TCGv_i64 fp0
= tcg_temp_new_i64();
8459 gen_load_fpr64(ctx
, fp0
, fs
);
8460 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
8461 gen_store_fpr64(ctx
, fp0
, fd
);
8462 tcg_temp_free_i64(fp0
);
8467 check_cp1_64bitmode(ctx
);
8469 TCGv_i64 fp0
= tcg_temp_new_i64();
8471 gen_load_fpr64(ctx
, fp0
, fs
);
8472 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8473 gen_store_fpr64(ctx
, fp0
, fd
);
8474 tcg_temp_free_i64(fp0
);
8479 check_cp1_64bitmode(ctx
);
8481 TCGv_i64 fp0
= tcg_temp_new_i64();
8482 TCGv_i64 fp1
= tcg_temp_new_i64();
8484 gen_load_fpr64(ctx
, fp0
, fs
);
8485 gen_load_fpr64(ctx
, fp1
, ft
);
8486 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8487 tcg_temp_free_i64(fp1
);
8488 gen_store_fpr64(ctx
, fp0
, fd
);
8489 tcg_temp_free_i64(fp0
);
8494 check_cp1_64bitmode(ctx
);
8496 TCGv_i32 fp0
= tcg_temp_new_i32();
8498 gen_load_fpr32h(fp0
, fs
);
8499 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8500 gen_store_fpr32(fp0
, fd
);
8501 tcg_temp_free_i32(fp0
);
8506 check_cp1_64bitmode(ctx
);
8508 TCGv_i64 fp0
= tcg_temp_new_i64();
8510 gen_load_fpr64(ctx
, fp0
, fs
);
8511 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8512 gen_store_fpr64(ctx
, fp0
, fd
);
8513 tcg_temp_free_i64(fp0
);
8518 check_cp1_64bitmode(ctx
);
8520 TCGv_i32 fp0
= tcg_temp_new_i32();
8522 gen_load_fpr32(fp0
, fs
);
8523 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8524 gen_store_fpr32(fp0
, fd
);
8525 tcg_temp_free_i32(fp0
);
8530 check_cp1_64bitmode(ctx
);
8532 TCGv_i32 fp0
= tcg_temp_new_i32();
8533 TCGv_i32 fp1
= tcg_temp_new_i32();
8535 gen_load_fpr32(fp0
, fs
);
8536 gen_load_fpr32(fp1
, ft
);
8537 gen_store_fpr32h(fp0
, fd
);
8538 gen_store_fpr32(fp1
, fd
);
8539 tcg_temp_free_i32(fp0
);
8540 tcg_temp_free_i32(fp1
);
8545 check_cp1_64bitmode(ctx
);
8547 TCGv_i32 fp0
= tcg_temp_new_i32();
8548 TCGv_i32 fp1
= tcg_temp_new_i32();
8550 gen_load_fpr32(fp0
, fs
);
8551 gen_load_fpr32h(fp1
, ft
);
8552 gen_store_fpr32(fp1
, fd
);
8553 gen_store_fpr32h(fp0
, fd
);
8554 tcg_temp_free_i32(fp0
);
8555 tcg_temp_free_i32(fp1
);
8560 check_cp1_64bitmode(ctx
);
8562 TCGv_i32 fp0
= tcg_temp_new_i32();
8563 TCGv_i32 fp1
= tcg_temp_new_i32();
8565 gen_load_fpr32h(fp0
, fs
);
8566 gen_load_fpr32(fp1
, ft
);
8567 gen_store_fpr32(fp1
, fd
);
8568 gen_store_fpr32h(fp0
, fd
);
8569 tcg_temp_free_i32(fp0
);
8570 tcg_temp_free_i32(fp1
);
8575 check_cp1_64bitmode(ctx
);
8577 TCGv_i32 fp0
= tcg_temp_new_i32();
8578 TCGv_i32 fp1
= tcg_temp_new_i32();
8580 gen_load_fpr32h(fp0
, fs
);
8581 gen_load_fpr32h(fp1
, ft
);
8582 gen_store_fpr32(fp1
, fd
);
8583 gen_store_fpr32h(fp0
, fd
);
8584 tcg_temp_free_i32(fp0
);
8585 tcg_temp_free_i32(fp1
);
8592 case OPC_CMP_UEQ_PS
:
8593 case OPC_CMP_OLT_PS
:
8594 case OPC_CMP_ULT_PS
:
8595 case OPC_CMP_OLE_PS
:
8596 case OPC_CMP_ULE_PS
:
8598 case OPC_CMP_NGLE_PS
:
8599 case OPC_CMP_SEQ_PS
:
8600 case OPC_CMP_NGL_PS
:
8602 case OPC_CMP_NGE_PS
:
8604 case OPC_CMP_NGT_PS
:
8605 if (ctx
->opcode
& (1 << 6)) {
8606 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8607 opn
= condnames_abs
[func
-48];
8609 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8610 opn
= condnames
[func
-48];
8615 generate_exception (ctx
, EXCP_RI
);
8618 (void)opn
; /* avoid a compiler warning */
8621 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8624 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8627 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8632 /* Coprocessor 3 (FPU) */
8633 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8634 int fd
, int fs
, int base
, int index
)
8636 const char *opn
= "extended float load/store";
8638 TCGv t0
= tcg_temp_new();
8641 gen_load_gpr(t0
, index
);
8642 } else if (index
== 0) {
8643 gen_load_gpr(t0
, base
);
8645 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8647 /* Don't do NOP if destination is zero: we must perform the actual
8653 TCGv_i32 fp0
= tcg_temp_new_i32();
8655 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
8656 tcg_gen_trunc_tl_i32(fp0
, t0
);
8657 gen_store_fpr32(fp0
, fd
);
8658 tcg_temp_free_i32(fp0
);
8664 check_cp1_registers(ctx
, fd
);
8666 TCGv_i64 fp0
= tcg_temp_new_i64();
8668 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8669 gen_store_fpr64(ctx
, fp0
, fd
);
8670 tcg_temp_free_i64(fp0
);
8675 check_cp1_64bitmode(ctx
);
8676 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8678 TCGv_i64 fp0
= tcg_temp_new_i64();
8680 tcg_gen_qemu_ld64(fp0
, t0
, ctx
->mem_idx
);
8681 gen_store_fpr64(ctx
, fp0
, fd
);
8682 tcg_temp_free_i64(fp0
);
8689 TCGv_i32 fp0
= tcg_temp_new_i32();
8690 TCGv t1
= tcg_temp_new();
8692 gen_load_fpr32(fp0
, fs
);
8693 tcg_gen_extu_i32_tl(t1
, fp0
);
8694 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
8695 tcg_temp_free_i32(fp0
);
8703 check_cp1_registers(ctx
, fs
);
8705 TCGv_i64 fp0
= tcg_temp_new_i64();
8707 gen_load_fpr64(ctx
, fp0
, fs
);
8708 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8709 tcg_temp_free_i64(fp0
);
8715 check_cp1_64bitmode(ctx
);
8716 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8718 TCGv_i64 fp0
= tcg_temp_new_i64();
8720 gen_load_fpr64(ctx
, fp0
, fs
);
8721 tcg_gen_qemu_st64(fp0
, t0
, ctx
->mem_idx
);
8722 tcg_temp_free_i64(fp0
);
8729 (void)opn
; (void)store
; /* avoid compiler warnings */
8730 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8731 regnames
[index
], regnames
[base
]);
8734 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8735 int fd
, int fr
, int fs
, int ft
)
8737 const char *opn
= "flt3_arith";
8741 check_cp1_64bitmode(ctx
);
8743 TCGv t0
= tcg_temp_local_new();
8744 TCGv_i32 fp
= tcg_temp_new_i32();
8745 TCGv_i32 fph
= tcg_temp_new_i32();
8746 int l1
= gen_new_label();
8747 int l2
= gen_new_label();
8749 gen_load_gpr(t0
, fr
);
8750 tcg_gen_andi_tl(t0
, t0
, 0x7);
8752 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8753 gen_load_fpr32(fp
, fs
);
8754 gen_load_fpr32h(fph
, fs
);
8755 gen_store_fpr32(fp
, fd
);
8756 gen_store_fpr32h(fph
, fd
);
8759 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8761 #ifdef TARGET_WORDS_BIGENDIAN
8762 gen_load_fpr32(fp
, fs
);
8763 gen_load_fpr32h(fph
, ft
);
8764 gen_store_fpr32h(fp
, fd
);
8765 gen_store_fpr32(fph
, fd
);
8767 gen_load_fpr32h(fph
, fs
);
8768 gen_load_fpr32(fp
, ft
);
8769 gen_store_fpr32(fph
, fd
);
8770 gen_store_fpr32h(fp
, fd
);
8773 tcg_temp_free_i32(fp
);
8774 tcg_temp_free_i32(fph
);
8781 TCGv_i32 fp0
= tcg_temp_new_i32();
8782 TCGv_i32 fp1
= tcg_temp_new_i32();
8783 TCGv_i32 fp2
= tcg_temp_new_i32();
8785 gen_load_fpr32(fp0
, fs
);
8786 gen_load_fpr32(fp1
, ft
);
8787 gen_load_fpr32(fp2
, fr
);
8788 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8789 tcg_temp_free_i32(fp0
);
8790 tcg_temp_free_i32(fp1
);
8791 gen_store_fpr32(fp2
, fd
);
8792 tcg_temp_free_i32(fp2
);
8798 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8800 TCGv_i64 fp0
= tcg_temp_new_i64();
8801 TCGv_i64 fp1
= tcg_temp_new_i64();
8802 TCGv_i64 fp2
= tcg_temp_new_i64();
8804 gen_load_fpr64(ctx
, fp0
, fs
);
8805 gen_load_fpr64(ctx
, fp1
, ft
);
8806 gen_load_fpr64(ctx
, fp2
, fr
);
8807 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8808 tcg_temp_free_i64(fp0
);
8809 tcg_temp_free_i64(fp1
);
8810 gen_store_fpr64(ctx
, fp2
, fd
);
8811 tcg_temp_free_i64(fp2
);
8816 check_cp1_64bitmode(ctx
);
8818 TCGv_i64 fp0
= tcg_temp_new_i64();
8819 TCGv_i64 fp1
= tcg_temp_new_i64();
8820 TCGv_i64 fp2
= tcg_temp_new_i64();
8822 gen_load_fpr64(ctx
, fp0
, fs
);
8823 gen_load_fpr64(ctx
, fp1
, ft
);
8824 gen_load_fpr64(ctx
, fp2
, fr
);
8825 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8826 tcg_temp_free_i64(fp0
);
8827 tcg_temp_free_i64(fp1
);
8828 gen_store_fpr64(ctx
, fp2
, fd
);
8829 tcg_temp_free_i64(fp2
);
8836 TCGv_i32 fp0
= tcg_temp_new_i32();
8837 TCGv_i32 fp1
= tcg_temp_new_i32();
8838 TCGv_i32 fp2
= tcg_temp_new_i32();
8840 gen_load_fpr32(fp0
, fs
);
8841 gen_load_fpr32(fp1
, ft
);
8842 gen_load_fpr32(fp2
, fr
);
8843 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8844 tcg_temp_free_i32(fp0
);
8845 tcg_temp_free_i32(fp1
);
8846 gen_store_fpr32(fp2
, fd
);
8847 tcg_temp_free_i32(fp2
);
8853 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8855 TCGv_i64 fp0
= tcg_temp_new_i64();
8856 TCGv_i64 fp1
= tcg_temp_new_i64();
8857 TCGv_i64 fp2
= tcg_temp_new_i64();
8859 gen_load_fpr64(ctx
, fp0
, fs
);
8860 gen_load_fpr64(ctx
, fp1
, ft
);
8861 gen_load_fpr64(ctx
, fp2
, fr
);
8862 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8863 tcg_temp_free_i64(fp0
);
8864 tcg_temp_free_i64(fp1
);
8865 gen_store_fpr64(ctx
, fp2
, fd
);
8866 tcg_temp_free_i64(fp2
);
8871 check_cp1_64bitmode(ctx
);
8873 TCGv_i64 fp0
= tcg_temp_new_i64();
8874 TCGv_i64 fp1
= tcg_temp_new_i64();
8875 TCGv_i64 fp2
= tcg_temp_new_i64();
8877 gen_load_fpr64(ctx
, fp0
, fs
);
8878 gen_load_fpr64(ctx
, fp1
, ft
);
8879 gen_load_fpr64(ctx
, fp2
, fr
);
8880 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8881 tcg_temp_free_i64(fp0
);
8882 tcg_temp_free_i64(fp1
);
8883 gen_store_fpr64(ctx
, fp2
, fd
);
8884 tcg_temp_free_i64(fp2
);
8891 TCGv_i32 fp0
= tcg_temp_new_i32();
8892 TCGv_i32 fp1
= tcg_temp_new_i32();
8893 TCGv_i32 fp2
= tcg_temp_new_i32();
8895 gen_load_fpr32(fp0
, fs
);
8896 gen_load_fpr32(fp1
, ft
);
8897 gen_load_fpr32(fp2
, fr
);
8898 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8899 tcg_temp_free_i32(fp0
);
8900 tcg_temp_free_i32(fp1
);
8901 gen_store_fpr32(fp2
, fd
);
8902 tcg_temp_free_i32(fp2
);
8908 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8910 TCGv_i64 fp0
= tcg_temp_new_i64();
8911 TCGv_i64 fp1
= tcg_temp_new_i64();
8912 TCGv_i64 fp2
= tcg_temp_new_i64();
8914 gen_load_fpr64(ctx
, fp0
, fs
);
8915 gen_load_fpr64(ctx
, fp1
, ft
);
8916 gen_load_fpr64(ctx
, fp2
, fr
);
8917 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8918 tcg_temp_free_i64(fp0
);
8919 tcg_temp_free_i64(fp1
);
8920 gen_store_fpr64(ctx
, fp2
, fd
);
8921 tcg_temp_free_i64(fp2
);
8926 check_cp1_64bitmode(ctx
);
8928 TCGv_i64 fp0
= tcg_temp_new_i64();
8929 TCGv_i64 fp1
= tcg_temp_new_i64();
8930 TCGv_i64 fp2
= tcg_temp_new_i64();
8932 gen_load_fpr64(ctx
, fp0
, fs
);
8933 gen_load_fpr64(ctx
, fp1
, ft
);
8934 gen_load_fpr64(ctx
, fp2
, fr
);
8935 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8936 tcg_temp_free_i64(fp0
);
8937 tcg_temp_free_i64(fp1
);
8938 gen_store_fpr64(ctx
, fp2
, fd
);
8939 tcg_temp_free_i64(fp2
);
8946 TCGv_i32 fp0
= tcg_temp_new_i32();
8947 TCGv_i32 fp1
= tcg_temp_new_i32();
8948 TCGv_i32 fp2
= tcg_temp_new_i32();
8950 gen_load_fpr32(fp0
, fs
);
8951 gen_load_fpr32(fp1
, ft
);
8952 gen_load_fpr32(fp2
, fr
);
8953 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8954 tcg_temp_free_i32(fp0
);
8955 tcg_temp_free_i32(fp1
);
8956 gen_store_fpr32(fp2
, fd
);
8957 tcg_temp_free_i32(fp2
);
8963 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8965 TCGv_i64 fp0
= tcg_temp_new_i64();
8966 TCGv_i64 fp1
= tcg_temp_new_i64();
8967 TCGv_i64 fp2
= tcg_temp_new_i64();
8969 gen_load_fpr64(ctx
, fp0
, fs
);
8970 gen_load_fpr64(ctx
, fp1
, ft
);
8971 gen_load_fpr64(ctx
, fp2
, fr
);
8972 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8973 tcg_temp_free_i64(fp0
);
8974 tcg_temp_free_i64(fp1
);
8975 gen_store_fpr64(ctx
, fp2
, fd
);
8976 tcg_temp_free_i64(fp2
);
8981 check_cp1_64bitmode(ctx
);
8983 TCGv_i64 fp0
= tcg_temp_new_i64();
8984 TCGv_i64 fp1
= tcg_temp_new_i64();
8985 TCGv_i64 fp2
= tcg_temp_new_i64();
8987 gen_load_fpr64(ctx
, fp0
, fs
);
8988 gen_load_fpr64(ctx
, fp1
, ft
);
8989 gen_load_fpr64(ctx
, fp2
, fr
);
8990 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8991 tcg_temp_free_i64(fp0
);
8992 tcg_temp_free_i64(fp1
);
8993 gen_store_fpr64(ctx
, fp2
, fd
);
8994 tcg_temp_free_i64(fp2
);
9000 generate_exception (ctx
, EXCP_RI
);
9003 (void)opn
; /* avoid a compiler warning */
9004 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9005 fregnames
[fs
], fregnames
[ft
]);
9008 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
9012 #if !defined(CONFIG_USER_ONLY)
9013 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9014 Therefore only check the ISA in system mode. */
9015 check_insn(ctx
, ISA_MIPS32R2
);
9017 t0
= tcg_temp_new();
9021 save_cpu_state(ctx
, 1);
9022 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9023 gen_store_gpr(t0
, rt
);
9026 save_cpu_state(ctx
, 1);
9027 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9028 gen_store_gpr(t0
, rt
);
9031 save_cpu_state(ctx
, 1);
9032 gen_helper_rdhwr_cc(t0
, cpu_env
);
9033 gen_store_gpr(t0
, rt
);
9036 save_cpu_state(ctx
, 1);
9037 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9038 gen_store_gpr(t0
, rt
);
9041 #if defined(CONFIG_USER_ONLY)
9042 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUMIPSState
, tls_value
));
9043 gen_store_gpr(t0
, rt
);
9046 /* XXX: Some CPUs implement this in hardware.
9047 Not supported yet. */
9049 default: /* Invalid */
9050 MIPS_INVAL("rdhwr");
9051 generate_exception(ctx
, EXCP_RI
);
9057 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9059 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9060 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9061 /* Branches completion */
9062 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9063 ctx
->bstate
= BS_BRANCH
;
9064 save_cpu_state(ctx
, 0);
9065 /* FIXME: Need to clear can_do_io. */
9066 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9068 /* unconditional branch */
9069 MIPS_DEBUG("unconditional branch");
9070 if (proc_hflags
& MIPS_HFLAG_BX
) {
9071 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9073 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9076 /* blikely taken case */
9077 MIPS_DEBUG("blikely branch taken");
9078 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9081 /* Conditional branch */
9082 MIPS_DEBUG("conditional branch");
9084 int l1
= gen_new_label();
9086 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9087 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9089 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9093 /* unconditional branch to register */
9094 MIPS_DEBUG("branch to register");
9095 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9096 TCGv t0
= tcg_temp_new();
9097 TCGv_i32 t1
= tcg_temp_new_i32();
9099 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9100 tcg_gen_trunc_tl_i32(t1
, t0
);
9102 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9103 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9104 tcg_gen_or_i32(hflags
, hflags
, t1
);
9105 tcg_temp_free_i32(t1
);
9107 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9109 tcg_gen_mov_tl(cpu_PC
, btarget
);
9111 if (ctx
->singlestep_enabled
) {
9112 save_cpu_state(ctx
, 0);
9113 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9118 MIPS_DEBUG("unknown branch");
9124 /* ISA extensions (ASEs) */
9125 /* MIPS16 extension to MIPS32 */
9127 /* MIPS16 major opcodes */
9129 M16_OPC_ADDIUSP
= 0x00,
9130 M16_OPC_ADDIUPC
= 0x01,
9133 M16_OPC_BEQZ
= 0x04,
9134 M16_OPC_BNEQZ
= 0x05,
9135 M16_OPC_SHIFT
= 0x06,
9137 M16_OPC_RRIA
= 0x08,
9138 M16_OPC_ADDIU8
= 0x09,
9139 M16_OPC_SLTI
= 0x0a,
9140 M16_OPC_SLTIU
= 0x0b,
9143 M16_OPC_CMPI
= 0x0e,
9147 M16_OPC_LWSP
= 0x12,
9151 M16_OPC_LWPC
= 0x16,
9155 M16_OPC_SWSP
= 0x1a,
9159 M16_OPC_EXTEND
= 0x1e,
9163 /* I8 funct field */
9182 /* RR funct field */
9216 /* I64 funct field */
9228 /* RR ry field for CNVT */
9230 RR_RY_CNVT_ZEB
= 0x0,
9231 RR_RY_CNVT_ZEH
= 0x1,
9232 RR_RY_CNVT_ZEW
= 0x2,
9233 RR_RY_CNVT_SEB
= 0x4,
9234 RR_RY_CNVT_SEH
= 0x5,
9235 RR_RY_CNVT_SEW
= 0x6,
9238 static int xlat (int r
)
9240 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9245 static void gen_mips16_save (DisasContext
*ctx
,
9246 int xsregs
, int aregs
,
9247 int do_ra
, int do_s0
, int do_s1
,
9250 TCGv t0
= tcg_temp_new();
9251 TCGv t1
= tcg_temp_new();
9281 generate_exception(ctx
, EXCP_RI
);
9287 gen_base_offset_addr(ctx
, t0
, 29, 12);
9288 gen_load_gpr(t1
, 7);
9289 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9292 gen_base_offset_addr(ctx
, t0
, 29, 8);
9293 gen_load_gpr(t1
, 6);
9294 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9297 gen_base_offset_addr(ctx
, t0
, 29, 4);
9298 gen_load_gpr(t1
, 5);
9299 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9302 gen_base_offset_addr(ctx
, t0
, 29, 0);
9303 gen_load_gpr(t1
, 4);
9304 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
9307 gen_load_gpr(t0
, 29);
9309 #define DECR_AND_STORE(reg) do { \
9310 tcg_gen_subi_tl(t0, t0, 4); \
9311 gen_load_gpr(t1, reg); \
9312 tcg_gen_qemu_st32(t1, t0, ctx->mem_idx); \
9376 generate_exception(ctx
, EXCP_RI
);
9392 #undef DECR_AND_STORE
9394 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9399 static void gen_mips16_restore (DisasContext
*ctx
,
9400 int xsregs
, int aregs
,
9401 int do_ra
, int do_s0
, int do_s1
,
9405 TCGv t0
= tcg_temp_new();
9406 TCGv t1
= tcg_temp_new();
9408 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9410 #define DECR_AND_LOAD(reg) do { \
9411 tcg_gen_subi_tl(t0, t0, 4); \
9412 tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
9413 gen_store_gpr(t1, reg); \
9477 generate_exception(ctx
, EXCP_RI
);
9493 #undef DECR_AND_LOAD
9495 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9500 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9501 int is_64_bit
, int extended
)
9505 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9506 generate_exception(ctx
, EXCP_RI
);
9510 t0
= tcg_temp_new();
9512 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9513 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9515 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9521 #if defined(TARGET_MIPS64)
9522 static void decode_i64_mips16 (DisasContext
*ctx
,
9523 int ry
, int funct
, int16_t offset
,
9529 offset
= extended
? offset
: offset
<< 3;
9530 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9534 offset
= extended
? offset
: offset
<< 3;
9535 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9539 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9540 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9544 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9545 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9548 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9549 generate_exception(ctx
, EXCP_RI
);
9551 offset
= extended
? offset
: offset
<< 3;
9552 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9557 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9558 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9562 offset
= extended
? offset
: offset
<< 2;
9563 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9567 offset
= extended
? offset
: offset
<< 2;
9568 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9574 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
9577 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9578 int op
, rx
, ry
, funct
, sa
;
9579 int16_t imm
, offset
;
9581 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9582 op
= (ctx
->opcode
>> 11) & 0x1f;
9583 sa
= (ctx
->opcode
>> 22) & 0x1f;
9584 funct
= (ctx
->opcode
>> 8) & 0x7;
9585 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9586 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9587 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9588 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9589 | (ctx
->opcode
& 0x1f));
9591 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9594 case M16_OPC_ADDIUSP
:
9595 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9597 case M16_OPC_ADDIUPC
:
9598 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9601 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9602 /* No delay slot, so just process as a normal instruction */
9605 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9606 /* No delay slot, so just process as a normal instruction */
9609 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9610 /* No delay slot, so just process as a normal instruction */
9613 switch (ctx
->opcode
& 0x3) {
9615 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9618 #if defined(TARGET_MIPS64)
9620 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9622 generate_exception(ctx
, EXCP_RI
);
9626 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9629 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9633 #if defined(TARGET_MIPS64)
9636 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9640 imm
= ctx
->opcode
& 0xf;
9641 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9642 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9643 imm
= (int16_t) (imm
<< 1) >> 1;
9644 if ((ctx
->opcode
>> 4) & 0x1) {
9645 #if defined(TARGET_MIPS64)
9647 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9649 generate_exception(ctx
, EXCP_RI
);
9652 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9655 case M16_OPC_ADDIU8
:
9656 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9659 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9662 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9667 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9670 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9673 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9676 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9680 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9681 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9682 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9683 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9684 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9685 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9686 | (ctx
->opcode
& 0xf)) << 3;
9688 if (ctx
->opcode
& (1 << 7)) {
9689 gen_mips16_save(ctx
, xsregs
, aregs
,
9690 do_ra
, do_s0
, do_s1
,
9693 gen_mips16_restore(ctx
, xsregs
, aregs
,
9694 do_ra
, do_s0
, do_s1
,
9700 generate_exception(ctx
, EXCP_RI
);
9705 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9708 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9710 #if defined(TARGET_MIPS64)
9712 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9716 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9719 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9722 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9725 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9728 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9731 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9734 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9736 #if defined(TARGET_MIPS64)
9738 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9742 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9745 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9748 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9751 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9753 #if defined(TARGET_MIPS64)
9755 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9759 generate_exception(ctx
, EXCP_RI
);
9766 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
9771 int op
, cnvt_op
, op1
, offset
;
9775 op
= (ctx
->opcode
>> 11) & 0x1f;
9776 sa
= (ctx
->opcode
>> 2) & 0x7;
9777 sa
= sa
== 0 ? 8 : sa
;
9778 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9779 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9780 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9781 op1
= offset
= ctx
->opcode
& 0x1f;
9786 case M16_OPC_ADDIUSP
:
9788 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9790 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9793 case M16_OPC_ADDIUPC
:
9794 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9797 offset
= (ctx
->opcode
& 0x7ff) << 1;
9798 offset
= (int16_t)(offset
<< 4) >> 4;
9799 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9800 /* No delay slot, so just process as a normal instruction */
9803 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9804 offset
= (((ctx
->opcode
& 0x1f) << 21)
9805 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9807 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9808 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9813 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9814 /* No delay slot, so just process as a normal instruction */
9817 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9818 /* No delay slot, so just process as a normal instruction */
9821 switch (ctx
->opcode
& 0x3) {
9823 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9826 #if defined(TARGET_MIPS64)
9828 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9830 generate_exception(ctx
, EXCP_RI
);
9834 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9837 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9841 #if defined(TARGET_MIPS64)
9844 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9849 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9851 if ((ctx
->opcode
>> 4) & 1) {
9852 #if defined(TARGET_MIPS64)
9854 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9856 generate_exception(ctx
, EXCP_RI
);
9859 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9863 case M16_OPC_ADDIU8
:
9865 int16_t imm
= (int8_t) ctx
->opcode
;
9867 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9872 int16_t imm
= (uint8_t) ctx
->opcode
;
9873 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9878 int16_t imm
= (uint8_t) ctx
->opcode
;
9879 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9886 funct
= (ctx
->opcode
>> 8) & 0x7;
9889 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9890 ((int8_t)ctx
->opcode
) << 1);
9893 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9894 ((int8_t)ctx
->opcode
) << 1);
9897 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9900 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9901 ((int8_t)ctx
->opcode
) << 3);
9905 int do_ra
= ctx
->opcode
& (1 << 6);
9906 int do_s0
= ctx
->opcode
& (1 << 5);
9907 int do_s1
= ctx
->opcode
& (1 << 4);
9908 int framesize
= ctx
->opcode
& 0xf;
9910 if (framesize
== 0) {
9913 framesize
= framesize
<< 3;
9916 if (ctx
->opcode
& (1 << 7)) {
9917 gen_mips16_save(ctx
, 0, 0,
9918 do_ra
, do_s0
, do_s1
, framesize
);
9920 gen_mips16_restore(ctx
, 0, 0,
9921 do_ra
, do_s0
, do_s1
, framesize
);
9927 int rz
= xlat(ctx
->opcode
& 0x7);
9929 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9930 ((ctx
->opcode
>> 5) & 0x7);
9931 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
9935 reg32
= ctx
->opcode
& 0x1f;
9936 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
9939 generate_exception(ctx
, EXCP_RI
);
9946 int16_t imm
= (uint8_t) ctx
->opcode
;
9948 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
9953 int16_t imm
= (uint8_t) ctx
->opcode
;
9954 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
9957 #if defined(TARGET_MIPS64)
9960 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
9964 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9967 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
9970 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
9973 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
9976 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9979 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
9982 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
9984 #if defined (TARGET_MIPS64)
9987 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
9991 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9994 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
9997 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10000 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10004 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10007 switch (ctx
->opcode
& 0x3) {
10009 mips32_op
= OPC_ADDU
;
10012 mips32_op
= OPC_SUBU
;
10014 #if defined(TARGET_MIPS64)
10016 mips32_op
= OPC_DADDU
;
10017 check_mips_64(ctx
);
10020 mips32_op
= OPC_DSUBU
;
10021 check_mips_64(ctx
);
10025 generate_exception(ctx
, EXCP_RI
);
10029 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10038 int nd
= (ctx
->opcode
>> 7) & 0x1;
10039 int link
= (ctx
->opcode
>> 6) & 0x1;
10040 int ra
= (ctx
->opcode
>> 5) & 0x1;
10043 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10048 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10055 /* XXX: not clear which exception should be raised
10056 * when in debug mode...
10058 check_insn(ctx
, ISA_MIPS32
);
10059 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10060 generate_exception(ctx
, EXCP_DBp
);
10062 generate_exception(ctx
, EXCP_DBp
);
10066 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10069 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10072 generate_exception(ctx
, EXCP_BREAK
);
10075 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10078 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10081 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10083 #if defined (TARGET_MIPS64)
10085 check_mips_64(ctx
);
10086 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10090 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10093 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10096 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10099 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10102 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10105 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10108 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
10112 case RR_RY_CNVT_ZEB
:
10113 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10115 case RR_RY_CNVT_ZEH
:
10116 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10118 case RR_RY_CNVT_SEB
:
10119 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10121 case RR_RY_CNVT_SEH
:
10122 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10124 #if defined (TARGET_MIPS64)
10125 case RR_RY_CNVT_ZEW
:
10126 check_mips_64(ctx
);
10127 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10129 case RR_RY_CNVT_SEW
:
10130 check_mips_64(ctx
);
10131 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10135 generate_exception(ctx
, EXCP_RI
);
10140 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
10142 #if defined (TARGET_MIPS64)
10144 check_mips_64(ctx
);
10145 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10148 check_mips_64(ctx
);
10149 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10152 check_mips_64(ctx
);
10153 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10156 check_mips_64(ctx
);
10157 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10161 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
10164 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
10167 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
10170 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
10172 #if defined (TARGET_MIPS64)
10174 check_mips_64(ctx
);
10175 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
10178 check_mips_64(ctx
);
10179 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
10182 check_mips_64(ctx
);
10183 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
10186 check_mips_64(ctx
);
10187 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
10191 generate_exception(ctx
, EXCP_RI
);
10195 case M16_OPC_EXTEND
:
10196 decode_extended_mips16_opc(env
, ctx
, is_branch
);
10199 #if defined(TARGET_MIPS64)
10201 funct
= (ctx
->opcode
>> 8) & 0x7;
10202 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10206 generate_exception(ctx
, EXCP_RI
);
10213 /* microMIPS extension to MIPS32/MIPS64 */
10216 * microMIPS32/microMIPS64 major opcodes
10218 * 1. MIPS Architecture for Programmers Volume II-B:
10219 * The microMIPS32 Instruction Set (Revision 3.05)
10221 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10223 * 2. MIPS Architecture For Programmers Volume II-A:
10224 * The MIPS64 Instruction Set (Revision 3.51)
10252 POOL32S
= 0x16, /* MIPS64 */
10253 DADDIU32
= 0x17, /* MIPS64 */
10255 /* 0x1f is reserved */
10264 /* 0x20 is reserved */
10274 /* 0x28 and 0x29 are reserved */
10284 /* 0x30 and 0x31 are reserved */
10291 SD32
= 0x36, /* MIPS64 */
10292 LD32
= 0x37, /* MIPS64 */
10294 /* 0x38 and 0x39 are reserved */
10305 /* POOL32A encoding of minor opcode field */
10308 /* These opcodes are distinguished only by bits 9..6; those bits are
10309 * what are recorded below. */
10335 /* The following can be distinguished by their lower 6 bits. */
10341 /* POOL32AXF encoding of minor opcode field extension */
10344 * 1. MIPS Architecture for Programmers Volume II-B:
10345 * The microMIPS32 Instruction Set (Revision 3.05)
10347 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10349 * 2. MIPS Architecture for Programmers VolumeIV-e:
10350 * The MIPS DSP Application-Specific Extension
10351 * to the microMIPS32 Architecture (Revision 2.34)
10353 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10368 /* begin of microMIPS32 DSP */
10370 /* bits 13..12 for 0x01 */
10376 /* bits 13..12 for 0x2a */
10382 /* bits 13..12 for 0x32 */
10386 /* end of microMIPS32 DSP */
10388 /* bits 15..12 for 0x2c */
10404 /* bits 15..12 for 0x34 */
10412 /* bits 15..12 for 0x3c */
10414 JR
= 0x0, /* alias */
10419 /* bits 15..12 for 0x05 */
10423 /* bits 15..12 for 0x0d */
10433 /* bits 15..12 for 0x15 */
10439 /* bits 15..12 for 0x1d */
10443 /* bits 15..12 for 0x2d */
10448 /* bits 15..12 for 0x35 */
10455 /* POOL32B encoding of minor opcode field (bits 15..12) */
10471 /* POOL32C encoding of minor opcode field (bits 15..12) */
10479 /* 0xa is reserved */
10486 /* 0x6 is reserved */
10492 /* POOL32F encoding of minor opcode field (bits 5..0) */
10495 /* These are the bit 7..6 values */
10506 /* These are the bit 8..6 values */
10550 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10554 /* POOL32Fxf encoding of minor opcode extension field */
10592 /* POOL32I encoding of minor opcode field (bits 25..21) */
10617 /* These overlap and are distinguished by bit16 of the instruction */
10626 /* POOL16A encoding of minor opcode field */
10633 /* POOL16B encoding of minor opcode field */
10640 /* POOL16C encoding of minor opcode field */
10660 /* POOL16D encoding of minor opcode field */
10667 /* POOL16E encoding of minor opcode field */
10674 static int mmreg (int r
)
10676 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10681 /* Used for 16-bit store instructions. */
10682 static int mmreg2 (int r
)
10684 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10689 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10690 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10691 #define uMIPS_RS2(op) uMIPS_RS(op)
10692 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10693 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10694 #define uMIPS_RS5(op) (op & 0x1f)
10696 /* Signed immediate */
10697 #define SIMM(op, start, width) \
10698 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10701 /* Zero-extended immediate */
10702 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10704 static void gen_addiur1sp(DisasContext
*ctx
)
10706 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10708 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10711 static void gen_addiur2(DisasContext
*ctx
)
10713 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10714 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10715 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10717 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10720 static void gen_addiusp(DisasContext
*ctx
)
10722 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10725 if (encoded
<= 1) {
10726 decoded
= 256 + encoded
;
10727 } else if (encoded
<= 255) {
10729 } else if (encoded
<= 509) {
10730 decoded
= encoded
- 512;
10732 decoded
= encoded
- 768;
10735 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10738 static void gen_addius5(DisasContext
*ctx
)
10740 int imm
= SIMM(ctx
->opcode
, 1, 4);
10741 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10743 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10746 static void gen_andi16(DisasContext
*ctx
)
10748 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10749 31, 32, 63, 64, 255, 32768, 65535 };
10750 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10751 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10752 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10754 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10757 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10758 int base
, int16_t offset
)
10760 const char *opn
= "ldst_multiple";
10764 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10765 generate_exception(ctx
, EXCP_RI
);
10769 t0
= tcg_temp_new();
10771 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10773 t1
= tcg_const_tl(reglist
);
10774 t2
= tcg_const_i32(ctx
->mem_idx
);
10776 save_cpu_state(ctx
, 1);
10779 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10783 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10786 #ifdef TARGET_MIPS64
10788 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10792 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10798 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10801 tcg_temp_free_i32(t2
);
10805 static void gen_pool16c_insn(DisasContext
*ctx
, int *is_branch
)
10807 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10808 int rs
= mmreg(ctx
->opcode
& 0x7);
10811 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10816 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10822 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10828 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10834 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10841 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10842 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10844 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10853 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10854 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10856 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10863 int reg
= ctx
->opcode
& 0x1f;
10865 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10872 int reg
= ctx
->opcode
& 0x1f;
10874 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10875 /* Let normal delay slot handling in our caller take us
10876 to the branch target. */
10888 int reg
= ctx
->opcode
& 0x1f;
10890 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10896 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
10900 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
10903 generate_exception(ctx
, EXCP_BREAK
);
10906 /* XXX: not clear which exception should be raised
10907 * when in debug mode...
10909 check_insn(ctx
, ISA_MIPS32
);
10910 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10911 generate_exception(ctx
, EXCP_DBp
);
10913 generate_exception(ctx
, EXCP_DBp
);
10916 case JRADDIUSP
+ 0:
10917 case JRADDIUSP
+ 1:
10919 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10921 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10922 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10923 /* Let normal delay slot handling in our caller take us
10924 to the branch target. */
10928 generate_exception(ctx
, EXCP_RI
);
10933 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10935 TCGv t0
= tcg_temp_new();
10936 TCGv t1
= tcg_temp_new();
10938 gen_load_gpr(t0
, base
);
10941 gen_load_gpr(t1
, index
);
10942 tcg_gen_shli_tl(t1
, t1
, 2);
10943 gen_op_addr_add(ctx
, t0
, t1
, t0
);
10946 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10947 gen_store_gpr(t1
, rd
);
10953 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
10954 int base
, int16_t offset
)
10956 const char *opn
= "ldst_pair";
10959 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
10960 generate_exception(ctx
, EXCP_RI
);
10964 t0
= tcg_temp_new();
10965 t1
= tcg_temp_new();
10967 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10972 generate_exception(ctx
, EXCP_RI
);
10975 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10976 gen_store_gpr(t1
, rd
);
10977 tcg_gen_movi_tl(t1
, 4);
10978 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10979 tcg_gen_qemu_ld32s(t1
, t0
, ctx
->mem_idx
);
10980 gen_store_gpr(t1
, rd
+1);
10984 gen_load_gpr(t1
, rd
);
10985 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
10986 tcg_gen_movi_tl(t1
, 4);
10987 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10988 gen_load_gpr(t1
, rd
+1);
10989 tcg_gen_qemu_st32(t1
, t0
, ctx
->mem_idx
);
10992 #ifdef TARGET_MIPS64
10995 generate_exception(ctx
, EXCP_RI
);
10998 tcg_gen_qemu_ld64(t1
, t0
, ctx
->mem_idx
);
10999 gen_store_gpr(t1
, rd
);
11000 tcg_gen_movi_tl(t1
, 8);
11001 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11002 tcg_gen_qemu_ld64(t1
, t0
, ctx
->mem_idx
);
11003 gen_store_gpr(t1
, rd
+1);
11007 gen_load_gpr(t1
, rd
);
11008 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
11009 tcg_gen_movi_tl(t1
, 8);
11010 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11011 gen_load_gpr(t1
, rd
+1);
11012 tcg_gen_qemu_st64(t1
, t0
, ctx
->mem_idx
);
11017 (void)opn
; /* avoid a compiler warning */
11018 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11023 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
,
11026 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11027 int minor
= (ctx
->opcode
>> 12) & 0xf;
11028 uint32_t mips32_op
;
11030 switch (extension
) {
11032 mips32_op
= OPC_TEQ
;
11035 mips32_op
= OPC_TGE
;
11038 mips32_op
= OPC_TGEU
;
11041 mips32_op
= OPC_TLT
;
11044 mips32_op
= OPC_TLTU
;
11047 mips32_op
= OPC_TNE
;
11049 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11051 #ifndef CONFIG_USER_ONLY
11054 check_cp0_enabled(ctx
);
11056 /* Treat as NOP. */
11059 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11063 check_cp0_enabled(ctx
);
11065 TCGv t0
= tcg_temp_new();
11067 gen_load_gpr(t0
, rt
);
11068 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11076 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11079 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11082 mips32_op
= OPC_CLO
;
11085 mips32_op
= OPC_CLZ
;
11087 check_insn(ctx
, ISA_MIPS32
);
11088 gen_cl(ctx
, mips32_op
, rt
, rs
);
11091 gen_rdhwr(ctx
, rt
, rs
);
11094 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11097 mips32_op
= OPC_MULT
;
11100 mips32_op
= OPC_MULTU
;
11103 mips32_op
= OPC_DIV
;
11106 mips32_op
= OPC_DIVU
;
11109 check_insn(ctx
, ISA_MIPS32
);
11110 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11113 mips32_op
= OPC_MADD
;
11116 mips32_op
= OPC_MADDU
;
11119 mips32_op
= OPC_MSUB
;
11122 mips32_op
= OPC_MSUBU
;
11124 check_insn(ctx
, ISA_MIPS32
);
11125 gen_muldiv(ctx
, mips32_op
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11128 goto pool32axf_invalid
;
11139 generate_exception_err(ctx
, EXCP_CpU
, 2);
11142 goto pool32axf_invalid
;
11149 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11154 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11158 goto pool32axf_invalid
;
11164 check_cp0_enabled(ctx
);
11165 check_insn(ctx
, ISA_MIPS32R2
);
11166 gen_load_srsgpr(rt
, rs
);
11169 check_cp0_enabled(ctx
);
11170 check_insn(ctx
, ISA_MIPS32R2
);
11171 gen_store_srsgpr(rt
, rs
);
11174 goto pool32axf_invalid
;
11177 #ifndef CONFIG_USER_ONLY
11181 mips32_op
= OPC_TLBP
;
11184 mips32_op
= OPC_TLBR
;
11187 mips32_op
= OPC_TLBWI
;
11190 mips32_op
= OPC_TLBWR
;
11193 mips32_op
= OPC_WAIT
;
11196 mips32_op
= OPC_DERET
;
11199 mips32_op
= OPC_ERET
;
11201 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11204 goto pool32axf_invalid
;
11210 check_cp0_enabled(ctx
);
11212 TCGv t0
= tcg_temp_new();
11214 save_cpu_state(ctx
, 1);
11215 gen_helper_di(t0
, cpu_env
);
11216 gen_store_gpr(t0
, rs
);
11217 /* Stop translation as we may have switched the execution mode */
11218 ctx
->bstate
= BS_STOP
;
11223 check_cp0_enabled(ctx
);
11225 TCGv t0
= tcg_temp_new();
11227 save_cpu_state(ctx
, 1);
11228 gen_helper_ei(t0
, cpu_env
);
11229 gen_store_gpr(t0
, rs
);
11230 /* Stop translation as we may have switched the execution mode */
11231 ctx
->bstate
= BS_STOP
;
11236 goto pool32axf_invalid
;
11246 generate_exception(ctx
, EXCP_SYSCALL
);
11247 ctx
->bstate
= BS_STOP
;
11250 check_insn(ctx
, ISA_MIPS32
);
11251 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11252 generate_exception(ctx
, EXCP_DBp
);
11254 generate_exception(ctx
, EXCP_DBp
);
11258 goto pool32axf_invalid
;
11262 switch (minor
& 3) {
11264 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
11267 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
11270 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
11273 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
11276 goto pool32axf_invalid
;
11281 MIPS_INVAL("pool32axf");
11282 generate_exception(ctx
, EXCP_RI
);
11287 /* Values for microMIPS fmt field. Variable-width, depending on which
11288 formats the instruction supports. */
11307 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11309 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11310 uint32_t mips32_op
;
11312 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11313 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11314 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11316 switch (extension
) {
11317 case FLOAT_1BIT_FMT(CFC1
, 0):
11318 mips32_op
= OPC_CFC1
;
11320 case FLOAT_1BIT_FMT(CTC1
, 0):
11321 mips32_op
= OPC_CTC1
;
11323 case FLOAT_1BIT_FMT(MFC1
, 0):
11324 mips32_op
= OPC_MFC1
;
11326 case FLOAT_1BIT_FMT(MTC1
, 0):
11327 mips32_op
= OPC_MTC1
;
11329 case FLOAT_1BIT_FMT(MFHC1
, 0):
11330 mips32_op
= OPC_MFHC1
;
11332 case FLOAT_1BIT_FMT(MTHC1
, 0):
11333 mips32_op
= OPC_MTHC1
;
11335 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11338 /* Reciprocal square root */
11339 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11340 mips32_op
= OPC_RSQRT_S
;
11342 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11343 mips32_op
= OPC_RSQRT_D
;
11347 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11348 mips32_op
= OPC_SQRT_S
;
11350 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11351 mips32_op
= OPC_SQRT_D
;
11355 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11356 mips32_op
= OPC_RECIP_S
;
11358 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11359 mips32_op
= OPC_RECIP_D
;
11363 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11364 mips32_op
= OPC_FLOOR_L_S
;
11366 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11367 mips32_op
= OPC_FLOOR_L_D
;
11369 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11370 mips32_op
= OPC_FLOOR_W_S
;
11372 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11373 mips32_op
= OPC_FLOOR_W_D
;
11377 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11378 mips32_op
= OPC_CEIL_L_S
;
11380 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11381 mips32_op
= OPC_CEIL_L_D
;
11383 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11384 mips32_op
= OPC_CEIL_W_S
;
11386 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11387 mips32_op
= OPC_CEIL_W_D
;
11391 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11392 mips32_op
= OPC_TRUNC_L_S
;
11394 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11395 mips32_op
= OPC_TRUNC_L_D
;
11397 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11398 mips32_op
= OPC_TRUNC_W_S
;
11400 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11401 mips32_op
= OPC_TRUNC_W_D
;
11405 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11406 mips32_op
= OPC_ROUND_L_S
;
11408 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11409 mips32_op
= OPC_ROUND_L_D
;
11411 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11412 mips32_op
= OPC_ROUND_W_S
;
11414 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11415 mips32_op
= OPC_ROUND_W_D
;
11418 /* Integer to floating-point conversion */
11419 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11420 mips32_op
= OPC_CVT_L_S
;
11422 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11423 mips32_op
= OPC_CVT_L_D
;
11425 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11426 mips32_op
= OPC_CVT_W_S
;
11428 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11429 mips32_op
= OPC_CVT_W_D
;
11432 /* Paired-foo conversions */
11433 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11434 mips32_op
= OPC_CVT_S_PL
;
11436 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11437 mips32_op
= OPC_CVT_S_PU
;
11439 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11440 mips32_op
= OPC_CVT_PW_PS
;
11442 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11443 mips32_op
= OPC_CVT_PS_PW
;
11446 /* Floating-point moves */
11447 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11448 mips32_op
= OPC_MOV_S
;
11450 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11451 mips32_op
= OPC_MOV_D
;
11453 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11454 mips32_op
= OPC_MOV_PS
;
11457 /* Absolute value */
11458 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11459 mips32_op
= OPC_ABS_S
;
11461 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11462 mips32_op
= OPC_ABS_D
;
11464 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11465 mips32_op
= OPC_ABS_PS
;
11469 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11470 mips32_op
= OPC_NEG_S
;
11472 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11473 mips32_op
= OPC_NEG_D
;
11475 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11476 mips32_op
= OPC_NEG_PS
;
11479 /* Reciprocal square root step */
11480 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11481 mips32_op
= OPC_RSQRT1_S
;
11483 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11484 mips32_op
= OPC_RSQRT1_D
;
11486 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11487 mips32_op
= OPC_RSQRT1_PS
;
11490 /* Reciprocal step */
11491 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11492 mips32_op
= OPC_RECIP1_S
;
11494 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11495 mips32_op
= OPC_RECIP1_S
;
11497 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11498 mips32_op
= OPC_RECIP1_PS
;
11501 /* Conversions from double */
11502 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11503 mips32_op
= OPC_CVT_D_S
;
11505 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11506 mips32_op
= OPC_CVT_D_W
;
11508 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11509 mips32_op
= OPC_CVT_D_L
;
11512 /* Conversions from single */
11513 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11514 mips32_op
= OPC_CVT_S_D
;
11516 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11517 mips32_op
= OPC_CVT_S_W
;
11519 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11520 mips32_op
= OPC_CVT_S_L
;
11522 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11525 /* Conditional moves on floating-point codes */
11526 case COND_FLOAT_MOV(MOVT
, 0):
11527 case COND_FLOAT_MOV(MOVT
, 1):
11528 case COND_FLOAT_MOV(MOVT
, 2):
11529 case COND_FLOAT_MOV(MOVT
, 3):
11530 case COND_FLOAT_MOV(MOVT
, 4):
11531 case COND_FLOAT_MOV(MOVT
, 5):
11532 case COND_FLOAT_MOV(MOVT
, 6):
11533 case COND_FLOAT_MOV(MOVT
, 7):
11534 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11536 case COND_FLOAT_MOV(MOVF
, 0):
11537 case COND_FLOAT_MOV(MOVF
, 1):
11538 case COND_FLOAT_MOV(MOVF
, 2):
11539 case COND_FLOAT_MOV(MOVF
, 3):
11540 case COND_FLOAT_MOV(MOVF
, 4):
11541 case COND_FLOAT_MOV(MOVF
, 5):
11542 case COND_FLOAT_MOV(MOVF
, 6):
11543 case COND_FLOAT_MOV(MOVF
, 7):
11544 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11547 MIPS_INVAL("pool32fxf");
11548 generate_exception(ctx
, EXCP_RI
);
11553 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11554 uint16_t insn_hw1
, int *is_branch
)
11558 int rt
, rs
, rd
, rr
;
11560 uint32_t op
, minor
, mips32_op
;
11561 uint32_t cond
, fmt
, cc
;
11563 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11564 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11566 rt
= (ctx
->opcode
>> 21) & 0x1f;
11567 rs
= (ctx
->opcode
>> 16) & 0x1f;
11568 rd
= (ctx
->opcode
>> 11) & 0x1f;
11569 rr
= (ctx
->opcode
>> 6) & 0x1f;
11570 imm
= (int16_t) ctx
->opcode
;
11572 op
= (ctx
->opcode
>> 26) & 0x3f;
11575 minor
= ctx
->opcode
& 0x3f;
11578 minor
= (ctx
->opcode
>> 6) & 0xf;
11581 mips32_op
= OPC_SLL
;
11584 mips32_op
= OPC_SRA
;
11587 mips32_op
= OPC_SRL
;
11590 mips32_op
= OPC_ROTR
;
11592 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11595 goto pool32a_invalid
;
11599 minor
= (ctx
->opcode
>> 6) & 0xf;
11603 mips32_op
= OPC_ADD
;
11606 mips32_op
= OPC_ADDU
;
11609 mips32_op
= OPC_SUB
;
11612 mips32_op
= OPC_SUBU
;
11615 mips32_op
= OPC_MUL
;
11617 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11621 mips32_op
= OPC_SLLV
;
11624 mips32_op
= OPC_SRLV
;
11627 mips32_op
= OPC_SRAV
;
11630 mips32_op
= OPC_ROTRV
;
11632 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11634 /* Logical operations */
11636 mips32_op
= OPC_AND
;
11639 mips32_op
= OPC_OR
;
11642 mips32_op
= OPC_NOR
;
11645 mips32_op
= OPC_XOR
;
11647 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11649 /* Set less than */
11651 mips32_op
= OPC_SLT
;
11654 mips32_op
= OPC_SLTU
;
11656 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11659 goto pool32a_invalid
;
11663 minor
= (ctx
->opcode
>> 6) & 0xf;
11665 /* Conditional moves */
11667 mips32_op
= OPC_MOVN
;
11670 mips32_op
= OPC_MOVZ
;
11672 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11675 gen_ldxs(ctx
, rs
, rt
, rd
);
11678 goto pool32a_invalid
;
11682 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11685 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11688 gen_pool32axf(env
, ctx
, rt
, rs
, is_branch
);
11691 generate_exception(ctx
, EXCP_BREAK
);
11695 MIPS_INVAL("pool32a");
11696 generate_exception(ctx
, EXCP_RI
);
11701 minor
= (ctx
->opcode
>> 12) & 0xf;
11704 check_cp0_enabled(ctx
);
11705 /* Treat as no-op. */
11709 /* COP2: Not implemented. */
11710 generate_exception_err(ctx
, EXCP_CpU
, 2);
11714 #ifdef TARGET_MIPS64
11718 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11722 #ifdef TARGET_MIPS64
11726 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11729 MIPS_INVAL("pool32b");
11730 generate_exception(ctx
, EXCP_RI
);
11735 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
11736 minor
= ctx
->opcode
& 0x3f;
11737 check_cp1_enabled(ctx
);
11740 mips32_op
= OPC_ALNV_PS
;
11743 mips32_op
= OPC_MADD_S
;
11746 mips32_op
= OPC_MADD_D
;
11749 mips32_op
= OPC_MADD_PS
;
11752 mips32_op
= OPC_MSUB_S
;
11755 mips32_op
= OPC_MSUB_D
;
11758 mips32_op
= OPC_MSUB_PS
;
11761 mips32_op
= OPC_NMADD_S
;
11764 mips32_op
= OPC_NMADD_D
;
11767 mips32_op
= OPC_NMADD_PS
;
11770 mips32_op
= OPC_NMSUB_S
;
11773 mips32_op
= OPC_NMSUB_D
;
11776 mips32_op
= OPC_NMSUB_PS
;
11778 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11780 case CABS_COND_FMT
:
11781 cond
= (ctx
->opcode
>> 6) & 0xf;
11782 cc
= (ctx
->opcode
>> 13) & 0x7;
11783 fmt
= (ctx
->opcode
>> 10) & 0x3;
11786 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11789 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11792 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11795 goto pool32f_invalid
;
11799 cond
= (ctx
->opcode
>> 6) & 0xf;
11800 cc
= (ctx
->opcode
>> 13) & 0x7;
11801 fmt
= (ctx
->opcode
>> 10) & 0x3;
11804 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11807 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11810 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11813 goto pool32f_invalid
;
11817 gen_pool32fxf(ctx
, rt
, rs
);
11821 switch ((ctx
->opcode
>> 6) & 0x7) {
11823 mips32_op
= OPC_PLL_PS
;
11826 mips32_op
= OPC_PLU_PS
;
11829 mips32_op
= OPC_PUL_PS
;
11832 mips32_op
= OPC_PUU_PS
;
11835 mips32_op
= OPC_CVT_PS_S
;
11837 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11840 goto pool32f_invalid
;
11845 switch ((ctx
->opcode
>> 6) & 0x7) {
11847 mips32_op
= OPC_LWXC1
;
11850 mips32_op
= OPC_SWXC1
;
11853 mips32_op
= OPC_LDXC1
;
11856 mips32_op
= OPC_SDXC1
;
11859 mips32_op
= OPC_LUXC1
;
11862 mips32_op
= OPC_SUXC1
;
11864 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11867 goto pool32f_invalid
;
11872 fmt
= (ctx
->opcode
>> 9) & 0x3;
11873 switch ((ctx
->opcode
>> 6) & 0x7) {
11877 mips32_op
= OPC_RSQRT2_S
;
11880 mips32_op
= OPC_RSQRT2_D
;
11883 mips32_op
= OPC_RSQRT2_PS
;
11886 goto pool32f_invalid
;
11892 mips32_op
= OPC_RECIP2_S
;
11895 mips32_op
= OPC_RECIP2_D
;
11898 mips32_op
= OPC_RECIP2_PS
;
11901 goto pool32f_invalid
;
11905 mips32_op
= OPC_ADDR_PS
;
11908 mips32_op
= OPC_MULR_PS
;
11910 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11913 goto pool32f_invalid
;
11917 /* MOV[FT].fmt and PREFX */
11918 cc
= (ctx
->opcode
>> 13) & 0x7;
11919 fmt
= (ctx
->opcode
>> 9) & 0x3;
11920 switch ((ctx
->opcode
>> 6) & 0x7) {
11924 gen_movcf_s(rs
, rt
, cc
, 0);
11927 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
11930 gen_movcf_ps(rs
, rt
, cc
, 0);
11933 goto pool32f_invalid
;
11939 gen_movcf_s(rs
, rt
, cc
, 1);
11942 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
11945 gen_movcf_ps(rs
, rt
, cc
, 1);
11948 goto pool32f_invalid
;
11954 goto pool32f_invalid
;
11957 #define FINSN_3ARG_SDPS(prfx) \
11958 switch ((ctx->opcode >> 8) & 0x3) { \
11960 mips32_op = OPC_##prfx##_S; \
11963 mips32_op = OPC_##prfx##_D; \
11965 case FMT_SDPS_PS: \
11966 mips32_op = OPC_##prfx##_PS; \
11969 goto pool32f_invalid; \
11972 /* regular FP ops */
11973 switch ((ctx
->opcode
>> 6) & 0x3) {
11975 FINSN_3ARG_SDPS(ADD
);
11978 FINSN_3ARG_SDPS(SUB
);
11981 FINSN_3ARG_SDPS(MUL
);
11984 fmt
= (ctx
->opcode
>> 8) & 0x3;
11986 mips32_op
= OPC_DIV_D
;
11987 } else if (fmt
== 0) {
11988 mips32_op
= OPC_DIV_S
;
11990 goto pool32f_invalid
;
11994 goto pool32f_invalid
;
11999 switch ((ctx
->opcode
>> 6) & 0x3) {
12001 FINSN_3ARG_SDPS(MOVN
);
12004 FINSN_3ARG_SDPS(MOVZ
);
12007 goto pool32f_invalid
;
12011 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12015 MIPS_INVAL("pool32f");
12016 generate_exception(ctx
, EXCP_RI
);
12020 generate_exception_err(ctx
, EXCP_CpU
, 1);
12024 minor
= (ctx
->opcode
>> 21) & 0x1f;
12027 mips32_op
= OPC_BLTZ
;
12030 mips32_op
= OPC_BLTZAL
;
12033 mips32_op
= OPC_BLTZALS
;
12036 mips32_op
= OPC_BGEZ
;
12039 mips32_op
= OPC_BGEZAL
;
12042 mips32_op
= OPC_BGEZALS
;
12045 mips32_op
= OPC_BLEZ
;
12048 mips32_op
= OPC_BGTZ
;
12050 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12056 mips32_op
= OPC_TLTI
;
12059 mips32_op
= OPC_TGEI
;
12062 mips32_op
= OPC_TLTIU
;
12065 mips32_op
= OPC_TGEIU
;
12068 mips32_op
= OPC_TNEI
;
12071 mips32_op
= OPC_TEQI
;
12073 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12078 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12079 4, rs
, 0, imm
<< 1);
12080 /* Compact branches don't have a delay slot, so just let
12081 the normal delay slot handling take us to the branch
12085 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12091 /* COP2: Not implemented. */
12092 generate_exception_err(ctx
, EXCP_CpU
, 2);
12095 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12098 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12101 mips32_op
= OPC_BC1FANY4
;
12104 mips32_op
= OPC_BC1TANY4
;
12107 check_insn(ctx
, ASE_MIPS3D
);
12110 gen_compute_branch1(ctx
, mips32_op
,
12111 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12116 /* MIPS DSP: not implemented */
12119 MIPS_INVAL("pool32i");
12120 generate_exception(ctx
, EXCP_RI
);
12125 minor
= (ctx
->opcode
>> 12) & 0xf;
12128 mips32_op
= OPC_LWL
;
12131 mips32_op
= OPC_SWL
;
12134 mips32_op
= OPC_LWR
;
12137 mips32_op
= OPC_SWR
;
12139 #if defined(TARGET_MIPS64)
12141 mips32_op
= OPC_LDL
;
12144 mips32_op
= OPC_SDL
;
12147 mips32_op
= OPC_LDR
;
12150 mips32_op
= OPC_SDR
;
12153 mips32_op
= OPC_LWU
;
12156 mips32_op
= OPC_LLD
;
12160 mips32_op
= OPC_LL
;
12163 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12166 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12169 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12171 #if defined(TARGET_MIPS64)
12173 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12177 /* Treat as no-op */
12180 MIPS_INVAL("pool32c");
12181 generate_exception(ctx
, EXCP_RI
);
12186 mips32_op
= OPC_ADDI
;
12189 mips32_op
= OPC_ADDIU
;
12191 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12194 /* Logical operations */
12196 mips32_op
= OPC_ORI
;
12199 mips32_op
= OPC_XORI
;
12202 mips32_op
= OPC_ANDI
;
12204 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12207 /* Set less than immediate */
12209 mips32_op
= OPC_SLTI
;
12212 mips32_op
= OPC_SLTIU
;
12214 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12217 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12218 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12222 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12223 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12227 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12231 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12235 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12236 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12240 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12241 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12244 /* Floating point (COP1) */
12246 mips32_op
= OPC_LWC1
;
12249 mips32_op
= OPC_LDC1
;
12252 mips32_op
= OPC_SWC1
;
12255 mips32_op
= OPC_SDC1
;
12257 gen_cop1_ldst(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12261 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12262 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12264 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12267 /* Loads and stores */
12269 mips32_op
= OPC_LB
;
12272 mips32_op
= OPC_LBU
;
12275 mips32_op
= OPC_LH
;
12278 mips32_op
= OPC_LHU
;
12281 mips32_op
= OPC_LW
;
12283 #ifdef TARGET_MIPS64
12285 mips32_op
= OPC_LD
;
12288 mips32_op
= OPC_SD
;
12292 mips32_op
= OPC_SB
;
12295 mips32_op
= OPC_SH
;
12298 mips32_op
= OPC_SW
;
12301 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12304 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12307 generate_exception(ctx
, EXCP_RI
);
12312 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
, int *is_branch
)
12316 /* make sure instructions are on a halfword boundary */
12317 if (ctx
->pc
& 0x1) {
12318 env
->CP0_BadVAddr
= ctx
->pc
;
12319 generate_exception(ctx
, EXCP_AdEL
);
12320 ctx
->bstate
= BS_STOP
;
12324 op
= (ctx
->opcode
>> 10) & 0x3f;
12325 /* Enforce properly-sized instructions in a delay slot */
12326 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12327 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12365 if (bits
& MIPS_HFLAG_BDS16
) {
12366 generate_exception(ctx
, EXCP_RI
);
12367 /* Just stop translation; the user is confused. */
12368 ctx
->bstate
= BS_STOP
;
12393 if (bits
& MIPS_HFLAG_BDS32
) {
12394 generate_exception(ctx
, EXCP_RI
);
12395 /* Just stop translation; the user is confused. */
12396 ctx
->bstate
= BS_STOP
;
12407 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12408 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12409 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12412 switch (ctx
->opcode
& 0x1) {
12421 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12426 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12427 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12428 int amount
= (ctx
->opcode
>> 1) & 0x7;
12430 amount
= amount
== 0 ? 8 : amount
;
12432 switch (ctx
->opcode
& 0x1) {
12441 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12445 gen_pool16c_insn(ctx
, is_branch
);
12449 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12450 int rb
= 28; /* GP */
12451 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12453 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12457 if (ctx
->opcode
& 1) {
12458 generate_exception(ctx
, EXCP_RI
);
12461 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12462 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12463 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12464 int rd
, rs
, re
, rt
;
12465 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12466 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12467 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12469 rd
= rd_enc
[enc_dest
];
12470 re
= re_enc
[enc_dest
];
12471 rs
= rs_rt_enc
[enc_rs
];
12472 rt
= rs_rt_enc
[enc_rt
];
12474 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12475 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12480 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12481 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12482 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12483 offset
= (offset
== 0xf ? -1 : offset
);
12485 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12490 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12491 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12492 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12494 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12499 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12500 int rb
= 29; /* SP */
12501 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12503 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12508 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12509 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12510 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12512 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12517 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12518 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12519 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12521 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12526 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12527 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12528 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12530 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12535 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12536 int rb
= 29; /* SP */
12537 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12539 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12544 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12545 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12546 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12548 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12553 int rd
= uMIPS_RD5(ctx
->opcode
);
12554 int rs
= uMIPS_RS5(ctx
->opcode
);
12556 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12563 switch (ctx
->opcode
& 0x1) {
12573 switch (ctx
->opcode
& 0x1) {
12578 gen_addiur1sp(ctx
);
12583 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12584 SIMM(ctx
->opcode
, 0, 10) << 1);
12589 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12590 mmreg(uMIPS_RD(ctx
->opcode
)),
12591 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12596 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12597 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12599 imm
= (imm
== 0x7f ? -1 : imm
);
12600 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12610 generate_exception(ctx
, EXCP_RI
);
12613 decode_micromips32_opc (env
, ctx
, op
, is_branch
);
12620 /* SmartMIPS extension to MIPS32 */
12622 #if defined(TARGET_MIPS64)
12624 /* MDMX extension to MIPS64 */
12628 /* MIPSDSP functions. */
12629 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12630 int rd
, int base
, int offset
)
12632 const char *opn
= "ldx";
12636 t0
= tcg_temp_new();
12639 gen_load_gpr(t0
, offset
);
12640 } else if (offset
== 0) {
12641 gen_load_gpr(t0
, base
);
12643 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12648 tcg_gen_qemu_ld8u(t0
, t0
, ctx
->mem_idx
);
12649 gen_store_gpr(t0
, rd
);
12653 tcg_gen_qemu_ld16s(t0
, t0
, ctx
->mem_idx
);
12654 gen_store_gpr(t0
, rd
);
12658 tcg_gen_qemu_ld32s(t0
, t0
, ctx
->mem_idx
);
12659 gen_store_gpr(t0
, rd
);
12662 #if defined(TARGET_MIPS64)
12664 tcg_gen_qemu_ld64(t0
, t0
, ctx
->mem_idx
);
12665 gen_store_gpr(t0
, rd
);
12670 (void)opn
; /* avoid a compiler warning */
12671 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12672 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12676 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12677 int ret
, int v1
, int v2
)
12679 const char *opn
= "mipsdsp arith";
12684 /* Treat as NOP. */
12689 v1_t
= tcg_temp_new();
12690 v2_t
= tcg_temp_new();
12692 gen_load_gpr(v1_t
, v1
);
12693 gen_load_gpr(v2_t
, v2
);
12696 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12697 case OPC_MULT_G_2E
:
12701 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12703 case OPC_ADDUH_R_QB
:
12704 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12707 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12709 case OPC_ADDQH_R_PH
:
12710 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12713 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12715 case OPC_ADDQH_R_W
:
12716 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12719 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12721 case OPC_SUBUH_R_QB
:
12722 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12725 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12727 case OPC_SUBQH_R_PH
:
12728 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12731 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12733 case OPC_SUBQH_R_W
:
12734 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12738 case OPC_ABSQ_S_PH_DSP
:
12740 case OPC_ABSQ_S_QB
:
12742 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12744 case OPC_ABSQ_S_PH
:
12746 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12750 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12752 case OPC_PRECEQ_W_PHL
:
12754 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12755 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12757 case OPC_PRECEQ_W_PHR
:
12759 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12760 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12761 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12763 case OPC_PRECEQU_PH_QBL
:
12765 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12767 case OPC_PRECEQU_PH_QBR
:
12769 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12771 case OPC_PRECEQU_PH_QBLA
:
12773 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12775 case OPC_PRECEQU_PH_QBRA
:
12777 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12779 case OPC_PRECEU_PH_QBL
:
12781 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12783 case OPC_PRECEU_PH_QBR
:
12785 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12787 case OPC_PRECEU_PH_QBLA
:
12789 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12791 case OPC_PRECEU_PH_QBRA
:
12793 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12797 case OPC_ADDU_QB_DSP
:
12801 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12803 case OPC_ADDQ_S_PH
:
12805 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12809 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12813 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12815 case OPC_ADDU_S_QB
:
12817 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12821 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12823 case OPC_ADDU_S_PH
:
12825 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12829 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12831 case OPC_SUBQ_S_PH
:
12833 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12837 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12841 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12843 case OPC_SUBU_S_QB
:
12845 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12849 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12851 case OPC_SUBU_S_PH
:
12853 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12857 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12861 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12865 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12867 case OPC_RADDU_W_QB
:
12869 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12873 case OPC_CMPU_EQ_QB_DSP
:
12875 case OPC_PRECR_QB_PH
:
12877 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12879 case OPC_PRECRQ_QB_PH
:
12881 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12883 case OPC_PRECR_SRA_PH_W
:
12886 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12887 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12889 tcg_temp_free_i32(sa_t
);
12892 case OPC_PRECR_SRA_R_PH_W
:
12895 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12896 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12898 tcg_temp_free_i32(sa_t
);
12901 case OPC_PRECRQ_PH_W
:
12903 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12905 case OPC_PRECRQ_RS_PH_W
:
12907 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12909 case OPC_PRECRQU_S_QB_PH
:
12911 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12915 #ifdef TARGET_MIPS64
12916 case OPC_ABSQ_S_QH_DSP
:
12918 case OPC_PRECEQ_L_PWL
:
12920 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
12922 case OPC_PRECEQ_L_PWR
:
12924 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
12926 case OPC_PRECEQ_PW_QHL
:
12928 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
12930 case OPC_PRECEQ_PW_QHR
:
12932 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
12934 case OPC_PRECEQ_PW_QHLA
:
12936 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
12938 case OPC_PRECEQ_PW_QHRA
:
12940 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
12942 case OPC_PRECEQU_QH_OBL
:
12944 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
12946 case OPC_PRECEQU_QH_OBR
:
12948 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
12950 case OPC_PRECEQU_QH_OBLA
:
12952 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
12954 case OPC_PRECEQU_QH_OBRA
:
12956 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
12958 case OPC_PRECEU_QH_OBL
:
12960 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
12962 case OPC_PRECEU_QH_OBR
:
12964 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
12966 case OPC_PRECEU_QH_OBLA
:
12968 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
12970 case OPC_PRECEU_QH_OBRA
:
12972 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
12974 case OPC_ABSQ_S_OB
:
12976 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
12978 case OPC_ABSQ_S_PW
:
12980 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
12982 case OPC_ABSQ_S_QH
:
12984 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
12988 case OPC_ADDU_OB_DSP
:
12990 case OPC_RADDU_L_OB
:
12992 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
12996 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12998 case OPC_SUBQ_S_PW
:
13000 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13004 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13006 case OPC_SUBQ_S_QH
:
13008 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13012 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13014 case OPC_SUBU_S_OB
:
13016 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13020 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13022 case OPC_SUBU_S_QH
:
13024 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13028 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13030 case OPC_SUBUH_R_OB
:
13032 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13036 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13038 case OPC_ADDQ_S_PW
:
13040 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13044 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13046 case OPC_ADDQ_S_QH
:
13048 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13052 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13054 case OPC_ADDU_S_OB
:
13056 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13060 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13062 case OPC_ADDU_S_QH
:
13064 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13068 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13070 case OPC_ADDUH_R_OB
:
13072 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13076 case OPC_CMPU_EQ_OB_DSP
:
13078 case OPC_PRECR_OB_QH
:
13080 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13082 case OPC_PRECR_SRA_QH_PW
:
13085 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13086 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13087 tcg_temp_free_i32(ret_t
);
13090 case OPC_PRECR_SRA_R_QH_PW
:
13093 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13094 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13095 tcg_temp_free_i32(sa_v
);
13098 case OPC_PRECRQ_OB_QH
:
13100 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13102 case OPC_PRECRQ_PW_L
:
13104 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13106 case OPC_PRECRQ_QH_PW
:
13108 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13110 case OPC_PRECRQ_RS_QH_PW
:
13112 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13114 case OPC_PRECRQU_S_OB_QH
:
13116 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13123 tcg_temp_free(v1_t
);
13124 tcg_temp_free(v2_t
);
13126 (void)opn
; /* avoid a compiler warning */
13127 MIPS_DEBUG("%s", opn
);
13130 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13131 int ret
, int v1
, int v2
)
13134 const char *opn
= "mipsdsp shift";
13140 /* Treat as NOP. */
13145 t0
= tcg_temp_new();
13146 v1_t
= tcg_temp_new();
13147 v2_t
= tcg_temp_new();
13149 tcg_gen_movi_tl(t0
, v1
);
13150 gen_load_gpr(v1_t
, v1
);
13151 gen_load_gpr(v2_t
, v2
);
13154 case OPC_SHLL_QB_DSP
:
13156 op2
= MASK_SHLL_QB(ctx
->opcode
);
13160 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13164 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13168 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13172 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13174 case OPC_SHLL_S_PH
:
13176 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13178 case OPC_SHLLV_S_PH
:
13180 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13184 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13186 case OPC_SHLLV_S_W
:
13188 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13192 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13196 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13200 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13204 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13208 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13210 case OPC_SHRA_R_QB
:
13212 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13216 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13218 case OPC_SHRAV_R_QB
:
13220 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13224 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13226 case OPC_SHRA_R_PH
:
13228 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13232 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13234 case OPC_SHRAV_R_PH
:
13236 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13240 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13242 case OPC_SHRAV_R_W
:
13244 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13246 default: /* Invalid */
13247 MIPS_INVAL("MASK SHLL.QB");
13248 generate_exception(ctx
, EXCP_RI
);
13253 #ifdef TARGET_MIPS64
13254 case OPC_SHLL_OB_DSP
:
13255 op2
= MASK_SHLL_OB(ctx
->opcode
);
13259 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13263 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13265 case OPC_SHLL_S_PW
:
13267 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13269 case OPC_SHLLV_S_PW
:
13271 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13275 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13279 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13283 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13287 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13289 case OPC_SHLL_S_QH
:
13291 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13293 case OPC_SHLLV_S_QH
:
13295 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13299 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13303 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13305 case OPC_SHRA_R_OB
:
13307 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13309 case OPC_SHRAV_R_OB
:
13311 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13315 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13319 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13321 case OPC_SHRA_R_PW
:
13323 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13325 case OPC_SHRAV_R_PW
:
13327 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13331 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13335 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13337 case OPC_SHRA_R_QH
:
13339 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13341 case OPC_SHRAV_R_QH
:
13343 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13347 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13351 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13355 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13359 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13361 default: /* Invalid */
13362 MIPS_INVAL("MASK SHLL.OB");
13363 generate_exception(ctx
, EXCP_RI
);
13371 tcg_temp_free(v1_t
);
13372 tcg_temp_free(v2_t
);
13373 (void)opn
; /* avoid a compiler warning */
13374 MIPS_DEBUG("%s", opn
);
13377 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13378 int ret
, int v1
, int v2
, int check_ret
)
13380 const char *opn
= "mipsdsp multiply";
13385 if ((ret
== 0) && (check_ret
== 1)) {
13386 /* Treat as NOP. */
13391 t0
= tcg_temp_new_i32();
13392 v1_t
= tcg_temp_new();
13393 v2_t
= tcg_temp_new();
13395 tcg_gen_movi_i32(t0
, ret
);
13396 gen_load_gpr(v1_t
, v1
);
13397 gen_load_gpr(v2_t
, v2
);
13400 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13401 * the same mask and op1. */
13402 case OPC_MULT_G_2E
:
13406 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13409 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13412 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13414 case OPC_MULQ_RS_W
:
13415 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13419 case OPC_DPA_W_PH_DSP
:
13421 case OPC_DPAU_H_QBL
:
13423 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13425 case OPC_DPAU_H_QBR
:
13427 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13429 case OPC_DPSU_H_QBL
:
13431 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13433 case OPC_DPSU_H_QBR
:
13435 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13439 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13441 case OPC_DPAX_W_PH
:
13443 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13445 case OPC_DPAQ_S_W_PH
:
13447 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13449 case OPC_DPAQX_S_W_PH
:
13451 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13453 case OPC_DPAQX_SA_W_PH
:
13455 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13459 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13461 case OPC_DPSX_W_PH
:
13463 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13465 case OPC_DPSQ_S_W_PH
:
13467 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13469 case OPC_DPSQX_S_W_PH
:
13471 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13473 case OPC_DPSQX_SA_W_PH
:
13475 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13477 case OPC_MULSAQ_S_W_PH
:
13479 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13481 case OPC_DPAQ_SA_L_W
:
13483 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13485 case OPC_DPSQ_SA_L_W
:
13487 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13489 case OPC_MAQ_S_W_PHL
:
13491 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13493 case OPC_MAQ_S_W_PHR
:
13495 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13497 case OPC_MAQ_SA_W_PHL
:
13499 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13501 case OPC_MAQ_SA_W_PHR
:
13503 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13505 case OPC_MULSA_W_PH
:
13507 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13511 #ifdef TARGET_MIPS64
13512 case OPC_DPAQ_W_QH_DSP
:
13514 int ac
= ret
& 0x03;
13515 tcg_gen_movi_i32(t0
, ac
);
13520 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13524 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13528 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13532 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13536 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13538 case OPC_DPAQ_S_W_QH
:
13540 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13542 case OPC_DPAQ_SA_L_PW
:
13544 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13546 case OPC_DPAU_H_OBL
:
13548 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13550 case OPC_DPAU_H_OBR
:
13552 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13556 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13558 case OPC_DPSQ_S_W_QH
:
13560 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13562 case OPC_DPSQ_SA_L_PW
:
13564 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13566 case OPC_DPSU_H_OBL
:
13568 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13570 case OPC_DPSU_H_OBR
:
13572 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13574 case OPC_MAQ_S_L_PWL
:
13576 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13578 case OPC_MAQ_S_L_PWR
:
13580 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13582 case OPC_MAQ_S_W_QHLL
:
13584 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13586 case OPC_MAQ_SA_W_QHLL
:
13588 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13590 case OPC_MAQ_S_W_QHLR
:
13592 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13594 case OPC_MAQ_SA_W_QHLR
:
13596 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13598 case OPC_MAQ_S_W_QHRL
:
13600 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13602 case OPC_MAQ_SA_W_QHRL
:
13604 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13606 case OPC_MAQ_S_W_QHRR
:
13608 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13610 case OPC_MAQ_SA_W_QHRR
:
13612 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13614 case OPC_MULSAQ_S_L_PW
:
13616 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13618 case OPC_MULSAQ_S_W_QH
:
13620 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13626 case OPC_ADDU_QB_DSP
:
13628 case OPC_MULEU_S_PH_QBL
:
13630 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13632 case OPC_MULEU_S_PH_QBR
:
13634 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13636 case OPC_MULQ_RS_PH
:
13638 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13640 case OPC_MULEQ_S_W_PHL
:
13642 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13644 case OPC_MULEQ_S_W_PHR
:
13646 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13648 case OPC_MULQ_S_PH
:
13650 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13654 #ifdef TARGET_MIPS64
13655 case OPC_ADDU_OB_DSP
:
13657 case OPC_MULEQ_S_PW_QHL
:
13659 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13661 case OPC_MULEQ_S_PW_QHR
:
13663 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13665 case OPC_MULEU_S_QH_OBL
:
13667 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13669 case OPC_MULEU_S_QH_OBR
:
13671 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13673 case OPC_MULQ_RS_QH
:
13675 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13682 tcg_temp_free_i32(t0
);
13683 tcg_temp_free(v1_t
);
13684 tcg_temp_free(v2_t
);
13686 (void)opn
; /* avoid a compiler warning */
13687 MIPS_DEBUG("%s", opn
);
13691 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13694 const char *opn
= "mipsdsp Bit/ Manipulation";
13700 /* Treat as NOP. */
13705 t0
= tcg_temp_new();
13706 val_t
= tcg_temp_new();
13707 gen_load_gpr(val_t
, val
);
13710 case OPC_ABSQ_S_PH_DSP
:
13714 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13719 target_long result
;
13720 imm
= (ctx
->opcode
>> 16) & 0xFF;
13721 result
= (uint32_t)imm
<< 24 |
13722 (uint32_t)imm
<< 16 |
13723 (uint32_t)imm
<< 8 |
13725 result
= (int32_t)result
;
13726 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13731 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13732 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13733 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13734 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13735 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13736 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13741 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13742 imm
= (int16_t)(imm
<< 6) >> 6;
13743 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13744 (target_long
)((int32_t)imm
<< 16 | \
13750 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13751 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13752 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13753 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13757 #ifdef TARGET_MIPS64
13758 case OPC_ABSQ_S_QH_DSP
:
13765 imm
= (ctx
->opcode
>> 16) & 0xFF;
13766 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13767 temp
= (temp
<< 16) | temp
;
13768 temp
= (temp
<< 32) | temp
;
13769 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13777 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13778 imm
= (int16_t)(imm
<< 6) >> 6;
13779 temp
= ((target_long
)imm
<< 32) \
13780 | ((target_long
)imm
& 0xFFFFFFFF);
13781 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13789 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13790 imm
= (int16_t)(imm
<< 6) >> 6;
13792 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13793 ((uint64_t)(uint16_t)imm
<< 32) |
13794 ((uint64_t)(uint16_t)imm
<< 16) |
13795 (uint64_t)(uint16_t)imm
;
13796 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13801 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13802 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13803 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13804 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13805 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13806 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13807 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13811 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13812 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13813 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13817 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13818 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13819 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13820 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13821 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13828 tcg_temp_free(val_t
);
13830 (void)opn
; /* avoid a compiler warning */
13831 MIPS_DEBUG("%s", opn
);
13834 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13835 uint32_t op1
, uint32_t op2
,
13836 int ret
, int v1
, int v2
, int check_ret
)
13838 const char *opn
= "mipsdsp add compare pick";
13843 if ((ret
== 0) && (check_ret
== 1)) {
13844 /* Treat as NOP. */
13849 t1
= tcg_temp_new();
13850 v1_t
= tcg_temp_new();
13851 v2_t
= tcg_temp_new();
13853 gen_load_gpr(v1_t
, v1
);
13854 gen_load_gpr(v2_t
, v2
);
13857 case OPC_CMPU_EQ_QB_DSP
:
13859 case OPC_CMPU_EQ_QB
:
13861 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13863 case OPC_CMPU_LT_QB
:
13865 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13867 case OPC_CMPU_LE_QB
:
13869 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13871 case OPC_CMPGU_EQ_QB
:
13873 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13875 case OPC_CMPGU_LT_QB
:
13877 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13879 case OPC_CMPGU_LE_QB
:
13881 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13883 case OPC_CMPGDU_EQ_QB
:
13885 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13886 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13887 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13888 tcg_gen_shli_tl(t1
, t1
, 24);
13889 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13891 case OPC_CMPGDU_LT_QB
:
13893 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
13894 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13895 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13896 tcg_gen_shli_tl(t1
, t1
, 24);
13897 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13899 case OPC_CMPGDU_LE_QB
:
13901 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
13902 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13903 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13904 tcg_gen_shli_tl(t1
, t1
, 24);
13905 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13907 case OPC_CMP_EQ_PH
:
13909 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
13911 case OPC_CMP_LT_PH
:
13913 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
13915 case OPC_CMP_LE_PH
:
13917 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
13921 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13925 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13927 case OPC_PACKRL_PH
:
13929 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13933 #ifdef TARGET_MIPS64
13934 case OPC_CMPU_EQ_OB_DSP
:
13936 case OPC_CMP_EQ_PW
:
13938 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
13940 case OPC_CMP_LT_PW
:
13942 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
13944 case OPC_CMP_LE_PW
:
13946 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
13948 case OPC_CMP_EQ_QH
:
13950 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
13952 case OPC_CMP_LT_QH
:
13954 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
13956 case OPC_CMP_LE_QH
:
13958 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
13960 case OPC_CMPGDU_EQ_OB
:
13962 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13964 case OPC_CMPGDU_LT_OB
:
13966 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13968 case OPC_CMPGDU_LE_OB
:
13970 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13972 case OPC_CMPGU_EQ_OB
:
13974 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13976 case OPC_CMPGU_LT_OB
:
13978 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13980 case OPC_CMPGU_LE_OB
:
13982 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13984 case OPC_CMPU_EQ_OB
:
13986 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
13988 case OPC_CMPU_LT_OB
:
13990 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
13992 case OPC_CMPU_LE_OB
:
13994 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
13996 case OPC_PACKRL_PW
:
13998 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14002 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14006 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14010 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14018 tcg_temp_free(v1_t
);
14019 tcg_temp_free(v2_t
);
14021 (void)opn
; /* avoid a compiler warning */
14022 MIPS_DEBUG("%s", opn
);
14025 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14026 uint32_t op1
, int rt
, int rs
, int sa
)
14028 const char *opn
= "mipsdsp append/dappend";
14034 /* Treat as NOP. */
14039 t0
= tcg_temp_new();
14040 gen_load_gpr(t0
, rs
);
14043 case OPC_APPEND_DSP
:
14044 switch (MASK_APPEND(ctx
->opcode
)) {
14047 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14049 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14053 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14054 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14055 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14056 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14058 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14062 if (sa
!= 0 && sa
!= 2) {
14063 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14064 tcg_gen_ext32u_tl(t0
, t0
);
14065 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14066 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14068 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14070 default: /* Invalid */
14071 MIPS_INVAL("MASK APPEND");
14072 generate_exception(ctx
, EXCP_RI
);
14076 #ifdef TARGET_MIPS64
14077 case OPC_DAPPEND_DSP
:
14078 switch (MASK_DAPPEND(ctx
->opcode
)) {
14081 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14085 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14086 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14087 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14091 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14092 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14093 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14098 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14099 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14100 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14101 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14104 default: /* Invalid */
14105 MIPS_INVAL("MASK DAPPEND");
14106 generate_exception(ctx
, EXCP_RI
);
14113 (void)opn
; /* avoid a compiler warning */
14114 MIPS_DEBUG("%s", opn
);
14117 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14118 int ret
, int v1
, int v2
, int check_ret
)
14121 const char *opn
= "mipsdsp accumulator";
14128 if ((ret
== 0) && (check_ret
== 1)) {
14129 /* Treat as NOP. */
14134 t0
= tcg_temp_new();
14135 t1
= tcg_temp_new();
14136 v1_t
= tcg_temp_new();
14137 v2_t
= tcg_temp_new();
14139 gen_load_gpr(v1_t
, v1
);
14140 gen_load_gpr(v2_t
, v2
);
14143 case OPC_EXTR_W_DSP
:
14147 tcg_gen_movi_tl(t0
, v2
);
14148 tcg_gen_movi_tl(t1
, v1
);
14149 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14152 tcg_gen_movi_tl(t0
, v2
);
14153 tcg_gen_movi_tl(t1
, v1
);
14154 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14156 case OPC_EXTR_RS_W
:
14157 tcg_gen_movi_tl(t0
, v2
);
14158 tcg_gen_movi_tl(t1
, v1
);
14159 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14162 tcg_gen_movi_tl(t0
, v2
);
14163 tcg_gen_movi_tl(t1
, v1
);
14164 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14166 case OPC_EXTRV_S_H
:
14167 tcg_gen_movi_tl(t0
, v2
);
14168 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14171 tcg_gen_movi_tl(t0
, v2
);
14172 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14174 case OPC_EXTRV_R_W
:
14175 tcg_gen_movi_tl(t0
, v2
);
14176 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14178 case OPC_EXTRV_RS_W
:
14179 tcg_gen_movi_tl(t0
, v2
);
14180 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14183 tcg_gen_movi_tl(t0
, v2
);
14184 tcg_gen_movi_tl(t1
, v1
);
14185 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14188 tcg_gen_movi_tl(t0
, v2
);
14189 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14192 tcg_gen_movi_tl(t0
, v2
);
14193 tcg_gen_movi_tl(t1
, v1
);
14194 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14197 tcg_gen_movi_tl(t0
, v2
);
14198 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14201 imm
= (ctx
->opcode
>> 20) & 0x3F;
14202 tcg_gen_movi_tl(t0
, ret
);
14203 tcg_gen_movi_tl(t1
, imm
);
14204 gen_helper_shilo(t0
, t1
, cpu_env
);
14207 tcg_gen_movi_tl(t0
, ret
);
14208 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14211 tcg_gen_movi_tl(t0
, ret
);
14212 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14215 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14216 tcg_gen_movi_tl(t0
, imm
);
14217 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14220 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14221 tcg_gen_movi_tl(t0
, imm
);
14222 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14226 #ifdef TARGET_MIPS64
14227 case OPC_DEXTR_W_DSP
:
14231 tcg_gen_movi_tl(t0
, ret
);
14232 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14236 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14237 int ac
= (ctx
->opcode
>> 11) & 0x03;
14238 tcg_gen_movi_tl(t0
, shift
);
14239 tcg_gen_movi_tl(t1
, ac
);
14240 gen_helper_dshilo(t0
, t1
, cpu_env
);
14245 int ac
= (ctx
->opcode
>> 11) & 0x03;
14246 tcg_gen_movi_tl(t0
, ac
);
14247 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14251 tcg_gen_movi_tl(t0
, v2
);
14252 tcg_gen_movi_tl(t1
, v1
);
14254 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14257 tcg_gen_movi_tl(t0
, v2
);
14258 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14261 tcg_gen_movi_tl(t0
, v2
);
14262 tcg_gen_movi_tl(t1
, v1
);
14263 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14266 tcg_gen_movi_tl(t0
, v2
);
14267 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14270 tcg_gen_movi_tl(t0
, v2
);
14271 tcg_gen_movi_tl(t1
, v1
);
14272 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14274 case OPC_DEXTR_R_L
:
14275 tcg_gen_movi_tl(t0
, v2
);
14276 tcg_gen_movi_tl(t1
, v1
);
14277 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14279 case OPC_DEXTR_RS_L
:
14280 tcg_gen_movi_tl(t0
, v2
);
14281 tcg_gen_movi_tl(t1
, v1
);
14282 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14285 tcg_gen_movi_tl(t0
, v2
);
14286 tcg_gen_movi_tl(t1
, v1
);
14287 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14289 case OPC_DEXTR_R_W
:
14290 tcg_gen_movi_tl(t0
, v2
);
14291 tcg_gen_movi_tl(t1
, v1
);
14292 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14294 case OPC_DEXTR_RS_W
:
14295 tcg_gen_movi_tl(t0
, v2
);
14296 tcg_gen_movi_tl(t1
, v1
);
14297 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14299 case OPC_DEXTR_S_H
:
14300 tcg_gen_movi_tl(t0
, v2
);
14301 tcg_gen_movi_tl(t1
, v1
);
14302 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14304 case OPC_DEXTRV_S_H
:
14305 tcg_gen_movi_tl(t0
, v2
);
14306 tcg_gen_movi_tl(t1
, v1
);
14307 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14310 tcg_gen_movi_tl(t0
, v2
);
14311 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14313 case OPC_DEXTRV_R_L
:
14314 tcg_gen_movi_tl(t0
, v2
);
14315 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14317 case OPC_DEXTRV_RS_L
:
14318 tcg_gen_movi_tl(t0
, v2
);
14319 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14322 tcg_gen_movi_tl(t0
, v2
);
14323 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14325 case OPC_DEXTRV_R_W
:
14326 tcg_gen_movi_tl(t0
, v2
);
14327 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14329 case OPC_DEXTRV_RS_W
:
14330 tcg_gen_movi_tl(t0
, v2
);
14331 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14340 tcg_temp_free(v1_t
);
14341 tcg_temp_free(v2_t
);
14343 (void)opn
; /* avoid a compiler warning */
14344 MIPS_DEBUG("%s", opn
);
14347 /* End MIPSDSP functions. */
14349 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
, int *is_branch
)
14352 int rs
, rt
, rd
, sa
;
14353 uint32_t op
, op1
, op2
;
14356 /* make sure instructions are on a word boundary */
14357 if (ctx
->pc
& 0x3) {
14358 env
->CP0_BadVAddr
= ctx
->pc
;
14359 generate_exception(ctx
, EXCP_AdEL
);
14363 /* Handle blikely not taken case */
14364 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14365 int l1
= gen_new_label();
14367 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14368 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14369 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14370 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14374 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14375 tcg_gen_debug_insn_start(ctx
->pc
);
14378 op
= MASK_OP_MAJOR(ctx
->opcode
);
14379 rs
= (ctx
->opcode
>> 21) & 0x1f;
14380 rt
= (ctx
->opcode
>> 16) & 0x1f;
14381 rd
= (ctx
->opcode
>> 11) & 0x1f;
14382 sa
= (ctx
->opcode
>> 6) & 0x1f;
14383 imm
= (int16_t)ctx
->opcode
;
14386 op1
= MASK_SPECIAL(ctx
->opcode
);
14388 case OPC_SLL
: /* Shift with immediate */
14390 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14393 switch ((ctx
->opcode
>> 21) & 0x1f) {
14395 /* rotr is decoded as srl on non-R2 CPUs */
14396 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14401 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14404 generate_exception(ctx
, EXCP_RI
);
14408 case OPC_MOVN
: /* Conditional move */
14410 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14411 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14412 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14414 case OPC_ADD
... OPC_SUBU
:
14415 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14417 case OPC_SLLV
: /* Shifts */
14419 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14422 switch ((ctx
->opcode
>> 6) & 0x1f) {
14424 /* rotrv is decoded as srlv on non-R2 CPUs */
14425 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14430 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14433 generate_exception(ctx
, EXCP_RI
);
14437 case OPC_SLT
: /* Set on less than */
14439 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14441 case OPC_AND
: /* Logic*/
14445 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14450 check_insn(ctx
, INSN_VR54XX
);
14451 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14452 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14454 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14459 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14461 case OPC_JR
... OPC_JALR
:
14462 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14465 case OPC_TGE
... OPC_TEQ
: /* Traps */
14467 gen_trap(ctx
, op1
, rs
, rt
, -1);
14469 case OPC_MFHI
: /* Move from HI/LO */
14471 gen_HILO(ctx
, op1
, rs
& 3, rd
);
14474 case OPC_MTLO
: /* Move to HI/LO */
14475 gen_HILO(ctx
, op1
, rd
& 3, rs
);
14477 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14478 #ifdef MIPS_STRICT_STANDARD
14479 MIPS_INVAL("PMON / selsl");
14480 generate_exception(ctx
, EXCP_RI
);
14482 gen_helper_0e0i(pmon
, sa
);
14486 generate_exception(ctx
, EXCP_SYSCALL
);
14487 ctx
->bstate
= BS_STOP
;
14490 generate_exception(ctx
, EXCP_BREAK
);
14493 #ifdef MIPS_STRICT_STANDARD
14494 MIPS_INVAL("SPIM");
14495 generate_exception(ctx
, EXCP_RI
);
14497 /* Implemented as RI exception for now. */
14498 MIPS_INVAL("spim (unofficial)");
14499 generate_exception(ctx
, EXCP_RI
);
14503 /* Treat as NOP. */
14507 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14508 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14509 check_cp1_enabled(ctx
);
14510 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14511 (ctx
->opcode
>> 16) & 1);
14513 generate_exception_err(ctx
, EXCP_CpU
, 1);
14517 #if defined(TARGET_MIPS64)
14518 /* MIPS64 specific opcodes */
14523 check_insn(ctx
, ISA_MIPS3
);
14524 check_mips_64(ctx
);
14525 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14528 switch ((ctx
->opcode
>> 21) & 0x1f) {
14530 /* drotr is decoded as dsrl on non-R2 CPUs */
14531 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14536 check_insn(ctx
, ISA_MIPS3
);
14537 check_mips_64(ctx
);
14538 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14541 generate_exception(ctx
, EXCP_RI
);
14546 switch ((ctx
->opcode
>> 21) & 0x1f) {
14548 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14549 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14554 check_insn(ctx
, ISA_MIPS3
);
14555 check_mips_64(ctx
);
14556 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14559 generate_exception(ctx
, EXCP_RI
);
14563 case OPC_DADD
... OPC_DSUBU
:
14564 check_insn(ctx
, ISA_MIPS3
);
14565 check_mips_64(ctx
);
14566 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14570 check_insn(ctx
, ISA_MIPS3
);
14571 check_mips_64(ctx
);
14572 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14575 switch ((ctx
->opcode
>> 6) & 0x1f) {
14577 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14578 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14583 check_insn(ctx
, ISA_MIPS3
);
14584 check_mips_64(ctx
);
14585 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14588 generate_exception(ctx
, EXCP_RI
);
14592 case OPC_DMULT
... OPC_DDIVU
:
14593 check_insn(ctx
, ISA_MIPS3
);
14594 check_mips_64(ctx
);
14595 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14598 default: /* Invalid */
14599 MIPS_INVAL("special");
14600 generate_exception(ctx
, EXCP_RI
);
14605 op1
= MASK_SPECIAL2(ctx
->opcode
);
14607 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14608 case OPC_MSUB
... OPC_MSUBU
:
14609 check_insn(ctx
, ISA_MIPS32
);
14610 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14613 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14617 check_insn(ctx
, ISA_MIPS32
);
14618 gen_cl(ctx
, op1
, rd
, rs
);
14621 /* XXX: not clear which exception should be raised
14622 * when in debug mode...
14624 check_insn(ctx
, ISA_MIPS32
);
14625 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14626 generate_exception(ctx
, EXCP_DBp
);
14628 generate_exception(ctx
, EXCP_DBp
);
14630 /* Treat as NOP. */
14633 case OPC_DIVU_G_2F
:
14634 case OPC_MULT_G_2F
:
14635 case OPC_MULTU_G_2F
:
14637 case OPC_MODU_G_2F
:
14638 check_insn(ctx
, INSN_LOONGSON2F
);
14639 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14641 #if defined(TARGET_MIPS64)
14644 check_insn(ctx
, ISA_MIPS64
);
14645 check_mips_64(ctx
);
14646 gen_cl(ctx
, op1
, rd
, rs
);
14648 case OPC_DMULT_G_2F
:
14649 case OPC_DMULTU_G_2F
:
14650 case OPC_DDIV_G_2F
:
14651 case OPC_DDIVU_G_2F
:
14652 case OPC_DMOD_G_2F
:
14653 case OPC_DMODU_G_2F
:
14654 check_insn(ctx
, INSN_LOONGSON2F
);
14655 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14658 default: /* Invalid */
14659 MIPS_INVAL("special2");
14660 generate_exception(ctx
, EXCP_RI
);
14665 op1
= MASK_SPECIAL3(ctx
->opcode
);
14669 check_insn(ctx
, ISA_MIPS32R2
);
14670 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14673 check_insn(ctx
, ISA_MIPS32R2
);
14674 op2
= MASK_BSHFL(ctx
->opcode
);
14675 gen_bshfl(ctx
, op2
, rt
, rd
);
14678 gen_rdhwr(ctx
, rt
, rd
);
14681 check_insn(ctx
, ASE_MT
);
14683 TCGv t0
= tcg_temp_new();
14684 TCGv t1
= tcg_temp_new();
14686 gen_load_gpr(t0
, rt
);
14687 gen_load_gpr(t1
, rs
);
14688 gen_helper_fork(t0
, t1
);
14694 check_insn(ctx
, ASE_MT
);
14696 TCGv t0
= tcg_temp_new();
14698 save_cpu_state(ctx
, 1);
14699 gen_load_gpr(t0
, rs
);
14700 gen_helper_yield(t0
, cpu_env
, t0
);
14701 gen_store_gpr(t0
, rd
);
14705 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14706 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14707 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14708 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14709 * the same mask and op1. */
14710 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14711 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14714 case OPC_ADDUH_R_QB
:
14716 case OPC_ADDQH_R_PH
:
14718 case OPC_ADDQH_R_W
:
14720 case OPC_SUBUH_R_QB
:
14722 case OPC_SUBQH_R_PH
:
14724 case OPC_SUBQH_R_W
:
14725 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14730 case OPC_MULQ_RS_W
:
14731 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14734 MIPS_INVAL("MASK ADDUH.QB");
14735 generate_exception(ctx
, EXCP_RI
);
14738 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14739 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14741 generate_exception(ctx
, EXCP_RI
);
14745 op2
= MASK_LX(ctx
->opcode
);
14747 #if defined(TARGET_MIPS64)
14753 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14755 default: /* Invalid */
14756 MIPS_INVAL("MASK LX");
14757 generate_exception(ctx
, EXCP_RI
);
14761 case OPC_ABSQ_S_PH_DSP
:
14762 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14764 case OPC_ABSQ_S_QB
:
14765 case OPC_ABSQ_S_PH
:
14767 case OPC_PRECEQ_W_PHL
:
14768 case OPC_PRECEQ_W_PHR
:
14769 case OPC_PRECEQU_PH_QBL
:
14770 case OPC_PRECEQU_PH_QBR
:
14771 case OPC_PRECEQU_PH_QBLA
:
14772 case OPC_PRECEQU_PH_QBRA
:
14773 case OPC_PRECEU_PH_QBL
:
14774 case OPC_PRECEU_PH_QBR
:
14775 case OPC_PRECEU_PH_QBLA
:
14776 case OPC_PRECEU_PH_QBRA
:
14777 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14784 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14787 MIPS_INVAL("MASK ABSQ_S.PH");
14788 generate_exception(ctx
, EXCP_RI
);
14792 case OPC_ADDU_QB_DSP
:
14793 op2
= MASK_ADDU_QB(ctx
->opcode
);
14796 case OPC_ADDQ_S_PH
:
14799 case OPC_ADDU_S_QB
:
14801 case OPC_ADDU_S_PH
:
14803 case OPC_SUBQ_S_PH
:
14806 case OPC_SUBU_S_QB
:
14808 case OPC_SUBU_S_PH
:
14812 case OPC_RADDU_W_QB
:
14813 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14815 case OPC_MULEU_S_PH_QBL
:
14816 case OPC_MULEU_S_PH_QBR
:
14817 case OPC_MULQ_RS_PH
:
14818 case OPC_MULEQ_S_W_PHL
:
14819 case OPC_MULEQ_S_W_PHR
:
14820 case OPC_MULQ_S_PH
:
14821 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14823 default: /* Invalid */
14824 MIPS_INVAL("MASK ADDU.QB");
14825 generate_exception(ctx
, EXCP_RI
);
14830 case OPC_CMPU_EQ_QB_DSP
:
14831 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14833 case OPC_PRECR_SRA_PH_W
:
14834 case OPC_PRECR_SRA_R_PH_W
:
14835 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14837 case OPC_PRECR_QB_PH
:
14838 case OPC_PRECRQ_QB_PH
:
14839 case OPC_PRECRQ_PH_W
:
14840 case OPC_PRECRQ_RS_PH_W
:
14841 case OPC_PRECRQU_S_QB_PH
:
14842 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14844 case OPC_CMPU_EQ_QB
:
14845 case OPC_CMPU_LT_QB
:
14846 case OPC_CMPU_LE_QB
:
14847 case OPC_CMP_EQ_PH
:
14848 case OPC_CMP_LT_PH
:
14849 case OPC_CMP_LE_PH
:
14850 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14852 case OPC_CMPGU_EQ_QB
:
14853 case OPC_CMPGU_LT_QB
:
14854 case OPC_CMPGU_LE_QB
:
14855 case OPC_CMPGDU_EQ_QB
:
14856 case OPC_CMPGDU_LT_QB
:
14857 case OPC_CMPGDU_LE_QB
:
14860 case OPC_PACKRL_PH
:
14861 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14863 default: /* Invalid */
14864 MIPS_INVAL("MASK CMPU.EQ.QB");
14865 generate_exception(ctx
, EXCP_RI
);
14869 case OPC_SHLL_QB_DSP
:
14870 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14872 case OPC_DPA_W_PH_DSP
:
14873 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14875 case OPC_DPAU_H_QBL
:
14876 case OPC_DPAU_H_QBR
:
14877 case OPC_DPSU_H_QBL
:
14878 case OPC_DPSU_H_QBR
:
14880 case OPC_DPAX_W_PH
:
14881 case OPC_DPAQ_S_W_PH
:
14882 case OPC_DPAQX_S_W_PH
:
14883 case OPC_DPAQX_SA_W_PH
:
14885 case OPC_DPSX_W_PH
:
14886 case OPC_DPSQ_S_W_PH
:
14887 case OPC_DPSQX_S_W_PH
:
14888 case OPC_DPSQX_SA_W_PH
:
14889 case OPC_MULSAQ_S_W_PH
:
14890 case OPC_DPAQ_SA_L_W
:
14891 case OPC_DPSQ_SA_L_W
:
14892 case OPC_MAQ_S_W_PHL
:
14893 case OPC_MAQ_S_W_PHR
:
14894 case OPC_MAQ_SA_W_PHL
:
14895 case OPC_MAQ_SA_W_PHR
:
14896 case OPC_MULSA_W_PH
:
14897 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14899 default: /* Invalid */
14900 MIPS_INVAL("MASK DPAW.PH");
14901 generate_exception(ctx
, EXCP_RI
);
14906 op2
= MASK_INSV(ctx
->opcode
);
14918 t0
= tcg_temp_new();
14919 t1
= tcg_temp_new();
14921 gen_load_gpr(t0
, rt
);
14922 gen_load_gpr(t1
, rs
);
14924 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
14930 default: /* Invalid */
14931 MIPS_INVAL("MASK INSV");
14932 generate_exception(ctx
, EXCP_RI
);
14936 case OPC_APPEND_DSP
:
14937 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
14939 case OPC_EXTR_W_DSP
:
14940 op2
= MASK_EXTR_W(ctx
->opcode
);
14944 case OPC_EXTR_RS_W
:
14946 case OPC_EXTRV_S_H
:
14948 case OPC_EXTRV_R_W
:
14949 case OPC_EXTRV_RS_W
:
14954 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
14957 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14963 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14965 default: /* Invalid */
14966 MIPS_INVAL("MASK EXTR.W");
14967 generate_exception(ctx
, EXCP_RI
);
14971 #if defined(TARGET_MIPS64)
14972 case OPC_DEXTM
... OPC_DEXT
:
14973 case OPC_DINSM
... OPC_DINS
:
14974 check_insn(ctx
, ISA_MIPS64R2
);
14975 check_mips_64(ctx
);
14976 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14979 check_insn(ctx
, ISA_MIPS64R2
);
14980 check_mips_64(ctx
);
14981 op2
= MASK_DBSHFL(ctx
->opcode
);
14982 gen_bshfl(ctx
, op2
, rt
, rd
);
14984 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
14985 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
14986 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
14987 check_insn(ctx
, INSN_LOONGSON2E
);
14988 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14990 case OPC_ABSQ_S_QH_DSP
:
14991 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
14993 case OPC_PRECEQ_L_PWL
:
14994 case OPC_PRECEQ_L_PWR
:
14995 case OPC_PRECEQ_PW_QHL
:
14996 case OPC_PRECEQ_PW_QHR
:
14997 case OPC_PRECEQ_PW_QHLA
:
14998 case OPC_PRECEQ_PW_QHRA
:
14999 case OPC_PRECEQU_QH_OBL
:
15000 case OPC_PRECEQU_QH_OBR
:
15001 case OPC_PRECEQU_QH_OBLA
:
15002 case OPC_PRECEQU_QH_OBRA
:
15003 case OPC_PRECEU_QH_OBL
:
15004 case OPC_PRECEU_QH_OBR
:
15005 case OPC_PRECEU_QH_OBLA
:
15006 case OPC_PRECEU_QH_OBRA
:
15007 case OPC_ABSQ_S_OB
:
15008 case OPC_ABSQ_S_PW
:
15009 case OPC_ABSQ_S_QH
:
15010 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15018 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
15020 default: /* Invalid */
15021 MIPS_INVAL("MASK ABSQ_S.QH");
15022 generate_exception(ctx
, EXCP_RI
);
15026 case OPC_ADDU_OB_DSP
:
15027 op2
= MASK_ADDU_OB(ctx
->opcode
);
15029 case OPC_RADDU_L_OB
:
15031 case OPC_SUBQ_S_PW
:
15033 case OPC_SUBQ_S_QH
:
15035 case OPC_SUBU_S_OB
:
15037 case OPC_SUBU_S_QH
:
15039 case OPC_SUBUH_R_OB
:
15041 case OPC_ADDQ_S_PW
:
15043 case OPC_ADDQ_S_QH
:
15045 case OPC_ADDU_S_OB
:
15047 case OPC_ADDU_S_QH
:
15049 case OPC_ADDUH_R_OB
:
15050 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15052 case OPC_MULEQ_S_PW_QHL
:
15053 case OPC_MULEQ_S_PW_QHR
:
15054 case OPC_MULEU_S_QH_OBL
:
15055 case OPC_MULEU_S_QH_OBR
:
15056 case OPC_MULQ_RS_QH
:
15057 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15059 default: /* Invalid */
15060 MIPS_INVAL("MASK ADDU.OB");
15061 generate_exception(ctx
, EXCP_RI
);
15065 case OPC_CMPU_EQ_OB_DSP
:
15066 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15068 case OPC_PRECR_SRA_QH_PW
:
15069 case OPC_PRECR_SRA_R_QH_PW
:
15070 /* Return value is rt. */
15071 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15073 case OPC_PRECR_OB_QH
:
15074 case OPC_PRECRQ_OB_QH
:
15075 case OPC_PRECRQ_PW_L
:
15076 case OPC_PRECRQ_QH_PW
:
15077 case OPC_PRECRQ_RS_QH_PW
:
15078 case OPC_PRECRQU_S_OB_QH
:
15079 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15081 case OPC_CMPU_EQ_OB
:
15082 case OPC_CMPU_LT_OB
:
15083 case OPC_CMPU_LE_OB
:
15084 case OPC_CMP_EQ_QH
:
15085 case OPC_CMP_LT_QH
:
15086 case OPC_CMP_LE_QH
:
15087 case OPC_CMP_EQ_PW
:
15088 case OPC_CMP_LT_PW
:
15089 case OPC_CMP_LE_PW
:
15090 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15092 case OPC_CMPGDU_EQ_OB
:
15093 case OPC_CMPGDU_LT_OB
:
15094 case OPC_CMPGDU_LE_OB
:
15095 case OPC_CMPGU_EQ_OB
:
15096 case OPC_CMPGU_LT_OB
:
15097 case OPC_CMPGU_LE_OB
:
15098 case OPC_PACKRL_PW
:
15102 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15104 default: /* Invalid */
15105 MIPS_INVAL("MASK CMPU_EQ.OB");
15106 generate_exception(ctx
, EXCP_RI
);
15110 case OPC_DAPPEND_DSP
:
15111 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15113 case OPC_DEXTR_W_DSP
:
15114 op2
= MASK_DEXTR_W(ctx
->opcode
);
15121 case OPC_DEXTR_R_L
:
15122 case OPC_DEXTR_RS_L
:
15124 case OPC_DEXTR_R_W
:
15125 case OPC_DEXTR_RS_W
:
15126 case OPC_DEXTR_S_H
:
15128 case OPC_DEXTRV_R_L
:
15129 case OPC_DEXTRV_RS_L
:
15130 case OPC_DEXTRV_S_H
:
15132 case OPC_DEXTRV_R_W
:
15133 case OPC_DEXTRV_RS_W
:
15134 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15139 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15141 default: /* Invalid */
15142 MIPS_INVAL("MASK EXTR.W");
15143 generate_exception(ctx
, EXCP_RI
);
15147 case OPC_DPAQ_W_QH_DSP
:
15148 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15150 case OPC_DPAU_H_OBL
:
15151 case OPC_DPAU_H_OBR
:
15152 case OPC_DPSU_H_OBL
:
15153 case OPC_DPSU_H_OBR
:
15155 case OPC_DPAQ_S_W_QH
:
15157 case OPC_DPSQ_S_W_QH
:
15158 case OPC_MULSAQ_S_W_QH
:
15159 case OPC_DPAQ_SA_L_PW
:
15160 case OPC_DPSQ_SA_L_PW
:
15161 case OPC_MULSAQ_S_L_PW
:
15162 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15164 case OPC_MAQ_S_W_QHLL
:
15165 case OPC_MAQ_S_W_QHLR
:
15166 case OPC_MAQ_S_W_QHRL
:
15167 case OPC_MAQ_S_W_QHRR
:
15168 case OPC_MAQ_SA_W_QHLL
:
15169 case OPC_MAQ_SA_W_QHLR
:
15170 case OPC_MAQ_SA_W_QHRL
:
15171 case OPC_MAQ_SA_W_QHRR
:
15172 case OPC_MAQ_S_L_PWL
:
15173 case OPC_MAQ_S_L_PWR
:
15178 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15180 default: /* Invalid */
15181 MIPS_INVAL("MASK DPAQ.W.QH");
15182 generate_exception(ctx
, EXCP_RI
);
15186 case OPC_DINSV_DSP
:
15187 op2
= MASK_INSV(ctx
->opcode
);
15199 t0
= tcg_temp_new();
15200 t1
= tcg_temp_new();
15202 gen_load_gpr(t0
, rt
);
15203 gen_load_gpr(t1
, rs
);
15205 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15208 default: /* Invalid */
15209 MIPS_INVAL("MASK DINSV");
15210 generate_exception(ctx
, EXCP_RI
);
15214 case OPC_SHLL_OB_DSP
:
15215 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15218 default: /* Invalid */
15219 MIPS_INVAL("special3");
15220 generate_exception(ctx
, EXCP_RI
);
15225 op1
= MASK_REGIMM(ctx
->opcode
);
15227 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15228 case OPC_BLTZAL
... OPC_BGEZALL
:
15229 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15232 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15234 gen_trap(ctx
, op1
, rs
, -1, imm
);
15237 check_insn(ctx
, ISA_MIPS32R2
);
15238 /* Treat as NOP. */
15240 case OPC_BPOSGE32
: /* MIPS DSP branch */
15241 #if defined(TARGET_MIPS64)
15245 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15248 default: /* Invalid */
15249 MIPS_INVAL("regimm");
15250 generate_exception(ctx
, EXCP_RI
);
15255 check_cp0_enabled(ctx
);
15256 op1
= MASK_CP0(ctx
->opcode
);
15262 #if defined(TARGET_MIPS64)
15266 #ifndef CONFIG_USER_ONLY
15267 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15268 #endif /* !CONFIG_USER_ONLY */
15270 case OPC_C0_FIRST
... OPC_C0_LAST
:
15271 #ifndef CONFIG_USER_ONLY
15272 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15273 #endif /* !CONFIG_USER_ONLY */
15276 #ifndef CONFIG_USER_ONLY
15278 TCGv t0
= tcg_temp_new();
15280 op2
= MASK_MFMC0(ctx
->opcode
);
15283 check_insn(ctx
, ASE_MT
);
15284 gen_helper_dmt(t0
);
15285 gen_store_gpr(t0
, rt
);
15288 check_insn(ctx
, ASE_MT
);
15289 gen_helper_emt(t0
);
15290 gen_store_gpr(t0
, rt
);
15293 check_insn(ctx
, ASE_MT
);
15294 gen_helper_dvpe(t0
, cpu_env
);
15295 gen_store_gpr(t0
, rt
);
15298 check_insn(ctx
, ASE_MT
);
15299 gen_helper_evpe(t0
, cpu_env
);
15300 gen_store_gpr(t0
, rt
);
15303 check_insn(ctx
, ISA_MIPS32R2
);
15304 save_cpu_state(ctx
, 1);
15305 gen_helper_di(t0
, cpu_env
);
15306 gen_store_gpr(t0
, rt
);
15307 /* Stop translation as we may have switched the execution mode */
15308 ctx
->bstate
= BS_STOP
;
15311 check_insn(ctx
, ISA_MIPS32R2
);
15312 save_cpu_state(ctx
, 1);
15313 gen_helper_ei(t0
, cpu_env
);
15314 gen_store_gpr(t0
, rt
);
15315 /* Stop translation as we may have switched the execution mode */
15316 ctx
->bstate
= BS_STOP
;
15318 default: /* Invalid */
15319 MIPS_INVAL("mfmc0");
15320 generate_exception(ctx
, EXCP_RI
);
15325 #endif /* !CONFIG_USER_ONLY */
15328 check_insn(ctx
, ISA_MIPS32R2
);
15329 gen_load_srsgpr(rt
, rd
);
15332 check_insn(ctx
, ISA_MIPS32R2
);
15333 gen_store_srsgpr(rt
, rd
);
15337 generate_exception(ctx
, EXCP_RI
);
15341 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15343 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15345 case OPC_SLTI
: /* Set on less than with immediate opcode */
15347 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15349 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15353 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15355 case OPC_J
... OPC_JAL
: /* Jump */
15356 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15357 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15360 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15361 case OPC_BEQL
... OPC_BGTZL
:
15362 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15365 case OPC_LB
... OPC_LWR
: /* Load and stores */
15367 gen_ld(ctx
, op
, rt
, rs
, imm
);
15369 case OPC_SB
... OPC_SW
:
15371 gen_st(ctx
, op
, rt
, rs
, imm
);
15374 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15377 check_cp0_enabled(ctx
);
15378 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15379 /* Treat as NOP. */
15382 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15383 /* Treat as NOP. */
15386 /* Floating point (COP1). */
15391 gen_cop1_ldst(env
, ctx
, op
, rt
, rs
, imm
);
15395 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15396 check_cp1_enabled(ctx
);
15397 op1
= MASK_CP1(ctx
->opcode
);
15401 check_insn(ctx
, ISA_MIPS32R2
);
15406 gen_cp1(ctx
, op1
, rt
, rd
);
15408 #if defined(TARGET_MIPS64)
15411 check_insn(ctx
, ISA_MIPS3
);
15412 gen_cp1(ctx
, op1
, rt
, rd
);
15418 check_insn(ctx
, ASE_MIPS3D
);
15421 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15422 (rt
>> 2) & 0x7, imm
<< 2);
15430 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15435 generate_exception (ctx
, EXCP_RI
);
15439 generate_exception_err(ctx
, EXCP_CpU
, 1);
15448 /* COP2: Not implemented. */
15449 generate_exception_err(ctx
, EXCP_CpU
, 2);
15452 check_insn(ctx
, INSN_LOONGSON2F
);
15453 /* Note that these instructions use different fields. */
15454 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15458 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15459 check_cp1_enabled(ctx
);
15460 op1
= MASK_CP3(ctx
->opcode
);
15468 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15471 /* Treat as NOP. */
15486 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15490 generate_exception (ctx
, EXCP_RI
);
15494 generate_exception_err(ctx
, EXCP_CpU
, 1);
15498 #if defined(TARGET_MIPS64)
15499 /* MIPS64 opcodes */
15501 case OPC_LDL
... OPC_LDR
:
15504 check_insn(ctx
, ISA_MIPS3
);
15505 check_mips_64(ctx
);
15506 gen_ld(ctx
, op
, rt
, rs
, imm
);
15508 case OPC_SDL
... OPC_SDR
:
15510 check_insn(ctx
, ISA_MIPS3
);
15511 check_mips_64(ctx
);
15512 gen_st(ctx
, op
, rt
, rs
, imm
);
15515 check_insn(ctx
, ISA_MIPS3
);
15516 check_mips_64(ctx
);
15517 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15521 check_insn(ctx
, ISA_MIPS3
);
15522 check_mips_64(ctx
);
15523 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15527 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15528 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15529 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15533 check_insn(ctx
, ASE_MDMX
);
15534 /* MDMX: Not implemented. */
15535 default: /* Invalid */
15536 MIPS_INVAL("major opcode");
15537 generate_exception(ctx
, EXCP_RI
);
15543 gen_intermediate_code_internal (CPUMIPSState
*env
, TranslationBlock
*tb
,
15547 target_ulong pc_start
;
15548 uint16_t *gen_opc_end
;
15557 qemu_log("search pc %d\n", search_pc
);
15560 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15563 ctx
.singlestep_enabled
= env
->singlestep_enabled
;
15564 ctx
.insn_flags
= env
->insn_flags
;
15566 ctx
.bstate
= BS_NONE
;
15567 /* Restore delay slot state from the tb context. */
15568 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15569 restore_cpu_state(env
, &ctx
);
15570 #ifdef CONFIG_USER_ONLY
15571 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15573 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15576 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15577 if (max_insns
== 0)
15578 max_insns
= CF_COUNT_MASK
;
15579 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15581 while (ctx
.bstate
== BS_NONE
) {
15582 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
15583 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
15584 if (bp
->pc
== ctx
.pc
) {
15585 save_cpu_state(&ctx
, 1);
15586 ctx
.bstate
= BS_BRANCH
;
15587 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15588 /* Include the breakpoint location or the tb won't
15589 * be flushed when it must be. */
15591 goto done_generating
;
15597 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15601 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15603 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15604 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15605 gen_opc_btarget
[lj
] = ctx
.btarget
;
15606 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15607 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15609 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15613 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15614 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15616 decode_opc(env
, &ctx
, &is_branch
);
15617 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15618 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15619 insn_bytes
= decode_micromips_opc(env
, &ctx
, &is_branch
);
15620 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15621 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15622 insn_bytes
= decode_mips16_opc(env
, &ctx
, &is_branch
);
15624 generate_exception(&ctx
, EXCP_RI
);
15625 ctx
.bstate
= BS_STOP
;
15629 handle_delay_slot(&ctx
, insn_bytes
);
15631 ctx
.pc
+= insn_bytes
;
15635 /* Execute a branch and its delay slot as a single instruction.
15636 This is what GDB expects and is consistent with what the
15637 hardware does (e.g. if a delay slot instruction faults, the
15638 reported PC is the PC of the branch). */
15639 if (env
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0)
15642 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15645 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15649 if (num_insns
>= max_insns
)
15655 if (tb
->cflags
& CF_LAST_IO
)
15657 if (env
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15658 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15659 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15661 switch (ctx
.bstate
) {
15663 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15666 save_cpu_state(&ctx
, 0);
15667 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15670 tcg_gen_exit_tb(0);
15678 gen_tb_end(tb
, num_insns
);
15679 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15681 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15684 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15686 tb
->size
= ctx
.pc
- pc_start
;
15687 tb
->icount
= num_insns
;
15691 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15692 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15693 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15699 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15701 gen_intermediate_code_internal(env
, tb
, 0);
15704 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15706 gen_intermediate_code_internal(env
, tb
, 1);
15709 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15713 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15715 #define printfpr(fp) \
15718 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15719 " fd:%13g fs:%13g psu: %13g\n", \
15720 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15721 (double)(fp)->fd, \
15722 (double)(fp)->fs[FP_ENDIAN_IDX], \
15723 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15726 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15727 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15728 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15729 " fd:%13g fs:%13g psu:%13g\n", \
15730 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15732 (double)tmp.fs[FP_ENDIAN_IDX], \
15733 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15738 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15739 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15740 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15741 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15742 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15743 printfpr(&env
->active_fpu
.fpr
[i
]);
15749 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15750 /* Debug help: The architecture requires 32bit code to maintain proper
15751 sign-extended values on 64bit machines. */
15753 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15756 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15757 fprintf_function cpu_fprintf
,
15762 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15763 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15764 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15765 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15766 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15767 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15768 if (!SIGN_EXT_P(env
->btarget
))
15769 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15771 for (i
= 0; i
< 32; i
++) {
15772 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15773 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15776 if (!SIGN_EXT_P(env
->CP0_EPC
))
15777 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15778 if (!SIGN_EXT_P(env
->lladdr
))
15779 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15783 void cpu_dump_state (CPUMIPSState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
15788 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15789 " LO=0x" TARGET_FMT_lx
" ds %04x "
15790 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15791 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15792 env
->hflags
, env
->btarget
, env
->bcond
);
15793 for (i
= 0; i
< 32; i
++) {
15795 cpu_fprintf(f
, "GPR%02d:", i
);
15796 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15798 cpu_fprintf(f
, "\n");
15801 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15802 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15803 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15804 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15805 if (env
->hflags
& MIPS_HFLAG_FPU
)
15806 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15807 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15808 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15812 void mips_tcg_init(void)
15817 /* Initialize various static tables. */
15821 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15822 TCGV_UNUSED(cpu_gpr
[0]);
15823 for (i
= 1; i
< 32; i
++)
15824 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15825 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15828 for (i
= 0; i
< 32; i
++) {
15829 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15830 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15833 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15834 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15835 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15836 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15837 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15839 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15840 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15842 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15843 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15846 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15847 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15849 bcond
= tcg_global_mem_new(TCG_AREG0
,
15850 offsetof(CPUMIPSState
, bcond
), "bcond");
15851 btarget
= tcg_global_mem_new(TCG_AREG0
,
15852 offsetof(CPUMIPSState
, btarget
), "btarget");
15853 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15854 offsetof(CPUMIPSState
, hflags
), "hflags");
15856 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15857 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15859 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15860 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15863 /* register helpers */
15864 #define GEN_HELPER 2
15865 #include "helper.h"
15870 #include "translate_init.c"
15872 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15876 const mips_def_t
*def
;
15878 def
= cpu_mips_find_by_name(cpu_model
);
15881 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15883 env
->cpu_model
= def
;
15884 env
->cpu_model_str
= cpu_model
;
15886 #ifndef CONFIG_USER_ONLY
15887 mmu_init(env
, def
);
15889 fpu_init(env
, def
);
15890 mvp_init(env
, def
);
15892 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15897 void cpu_state_reset(CPUMIPSState
*env
)
15899 #ifndef CONFIG_USER_ONLY
15900 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
15901 CPUState
*cs
= CPU(cpu
);
15904 /* Reset registers to their default values */
15905 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15906 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15907 #ifdef TARGET_WORDS_BIGENDIAN
15908 env
->CP0_Config0
|= (1 << CP0C0_BE
);
15910 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
15911 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
15912 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
15913 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
15914 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
15915 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
15916 << env
->cpu_model
->CP0_LLAddr_shift
;
15917 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
15918 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
15919 env
->CCRes
= env
->cpu_model
->CCRes
;
15920 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
15921 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
15922 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
15923 env
->current_tc
= 0;
15924 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
15925 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
15926 #if defined(TARGET_MIPS64)
15927 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
15928 env
->SEGMask
|= 3ULL << 62;
15931 env
->PABITS
= env
->cpu_model
->PABITS
;
15932 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
15933 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
15934 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
15935 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
15936 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
15937 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
15938 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
15939 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
15940 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
15941 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
15942 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
15943 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
15944 env
->insn_flags
= env
->cpu_model
->insn_flags
;
15946 #if defined(CONFIG_USER_ONLY)
15947 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
15948 # ifdef TARGET_MIPS64
15949 /* Enable 64-bit register mode. */
15950 env
->CP0_Status
|= (1 << CP0St_PX
);
15952 # ifdef TARGET_ABI_MIPSN64
15953 /* Enable 64-bit address mode. */
15954 env
->CP0_Status
|= (1 << CP0St_UX
);
15956 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15957 hardware registers. */
15958 env
->CP0_HWREna
|= 0x0000000F;
15959 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15960 env
->CP0_Status
|= (1 << CP0St_CU1
);
15962 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
15963 env
->CP0_Status
|= (1 << CP0St_MX
);
15965 /* Enable 64-bit FPU if the target cpu supports it. */
15966 if (env
->active_fpu
.fcr0
& (1 << FCR0_F64
)) {
15967 env
->CP0_Status
|= (1 << CP0St_FR
);
15970 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
15971 /* If the exception was raised from a delay slot,
15972 come back to the jump. */
15973 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
15975 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
15977 env
->active_tc
.PC
= (int32_t)0xBFC00000;
15978 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
15979 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
15980 env
->CP0_Wired
= 0;
15981 env
->CP0_EBase
= 0x80000000 | (cs
->cpu_index
& 0x3FF);
15982 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
15983 /* vectored interrupts not implemented, timer on int 7,
15984 no performance counters. */
15985 env
->CP0_IntCtl
= 0xe0000000;
15989 for (i
= 0; i
< 7; i
++) {
15990 env
->CP0_WatchLo
[i
] = 0;
15991 env
->CP0_WatchHi
[i
] = 0x80000000;
15993 env
->CP0_WatchLo
[7] = 0;
15994 env
->CP0_WatchHi
[7] = 0;
15996 /* Count register increments in debug mode, EJTAG version 1 */
15997 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
15999 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
16002 /* Only TC0 on VPE 0 starts as active. */
16003 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
16004 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
16005 env
->tcs
[i
].CP0_TCHalt
= 1;
16007 env
->active_tc
.CP0_TCHalt
= 1;
16010 if (cs
->cpu_index
== 0) {
16011 /* VPE0 starts up enabled. */
16012 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
16013 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
16015 /* TC0 starts up unhalted. */
16017 env
->active_tc
.CP0_TCHalt
= 0;
16018 env
->tcs
[0].CP0_TCHalt
= 0;
16019 /* With thread 0 active. */
16020 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
16021 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16025 compute_hflags(env
);
16026 env
->exception_index
= EXCP_NONE
;
16029 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16031 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16032 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16033 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16034 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16035 case MIPS_HFLAG_BR
:
16037 case MIPS_HFLAG_BC
:
16038 case MIPS_HFLAG_BL
:
16040 env
->btarget
= gen_opc_btarget
[pc_pos
];