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"
27 #include "exec/cpu_ldst.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.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 int32_t CP0_Config1
;
1071 /* Routine used to access memory */
1073 uint32_t hflags
, saved_hflags
;
1075 target_ulong btarget
;
1080 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1081 * exception condition */
1082 BS_STOP
= 1, /* We want to stop translation for any reason */
1083 BS_BRANCH
= 2, /* We reached a branch condition */
1084 BS_EXCP
= 3, /* We reached an exception condition */
1087 static const char * const regnames
[] = {
1088 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1089 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1090 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1091 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1094 static const char * const regnames_HI
[] = {
1095 "HI0", "HI1", "HI2", "HI3",
1098 static const char * const regnames_LO
[] = {
1099 "LO0", "LO1", "LO2", "LO3",
1102 static const char * const regnames_ACX
[] = {
1103 "ACX0", "ACX1", "ACX2", "ACX3",
1106 static const char * const fregnames
[] = {
1107 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1108 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1109 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1110 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1113 #define MIPS_DEBUG(fmt, ...) \
1115 if (MIPS_DEBUG_DISAS) { \
1116 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1117 TARGET_FMT_lx ": %08x " fmt "\n", \
1118 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1122 #define LOG_DISAS(...) \
1124 if (MIPS_DEBUG_DISAS) { \
1125 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1129 #define MIPS_INVAL(op) \
1130 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1131 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1133 /* General purpose registers moves. */
1134 static inline void gen_load_gpr (TCGv t
, int reg
)
1137 tcg_gen_movi_tl(t
, 0);
1139 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1142 static inline void gen_store_gpr (TCGv t
, int reg
)
1145 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1148 /* Moves to/from ACX register. */
1149 static inline void gen_load_ACX (TCGv t
, int reg
)
1151 tcg_gen_mov_tl(t
, cpu_ACX
[reg
]);
1154 static inline void gen_store_ACX (TCGv t
, int reg
)
1156 tcg_gen_mov_tl(cpu_ACX
[reg
], t
);
1159 /* Moves to/from shadow registers. */
1160 static inline void gen_load_srsgpr (int from
, int to
)
1162 TCGv t0
= tcg_temp_new();
1165 tcg_gen_movi_tl(t0
, 0);
1167 TCGv_i32 t2
= tcg_temp_new_i32();
1168 TCGv_ptr addr
= tcg_temp_new_ptr();
1170 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1171 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1172 tcg_gen_andi_i32(t2
, t2
, 0xf);
1173 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1174 tcg_gen_ext_i32_ptr(addr
, t2
);
1175 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1177 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1178 tcg_temp_free_ptr(addr
);
1179 tcg_temp_free_i32(t2
);
1181 gen_store_gpr(t0
, to
);
1185 static inline void gen_store_srsgpr (int from
, int to
)
1188 TCGv t0
= tcg_temp_new();
1189 TCGv_i32 t2
= tcg_temp_new_i32();
1190 TCGv_ptr addr
= tcg_temp_new_ptr();
1192 gen_load_gpr(t0
, from
);
1193 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1194 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1195 tcg_gen_andi_i32(t2
, t2
, 0xf);
1196 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1197 tcg_gen_ext_i32_ptr(addr
, t2
);
1198 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1200 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1201 tcg_temp_free_ptr(addr
);
1202 tcg_temp_free_i32(t2
);
1207 /* Floating point register moves. */
1208 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1210 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1213 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1215 TCGv_i64 t64
= tcg_temp_new_i64();
1216 tcg_gen_extu_i32_i64(t64
, t
);
1217 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1218 tcg_temp_free_i64(t64
);
1221 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1223 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1224 TCGv_i64 t64
= tcg_temp_new_i64();
1225 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1226 tcg_gen_trunc_i64_i32(t
, t64
);
1227 tcg_temp_free_i64(t64
);
1229 gen_load_fpr32(t
, reg
| 1);
1233 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1235 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1236 TCGv_i64 t64
= tcg_temp_new_i64();
1237 tcg_gen_extu_i32_i64(t64
, t
);
1238 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1239 tcg_temp_free_i64(t64
);
1241 gen_store_fpr32(t
, reg
| 1);
1245 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1247 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1248 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1250 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1254 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1256 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1257 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1260 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1261 t0
= tcg_temp_new_i64();
1262 tcg_gen_shri_i64(t0
, t
, 32);
1263 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1264 tcg_temp_free_i64(t0
);
1268 static inline int get_fp_bit (int cc
)
1277 static inline void gen_save_pc(target_ulong pc
)
1279 tcg_gen_movi_tl(cpu_PC
, pc
);
1282 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1284 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1285 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1286 gen_save_pc(ctx
->pc
);
1287 ctx
->saved_pc
= ctx
->pc
;
1289 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1290 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1291 ctx
->saved_hflags
= ctx
->hflags
;
1292 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1298 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1304 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1306 ctx
->saved_hflags
= ctx
->hflags
;
1307 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1313 ctx
->btarget
= env
->btarget
;
1319 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1321 TCGv_i32 texcp
= tcg_const_i32(excp
);
1322 TCGv_i32 terr
= tcg_const_i32(err
);
1323 save_cpu_state(ctx
, 1);
1324 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1325 tcg_temp_free_i32(terr
);
1326 tcg_temp_free_i32(texcp
);
1330 generate_exception (DisasContext
*ctx
, int excp
)
1332 save_cpu_state(ctx
, 1);
1333 gen_helper_0e0i(raise_exception
, excp
);
1336 /* Addresses computation */
1337 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1339 tcg_gen_add_tl(ret
, arg0
, arg1
);
1341 #if defined(TARGET_MIPS64)
1342 /* For compatibility with 32-bit code, data reference in user mode
1343 with Status_UX = 0 should be casted to 32-bit and sign extended.
1344 See the MIPS64 PRA manual, section 4.10. */
1345 if (((ctx
->hflags
& MIPS_HFLAG_KSU
) == MIPS_HFLAG_UM
) &&
1346 !(ctx
->hflags
& MIPS_HFLAG_UX
)) {
1347 tcg_gen_ext32s_i64(ret
, ret
);
1352 static inline void check_cp0_enabled(DisasContext
*ctx
)
1354 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1355 generate_exception_err(ctx
, EXCP_CpU
, 0);
1358 static inline void check_cp1_enabled(DisasContext
*ctx
)
1360 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1361 generate_exception_err(ctx
, EXCP_CpU
, 1);
1364 /* Verify that the processor is running with COP1X instructions enabled.
1365 This is associated with the nabla symbol in the MIPS32 and MIPS64
1368 static inline void check_cop1x(DisasContext
*ctx
)
1370 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1371 generate_exception(ctx
, EXCP_RI
);
1374 /* Verify that the processor is running with 64-bit floating-point
1375 operations enabled. */
1377 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1379 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1380 generate_exception(ctx
, EXCP_RI
);
1384 * Verify if floating point register is valid; an operation is not defined
1385 * if bit 0 of any register specification is set and the FR bit in the
1386 * Status register equals zero, since the register numbers specify an
1387 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1388 * in the Status register equals one, both even and odd register numbers
1389 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1391 * Multiple 64 bit wide registers can be checked by calling
1392 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1394 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1396 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1397 generate_exception(ctx
, EXCP_RI
);
1400 /* Verify that the processor is running with DSP instructions enabled.
1401 This is enabled by CP0 Status register MX(24) bit.
1404 static inline void check_dsp(DisasContext
*ctx
)
1406 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1407 if (ctx
->insn_flags
& ASE_DSP
) {
1408 generate_exception(ctx
, EXCP_DSPDIS
);
1410 generate_exception(ctx
, EXCP_RI
);
1415 static inline void check_dspr2(DisasContext
*ctx
)
1417 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1418 if (ctx
->insn_flags
& ASE_DSP
) {
1419 generate_exception(ctx
, EXCP_DSPDIS
);
1421 generate_exception(ctx
, EXCP_RI
);
1426 /* This code generates a "reserved instruction" exception if the
1427 CPU does not support the instruction set corresponding to flags. */
1428 static inline void check_insn(DisasContext
*ctx
, int flags
)
1430 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1431 generate_exception(ctx
, EXCP_RI
);
1435 /* This code generates a "reserved instruction" exception if 64-bit
1436 instructions are not enabled. */
1437 static inline void check_mips_64(DisasContext
*ctx
)
1439 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1440 generate_exception(ctx
, EXCP_RI
);
1443 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1444 calling interface for 32 and 64-bit FPRs. No sense in changing
1445 all callers for gen_load_fpr32 when we need the CTX parameter for
1447 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1448 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1449 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1450 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1451 int ft, int fs, int cc) \
1453 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1454 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1457 check_cp1_64bitmode(ctx); \
1463 check_cp1_registers(ctx, fs | ft); \
1471 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1472 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1474 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1475 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1476 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1477 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1478 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1479 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1480 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1481 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1482 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1483 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1484 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1485 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1486 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1487 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1488 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1489 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1492 tcg_temp_free_i##bits (fp0); \
1493 tcg_temp_free_i##bits (fp1); \
1496 FOP_CONDS(, 0, d
, FMT_D
, 64)
1497 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1498 FOP_CONDS(, 0, s
, FMT_S
, 32)
1499 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1500 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1501 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1503 #undef gen_ldcmp_fpr32
1504 #undef gen_ldcmp_fpr64
1506 /* load/store instructions. */
1507 #ifdef CONFIG_USER_ONLY
1508 #define OP_LD_ATOMIC(insn,fname) \
1509 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1511 TCGv t0 = tcg_temp_new(); \
1512 tcg_gen_mov_tl(t0, arg1); \
1513 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1514 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1515 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1516 tcg_temp_free(t0); \
1519 #define OP_LD_ATOMIC(insn,fname) \
1520 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1522 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1525 OP_LD_ATOMIC(ll
,ld32s
);
1526 #if defined(TARGET_MIPS64)
1527 OP_LD_ATOMIC(lld
,ld64
);
1531 #ifdef CONFIG_USER_ONLY
1532 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1533 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1535 TCGv t0 = tcg_temp_new(); \
1536 int l1 = gen_new_label(); \
1537 int l2 = gen_new_label(); \
1539 tcg_gen_andi_tl(t0, arg2, almask); \
1540 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1541 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1542 generate_exception(ctx, EXCP_AdES); \
1543 gen_set_label(l1); \
1544 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1545 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1546 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1547 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1548 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1549 gen_helper_0e0i(raise_exception, EXCP_SC); \
1550 gen_set_label(l2); \
1551 tcg_gen_movi_tl(t0, 0); \
1552 gen_store_gpr(t0, rt); \
1553 tcg_temp_free(t0); \
1556 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1557 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1559 TCGv t0 = tcg_temp_new(); \
1560 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1561 gen_store_gpr(t0, rt); \
1562 tcg_temp_free(t0); \
1565 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1566 #if defined(TARGET_MIPS64)
1567 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1571 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1572 int base
, int16_t offset
)
1575 tcg_gen_movi_tl(addr
, offset
);
1576 } else if (offset
== 0) {
1577 gen_load_gpr(addr
, base
);
1579 tcg_gen_movi_tl(addr
, offset
);
1580 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1584 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1586 target_ulong pc
= ctx
->pc
;
1588 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1589 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1594 pc
&= ~(target_ulong
)3;
1599 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1600 int rt
, int base
, int16_t offset
)
1602 const char *opn
= "ld";
1605 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1606 /* Loongson CPU uses a load to zero register for prefetch.
1607 We emulate it as a NOP. On other CPU we must perform the
1608 actual memory access. */
1613 t0
= tcg_temp_new();
1614 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1617 #if defined(TARGET_MIPS64)
1619 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1620 gen_store_gpr(t0
, rt
);
1624 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1625 gen_store_gpr(t0
, rt
);
1629 save_cpu_state(ctx
, 1);
1630 op_ld_lld(t0
, t0
, ctx
);
1631 gen_store_gpr(t0
, rt
);
1635 t1
= tcg_temp_new();
1636 tcg_gen_andi_tl(t1
, t0
, 7);
1637 #ifndef TARGET_WORDS_BIGENDIAN
1638 tcg_gen_xori_tl(t1
, t1
, 7);
1640 tcg_gen_shli_tl(t1
, t1
, 3);
1641 tcg_gen_andi_tl(t0
, t0
, ~7);
1642 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1643 tcg_gen_shl_tl(t0
, t0
, t1
);
1644 tcg_gen_xori_tl(t1
, t1
, 63);
1645 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1646 tcg_gen_shr_tl(t2
, t2
, t1
);
1647 gen_load_gpr(t1
, rt
);
1648 tcg_gen_and_tl(t1
, t1
, t2
);
1650 tcg_gen_or_tl(t0
, t0
, t1
);
1652 gen_store_gpr(t0
, rt
);
1656 t1
= tcg_temp_new();
1657 tcg_gen_andi_tl(t1
, t0
, 7);
1658 #ifdef TARGET_WORDS_BIGENDIAN
1659 tcg_gen_xori_tl(t1
, t1
, 7);
1661 tcg_gen_shli_tl(t1
, t1
, 3);
1662 tcg_gen_andi_tl(t0
, t0
, ~7);
1663 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1664 tcg_gen_shr_tl(t0
, t0
, t1
);
1665 tcg_gen_xori_tl(t1
, t1
, 63);
1666 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1667 tcg_gen_shl_tl(t2
, t2
, t1
);
1668 gen_load_gpr(t1
, rt
);
1669 tcg_gen_and_tl(t1
, t1
, t2
);
1671 tcg_gen_or_tl(t0
, t0
, t1
);
1673 gen_store_gpr(t0
, rt
);
1677 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1678 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1680 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1681 gen_store_gpr(t0
, rt
);
1686 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1687 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1689 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1690 gen_store_gpr(t0
, rt
);
1694 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1695 gen_store_gpr(t0
, rt
);
1699 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
1700 gen_store_gpr(t0
, rt
);
1704 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
1705 gen_store_gpr(t0
, rt
);
1709 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
1710 gen_store_gpr(t0
, rt
);
1714 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
1715 gen_store_gpr(t0
, rt
);
1719 t1
= tcg_temp_new();
1720 tcg_gen_andi_tl(t1
, t0
, 3);
1721 #ifndef TARGET_WORDS_BIGENDIAN
1722 tcg_gen_xori_tl(t1
, t1
, 3);
1724 tcg_gen_shli_tl(t1
, t1
, 3);
1725 tcg_gen_andi_tl(t0
, t0
, ~3);
1726 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1727 tcg_gen_shl_tl(t0
, t0
, t1
);
1728 tcg_gen_xori_tl(t1
, t1
, 31);
1729 t2
= tcg_const_tl(0x7fffffffull
);
1730 tcg_gen_shr_tl(t2
, t2
, t1
);
1731 gen_load_gpr(t1
, rt
);
1732 tcg_gen_and_tl(t1
, t1
, t2
);
1734 tcg_gen_or_tl(t0
, t0
, t1
);
1736 tcg_gen_ext32s_tl(t0
, t0
);
1737 gen_store_gpr(t0
, rt
);
1741 t1
= tcg_temp_new();
1742 tcg_gen_andi_tl(t1
, t0
, 3);
1743 #ifdef TARGET_WORDS_BIGENDIAN
1744 tcg_gen_xori_tl(t1
, t1
, 3);
1746 tcg_gen_shli_tl(t1
, t1
, 3);
1747 tcg_gen_andi_tl(t0
, t0
, ~3);
1748 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1749 tcg_gen_shr_tl(t0
, t0
, t1
);
1750 tcg_gen_xori_tl(t1
, t1
, 31);
1751 t2
= tcg_const_tl(0xfffffffeull
);
1752 tcg_gen_shl_tl(t2
, t2
, t1
);
1753 gen_load_gpr(t1
, rt
);
1754 tcg_gen_and_tl(t1
, t1
, t2
);
1756 tcg_gen_or_tl(t0
, t0
, t1
);
1758 tcg_gen_ext32s_tl(t0
, t0
);
1759 gen_store_gpr(t0
, rt
);
1763 save_cpu_state(ctx
, 1);
1764 op_ld_ll(t0
, t0
, ctx
);
1765 gen_store_gpr(t0
, rt
);
1769 (void)opn
; /* avoid a compiler warning */
1770 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1775 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1776 int base
, int16_t offset
)
1778 const char *opn
= "st";
1779 TCGv t0
= tcg_temp_new();
1780 TCGv t1
= tcg_temp_new();
1782 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1783 gen_load_gpr(t1
, rt
);
1785 #if defined(TARGET_MIPS64)
1787 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
1791 save_cpu_state(ctx
, 1);
1792 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1796 save_cpu_state(ctx
, 1);
1797 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
1802 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
1806 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
1810 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
1814 save_cpu_state(ctx
, 1);
1815 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
1819 save_cpu_state(ctx
, 1);
1820 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
1824 (void)opn
; /* avoid a compiler warning */
1825 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1831 /* Store conditional */
1832 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
1833 int base
, int16_t offset
)
1835 const char *opn
= "st_cond";
1838 #ifdef CONFIG_USER_ONLY
1839 t0
= tcg_temp_local_new();
1840 t1
= tcg_temp_local_new();
1842 t0
= tcg_temp_new();
1843 t1
= tcg_temp_new();
1845 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1846 gen_load_gpr(t1
, rt
);
1848 #if defined(TARGET_MIPS64)
1850 save_cpu_state(ctx
, 1);
1851 op_st_scd(t1
, t0
, rt
, ctx
);
1856 save_cpu_state(ctx
, 1);
1857 op_st_sc(t1
, t0
, rt
, ctx
);
1861 (void)opn
; /* avoid a compiler warning */
1862 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1867 /* Load and store */
1868 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
1869 int base
, int16_t offset
)
1871 const char *opn
= "flt_ldst";
1872 TCGv t0
= tcg_temp_new();
1874 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1875 /* Don't do NOP if destination is zero: we must perform the actual
1880 TCGv_i32 fp0
= tcg_temp_new_i32();
1881 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
1882 gen_store_fpr32(fp0
, ft
);
1883 tcg_temp_free_i32(fp0
);
1889 TCGv_i32 fp0
= tcg_temp_new_i32();
1890 gen_load_fpr32(fp0
, ft
);
1891 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1892 tcg_temp_free_i32(fp0
);
1898 TCGv_i64 fp0
= tcg_temp_new_i64();
1899 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1900 gen_store_fpr64(ctx
, fp0
, ft
);
1901 tcg_temp_free_i64(fp0
);
1907 TCGv_i64 fp0
= tcg_temp_new_i64();
1908 gen_load_fpr64(ctx
, fp0
, ft
);
1909 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1910 tcg_temp_free_i64(fp0
);
1916 generate_exception(ctx
, EXCP_RI
);
1919 (void)opn
; /* avoid a compiler warning */
1920 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
1925 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
1926 int rs
, int16_t imm
)
1928 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
1929 check_cp1_enabled(ctx
);
1930 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
1932 generate_exception_err(ctx
, EXCP_CpU
, 1);
1936 /* Arithmetic with immediate operand */
1937 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
1938 int rt
, int rs
, int16_t imm
)
1940 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
1941 const char *opn
= "imm arith";
1943 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
1944 /* If no destination, treat it as a NOP.
1945 For addi, we must generate the overflow exception when needed. */
1952 TCGv t0
= tcg_temp_local_new();
1953 TCGv t1
= tcg_temp_new();
1954 TCGv t2
= tcg_temp_new();
1955 int l1
= gen_new_label();
1957 gen_load_gpr(t1
, rs
);
1958 tcg_gen_addi_tl(t0
, t1
, uimm
);
1959 tcg_gen_ext32s_tl(t0
, t0
);
1961 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1962 tcg_gen_xori_tl(t2
, t0
, uimm
);
1963 tcg_gen_and_tl(t1
, t1
, t2
);
1965 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1967 /* operands of same sign, result different sign */
1968 generate_exception(ctx
, EXCP_OVERFLOW
);
1970 tcg_gen_ext32s_tl(t0
, t0
);
1971 gen_store_gpr(t0
, rt
);
1978 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1979 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
1981 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1985 #if defined(TARGET_MIPS64)
1988 TCGv t0
= tcg_temp_local_new();
1989 TCGv t1
= tcg_temp_new();
1990 TCGv t2
= tcg_temp_new();
1991 int l1
= gen_new_label();
1993 gen_load_gpr(t1
, rs
);
1994 tcg_gen_addi_tl(t0
, t1
, uimm
);
1996 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1997 tcg_gen_xori_tl(t2
, t0
, uimm
);
1998 tcg_gen_and_tl(t1
, t1
, t2
);
2000 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2002 /* operands of same sign, result different sign */
2003 generate_exception(ctx
, EXCP_OVERFLOW
);
2005 gen_store_gpr(t0
, rt
);
2012 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2014 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2020 (void)opn
; /* avoid a compiler warning */
2021 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2024 /* Logic with immediate operand */
2025 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2026 int rt
, int rs
, int16_t imm
)
2031 /* If no destination, treat it as a NOP. */
2035 uimm
= (uint16_t)imm
;
2038 if (likely(rs
!= 0))
2039 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2041 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2042 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2043 regnames
[rs
], uimm
);
2047 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2049 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2050 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2051 regnames
[rs
], uimm
);
2054 if (likely(rs
!= 0))
2055 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2057 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2058 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2059 regnames
[rs
], uimm
);
2062 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2063 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2067 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2072 /* Set on less than with immediate operand */
2073 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2074 int rt
, int rs
, int16_t imm
)
2076 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2077 const char *opn
= "imm arith";
2081 /* If no destination, treat it as a NOP. */
2085 t0
= tcg_temp_new();
2086 gen_load_gpr(t0
, rs
);
2089 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2093 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2097 (void)opn
; /* avoid a compiler warning */
2098 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2102 /* Shifts with immediate operand */
2103 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2104 int rt
, int rs
, int16_t imm
)
2106 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2107 const char *opn
= "imm shift";
2111 /* If no destination, treat it as a NOP. */
2116 t0
= tcg_temp_new();
2117 gen_load_gpr(t0
, rs
);
2120 tcg_gen_shli_tl(t0
, t0
, uimm
);
2121 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2125 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2130 tcg_gen_ext32u_tl(t0
, t0
);
2131 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2133 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2139 TCGv_i32 t1
= tcg_temp_new_i32();
2141 tcg_gen_trunc_tl_i32(t1
, t0
);
2142 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2143 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2144 tcg_temp_free_i32(t1
);
2146 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2150 #if defined(TARGET_MIPS64)
2152 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2156 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2160 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2165 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2167 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2172 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2176 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2180 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2184 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2189 (void)opn
; /* avoid a compiler warning */
2190 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2195 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2196 int rd
, int rs
, int rt
)
2198 const char *opn
= "arith";
2200 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2201 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2202 /* If no destination, treat it as a NOP.
2203 For add & sub, we must generate the overflow exception when needed. */
2211 TCGv t0
= tcg_temp_local_new();
2212 TCGv t1
= tcg_temp_new();
2213 TCGv t2
= tcg_temp_new();
2214 int l1
= gen_new_label();
2216 gen_load_gpr(t1
, rs
);
2217 gen_load_gpr(t2
, rt
);
2218 tcg_gen_add_tl(t0
, t1
, t2
);
2219 tcg_gen_ext32s_tl(t0
, t0
);
2220 tcg_gen_xor_tl(t1
, t1
, t2
);
2221 tcg_gen_xor_tl(t2
, t0
, t2
);
2222 tcg_gen_andc_tl(t1
, t2
, t1
);
2224 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2226 /* operands of same sign, result different sign */
2227 generate_exception(ctx
, EXCP_OVERFLOW
);
2229 gen_store_gpr(t0
, rd
);
2235 if (rs
!= 0 && rt
!= 0) {
2236 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2237 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2238 } else if (rs
== 0 && rt
!= 0) {
2239 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2240 } else if (rs
!= 0 && rt
== 0) {
2241 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2243 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2249 TCGv t0
= tcg_temp_local_new();
2250 TCGv t1
= tcg_temp_new();
2251 TCGv t2
= tcg_temp_new();
2252 int l1
= gen_new_label();
2254 gen_load_gpr(t1
, rs
);
2255 gen_load_gpr(t2
, rt
);
2256 tcg_gen_sub_tl(t0
, t1
, t2
);
2257 tcg_gen_ext32s_tl(t0
, t0
);
2258 tcg_gen_xor_tl(t2
, t1
, t2
);
2259 tcg_gen_xor_tl(t1
, t0
, t1
);
2260 tcg_gen_and_tl(t1
, t1
, t2
);
2262 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2264 /* operands of different sign, first operand and result different sign */
2265 generate_exception(ctx
, EXCP_OVERFLOW
);
2267 gen_store_gpr(t0
, rd
);
2273 if (rs
!= 0 && rt
!= 0) {
2274 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2275 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2276 } else if (rs
== 0 && rt
!= 0) {
2277 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2278 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2279 } else if (rs
!= 0 && rt
== 0) {
2280 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2282 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2286 #if defined(TARGET_MIPS64)
2289 TCGv t0
= tcg_temp_local_new();
2290 TCGv t1
= tcg_temp_new();
2291 TCGv t2
= tcg_temp_new();
2292 int l1
= gen_new_label();
2294 gen_load_gpr(t1
, rs
);
2295 gen_load_gpr(t2
, rt
);
2296 tcg_gen_add_tl(t0
, t1
, t2
);
2297 tcg_gen_xor_tl(t1
, t1
, t2
);
2298 tcg_gen_xor_tl(t2
, t0
, t2
);
2299 tcg_gen_andc_tl(t1
, t2
, t1
);
2301 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2303 /* operands of same sign, result different sign */
2304 generate_exception(ctx
, EXCP_OVERFLOW
);
2306 gen_store_gpr(t0
, rd
);
2312 if (rs
!= 0 && rt
!= 0) {
2313 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2314 } else if (rs
== 0 && rt
!= 0) {
2315 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2316 } else if (rs
!= 0 && rt
== 0) {
2317 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2319 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2325 TCGv t0
= tcg_temp_local_new();
2326 TCGv t1
= tcg_temp_new();
2327 TCGv t2
= tcg_temp_new();
2328 int l1
= gen_new_label();
2330 gen_load_gpr(t1
, rs
);
2331 gen_load_gpr(t2
, rt
);
2332 tcg_gen_sub_tl(t0
, t1
, t2
);
2333 tcg_gen_xor_tl(t2
, t1
, t2
);
2334 tcg_gen_xor_tl(t1
, t0
, t1
);
2335 tcg_gen_and_tl(t1
, t1
, t2
);
2337 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2339 /* operands of different sign, first operand and result different sign */
2340 generate_exception(ctx
, EXCP_OVERFLOW
);
2342 gen_store_gpr(t0
, rd
);
2348 if (rs
!= 0 && rt
!= 0) {
2349 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2350 } else if (rs
== 0 && rt
!= 0) {
2351 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2352 } else if (rs
!= 0 && rt
== 0) {
2353 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2355 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2361 if (likely(rs
!= 0 && rt
!= 0)) {
2362 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2363 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2365 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2370 (void)opn
; /* avoid a compiler warning */
2371 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2374 /* Conditional move */
2375 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2376 int rd
, int rs
, int rt
)
2378 const char *opn
= "cond move";
2382 /* If no destination, treat it as a NOP. */
2387 t0
= tcg_temp_new();
2388 gen_load_gpr(t0
, rt
);
2389 t1
= tcg_const_tl(0);
2390 t2
= tcg_temp_new();
2391 gen_load_gpr(t2
, rs
);
2394 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2398 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2406 (void)opn
; /* avoid a compiler warning */
2407 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2411 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2412 int rd
, int rs
, int rt
)
2414 const char *opn
= "logic";
2417 /* If no destination, treat it as a NOP. */
2424 if (likely(rs
!= 0 && rt
!= 0)) {
2425 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2427 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2432 if (rs
!= 0 && rt
!= 0) {
2433 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2434 } else if (rs
== 0 && rt
!= 0) {
2435 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2436 } else if (rs
!= 0 && rt
== 0) {
2437 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2439 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2444 if (likely(rs
!= 0 && rt
!= 0)) {
2445 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2446 } else if (rs
== 0 && rt
!= 0) {
2447 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2448 } else if (rs
!= 0 && rt
== 0) {
2449 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2451 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2456 if (likely(rs
!= 0 && rt
!= 0)) {
2457 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2458 } else if (rs
== 0 && rt
!= 0) {
2459 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2460 } else if (rs
!= 0 && rt
== 0) {
2461 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2463 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2468 (void)opn
; /* avoid a compiler warning */
2469 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2472 /* Set on lower than */
2473 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2474 int rd
, int rs
, int rt
)
2476 const char *opn
= "slt";
2480 /* If no destination, treat it as a NOP. */
2485 t0
= tcg_temp_new();
2486 t1
= tcg_temp_new();
2487 gen_load_gpr(t0
, rs
);
2488 gen_load_gpr(t1
, rt
);
2491 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2495 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2499 (void)opn
; /* avoid a compiler warning */
2500 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2506 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2507 int rd
, int rs
, int rt
)
2509 const char *opn
= "shifts";
2513 /* If no destination, treat it as a NOP.
2514 For add & sub, we must generate the overflow exception when needed. */
2519 t0
= tcg_temp_new();
2520 t1
= tcg_temp_new();
2521 gen_load_gpr(t0
, rs
);
2522 gen_load_gpr(t1
, rt
);
2525 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2526 tcg_gen_shl_tl(t0
, t1
, t0
);
2527 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2531 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2532 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2536 tcg_gen_ext32u_tl(t1
, t1
);
2537 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2538 tcg_gen_shr_tl(t0
, t1
, t0
);
2539 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2544 TCGv_i32 t2
= tcg_temp_new_i32();
2545 TCGv_i32 t3
= tcg_temp_new_i32();
2547 tcg_gen_trunc_tl_i32(t2
, t0
);
2548 tcg_gen_trunc_tl_i32(t3
, t1
);
2549 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2550 tcg_gen_rotr_i32(t2
, t3
, t2
);
2551 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2552 tcg_temp_free_i32(t2
);
2553 tcg_temp_free_i32(t3
);
2557 #if defined(TARGET_MIPS64)
2559 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2560 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2564 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2565 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2569 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2570 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2574 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2575 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2580 (void)opn
; /* avoid a compiler warning */
2581 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2586 /* Arithmetic on HI/LO registers */
2587 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2589 const char *opn
= "hilo";
2591 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2603 #if defined(TARGET_MIPS64)
2605 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2609 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2614 #if defined(TARGET_MIPS64)
2616 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2620 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2626 #if defined(TARGET_MIPS64)
2628 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2632 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2635 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2641 #if defined(TARGET_MIPS64)
2643 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2647 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2650 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2655 (void)opn
; /* avoid a compiler warning */
2656 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2659 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
2660 int acc
, int rs
, int rt
)
2662 const char *opn
= "mul/div";
2665 t0
= tcg_temp_new();
2666 t1
= tcg_temp_new();
2668 gen_load_gpr(t0
, rs
);
2669 gen_load_gpr(t1
, rt
);
2678 TCGv t2
= tcg_temp_new();
2679 TCGv t3
= tcg_temp_new();
2680 tcg_gen_ext32s_tl(t0
, t0
);
2681 tcg_gen_ext32s_tl(t1
, t1
);
2682 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2683 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2684 tcg_gen_and_tl(t2
, t2
, t3
);
2685 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2686 tcg_gen_or_tl(t2
, t2
, t3
);
2687 tcg_gen_movi_tl(t3
, 0);
2688 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2689 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2690 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2691 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2692 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2700 TCGv t2
= tcg_const_tl(0);
2701 TCGv t3
= tcg_const_tl(1);
2702 tcg_gen_ext32u_tl(t0
, t0
);
2703 tcg_gen_ext32u_tl(t1
, t1
);
2704 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2705 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
2706 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
2707 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2708 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2716 TCGv_i32 t2
= tcg_temp_new_i32();
2717 TCGv_i32 t3
= tcg_temp_new_i32();
2718 tcg_gen_trunc_tl_i32(t2
, t0
);
2719 tcg_gen_trunc_tl_i32(t3
, t1
);
2720 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
2721 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2722 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2723 tcg_temp_free_i32(t2
);
2724 tcg_temp_free_i32(t3
);
2730 TCGv_i32 t2
= tcg_temp_new_i32();
2731 TCGv_i32 t3
= tcg_temp_new_i32();
2732 tcg_gen_trunc_tl_i32(t2
, t0
);
2733 tcg_gen_trunc_tl_i32(t3
, t1
);
2734 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
2735 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2736 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2737 tcg_temp_free_i32(t2
);
2738 tcg_temp_free_i32(t3
);
2742 #if defined(TARGET_MIPS64)
2745 TCGv t2
= tcg_temp_new();
2746 TCGv t3
= tcg_temp_new();
2747 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2748 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2749 tcg_gen_and_tl(t2
, t2
, t3
);
2750 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2751 tcg_gen_or_tl(t2
, t2
, t3
);
2752 tcg_gen_movi_tl(t3
, 0);
2753 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2754 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2755 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2763 TCGv t2
= tcg_const_tl(0);
2764 TCGv t3
= tcg_const_tl(1);
2765 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2766 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
2767 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
2774 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2778 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2784 TCGv_i64 t2
= tcg_temp_new_i64();
2785 TCGv_i64 t3
= tcg_temp_new_i64();
2787 tcg_gen_ext_tl_i64(t2
, t0
);
2788 tcg_gen_ext_tl_i64(t3
, t1
);
2789 tcg_gen_mul_i64(t2
, t2
, t3
);
2790 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2791 tcg_gen_add_i64(t2
, t2
, t3
);
2792 tcg_temp_free_i64(t3
);
2793 tcg_gen_trunc_i64_tl(t0
, t2
);
2794 tcg_gen_shri_i64(t2
, t2
, 32);
2795 tcg_gen_trunc_i64_tl(t1
, t2
);
2796 tcg_temp_free_i64(t2
);
2797 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2798 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2804 TCGv_i64 t2
= tcg_temp_new_i64();
2805 TCGv_i64 t3
= tcg_temp_new_i64();
2807 tcg_gen_ext32u_tl(t0
, t0
);
2808 tcg_gen_ext32u_tl(t1
, t1
);
2809 tcg_gen_extu_tl_i64(t2
, t0
);
2810 tcg_gen_extu_tl_i64(t3
, t1
);
2811 tcg_gen_mul_i64(t2
, t2
, t3
);
2812 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2813 tcg_gen_add_i64(t2
, t2
, t3
);
2814 tcg_temp_free_i64(t3
);
2815 tcg_gen_trunc_i64_tl(t0
, t2
);
2816 tcg_gen_shri_i64(t2
, t2
, 32);
2817 tcg_gen_trunc_i64_tl(t1
, t2
);
2818 tcg_temp_free_i64(t2
);
2819 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2820 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2826 TCGv_i64 t2
= tcg_temp_new_i64();
2827 TCGv_i64 t3
= tcg_temp_new_i64();
2829 tcg_gen_ext_tl_i64(t2
, t0
);
2830 tcg_gen_ext_tl_i64(t3
, t1
);
2831 tcg_gen_mul_i64(t2
, t2
, t3
);
2832 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2833 tcg_gen_sub_i64(t2
, t3
, t2
);
2834 tcg_temp_free_i64(t3
);
2835 tcg_gen_trunc_i64_tl(t0
, t2
);
2836 tcg_gen_shri_i64(t2
, t2
, 32);
2837 tcg_gen_trunc_i64_tl(t1
, t2
);
2838 tcg_temp_free_i64(t2
);
2839 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2840 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2846 TCGv_i64 t2
= tcg_temp_new_i64();
2847 TCGv_i64 t3
= tcg_temp_new_i64();
2849 tcg_gen_ext32u_tl(t0
, t0
);
2850 tcg_gen_ext32u_tl(t1
, t1
);
2851 tcg_gen_extu_tl_i64(t2
, t0
);
2852 tcg_gen_extu_tl_i64(t3
, t1
);
2853 tcg_gen_mul_i64(t2
, t2
, t3
);
2854 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2855 tcg_gen_sub_i64(t2
, t3
, t2
);
2856 tcg_temp_free_i64(t3
);
2857 tcg_gen_trunc_i64_tl(t0
, t2
);
2858 tcg_gen_shri_i64(t2
, t2
, 32);
2859 tcg_gen_trunc_i64_tl(t1
, t2
);
2860 tcg_temp_free_i64(t2
);
2861 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2862 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2868 generate_exception(ctx
, EXCP_RI
);
2871 (void)opn
; /* avoid a compiler warning */
2872 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2878 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2879 int rd
, int rs
, int rt
)
2881 const char *opn
= "mul vr54xx";
2882 TCGv t0
= tcg_temp_new();
2883 TCGv t1
= tcg_temp_new();
2885 gen_load_gpr(t0
, rs
);
2886 gen_load_gpr(t1
, rt
);
2889 case OPC_VR54XX_MULS
:
2890 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2893 case OPC_VR54XX_MULSU
:
2894 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2897 case OPC_VR54XX_MACC
:
2898 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2901 case OPC_VR54XX_MACCU
:
2902 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2905 case OPC_VR54XX_MSAC
:
2906 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2909 case OPC_VR54XX_MSACU
:
2910 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2913 case OPC_VR54XX_MULHI
:
2914 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2917 case OPC_VR54XX_MULHIU
:
2918 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2921 case OPC_VR54XX_MULSHI
:
2922 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2925 case OPC_VR54XX_MULSHIU
:
2926 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2929 case OPC_VR54XX_MACCHI
:
2930 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2933 case OPC_VR54XX_MACCHIU
:
2934 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2937 case OPC_VR54XX_MSACHI
:
2938 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2941 case OPC_VR54XX_MSACHIU
:
2942 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2946 MIPS_INVAL("mul vr54xx");
2947 generate_exception(ctx
, EXCP_RI
);
2950 gen_store_gpr(t0
, rd
);
2951 (void)opn
; /* avoid a compiler warning */
2952 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2959 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2962 const char *opn
= "CLx";
2970 t0
= tcg_temp_new();
2971 gen_load_gpr(t0
, rs
);
2974 gen_helper_clo(cpu_gpr
[rd
], t0
);
2978 gen_helper_clz(cpu_gpr
[rd
], t0
);
2981 #if defined(TARGET_MIPS64)
2983 gen_helper_dclo(cpu_gpr
[rd
], t0
);
2987 gen_helper_dclz(cpu_gpr
[rd
], t0
);
2992 (void)opn
; /* avoid a compiler warning */
2993 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
2997 /* Godson integer instructions */
2998 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
2999 int rd
, int rs
, int rt
)
3001 const char *opn
= "loongson";
3013 case OPC_MULTU_G_2E
:
3014 case OPC_MULTU_G_2F
:
3015 #if defined(TARGET_MIPS64)
3016 case OPC_DMULT_G_2E
:
3017 case OPC_DMULT_G_2F
:
3018 case OPC_DMULTU_G_2E
:
3019 case OPC_DMULTU_G_2F
:
3021 t0
= tcg_temp_new();
3022 t1
= tcg_temp_new();
3025 t0
= tcg_temp_local_new();
3026 t1
= tcg_temp_local_new();
3030 gen_load_gpr(t0
, rs
);
3031 gen_load_gpr(t1
, rt
);
3036 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3037 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3040 case OPC_MULTU_G_2E
:
3041 case OPC_MULTU_G_2F
:
3042 tcg_gen_ext32u_tl(t0
, t0
);
3043 tcg_gen_ext32u_tl(t1
, t1
);
3044 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3045 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3051 int l1
= gen_new_label();
3052 int l2
= gen_new_label();
3053 int l3
= gen_new_label();
3054 tcg_gen_ext32s_tl(t0
, t0
);
3055 tcg_gen_ext32s_tl(t1
, t1
);
3056 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3057 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3060 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3061 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3062 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3065 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3066 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3074 int l1
= gen_new_label();
3075 int l2
= gen_new_label();
3076 tcg_gen_ext32u_tl(t0
, t0
);
3077 tcg_gen_ext32u_tl(t1
, t1
);
3078 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3079 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3082 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3083 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3091 int l1
= gen_new_label();
3092 int l2
= gen_new_label();
3093 int l3
= gen_new_label();
3094 tcg_gen_ext32u_tl(t0
, t0
);
3095 tcg_gen_ext32u_tl(t1
, t1
);
3096 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3097 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3098 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3100 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3103 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3104 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3112 int l1
= gen_new_label();
3113 int l2
= gen_new_label();
3114 tcg_gen_ext32u_tl(t0
, t0
);
3115 tcg_gen_ext32u_tl(t1
, t1
);
3116 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3117 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3120 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3121 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3126 #if defined(TARGET_MIPS64)
3127 case OPC_DMULT_G_2E
:
3128 case OPC_DMULT_G_2F
:
3129 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3132 case OPC_DMULTU_G_2E
:
3133 case OPC_DMULTU_G_2F
:
3134 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3140 int l1
= gen_new_label();
3141 int l2
= gen_new_label();
3142 int l3
= gen_new_label();
3143 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3144 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3147 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3148 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3149 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3152 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3157 case OPC_DDIVU_G_2E
:
3158 case OPC_DDIVU_G_2F
:
3160 int l1
= gen_new_label();
3161 int l2
= gen_new_label();
3162 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3163 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3166 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3174 int l1
= gen_new_label();
3175 int l2
= gen_new_label();
3176 int l3
= gen_new_label();
3177 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3178 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3179 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3181 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3184 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3189 case OPC_DMODU_G_2E
:
3190 case OPC_DMODU_G_2F
:
3192 int l1
= gen_new_label();
3193 int l2
= gen_new_label();
3194 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3195 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3198 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3206 (void)opn
; /* avoid a compiler warning */
3207 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3212 /* Loongson multimedia instructions */
3213 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3215 const char *opn
= "loongson_cp2";
3216 uint32_t opc
, shift_max
;
3219 opc
= MASK_LMI(ctx
->opcode
);
3225 t0
= tcg_temp_local_new_i64();
3226 t1
= tcg_temp_local_new_i64();
3229 t0
= tcg_temp_new_i64();
3230 t1
= tcg_temp_new_i64();
3234 gen_load_fpr64(ctx
, t0
, rs
);
3235 gen_load_fpr64(ctx
, t1
, rt
);
3237 #define LMI_HELPER(UP, LO) \
3238 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3239 #define LMI_HELPER_1(UP, LO) \
3240 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3241 #define LMI_DIRECT(UP, LO, OP) \
3242 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3245 LMI_HELPER(PADDSH
, paddsh
);
3246 LMI_HELPER(PADDUSH
, paddush
);
3247 LMI_HELPER(PADDH
, paddh
);
3248 LMI_HELPER(PADDW
, paddw
);
3249 LMI_HELPER(PADDSB
, paddsb
);
3250 LMI_HELPER(PADDUSB
, paddusb
);
3251 LMI_HELPER(PADDB
, paddb
);
3253 LMI_HELPER(PSUBSH
, psubsh
);
3254 LMI_HELPER(PSUBUSH
, psubush
);
3255 LMI_HELPER(PSUBH
, psubh
);
3256 LMI_HELPER(PSUBW
, psubw
);
3257 LMI_HELPER(PSUBSB
, psubsb
);
3258 LMI_HELPER(PSUBUSB
, psubusb
);
3259 LMI_HELPER(PSUBB
, psubb
);
3261 LMI_HELPER(PSHUFH
, pshufh
);
3262 LMI_HELPER(PACKSSWH
, packsswh
);
3263 LMI_HELPER(PACKSSHB
, packsshb
);
3264 LMI_HELPER(PACKUSHB
, packushb
);
3266 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3267 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3268 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3269 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3270 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3271 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3273 LMI_HELPER(PAVGH
, pavgh
);
3274 LMI_HELPER(PAVGB
, pavgb
);
3275 LMI_HELPER(PMAXSH
, pmaxsh
);
3276 LMI_HELPER(PMINSH
, pminsh
);
3277 LMI_HELPER(PMAXUB
, pmaxub
);
3278 LMI_HELPER(PMINUB
, pminub
);
3280 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3281 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3282 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3283 LMI_HELPER(PCMPGTH
, pcmpgth
);
3284 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3285 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3287 LMI_HELPER(PSLLW
, psllw
);
3288 LMI_HELPER(PSLLH
, psllh
);
3289 LMI_HELPER(PSRLW
, psrlw
);
3290 LMI_HELPER(PSRLH
, psrlh
);
3291 LMI_HELPER(PSRAW
, psraw
);
3292 LMI_HELPER(PSRAH
, psrah
);
3294 LMI_HELPER(PMULLH
, pmullh
);
3295 LMI_HELPER(PMULHH
, pmulhh
);
3296 LMI_HELPER(PMULHUH
, pmulhuh
);
3297 LMI_HELPER(PMADDHW
, pmaddhw
);
3299 LMI_HELPER(PASUBUB
, pasubub
);
3300 LMI_HELPER_1(BIADD
, biadd
);
3301 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3303 LMI_DIRECT(PADDD
, paddd
, add
);
3304 LMI_DIRECT(PSUBD
, psubd
, sub
);
3305 LMI_DIRECT(XOR_CP2
, xor, xor);
3306 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3307 LMI_DIRECT(AND_CP2
, and, and);
3308 LMI_DIRECT(PANDN
, pandn
, andc
);
3309 LMI_DIRECT(OR
, or, or);
3312 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3316 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3320 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3324 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3329 tcg_gen_andi_i64(t1
, t1
, 3);
3330 tcg_gen_shli_i64(t1
, t1
, 4);
3331 tcg_gen_shr_i64(t0
, t0
, t1
);
3332 tcg_gen_ext16u_i64(t0
, t0
);
3337 tcg_gen_add_i64(t0
, t0
, t1
);
3338 tcg_gen_ext32s_i64(t0
, t0
);
3342 tcg_gen_sub_i64(t0
, t0
, t1
);
3343 tcg_gen_ext32s_i64(t0
, t0
);
3372 /* Make sure shift count isn't TCG undefined behaviour. */
3373 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3378 tcg_gen_shl_i64(t0
, t0
, t1
);
3382 /* Since SRA is UndefinedResult without sign-extended inputs,
3383 we can treat SRA and DSRA the same. */
3384 tcg_gen_sar_i64(t0
, t0
, t1
);
3387 /* We want to shift in zeros for SRL; zero-extend first. */
3388 tcg_gen_ext32u_i64(t0
, t0
);
3391 tcg_gen_shr_i64(t0
, t0
, t1
);
3395 if (shift_max
== 32) {
3396 tcg_gen_ext32s_i64(t0
, t0
);
3399 /* Shifts larger than MAX produce zero. */
3400 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3401 tcg_gen_neg_i64(t1
, t1
);
3402 tcg_gen_and_i64(t0
, t0
, t1
);
3408 TCGv_i64 t2
= tcg_temp_new_i64();
3409 int lab
= gen_new_label();
3411 tcg_gen_mov_i64(t2
, t0
);
3412 tcg_gen_add_i64(t0
, t1
, t2
);
3413 if (opc
== OPC_ADD_CP2
) {
3414 tcg_gen_ext32s_i64(t0
, t0
);
3416 tcg_gen_xor_i64(t1
, t1
, t2
);
3417 tcg_gen_xor_i64(t2
, t2
, t0
);
3418 tcg_gen_andc_i64(t1
, t2
, t1
);
3419 tcg_temp_free_i64(t2
);
3420 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3421 generate_exception(ctx
, EXCP_OVERFLOW
);
3424 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3431 TCGv_i64 t2
= tcg_temp_new_i64();
3432 int lab
= gen_new_label();
3434 tcg_gen_mov_i64(t2
, t0
);
3435 tcg_gen_sub_i64(t0
, t1
, t2
);
3436 if (opc
== OPC_SUB_CP2
) {
3437 tcg_gen_ext32s_i64(t0
, t0
);
3439 tcg_gen_xor_i64(t1
, t1
, t2
);
3440 tcg_gen_xor_i64(t2
, t2
, t0
);
3441 tcg_gen_and_i64(t1
, t1
, t2
);
3442 tcg_temp_free_i64(t2
);
3443 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3444 generate_exception(ctx
, EXCP_OVERFLOW
);
3447 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3452 tcg_gen_ext32u_i64(t0
, t0
);
3453 tcg_gen_ext32u_i64(t1
, t1
);
3454 tcg_gen_mul_i64(t0
, t0
, t1
);
3464 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3465 FD field is the CC field? */
3468 generate_exception(ctx
, EXCP_RI
);
3475 gen_store_fpr64(ctx
, t0
, rd
);
3477 (void)opn
; /* avoid a compiler warning */
3478 MIPS_DEBUG("%s %s, %s, %s", opn
,
3479 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3480 tcg_temp_free_i64(t0
);
3481 tcg_temp_free_i64(t1
);
3485 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3486 int rs
, int rt
, int16_t imm
)
3489 TCGv t0
= tcg_temp_new();
3490 TCGv t1
= tcg_temp_new();
3493 /* Load needed operands */
3501 /* Compare two registers */
3503 gen_load_gpr(t0
, rs
);
3504 gen_load_gpr(t1
, rt
);
3514 /* Compare register to immediate */
3515 if (rs
!= 0 || imm
!= 0) {
3516 gen_load_gpr(t0
, rs
);
3517 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3524 case OPC_TEQ
: /* rs == rs */
3525 case OPC_TEQI
: /* r0 == 0 */
3526 case OPC_TGE
: /* rs >= rs */
3527 case OPC_TGEI
: /* r0 >= 0 */
3528 case OPC_TGEU
: /* rs >= rs unsigned */
3529 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3531 generate_exception(ctx
, EXCP_TRAP
);
3533 case OPC_TLT
: /* rs < rs */
3534 case OPC_TLTI
: /* r0 < 0 */
3535 case OPC_TLTU
: /* rs < rs unsigned */
3536 case OPC_TLTIU
: /* r0 < 0 unsigned */
3537 case OPC_TNE
: /* rs != rs */
3538 case OPC_TNEI
: /* r0 != 0 */
3539 /* Never trap: treat as NOP. */
3543 int l1
= gen_new_label();
3548 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3552 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3556 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3560 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3564 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3568 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3571 generate_exception(ctx
, EXCP_TRAP
);
3578 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3580 TranslationBlock
*tb
;
3582 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3583 likely(!ctx
->singlestep_enabled
)) {
3586 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3589 if (ctx
->singlestep_enabled
) {
3590 save_cpu_state(ctx
, 0);
3591 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3597 /* Branches (before delay slot) */
3598 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3600 int rs
, int rt
, int32_t offset
)
3602 target_ulong btgt
= -1;
3604 int bcond_compute
= 0;
3605 TCGv t0
= tcg_temp_new();
3606 TCGv t1
= tcg_temp_new();
3608 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3609 #ifdef MIPS_DEBUG_DISAS
3610 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3612 generate_exception(ctx
, EXCP_RI
);
3616 /* Load needed operands */
3622 /* Compare two registers */
3624 gen_load_gpr(t0
, rs
);
3625 gen_load_gpr(t1
, rt
);
3628 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3644 /* Compare to zero */
3646 gen_load_gpr(t0
, rs
);
3649 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3652 #if defined(TARGET_MIPS64)
3654 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3656 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3659 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3666 /* Jump to immediate */
3667 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3673 /* Jump to register */
3674 if (offset
!= 0 && offset
!= 16) {
3675 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3676 others are reserved. */
3677 MIPS_INVAL("jump hint");
3678 generate_exception(ctx
, EXCP_RI
);
3681 gen_load_gpr(btarget
, rs
);
3684 MIPS_INVAL("branch/jump");
3685 generate_exception(ctx
, EXCP_RI
);
3688 if (bcond_compute
== 0) {
3689 /* No condition to be computed */
3691 case OPC_BEQ
: /* rx == rx */
3692 case OPC_BEQL
: /* rx == rx likely */
3693 case OPC_BGEZ
: /* 0 >= 0 */
3694 case OPC_BGEZL
: /* 0 >= 0 likely */
3695 case OPC_BLEZ
: /* 0 <= 0 */
3696 case OPC_BLEZL
: /* 0 <= 0 likely */
3698 ctx
->hflags
|= MIPS_HFLAG_B
;
3699 MIPS_DEBUG("balways");
3702 case OPC_BGEZAL
: /* 0 >= 0 */
3703 case OPC_BGEZALL
: /* 0 >= 0 likely */
3704 ctx
->hflags
|= (opc
== OPC_BGEZALS
3706 : MIPS_HFLAG_BDS32
);
3707 /* Always take and link */
3709 ctx
->hflags
|= MIPS_HFLAG_B
;
3710 MIPS_DEBUG("balways and link");
3712 case OPC_BNE
: /* rx != rx */
3713 case OPC_BGTZ
: /* 0 > 0 */
3714 case OPC_BLTZ
: /* 0 < 0 */
3716 MIPS_DEBUG("bnever (NOP)");
3719 case OPC_BLTZAL
: /* 0 < 0 */
3720 ctx
->hflags
|= (opc
== OPC_BLTZALS
3722 : MIPS_HFLAG_BDS32
);
3723 /* Handle as an unconditional branch to get correct delay
3726 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3727 ctx
->hflags
|= MIPS_HFLAG_B
;
3728 MIPS_DEBUG("bnever and link");
3730 case OPC_BLTZALL
: /* 0 < 0 likely */
3731 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3732 /* Skip the instruction in the delay slot */
3733 MIPS_DEBUG("bnever, link and skip");
3736 case OPC_BNEL
: /* rx != rx likely */
3737 case OPC_BGTZL
: /* 0 > 0 likely */
3738 case OPC_BLTZL
: /* 0 < 0 likely */
3739 /* Skip the instruction in the delay slot */
3740 MIPS_DEBUG("bnever and skip");
3744 ctx
->hflags
|= MIPS_HFLAG_B
;
3745 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3749 ctx
->hflags
|= MIPS_HFLAG_BX
;
3754 ctx
->hflags
|= MIPS_HFLAG_B
;
3755 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3757 : MIPS_HFLAG_BDS32
);
3758 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3761 ctx
->hflags
|= MIPS_HFLAG_BR
;
3762 if (insn_bytes
== 4)
3763 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3764 MIPS_DEBUG("jr %s", regnames
[rs
]);
3770 ctx
->hflags
|= MIPS_HFLAG_BR
;
3771 ctx
->hflags
|= (opc
== OPC_JALRS
3773 : MIPS_HFLAG_BDS32
);
3774 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3777 MIPS_INVAL("branch/jump");
3778 generate_exception(ctx
, EXCP_RI
);
3784 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3785 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3786 regnames
[rs
], regnames
[rt
], btgt
);
3789 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3790 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3791 regnames
[rs
], regnames
[rt
], btgt
);
3794 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3795 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3796 regnames
[rs
], regnames
[rt
], btgt
);
3799 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3800 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3801 regnames
[rs
], regnames
[rt
], btgt
);
3804 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3805 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3808 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3809 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3813 ctx
->hflags
|= (opc
== OPC_BGEZALS
3815 : MIPS_HFLAG_BDS32
);
3816 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3817 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3821 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3823 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3826 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3827 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3830 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3831 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3834 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3835 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3838 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3839 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3842 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3843 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3846 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3847 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3850 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3851 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3853 #if defined(TARGET_MIPS64)
3855 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3856 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3861 ctx
->hflags
|= (opc
== OPC_BLTZALS
3863 : MIPS_HFLAG_BDS32
);
3864 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3866 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3868 ctx
->hflags
|= MIPS_HFLAG_BC
;
3871 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3873 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3875 ctx
->hflags
|= MIPS_HFLAG_BL
;
3878 MIPS_INVAL("conditional branch/jump");
3879 generate_exception(ctx
, EXCP_RI
);
3883 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3884 blink
, ctx
->hflags
, btgt
);
3886 ctx
->btarget
= btgt
;
3888 int post_delay
= insn_bytes
;
3889 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3891 if (opc
!= OPC_JALRC
)
3892 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3894 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3898 if (insn_bytes
== 2)
3899 ctx
->hflags
|= MIPS_HFLAG_B16
;
3904 /* special3 bitfield operations */
3905 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3906 int rs
, int lsb
, int msb
)
3908 TCGv t0
= tcg_temp_new();
3909 TCGv t1
= tcg_temp_new();
3911 gen_load_gpr(t1
, rs
);
3916 tcg_gen_shri_tl(t0
, t1
, lsb
);
3918 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3920 tcg_gen_ext32s_tl(t0
, t0
);
3923 #if defined(TARGET_MIPS64)
3925 tcg_gen_shri_tl(t0
, t1
, lsb
);
3927 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3931 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3932 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3935 tcg_gen_shri_tl(t0
, t1
, lsb
);
3936 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3942 gen_load_gpr(t0
, rt
);
3943 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3944 tcg_gen_ext32s_tl(t0
, t0
);
3946 #if defined(TARGET_MIPS64)
3948 gen_load_gpr(t0
, rt
);
3949 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3952 gen_load_gpr(t0
, rt
);
3953 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3956 gen_load_gpr(t0
, rt
);
3957 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3962 MIPS_INVAL("bitops");
3963 generate_exception(ctx
, EXCP_RI
);
3968 gen_store_gpr(t0
, rt
);
3973 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
3978 /* If no destination, treat it as a NOP. */
3983 t0
= tcg_temp_new();
3984 gen_load_gpr(t0
, rt
);
3988 TCGv t1
= tcg_temp_new();
3990 tcg_gen_shri_tl(t1
, t0
, 8);
3991 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
3992 tcg_gen_shli_tl(t0
, t0
, 8);
3993 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
3994 tcg_gen_or_tl(t0
, t0
, t1
);
3996 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4000 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4003 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4005 #if defined(TARGET_MIPS64)
4008 TCGv t1
= tcg_temp_new();
4010 tcg_gen_shri_tl(t1
, t0
, 8);
4011 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4012 tcg_gen_shli_tl(t0
, t0
, 8);
4013 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4014 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4020 TCGv t1
= tcg_temp_new();
4022 tcg_gen_shri_tl(t1
, t0
, 16);
4023 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4024 tcg_gen_shli_tl(t0
, t0
, 16);
4025 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4026 tcg_gen_or_tl(t0
, t0
, t1
);
4027 tcg_gen_shri_tl(t1
, t0
, 32);
4028 tcg_gen_shli_tl(t0
, t0
, 32);
4029 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4035 MIPS_INVAL("bsfhl");
4036 generate_exception(ctx
, EXCP_RI
);
4043 #ifndef CONFIG_USER_ONLY
4044 /* CP0 (MMU and control) */
4045 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4047 TCGv_i32 t0
= tcg_temp_new_i32();
4049 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4050 tcg_gen_ext_i32_tl(arg
, t0
);
4051 tcg_temp_free_i32(t0
);
4054 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4056 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4057 tcg_gen_ext32s_tl(arg
, arg
);
4060 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4062 TCGv_i32 t0
= tcg_temp_new_i32();
4064 tcg_gen_trunc_tl_i32(t0
, arg
);
4065 tcg_gen_st_i32(t0
, cpu_env
, off
);
4066 tcg_temp_free_i32(t0
);
4069 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4071 tcg_gen_ext32s_tl(arg
, arg
);
4072 tcg_gen_st_tl(arg
, cpu_env
, off
);
4075 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4077 const char *rn
= "invalid";
4080 check_insn(ctx
, ISA_MIPS32
);
4086 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4090 check_insn(ctx
, ASE_MT
);
4091 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4095 check_insn(ctx
, ASE_MT
);
4096 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4100 check_insn(ctx
, ASE_MT
);
4101 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4111 gen_helper_mfc0_random(arg
, cpu_env
);
4115 check_insn(ctx
, ASE_MT
);
4116 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4120 check_insn(ctx
, ASE_MT
);
4121 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4125 check_insn(ctx
, ASE_MT
);
4126 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4130 check_insn(ctx
, ASE_MT
);
4131 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4135 check_insn(ctx
, ASE_MT
);
4136 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4140 check_insn(ctx
, ASE_MT
);
4141 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4142 rn
= "VPEScheFBack";
4145 check_insn(ctx
, ASE_MT
);
4146 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4156 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4157 tcg_gen_ext32s_tl(arg
, arg
);
4161 check_insn(ctx
, ASE_MT
);
4162 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4166 check_insn(ctx
, ASE_MT
);
4167 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4171 check_insn(ctx
, ASE_MT
);
4172 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4176 check_insn(ctx
, ASE_MT
);
4177 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4181 check_insn(ctx
, ASE_MT
);
4182 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4186 check_insn(ctx
, ASE_MT
);
4187 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4191 check_insn(ctx
, ASE_MT
);
4192 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4202 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4203 tcg_gen_ext32s_tl(arg
, arg
);
4213 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4214 tcg_gen_ext32s_tl(arg
, arg
);
4218 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4219 rn
= "ContextConfig";
4224 tcg_gen_ld32s_tl(arg
, cpu_env
,
4225 offsetof(CPUMIPSState
,
4226 active_tc
.CP0_UserLocal
));
4229 tcg_gen_movi_tl(arg
, 0);
4239 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4243 check_insn(ctx
, ISA_MIPS32R2
);
4244 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4254 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4258 check_insn(ctx
, ISA_MIPS32R2
);
4259 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4263 check_insn(ctx
, ISA_MIPS32R2
);
4264 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4268 check_insn(ctx
, ISA_MIPS32R2
);
4269 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4273 check_insn(ctx
, ISA_MIPS32R2
);
4274 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4278 check_insn(ctx
, ISA_MIPS32R2
);
4279 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4289 check_insn(ctx
, ISA_MIPS32R2
);
4290 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4300 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4301 tcg_gen_ext32s_tl(arg
, arg
);
4311 /* Mark as an IO operation because we read the time. */
4314 gen_helper_mfc0_count(arg
, cpu_env
);
4318 /* Break the TB to be able to take timer interrupts immediately
4319 after reading count. */
4320 ctx
->bstate
= BS_STOP
;
4323 /* 6,7 are implementation dependent */
4331 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4332 tcg_gen_ext32s_tl(arg
, arg
);
4342 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4345 /* 6,7 are implementation dependent */
4353 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4357 check_insn(ctx
, ISA_MIPS32R2
);
4358 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4362 check_insn(ctx
, ISA_MIPS32R2
);
4363 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4367 check_insn(ctx
, ISA_MIPS32R2
);
4368 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4378 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4388 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4389 tcg_gen_ext32s_tl(arg
, arg
);
4399 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4403 check_insn(ctx
, ISA_MIPS32R2
);
4404 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4414 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4418 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4422 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4426 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
4434 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
4437 /* 6,7 are implementation dependent */
4439 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4443 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4453 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4463 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4473 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4483 #if defined(TARGET_MIPS64)
4484 check_insn(ctx
, ISA_MIPS3
);
4485 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4486 tcg_gen_ext32s_tl(arg
, arg
);
4495 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4498 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4506 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4507 rn
= "'Diagnostic"; /* implementation dependent */
4512 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4516 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4517 rn
= "TraceControl";
4520 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4521 rn
= "TraceControl2";
4524 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4525 rn
= "UserTraceData";
4528 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4539 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4540 tcg_gen_ext32s_tl(arg
, arg
);
4550 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4551 rn
= "Performance0";
4554 // gen_helper_mfc0_performance1(arg);
4555 rn
= "Performance1";
4558 // gen_helper_mfc0_performance2(arg);
4559 rn
= "Performance2";
4562 // gen_helper_mfc0_performance3(arg);
4563 rn
= "Performance3";
4566 // gen_helper_mfc0_performance4(arg);
4567 rn
= "Performance4";
4570 // gen_helper_mfc0_performance5(arg);
4571 rn
= "Performance5";
4574 // gen_helper_mfc0_performance6(arg);
4575 rn
= "Performance6";
4578 // gen_helper_mfc0_performance7(arg);
4579 rn
= "Performance7";
4586 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4592 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4605 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4612 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4625 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4632 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4642 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4643 tcg_gen_ext32s_tl(arg
, arg
);
4654 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4664 (void)rn
; /* avoid a compiler warning */
4665 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4669 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4670 generate_exception(ctx
, EXCP_RI
);
4673 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4675 const char *rn
= "invalid";
4678 check_insn(ctx
, ISA_MIPS32
);
4687 gen_helper_mtc0_index(cpu_env
, arg
);
4691 check_insn(ctx
, ASE_MT
);
4692 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4696 check_insn(ctx
, ASE_MT
);
4701 check_insn(ctx
, ASE_MT
);
4716 check_insn(ctx
, ASE_MT
);
4717 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4721 check_insn(ctx
, ASE_MT
);
4722 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4726 check_insn(ctx
, ASE_MT
);
4727 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4731 check_insn(ctx
, ASE_MT
);
4732 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4736 check_insn(ctx
, ASE_MT
);
4737 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4741 check_insn(ctx
, ASE_MT
);
4742 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4743 rn
= "VPEScheFBack";
4746 check_insn(ctx
, ASE_MT
);
4747 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4757 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4761 check_insn(ctx
, ASE_MT
);
4762 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4766 check_insn(ctx
, ASE_MT
);
4767 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4771 check_insn(ctx
, ASE_MT
);
4772 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4776 check_insn(ctx
, ASE_MT
);
4777 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4781 check_insn(ctx
, ASE_MT
);
4782 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4786 check_insn(ctx
, ASE_MT
);
4787 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4791 check_insn(ctx
, ASE_MT
);
4792 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4802 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4812 gen_helper_mtc0_context(cpu_env
, arg
);
4816 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4817 rn
= "ContextConfig";
4822 tcg_gen_st_tl(arg
, cpu_env
,
4823 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
4834 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4838 check_insn(ctx
, ISA_MIPS32R2
);
4839 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4849 gen_helper_mtc0_wired(cpu_env
, arg
);
4853 check_insn(ctx
, ISA_MIPS32R2
);
4854 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4858 check_insn(ctx
, ISA_MIPS32R2
);
4859 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4863 check_insn(ctx
, ISA_MIPS32R2
);
4864 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4868 check_insn(ctx
, ISA_MIPS32R2
);
4869 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4873 check_insn(ctx
, ISA_MIPS32R2
);
4874 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4884 check_insn(ctx
, ISA_MIPS32R2
);
4885 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4886 ctx
->bstate
= BS_STOP
;
4900 gen_helper_mtc0_count(cpu_env
, arg
);
4903 /* 6,7 are implementation dependent */
4911 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4921 gen_helper_mtc0_compare(cpu_env
, arg
);
4924 /* 6,7 are implementation dependent */
4932 save_cpu_state(ctx
, 1);
4933 gen_helper_mtc0_status(cpu_env
, arg
);
4934 /* BS_STOP isn't good enough here, hflags may have changed. */
4935 gen_save_pc(ctx
->pc
+ 4);
4936 ctx
->bstate
= BS_EXCP
;
4940 check_insn(ctx
, ISA_MIPS32R2
);
4941 gen_helper_mtc0_intctl(cpu_env
, arg
);
4942 /* Stop translation as we may have switched the execution mode */
4943 ctx
->bstate
= BS_STOP
;
4947 check_insn(ctx
, ISA_MIPS32R2
);
4948 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4949 /* Stop translation as we may have switched the execution mode */
4950 ctx
->bstate
= BS_STOP
;
4954 check_insn(ctx
, ISA_MIPS32R2
);
4955 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4956 /* Stop translation as we may have switched the execution mode */
4957 ctx
->bstate
= BS_STOP
;
4967 save_cpu_state(ctx
, 1);
4968 gen_helper_mtc0_cause(cpu_env
, arg
);
4978 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4992 check_insn(ctx
, ISA_MIPS32R2
);
4993 gen_helper_mtc0_ebase(cpu_env
, arg
);
5003 gen_helper_mtc0_config0(cpu_env
, arg
);
5005 /* Stop translation as we may have switched the execution mode */
5006 ctx
->bstate
= BS_STOP
;
5009 /* ignored, read only */
5013 gen_helper_mtc0_config2(cpu_env
, arg
);
5015 /* Stop translation as we may have switched the execution mode */
5016 ctx
->bstate
= BS_STOP
;
5019 /* ignored, read only */
5023 gen_helper_mtc0_config4(cpu_env
, arg
);
5025 ctx
->bstate
= BS_STOP
;
5028 gen_helper_mtc0_config5(cpu_env
, arg
);
5030 /* Stop translation as we may have switched the execution mode */
5031 ctx
->bstate
= BS_STOP
;
5033 /* 6,7 are implementation dependent */
5043 rn
= "Invalid config selector";
5050 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5060 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5070 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5080 #if defined(TARGET_MIPS64)
5081 check_insn(ctx
, ISA_MIPS3
);
5082 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5091 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5094 gen_helper_mtc0_framemask(cpu_env
, arg
);
5103 rn
= "Diagnostic"; /* implementation dependent */
5108 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5109 /* BS_STOP isn't good enough here, hflags may have changed. */
5110 gen_save_pc(ctx
->pc
+ 4);
5111 ctx
->bstate
= BS_EXCP
;
5115 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5116 rn
= "TraceControl";
5117 /* Stop translation as we may have switched the execution mode */
5118 ctx
->bstate
= BS_STOP
;
5121 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5122 rn
= "TraceControl2";
5123 /* Stop translation as we may have switched the execution mode */
5124 ctx
->bstate
= BS_STOP
;
5127 /* Stop translation as we may have switched the execution mode */
5128 ctx
->bstate
= BS_STOP
;
5129 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5130 rn
= "UserTraceData";
5131 /* Stop translation as we may have switched the execution mode */
5132 ctx
->bstate
= BS_STOP
;
5135 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5136 /* Stop translation as we may have switched the execution mode */
5137 ctx
->bstate
= BS_STOP
;
5148 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5158 gen_helper_mtc0_performance0(cpu_env
, arg
);
5159 rn
= "Performance0";
5162 // gen_helper_mtc0_performance1(arg);
5163 rn
= "Performance1";
5166 // gen_helper_mtc0_performance2(arg);
5167 rn
= "Performance2";
5170 // gen_helper_mtc0_performance3(arg);
5171 rn
= "Performance3";
5174 // gen_helper_mtc0_performance4(arg);
5175 rn
= "Performance4";
5178 // gen_helper_mtc0_performance5(arg);
5179 rn
= "Performance5";
5182 // gen_helper_mtc0_performance6(arg);
5183 rn
= "Performance6";
5186 // gen_helper_mtc0_performance7(arg);
5187 rn
= "Performance7";
5213 gen_helper_mtc0_taglo(cpu_env
, arg
);
5220 gen_helper_mtc0_datalo(cpu_env
, arg
);
5233 gen_helper_mtc0_taghi(cpu_env
, arg
);
5240 gen_helper_mtc0_datahi(cpu_env
, arg
);
5251 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5262 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5268 /* Stop translation as we may have switched the execution mode */
5269 ctx
->bstate
= BS_STOP
;
5274 (void)rn
; /* avoid a compiler warning */
5275 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5276 /* For simplicity assume that all writes can cause interrupts. */
5279 ctx
->bstate
= BS_STOP
;
5284 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5285 generate_exception(ctx
, EXCP_RI
);
5288 #if defined(TARGET_MIPS64)
5289 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5291 const char *rn
= "invalid";
5294 check_insn(ctx
, ISA_MIPS64
);
5300 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5304 check_insn(ctx
, ASE_MT
);
5305 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5309 check_insn(ctx
, ASE_MT
);
5310 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5314 check_insn(ctx
, ASE_MT
);
5315 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5325 gen_helper_mfc0_random(arg
, cpu_env
);
5329 check_insn(ctx
, ASE_MT
);
5330 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5334 check_insn(ctx
, ASE_MT
);
5335 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5339 check_insn(ctx
, ASE_MT
);
5340 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5344 check_insn(ctx
, ASE_MT
);
5345 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5349 check_insn(ctx
, ASE_MT
);
5350 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5354 check_insn(ctx
, ASE_MT
);
5355 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5356 rn
= "VPEScheFBack";
5359 check_insn(ctx
, ASE_MT
);
5360 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5370 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5374 check_insn(ctx
, ASE_MT
);
5375 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5379 check_insn(ctx
, ASE_MT
);
5380 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5384 check_insn(ctx
, ASE_MT
);
5385 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5389 check_insn(ctx
, ASE_MT
);
5390 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5394 check_insn(ctx
, ASE_MT
);
5395 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5399 check_insn(ctx
, ASE_MT
);
5400 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5404 check_insn(ctx
, ASE_MT
);
5405 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5415 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5425 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5429 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5430 rn
= "ContextConfig";
5435 tcg_gen_ld_tl(arg
, cpu_env
,
5436 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5439 tcg_gen_movi_tl(arg
, 0);
5449 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5453 check_insn(ctx
, ISA_MIPS32R2
);
5454 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5464 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5468 check_insn(ctx
, ISA_MIPS32R2
);
5469 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5473 check_insn(ctx
, ISA_MIPS32R2
);
5474 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5478 check_insn(ctx
, ISA_MIPS32R2
);
5479 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5483 check_insn(ctx
, ISA_MIPS32R2
);
5484 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5488 check_insn(ctx
, ISA_MIPS32R2
);
5489 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5499 check_insn(ctx
, ISA_MIPS32R2
);
5500 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5510 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5520 /* Mark as an IO operation because we read the time. */
5523 gen_helper_mfc0_count(arg
, cpu_env
);
5527 /* Break the TB to be able to take timer interrupts immediately
5528 after reading count. */
5529 ctx
->bstate
= BS_STOP
;
5532 /* 6,7 are implementation dependent */
5540 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5550 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5553 /* 6,7 are implementation dependent */
5561 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5565 check_insn(ctx
, ISA_MIPS32R2
);
5566 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5570 check_insn(ctx
, ISA_MIPS32R2
);
5571 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5575 check_insn(ctx
, ISA_MIPS32R2
);
5576 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5586 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5596 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5606 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5610 check_insn(ctx
, ISA_MIPS32R2
);
5611 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5621 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5625 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5629 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5633 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5636 /* 6,7 are implementation dependent */
5638 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5642 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5652 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5662 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5672 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5682 check_insn(ctx
, ISA_MIPS3
);
5683 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5691 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5694 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5702 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5703 rn
= "'Diagnostic"; /* implementation dependent */
5708 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5712 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5713 rn
= "TraceControl";
5716 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5717 rn
= "TraceControl2";
5720 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5721 rn
= "UserTraceData";
5724 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5735 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5745 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5746 rn
= "Performance0";
5749 // gen_helper_dmfc0_performance1(arg);
5750 rn
= "Performance1";
5753 // gen_helper_dmfc0_performance2(arg);
5754 rn
= "Performance2";
5757 // gen_helper_dmfc0_performance3(arg);
5758 rn
= "Performance3";
5761 // gen_helper_dmfc0_performance4(arg);
5762 rn
= "Performance4";
5765 // gen_helper_dmfc0_performance5(arg);
5766 rn
= "Performance5";
5769 // gen_helper_dmfc0_performance6(arg);
5770 rn
= "Performance6";
5773 // gen_helper_dmfc0_performance7(arg);
5774 rn
= "Performance7";
5781 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5788 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5801 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5808 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5821 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5828 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5838 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5849 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5859 (void)rn
; /* avoid a compiler warning */
5860 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5864 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5865 generate_exception(ctx
, EXCP_RI
);
5868 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5870 const char *rn
= "invalid";
5873 check_insn(ctx
, ISA_MIPS64
);
5882 gen_helper_mtc0_index(cpu_env
, arg
);
5886 check_insn(ctx
, ASE_MT
);
5887 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5891 check_insn(ctx
, ASE_MT
);
5896 check_insn(ctx
, ASE_MT
);
5911 check_insn(ctx
, ASE_MT
);
5912 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5916 check_insn(ctx
, ASE_MT
);
5917 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5921 check_insn(ctx
, ASE_MT
);
5922 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5926 check_insn(ctx
, ASE_MT
);
5927 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5931 check_insn(ctx
, ASE_MT
);
5932 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5936 check_insn(ctx
, ASE_MT
);
5937 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5938 rn
= "VPEScheFBack";
5941 check_insn(ctx
, ASE_MT
);
5942 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5952 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5956 check_insn(ctx
, ASE_MT
);
5957 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5961 check_insn(ctx
, ASE_MT
);
5962 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5966 check_insn(ctx
, ASE_MT
);
5967 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5971 check_insn(ctx
, ASE_MT
);
5972 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5976 check_insn(ctx
, ASE_MT
);
5977 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5981 check_insn(ctx
, ASE_MT
);
5982 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5986 check_insn(ctx
, ASE_MT
);
5987 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5997 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
6007 gen_helper_mtc0_context(cpu_env
, arg
);
6011 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6012 rn
= "ContextConfig";
6017 tcg_gen_st_tl(arg
, cpu_env
,
6018 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6029 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6033 check_insn(ctx
, ISA_MIPS32R2
);
6034 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6044 gen_helper_mtc0_wired(cpu_env
, arg
);
6048 check_insn(ctx
, ISA_MIPS32R2
);
6049 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6053 check_insn(ctx
, ISA_MIPS32R2
);
6054 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6058 check_insn(ctx
, ISA_MIPS32R2
);
6059 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6063 check_insn(ctx
, ISA_MIPS32R2
);
6064 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6068 check_insn(ctx
, ISA_MIPS32R2
);
6069 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6079 check_insn(ctx
, ISA_MIPS32R2
);
6080 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6081 ctx
->bstate
= BS_STOP
;
6095 gen_helper_mtc0_count(cpu_env
, arg
);
6098 /* 6,7 are implementation dependent */
6102 /* Stop translation as we may have switched the execution mode */
6103 ctx
->bstate
= BS_STOP
;
6108 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6118 gen_helper_mtc0_compare(cpu_env
, arg
);
6121 /* 6,7 are implementation dependent */
6125 /* Stop translation as we may have switched the execution mode */
6126 ctx
->bstate
= BS_STOP
;
6131 save_cpu_state(ctx
, 1);
6132 gen_helper_mtc0_status(cpu_env
, arg
);
6133 /* BS_STOP isn't good enough here, hflags may have changed. */
6134 gen_save_pc(ctx
->pc
+ 4);
6135 ctx
->bstate
= BS_EXCP
;
6139 check_insn(ctx
, ISA_MIPS32R2
);
6140 gen_helper_mtc0_intctl(cpu_env
, arg
);
6141 /* Stop translation as we may have switched the execution mode */
6142 ctx
->bstate
= BS_STOP
;
6146 check_insn(ctx
, ISA_MIPS32R2
);
6147 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6148 /* Stop translation as we may have switched the execution mode */
6149 ctx
->bstate
= BS_STOP
;
6153 check_insn(ctx
, ISA_MIPS32R2
);
6154 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6155 /* Stop translation as we may have switched the execution mode */
6156 ctx
->bstate
= BS_STOP
;
6166 save_cpu_state(ctx
, 1);
6167 /* Mark as an IO operation because we may trigger a software
6172 gen_helper_mtc0_cause(cpu_env
, arg
);
6176 /* Stop translation as we may have triggered an intetrupt */
6177 ctx
->bstate
= BS_STOP
;
6187 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6201 check_insn(ctx
, ISA_MIPS32R2
);
6202 gen_helper_mtc0_ebase(cpu_env
, arg
);
6212 gen_helper_mtc0_config0(cpu_env
, arg
);
6214 /* Stop translation as we may have switched the execution mode */
6215 ctx
->bstate
= BS_STOP
;
6218 /* ignored, read only */
6222 gen_helper_mtc0_config2(cpu_env
, arg
);
6224 /* Stop translation as we may have switched the execution mode */
6225 ctx
->bstate
= BS_STOP
;
6231 /* 6,7 are implementation dependent */
6233 rn
= "Invalid config selector";
6240 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6250 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6260 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6270 check_insn(ctx
, ISA_MIPS3
);
6271 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6279 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6282 gen_helper_mtc0_framemask(cpu_env
, arg
);
6291 rn
= "Diagnostic"; /* implementation dependent */
6296 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6297 /* BS_STOP isn't good enough here, hflags may have changed. */
6298 gen_save_pc(ctx
->pc
+ 4);
6299 ctx
->bstate
= BS_EXCP
;
6303 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6304 /* Stop translation as we may have switched the execution mode */
6305 ctx
->bstate
= BS_STOP
;
6306 rn
= "TraceControl";
6309 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6310 /* Stop translation as we may have switched the execution mode */
6311 ctx
->bstate
= BS_STOP
;
6312 rn
= "TraceControl2";
6315 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6316 /* Stop translation as we may have switched the execution mode */
6317 ctx
->bstate
= BS_STOP
;
6318 rn
= "UserTraceData";
6321 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6322 /* Stop translation as we may have switched the execution mode */
6323 ctx
->bstate
= BS_STOP
;
6334 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6344 gen_helper_mtc0_performance0(cpu_env
, arg
);
6345 rn
= "Performance0";
6348 // gen_helper_mtc0_performance1(cpu_env, arg);
6349 rn
= "Performance1";
6352 // gen_helper_mtc0_performance2(cpu_env, arg);
6353 rn
= "Performance2";
6356 // gen_helper_mtc0_performance3(cpu_env, arg);
6357 rn
= "Performance3";
6360 // gen_helper_mtc0_performance4(cpu_env, arg);
6361 rn
= "Performance4";
6364 // gen_helper_mtc0_performance5(cpu_env, arg);
6365 rn
= "Performance5";
6368 // gen_helper_mtc0_performance6(cpu_env, arg);
6369 rn
= "Performance6";
6372 // gen_helper_mtc0_performance7(cpu_env, arg);
6373 rn
= "Performance7";
6399 gen_helper_mtc0_taglo(cpu_env
, arg
);
6406 gen_helper_mtc0_datalo(cpu_env
, arg
);
6419 gen_helper_mtc0_taghi(cpu_env
, arg
);
6426 gen_helper_mtc0_datahi(cpu_env
, arg
);
6437 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6448 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6454 /* Stop translation as we may have switched the execution mode */
6455 ctx
->bstate
= BS_STOP
;
6460 (void)rn
; /* avoid a compiler warning */
6461 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6462 /* For simplicity assume that all writes can cause interrupts. */
6465 ctx
->bstate
= BS_STOP
;
6470 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6471 generate_exception(ctx
, EXCP_RI
);
6473 #endif /* TARGET_MIPS64 */
6475 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6476 int u
, int sel
, int h
)
6478 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6479 TCGv t0
= tcg_temp_local_new();
6481 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6482 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6483 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6484 tcg_gen_movi_tl(t0
, -1);
6485 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6486 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6487 tcg_gen_movi_tl(t0
, -1);
6493 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6496 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6506 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6509 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6512 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6515 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6518 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6521 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6524 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6527 gen_mfc0(ctx
, t0
, rt
, sel
);
6534 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6537 gen_mfc0(ctx
, t0
, rt
, sel
);
6543 gen_helper_mftc0_status(t0
, cpu_env
);
6546 gen_mfc0(ctx
, t0
, rt
, sel
);
6552 gen_helper_mftc0_cause(t0
, cpu_env
);
6562 gen_helper_mftc0_epc(t0
, cpu_env
);
6572 gen_helper_mftc0_ebase(t0
, cpu_env
);
6582 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6592 gen_helper_mftc0_debug(t0
, cpu_env
);
6595 gen_mfc0(ctx
, t0
, rt
, sel
);
6600 gen_mfc0(ctx
, t0
, rt
, sel
);
6602 } else switch (sel
) {
6603 /* GPR registers. */
6605 gen_helper_1e0i(mftgpr
, t0
, rt
);
6607 /* Auxiliary CPU registers */
6611 gen_helper_1e0i(mftlo
, t0
, 0);
6614 gen_helper_1e0i(mfthi
, t0
, 0);
6617 gen_helper_1e0i(mftacx
, t0
, 0);
6620 gen_helper_1e0i(mftlo
, t0
, 1);
6623 gen_helper_1e0i(mfthi
, t0
, 1);
6626 gen_helper_1e0i(mftacx
, t0
, 1);
6629 gen_helper_1e0i(mftlo
, t0
, 2);
6632 gen_helper_1e0i(mfthi
, t0
, 2);
6635 gen_helper_1e0i(mftacx
, t0
, 2);
6638 gen_helper_1e0i(mftlo
, t0
, 3);
6641 gen_helper_1e0i(mfthi
, t0
, 3);
6644 gen_helper_1e0i(mftacx
, t0
, 3);
6647 gen_helper_mftdsp(t0
, cpu_env
);
6653 /* Floating point (COP1). */
6655 /* XXX: For now we support only a single FPU context. */
6657 TCGv_i32 fp0
= tcg_temp_new_i32();
6659 gen_load_fpr32(fp0
, rt
);
6660 tcg_gen_ext_i32_tl(t0
, fp0
);
6661 tcg_temp_free_i32(fp0
);
6663 TCGv_i32 fp0
= tcg_temp_new_i32();
6665 gen_load_fpr32h(ctx
, fp0
, rt
);
6666 tcg_gen_ext_i32_tl(t0
, fp0
);
6667 tcg_temp_free_i32(fp0
);
6671 /* XXX: For now we support only a single FPU context. */
6672 gen_helper_1e0i(cfc1
, t0
, rt
);
6674 /* COP2: Not implemented. */
6681 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6682 gen_store_gpr(t0
, rd
);
6688 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6689 generate_exception(ctx
, EXCP_RI
);
6692 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6693 int u
, int sel
, int h
)
6695 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6696 TCGv t0
= tcg_temp_local_new();
6698 gen_load_gpr(t0
, rt
);
6699 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6700 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6701 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6703 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6704 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6711 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6714 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6724 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6727 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6730 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6733 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6736 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6739 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6742 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6745 gen_mtc0(ctx
, t0
, rd
, sel
);
6752 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6755 gen_mtc0(ctx
, t0
, rd
, sel
);
6761 gen_helper_mttc0_status(cpu_env
, t0
);
6764 gen_mtc0(ctx
, t0
, rd
, sel
);
6770 gen_helper_mttc0_cause(cpu_env
, t0
);
6780 gen_helper_mttc0_ebase(cpu_env
, t0
);
6790 gen_helper_mttc0_debug(cpu_env
, t0
);
6793 gen_mtc0(ctx
, t0
, rd
, sel
);
6798 gen_mtc0(ctx
, t0
, rd
, sel
);
6800 } else switch (sel
) {
6801 /* GPR registers. */
6803 gen_helper_0e1i(mttgpr
, t0
, rd
);
6805 /* Auxiliary CPU registers */
6809 gen_helper_0e1i(mttlo
, t0
, 0);
6812 gen_helper_0e1i(mtthi
, t0
, 0);
6815 gen_helper_0e1i(mttacx
, t0
, 0);
6818 gen_helper_0e1i(mttlo
, t0
, 1);
6821 gen_helper_0e1i(mtthi
, t0
, 1);
6824 gen_helper_0e1i(mttacx
, t0
, 1);
6827 gen_helper_0e1i(mttlo
, t0
, 2);
6830 gen_helper_0e1i(mtthi
, t0
, 2);
6833 gen_helper_0e1i(mttacx
, t0
, 2);
6836 gen_helper_0e1i(mttlo
, t0
, 3);
6839 gen_helper_0e1i(mtthi
, t0
, 3);
6842 gen_helper_0e1i(mttacx
, t0
, 3);
6845 gen_helper_mttdsp(cpu_env
, t0
);
6851 /* Floating point (COP1). */
6853 /* XXX: For now we support only a single FPU context. */
6855 TCGv_i32 fp0
= tcg_temp_new_i32();
6857 tcg_gen_trunc_tl_i32(fp0
, t0
);
6858 gen_store_fpr32(fp0
, rd
);
6859 tcg_temp_free_i32(fp0
);
6861 TCGv_i32 fp0
= tcg_temp_new_i32();
6863 tcg_gen_trunc_tl_i32(fp0
, t0
);
6864 gen_store_fpr32h(ctx
, fp0
, rd
);
6865 tcg_temp_free_i32(fp0
);
6869 /* XXX: For now we support only a single FPU context. */
6871 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
6873 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
6874 tcg_temp_free_i32(fs_tmp
);
6877 /* COP2: Not implemented. */
6884 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6890 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6891 generate_exception(ctx
, EXCP_RI
);
6894 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6896 const char *opn
= "ldst";
6898 check_cp0_enabled(ctx
);
6905 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6910 TCGv t0
= tcg_temp_new();
6912 gen_load_gpr(t0
, rt
);
6913 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6918 #if defined(TARGET_MIPS64)
6920 check_insn(ctx
, ISA_MIPS3
);
6925 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6929 check_insn(ctx
, ISA_MIPS3
);
6931 TCGv t0
= tcg_temp_new();
6933 gen_load_gpr(t0
, rt
);
6934 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6941 check_insn(ctx
, ASE_MT
);
6946 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6947 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6951 check_insn(ctx
, ASE_MT
);
6952 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6953 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6958 if (!env
->tlb
->helper_tlbwi
)
6960 gen_helper_tlbwi(cpu_env
);
6964 if (!env
->tlb
->helper_tlbwr
)
6966 gen_helper_tlbwr(cpu_env
);
6970 if (!env
->tlb
->helper_tlbp
)
6972 gen_helper_tlbp(cpu_env
);
6976 if (!env
->tlb
->helper_tlbr
)
6978 gen_helper_tlbr(cpu_env
);
6982 check_insn(ctx
, ISA_MIPS2
);
6983 gen_helper_eret(cpu_env
);
6984 ctx
->bstate
= BS_EXCP
;
6988 check_insn(ctx
, ISA_MIPS32
);
6989 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6991 generate_exception(ctx
, EXCP_RI
);
6993 gen_helper_deret(cpu_env
);
6994 ctx
->bstate
= BS_EXCP
;
6999 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
7000 /* If we get an exception, we want to restart at next instruction */
7002 save_cpu_state(ctx
, 1);
7004 gen_helper_wait(cpu_env
);
7005 ctx
->bstate
= BS_EXCP
;
7010 generate_exception(ctx
, EXCP_RI
);
7013 (void)opn
; /* avoid a compiler warning */
7014 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
7016 #endif /* !CONFIG_USER_ONLY */
7018 /* CP1 Branches (before delay slot) */
7019 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
7020 int32_t cc
, int32_t offset
)
7022 target_ulong btarget
;
7023 const char *opn
= "cp1 cond branch";
7024 TCGv_i32 t0
= tcg_temp_new_i32();
7027 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
7029 btarget
= ctx
->pc
+ 4 + offset
;
7033 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7034 tcg_gen_not_i32(t0
, t0
);
7035 tcg_gen_andi_i32(t0
, t0
, 1);
7036 tcg_gen_extu_i32_tl(bcond
, t0
);
7040 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7041 tcg_gen_not_i32(t0
, t0
);
7042 tcg_gen_andi_i32(t0
, t0
, 1);
7043 tcg_gen_extu_i32_tl(bcond
, t0
);
7047 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7048 tcg_gen_andi_i32(t0
, t0
, 1);
7049 tcg_gen_extu_i32_tl(bcond
, t0
);
7053 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7054 tcg_gen_andi_i32(t0
, t0
, 1);
7055 tcg_gen_extu_i32_tl(bcond
, t0
);
7058 ctx
->hflags
|= MIPS_HFLAG_BL
;
7062 TCGv_i32 t1
= tcg_temp_new_i32();
7063 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7064 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7065 tcg_gen_nand_i32(t0
, t0
, t1
);
7066 tcg_temp_free_i32(t1
);
7067 tcg_gen_andi_i32(t0
, t0
, 1);
7068 tcg_gen_extu_i32_tl(bcond
, t0
);
7074 TCGv_i32 t1
= tcg_temp_new_i32();
7075 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7076 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7077 tcg_gen_or_i32(t0
, t0
, t1
);
7078 tcg_temp_free_i32(t1
);
7079 tcg_gen_andi_i32(t0
, t0
, 1);
7080 tcg_gen_extu_i32_tl(bcond
, t0
);
7086 TCGv_i32 t1
= tcg_temp_new_i32();
7087 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7088 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7089 tcg_gen_and_i32(t0
, t0
, t1
);
7090 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7091 tcg_gen_and_i32(t0
, t0
, t1
);
7092 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7093 tcg_gen_nand_i32(t0
, t0
, t1
);
7094 tcg_temp_free_i32(t1
);
7095 tcg_gen_andi_i32(t0
, t0
, 1);
7096 tcg_gen_extu_i32_tl(bcond
, t0
);
7102 TCGv_i32 t1
= tcg_temp_new_i32();
7103 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7104 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7105 tcg_gen_or_i32(t0
, t0
, t1
);
7106 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7107 tcg_gen_or_i32(t0
, t0
, t1
);
7108 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7109 tcg_gen_or_i32(t0
, t0
, t1
);
7110 tcg_temp_free_i32(t1
);
7111 tcg_gen_andi_i32(t0
, t0
, 1);
7112 tcg_gen_extu_i32_tl(bcond
, t0
);
7116 ctx
->hflags
|= MIPS_HFLAG_BC
;
7120 generate_exception (ctx
, EXCP_RI
);
7123 (void)opn
; /* avoid a compiler warning */
7124 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7125 ctx
->hflags
, btarget
);
7126 ctx
->btarget
= btarget
;
7129 tcg_temp_free_i32(t0
);
7132 /* Coprocessor 1 (FPU) */
7134 #define FOP(func, fmt) (((fmt) << 21) | (func))
7137 OPC_ADD_S
= FOP(0, FMT_S
),
7138 OPC_SUB_S
= FOP(1, FMT_S
),
7139 OPC_MUL_S
= FOP(2, FMT_S
),
7140 OPC_DIV_S
= FOP(3, FMT_S
),
7141 OPC_SQRT_S
= FOP(4, FMT_S
),
7142 OPC_ABS_S
= FOP(5, FMT_S
),
7143 OPC_MOV_S
= FOP(6, FMT_S
),
7144 OPC_NEG_S
= FOP(7, FMT_S
),
7145 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7146 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7147 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7148 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7149 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7150 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7151 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7152 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7153 OPC_MOVCF_S
= FOP(17, FMT_S
),
7154 OPC_MOVZ_S
= FOP(18, FMT_S
),
7155 OPC_MOVN_S
= FOP(19, FMT_S
),
7156 OPC_RECIP_S
= FOP(21, FMT_S
),
7157 OPC_RSQRT_S
= FOP(22, FMT_S
),
7158 OPC_RECIP2_S
= FOP(28, FMT_S
),
7159 OPC_RECIP1_S
= FOP(29, FMT_S
),
7160 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7161 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7162 OPC_CVT_D_S
= FOP(33, FMT_S
),
7163 OPC_CVT_W_S
= FOP(36, FMT_S
),
7164 OPC_CVT_L_S
= FOP(37, FMT_S
),
7165 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7166 OPC_CMP_F_S
= FOP (48, FMT_S
),
7167 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7168 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7169 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7170 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7171 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7172 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7173 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7174 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7175 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7176 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7177 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7178 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7179 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7180 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7181 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7183 OPC_ADD_D
= FOP(0, FMT_D
),
7184 OPC_SUB_D
= FOP(1, FMT_D
),
7185 OPC_MUL_D
= FOP(2, FMT_D
),
7186 OPC_DIV_D
= FOP(3, FMT_D
),
7187 OPC_SQRT_D
= FOP(4, FMT_D
),
7188 OPC_ABS_D
= FOP(5, FMT_D
),
7189 OPC_MOV_D
= FOP(6, FMT_D
),
7190 OPC_NEG_D
= FOP(7, FMT_D
),
7191 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7192 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7193 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7194 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7195 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7196 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7197 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7198 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7199 OPC_MOVCF_D
= FOP(17, FMT_D
),
7200 OPC_MOVZ_D
= FOP(18, FMT_D
),
7201 OPC_MOVN_D
= FOP(19, FMT_D
),
7202 OPC_RECIP_D
= FOP(21, FMT_D
),
7203 OPC_RSQRT_D
= FOP(22, FMT_D
),
7204 OPC_RECIP2_D
= FOP(28, FMT_D
),
7205 OPC_RECIP1_D
= FOP(29, FMT_D
),
7206 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7207 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7208 OPC_CVT_S_D
= FOP(32, FMT_D
),
7209 OPC_CVT_W_D
= FOP(36, FMT_D
),
7210 OPC_CVT_L_D
= FOP(37, FMT_D
),
7211 OPC_CMP_F_D
= FOP (48, FMT_D
),
7212 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7213 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7214 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7215 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7216 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7217 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7218 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7219 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7220 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7221 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7222 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7223 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7224 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7225 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7226 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7228 OPC_CVT_S_W
= FOP(32, FMT_W
),
7229 OPC_CVT_D_W
= FOP(33, FMT_W
),
7230 OPC_CVT_S_L
= FOP(32, FMT_L
),
7231 OPC_CVT_D_L
= FOP(33, FMT_L
),
7232 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7234 OPC_ADD_PS
= FOP(0, FMT_PS
),
7235 OPC_SUB_PS
= FOP(1, FMT_PS
),
7236 OPC_MUL_PS
= FOP(2, FMT_PS
),
7237 OPC_DIV_PS
= FOP(3, FMT_PS
),
7238 OPC_ABS_PS
= FOP(5, FMT_PS
),
7239 OPC_MOV_PS
= FOP(6, FMT_PS
),
7240 OPC_NEG_PS
= FOP(7, FMT_PS
),
7241 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7242 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7243 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7244 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7245 OPC_MULR_PS
= FOP(26, FMT_PS
),
7246 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7247 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7248 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7249 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7251 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7252 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7253 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7254 OPC_PLL_PS
= FOP(44, FMT_PS
),
7255 OPC_PLU_PS
= FOP(45, FMT_PS
),
7256 OPC_PUL_PS
= FOP(46, FMT_PS
),
7257 OPC_PUU_PS
= FOP(47, FMT_PS
),
7258 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7259 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7260 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7261 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7262 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7263 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7264 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7265 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7266 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7267 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7268 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7269 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7270 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7271 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7272 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7273 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7276 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7278 const char *opn
= "cp1 move";
7279 TCGv t0
= tcg_temp_new();
7284 TCGv_i32 fp0
= tcg_temp_new_i32();
7286 gen_load_fpr32(fp0
, fs
);
7287 tcg_gen_ext_i32_tl(t0
, fp0
);
7288 tcg_temp_free_i32(fp0
);
7290 gen_store_gpr(t0
, rt
);
7294 gen_load_gpr(t0
, rt
);
7296 TCGv_i32 fp0
= tcg_temp_new_i32();
7298 tcg_gen_trunc_tl_i32(fp0
, t0
);
7299 gen_store_fpr32(fp0
, fs
);
7300 tcg_temp_free_i32(fp0
);
7305 gen_helper_1e0i(cfc1
, t0
, fs
);
7306 gen_store_gpr(t0
, rt
);
7310 gen_load_gpr(t0
, rt
);
7312 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
7314 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7315 tcg_temp_free_i32(fs_tmp
);
7319 #if defined(TARGET_MIPS64)
7321 gen_load_fpr64(ctx
, t0
, fs
);
7322 gen_store_gpr(t0
, rt
);
7326 gen_load_gpr(t0
, rt
);
7327 gen_store_fpr64(ctx
, t0
, fs
);
7333 TCGv_i32 fp0
= tcg_temp_new_i32();
7335 gen_load_fpr32h(ctx
, fp0
, fs
);
7336 tcg_gen_ext_i32_tl(t0
, fp0
);
7337 tcg_temp_free_i32(fp0
);
7339 gen_store_gpr(t0
, rt
);
7343 gen_load_gpr(t0
, rt
);
7345 TCGv_i32 fp0
= tcg_temp_new_i32();
7347 tcg_gen_trunc_tl_i32(fp0
, t0
);
7348 gen_store_fpr32h(ctx
, fp0
, fs
);
7349 tcg_temp_free_i32(fp0
);
7355 generate_exception (ctx
, EXCP_RI
);
7358 (void)opn
; /* avoid a compiler warning */
7359 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7365 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7381 l1
= gen_new_label();
7382 t0
= tcg_temp_new_i32();
7383 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7384 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7385 tcg_temp_free_i32(t0
);
7387 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7389 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7394 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7397 TCGv_i32 t0
= tcg_temp_new_i32();
7398 int l1
= gen_new_label();
7405 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7406 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7407 gen_load_fpr32(t0
, fs
);
7408 gen_store_fpr32(t0
, fd
);
7410 tcg_temp_free_i32(t0
);
7413 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7416 TCGv_i32 t0
= tcg_temp_new_i32();
7418 int l1
= gen_new_label();
7425 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7426 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7427 tcg_temp_free_i32(t0
);
7428 fp0
= tcg_temp_new_i64();
7429 gen_load_fpr64(ctx
, fp0
, fs
);
7430 gen_store_fpr64(ctx
, fp0
, fd
);
7431 tcg_temp_free_i64(fp0
);
7435 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
7439 TCGv_i32 t0
= tcg_temp_new_i32();
7440 int l1
= gen_new_label();
7441 int l2
= gen_new_label();
7448 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7449 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7450 gen_load_fpr32(t0
, fs
);
7451 gen_store_fpr32(t0
, fd
);
7454 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7455 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7456 gen_load_fpr32h(ctx
, t0
, fs
);
7457 gen_store_fpr32h(ctx
, t0
, fd
);
7458 tcg_temp_free_i32(t0
);
7463 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7464 int ft
, int fs
, int fd
, int cc
)
7466 const char *opn
= "farith";
7467 const char *condnames
[] = {
7485 const char *condnames_abs
[] = {
7503 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7504 uint32_t func
= ctx
->opcode
& 0x3f;
7509 TCGv_i32 fp0
= tcg_temp_new_i32();
7510 TCGv_i32 fp1
= tcg_temp_new_i32();
7512 gen_load_fpr32(fp0
, fs
);
7513 gen_load_fpr32(fp1
, ft
);
7514 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7515 tcg_temp_free_i32(fp1
);
7516 gen_store_fpr32(fp0
, fd
);
7517 tcg_temp_free_i32(fp0
);
7524 TCGv_i32 fp0
= tcg_temp_new_i32();
7525 TCGv_i32 fp1
= tcg_temp_new_i32();
7527 gen_load_fpr32(fp0
, fs
);
7528 gen_load_fpr32(fp1
, ft
);
7529 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7530 tcg_temp_free_i32(fp1
);
7531 gen_store_fpr32(fp0
, fd
);
7532 tcg_temp_free_i32(fp0
);
7539 TCGv_i32 fp0
= tcg_temp_new_i32();
7540 TCGv_i32 fp1
= tcg_temp_new_i32();
7542 gen_load_fpr32(fp0
, fs
);
7543 gen_load_fpr32(fp1
, ft
);
7544 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7545 tcg_temp_free_i32(fp1
);
7546 gen_store_fpr32(fp0
, fd
);
7547 tcg_temp_free_i32(fp0
);
7554 TCGv_i32 fp0
= tcg_temp_new_i32();
7555 TCGv_i32 fp1
= tcg_temp_new_i32();
7557 gen_load_fpr32(fp0
, fs
);
7558 gen_load_fpr32(fp1
, ft
);
7559 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7560 tcg_temp_free_i32(fp1
);
7561 gen_store_fpr32(fp0
, fd
);
7562 tcg_temp_free_i32(fp0
);
7569 TCGv_i32 fp0
= tcg_temp_new_i32();
7571 gen_load_fpr32(fp0
, fs
);
7572 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7573 gen_store_fpr32(fp0
, fd
);
7574 tcg_temp_free_i32(fp0
);
7580 TCGv_i32 fp0
= tcg_temp_new_i32();
7582 gen_load_fpr32(fp0
, fs
);
7583 gen_helper_float_abs_s(fp0
, fp0
);
7584 gen_store_fpr32(fp0
, fd
);
7585 tcg_temp_free_i32(fp0
);
7591 TCGv_i32 fp0
= tcg_temp_new_i32();
7593 gen_load_fpr32(fp0
, fs
);
7594 gen_store_fpr32(fp0
, fd
);
7595 tcg_temp_free_i32(fp0
);
7601 TCGv_i32 fp0
= tcg_temp_new_i32();
7603 gen_load_fpr32(fp0
, fs
);
7604 gen_helper_float_chs_s(fp0
, fp0
);
7605 gen_store_fpr32(fp0
, fd
);
7606 tcg_temp_free_i32(fp0
);
7611 check_cp1_64bitmode(ctx
);
7613 TCGv_i32 fp32
= tcg_temp_new_i32();
7614 TCGv_i64 fp64
= tcg_temp_new_i64();
7616 gen_load_fpr32(fp32
, fs
);
7617 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7618 tcg_temp_free_i32(fp32
);
7619 gen_store_fpr64(ctx
, fp64
, fd
);
7620 tcg_temp_free_i64(fp64
);
7625 check_cp1_64bitmode(ctx
);
7627 TCGv_i32 fp32
= tcg_temp_new_i32();
7628 TCGv_i64 fp64
= tcg_temp_new_i64();
7630 gen_load_fpr32(fp32
, fs
);
7631 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7632 tcg_temp_free_i32(fp32
);
7633 gen_store_fpr64(ctx
, fp64
, fd
);
7634 tcg_temp_free_i64(fp64
);
7639 check_cp1_64bitmode(ctx
);
7641 TCGv_i32 fp32
= tcg_temp_new_i32();
7642 TCGv_i64 fp64
= tcg_temp_new_i64();
7644 gen_load_fpr32(fp32
, fs
);
7645 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7646 tcg_temp_free_i32(fp32
);
7647 gen_store_fpr64(ctx
, fp64
, fd
);
7648 tcg_temp_free_i64(fp64
);
7653 check_cp1_64bitmode(ctx
);
7655 TCGv_i32 fp32
= tcg_temp_new_i32();
7656 TCGv_i64 fp64
= tcg_temp_new_i64();
7658 gen_load_fpr32(fp32
, fs
);
7659 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7660 tcg_temp_free_i32(fp32
);
7661 gen_store_fpr64(ctx
, fp64
, fd
);
7662 tcg_temp_free_i64(fp64
);
7668 TCGv_i32 fp0
= tcg_temp_new_i32();
7670 gen_load_fpr32(fp0
, fs
);
7671 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7672 gen_store_fpr32(fp0
, fd
);
7673 tcg_temp_free_i32(fp0
);
7679 TCGv_i32 fp0
= tcg_temp_new_i32();
7681 gen_load_fpr32(fp0
, fs
);
7682 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7683 gen_store_fpr32(fp0
, fd
);
7684 tcg_temp_free_i32(fp0
);
7690 TCGv_i32 fp0
= tcg_temp_new_i32();
7692 gen_load_fpr32(fp0
, fs
);
7693 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7694 gen_store_fpr32(fp0
, fd
);
7695 tcg_temp_free_i32(fp0
);
7701 TCGv_i32 fp0
= tcg_temp_new_i32();
7703 gen_load_fpr32(fp0
, fs
);
7704 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7705 gen_store_fpr32(fp0
, fd
);
7706 tcg_temp_free_i32(fp0
);
7711 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7716 int l1
= gen_new_label();
7720 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7722 fp0
= tcg_temp_new_i32();
7723 gen_load_fpr32(fp0
, fs
);
7724 gen_store_fpr32(fp0
, fd
);
7725 tcg_temp_free_i32(fp0
);
7732 int l1
= gen_new_label();
7736 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7737 fp0
= tcg_temp_new_i32();
7738 gen_load_fpr32(fp0
, fs
);
7739 gen_store_fpr32(fp0
, fd
);
7740 tcg_temp_free_i32(fp0
);
7749 TCGv_i32 fp0
= tcg_temp_new_i32();
7751 gen_load_fpr32(fp0
, fs
);
7752 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7753 gen_store_fpr32(fp0
, fd
);
7754 tcg_temp_free_i32(fp0
);
7761 TCGv_i32 fp0
= tcg_temp_new_i32();
7763 gen_load_fpr32(fp0
, fs
);
7764 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7765 gen_store_fpr32(fp0
, fd
);
7766 tcg_temp_free_i32(fp0
);
7771 check_cp1_64bitmode(ctx
);
7773 TCGv_i32 fp0
= tcg_temp_new_i32();
7774 TCGv_i32 fp1
= tcg_temp_new_i32();
7776 gen_load_fpr32(fp0
, fs
);
7777 gen_load_fpr32(fp1
, ft
);
7778 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7779 tcg_temp_free_i32(fp1
);
7780 gen_store_fpr32(fp0
, fd
);
7781 tcg_temp_free_i32(fp0
);
7786 check_cp1_64bitmode(ctx
);
7788 TCGv_i32 fp0
= tcg_temp_new_i32();
7790 gen_load_fpr32(fp0
, fs
);
7791 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7792 gen_store_fpr32(fp0
, fd
);
7793 tcg_temp_free_i32(fp0
);
7798 check_cp1_64bitmode(ctx
);
7800 TCGv_i32 fp0
= tcg_temp_new_i32();
7802 gen_load_fpr32(fp0
, fs
);
7803 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7804 gen_store_fpr32(fp0
, fd
);
7805 tcg_temp_free_i32(fp0
);
7810 check_cp1_64bitmode(ctx
);
7812 TCGv_i32 fp0
= tcg_temp_new_i32();
7813 TCGv_i32 fp1
= tcg_temp_new_i32();
7815 gen_load_fpr32(fp0
, fs
);
7816 gen_load_fpr32(fp1
, ft
);
7817 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7818 tcg_temp_free_i32(fp1
);
7819 gen_store_fpr32(fp0
, fd
);
7820 tcg_temp_free_i32(fp0
);
7825 check_cp1_registers(ctx
, fd
);
7827 TCGv_i32 fp32
= tcg_temp_new_i32();
7828 TCGv_i64 fp64
= tcg_temp_new_i64();
7830 gen_load_fpr32(fp32
, fs
);
7831 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7832 tcg_temp_free_i32(fp32
);
7833 gen_store_fpr64(ctx
, fp64
, fd
);
7834 tcg_temp_free_i64(fp64
);
7840 TCGv_i32 fp0
= tcg_temp_new_i32();
7842 gen_load_fpr32(fp0
, fs
);
7843 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7844 gen_store_fpr32(fp0
, fd
);
7845 tcg_temp_free_i32(fp0
);
7850 check_cp1_64bitmode(ctx
);
7852 TCGv_i32 fp32
= tcg_temp_new_i32();
7853 TCGv_i64 fp64
= tcg_temp_new_i64();
7855 gen_load_fpr32(fp32
, fs
);
7856 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7857 tcg_temp_free_i32(fp32
);
7858 gen_store_fpr64(ctx
, fp64
, fd
);
7859 tcg_temp_free_i64(fp64
);
7864 check_cp1_64bitmode(ctx
);
7866 TCGv_i64 fp64
= tcg_temp_new_i64();
7867 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7868 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7870 gen_load_fpr32(fp32_0
, fs
);
7871 gen_load_fpr32(fp32_1
, ft
);
7872 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7873 tcg_temp_free_i32(fp32_1
);
7874 tcg_temp_free_i32(fp32_0
);
7875 gen_store_fpr64(ctx
, fp64
, fd
);
7876 tcg_temp_free_i64(fp64
);
7889 case OPC_CMP_NGLE_S
:
7896 if (ctx
->opcode
& (1 << 6)) {
7897 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7898 opn
= condnames_abs
[func
-48];
7900 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7901 opn
= condnames
[func
-48];
7905 check_cp1_registers(ctx
, fs
| ft
| fd
);
7907 TCGv_i64 fp0
= tcg_temp_new_i64();
7908 TCGv_i64 fp1
= tcg_temp_new_i64();
7910 gen_load_fpr64(ctx
, fp0
, fs
);
7911 gen_load_fpr64(ctx
, fp1
, ft
);
7912 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7913 tcg_temp_free_i64(fp1
);
7914 gen_store_fpr64(ctx
, fp0
, fd
);
7915 tcg_temp_free_i64(fp0
);
7921 check_cp1_registers(ctx
, fs
| ft
| fd
);
7923 TCGv_i64 fp0
= tcg_temp_new_i64();
7924 TCGv_i64 fp1
= tcg_temp_new_i64();
7926 gen_load_fpr64(ctx
, fp0
, fs
);
7927 gen_load_fpr64(ctx
, fp1
, ft
);
7928 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7929 tcg_temp_free_i64(fp1
);
7930 gen_store_fpr64(ctx
, fp0
, fd
);
7931 tcg_temp_free_i64(fp0
);
7937 check_cp1_registers(ctx
, fs
| ft
| fd
);
7939 TCGv_i64 fp0
= tcg_temp_new_i64();
7940 TCGv_i64 fp1
= tcg_temp_new_i64();
7942 gen_load_fpr64(ctx
, fp0
, fs
);
7943 gen_load_fpr64(ctx
, fp1
, ft
);
7944 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7945 tcg_temp_free_i64(fp1
);
7946 gen_store_fpr64(ctx
, fp0
, fd
);
7947 tcg_temp_free_i64(fp0
);
7953 check_cp1_registers(ctx
, fs
| ft
| fd
);
7955 TCGv_i64 fp0
= tcg_temp_new_i64();
7956 TCGv_i64 fp1
= tcg_temp_new_i64();
7958 gen_load_fpr64(ctx
, fp0
, fs
);
7959 gen_load_fpr64(ctx
, fp1
, ft
);
7960 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7961 tcg_temp_free_i64(fp1
);
7962 gen_store_fpr64(ctx
, fp0
, fd
);
7963 tcg_temp_free_i64(fp0
);
7969 check_cp1_registers(ctx
, fs
| fd
);
7971 TCGv_i64 fp0
= tcg_temp_new_i64();
7973 gen_load_fpr64(ctx
, fp0
, fs
);
7974 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7975 gen_store_fpr64(ctx
, fp0
, fd
);
7976 tcg_temp_free_i64(fp0
);
7981 check_cp1_registers(ctx
, fs
| fd
);
7983 TCGv_i64 fp0
= tcg_temp_new_i64();
7985 gen_load_fpr64(ctx
, fp0
, fs
);
7986 gen_helper_float_abs_d(fp0
, fp0
);
7987 gen_store_fpr64(ctx
, fp0
, fd
);
7988 tcg_temp_free_i64(fp0
);
7993 check_cp1_registers(ctx
, fs
| fd
);
7995 TCGv_i64 fp0
= tcg_temp_new_i64();
7997 gen_load_fpr64(ctx
, fp0
, fs
);
7998 gen_store_fpr64(ctx
, fp0
, fd
);
7999 tcg_temp_free_i64(fp0
);
8004 check_cp1_registers(ctx
, fs
| fd
);
8006 TCGv_i64 fp0
= tcg_temp_new_i64();
8008 gen_load_fpr64(ctx
, fp0
, fs
);
8009 gen_helper_float_chs_d(fp0
, fp0
);
8010 gen_store_fpr64(ctx
, fp0
, fd
);
8011 tcg_temp_free_i64(fp0
);
8016 check_cp1_64bitmode(ctx
);
8018 TCGv_i64 fp0
= tcg_temp_new_i64();
8020 gen_load_fpr64(ctx
, fp0
, fs
);
8021 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
8022 gen_store_fpr64(ctx
, fp0
, fd
);
8023 tcg_temp_free_i64(fp0
);
8028 check_cp1_64bitmode(ctx
);
8030 TCGv_i64 fp0
= tcg_temp_new_i64();
8032 gen_load_fpr64(ctx
, fp0
, fs
);
8033 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
8034 gen_store_fpr64(ctx
, fp0
, fd
);
8035 tcg_temp_free_i64(fp0
);
8040 check_cp1_64bitmode(ctx
);
8042 TCGv_i64 fp0
= tcg_temp_new_i64();
8044 gen_load_fpr64(ctx
, fp0
, fs
);
8045 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
8046 gen_store_fpr64(ctx
, fp0
, fd
);
8047 tcg_temp_free_i64(fp0
);
8052 check_cp1_64bitmode(ctx
);
8054 TCGv_i64 fp0
= tcg_temp_new_i64();
8056 gen_load_fpr64(ctx
, fp0
, fs
);
8057 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8058 gen_store_fpr64(ctx
, fp0
, fd
);
8059 tcg_temp_free_i64(fp0
);
8064 check_cp1_registers(ctx
, fs
);
8066 TCGv_i32 fp32
= tcg_temp_new_i32();
8067 TCGv_i64 fp64
= tcg_temp_new_i64();
8069 gen_load_fpr64(ctx
, fp64
, fs
);
8070 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8071 tcg_temp_free_i64(fp64
);
8072 gen_store_fpr32(fp32
, fd
);
8073 tcg_temp_free_i32(fp32
);
8078 check_cp1_registers(ctx
, fs
);
8080 TCGv_i32 fp32
= tcg_temp_new_i32();
8081 TCGv_i64 fp64
= tcg_temp_new_i64();
8083 gen_load_fpr64(ctx
, fp64
, fs
);
8084 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8085 tcg_temp_free_i64(fp64
);
8086 gen_store_fpr32(fp32
, fd
);
8087 tcg_temp_free_i32(fp32
);
8092 check_cp1_registers(ctx
, fs
);
8094 TCGv_i32 fp32
= tcg_temp_new_i32();
8095 TCGv_i64 fp64
= tcg_temp_new_i64();
8097 gen_load_fpr64(ctx
, fp64
, fs
);
8098 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8099 tcg_temp_free_i64(fp64
);
8100 gen_store_fpr32(fp32
, fd
);
8101 tcg_temp_free_i32(fp32
);
8106 check_cp1_registers(ctx
, fs
);
8108 TCGv_i32 fp32
= tcg_temp_new_i32();
8109 TCGv_i64 fp64
= tcg_temp_new_i64();
8111 gen_load_fpr64(ctx
, fp64
, fs
);
8112 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8113 tcg_temp_free_i64(fp64
);
8114 gen_store_fpr32(fp32
, fd
);
8115 tcg_temp_free_i32(fp32
);
8120 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8125 int l1
= gen_new_label();
8129 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8131 fp0
= tcg_temp_new_i64();
8132 gen_load_fpr64(ctx
, fp0
, fs
);
8133 gen_store_fpr64(ctx
, fp0
, fd
);
8134 tcg_temp_free_i64(fp0
);
8141 int l1
= gen_new_label();
8145 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8146 fp0
= tcg_temp_new_i64();
8147 gen_load_fpr64(ctx
, fp0
, fs
);
8148 gen_store_fpr64(ctx
, fp0
, fd
);
8149 tcg_temp_free_i64(fp0
);
8156 check_cp1_64bitmode(ctx
);
8158 TCGv_i64 fp0
= tcg_temp_new_i64();
8160 gen_load_fpr64(ctx
, fp0
, fs
);
8161 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8162 gen_store_fpr64(ctx
, fp0
, fd
);
8163 tcg_temp_free_i64(fp0
);
8168 check_cp1_64bitmode(ctx
);
8170 TCGv_i64 fp0
= tcg_temp_new_i64();
8172 gen_load_fpr64(ctx
, fp0
, fs
);
8173 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8174 gen_store_fpr64(ctx
, fp0
, fd
);
8175 tcg_temp_free_i64(fp0
);
8180 check_cp1_64bitmode(ctx
);
8182 TCGv_i64 fp0
= tcg_temp_new_i64();
8183 TCGv_i64 fp1
= tcg_temp_new_i64();
8185 gen_load_fpr64(ctx
, fp0
, fs
);
8186 gen_load_fpr64(ctx
, fp1
, ft
);
8187 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8188 tcg_temp_free_i64(fp1
);
8189 gen_store_fpr64(ctx
, fp0
, fd
);
8190 tcg_temp_free_i64(fp0
);
8195 check_cp1_64bitmode(ctx
);
8197 TCGv_i64 fp0
= tcg_temp_new_i64();
8199 gen_load_fpr64(ctx
, fp0
, fs
);
8200 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8201 gen_store_fpr64(ctx
, fp0
, fd
);
8202 tcg_temp_free_i64(fp0
);
8207 check_cp1_64bitmode(ctx
);
8209 TCGv_i64 fp0
= tcg_temp_new_i64();
8211 gen_load_fpr64(ctx
, fp0
, fs
);
8212 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8213 gen_store_fpr64(ctx
, fp0
, fd
);
8214 tcg_temp_free_i64(fp0
);
8219 check_cp1_64bitmode(ctx
);
8221 TCGv_i64 fp0
= tcg_temp_new_i64();
8222 TCGv_i64 fp1
= tcg_temp_new_i64();
8224 gen_load_fpr64(ctx
, fp0
, fs
);
8225 gen_load_fpr64(ctx
, fp1
, ft
);
8226 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8227 tcg_temp_free_i64(fp1
);
8228 gen_store_fpr64(ctx
, fp0
, fd
);
8229 tcg_temp_free_i64(fp0
);
8242 case OPC_CMP_NGLE_D
:
8249 if (ctx
->opcode
& (1 << 6)) {
8250 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8251 opn
= condnames_abs
[func
-48];
8253 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8254 opn
= condnames
[func
-48];
8258 check_cp1_registers(ctx
, fs
);
8260 TCGv_i32 fp32
= tcg_temp_new_i32();
8261 TCGv_i64 fp64
= tcg_temp_new_i64();
8263 gen_load_fpr64(ctx
, fp64
, fs
);
8264 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8265 tcg_temp_free_i64(fp64
);
8266 gen_store_fpr32(fp32
, fd
);
8267 tcg_temp_free_i32(fp32
);
8272 check_cp1_registers(ctx
, fs
);
8274 TCGv_i32 fp32
= tcg_temp_new_i32();
8275 TCGv_i64 fp64
= tcg_temp_new_i64();
8277 gen_load_fpr64(ctx
, fp64
, fs
);
8278 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8279 tcg_temp_free_i64(fp64
);
8280 gen_store_fpr32(fp32
, fd
);
8281 tcg_temp_free_i32(fp32
);
8286 check_cp1_64bitmode(ctx
);
8288 TCGv_i64 fp0
= tcg_temp_new_i64();
8290 gen_load_fpr64(ctx
, fp0
, fs
);
8291 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8292 gen_store_fpr64(ctx
, fp0
, fd
);
8293 tcg_temp_free_i64(fp0
);
8299 TCGv_i32 fp0
= tcg_temp_new_i32();
8301 gen_load_fpr32(fp0
, fs
);
8302 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8303 gen_store_fpr32(fp0
, fd
);
8304 tcg_temp_free_i32(fp0
);
8309 check_cp1_registers(ctx
, fd
);
8311 TCGv_i32 fp32
= tcg_temp_new_i32();
8312 TCGv_i64 fp64
= tcg_temp_new_i64();
8314 gen_load_fpr32(fp32
, fs
);
8315 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8316 tcg_temp_free_i32(fp32
);
8317 gen_store_fpr64(ctx
, fp64
, fd
);
8318 tcg_temp_free_i64(fp64
);
8323 check_cp1_64bitmode(ctx
);
8325 TCGv_i32 fp32
= tcg_temp_new_i32();
8326 TCGv_i64 fp64
= tcg_temp_new_i64();
8328 gen_load_fpr64(ctx
, fp64
, fs
);
8329 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8330 tcg_temp_free_i64(fp64
);
8331 gen_store_fpr32(fp32
, fd
);
8332 tcg_temp_free_i32(fp32
);
8337 check_cp1_64bitmode(ctx
);
8339 TCGv_i64 fp0
= tcg_temp_new_i64();
8341 gen_load_fpr64(ctx
, fp0
, fs
);
8342 gen_helper_float_cvtd_l(fp0
, cpu_env
, 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_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8355 gen_store_fpr64(ctx
, fp0
, fd
);
8356 tcg_temp_free_i64(fp0
);
8361 check_cp1_64bitmode(ctx
);
8363 TCGv_i64 fp0
= tcg_temp_new_i64();
8364 TCGv_i64 fp1
= tcg_temp_new_i64();
8366 gen_load_fpr64(ctx
, fp0
, fs
);
8367 gen_load_fpr64(ctx
, fp1
, ft
);
8368 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8369 tcg_temp_free_i64(fp1
);
8370 gen_store_fpr64(ctx
, fp0
, fd
);
8371 tcg_temp_free_i64(fp0
);
8376 check_cp1_64bitmode(ctx
);
8378 TCGv_i64 fp0
= tcg_temp_new_i64();
8379 TCGv_i64 fp1
= tcg_temp_new_i64();
8381 gen_load_fpr64(ctx
, fp0
, fs
);
8382 gen_load_fpr64(ctx
, fp1
, ft
);
8383 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8384 tcg_temp_free_i64(fp1
);
8385 gen_store_fpr64(ctx
, fp0
, fd
);
8386 tcg_temp_free_i64(fp0
);
8391 check_cp1_64bitmode(ctx
);
8393 TCGv_i64 fp0
= tcg_temp_new_i64();
8394 TCGv_i64 fp1
= tcg_temp_new_i64();
8396 gen_load_fpr64(ctx
, fp0
, fs
);
8397 gen_load_fpr64(ctx
, fp1
, ft
);
8398 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8399 tcg_temp_free_i64(fp1
);
8400 gen_store_fpr64(ctx
, fp0
, fd
);
8401 tcg_temp_free_i64(fp0
);
8406 check_cp1_64bitmode(ctx
);
8408 TCGv_i64 fp0
= tcg_temp_new_i64();
8410 gen_load_fpr64(ctx
, fp0
, fs
);
8411 gen_helper_float_abs_ps(fp0
, fp0
);
8412 gen_store_fpr64(ctx
, fp0
, fd
);
8413 tcg_temp_free_i64(fp0
);
8418 check_cp1_64bitmode(ctx
);
8420 TCGv_i64 fp0
= tcg_temp_new_i64();
8422 gen_load_fpr64(ctx
, fp0
, fs
);
8423 gen_store_fpr64(ctx
, fp0
, fd
);
8424 tcg_temp_free_i64(fp0
);
8429 check_cp1_64bitmode(ctx
);
8431 TCGv_i64 fp0
= tcg_temp_new_i64();
8433 gen_load_fpr64(ctx
, fp0
, fs
);
8434 gen_helper_float_chs_ps(fp0
, fp0
);
8435 gen_store_fpr64(ctx
, fp0
, fd
);
8436 tcg_temp_free_i64(fp0
);
8441 check_cp1_64bitmode(ctx
);
8442 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8446 check_cp1_64bitmode(ctx
);
8448 int l1
= gen_new_label();
8452 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8453 fp0
= tcg_temp_new_i64();
8454 gen_load_fpr64(ctx
, fp0
, fs
);
8455 gen_store_fpr64(ctx
, fp0
, fd
);
8456 tcg_temp_free_i64(fp0
);
8462 check_cp1_64bitmode(ctx
);
8464 int l1
= gen_new_label();
8468 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8469 fp0
= tcg_temp_new_i64();
8470 gen_load_fpr64(ctx
, fp0
, fs
);
8471 gen_store_fpr64(ctx
, fp0
, fd
);
8472 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
, ft
);
8485 gen_load_fpr64(ctx
, fp1
, fs
);
8486 gen_helper_float_addr_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_i64 fp0
= tcg_temp_new_i64();
8497 TCGv_i64 fp1
= tcg_temp_new_i64();
8499 gen_load_fpr64(ctx
, fp0
, ft
);
8500 gen_load_fpr64(ctx
, fp1
, fs
);
8501 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8502 tcg_temp_free_i64(fp1
);
8503 gen_store_fpr64(ctx
, fp0
, fd
);
8504 tcg_temp_free_i64(fp0
);
8509 check_cp1_64bitmode(ctx
);
8511 TCGv_i64 fp0
= tcg_temp_new_i64();
8512 TCGv_i64 fp1
= tcg_temp_new_i64();
8514 gen_load_fpr64(ctx
, fp0
, fs
);
8515 gen_load_fpr64(ctx
, fp1
, ft
);
8516 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8517 tcg_temp_free_i64(fp1
);
8518 gen_store_fpr64(ctx
, fp0
, fd
);
8519 tcg_temp_free_i64(fp0
);
8524 check_cp1_64bitmode(ctx
);
8526 TCGv_i64 fp0
= tcg_temp_new_i64();
8528 gen_load_fpr64(ctx
, fp0
, fs
);
8529 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
8530 gen_store_fpr64(ctx
, fp0
, fd
);
8531 tcg_temp_free_i64(fp0
);
8536 check_cp1_64bitmode(ctx
);
8538 TCGv_i64 fp0
= tcg_temp_new_i64();
8540 gen_load_fpr64(ctx
, fp0
, fs
);
8541 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8542 gen_store_fpr64(ctx
, fp0
, fd
);
8543 tcg_temp_free_i64(fp0
);
8548 check_cp1_64bitmode(ctx
);
8550 TCGv_i64 fp0
= tcg_temp_new_i64();
8551 TCGv_i64 fp1
= tcg_temp_new_i64();
8553 gen_load_fpr64(ctx
, fp0
, fs
);
8554 gen_load_fpr64(ctx
, fp1
, ft
);
8555 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8556 tcg_temp_free_i64(fp1
);
8557 gen_store_fpr64(ctx
, fp0
, fd
);
8558 tcg_temp_free_i64(fp0
);
8563 check_cp1_64bitmode(ctx
);
8565 TCGv_i32 fp0
= tcg_temp_new_i32();
8567 gen_load_fpr32h(ctx
, fp0
, fs
);
8568 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8569 gen_store_fpr32(fp0
, fd
);
8570 tcg_temp_free_i32(fp0
);
8575 check_cp1_64bitmode(ctx
);
8577 TCGv_i64 fp0
= tcg_temp_new_i64();
8579 gen_load_fpr64(ctx
, fp0
, fs
);
8580 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8581 gen_store_fpr64(ctx
, fp0
, fd
);
8582 tcg_temp_free_i64(fp0
);
8587 check_cp1_64bitmode(ctx
);
8589 TCGv_i32 fp0
= tcg_temp_new_i32();
8591 gen_load_fpr32(fp0
, fs
);
8592 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8593 gen_store_fpr32(fp0
, fd
);
8594 tcg_temp_free_i32(fp0
);
8599 check_cp1_64bitmode(ctx
);
8601 TCGv_i32 fp0
= tcg_temp_new_i32();
8602 TCGv_i32 fp1
= tcg_temp_new_i32();
8604 gen_load_fpr32(fp0
, fs
);
8605 gen_load_fpr32(fp1
, ft
);
8606 gen_store_fpr32h(ctx
, fp0
, fd
);
8607 gen_store_fpr32(fp1
, fd
);
8608 tcg_temp_free_i32(fp0
);
8609 tcg_temp_free_i32(fp1
);
8614 check_cp1_64bitmode(ctx
);
8616 TCGv_i32 fp0
= tcg_temp_new_i32();
8617 TCGv_i32 fp1
= tcg_temp_new_i32();
8619 gen_load_fpr32(fp0
, fs
);
8620 gen_load_fpr32h(ctx
, fp1
, ft
);
8621 gen_store_fpr32(fp1
, fd
);
8622 gen_store_fpr32h(ctx
, fp0
, fd
);
8623 tcg_temp_free_i32(fp0
);
8624 tcg_temp_free_i32(fp1
);
8629 check_cp1_64bitmode(ctx
);
8631 TCGv_i32 fp0
= tcg_temp_new_i32();
8632 TCGv_i32 fp1
= tcg_temp_new_i32();
8634 gen_load_fpr32h(ctx
, fp0
, fs
);
8635 gen_load_fpr32(fp1
, ft
);
8636 gen_store_fpr32(fp1
, fd
);
8637 gen_store_fpr32h(ctx
, fp0
, fd
);
8638 tcg_temp_free_i32(fp0
);
8639 tcg_temp_free_i32(fp1
);
8644 check_cp1_64bitmode(ctx
);
8646 TCGv_i32 fp0
= tcg_temp_new_i32();
8647 TCGv_i32 fp1
= tcg_temp_new_i32();
8649 gen_load_fpr32h(ctx
, fp0
, fs
);
8650 gen_load_fpr32h(ctx
, fp1
, ft
);
8651 gen_store_fpr32(fp1
, fd
);
8652 gen_store_fpr32h(ctx
, fp0
, fd
);
8653 tcg_temp_free_i32(fp0
);
8654 tcg_temp_free_i32(fp1
);
8661 case OPC_CMP_UEQ_PS
:
8662 case OPC_CMP_OLT_PS
:
8663 case OPC_CMP_ULT_PS
:
8664 case OPC_CMP_OLE_PS
:
8665 case OPC_CMP_ULE_PS
:
8667 case OPC_CMP_NGLE_PS
:
8668 case OPC_CMP_SEQ_PS
:
8669 case OPC_CMP_NGL_PS
:
8671 case OPC_CMP_NGE_PS
:
8673 case OPC_CMP_NGT_PS
:
8674 if (ctx
->opcode
& (1 << 6)) {
8675 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8676 opn
= condnames_abs
[func
-48];
8678 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8679 opn
= condnames
[func
-48];
8684 generate_exception (ctx
, EXCP_RI
);
8687 (void)opn
; /* avoid a compiler warning */
8690 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8693 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8696 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8701 /* Coprocessor 3 (FPU) */
8702 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8703 int fd
, int fs
, int base
, int index
)
8705 const char *opn
= "extended float load/store";
8707 TCGv t0
= tcg_temp_new();
8710 gen_load_gpr(t0
, index
);
8711 } else if (index
== 0) {
8712 gen_load_gpr(t0
, base
);
8714 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8716 /* Don't do NOP if destination is zero: we must perform the actual
8722 TCGv_i32 fp0
= tcg_temp_new_i32();
8724 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
8725 tcg_gen_trunc_tl_i32(fp0
, t0
);
8726 gen_store_fpr32(fp0
, fd
);
8727 tcg_temp_free_i32(fp0
);
8733 check_cp1_registers(ctx
, fd
);
8735 TCGv_i64 fp0
= tcg_temp_new_i64();
8736 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8737 gen_store_fpr64(ctx
, fp0
, fd
);
8738 tcg_temp_free_i64(fp0
);
8743 check_cp1_64bitmode(ctx
);
8744 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8746 TCGv_i64 fp0
= tcg_temp_new_i64();
8748 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8749 gen_store_fpr64(ctx
, fp0
, fd
);
8750 tcg_temp_free_i64(fp0
);
8757 TCGv_i32 fp0
= tcg_temp_new_i32();
8758 gen_load_fpr32(fp0
, fs
);
8759 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
8760 tcg_temp_free_i32(fp0
);
8767 check_cp1_registers(ctx
, fs
);
8769 TCGv_i64 fp0
= tcg_temp_new_i64();
8770 gen_load_fpr64(ctx
, fp0
, fs
);
8771 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8772 tcg_temp_free_i64(fp0
);
8778 check_cp1_64bitmode(ctx
);
8779 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8781 TCGv_i64 fp0
= tcg_temp_new_i64();
8782 gen_load_fpr64(ctx
, fp0
, fs
);
8783 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8784 tcg_temp_free_i64(fp0
);
8791 (void)opn
; (void)store
; /* avoid compiler warnings */
8792 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8793 regnames
[index
], regnames
[base
]);
8796 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8797 int fd
, int fr
, int fs
, int ft
)
8799 const char *opn
= "flt3_arith";
8803 check_cp1_64bitmode(ctx
);
8805 TCGv t0
= tcg_temp_local_new();
8806 TCGv_i32 fp
= tcg_temp_new_i32();
8807 TCGv_i32 fph
= tcg_temp_new_i32();
8808 int l1
= gen_new_label();
8809 int l2
= gen_new_label();
8811 gen_load_gpr(t0
, fr
);
8812 tcg_gen_andi_tl(t0
, t0
, 0x7);
8814 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8815 gen_load_fpr32(fp
, fs
);
8816 gen_load_fpr32h(ctx
, fph
, fs
);
8817 gen_store_fpr32(fp
, fd
);
8818 gen_store_fpr32h(ctx
, fph
, fd
);
8821 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8823 #ifdef TARGET_WORDS_BIGENDIAN
8824 gen_load_fpr32(fp
, fs
);
8825 gen_load_fpr32h(ctx
, fph
, ft
);
8826 gen_store_fpr32h(ctx
, fp
, fd
);
8827 gen_store_fpr32(fph
, fd
);
8829 gen_load_fpr32h(ctx
, fph
, fs
);
8830 gen_load_fpr32(fp
, ft
);
8831 gen_store_fpr32(fph
, fd
);
8832 gen_store_fpr32h(ctx
, fp
, fd
);
8835 tcg_temp_free_i32(fp
);
8836 tcg_temp_free_i32(fph
);
8843 TCGv_i32 fp0
= tcg_temp_new_i32();
8844 TCGv_i32 fp1
= tcg_temp_new_i32();
8845 TCGv_i32 fp2
= tcg_temp_new_i32();
8847 gen_load_fpr32(fp0
, fs
);
8848 gen_load_fpr32(fp1
, ft
);
8849 gen_load_fpr32(fp2
, fr
);
8850 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8851 tcg_temp_free_i32(fp0
);
8852 tcg_temp_free_i32(fp1
);
8853 gen_store_fpr32(fp2
, fd
);
8854 tcg_temp_free_i32(fp2
);
8860 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8862 TCGv_i64 fp0
= tcg_temp_new_i64();
8863 TCGv_i64 fp1
= tcg_temp_new_i64();
8864 TCGv_i64 fp2
= tcg_temp_new_i64();
8866 gen_load_fpr64(ctx
, fp0
, fs
);
8867 gen_load_fpr64(ctx
, fp1
, ft
);
8868 gen_load_fpr64(ctx
, fp2
, fr
);
8869 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8870 tcg_temp_free_i64(fp0
);
8871 tcg_temp_free_i64(fp1
);
8872 gen_store_fpr64(ctx
, fp2
, fd
);
8873 tcg_temp_free_i64(fp2
);
8878 check_cp1_64bitmode(ctx
);
8880 TCGv_i64 fp0
= tcg_temp_new_i64();
8881 TCGv_i64 fp1
= tcg_temp_new_i64();
8882 TCGv_i64 fp2
= tcg_temp_new_i64();
8884 gen_load_fpr64(ctx
, fp0
, fs
);
8885 gen_load_fpr64(ctx
, fp1
, ft
);
8886 gen_load_fpr64(ctx
, fp2
, fr
);
8887 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8888 tcg_temp_free_i64(fp0
);
8889 tcg_temp_free_i64(fp1
);
8890 gen_store_fpr64(ctx
, fp2
, fd
);
8891 tcg_temp_free_i64(fp2
);
8898 TCGv_i32 fp0
= tcg_temp_new_i32();
8899 TCGv_i32 fp1
= tcg_temp_new_i32();
8900 TCGv_i32 fp2
= tcg_temp_new_i32();
8902 gen_load_fpr32(fp0
, fs
);
8903 gen_load_fpr32(fp1
, ft
);
8904 gen_load_fpr32(fp2
, fr
);
8905 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8906 tcg_temp_free_i32(fp0
);
8907 tcg_temp_free_i32(fp1
);
8908 gen_store_fpr32(fp2
, fd
);
8909 tcg_temp_free_i32(fp2
);
8915 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8917 TCGv_i64 fp0
= tcg_temp_new_i64();
8918 TCGv_i64 fp1
= tcg_temp_new_i64();
8919 TCGv_i64 fp2
= tcg_temp_new_i64();
8921 gen_load_fpr64(ctx
, fp0
, fs
);
8922 gen_load_fpr64(ctx
, fp1
, ft
);
8923 gen_load_fpr64(ctx
, fp2
, fr
);
8924 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8925 tcg_temp_free_i64(fp0
);
8926 tcg_temp_free_i64(fp1
);
8927 gen_store_fpr64(ctx
, fp2
, fd
);
8928 tcg_temp_free_i64(fp2
);
8933 check_cp1_64bitmode(ctx
);
8935 TCGv_i64 fp0
= tcg_temp_new_i64();
8936 TCGv_i64 fp1
= tcg_temp_new_i64();
8937 TCGv_i64 fp2
= tcg_temp_new_i64();
8939 gen_load_fpr64(ctx
, fp0
, fs
);
8940 gen_load_fpr64(ctx
, fp1
, ft
);
8941 gen_load_fpr64(ctx
, fp2
, fr
);
8942 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8943 tcg_temp_free_i64(fp0
);
8944 tcg_temp_free_i64(fp1
);
8945 gen_store_fpr64(ctx
, fp2
, fd
);
8946 tcg_temp_free_i64(fp2
);
8953 TCGv_i32 fp0
= tcg_temp_new_i32();
8954 TCGv_i32 fp1
= tcg_temp_new_i32();
8955 TCGv_i32 fp2
= tcg_temp_new_i32();
8957 gen_load_fpr32(fp0
, fs
);
8958 gen_load_fpr32(fp1
, ft
);
8959 gen_load_fpr32(fp2
, fr
);
8960 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8961 tcg_temp_free_i32(fp0
);
8962 tcg_temp_free_i32(fp1
);
8963 gen_store_fpr32(fp2
, fd
);
8964 tcg_temp_free_i32(fp2
);
8970 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8972 TCGv_i64 fp0
= tcg_temp_new_i64();
8973 TCGv_i64 fp1
= tcg_temp_new_i64();
8974 TCGv_i64 fp2
= tcg_temp_new_i64();
8976 gen_load_fpr64(ctx
, fp0
, fs
);
8977 gen_load_fpr64(ctx
, fp1
, ft
);
8978 gen_load_fpr64(ctx
, fp2
, fr
);
8979 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8980 tcg_temp_free_i64(fp0
);
8981 tcg_temp_free_i64(fp1
);
8982 gen_store_fpr64(ctx
, fp2
, fd
);
8983 tcg_temp_free_i64(fp2
);
8988 check_cp1_64bitmode(ctx
);
8990 TCGv_i64 fp0
= tcg_temp_new_i64();
8991 TCGv_i64 fp1
= tcg_temp_new_i64();
8992 TCGv_i64 fp2
= tcg_temp_new_i64();
8994 gen_load_fpr64(ctx
, fp0
, fs
);
8995 gen_load_fpr64(ctx
, fp1
, ft
);
8996 gen_load_fpr64(ctx
, fp2
, fr
);
8997 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8998 tcg_temp_free_i64(fp0
);
8999 tcg_temp_free_i64(fp1
);
9000 gen_store_fpr64(ctx
, fp2
, fd
);
9001 tcg_temp_free_i64(fp2
);
9008 TCGv_i32 fp0
= tcg_temp_new_i32();
9009 TCGv_i32 fp1
= tcg_temp_new_i32();
9010 TCGv_i32 fp2
= tcg_temp_new_i32();
9012 gen_load_fpr32(fp0
, fs
);
9013 gen_load_fpr32(fp1
, ft
);
9014 gen_load_fpr32(fp2
, fr
);
9015 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9016 tcg_temp_free_i32(fp0
);
9017 tcg_temp_free_i32(fp1
);
9018 gen_store_fpr32(fp2
, fd
);
9019 tcg_temp_free_i32(fp2
);
9025 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9027 TCGv_i64 fp0
= tcg_temp_new_i64();
9028 TCGv_i64 fp1
= tcg_temp_new_i64();
9029 TCGv_i64 fp2
= tcg_temp_new_i64();
9031 gen_load_fpr64(ctx
, fp0
, fs
);
9032 gen_load_fpr64(ctx
, fp1
, ft
);
9033 gen_load_fpr64(ctx
, fp2
, fr
);
9034 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9035 tcg_temp_free_i64(fp0
);
9036 tcg_temp_free_i64(fp1
);
9037 gen_store_fpr64(ctx
, fp2
, fd
);
9038 tcg_temp_free_i64(fp2
);
9043 check_cp1_64bitmode(ctx
);
9045 TCGv_i64 fp0
= tcg_temp_new_i64();
9046 TCGv_i64 fp1
= tcg_temp_new_i64();
9047 TCGv_i64 fp2
= tcg_temp_new_i64();
9049 gen_load_fpr64(ctx
, fp0
, fs
);
9050 gen_load_fpr64(ctx
, fp1
, ft
);
9051 gen_load_fpr64(ctx
, fp2
, fr
);
9052 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9053 tcg_temp_free_i64(fp0
);
9054 tcg_temp_free_i64(fp1
);
9055 gen_store_fpr64(ctx
, fp2
, fd
);
9056 tcg_temp_free_i64(fp2
);
9062 generate_exception (ctx
, EXCP_RI
);
9065 (void)opn
; /* avoid a compiler warning */
9066 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9067 fregnames
[fs
], fregnames
[ft
]);
9070 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
9074 #if !defined(CONFIG_USER_ONLY)
9075 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9076 Therefore only check the ISA in system mode. */
9077 check_insn(ctx
, ISA_MIPS32R2
);
9079 t0
= tcg_temp_new();
9083 save_cpu_state(ctx
, 1);
9084 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9085 gen_store_gpr(t0
, rt
);
9088 save_cpu_state(ctx
, 1);
9089 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9090 gen_store_gpr(t0
, rt
);
9093 save_cpu_state(ctx
, 1);
9094 gen_helper_rdhwr_cc(t0
, cpu_env
);
9095 gen_store_gpr(t0
, rt
);
9098 save_cpu_state(ctx
, 1);
9099 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9100 gen_store_gpr(t0
, rt
);
9103 #if defined(CONFIG_USER_ONLY)
9104 tcg_gen_ld_tl(t0
, cpu_env
,
9105 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9106 gen_store_gpr(t0
, rt
);
9109 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
9110 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
9111 tcg_gen_ld_tl(t0
, cpu_env
,
9112 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9113 gen_store_gpr(t0
, rt
);
9115 generate_exception(ctx
, EXCP_RI
);
9119 default: /* Invalid */
9120 MIPS_INVAL("rdhwr");
9121 generate_exception(ctx
, EXCP_RI
);
9127 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9129 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9130 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9131 /* Branches completion */
9132 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9133 ctx
->bstate
= BS_BRANCH
;
9134 save_cpu_state(ctx
, 0);
9135 /* FIXME: Need to clear can_do_io. */
9136 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9138 /* unconditional branch */
9139 MIPS_DEBUG("unconditional branch");
9140 if (proc_hflags
& MIPS_HFLAG_BX
) {
9141 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9143 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9146 /* blikely taken case */
9147 MIPS_DEBUG("blikely branch taken");
9148 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9151 /* Conditional branch */
9152 MIPS_DEBUG("conditional branch");
9154 int l1
= gen_new_label();
9156 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9157 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9159 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9163 /* unconditional branch to register */
9164 MIPS_DEBUG("branch to register");
9165 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9166 TCGv t0
= tcg_temp_new();
9167 TCGv_i32 t1
= tcg_temp_new_i32();
9169 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9170 tcg_gen_trunc_tl_i32(t1
, t0
);
9172 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9173 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9174 tcg_gen_or_i32(hflags
, hflags
, t1
);
9175 tcg_temp_free_i32(t1
);
9177 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9179 tcg_gen_mov_tl(cpu_PC
, btarget
);
9181 if (ctx
->singlestep_enabled
) {
9182 save_cpu_state(ctx
, 0);
9183 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9188 MIPS_DEBUG("unknown branch");
9194 /* ISA extensions (ASEs) */
9195 /* MIPS16 extension to MIPS32 */
9197 /* MIPS16 major opcodes */
9199 M16_OPC_ADDIUSP
= 0x00,
9200 M16_OPC_ADDIUPC
= 0x01,
9203 M16_OPC_BEQZ
= 0x04,
9204 M16_OPC_BNEQZ
= 0x05,
9205 M16_OPC_SHIFT
= 0x06,
9207 M16_OPC_RRIA
= 0x08,
9208 M16_OPC_ADDIU8
= 0x09,
9209 M16_OPC_SLTI
= 0x0a,
9210 M16_OPC_SLTIU
= 0x0b,
9213 M16_OPC_CMPI
= 0x0e,
9217 M16_OPC_LWSP
= 0x12,
9221 M16_OPC_LWPC
= 0x16,
9225 M16_OPC_SWSP
= 0x1a,
9229 M16_OPC_EXTEND
= 0x1e,
9233 /* I8 funct field */
9252 /* RR funct field */
9286 /* I64 funct field */
9298 /* RR ry field for CNVT */
9300 RR_RY_CNVT_ZEB
= 0x0,
9301 RR_RY_CNVT_ZEH
= 0x1,
9302 RR_RY_CNVT_ZEW
= 0x2,
9303 RR_RY_CNVT_SEB
= 0x4,
9304 RR_RY_CNVT_SEH
= 0x5,
9305 RR_RY_CNVT_SEW
= 0x6,
9308 static int xlat (int r
)
9310 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9315 static void gen_mips16_save (DisasContext
*ctx
,
9316 int xsregs
, int aregs
,
9317 int do_ra
, int do_s0
, int do_s1
,
9320 TCGv t0
= tcg_temp_new();
9321 TCGv t1
= tcg_temp_new();
9351 generate_exception(ctx
, EXCP_RI
);
9357 gen_base_offset_addr(ctx
, t0
, 29, 12);
9358 gen_load_gpr(t1
, 7);
9359 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9362 gen_base_offset_addr(ctx
, t0
, 29, 8);
9363 gen_load_gpr(t1
, 6);
9364 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9367 gen_base_offset_addr(ctx
, t0
, 29, 4);
9368 gen_load_gpr(t1
, 5);
9369 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9372 gen_base_offset_addr(ctx
, t0
, 29, 0);
9373 gen_load_gpr(t1
, 4);
9374 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9377 gen_load_gpr(t0
, 29);
9379 #define DECR_AND_STORE(reg) do { \
9380 tcg_gen_subi_tl(t0, t0, 4); \
9381 gen_load_gpr(t1, reg); \
9382 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9446 generate_exception(ctx
, EXCP_RI
);
9462 #undef DECR_AND_STORE
9464 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9469 static void gen_mips16_restore (DisasContext
*ctx
,
9470 int xsregs
, int aregs
,
9471 int do_ra
, int do_s0
, int do_s1
,
9475 TCGv t0
= tcg_temp_new();
9476 TCGv t1
= tcg_temp_new();
9478 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9480 #define DECR_AND_LOAD(reg) do { \
9481 tcg_gen_subi_tl(t0, t0, 4); \
9482 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9483 gen_store_gpr(t1, reg); \
9547 generate_exception(ctx
, EXCP_RI
);
9563 #undef DECR_AND_LOAD
9565 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9570 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9571 int is_64_bit
, int extended
)
9575 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9576 generate_exception(ctx
, EXCP_RI
);
9580 t0
= tcg_temp_new();
9582 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9583 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9585 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9591 #if defined(TARGET_MIPS64)
9592 static void decode_i64_mips16 (DisasContext
*ctx
,
9593 int ry
, int funct
, int16_t offset
,
9599 offset
= extended
? offset
: offset
<< 3;
9600 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9604 offset
= extended
? offset
: offset
<< 3;
9605 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9609 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9610 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9614 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9615 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9618 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9619 generate_exception(ctx
, EXCP_RI
);
9621 offset
= extended
? offset
: offset
<< 3;
9622 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9627 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9628 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9632 offset
= extended
? offset
: offset
<< 2;
9633 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9637 offset
= extended
? offset
: offset
<< 2;
9638 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9644 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9646 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9647 int op
, rx
, ry
, funct
, sa
;
9648 int16_t imm
, offset
;
9650 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9651 op
= (ctx
->opcode
>> 11) & 0x1f;
9652 sa
= (ctx
->opcode
>> 22) & 0x1f;
9653 funct
= (ctx
->opcode
>> 8) & 0x7;
9654 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9655 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9656 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9657 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9658 | (ctx
->opcode
& 0x1f));
9660 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9663 case M16_OPC_ADDIUSP
:
9664 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9666 case M16_OPC_ADDIUPC
:
9667 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9670 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9671 /* No delay slot, so just process as a normal instruction */
9674 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9675 /* No delay slot, so just process as a normal instruction */
9678 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9679 /* No delay slot, so just process as a normal instruction */
9682 switch (ctx
->opcode
& 0x3) {
9684 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9687 #if defined(TARGET_MIPS64)
9689 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9691 generate_exception(ctx
, EXCP_RI
);
9695 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9698 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9702 #if defined(TARGET_MIPS64)
9705 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9709 imm
= ctx
->opcode
& 0xf;
9710 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9711 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9712 imm
= (int16_t) (imm
<< 1) >> 1;
9713 if ((ctx
->opcode
>> 4) & 0x1) {
9714 #if defined(TARGET_MIPS64)
9716 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9718 generate_exception(ctx
, EXCP_RI
);
9721 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9724 case M16_OPC_ADDIU8
:
9725 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9728 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9731 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9736 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9739 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9742 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9745 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9749 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9750 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9751 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9752 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9753 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9754 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9755 | (ctx
->opcode
& 0xf)) << 3;
9757 if (ctx
->opcode
& (1 << 7)) {
9758 gen_mips16_save(ctx
, xsregs
, aregs
,
9759 do_ra
, do_s0
, do_s1
,
9762 gen_mips16_restore(ctx
, xsregs
, aregs
,
9763 do_ra
, do_s0
, do_s1
,
9769 generate_exception(ctx
, EXCP_RI
);
9774 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9777 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9779 #if defined(TARGET_MIPS64)
9781 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9785 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9788 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9791 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9794 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9797 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9800 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9803 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9805 #if defined(TARGET_MIPS64)
9807 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9811 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9814 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9817 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9820 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9822 #if defined(TARGET_MIPS64)
9824 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9828 generate_exception(ctx
, EXCP_RI
);
9835 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9839 int op
, cnvt_op
, op1
, offset
;
9843 op
= (ctx
->opcode
>> 11) & 0x1f;
9844 sa
= (ctx
->opcode
>> 2) & 0x7;
9845 sa
= sa
== 0 ? 8 : sa
;
9846 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9847 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9848 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9849 op1
= offset
= ctx
->opcode
& 0x1f;
9854 case M16_OPC_ADDIUSP
:
9856 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9858 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9861 case M16_OPC_ADDIUPC
:
9862 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9865 offset
= (ctx
->opcode
& 0x7ff) << 1;
9866 offset
= (int16_t)(offset
<< 4) >> 4;
9867 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9868 /* No delay slot, so just process as a normal instruction */
9871 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9872 offset
= (((ctx
->opcode
& 0x1f) << 21)
9873 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9875 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9876 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9880 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9881 /* No delay slot, so just process as a normal instruction */
9884 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9885 /* No delay slot, so just process as a normal instruction */
9888 switch (ctx
->opcode
& 0x3) {
9890 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9893 #if defined(TARGET_MIPS64)
9895 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9897 generate_exception(ctx
, EXCP_RI
);
9901 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9904 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9908 #if defined(TARGET_MIPS64)
9911 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9916 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9918 if ((ctx
->opcode
>> 4) & 1) {
9919 #if defined(TARGET_MIPS64)
9921 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9923 generate_exception(ctx
, EXCP_RI
);
9926 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9930 case M16_OPC_ADDIU8
:
9932 int16_t imm
= (int8_t) ctx
->opcode
;
9934 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9939 int16_t imm
= (uint8_t) ctx
->opcode
;
9940 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9945 int16_t imm
= (uint8_t) ctx
->opcode
;
9946 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9953 funct
= (ctx
->opcode
>> 8) & 0x7;
9956 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9957 ((int8_t)ctx
->opcode
) << 1);
9960 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9961 ((int8_t)ctx
->opcode
) << 1);
9964 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9967 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9968 ((int8_t)ctx
->opcode
) << 3);
9972 int do_ra
= ctx
->opcode
& (1 << 6);
9973 int do_s0
= ctx
->opcode
& (1 << 5);
9974 int do_s1
= ctx
->opcode
& (1 << 4);
9975 int framesize
= ctx
->opcode
& 0xf;
9977 if (framesize
== 0) {
9980 framesize
= framesize
<< 3;
9983 if (ctx
->opcode
& (1 << 7)) {
9984 gen_mips16_save(ctx
, 0, 0,
9985 do_ra
, do_s0
, do_s1
, framesize
);
9987 gen_mips16_restore(ctx
, 0, 0,
9988 do_ra
, do_s0
, do_s1
, framesize
);
9994 int rz
= xlat(ctx
->opcode
& 0x7);
9996 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9997 ((ctx
->opcode
>> 5) & 0x7);
9998 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
10002 reg32
= ctx
->opcode
& 0x1f;
10003 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
10006 generate_exception(ctx
, EXCP_RI
);
10013 int16_t imm
= (uint8_t) ctx
->opcode
;
10015 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
10020 int16_t imm
= (uint8_t) ctx
->opcode
;
10021 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
10024 #if defined(TARGET_MIPS64)
10026 check_mips_64(ctx
);
10027 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
10031 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
10034 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
10037 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10040 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
10043 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
10046 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
10049 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
10051 #if defined (TARGET_MIPS64)
10053 check_mips_64(ctx
);
10054 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
10058 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10061 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
10064 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10067 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10071 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10074 switch (ctx
->opcode
& 0x3) {
10076 mips32_op
= OPC_ADDU
;
10079 mips32_op
= OPC_SUBU
;
10081 #if defined(TARGET_MIPS64)
10083 mips32_op
= OPC_DADDU
;
10084 check_mips_64(ctx
);
10087 mips32_op
= OPC_DSUBU
;
10088 check_mips_64(ctx
);
10092 generate_exception(ctx
, EXCP_RI
);
10096 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10105 int nd
= (ctx
->opcode
>> 7) & 0x1;
10106 int link
= (ctx
->opcode
>> 6) & 0x1;
10107 int ra
= (ctx
->opcode
>> 5) & 0x1;
10110 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10115 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10119 /* XXX: not clear which exception should be raised
10120 * when in debug mode...
10122 check_insn(ctx
, ISA_MIPS32
);
10123 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10124 generate_exception(ctx
, EXCP_DBp
);
10126 generate_exception(ctx
, EXCP_DBp
);
10130 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10133 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10136 generate_exception(ctx
, EXCP_BREAK
);
10139 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10142 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10145 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10147 #if defined (TARGET_MIPS64)
10149 check_mips_64(ctx
);
10150 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10154 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10157 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10160 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10163 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10166 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10169 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10172 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
10176 case RR_RY_CNVT_ZEB
:
10177 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10179 case RR_RY_CNVT_ZEH
:
10180 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10182 case RR_RY_CNVT_SEB
:
10183 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10185 case RR_RY_CNVT_SEH
:
10186 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10188 #if defined (TARGET_MIPS64)
10189 case RR_RY_CNVT_ZEW
:
10190 check_mips_64(ctx
);
10191 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10193 case RR_RY_CNVT_SEW
:
10194 check_mips_64(ctx
);
10195 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10199 generate_exception(ctx
, EXCP_RI
);
10204 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
10206 #if defined (TARGET_MIPS64)
10208 check_mips_64(ctx
);
10209 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10212 check_mips_64(ctx
);
10213 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10216 check_mips_64(ctx
);
10217 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10220 check_mips_64(ctx
);
10221 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10225 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
10228 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
10231 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
10234 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
10236 #if defined (TARGET_MIPS64)
10238 check_mips_64(ctx
);
10239 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
10242 check_mips_64(ctx
);
10243 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
10246 check_mips_64(ctx
);
10247 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
10250 check_mips_64(ctx
);
10251 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
10255 generate_exception(ctx
, EXCP_RI
);
10259 case M16_OPC_EXTEND
:
10260 decode_extended_mips16_opc(env
, ctx
);
10263 #if defined(TARGET_MIPS64)
10265 funct
= (ctx
->opcode
>> 8) & 0x7;
10266 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10270 generate_exception(ctx
, EXCP_RI
);
10277 /* microMIPS extension to MIPS32/MIPS64 */
10280 * microMIPS32/microMIPS64 major opcodes
10282 * 1. MIPS Architecture for Programmers Volume II-B:
10283 * The microMIPS32 Instruction Set (Revision 3.05)
10285 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10287 * 2. MIPS Architecture For Programmers Volume II-A:
10288 * The MIPS64 Instruction Set (Revision 3.51)
10316 POOL32S
= 0x16, /* MIPS64 */
10317 DADDIU32
= 0x17, /* MIPS64 */
10319 /* 0x1f is reserved */
10328 /* 0x20 is reserved */
10338 /* 0x28 and 0x29 are reserved */
10348 /* 0x30 and 0x31 are reserved */
10355 SD32
= 0x36, /* MIPS64 */
10356 LD32
= 0x37, /* MIPS64 */
10358 /* 0x38 and 0x39 are reserved */
10369 /* POOL32A encoding of minor opcode field */
10372 /* These opcodes are distinguished only by bits 9..6; those bits are
10373 * what are recorded below. */
10399 /* The following can be distinguished by their lower 6 bits. */
10405 /* POOL32AXF encoding of minor opcode field extension */
10408 * 1. MIPS Architecture for Programmers Volume II-B:
10409 * The microMIPS32 Instruction Set (Revision 3.05)
10411 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10413 * 2. MIPS Architecture for Programmers VolumeIV-e:
10414 * The MIPS DSP Application-Specific Extension
10415 * to the microMIPS32 Architecture (Revision 2.34)
10417 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10432 /* begin of microMIPS32 DSP */
10434 /* bits 13..12 for 0x01 */
10440 /* bits 13..12 for 0x2a */
10446 /* bits 13..12 for 0x32 */
10450 /* end of microMIPS32 DSP */
10452 /* bits 15..12 for 0x2c */
10468 /* bits 15..12 for 0x34 */
10476 /* bits 15..12 for 0x3c */
10478 JR
= 0x0, /* alias */
10483 /* bits 15..12 for 0x05 */
10487 /* bits 15..12 for 0x0d */
10497 /* bits 15..12 for 0x15 */
10503 /* bits 15..12 for 0x1d */
10507 /* bits 15..12 for 0x2d */
10512 /* bits 15..12 for 0x35 */
10519 /* POOL32B encoding of minor opcode field (bits 15..12) */
10535 /* POOL32C encoding of minor opcode field (bits 15..12) */
10543 /* 0xa is reserved */
10550 /* 0x6 is reserved */
10556 /* POOL32F encoding of minor opcode field (bits 5..0) */
10559 /* These are the bit 7..6 values */
10570 /* These are the bit 8..6 values */
10614 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10618 /* POOL32Fxf encoding of minor opcode extension field */
10656 /* POOL32I encoding of minor opcode field (bits 25..21) */
10681 /* These overlap and are distinguished by bit16 of the instruction */
10690 /* POOL16A encoding of minor opcode field */
10697 /* POOL16B encoding of minor opcode field */
10704 /* POOL16C encoding of minor opcode field */
10724 /* POOL16D encoding of minor opcode field */
10731 /* POOL16E encoding of minor opcode field */
10738 static int mmreg (int r
)
10740 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10745 /* Used for 16-bit store instructions. */
10746 static int mmreg2 (int r
)
10748 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10753 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10754 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10755 #define uMIPS_RS2(op) uMIPS_RS(op)
10756 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10757 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10758 #define uMIPS_RS5(op) (op & 0x1f)
10760 /* Signed immediate */
10761 #define SIMM(op, start, width) \
10762 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10765 /* Zero-extended immediate */
10766 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10768 static void gen_addiur1sp(DisasContext
*ctx
)
10770 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10772 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10775 static void gen_addiur2(DisasContext
*ctx
)
10777 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10778 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10779 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10781 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10784 static void gen_addiusp(DisasContext
*ctx
)
10786 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10789 if (encoded
<= 1) {
10790 decoded
= 256 + encoded
;
10791 } else if (encoded
<= 255) {
10793 } else if (encoded
<= 509) {
10794 decoded
= encoded
- 512;
10796 decoded
= encoded
- 768;
10799 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10802 static void gen_addius5(DisasContext
*ctx
)
10804 int imm
= SIMM(ctx
->opcode
, 1, 4);
10805 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10807 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10810 static void gen_andi16(DisasContext
*ctx
)
10812 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10813 31, 32, 63, 64, 255, 32768, 65535 };
10814 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10815 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10816 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10818 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10821 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10822 int base
, int16_t offset
)
10824 const char *opn
= "ldst_multiple";
10828 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10829 generate_exception(ctx
, EXCP_RI
);
10833 t0
= tcg_temp_new();
10835 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10837 t1
= tcg_const_tl(reglist
);
10838 t2
= tcg_const_i32(ctx
->mem_idx
);
10840 save_cpu_state(ctx
, 1);
10843 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10847 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10850 #ifdef TARGET_MIPS64
10852 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10856 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10862 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10865 tcg_temp_free_i32(t2
);
10869 static void gen_pool16c_insn(DisasContext
*ctx
)
10871 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10872 int rs
= mmreg(ctx
->opcode
& 0x7);
10875 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10880 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10886 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10892 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10898 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10905 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10906 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10908 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10917 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10918 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10920 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10927 int reg
= ctx
->opcode
& 0x1f;
10929 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10935 int reg
= ctx
->opcode
& 0x1f;
10937 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10938 /* Let normal delay slot handling in our caller take us
10939 to the branch target. */
10951 int reg
= ctx
->opcode
& 0x1f;
10953 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10958 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
10962 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
10965 generate_exception(ctx
, EXCP_BREAK
);
10968 /* XXX: not clear which exception should be raised
10969 * when in debug mode...
10971 check_insn(ctx
, ISA_MIPS32
);
10972 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10973 generate_exception(ctx
, EXCP_DBp
);
10975 generate_exception(ctx
, EXCP_DBp
);
10978 case JRADDIUSP
+ 0:
10979 case JRADDIUSP
+ 1:
10981 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10983 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10984 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10985 /* Let normal delay slot handling in our caller take us
10986 to the branch target. */
10990 generate_exception(ctx
, EXCP_RI
);
10995 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10997 TCGv t0
= tcg_temp_new();
10998 TCGv t1
= tcg_temp_new();
11000 gen_load_gpr(t0
, base
);
11003 gen_load_gpr(t1
, index
);
11004 tcg_gen_shli_tl(t1
, t1
, 2);
11005 gen_op_addr_add(ctx
, t0
, t1
, t0
);
11008 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11009 gen_store_gpr(t1
, rd
);
11015 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
11016 int base
, int16_t offset
)
11018 const char *opn
= "ldst_pair";
11021 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
11022 generate_exception(ctx
, EXCP_RI
);
11026 t0
= tcg_temp_new();
11027 t1
= tcg_temp_new();
11029 gen_base_offset_addr(ctx
, t0
, base
, offset
);
11034 generate_exception(ctx
, EXCP_RI
);
11037 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11038 gen_store_gpr(t1
, rd
);
11039 tcg_gen_movi_tl(t1
, 4);
11040 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11041 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11042 gen_store_gpr(t1
, rd
+1);
11046 gen_load_gpr(t1
, rd
);
11047 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11048 tcg_gen_movi_tl(t1
, 4);
11049 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11050 gen_load_gpr(t1
, rd
+1);
11051 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11054 #ifdef TARGET_MIPS64
11057 generate_exception(ctx
, EXCP_RI
);
11060 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11061 gen_store_gpr(t1
, rd
);
11062 tcg_gen_movi_tl(t1
, 8);
11063 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11064 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11065 gen_store_gpr(t1
, rd
+1);
11069 gen_load_gpr(t1
, rd
);
11070 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11071 tcg_gen_movi_tl(t1
, 8);
11072 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11073 gen_load_gpr(t1
, rd
+1);
11074 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11079 (void)opn
; /* avoid a compiler warning */
11080 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11085 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
11087 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11088 int minor
= (ctx
->opcode
>> 12) & 0xf;
11089 uint32_t mips32_op
;
11091 switch (extension
) {
11093 mips32_op
= OPC_TEQ
;
11096 mips32_op
= OPC_TGE
;
11099 mips32_op
= OPC_TGEU
;
11102 mips32_op
= OPC_TLT
;
11105 mips32_op
= OPC_TLTU
;
11108 mips32_op
= OPC_TNE
;
11110 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11112 #ifndef CONFIG_USER_ONLY
11115 check_cp0_enabled(ctx
);
11117 /* Treat as NOP. */
11120 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11124 check_cp0_enabled(ctx
);
11126 TCGv t0
= tcg_temp_new();
11128 gen_load_gpr(t0
, rt
);
11129 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11135 switch (minor
& 3) {
11137 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11140 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11143 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11146 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11149 goto pool32axf_invalid
;
11153 switch (minor
& 3) {
11155 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11158 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11161 goto pool32axf_invalid
;
11167 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11170 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11173 mips32_op
= OPC_CLO
;
11176 mips32_op
= OPC_CLZ
;
11178 check_insn(ctx
, ISA_MIPS32
);
11179 gen_cl(ctx
, mips32_op
, rt
, rs
);
11182 gen_rdhwr(ctx
, rt
, rs
);
11185 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11188 mips32_op
= OPC_MULT
;
11191 mips32_op
= OPC_MULTU
;
11194 mips32_op
= OPC_DIV
;
11197 mips32_op
= OPC_DIVU
;
11200 check_insn(ctx
, ISA_MIPS32
);
11201 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11204 mips32_op
= OPC_MADD
;
11207 mips32_op
= OPC_MADDU
;
11210 mips32_op
= OPC_MSUB
;
11213 mips32_op
= OPC_MSUBU
;
11215 check_insn(ctx
, ISA_MIPS32
);
11216 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11219 goto pool32axf_invalid
;
11230 generate_exception_err(ctx
, EXCP_CpU
, 2);
11233 goto pool32axf_invalid
;
11240 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11244 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11247 goto pool32axf_invalid
;
11253 check_cp0_enabled(ctx
);
11254 check_insn(ctx
, ISA_MIPS32R2
);
11255 gen_load_srsgpr(rt
, rs
);
11258 check_cp0_enabled(ctx
);
11259 check_insn(ctx
, ISA_MIPS32R2
);
11260 gen_store_srsgpr(rt
, rs
);
11263 goto pool32axf_invalid
;
11266 #ifndef CONFIG_USER_ONLY
11270 mips32_op
= OPC_TLBP
;
11273 mips32_op
= OPC_TLBR
;
11276 mips32_op
= OPC_TLBWI
;
11279 mips32_op
= OPC_TLBWR
;
11282 mips32_op
= OPC_WAIT
;
11285 mips32_op
= OPC_DERET
;
11288 mips32_op
= OPC_ERET
;
11290 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11293 goto pool32axf_invalid
;
11299 check_cp0_enabled(ctx
);
11301 TCGv t0
= tcg_temp_new();
11303 save_cpu_state(ctx
, 1);
11304 gen_helper_di(t0
, cpu_env
);
11305 gen_store_gpr(t0
, rs
);
11306 /* Stop translation as we may have switched the execution mode */
11307 ctx
->bstate
= BS_STOP
;
11312 check_cp0_enabled(ctx
);
11314 TCGv t0
= tcg_temp_new();
11316 save_cpu_state(ctx
, 1);
11317 gen_helper_ei(t0
, cpu_env
);
11318 gen_store_gpr(t0
, rs
);
11319 /* Stop translation as we may have switched the execution mode */
11320 ctx
->bstate
= BS_STOP
;
11325 goto pool32axf_invalid
;
11335 generate_exception(ctx
, EXCP_SYSCALL
);
11336 ctx
->bstate
= BS_STOP
;
11339 check_insn(ctx
, ISA_MIPS32
);
11340 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11341 generate_exception(ctx
, EXCP_DBp
);
11343 generate_exception(ctx
, EXCP_DBp
);
11347 goto pool32axf_invalid
;
11351 switch (minor
& 3) {
11353 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
11356 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
11359 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
11362 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
11365 goto pool32axf_invalid
;
11371 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
11374 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
11377 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
11380 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
11383 goto pool32axf_invalid
;
11388 MIPS_INVAL("pool32axf");
11389 generate_exception(ctx
, EXCP_RI
);
11394 /* Values for microMIPS fmt field. Variable-width, depending on which
11395 formats the instruction supports. */
11414 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11416 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11417 uint32_t mips32_op
;
11419 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11420 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11421 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11423 switch (extension
) {
11424 case FLOAT_1BIT_FMT(CFC1
, 0):
11425 mips32_op
= OPC_CFC1
;
11427 case FLOAT_1BIT_FMT(CTC1
, 0):
11428 mips32_op
= OPC_CTC1
;
11430 case FLOAT_1BIT_FMT(MFC1
, 0):
11431 mips32_op
= OPC_MFC1
;
11433 case FLOAT_1BIT_FMT(MTC1
, 0):
11434 mips32_op
= OPC_MTC1
;
11436 case FLOAT_1BIT_FMT(MFHC1
, 0):
11437 mips32_op
= OPC_MFHC1
;
11439 case FLOAT_1BIT_FMT(MTHC1
, 0):
11440 mips32_op
= OPC_MTHC1
;
11442 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11445 /* Reciprocal square root */
11446 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11447 mips32_op
= OPC_RSQRT_S
;
11449 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11450 mips32_op
= OPC_RSQRT_D
;
11454 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11455 mips32_op
= OPC_SQRT_S
;
11457 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11458 mips32_op
= OPC_SQRT_D
;
11462 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11463 mips32_op
= OPC_RECIP_S
;
11465 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11466 mips32_op
= OPC_RECIP_D
;
11470 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11471 mips32_op
= OPC_FLOOR_L_S
;
11473 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11474 mips32_op
= OPC_FLOOR_L_D
;
11476 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11477 mips32_op
= OPC_FLOOR_W_S
;
11479 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11480 mips32_op
= OPC_FLOOR_W_D
;
11484 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11485 mips32_op
= OPC_CEIL_L_S
;
11487 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11488 mips32_op
= OPC_CEIL_L_D
;
11490 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11491 mips32_op
= OPC_CEIL_W_S
;
11493 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11494 mips32_op
= OPC_CEIL_W_D
;
11498 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11499 mips32_op
= OPC_TRUNC_L_S
;
11501 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11502 mips32_op
= OPC_TRUNC_L_D
;
11504 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11505 mips32_op
= OPC_TRUNC_W_S
;
11507 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11508 mips32_op
= OPC_TRUNC_W_D
;
11512 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11513 mips32_op
= OPC_ROUND_L_S
;
11515 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11516 mips32_op
= OPC_ROUND_L_D
;
11518 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11519 mips32_op
= OPC_ROUND_W_S
;
11521 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11522 mips32_op
= OPC_ROUND_W_D
;
11525 /* Integer to floating-point conversion */
11526 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11527 mips32_op
= OPC_CVT_L_S
;
11529 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11530 mips32_op
= OPC_CVT_L_D
;
11532 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11533 mips32_op
= OPC_CVT_W_S
;
11535 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11536 mips32_op
= OPC_CVT_W_D
;
11539 /* Paired-foo conversions */
11540 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11541 mips32_op
= OPC_CVT_S_PL
;
11543 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11544 mips32_op
= OPC_CVT_S_PU
;
11546 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11547 mips32_op
= OPC_CVT_PW_PS
;
11549 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11550 mips32_op
= OPC_CVT_PS_PW
;
11553 /* Floating-point moves */
11554 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11555 mips32_op
= OPC_MOV_S
;
11557 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11558 mips32_op
= OPC_MOV_D
;
11560 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11561 mips32_op
= OPC_MOV_PS
;
11564 /* Absolute value */
11565 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11566 mips32_op
= OPC_ABS_S
;
11568 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11569 mips32_op
= OPC_ABS_D
;
11571 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11572 mips32_op
= OPC_ABS_PS
;
11576 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11577 mips32_op
= OPC_NEG_S
;
11579 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11580 mips32_op
= OPC_NEG_D
;
11582 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11583 mips32_op
= OPC_NEG_PS
;
11586 /* Reciprocal square root step */
11587 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11588 mips32_op
= OPC_RSQRT1_S
;
11590 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11591 mips32_op
= OPC_RSQRT1_D
;
11593 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11594 mips32_op
= OPC_RSQRT1_PS
;
11597 /* Reciprocal step */
11598 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11599 mips32_op
= OPC_RECIP1_S
;
11601 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11602 mips32_op
= OPC_RECIP1_S
;
11604 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11605 mips32_op
= OPC_RECIP1_PS
;
11608 /* Conversions from double */
11609 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11610 mips32_op
= OPC_CVT_D_S
;
11612 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11613 mips32_op
= OPC_CVT_D_W
;
11615 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11616 mips32_op
= OPC_CVT_D_L
;
11619 /* Conversions from single */
11620 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11621 mips32_op
= OPC_CVT_S_D
;
11623 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11624 mips32_op
= OPC_CVT_S_W
;
11626 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11627 mips32_op
= OPC_CVT_S_L
;
11629 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11632 /* Conditional moves on floating-point codes */
11633 case COND_FLOAT_MOV(MOVT
, 0):
11634 case COND_FLOAT_MOV(MOVT
, 1):
11635 case COND_FLOAT_MOV(MOVT
, 2):
11636 case COND_FLOAT_MOV(MOVT
, 3):
11637 case COND_FLOAT_MOV(MOVT
, 4):
11638 case COND_FLOAT_MOV(MOVT
, 5):
11639 case COND_FLOAT_MOV(MOVT
, 6):
11640 case COND_FLOAT_MOV(MOVT
, 7):
11641 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11643 case COND_FLOAT_MOV(MOVF
, 0):
11644 case COND_FLOAT_MOV(MOVF
, 1):
11645 case COND_FLOAT_MOV(MOVF
, 2):
11646 case COND_FLOAT_MOV(MOVF
, 3):
11647 case COND_FLOAT_MOV(MOVF
, 4):
11648 case COND_FLOAT_MOV(MOVF
, 5):
11649 case COND_FLOAT_MOV(MOVF
, 6):
11650 case COND_FLOAT_MOV(MOVF
, 7):
11651 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11654 MIPS_INVAL("pool32fxf");
11655 generate_exception(ctx
, EXCP_RI
);
11660 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11665 int rt
, rs
, rd
, rr
;
11667 uint32_t op
, minor
, mips32_op
;
11668 uint32_t cond
, fmt
, cc
;
11670 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11671 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11673 rt
= (ctx
->opcode
>> 21) & 0x1f;
11674 rs
= (ctx
->opcode
>> 16) & 0x1f;
11675 rd
= (ctx
->opcode
>> 11) & 0x1f;
11676 rr
= (ctx
->opcode
>> 6) & 0x1f;
11677 imm
= (int16_t) ctx
->opcode
;
11679 op
= (ctx
->opcode
>> 26) & 0x3f;
11682 minor
= ctx
->opcode
& 0x3f;
11685 minor
= (ctx
->opcode
>> 6) & 0xf;
11688 mips32_op
= OPC_SLL
;
11691 mips32_op
= OPC_SRA
;
11694 mips32_op
= OPC_SRL
;
11697 mips32_op
= OPC_ROTR
;
11699 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11702 goto pool32a_invalid
;
11706 minor
= (ctx
->opcode
>> 6) & 0xf;
11710 mips32_op
= OPC_ADD
;
11713 mips32_op
= OPC_ADDU
;
11716 mips32_op
= OPC_SUB
;
11719 mips32_op
= OPC_SUBU
;
11722 mips32_op
= OPC_MUL
;
11724 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11728 mips32_op
= OPC_SLLV
;
11731 mips32_op
= OPC_SRLV
;
11734 mips32_op
= OPC_SRAV
;
11737 mips32_op
= OPC_ROTRV
;
11739 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11741 /* Logical operations */
11743 mips32_op
= OPC_AND
;
11746 mips32_op
= OPC_OR
;
11749 mips32_op
= OPC_NOR
;
11752 mips32_op
= OPC_XOR
;
11754 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11756 /* Set less than */
11758 mips32_op
= OPC_SLT
;
11761 mips32_op
= OPC_SLTU
;
11763 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11766 goto pool32a_invalid
;
11770 minor
= (ctx
->opcode
>> 6) & 0xf;
11772 /* Conditional moves */
11774 mips32_op
= OPC_MOVN
;
11777 mips32_op
= OPC_MOVZ
;
11779 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11782 gen_ldxs(ctx
, rs
, rt
, rd
);
11785 goto pool32a_invalid
;
11789 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11792 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11795 gen_pool32axf(env
, ctx
, rt
, rs
);
11798 generate_exception(ctx
, EXCP_BREAK
);
11802 MIPS_INVAL("pool32a");
11803 generate_exception(ctx
, EXCP_RI
);
11808 minor
= (ctx
->opcode
>> 12) & 0xf;
11811 check_cp0_enabled(ctx
);
11812 /* Treat as no-op. */
11816 /* COP2: Not implemented. */
11817 generate_exception_err(ctx
, EXCP_CpU
, 2);
11821 #ifdef TARGET_MIPS64
11825 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11829 #ifdef TARGET_MIPS64
11833 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11836 MIPS_INVAL("pool32b");
11837 generate_exception(ctx
, EXCP_RI
);
11842 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
11843 minor
= ctx
->opcode
& 0x3f;
11844 check_cp1_enabled(ctx
);
11847 mips32_op
= OPC_ALNV_PS
;
11850 mips32_op
= OPC_MADD_S
;
11853 mips32_op
= OPC_MADD_D
;
11856 mips32_op
= OPC_MADD_PS
;
11859 mips32_op
= OPC_MSUB_S
;
11862 mips32_op
= OPC_MSUB_D
;
11865 mips32_op
= OPC_MSUB_PS
;
11868 mips32_op
= OPC_NMADD_S
;
11871 mips32_op
= OPC_NMADD_D
;
11874 mips32_op
= OPC_NMADD_PS
;
11877 mips32_op
= OPC_NMSUB_S
;
11880 mips32_op
= OPC_NMSUB_D
;
11883 mips32_op
= OPC_NMSUB_PS
;
11885 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11887 case CABS_COND_FMT
:
11888 cond
= (ctx
->opcode
>> 6) & 0xf;
11889 cc
= (ctx
->opcode
>> 13) & 0x7;
11890 fmt
= (ctx
->opcode
>> 10) & 0x3;
11893 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11896 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11899 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11902 goto pool32f_invalid
;
11906 cond
= (ctx
->opcode
>> 6) & 0xf;
11907 cc
= (ctx
->opcode
>> 13) & 0x7;
11908 fmt
= (ctx
->opcode
>> 10) & 0x3;
11911 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11914 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11917 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11920 goto pool32f_invalid
;
11924 gen_pool32fxf(ctx
, rt
, rs
);
11928 switch ((ctx
->opcode
>> 6) & 0x7) {
11930 mips32_op
= OPC_PLL_PS
;
11933 mips32_op
= OPC_PLU_PS
;
11936 mips32_op
= OPC_PUL_PS
;
11939 mips32_op
= OPC_PUU_PS
;
11942 mips32_op
= OPC_CVT_PS_S
;
11944 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11947 goto pool32f_invalid
;
11952 switch ((ctx
->opcode
>> 6) & 0x7) {
11954 mips32_op
= OPC_LWXC1
;
11957 mips32_op
= OPC_SWXC1
;
11960 mips32_op
= OPC_LDXC1
;
11963 mips32_op
= OPC_SDXC1
;
11966 mips32_op
= OPC_LUXC1
;
11969 mips32_op
= OPC_SUXC1
;
11971 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11974 goto pool32f_invalid
;
11979 fmt
= (ctx
->opcode
>> 9) & 0x3;
11980 switch ((ctx
->opcode
>> 6) & 0x7) {
11984 mips32_op
= OPC_RSQRT2_S
;
11987 mips32_op
= OPC_RSQRT2_D
;
11990 mips32_op
= OPC_RSQRT2_PS
;
11993 goto pool32f_invalid
;
11999 mips32_op
= OPC_RECIP2_S
;
12002 mips32_op
= OPC_RECIP2_D
;
12005 mips32_op
= OPC_RECIP2_PS
;
12008 goto pool32f_invalid
;
12012 mips32_op
= OPC_ADDR_PS
;
12015 mips32_op
= OPC_MULR_PS
;
12017 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12020 goto pool32f_invalid
;
12024 /* MOV[FT].fmt and PREFX */
12025 cc
= (ctx
->opcode
>> 13) & 0x7;
12026 fmt
= (ctx
->opcode
>> 9) & 0x3;
12027 switch ((ctx
->opcode
>> 6) & 0x7) {
12031 gen_movcf_s(rs
, rt
, cc
, 0);
12034 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
12037 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
12040 goto pool32f_invalid
;
12046 gen_movcf_s(rs
, rt
, cc
, 1);
12049 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
12052 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
12055 goto pool32f_invalid
;
12061 goto pool32f_invalid
;
12064 #define FINSN_3ARG_SDPS(prfx) \
12065 switch ((ctx->opcode >> 8) & 0x3) { \
12067 mips32_op = OPC_##prfx##_S; \
12070 mips32_op = OPC_##prfx##_D; \
12072 case FMT_SDPS_PS: \
12073 mips32_op = OPC_##prfx##_PS; \
12076 goto pool32f_invalid; \
12079 /* regular FP ops */
12080 switch ((ctx
->opcode
>> 6) & 0x3) {
12082 FINSN_3ARG_SDPS(ADD
);
12085 FINSN_3ARG_SDPS(SUB
);
12088 FINSN_3ARG_SDPS(MUL
);
12091 fmt
= (ctx
->opcode
>> 8) & 0x3;
12093 mips32_op
= OPC_DIV_D
;
12094 } else if (fmt
== 0) {
12095 mips32_op
= OPC_DIV_S
;
12097 goto pool32f_invalid
;
12101 goto pool32f_invalid
;
12106 switch ((ctx
->opcode
>> 6) & 0x3) {
12108 FINSN_3ARG_SDPS(MOVN
);
12111 FINSN_3ARG_SDPS(MOVZ
);
12114 goto pool32f_invalid
;
12118 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12122 MIPS_INVAL("pool32f");
12123 generate_exception(ctx
, EXCP_RI
);
12127 generate_exception_err(ctx
, EXCP_CpU
, 1);
12131 minor
= (ctx
->opcode
>> 21) & 0x1f;
12134 mips32_op
= OPC_BLTZ
;
12137 mips32_op
= OPC_BLTZAL
;
12140 mips32_op
= OPC_BLTZALS
;
12143 mips32_op
= OPC_BGEZ
;
12146 mips32_op
= OPC_BGEZAL
;
12149 mips32_op
= OPC_BGEZALS
;
12152 mips32_op
= OPC_BLEZ
;
12155 mips32_op
= OPC_BGTZ
;
12157 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12162 mips32_op
= OPC_TLTI
;
12165 mips32_op
= OPC_TGEI
;
12168 mips32_op
= OPC_TLTIU
;
12171 mips32_op
= OPC_TGEIU
;
12174 mips32_op
= OPC_TNEI
;
12177 mips32_op
= OPC_TEQI
;
12179 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12184 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12185 4, rs
, 0, imm
<< 1);
12186 /* Compact branches don't have a delay slot, so just let
12187 the normal delay slot handling take us to the branch
12191 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12197 /* COP2: Not implemented. */
12198 generate_exception_err(ctx
, EXCP_CpU
, 2);
12201 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12204 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12207 mips32_op
= OPC_BC1FANY4
;
12210 mips32_op
= OPC_BC1TANY4
;
12213 check_insn(ctx
, ASE_MIPS3D
);
12216 gen_compute_branch1(ctx
, mips32_op
,
12217 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12221 /* MIPS DSP: not implemented */
12224 MIPS_INVAL("pool32i");
12225 generate_exception(ctx
, EXCP_RI
);
12230 minor
= (ctx
->opcode
>> 12) & 0xf;
12233 mips32_op
= OPC_LWL
;
12236 mips32_op
= OPC_SWL
;
12239 mips32_op
= OPC_LWR
;
12242 mips32_op
= OPC_SWR
;
12244 #if defined(TARGET_MIPS64)
12246 mips32_op
= OPC_LDL
;
12249 mips32_op
= OPC_SDL
;
12252 mips32_op
= OPC_LDR
;
12255 mips32_op
= OPC_SDR
;
12258 mips32_op
= OPC_LWU
;
12261 mips32_op
= OPC_LLD
;
12265 mips32_op
= OPC_LL
;
12268 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12271 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12274 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12276 #if defined(TARGET_MIPS64)
12278 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12282 /* Treat as no-op */
12285 MIPS_INVAL("pool32c");
12286 generate_exception(ctx
, EXCP_RI
);
12291 mips32_op
= OPC_ADDI
;
12294 mips32_op
= OPC_ADDIU
;
12296 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12299 /* Logical operations */
12301 mips32_op
= OPC_ORI
;
12304 mips32_op
= OPC_XORI
;
12307 mips32_op
= OPC_ANDI
;
12309 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12312 /* Set less than immediate */
12314 mips32_op
= OPC_SLTI
;
12317 mips32_op
= OPC_SLTIU
;
12319 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12322 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12323 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12326 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12327 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12330 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12333 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12336 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12337 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12340 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12341 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12343 /* Floating point (COP1) */
12345 mips32_op
= OPC_LWC1
;
12348 mips32_op
= OPC_LDC1
;
12351 mips32_op
= OPC_SWC1
;
12354 mips32_op
= OPC_SDC1
;
12356 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
12360 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12361 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12363 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12366 /* Loads and stores */
12368 mips32_op
= OPC_LB
;
12371 mips32_op
= OPC_LBU
;
12374 mips32_op
= OPC_LH
;
12377 mips32_op
= OPC_LHU
;
12380 mips32_op
= OPC_LW
;
12382 #ifdef TARGET_MIPS64
12384 mips32_op
= OPC_LD
;
12387 mips32_op
= OPC_SD
;
12391 mips32_op
= OPC_SB
;
12394 mips32_op
= OPC_SH
;
12397 mips32_op
= OPC_SW
;
12400 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12403 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12406 generate_exception(ctx
, EXCP_RI
);
12411 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
12415 /* make sure instructions are on a halfword boundary */
12416 if (ctx
->pc
& 0x1) {
12417 env
->CP0_BadVAddr
= ctx
->pc
;
12418 generate_exception(ctx
, EXCP_AdEL
);
12419 ctx
->bstate
= BS_STOP
;
12423 op
= (ctx
->opcode
>> 10) & 0x3f;
12424 /* Enforce properly-sized instructions in a delay slot */
12425 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12426 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12464 if (bits
& MIPS_HFLAG_BDS16
) {
12465 generate_exception(ctx
, EXCP_RI
);
12466 /* Just stop translation; the user is confused. */
12467 ctx
->bstate
= BS_STOP
;
12492 if (bits
& MIPS_HFLAG_BDS32
) {
12493 generate_exception(ctx
, EXCP_RI
);
12494 /* Just stop translation; the user is confused. */
12495 ctx
->bstate
= BS_STOP
;
12506 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12507 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12508 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12511 switch (ctx
->opcode
& 0x1) {
12520 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12525 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12526 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12527 int amount
= (ctx
->opcode
>> 1) & 0x7;
12529 amount
= amount
== 0 ? 8 : amount
;
12531 switch (ctx
->opcode
& 0x1) {
12540 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12544 gen_pool16c_insn(ctx
);
12548 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12549 int rb
= 28; /* GP */
12550 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12552 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12556 if (ctx
->opcode
& 1) {
12557 generate_exception(ctx
, EXCP_RI
);
12560 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12561 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12562 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12563 int rd
, rs
, re
, rt
;
12564 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12565 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12566 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12568 rd
= rd_enc
[enc_dest
];
12569 re
= re_enc
[enc_dest
];
12570 rs
= rs_rt_enc
[enc_rs
];
12571 rt
= rs_rt_enc
[enc_rt
];
12573 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12574 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12579 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12580 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12581 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12582 offset
= (offset
== 0xf ? -1 : offset
);
12584 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12589 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12590 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12591 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12593 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12598 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12599 int rb
= 29; /* SP */
12600 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12602 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12607 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12608 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12609 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12611 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12616 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12617 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12618 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12620 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12625 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12626 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12627 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12629 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12634 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12635 int rb
= 29; /* SP */
12636 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12638 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12643 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12644 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12645 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12647 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12652 int rd
= uMIPS_RD5(ctx
->opcode
);
12653 int rs
= uMIPS_RS5(ctx
->opcode
);
12655 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12662 switch (ctx
->opcode
& 0x1) {
12672 switch (ctx
->opcode
& 0x1) {
12677 gen_addiur1sp(ctx
);
12682 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12683 SIMM(ctx
->opcode
, 0, 10) << 1);
12687 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12688 mmreg(uMIPS_RD(ctx
->opcode
)),
12689 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12693 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12694 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12696 imm
= (imm
== 0x7f ? -1 : imm
);
12697 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12707 generate_exception(ctx
, EXCP_RI
);
12710 decode_micromips32_opc (env
, ctx
, op
);
12717 /* SmartMIPS extension to MIPS32 */
12719 #if defined(TARGET_MIPS64)
12721 /* MDMX extension to MIPS64 */
12725 /* MIPSDSP functions. */
12726 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12727 int rd
, int base
, int offset
)
12729 const char *opn
= "ldx";
12733 t0
= tcg_temp_new();
12736 gen_load_gpr(t0
, offset
);
12737 } else if (offset
== 0) {
12738 gen_load_gpr(t0
, base
);
12740 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12745 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
12746 gen_store_gpr(t0
, rd
);
12750 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
12751 gen_store_gpr(t0
, rd
);
12755 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12756 gen_store_gpr(t0
, rd
);
12759 #if defined(TARGET_MIPS64)
12761 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12762 gen_store_gpr(t0
, rd
);
12767 (void)opn
; /* avoid a compiler warning */
12768 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12769 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12773 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12774 int ret
, int v1
, int v2
)
12776 const char *opn
= "mipsdsp arith";
12781 /* Treat as NOP. */
12786 v1_t
= tcg_temp_new();
12787 v2_t
= tcg_temp_new();
12789 gen_load_gpr(v1_t
, v1
);
12790 gen_load_gpr(v2_t
, v2
);
12793 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12794 case OPC_MULT_G_2E
:
12798 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12800 case OPC_ADDUH_R_QB
:
12801 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12804 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12806 case OPC_ADDQH_R_PH
:
12807 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12810 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12812 case OPC_ADDQH_R_W
:
12813 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12816 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12818 case OPC_SUBUH_R_QB
:
12819 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12822 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12824 case OPC_SUBQH_R_PH
:
12825 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12828 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12830 case OPC_SUBQH_R_W
:
12831 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12835 case OPC_ABSQ_S_PH_DSP
:
12837 case OPC_ABSQ_S_QB
:
12839 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12841 case OPC_ABSQ_S_PH
:
12843 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12847 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12849 case OPC_PRECEQ_W_PHL
:
12851 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12852 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12854 case OPC_PRECEQ_W_PHR
:
12856 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12857 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12858 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12860 case OPC_PRECEQU_PH_QBL
:
12862 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12864 case OPC_PRECEQU_PH_QBR
:
12866 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12868 case OPC_PRECEQU_PH_QBLA
:
12870 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12872 case OPC_PRECEQU_PH_QBRA
:
12874 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12876 case OPC_PRECEU_PH_QBL
:
12878 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12880 case OPC_PRECEU_PH_QBR
:
12882 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12884 case OPC_PRECEU_PH_QBLA
:
12886 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12888 case OPC_PRECEU_PH_QBRA
:
12890 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12894 case OPC_ADDU_QB_DSP
:
12898 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12900 case OPC_ADDQ_S_PH
:
12902 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12906 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12910 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12912 case OPC_ADDU_S_QB
:
12914 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12918 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12920 case OPC_ADDU_S_PH
:
12922 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12926 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12928 case OPC_SUBQ_S_PH
:
12930 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12934 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12938 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12940 case OPC_SUBU_S_QB
:
12942 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12946 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12948 case OPC_SUBU_S_PH
:
12950 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12954 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12958 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12962 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12964 case OPC_RADDU_W_QB
:
12966 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12970 case OPC_CMPU_EQ_QB_DSP
:
12972 case OPC_PRECR_QB_PH
:
12974 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12976 case OPC_PRECRQ_QB_PH
:
12978 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12980 case OPC_PRECR_SRA_PH_W
:
12983 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12984 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12986 tcg_temp_free_i32(sa_t
);
12989 case OPC_PRECR_SRA_R_PH_W
:
12992 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12993 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12995 tcg_temp_free_i32(sa_t
);
12998 case OPC_PRECRQ_PH_W
:
13000 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13002 case OPC_PRECRQ_RS_PH_W
:
13004 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13006 case OPC_PRECRQU_S_QB_PH
:
13008 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13012 #ifdef TARGET_MIPS64
13013 case OPC_ABSQ_S_QH_DSP
:
13015 case OPC_PRECEQ_L_PWL
:
13017 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
13019 case OPC_PRECEQ_L_PWR
:
13021 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
13023 case OPC_PRECEQ_PW_QHL
:
13025 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
13027 case OPC_PRECEQ_PW_QHR
:
13029 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
13031 case OPC_PRECEQ_PW_QHLA
:
13033 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
13035 case OPC_PRECEQ_PW_QHRA
:
13037 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
13039 case OPC_PRECEQU_QH_OBL
:
13041 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
13043 case OPC_PRECEQU_QH_OBR
:
13045 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
13047 case OPC_PRECEQU_QH_OBLA
:
13049 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
13051 case OPC_PRECEQU_QH_OBRA
:
13053 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
13055 case OPC_PRECEU_QH_OBL
:
13057 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
13059 case OPC_PRECEU_QH_OBR
:
13061 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
13063 case OPC_PRECEU_QH_OBLA
:
13065 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
13067 case OPC_PRECEU_QH_OBRA
:
13069 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
13071 case OPC_ABSQ_S_OB
:
13073 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
13075 case OPC_ABSQ_S_PW
:
13077 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
13079 case OPC_ABSQ_S_QH
:
13081 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
13085 case OPC_ADDU_OB_DSP
:
13087 case OPC_RADDU_L_OB
:
13089 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
13093 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13095 case OPC_SUBQ_S_PW
:
13097 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13101 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13103 case OPC_SUBQ_S_QH
:
13105 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13109 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13111 case OPC_SUBU_S_OB
:
13113 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13117 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13119 case OPC_SUBU_S_QH
:
13121 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13125 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13127 case OPC_SUBUH_R_OB
:
13129 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13133 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13135 case OPC_ADDQ_S_PW
:
13137 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13141 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13143 case OPC_ADDQ_S_QH
:
13145 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13149 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13151 case OPC_ADDU_S_OB
:
13153 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13157 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13159 case OPC_ADDU_S_QH
:
13161 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13165 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13167 case OPC_ADDUH_R_OB
:
13169 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13173 case OPC_CMPU_EQ_OB_DSP
:
13175 case OPC_PRECR_OB_QH
:
13177 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13179 case OPC_PRECR_SRA_QH_PW
:
13182 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13183 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13184 tcg_temp_free_i32(ret_t
);
13187 case OPC_PRECR_SRA_R_QH_PW
:
13190 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13191 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13192 tcg_temp_free_i32(sa_v
);
13195 case OPC_PRECRQ_OB_QH
:
13197 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13199 case OPC_PRECRQ_PW_L
:
13201 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13203 case OPC_PRECRQ_QH_PW
:
13205 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13207 case OPC_PRECRQ_RS_QH_PW
:
13209 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13211 case OPC_PRECRQU_S_OB_QH
:
13213 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13220 tcg_temp_free(v1_t
);
13221 tcg_temp_free(v2_t
);
13223 (void)opn
; /* avoid a compiler warning */
13224 MIPS_DEBUG("%s", opn
);
13227 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13228 int ret
, int v1
, int v2
)
13231 const char *opn
= "mipsdsp shift";
13237 /* Treat as NOP. */
13242 t0
= tcg_temp_new();
13243 v1_t
= tcg_temp_new();
13244 v2_t
= tcg_temp_new();
13246 tcg_gen_movi_tl(t0
, v1
);
13247 gen_load_gpr(v1_t
, v1
);
13248 gen_load_gpr(v2_t
, v2
);
13251 case OPC_SHLL_QB_DSP
:
13253 op2
= MASK_SHLL_QB(ctx
->opcode
);
13257 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13261 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13265 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13269 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13271 case OPC_SHLL_S_PH
:
13273 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13275 case OPC_SHLLV_S_PH
:
13277 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13281 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13283 case OPC_SHLLV_S_W
:
13285 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13289 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13293 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13297 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13301 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13305 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13307 case OPC_SHRA_R_QB
:
13309 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13313 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13315 case OPC_SHRAV_R_QB
:
13317 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13321 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13323 case OPC_SHRA_R_PH
:
13325 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13329 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13331 case OPC_SHRAV_R_PH
:
13333 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13337 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13339 case OPC_SHRAV_R_W
:
13341 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13343 default: /* Invalid */
13344 MIPS_INVAL("MASK SHLL.QB");
13345 generate_exception(ctx
, EXCP_RI
);
13350 #ifdef TARGET_MIPS64
13351 case OPC_SHLL_OB_DSP
:
13352 op2
= MASK_SHLL_OB(ctx
->opcode
);
13356 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13360 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13362 case OPC_SHLL_S_PW
:
13364 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13366 case OPC_SHLLV_S_PW
:
13368 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13372 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13376 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13380 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13384 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13386 case OPC_SHLL_S_QH
:
13388 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13390 case OPC_SHLLV_S_QH
:
13392 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13396 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13400 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13402 case OPC_SHRA_R_OB
:
13404 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13406 case OPC_SHRAV_R_OB
:
13408 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13412 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13416 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13418 case OPC_SHRA_R_PW
:
13420 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13422 case OPC_SHRAV_R_PW
:
13424 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13428 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13432 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13434 case OPC_SHRA_R_QH
:
13436 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13438 case OPC_SHRAV_R_QH
:
13440 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13444 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13448 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13452 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13456 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13458 default: /* Invalid */
13459 MIPS_INVAL("MASK SHLL.OB");
13460 generate_exception(ctx
, EXCP_RI
);
13468 tcg_temp_free(v1_t
);
13469 tcg_temp_free(v2_t
);
13470 (void)opn
; /* avoid a compiler warning */
13471 MIPS_DEBUG("%s", opn
);
13474 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13475 int ret
, int v1
, int v2
, int check_ret
)
13477 const char *opn
= "mipsdsp multiply";
13482 if ((ret
== 0) && (check_ret
== 1)) {
13483 /* Treat as NOP. */
13488 t0
= tcg_temp_new_i32();
13489 v1_t
= tcg_temp_new();
13490 v2_t
= tcg_temp_new();
13492 tcg_gen_movi_i32(t0
, ret
);
13493 gen_load_gpr(v1_t
, v1
);
13494 gen_load_gpr(v2_t
, v2
);
13497 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13498 * the same mask and op1. */
13499 case OPC_MULT_G_2E
:
13503 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13506 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13509 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13511 case OPC_MULQ_RS_W
:
13512 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13516 case OPC_DPA_W_PH_DSP
:
13518 case OPC_DPAU_H_QBL
:
13520 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13522 case OPC_DPAU_H_QBR
:
13524 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13526 case OPC_DPSU_H_QBL
:
13528 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13530 case OPC_DPSU_H_QBR
:
13532 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13536 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13538 case OPC_DPAX_W_PH
:
13540 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13542 case OPC_DPAQ_S_W_PH
:
13544 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13546 case OPC_DPAQX_S_W_PH
:
13548 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13550 case OPC_DPAQX_SA_W_PH
:
13552 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13556 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13558 case OPC_DPSX_W_PH
:
13560 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13562 case OPC_DPSQ_S_W_PH
:
13564 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13566 case OPC_DPSQX_S_W_PH
:
13568 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13570 case OPC_DPSQX_SA_W_PH
:
13572 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13574 case OPC_MULSAQ_S_W_PH
:
13576 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13578 case OPC_DPAQ_SA_L_W
:
13580 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13582 case OPC_DPSQ_SA_L_W
:
13584 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13586 case OPC_MAQ_S_W_PHL
:
13588 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13590 case OPC_MAQ_S_W_PHR
:
13592 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13594 case OPC_MAQ_SA_W_PHL
:
13596 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13598 case OPC_MAQ_SA_W_PHR
:
13600 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13602 case OPC_MULSA_W_PH
:
13604 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13608 #ifdef TARGET_MIPS64
13609 case OPC_DPAQ_W_QH_DSP
:
13611 int ac
= ret
& 0x03;
13612 tcg_gen_movi_i32(t0
, ac
);
13617 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13621 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13625 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13629 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13633 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13635 case OPC_DPAQ_S_W_QH
:
13637 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13639 case OPC_DPAQ_SA_L_PW
:
13641 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13643 case OPC_DPAU_H_OBL
:
13645 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13647 case OPC_DPAU_H_OBR
:
13649 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13653 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13655 case OPC_DPSQ_S_W_QH
:
13657 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13659 case OPC_DPSQ_SA_L_PW
:
13661 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13663 case OPC_DPSU_H_OBL
:
13665 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13667 case OPC_DPSU_H_OBR
:
13669 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13671 case OPC_MAQ_S_L_PWL
:
13673 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13675 case OPC_MAQ_S_L_PWR
:
13677 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13679 case OPC_MAQ_S_W_QHLL
:
13681 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13683 case OPC_MAQ_SA_W_QHLL
:
13685 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13687 case OPC_MAQ_S_W_QHLR
:
13689 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13691 case OPC_MAQ_SA_W_QHLR
:
13693 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13695 case OPC_MAQ_S_W_QHRL
:
13697 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13699 case OPC_MAQ_SA_W_QHRL
:
13701 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13703 case OPC_MAQ_S_W_QHRR
:
13705 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13707 case OPC_MAQ_SA_W_QHRR
:
13709 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13711 case OPC_MULSAQ_S_L_PW
:
13713 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13715 case OPC_MULSAQ_S_W_QH
:
13717 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13723 case OPC_ADDU_QB_DSP
:
13725 case OPC_MULEU_S_PH_QBL
:
13727 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13729 case OPC_MULEU_S_PH_QBR
:
13731 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13733 case OPC_MULQ_RS_PH
:
13735 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13737 case OPC_MULEQ_S_W_PHL
:
13739 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13741 case OPC_MULEQ_S_W_PHR
:
13743 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13745 case OPC_MULQ_S_PH
:
13747 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13751 #ifdef TARGET_MIPS64
13752 case OPC_ADDU_OB_DSP
:
13754 case OPC_MULEQ_S_PW_QHL
:
13756 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13758 case OPC_MULEQ_S_PW_QHR
:
13760 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13762 case OPC_MULEU_S_QH_OBL
:
13764 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13766 case OPC_MULEU_S_QH_OBR
:
13768 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13770 case OPC_MULQ_RS_QH
:
13772 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13779 tcg_temp_free_i32(t0
);
13780 tcg_temp_free(v1_t
);
13781 tcg_temp_free(v2_t
);
13783 (void)opn
; /* avoid a compiler warning */
13784 MIPS_DEBUG("%s", opn
);
13788 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13791 const char *opn
= "mipsdsp Bit/ Manipulation";
13797 /* Treat as NOP. */
13802 t0
= tcg_temp_new();
13803 val_t
= tcg_temp_new();
13804 gen_load_gpr(val_t
, val
);
13807 case OPC_ABSQ_S_PH_DSP
:
13811 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13816 target_long result
;
13817 imm
= (ctx
->opcode
>> 16) & 0xFF;
13818 result
= (uint32_t)imm
<< 24 |
13819 (uint32_t)imm
<< 16 |
13820 (uint32_t)imm
<< 8 |
13822 result
= (int32_t)result
;
13823 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13828 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13829 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13830 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13831 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13832 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13833 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13838 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13839 imm
= (int16_t)(imm
<< 6) >> 6;
13840 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13841 (target_long
)((int32_t)imm
<< 16 | \
13847 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13848 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13849 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13850 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13854 #ifdef TARGET_MIPS64
13855 case OPC_ABSQ_S_QH_DSP
:
13862 imm
= (ctx
->opcode
>> 16) & 0xFF;
13863 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13864 temp
= (temp
<< 16) | temp
;
13865 temp
= (temp
<< 32) | temp
;
13866 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13874 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13875 imm
= (int16_t)(imm
<< 6) >> 6;
13876 temp
= ((target_long
)imm
<< 32) \
13877 | ((target_long
)imm
& 0xFFFFFFFF);
13878 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13886 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13887 imm
= (int16_t)(imm
<< 6) >> 6;
13889 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13890 ((uint64_t)(uint16_t)imm
<< 32) |
13891 ((uint64_t)(uint16_t)imm
<< 16) |
13892 (uint64_t)(uint16_t)imm
;
13893 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13898 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13899 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13900 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13901 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13902 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13903 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13904 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13908 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13909 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13910 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13914 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13915 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13916 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13917 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13918 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13925 tcg_temp_free(val_t
);
13927 (void)opn
; /* avoid a compiler warning */
13928 MIPS_DEBUG("%s", opn
);
13931 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13932 uint32_t op1
, uint32_t op2
,
13933 int ret
, int v1
, int v2
, int check_ret
)
13935 const char *opn
= "mipsdsp add compare pick";
13940 if ((ret
== 0) && (check_ret
== 1)) {
13941 /* Treat as NOP. */
13946 t1
= tcg_temp_new();
13947 v1_t
= tcg_temp_new();
13948 v2_t
= tcg_temp_new();
13950 gen_load_gpr(v1_t
, v1
);
13951 gen_load_gpr(v2_t
, v2
);
13954 case OPC_CMPU_EQ_QB_DSP
:
13956 case OPC_CMPU_EQ_QB
:
13958 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13960 case OPC_CMPU_LT_QB
:
13962 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13964 case OPC_CMPU_LE_QB
:
13966 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13968 case OPC_CMPGU_EQ_QB
:
13970 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13972 case OPC_CMPGU_LT_QB
:
13974 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13976 case OPC_CMPGU_LE_QB
:
13978 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13980 case OPC_CMPGDU_EQ_QB
:
13982 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13983 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13984 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13985 tcg_gen_shli_tl(t1
, t1
, 24);
13986 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13988 case OPC_CMPGDU_LT_QB
:
13990 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
13991 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13992 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13993 tcg_gen_shli_tl(t1
, t1
, 24);
13994 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13996 case OPC_CMPGDU_LE_QB
:
13998 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
13999 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14000 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
14001 tcg_gen_shli_tl(t1
, t1
, 24);
14002 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14004 case OPC_CMP_EQ_PH
:
14006 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
14008 case OPC_CMP_LT_PH
:
14010 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
14012 case OPC_CMP_LE_PH
:
14014 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
14018 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14022 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14024 case OPC_PACKRL_PH
:
14026 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14030 #ifdef TARGET_MIPS64
14031 case OPC_CMPU_EQ_OB_DSP
:
14033 case OPC_CMP_EQ_PW
:
14035 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
14037 case OPC_CMP_LT_PW
:
14039 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
14041 case OPC_CMP_LE_PW
:
14043 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
14045 case OPC_CMP_EQ_QH
:
14047 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
14049 case OPC_CMP_LT_QH
:
14051 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
14053 case OPC_CMP_LE_QH
:
14055 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
14057 case OPC_CMPGDU_EQ_OB
:
14059 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14061 case OPC_CMPGDU_LT_OB
:
14063 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14065 case OPC_CMPGDU_LE_OB
:
14067 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14069 case OPC_CMPGU_EQ_OB
:
14071 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14073 case OPC_CMPGU_LT_OB
:
14075 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14077 case OPC_CMPGU_LE_OB
:
14079 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14081 case OPC_CMPU_EQ_OB
:
14083 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
14085 case OPC_CMPU_LT_OB
:
14087 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
14089 case OPC_CMPU_LE_OB
:
14091 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
14093 case OPC_PACKRL_PW
:
14095 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14099 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14103 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14107 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14115 tcg_temp_free(v1_t
);
14116 tcg_temp_free(v2_t
);
14118 (void)opn
; /* avoid a compiler warning */
14119 MIPS_DEBUG("%s", opn
);
14122 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14123 uint32_t op1
, int rt
, int rs
, int sa
)
14125 const char *opn
= "mipsdsp append/dappend";
14131 /* Treat as NOP. */
14136 t0
= tcg_temp_new();
14137 gen_load_gpr(t0
, rs
);
14140 case OPC_APPEND_DSP
:
14141 switch (MASK_APPEND(ctx
->opcode
)) {
14144 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14146 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14150 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14151 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14152 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14153 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14155 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14159 if (sa
!= 0 && sa
!= 2) {
14160 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14161 tcg_gen_ext32u_tl(t0
, t0
);
14162 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14163 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14165 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14167 default: /* Invalid */
14168 MIPS_INVAL("MASK APPEND");
14169 generate_exception(ctx
, EXCP_RI
);
14173 #ifdef TARGET_MIPS64
14174 case OPC_DAPPEND_DSP
:
14175 switch (MASK_DAPPEND(ctx
->opcode
)) {
14178 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14182 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14183 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14184 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14188 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14189 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14190 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14195 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14196 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14197 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14198 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14201 default: /* Invalid */
14202 MIPS_INVAL("MASK DAPPEND");
14203 generate_exception(ctx
, EXCP_RI
);
14210 (void)opn
; /* avoid a compiler warning */
14211 MIPS_DEBUG("%s", opn
);
14214 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14215 int ret
, int v1
, int v2
, int check_ret
)
14218 const char *opn
= "mipsdsp accumulator";
14225 if ((ret
== 0) && (check_ret
== 1)) {
14226 /* Treat as NOP. */
14231 t0
= tcg_temp_new();
14232 t1
= tcg_temp_new();
14233 v1_t
= tcg_temp_new();
14234 v2_t
= tcg_temp_new();
14236 gen_load_gpr(v1_t
, v1
);
14237 gen_load_gpr(v2_t
, v2
);
14240 case OPC_EXTR_W_DSP
:
14244 tcg_gen_movi_tl(t0
, v2
);
14245 tcg_gen_movi_tl(t1
, v1
);
14246 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14249 tcg_gen_movi_tl(t0
, v2
);
14250 tcg_gen_movi_tl(t1
, v1
);
14251 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14253 case OPC_EXTR_RS_W
:
14254 tcg_gen_movi_tl(t0
, v2
);
14255 tcg_gen_movi_tl(t1
, v1
);
14256 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14259 tcg_gen_movi_tl(t0
, v2
);
14260 tcg_gen_movi_tl(t1
, v1
);
14261 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14263 case OPC_EXTRV_S_H
:
14264 tcg_gen_movi_tl(t0
, v2
);
14265 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14268 tcg_gen_movi_tl(t0
, v2
);
14269 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14271 case OPC_EXTRV_R_W
:
14272 tcg_gen_movi_tl(t0
, v2
);
14273 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14275 case OPC_EXTRV_RS_W
:
14276 tcg_gen_movi_tl(t0
, v2
);
14277 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14280 tcg_gen_movi_tl(t0
, v2
);
14281 tcg_gen_movi_tl(t1
, v1
);
14282 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14285 tcg_gen_movi_tl(t0
, v2
);
14286 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14289 tcg_gen_movi_tl(t0
, v2
);
14290 tcg_gen_movi_tl(t1
, v1
);
14291 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14294 tcg_gen_movi_tl(t0
, v2
);
14295 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14298 imm
= (ctx
->opcode
>> 20) & 0x3F;
14299 tcg_gen_movi_tl(t0
, ret
);
14300 tcg_gen_movi_tl(t1
, imm
);
14301 gen_helper_shilo(t0
, t1
, cpu_env
);
14304 tcg_gen_movi_tl(t0
, ret
);
14305 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14308 tcg_gen_movi_tl(t0
, ret
);
14309 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14312 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14313 tcg_gen_movi_tl(t0
, imm
);
14314 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14317 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14318 tcg_gen_movi_tl(t0
, imm
);
14319 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14323 #ifdef TARGET_MIPS64
14324 case OPC_DEXTR_W_DSP
:
14328 tcg_gen_movi_tl(t0
, ret
);
14329 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14333 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14334 int ac
= (ctx
->opcode
>> 11) & 0x03;
14335 tcg_gen_movi_tl(t0
, shift
);
14336 tcg_gen_movi_tl(t1
, ac
);
14337 gen_helper_dshilo(t0
, t1
, cpu_env
);
14342 int ac
= (ctx
->opcode
>> 11) & 0x03;
14343 tcg_gen_movi_tl(t0
, ac
);
14344 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14348 tcg_gen_movi_tl(t0
, v2
);
14349 tcg_gen_movi_tl(t1
, v1
);
14351 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14354 tcg_gen_movi_tl(t0
, v2
);
14355 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14358 tcg_gen_movi_tl(t0
, v2
);
14359 tcg_gen_movi_tl(t1
, v1
);
14360 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14363 tcg_gen_movi_tl(t0
, v2
);
14364 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14367 tcg_gen_movi_tl(t0
, v2
);
14368 tcg_gen_movi_tl(t1
, v1
);
14369 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14371 case OPC_DEXTR_R_L
:
14372 tcg_gen_movi_tl(t0
, v2
);
14373 tcg_gen_movi_tl(t1
, v1
);
14374 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14376 case OPC_DEXTR_RS_L
:
14377 tcg_gen_movi_tl(t0
, v2
);
14378 tcg_gen_movi_tl(t1
, v1
);
14379 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14382 tcg_gen_movi_tl(t0
, v2
);
14383 tcg_gen_movi_tl(t1
, v1
);
14384 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14386 case OPC_DEXTR_R_W
:
14387 tcg_gen_movi_tl(t0
, v2
);
14388 tcg_gen_movi_tl(t1
, v1
);
14389 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14391 case OPC_DEXTR_RS_W
:
14392 tcg_gen_movi_tl(t0
, v2
);
14393 tcg_gen_movi_tl(t1
, v1
);
14394 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14396 case OPC_DEXTR_S_H
:
14397 tcg_gen_movi_tl(t0
, v2
);
14398 tcg_gen_movi_tl(t1
, v1
);
14399 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14401 case OPC_DEXTRV_S_H
:
14402 tcg_gen_movi_tl(t0
, v2
);
14403 tcg_gen_movi_tl(t1
, v1
);
14404 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14407 tcg_gen_movi_tl(t0
, v2
);
14408 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14410 case OPC_DEXTRV_R_L
:
14411 tcg_gen_movi_tl(t0
, v2
);
14412 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14414 case OPC_DEXTRV_RS_L
:
14415 tcg_gen_movi_tl(t0
, v2
);
14416 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14419 tcg_gen_movi_tl(t0
, v2
);
14420 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14422 case OPC_DEXTRV_R_W
:
14423 tcg_gen_movi_tl(t0
, v2
);
14424 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14426 case OPC_DEXTRV_RS_W
:
14427 tcg_gen_movi_tl(t0
, v2
);
14428 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14437 tcg_temp_free(v1_t
);
14438 tcg_temp_free(v2_t
);
14440 (void)opn
; /* avoid a compiler warning */
14441 MIPS_DEBUG("%s", opn
);
14444 /* End MIPSDSP functions. */
14446 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
14449 int rs
, rt
, rd
, sa
;
14450 uint32_t op
, op1
, op2
;
14453 /* make sure instructions are on a word boundary */
14454 if (ctx
->pc
& 0x3) {
14455 env
->CP0_BadVAddr
= ctx
->pc
;
14456 generate_exception(ctx
, EXCP_AdEL
);
14460 /* Handle blikely not taken case */
14461 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14462 int l1
= gen_new_label();
14464 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14465 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14466 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14467 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14471 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14472 tcg_gen_debug_insn_start(ctx
->pc
);
14475 op
= MASK_OP_MAJOR(ctx
->opcode
);
14476 rs
= (ctx
->opcode
>> 21) & 0x1f;
14477 rt
= (ctx
->opcode
>> 16) & 0x1f;
14478 rd
= (ctx
->opcode
>> 11) & 0x1f;
14479 sa
= (ctx
->opcode
>> 6) & 0x1f;
14480 imm
= (int16_t)ctx
->opcode
;
14483 op1
= MASK_SPECIAL(ctx
->opcode
);
14485 case OPC_SLL
: /* Shift with immediate */
14487 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14490 switch ((ctx
->opcode
>> 21) & 0x1f) {
14492 /* rotr is decoded as srl on non-R2 CPUs */
14493 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14498 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14501 generate_exception(ctx
, EXCP_RI
);
14505 case OPC_MOVN
: /* Conditional move */
14507 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14508 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14509 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14511 case OPC_ADD
... OPC_SUBU
:
14512 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14514 case OPC_SLLV
: /* Shifts */
14516 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14519 switch ((ctx
->opcode
>> 6) & 0x1f) {
14521 /* rotrv is decoded as srlv on non-R2 CPUs */
14522 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14527 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14530 generate_exception(ctx
, EXCP_RI
);
14534 case OPC_SLT
: /* Set on less than */
14536 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14538 case OPC_AND
: /* Logic*/
14542 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14547 check_insn(ctx
, INSN_VR54XX
);
14548 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14549 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14551 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14556 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14558 case OPC_JR
... OPC_JALR
:
14559 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14561 case OPC_TGE
... OPC_TEQ
: /* Traps */
14563 gen_trap(ctx
, op1
, rs
, rt
, -1);
14565 case OPC_MFHI
: /* Move from HI/LO */
14567 gen_HILO(ctx
, op1
, rs
& 3, rd
);
14570 case OPC_MTLO
: /* Move to HI/LO */
14571 gen_HILO(ctx
, op1
, rd
& 3, rs
);
14573 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14574 #ifdef MIPS_STRICT_STANDARD
14575 MIPS_INVAL("PMON / selsl");
14576 generate_exception(ctx
, EXCP_RI
);
14578 gen_helper_0e0i(pmon
, sa
);
14582 generate_exception(ctx
, EXCP_SYSCALL
);
14583 ctx
->bstate
= BS_STOP
;
14586 generate_exception(ctx
, EXCP_BREAK
);
14589 #ifdef MIPS_STRICT_STANDARD
14590 MIPS_INVAL("SPIM");
14591 generate_exception(ctx
, EXCP_RI
);
14593 /* Implemented as RI exception for now. */
14594 MIPS_INVAL("spim (unofficial)");
14595 generate_exception(ctx
, EXCP_RI
);
14599 /* Treat as NOP. */
14603 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14604 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
14605 check_cp1_enabled(ctx
);
14606 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14607 (ctx
->opcode
>> 16) & 1);
14609 generate_exception_err(ctx
, EXCP_CpU
, 1);
14613 #if defined(TARGET_MIPS64)
14614 /* MIPS64 specific opcodes */
14619 check_insn(ctx
, ISA_MIPS3
);
14620 check_mips_64(ctx
);
14621 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14624 switch ((ctx
->opcode
>> 21) & 0x1f) {
14626 /* drotr is decoded as dsrl on non-R2 CPUs */
14627 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14632 check_insn(ctx
, ISA_MIPS3
);
14633 check_mips_64(ctx
);
14634 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14637 generate_exception(ctx
, EXCP_RI
);
14642 switch ((ctx
->opcode
>> 21) & 0x1f) {
14644 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14645 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14650 check_insn(ctx
, ISA_MIPS3
);
14651 check_mips_64(ctx
);
14652 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14655 generate_exception(ctx
, EXCP_RI
);
14659 case OPC_DADD
... OPC_DSUBU
:
14660 check_insn(ctx
, ISA_MIPS3
);
14661 check_mips_64(ctx
);
14662 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14666 check_insn(ctx
, ISA_MIPS3
);
14667 check_mips_64(ctx
);
14668 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14671 switch ((ctx
->opcode
>> 6) & 0x1f) {
14673 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14674 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14679 check_insn(ctx
, ISA_MIPS3
);
14680 check_mips_64(ctx
);
14681 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14684 generate_exception(ctx
, EXCP_RI
);
14688 case OPC_DMULT
... OPC_DDIVU
:
14689 check_insn(ctx
, ISA_MIPS3
);
14690 check_mips_64(ctx
);
14691 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14694 default: /* Invalid */
14695 MIPS_INVAL("special");
14696 generate_exception(ctx
, EXCP_RI
);
14701 op1
= MASK_SPECIAL2(ctx
->opcode
);
14703 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14704 case OPC_MSUB
... OPC_MSUBU
:
14705 check_insn(ctx
, ISA_MIPS32
);
14706 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14709 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14713 check_insn(ctx
, ISA_MIPS32
);
14714 gen_cl(ctx
, op1
, rd
, rs
);
14717 /* XXX: not clear which exception should be raised
14718 * when in debug mode...
14720 check_insn(ctx
, ISA_MIPS32
);
14721 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14722 generate_exception(ctx
, EXCP_DBp
);
14724 generate_exception(ctx
, EXCP_DBp
);
14726 /* Treat as NOP. */
14729 case OPC_DIVU_G_2F
:
14730 case OPC_MULT_G_2F
:
14731 case OPC_MULTU_G_2F
:
14733 case OPC_MODU_G_2F
:
14734 check_insn(ctx
, INSN_LOONGSON2F
);
14735 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14737 #if defined(TARGET_MIPS64)
14740 check_insn(ctx
, ISA_MIPS64
);
14741 check_mips_64(ctx
);
14742 gen_cl(ctx
, op1
, rd
, rs
);
14744 case OPC_DMULT_G_2F
:
14745 case OPC_DMULTU_G_2F
:
14746 case OPC_DDIV_G_2F
:
14747 case OPC_DDIVU_G_2F
:
14748 case OPC_DMOD_G_2F
:
14749 case OPC_DMODU_G_2F
:
14750 check_insn(ctx
, INSN_LOONGSON2F
);
14751 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14754 default: /* Invalid */
14755 MIPS_INVAL("special2");
14756 generate_exception(ctx
, EXCP_RI
);
14761 op1
= MASK_SPECIAL3(ctx
->opcode
);
14765 check_insn(ctx
, ISA_MIPS32R2
);
14766 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14769 check_insn(ctx
, ISA_MIPS32R2
);
14770 op2
= MASK_BSHFL(ctx
->opcode
);
14771 gen_bshfl(ctx
, op2
, rt
, rd
);
14774 gen_rdhwr(ctx
, rt
, rd
);
14777 check_insn(ctx
, ASE_MT
);
14779 TCGv t0
= tcg_temp_new();
14780 TCGv t1
= tcg_temp_new();
14782 gen_load_gpr(t0
, rt
);
14783 gen_load_gpr(t1
, rs
);
14784 gen_helper_fork(t0
, t1
);
14790 check_insn(ctx
, ASE_MT
);
14792 TCGv t0
= tcg_temp_new();
14794 save_cpu_state(ctx
, 1);
14795 gen_load_gpr(t0
, rs
);
14796 gen_helper_yield(t0
, cpu_env
, t0
);
14797 gen_store_gpr(t0
, rd
);
14801 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14802 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14803 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14804 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14805 * the same mask and op1. */
14806 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14807 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14810 case OPC_ADDUH_R_QB
:
14812 case OPC_ADDQH_R_PH
:
14814 case OPC_ADDQH_R_W
:
14816 case OPC_SUBUH_R_QB
:
14818 case OPC_SUBQH_R_PH
:
14820 case OPC_SUBQH_R_W
:
14821 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14826 case OPC_MULQ_RS_W
:
14827 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14830 MIPS_INVAL("MASK ADDUH.QB");
14831 generate_exception(ctx
, EXCP_RI
);
14834 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14835 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14837 generate_exception(ctx
, EXCP_RI
);
14841 op2
= MASK_LX(ctx
->opcode
);
14843 #if defined(TARGET_MIPS64)
14849 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14851 default: /* Invalid */
14852 MIPS_INVAL("MASK LX");
14853 generate_exception(ctx
, EXCP_RI
);
14857 case OPC_ABSQ_S_PH_DSP
:
14858 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14860 case OPC_ABSQ_S_QB
:
14861 case OPC_ABSQ_S_PH
:
14863 case OPC_PRECEQ_W_PHL
:
14864 case OPC_PRECEQ_W_PHR
:
14865 case OPC_PRECEQU_PH_QBL
:
14866 case OPC_PRECEQU_PH_QBR
:
14867 case OPC_PRECEQU_PH_QBLA
:
14868 case OPC_PRECEQU_PH_QBRA
:
14869 case OPC_PRECEU_PH_QBL
:
14870 case OPC_PRECEU_PH_QBR
:
14871 case OPC_PRECEU_PH_QBLA
:
14872 case OPC_PRECEU_PH_QBRA
:
14873 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14880 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14883 MIPS_INVAL("MASK ABSQ_S.PH");
14884 generate_exception(ctx
, EXCP_RI
);
14888 case OPC_ADDU_QB_DSP
:
14889 op2
= MASK_ADDU_QB(ctx
->opcode
);
14892 case OPC_ADDQ_S_PH
:
14895 case OPC_ADDU_S_QB
:
14897 case OPC_ADDU_S_PH
:
14899 case OPC_SUBQ_S_PH
:
14902 case OPC_SUBU_S_QB
:
14904 case OPC_SUBU_S_PH
:
14908 case OPC_RADDU_W_QB
:
14909 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14911 case OPC_MULEU_S_PH_QBL
:
14912 case OPC_MULEU_S_PH_QBR
:
14913 case OPC_MULQ_RS_PH
:
14914 case OPC_MULEQ_S_W_PHL
:
14915 case OPC_MULEQ_S_W_PHR
:
14916 case OPC_MULQ_S_PH
:
14917 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14919 default: /* Invalid */
14920 MIPS_INVAL("MASK ADDU.QB");
14921 generate_exception(ctx
, EXCP_RI
);
14926 case OPC_CMPU_EQ_QB_DSP
:
14927 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14929 case OPC_PRECR_SRA_PH_W
:
14930 case OPC_PRECR_SRA_R_PH_W
:
14931 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14933 case OPC_PRECR_QB_PH
:
14934 case OPC_PRECRQ_QB_PH
:
14935 case OPC_PRECRQ_PH_W
:
14936 case OPC_PRECRQ_RS_PH_W
:
14937 case OPC_PRECRQU_S_QB_PH
:
14938 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14940 case OPC_CMPU_EQ_QB
:
14941 case OPC_CMPU_LT_QB
:
14942 case OPC_CMPU_LE_QB
:
14943 case OPC_CMP_EQ_PH
:
14944 case OPC_CMP_LT_PH
:
14945 case OPC_CMP_LE_PH
:
14946 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14948 case OPC_CMPGU_EQ_QB
:
14949 case OPC_CMPGU_LT_QB
:
14950 case OPC_CMPGU_LE_QB
:
14951 case OPC_CMPGDU_EQ_QB
:
14952 case OPC_CMPGDU_LT_QB
:
14953 case OPC_CMPGDU_LE_QB
:
14956 case OPC_PACKRL_PH
:
14957 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14959 default: /* Invalid */
14960 MIPS_INVAL("MASK CMPU.EQ.QB");
14961 generate_exception(ctx
, EXCP_RI
);
14965 case OPC_SHLL_QB_DSP
:
14966 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14968 case OPC_DPA_W_PH_DSP
:
14969 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14971 case OPC_DPAU_H_QBL
:
14972 case OPC_DPAU_H_QBR
:
14973 case OPC_DPSU_H_QBL
:
14974 case OPC_DPSU_H_QBR
:
14976 case OPC_DPAX_W_PH
:
14977 case OPC_DPAQ_S_W_PH
:
14978 case OPC_DPAQX_S_W_PH
:
14979 case OPC_DPAQX_SA_W_PH
:
14981 case OPC_DPSX_W_PH
:
14982 case OPC_DPSQ_S_W_PH
:
14983 case OPC_DPSQX_S_W_PH
:
14984 case OPC_DPSQX_SA_W_PH
:
14985 case OPC_MULSAQ_S_W_PH
:
14986 case OPC_DPAQ_SA_L_W
:
14987 case OPC_DPSQ_SA_L_W
:
14988 case OPC_MAQ_S_W_PHL
:
14989 case OPC_MAQ_S_W_PHR
:
14990 case OPC_MAQ_SA_W_PHL
:
14991 case OPC_MAQ_SA_W_PHR
:
14992 case OPC_MULSA_W_PH
:
14993 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14995 default: /* Invalid */
14996 MIPS_INVAL("MASK DPAW.PH");
14997 generate_exception(ctx
, EXCP_RI
);
15002 op2
= MASK_INSV(ctx
->opcode
);
15014 t0
= tcg_temp_new();
15015 t1
= tcg_temp_new();
15017 gen_load_gpr(t0
, rt
);
15018 gen_load_gpr(t1
, rs
);
15020 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15026 default: /* Invalid */
15027 MIPS_INVAL("MASK INSV");
15028 generate_exception(ctx
, EXCP_RI
);
15032 case OPC_APPEND_DSP
:
15033 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15035 case OPC_EXTR_W_DSP
:
15036 op2
= MASK_EXTR_W(ctx
->opcode
);
15040 case OPC_EXTR_RS_W
:
15042 case OPC_EXTRV_S_H
:
15044 case OPC_EXTRV_R_W
:
15045 case OPC_EXTRV_RS_W
:
15050 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15053 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15059 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15061 default: /* Invalid */
15062 MIPS_INVAL("MASK EXTR.W");
15063 generate_exception(ctx
, EXCP_RI
);
15067 #if defined(TARGET_MIPS64)
15068 case OPC_DEXTM
... OPC_DEXT
:
15069 case OPC_DINSM
... OPC_DINS
:
15070 check_insn(ctx
, ISA_MIPS64R2
);
15071 check_mips_64(ctx
);
15072 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
15075 check_insn(ctx
, ISA_MIPS64R2
);
15076 check_mips_64(ctx
);
15077 op2
= MASK_DBSHFL(ctx
->opcode
);
15078 gen_bshfl(ctx
, op2
, rt
, rd
);
15080 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
15081 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
15082 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
15083 check_insn(ctx
, INSN_LOONGSON2E
);
15084 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
15086 case OPC_ABSQ_S_QH_DSP
:
15087 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
15089 case OPC_PRECEQ_L_PWL
:
15090 case OPC_PRECEQ_L_PWR
:
15091 case OPC_PRECEQ_PW_QHL
:
15092 case OPC_PRECEQ_PW_QHR
:
15093 case OPC_PRECEQ_PW_QHLA
:
15094 case OPC_PRECEQ_PW_QHRA
:
15095 case OPC_PRECEQU_QH_OBL
:
15096 case OPC_PRECEQU_QH_OBR
:
15097 case OPC_PRECEQU_QH_OBLA
:
15098 case OPC_PRECEQU_QH_OBRA
:
15099 case OPC_PRECEU_QH_OBL
:
15100 case OPC_PRECEU_QH_OBR
:
15101 case OPC_PRECEU_QH_OBLA
:
15102 case OPC_PRECEU_QH_OBRA
:
15103 case OPC_ABSQ_S_OB
:
15104 case OPC_ABSQ_S_PW
:
15105 case OPC_ABSQ_S_QH
:
15106 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15114 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
15116 default: /* Invalid */
15117 MIPS_INVAL("MASK ABSQ_S.QH");
15118 generate_exception(ctx
, EXCP_RI
);
15122 case OPC_ADDU_OB_DSP
:
15123 op2
= MASK_ADDU_OB(ctx
->opcode
);
15125 case OPC_RADDU_L_OB
:
15127 case OPC_SUBQ_S_PW
:
15129 case OPC_SUBQ_S_QH
:
15131 case OPC_SUBU_S_OB
:
15133 case OPC_SUBU_S_QH
:
15135 case OPC_SUBUH_R_OB
:
15137 case OPC_ADDQ_S_PW
:
15139 case OPC_ADDQ_S_QH
:
15141 case OPC_ADDU_S_OB
:
15143 case OPC_ADDU_S_QH
:
15145 case OPC_ADDUH_R_OB
:
15146 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15148 case OPC_MULEQ_S_PW_QHL
:
15149 case OPC_MULEQ_S_PW_QHR
:
15150 case OPC_MULEU_S_QH_OBL
:
15151 case OPC_MULEU_S_QH_OBR
:
15152 case OPC_MULQ_RS_QH
:
15153 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15155 default: /* Invalid */
15156 MIPS_INVAL("MASK ADDU.OB");
15157 generate_exception(ctx
, EXCP_RI
);
15161 case OPC_CMPU_EQ_OB_DSP
:
15162 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15164 case OPC_PRECR_SRA_QH_PW
:
15165 case OPC_PRECR_SRA_R_QH_PW
:
15166 /* Return value is rt. */
15167 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15169 case OPC_PRECR_OB_QH
:
15170 case OPC_PRECRQ_OB_QH
:
15171 case OPC_PRECRQ_PW_L
:
15172 case OPC_PRECRQ_QH_PW
:
15173 case OPC_PRECRQ_RS_QH_PW
:
15174 case OPC_PRECRQU_S_OB_QH
:
15175 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15177 case OPC_CMPU_EQ_OB
:
15178 case OPC_CMPU_LT_OB
:
15179 case OPC_CMPU_LE_OB
:
15180 case OPC_CMP_EQ_QH
:
15181 case OPC_CMP_LT_QH
:
15182 case OPC_CMP_LE_QH
:
15183 case OPC_CMP_EQ_PW
:
15184 case OPC_CMP_LT_PW
:
15185 case OPC_CMP_LE_PW
:
15186 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15188 case OPC_CMPGDU_EQ_OB
:
15189 case OPC_CMPGDU_LT_OB
:
15190 case OPC_CMPGDU_LE_OB
:
15191 case OPC_CMPGU_EQ_OB
:
15192 case OPC_CMPGU_LT_OB
:
15193 case OPC_CMPGU_LE_OB
:
15194 case OPC_PACKRL_PW
:
15198 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15200 default: /* Invalid */
15201 MIPS_INVAL("MASK CMPU_EQ.OB");
15202 generate_exception(ctx
, EXCP_RI
);
15206 case OPC_DAPPEND_DSP
:
15207 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15209 case OPC_DEXTR_W_DSP
:
15210 op2
= MASK_DEXTR_W(ctx
->opcode
);
15217 case OPC_DEXTR_R_L
:
15218 case OPC_DEXTR_RS_L
:
15220 case OPC_DEXTR_R_W
:
15221 case OPC_DEXTR_RS_W
:
15222 case OPC_DEXTR_S_H
:
15224 case OPC_DEXTRV_R_L
:
15225 case OPC_DEXTRV_RS_L
:
15226 case OPC_DEXTRV_S_H
:
15228 case OPC_DEXTRV_R_W
:
15229 case OPC_DEXTRV_RS_W
:
15230 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15235 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15237 default: /* Invalid */
15238 MIPS_INVAL("MASK EXTR.W");
15239 generate_exception(ctx
, EXCP_RI
);
15243 case OPC_DPAQ_W_QH_DSP
:
15244 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15246 case OPC_DPAU_H_OBL
:
15247 case OPC_DPAU_H_OBR
:
15248 case OPC_DPSU_H_OBL
:
15249 case OPC_DPSU_H_OBR
:
15251 case OPC_DPAQ_S_W_QH
:
15253 case OPC_DPSQ_S_W_QH
:
15254 case OPC_MULSAQ_S_W_QH
:
15255 case OPC_DPAQ_SA_L_PW
:
15256 case OPC_DPSQ_SA_L_PW
:
15257 case OPC_MULSAQ_S_L_PW
:
15258 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15260 case OPC_MAQ_S_W_QHLL
:
15261 case OPC_MAQ_S_W_QHLR
:
15262 case OPC_MAQ_S_W_QHRL
:
15263 case OPC_MAQ_S_W_QHRR
:
15264 case OPC_MAQ_SA_W_QHLL
:
15265 case OPC_MAQ_SA_W_QHLR
:
15266 case OPC_MAQ_SA_W_QHRL
:
15267 case OPC_MAQ_SA_W_QHRR
:
15268 case OPC_MAQ_S_L_PWL
:
15269 case OPC_MAQ_S_L_PWR
:
15274 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15276 default: /* Invalid */
15277 MIPS_INVAL("MASK DPAQ.W.QH");
15278 generate_exception(ctx
, EXCP_RI
);
15282 case OPC_DINSV_DSP
:
15283 op2
= MASK_INSV(ctx
->opcode
);
15295 t0
= tcg_temp_new();
15296 t1
= tcg_temp_new();
15298 gen_load_gpr(t0
, rt
);
15299 gen_load_gpr(t1
, rs
);
15301 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15304 default: /* Invalid */
15305 MIPS_INVAL("MASK DINSV");
15306 generate_exception(ctx
, EXCP_RI
);
15310 case OPC_SHLL_OB_DSP
:
15311 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15314 default: /* Invalid */
15315 MIPS_INVAL("special3");
15316 generate_exception(ctx
, EXCP_RI
);
15321 op1
= MASK_REGIMM(ctx
->opcode
);
15323 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15324 case OPC_BLTZAL
... OPC_BGEZALL
:
15325 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15327 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15329 gen_trap(ctx
, op1
, rs
, -1, imm
);
15332 check_insn(ctx
, ISA_MIPS32R2
);
15333 /* Treat as NOP. */
15335 case OPC_BPOSGE32
: /* MIPS DSP branch */
15336 #if defined(TARGET_MIPS64)
15340 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15342 default: /* Invalid */
15343 MIPS_INVAL("regimm");
15344 generate_exception(ctx
, EXCP_RI
);
15349 check_cp0_enabled(ctx
);
15350 op1
= MASK_CP0(ctx
->opcode
);
15356 #if defined(TARGET_MIPS64)
15360 #ifndef CONFIG_USER_ONLY
15361 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15362 #endif /* !CONFIG_USER_ONLY */
15364 case OPC_C0_FIRST
... OPC_C0_LAST
:
15365 #ifndef CONFIG_USER_ONLY
15366 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15367 #endif /* !CONFIG_USER_ONLY */
15370 #ifndef CONFIG_USER_ONLY
15372 TCGv t0
= tcg_temp_new();
15374 op2
= MASK_MFMC0(ctx
->opcode
);
15377 check_insn(ctx
, ASE_MT
);
15378 gen_helper_dmt(t0
);
15379 gen_store_gpr(t0
, rt
);
15382 check_insn(ctx
, ASE_MT
);
15383 gen_helper_emt(t0
);
15384 gen_store_gpr(t0
, rt
);
15387 check_insn(ctx
, ASE_MT
);
15388 gen_helper_dvpe(t0
, cpu_env
);
15389 gen_store_gpr(t0
, rt
);
15392 check_insn(ctx
, ASE_MT
);
15393 gen_helper_evpe(t0
, cpu_env
);
15394 gen_store_gpr(t0
, rt
);
15397 check_insn(ctx
, ISA_MIPS32R2
);
15398 save_cpu_state(ctx
, 1);
15399 gen_helper_di(t0
, cpu_env
);
15400 gen_store_gpr(t0
, rt
);
15401 /* Stop translation as we may have switched the execution mode */
15402 ctx
->bstate
= BS_STOP
;
15405 check_insn(ctx
, ISA_MIPS32R2
);
15406 save_cpu_state(ctx
, 1);
15407 gen_helper_ei(t0
, cpu_env
);
15408 gen_store_gpr(t0
, rt
);
15409 /* Stop translation as we may have switched the execution mode */
15410 ctx
->bstate
= BS_STOP
;
15412 default: /* Invalid */
15413 MIPS_INVAL("mfmc0");
15414 generate_exception(ctx
, EXCP_RI
);
15419 #endif /* !CONFIG_USER_ONLY */
15422 check_insn(ctx
, ISA_MIPS32R2
);
15423 gen_load_srsgpr(rt
, rd
);
15426 check_insn(ctx
, ISA_MIPS32R2
);
15427 gen_store_srsgpr(rt
, rd
);
15431 generate_exception(ctx
, EXCP_RI
);
15435 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15437 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15439 case OPC_SLTI
: /* Set on less than with immediate opcode */
15441 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15443 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15447 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15449 case OPC_J
... OPC_JAL
: /* Jump */
15450 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15451 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15453 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15454 case OPC_BEQL
... OPC_BGTZL
:
15455 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15457 case OPC_LB
... OPC_LWR
: /* Load and stores */
15459 gen_ld(ctx
, op
, rt
, rs
, imm
);
15461 case OPC_SB
... OPC_SW
:
15463 gen_st(ctx
, op
, rt
, rs
, imm
);
15466 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15469 check_cp0_enabled(ctx
);
15470 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15471 /* Treat as NOP. */
15474 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15475 /* Treat as NOP. */
15478 /* Floating point (COP1). */
15483 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
15487 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15488 check_cp1_enabled(ctx
);
15489 op1
= MASK_CP1(ctx
->opcode
);
15493 check_insn(ctx
, ISA_MIPS32R2
);
15498 gen_cp1(ctx
, op1
, rt
, rd
);
15500 #if defined(TARGET_MIPS64)
15503 check_insn(ctx
, ISA_MIPS3
);
15504 gen_cp1(ctx
, op1
, rt
, rd
);
15510 check_insn(ctx
, ASE_MIPS3D
);
15513 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15514 (rt
>> 2) & 0x7, imm
<< 2);
15521 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15526 generate_exception (ctx
, EXCP_RI
);
15530 generate_exception_err(ctx
, EXCP_CpU
, 1);
15539 /* COP2: Not implemented. */
15540 generate_exception_err(ctx
, EXCP_CpU
, 2);
15543 check_insn(ctx
, INSN_LOONGSON2F
);
15544 /* Note that these instructions use different fields. */
15545 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15549 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15550 check_cp1_enabled(ctx
);
15551 op1
= MASK_CP3(ctx
->opcode
);
15559 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15562 /* Treat as NOP. */
15577 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15581 generate_exception (ctx
, EXCP_RI
);
15585 generate_exception_err(ctx
, EXCP_CpU
, 1);
15589 #if defined(TARGET_MIPS64)
15590 /* MIPS64 opcodes */
15592 case OPC_LDL
... OPC_LDR
:
15595 check_insn(ctx
, ISA_MIPS3
);
15596 check_mips_64(ctx
);
15597 gen_ld(ctx
, op
, rt
, rs
, imm
);
15599 case OPC_SDL
... OPC_SDR
:
15601 check_insn(ctx
, ISA_MIPS3
);
15602 check_mips_64(ctx
);
15603 gen_st(ctx
, op
, rt
, rs
, imm
);
15606 check_insn(ctx
, ISA_MIPS3
);
15607 check_mips_64(ctx
);
15608 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15612 check_insn(ctx
, ISA_MIPS3
);
15613 check_mips_64(ctx
);
15614 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15618 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15619 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15620 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15623 check_insn(ctx
, ASE_MDMX
);
15624 /* MDMX: Not implemented. */
15625 default: /* Invalid */
15626 MIPS_INVAL("major opcode");
15627 generate_exception(ctx
, EXCP_RI
);
15633 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
15636 CPUState
*cs
= CPU(cpu
);
15637 CPUMIPSState
*env
= &cpu
->env
;
15639 target_ulong pc_start
;
15640 uint16_t *gen_opc_end
;
15649 qemu_log("search pc %d\n", search_pc
);
15652 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15655 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
15656 ctx
.insn_flags
= env
->insn_flags
;
15657 ctx
.CP0_Config1
= env
->CP0_Config1
;
15659 ctx
.bstate
= BS_NONE
;
15660 /* Restore delay slot state from the tb context. */
15661 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15662 ctx
.ulri
= env
->CP0_Config3
& (1 << CP0C3_ULRI
);
15663 restore_cpu_state(env
, &ctx
);
15664 #ifdef CONFIG_USER_ONLY
15665 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15667 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15670 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15671 if (max_insns
== 0)
15672 max_insns
= CF_COUNT_MASK
;
15673 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15675 while (ctx
.bstate
== BS_NONE
) {
15676 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
15677 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
15678 if (bp
->pc
== ctx
.pc
) {
15679 save_cpu_state(&ctx
, 1);
15680 ctx
.bstate
= BS_BRANCH
;
15681 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15682 /* Include the breakpoint location or the tb won't
15683 * be flushed when it must be. */
15685 goto done_generating
;
15691 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15695 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15697 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15698 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15699 gen_opc_btarget
[lj
] = ctx
.btarget
;
15700 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15701 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15703 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15706 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
15707 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15708 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15710 decode_opc(env
, &ctx
);
15711 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15712 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15713 insn_bytes
= decode_micromips_opc(env
, &ctx
);
15714 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15715 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15716 insn_bytes
= decode_mips16_opc(env
, &ctx
);
15718 generate_exception(&ctx
, EXCP_RI
);
15719 ctx
.bstate
= BS_STOP
;
15723 handle_delay_slot(&ctx
, insn_bytes
);
15725 ctx
.pc
+= insn_bytes
;
15729 /* Execute a branch and its delay slot as a single instruction.
15730 This is what GDB expects and is consistent with what the
15731 hardware does (e.g. if a delay slot instruction faults, the
15732 reported PC is the PC of the branch). */
15733 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
15737 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15740 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15744 if (num_insns
>= max_insns
)
15750 if (tb
->cflags
& CF_LAST_IO
) {
15753 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15754 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15755 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15757 switch (ctx
.bstate
) {
15759 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15762 save_cpu_state(&ctx
, 0);
15763 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15766 tcg_gen_exit_tb(0);
15774 gen_tb_end(tb
, num_insns
);
15775 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15777 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15780 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15782 tb
->size
= ctx
.pc
- pc_start
;
15783 tb
->icount
= num_insns
;
15787 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15788 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15789 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15795 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15797 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
15800 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15802 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
15805 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15809 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15811 #define printfpr(fp) \
15814 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15815 " fd:%13g fs:%13g psu: %13g\n", \
15816 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15817 (double)(fp)->fd, \
15818 (double)(fp)->fs[FP_ENDIAN_IDX], \
15819 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15822 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15823 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15824 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15825 " fd:%13g fs:%13g psu:%13g\n", \
15826 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15828 (double)tmp.fs[FP_ENDIAN_IDX], \
15829 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15834 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15835 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15836 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15837 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15838 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15839 printfpr(&env
->active_fpu
.fpr
[i
]);
15845 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15846 /* Debug help: The architecture requires 32bit code to maintain proper
15847 sign-extended values on 64bit machines. */
15849 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15852 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15853 fprintf_function cpu_fprintf
,
15858 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15859 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15860 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15861 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15862 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15863 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15864 if (!SIGN_EXT_P(env
->btarget
))
15865 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15867 for (i
= 0; i
< 32; i
++) {
15868 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15869 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15872 if (!SIGN_EXT_P(env
->CP0_EPC
))
15873 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15874 if (!SIGN_EXT_P(env
->lladdr
))
15875 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15879 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
15882 MIPSCPU
*cpu
= MIPS_CPU(cs
);
15883 CPUMIPSState
*env
= &cpu
->env
;
15886 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15887 " LO=0x" TARGET_FMT_lx
" ds %04x "
15888 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15889 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15890 env
->hflags
, env
->btarget
, env
->bcond
);
15891 for (i
= 0; i
< 32; i
++) {
15893 cpu_fprintf(f
, "GPR%02d:", i
);
15894 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15896 cpu_fprintf(f
, "\n");
15899 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15900 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15901 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15902 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15903 if (env
->hflags
& MIPS_HFLAG_FPU
)
15904 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15905 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15906 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15910 void mips_tcg_init(void)
15915 /* Initialize various static tables. */
15919 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15920 TCGV_UNUSED(cpu_gpr
[0]);
15921 for (i
= 1; i
< 32; i
++)
15922 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15923 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15926 for (i
= 0; i
< 32; i
++) {
15927 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15928 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15931 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15932 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15933 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15934 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15935 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15937 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15938 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15940 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15941 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15944 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15945 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15947 bcond
= tcg_global_mem_new(TCG_AREG0
,
15948 offsetof(CPUMIPSState
, bcond
), "bcond");
15949 btarget
= tcg_global_mem_new(TCG_AREG0
,
15950 offsetof(CPUMIPSState
, btarget
), "btarget");
15951 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15952 offsetof(CPUMIPSState
, hflags
), "hflags");
15954 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15955 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15957 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15958 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15964 #include "translate_init.c"
15966 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15970 const mips_def_t
*def
;
15972 def
= cpu_mips_find_by_name(cpu_model
);
15975 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15977 env
->cpu_model
= def
;
15979 #ifndef CONFIG_USER_ONLY
15980 mmu_init(env
, def
);
15982 fpu_init(env
, def
);
15983 mvp_init(env
, def
);
15985 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15990 void cpu_state_reset(CPUMIPSState
*env
)
15992 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
15993 CPUState
*cs
= CPU(cpu
);
15995 /* Reset registers to their default values */
15996 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15997 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15998 #ifdef TARGET_WORDS_BIGENDIAN
15999 env
->CP0_Config0
|= (1 << CP0C0_BE
);
16001 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
16002 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
16003 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
16004 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
16005 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
16006 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
16007 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
16008 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
16009 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
16010 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
16011 << env
->cpu_model
->CP0_LLAddr_shift
;
16012 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
16013 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
16014 env
->CCRes
= env
->cpu_model
->CCRes
;
16015 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
16016 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
16017 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
16018 env
->current_tc
= 0;
16019 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
16020 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
16021 #if defined(TARGET_MIPS64)
16022 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
16023 env
->SEGMask
|= 3ULL << 62;
16026 env
->PABITS
= env
->cpu_model
->PABITS
;
16027 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
16028 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
16029 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
16030 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
16031 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
16032 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
16033 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
16034 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
16035 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
16036 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
16037 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
16038 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
16039 env
->insn_flags
= env
->cpu_model
->insn_flags
;
16041 #if defined(CONFIG_USER_ONLY)
16042 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
16043 # ifdef TARGET_MIPS64
16044 /* Enable 64-bit register mode. */
16045 env
->CP0_Status
|= (1 << CP0St_PX
);
16047 # ifdef TARGET_ABI_MIPSN64
16048 /* Enable 64-bit address mode. */
16049 env
->CP0_Status
|= (1 << CP0St_UX
);
16051 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16052 hardware registers. */
16053 env
->CP0_HWREna
|= 0x0000000F;
16054 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16055 env
->CP0_Status
|= (1 << CP0St_CU1
);
16057 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
16058 env
->CP0_Status
|= (1 << CP0St_MX
);
16060 # if defined(TARGET_MIPS64)
16061 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16062 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
16063 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
16064 env
->CP0_Status
|= (1 << CP0St_FR
);
16068 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
16069 /* If the exception was raised from a delay slot,
16070 come back to the jump. */
16071 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
16073 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
16075 env
->active_tc
.PC
= (int32_t)0xBFC00000;
16076 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
16077 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
16078 env
->CP0_Wired
= 0;
16079 env
->CP0_EBase
= 0x80000000 | (cs
->cpu_index
& 0x3FF);
16080 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
16081 /* vectored interrupts not implemented, timer on int 7,
16082 no performance counters. */
16083 env
->CP0_IntCtl
= 0xe0000000;
16087 for (i
= 0; i
< 7; i
++) {
16088 env
->CP0_WatchLo
[i
] = 0;
16089 env
->CP0_WatchHi
[i
] = 0x80000000;
16091 env
->CP0_WatchLo
[7] = 0;
16092 env
->CP0_WatchHi
[7] = 0;
16094 /* Count register increments in debug mode, EJTAG version 1 */
16095 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
16097 cpu_mips_store_count(env
, 1);
16099 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
16102 /* Only TC0 on VPE 0 starts as active. */
16103 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
16104 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
16105 env
->tcs
[i
].CP0_TCHalt
= 1;
16107 env
->active_tc
.CP0_TCHalt
= 1;
16110 if (cs
->cpu_index
== 0) {
16111 /* VPE0 starts up enabled. */
16112 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
16113 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
16115 /* TC0 starts up unhalted. */
16117 env
->active_tc
.CP0_TCHalt
= 0;
16118 env
->tcs
[0].CP0_TCHalt
= 0;
16119 /* With thread 0 active. */
16120 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
16121 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16125 compute_hflags(env
);
16126 cs
->exception_index
= EXCP_NONE
;
16129 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16131 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16132 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16133 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16134 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16135 case MIPS_HFLAG_BR
:
16137 case MIPS_HFLAG_BC
:
16138 case MIPS_HFLAG_BL
:
16140 env
->btarget
= gen_opc_btarget
[pc_pos
];