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"
28 #include "exec/helper-proto.h"
29 #include "exec/helper-gen.h"
31 #define MIPS_DEBUG_DISAS 0
32 //#define MIPS_DEBUG_SIGN_EXTENSIONS
34 /* MIPS major opcodes */
35 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
38 /* indirect opcode tables */
39 OPC_SPECIAL
= (0x00 << 26),
40 OPC_REGIMM
= (0x01 << 26),
41 OPC_CP0
= (0x10 << 26),
42 OPC_CP1
= (0x11 << 26),
43 OPC_CP2
= (0x12 << 26),
44 OPC_CP3
= (0x13 << 26),
45 OPC_SPECIAL2
= (0x1C << 26),
46 OPC_SPECIAL3
= (0x1F << 26),
47 /* arithmetic with immediate */
48 OPC_ADDI
= (0x08 << 26),
49 OPC_ADDIU
= (0x09 << 26),
50 OPC_SLTI
= (0x0A << 26),
51 OPC_SLTIU
= (0x0B << 26),
52 /* logic with immediate */
53 OPC_ANDI
= (0x0C << 26),
54 OPC_ORI
= (0x0D << 26),
55 OPC_XORI
= (0x0E << 26),
56 OPC_LUI
= (0x0F << 26),
57 /* arithmetic with immediate */
58 OPC_DADDI
= (0x18 << 26),
59 OPC_DADDIU
= (0x19 << 26),
60 /* Jump and branches */
62 OPC_JAL
= (0x03 << 26),
63 OPC_JALS
= OPC_JAL
| 0x5,
64 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
65 OPC_BEQL
= (0x14 << 26),
66 OPC_BNE
= (0x05 << 26),
67 OPC_BNEL
= (0x15 << 26),
68 OPC_BLEZ
= (0x06 << 26),
69 OPC_BLEZL
= (0x16 << 26),
70 OPC_BGTZ
= (0x07 << 26),
71 OPC_BGTZL
= (0x17 << 26),
72 OPC_JALX
= (0x1D << 26), /* MIPS 16 only */
73 OPC_JALXS
= OPC_JALX
| 0x5,
75 OPC_LDL
= (0x1A << 26),
76 OPC_LDR
= (0x1B << 26),
77 OPC_LB
= (0x20 << 26),
78 OPC_LH
= (0x21 << 26),
79 OPC_LWL
= (0x22 << 26),
80 OPC_LW
= (0x23 << 26),
81 OPC_LWPC
= OPC_LW
| 0x5,
82 OPC_LBU
= (0x24 << 26),
83 OPC_LHU
= (0x25 << 26),
84 OPC_LWR
= (0x26 << 26),
85 OPC_LWU
= (0x27 << 26),
86 OPC_SB
= (0x28 << 26),
87 OPC_SH
= (0x29 << 26),
88 OPC_SWL
= (0x2A << 26),
89 OPC_SW
= (0x2B << 26),
90 OPC_SDL
= (0x2C << 26),
91 OPC_SDR
= (0x2D << 26),
92 OPC_SWR
= (0x2E << 26),
93 OPC_LL
= (0x30 << 26),
94 OPC_LLD
= (0x34 << 26),
95 OPC_LD
= (0x37 << 26),
96 OPC_LDPC
= OPC_LD
| 0x5,
97 OPC_SC
= (0x38 << 26),
98 OPC_SCD
= (0x3C << 26),
99 OPC_SD
= (0x3F << 26),
100 /* Floating point load/store */
101 OPC_LWC1
= (0x31 << 26),
102 OPC_LWC2
= (0x32 << 26),
103 OPC_LDC1
= (0x35 << 26),
104 OPC_LDC2
= (0x36 << 26),
105 OPC_SWC1
= (0x39 << 26),
106 OPC_SWC2
= (0x3A << 26),
107 OPC_SDC1
= (0x3D << 26),
108 OPC_SDC2
= (0x3E << 26),
109 /* MDMX ASE specific */
110 OPC_MDMX
= (0x1E << 26),
111 /* Cache and prefetch */
112 OPC_CACHE
= (0x2F << 26),
113 OPC_PREF
= (0x33 << 26),
114 /* Reserved major opcode */
115 OPC_MAJOR3B_RESERVED
= (0x3B << 26),
118 /* MIPS special opcodes */
119 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
123 OPC_SLL
= 0x00 | OPC_SPECIAL
,
124 /* NOP is SLL r0, r0, 0 */
125 /* SSNOP is SLL r0, r0, 1 */
126 /* EHB is SLL r0, r0, 3 */
127 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
128 OPC_ROTR
= OPC_SRL
| (1 << 21),
129 OPC_SRA
= 0x03 | OPC_SPECIAL
,
130 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
131 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
132 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
133 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
134 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
135 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
136 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
137 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
138 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
139 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
140 OPC_DROTR
= OPC_DSRL
| (1 << 21),
141 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
142 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
143 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
144 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
145 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
146 /* Multiplication / division */
147 OPC_MULT
= 0x18 | OPC_SPECIAL
,
148 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
149 OPC_DIV
= 0x1A | OPC_SPECIAL
,
150 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
151 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
152 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
153 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
154 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
155 /* 2 registers arithmetic / logic */
156 OPC_ADD
= 0x20 | OPC_SPECIAL
,
157 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
158 OPC_SUB
= 0x22 | OPC_SPECIAL
,
159 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
160 OPC_AND
= 0x24 | OPC_SPECIAL
,
161 OPC_OR
= 0x25 | OPC_SPECIAL
,
162 OPC_XOR
= 0x26 | OPC_SPECIAL
,
163 OPC_NOR
= 0x27 | OPC_SPECIAL
,
164 OPC_SLT
= 0x2A | OPC_SPECIAL
,
165 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
166 OPC_DADD
= 0x2C | OPC_SPECIAL
,
167 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
168 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
169 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
171 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
172 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
173 OPC_JALRC
= OPC_JALR
| (0x5 << 6),
174 OPC_JALRS
= 0x10 | OPC_SPECIAL
| (0x5 << 6),
176 OPC_TGE
= 0x30 | OPC_SPECIAL
,
177 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
178 OPC_TLT
= 0x32 | OPC_SPECIAL
,
179 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
180 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
181 OPC_TNE
= 0x36 | OPC_SPECIAL
,
182 /* HI / LO registers load & stores */
183 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
184 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
185 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
186 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
187 /* Conditional moves */
188 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
189 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
191 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
194 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
195 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
196 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
197 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
198 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
200 OPC_SPECIAL15_RESERVED
= 0x15 | OPC_SPECIAL
,
201 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
202 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
203 OPC_SPECIAL35_RESERVED
= 0x35 | OPC_SPECIAL
,
204 OPC_SPECIAL37_RESERVED
= 0x37 | OPC_SPECIAL
,
205 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
206 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
209 /* Multiplication variants of the vr54xx. */
210 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
213 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
214 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
215 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
216 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
217 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
218 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
219 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
220 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
221 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
222 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
223 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
224 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
225 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
226 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
229 /* REGIMM (rt field) opcodes */
230 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
233 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
234 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
235 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
236 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
237 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
238 OPC_BLTZALS
= OPC_BLTZAL
| 0x5, /* microMIPS */
239 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
240 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
241 OPC_BGEZALS
= OPC_BGEZAL
| 0x5, /* microMIPS */
242 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
243 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
244 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
245 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
246 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
247 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
248 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
249 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
252 /* Special2 opcodes */
253 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
256 /* Multiply & xxx operations */
257 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
258 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
259 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
260 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
261 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
263 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
264 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
265 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
266 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
267 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
268 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
269 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
270 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
271 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
272 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
273 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
274 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
276 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
277 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
278 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
279 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
281 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
284 /* Special3 opcodes */
285 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
288 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
289 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
290 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
291 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
292 OPC_INS
= 0x04 | OPC_SPECIAL3
,
293 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
294 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
295 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
296 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
297 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
298 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
299 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
300 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
303 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
304 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
305 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
306 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
307 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
308 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
309 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
310 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
311 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
312 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
313 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
314 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
317 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
318 /* MIPS DSP Arithmetic */
319 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
320 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
321 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
322 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
323 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
324 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
325 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
326 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
327 /* MIPS DSP GPR-Based Shift Sub-class */
328 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
329 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
330 /* MIPS DSP Multiply Sub-class insns */
331 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
332 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
333 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
334 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
335 /* DSP Bit/Manipulation Sub-class */
336 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
337 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
338 /* MIPS DSP Append Sub-class */
339 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
340 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
341 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
342 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
343 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
347 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
350 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
351 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
352 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
356 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
359 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
360 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
363 /* MIPS DSP REGIMM opcodes */
365 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
366 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
369 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
372 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
373 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
374 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
375 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
378 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
380 /* MIPS DSP Arithmetic Sub-class */
381 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
382 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
383 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
384 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
385 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
386 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
387 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
388 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
389 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
390 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
391 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
392 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
393 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
394 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
395 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
396 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
397 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
398 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
399 /* MIPS DSP Multiply Sub-class insns */
400 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
401 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
402 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
403 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
404 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
405 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
408 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
409 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
411 /* MIPS DSP Arithmetic Sub-class */
412 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
413 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
414 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
415 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
416 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
417 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
418 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
419 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
420 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
421 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
422 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
423 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
424 /* MIPS DSP Multiply Sub-class insns */
425 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
426 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
427 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
428 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
431 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
433 /* MIPS DSP Arithmetic Sub-class */
434 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
435 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
436 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
437 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
438 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
439 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
440 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
441 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
442 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
443 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
444 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
445 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
446 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
447 /* DSP Bit/Manipulation Sub-class */
448 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
449 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
450 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
451 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
452 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
455 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
457 /* MIPS DSP Arithmetic Sub-class */
458 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
459 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
460 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
461 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
462 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
463 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
464 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
465 /* DSP Compare-Pick Sub-class */
466 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
467 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
468 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
469 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
470 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
471 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
472 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
473 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
474 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
475 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
476 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
477 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
478 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
479 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
480 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
483 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
485 /* MIPS DSP GPR-Based Shift Sub-class */
486 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
487 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
488 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
489 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
490 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
491 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
492 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
493 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
494 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
495 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
496 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
497 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
498 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
499 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
500 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
501 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
502 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
503 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
504 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
505 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
506 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
507 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
510 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
512 /* MIPS DSP Multiply Sub-class insns */
513 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
514 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
515 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
516 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
517 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
518 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
519 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
520 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
521 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
522 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
523 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
524 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
525 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
526 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
527 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
528 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
529 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
530 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
531 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
532 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
533 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
534 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
537 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
539 /* DSP Bit/Manipulation Sub-class */
540 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
543 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
545 /* MIPS DSP Append Sub-class */
546 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
547 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
548 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
551 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
553 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
554 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
555 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
556 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
557 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
558 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
559 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
560 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
561 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
562 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
563 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
564 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
565 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
566 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
567 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
568 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
569 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
570 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
573 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575 /* MIPS DSP Arithmetic Sub-class */
576 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
577 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
578 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
579 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
580 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
581 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
582 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
583 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
584 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
585 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
586 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
587 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
588 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
589 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
590 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
591 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
592 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
593 /* DSP Bit/Manipulation Sub-class */
594 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
595 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
596 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
597 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
598 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
599 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
602 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
604 /* MIPS DSP Multiply Sub-class insns */
605 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
606 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
607 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
608 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
609 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
610 /* MIPS DSP Arithmetic Sub-class */
611 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
612 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
613 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
614 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
615 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
616 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
617 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
618 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
619 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
620 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
621 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
622 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
623 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
624 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
625 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
626 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
627 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
628 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
629 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
630 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
631 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
634 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
636 /* DSP Compare-Pick Sub-class */
637 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
638 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
639 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
640 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
641 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
642 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
643 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
644 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
645 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
646 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
647 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
648 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
649 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
650 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
651 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
652 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
653 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
654 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
655 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
656 /* MIPS DSP Arithmetic Sub-class */
657 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
658 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
659 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
660 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
661 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
662 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
663 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
664 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
667 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
669 /* DSP Append Sub-class */
670 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
671 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
672 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
673 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
676 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
678 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
679 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
680 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
681 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
682 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
683 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
684 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
685 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
686 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
687 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
688 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
689 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
690 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
691 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
692 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
693 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
694 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
695 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
696 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
697 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
698 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
699 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
702 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
704 /* DSP Bit/Manipulation Sub-class */
705 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
708 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
710 /* MIPS DSP Multiply Sub-class insns */
711 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
712 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
713 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
714 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
715 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
716 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
717 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
718 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
719 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
720 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
721 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
722 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
723 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
724 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
725 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
726 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
727 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
728 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
729 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
730 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
731 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
732 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
733 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
734 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
735 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
736 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
739 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
741 /* MIPS DSP GPR-Based Shift Sub-class */
742 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
743 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
744 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
745 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
746 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
747 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
748 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
749 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
750 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
751 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
752 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
753 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
754 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
755 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
756 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
757 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
758 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
759 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
760 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
761 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
762 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
763 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
764 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
765 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
766 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
767 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
770 /* Coprocessor 0 (rs field) */
771 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
774 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
775 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
776 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
777 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
778 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
779 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
780 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
781 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
782 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
783 OPC_C0
= (0x10 << 21) | OPC_CP0
,
784 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
785 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
789 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
792 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
793 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
794 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
795 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
796 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
797 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
800 /* Coprocessor 0 (with rs == C0) */
801 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
804 OPC_TLBR
= 0x01 | OPC_C0
,
805 OPC_TLBWI
= 0x02 | OPC_C0
,
806 OPC_TLBWR
= 0x06 | OPC_C0
,
807 OPC_TLBP
= 0x08 | OPC_C0
,
808 OPC_RFE
= 0x10 | OPC_C0
,
809 OPC_ERET
= 0x18 | OPC_C0
,
810 OPC_DERET
= 0x1F | OPC_C0
,
811 OPC_WAIT
= 0x20 | OPC_C0
,
814 /* Coprocessor 1 (rs field) */
815 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
817 /* Values for the fmt field in FP instructions */
819 /* 0 - 15 are reserved */
820 FMT_S
= 16, /* single fp */
821 FMT_D
= 17, /* double fp */
822 FMT_E
= 18, /* extended fp */
823 FMT_Q
= 19, /* quad fp */
824 FMT_W
= 20, /* 32-bit fixed */
825 FMT_L
= 21, /* 64-bit fixed */
826 FMT_PS
= 22, /* paired single fp */
827 /* 23 - 31 are reserved */
831 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
832 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
833 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
834 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
835 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
836 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
837 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
838 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
839 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
840 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
841 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
842 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
843 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
844 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
845 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
846 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
847 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
848 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
851 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
852 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
855 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
856 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
857 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
858 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
862 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
863 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
867 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
868 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
871 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
874 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
875 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
876 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
877 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
878 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
879 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
880 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
881 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
882 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
885 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
888 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
889 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
890 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
891 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
892 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
893 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
894 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
895 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
897 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
898 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
899 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
900 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
901 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
902 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
903 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
904 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
906 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
907 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
908 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
909 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
910 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
911 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
912 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
913 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
915 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
916 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
917 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
918 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
919 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
920 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
921 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
922 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
924 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
925 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
926 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
927 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
928 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
929 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
931 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
932 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
933 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
934 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
935 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
936 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
938 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
939 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
940 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
941 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
942 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
943 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
945 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
946 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
947 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
948 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
949 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
950 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
952 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
953 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
954 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
955 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
956 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
957 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
959 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
960 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
961 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
962 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
963 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
964 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
966 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
967 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
968 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
969 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
970 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
971 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
973 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
974 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
975 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
976 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
977 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
978 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
982 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
985 OPC_LWXC1
= 0x00 | OPC_CP3
,
986 OPC_LDXC1
= 0x01 | OPC_CP3
,
987 OPC_LUXC1
= 0x05 | OPC_CP3
,
988 OPC_SWXC1
= 0x08 | OPC_CP3
,
989 OPC_SDXC1
= 0x09 | OPC_CP3
,
990 OPC_SUXC1
= 0x0D | OPC_CP3
,
991 OPC_PREFX
= 0x0F | OPC_CP3
,
992 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
993 OPC_MADD_S
= 0x20 | OPC_CP3
,
994 OPC_MADD_D
= 0x21 | OPC_CP3
,
995 OPC_MADD_PS
= 0x26 | OPC_CP3
,
996 OPC_MSUB_S
= 0x28 | OPC_CP3
,
997 OPC_MSUB_D
= 0x29 | OPC_CP3
,
998 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
999 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1000 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1001 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1002 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1003 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1004 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1007 /* global register indices */
1008 static TCGv_ptr cpu_env
;
1009 static TCGv cpu_gpr
[32], cpu_PC
;
1010 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
], cpu_ACX
[MIPS_DSP_ACC
];
1011 static TCGv cpu_dspctrl
, btarget
, bcond
;
1012 static TCGv_i32 hflags
;
1013 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1014 static TCGv_i64 fpu_f64
[32];
1016 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1017 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1019 #include "exec/gen-icount.h"
1021 #define gen_helper_0e0i(name, arg) do { \
1022 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1023 gen_helper_##name(cpu_env, helper_tmp); \
1024 tcg_temp_free_i32(helper_tmp); \
1027 #define gen_helper_0e1i(name, arg1, arg2) do { \
1028 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1029 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1030 tcg_temp_free_i32(helper_tmp); \
1033 #define gen_helper_1e0i(name, ret, arg1) do { \
1034 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1035 gen_helper_##name(ret, cpu_env, helper_tmp); \
1036 tcg_temp_free_i32(helper_tmp); \
1039 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1040 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1041 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1042 tcg_temp_free_i32(helper_tmp); \
1045 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1046 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1047 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1048 tcg_temp_free_i32(helper_tmp); \
1051 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1052 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1053 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1054 tcg_temp_free_i32(helper_tmp); \
1057 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1058 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1059 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1060 tcg_temp_free_i32(helper_tmp); \
1063 typedef struct DisasContext
{
1064 struct TranslationBlock
*tb
;
1065 target_ulong pc
, saved_pc
;
1067 int singlestep_enabled
;
1069 /* Routine used to access memory */
1071 uint32_t hflags
, saved_hflags
;
1073 target_ulong btarget
;
1077 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1078 * exception condition */
1079 BS_STOP
= 1, /* We want to stop translation for any reason */
1080 BS_BRANCH
= 2, /* We reached a branch condition */
1081 BS_EXCP
= 3, /* We reached an exception condition */
1084 static const char * const regnames
[] = {
1085 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1086 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1087 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1088 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1091 static const char * const regnames_HI
[] = {
1092 "HI0", "HI1", "HI2", "HI3",
1095 static const char * const regnames_LO
[] = {
1096 "LO0", "LO1", "LO2", "LO3",
1099 static const char * const regnames_ACX
[] = {
1100 "ACX0", "ACX1", "ACX2", "ACX3",
1103 static const char * const fregnames
[] = {
1104 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1105 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1106 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1107 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1110 #define MIPS_DEBUG(fmt, ...) \
1112 if (MIPS_DEBUG_DISAS) { \
1113 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1114 TARGET_FMT_lx ": %08x " fmt "\n", \
1115 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1119 #define LOG_DISAS(...) \
1121 if (MIPS_DEBUG_DISAS) { \
1122 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1126 #define MIPS_INVAL(op) \
1127 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1128 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1130 /* General purpose registers moves. */
1131 static inline void gen_load_gpr (TCGv t
, int reg
)
1134 tcg_gen_movi_tl(t
, 0);
1136 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1139 static inline void gen_store_gpr (TCGv t
, int reg
)
1142 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1145 /* Moves to/from ACX register. */
1146 static inline void gen_load_ACX (TCGv t
, int reg
)
1148 tcg_gen_mov_tl(t
, cpu_ACX
[reg
]);
1151 static inline void gen_store_ACX (TCGv t
, int reg
)
1153 tcg_gen_mov_tl(cpu_ACX
[reg
], t
);
1156 /* Moves to/from shadow registers. */
1157 static inline void gen_load_srsgpr (int from
, int to
)
1159 TCGv t0
= tcg_temp_new();
1162 tcg_gen_movi_tl(t0
, 0);
1164 TCGv_i32 t2
= tcg_temp_new_i32();
1165 TCGv_ptr addr
= tcg_temp_new_ptr();
1167 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1168 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1169 tcg_gen_andi_i32(t2
, t2
, 0xf);
1170 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1171 tcg_gen_ext_i32_ptr(addr
, t2
);
1172 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1174 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1175 tcg_temp_free_ptr(addr
);
1176 tcg_temp_free_i32(t2
);
1178 gen_store_gpr(t0
, to
);
1182 static inline void gen_store_srsgpr (int from
, int to
)
1185 TCGv t0
= tcg_temp_new();
1186 TCGv_i32 t2
= tcg_temp_new_i32();
1187 TCGv_ptr addr
= tcg_temp_new_ptr();
1189 gen_load_gpr(t0
, from
);
1190 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1191 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1192 tcg_gen_andi_i32(t2
, t2
, 0xf);
1193 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1194 tcg_gen_ext_i32_ptr(addr
, t2
);
1195 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1197 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1198 tcg_temp_free_ptr(addr
);
1199 tcg_temp_free_i32(t2
);
1204 /* Floating point register moves. */
1205 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1207 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1210 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1212 TCGv_i64 t64
= tcg_temp_new_i64();
1213 tcg_gen_extu_i32_i64(t64
, t
);
1214 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1215 tcg_temp_free_i64(t64
);
1218 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1220 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1221 TCGv_i64 t64
= tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1223 tcg_gen_trunc_i64_i32(t
, t64
);
1224 tcg_temp_free_i64(t64
);
1226 gen_load_fpr32(t
, reg
| 1);
1230 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1232 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1233 TCGv_i64 t64
= tcg_temp_new_i64();
1234 tcg_gen_extu_i32_i64(t64
, t
);
1235 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1236 tcg_temp_free_i64(t64
);
1238 gen_store_fpr32(t
, reg
| 1);
1242 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1244 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1245 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1247 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1251 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1253 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1254 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1257 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1258 t0
= tcg_temp_new_i64();
1259 tcg_gen_shri_i64(t0
, t
, 32);
1260 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1261 tcg_temp_free_i64(t0
);
1265 static inline int get_fp_bit (int cc
)
1274 static inline void gen_save_pc(target_ulong pc
)
1276 tcg_gen_movi_tl(cpu_PC
, pc
);
1279 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1281 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1282 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1283 gen_save_pc(ctx
->pc
);
1284 ctx
->saved_pc
= ctx
->pc
;
1286 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1287 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1288 ctx
->saved_hflags
= ctx
->hflags
;
1289 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1295 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1301 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1303 ctx
->saved_hflags
= ctx
->hflags
;
1304 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1310 ctx
->btarget
= env
->btarget
;
1316 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1318 TCGv_i32 texcp
= tcg_const_i32(excp
);
1319 TCGv_i32 terr
= tcg_const_i32(err
);
1320 save_cpu_state(ctx
, 1);
1321 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1322 tcg_temp_free_i32(terr
);
1323 tcg_temp_free_i32(texcp
);
1327 generate_exception (DisasContext
*ctx
, int excp
)
1329 save_cpu_state(ctx
, 1);
1330 gen_helper_0e0i(raise_exception
, excp
);
1333 /* Addresses computation */
1334 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1336 tcg_gen_add_tl(ret
, arg0
, arg1
);
1338 #if defined(TARGET_MIPS64)
1339 /* For compatibility with 32-bit code, data reference in user mode
1340 with Status_UX = 0 should be casted to 32-bit and sign extended.
1341 See the MIPS64 PRA manual, section 4.10. */
1342 if (((ctx
->hflags
& MIPS_HFLAG_KSU
) == MIPS_HFLAG_UM
) &&
1343 !(ctx
->hflags
& MIPS_HFLAG_UX
)) {
1344 tcg_gen_ext32s_i64(ret
, ret
);
1349 static inline void check_cp0_enabled(DisasContext
*ctx
)
1351 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1352 generate_exception_err(ctx
, EXCP_CpU
, 0);
1355 static inline void check_cp1_enabled(DisasContext
*ctx
)
1357 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1358 generate_exception_err(ctx
, EXCP_CpU
, 1);
1361 /* Verify that the processor is running with COP1X instructions enabled.
1362 This is associated with the nabla symbol in the MIPS32 and MIPS64
1365 static inline void check_cop1x(DisasContext
*ctx
)
1367 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1368 generate_exception(ctx
, EXCP_RI
);
1371 /* Verify that the processor is running with 64-bit floating-point
1372 operations enabled. */
1374 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1376 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1377 generate_exception(ctx
, EXCP_RI
);
1381 * Verify if floating point register is valid; an operation is not defined
1382 * if bit 0 of any register specification is set and the FR bit in the
1383 * Status register equals zero, since the register numbers specify an
1384 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1385 * in the Status register equals one, both even and odd register numbers
1386 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1388 * Multiple 64 bit wide registers can be checked by calling
1389 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1391 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1393 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1394 generate_exception(ctx
, EXCP_RI
);
1397 /* Verify that the processor is running with DSP instructions enabled.
1398 This is enabled by CP0 Status register MX(24) bit.
1401 static inline void check_dsp(DisasContext
*ctx
)
1403 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1404 if (ctx
->insn_flags
& ASE_DSP
) {
1405 generate_exception(ctx
, EXCP_DSPDIS
);
1407 generate_exception(ctx
, EXCP_RI
);
1412 static inline void check_dspr2(DisasContext
*ctx
)
1414 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1415 if (ctx
->insn_flags
& ASE_DSP
) {
1416 generate_exception(ctx
, EXCP_DSPDIS
);
1418 generate_exception(ctx
, EXCP_RI
);
1423 /* This code generates a "reserved instruction" exception if the
1424 CPU does not support the instruction set corresponding to flags. */
1425 static inline void check_insn(DisasContext
*ctx
, int flags
)
1427 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1428 generate_exception(ctx
, EXCP_RI
);
1432 /* This code generates a "reserved instruction" exception if 64-bit
1433 instructions are not enabled. */
1434 static inline void check_mips_64(DisasContext
*ctx
)
1436 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1437 generate_exception(ctx
, EXCP_RI
);
1440 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1441 calling interface for 32 and 64-bit FPRs. No sense in changing
1442 all callers for gen_load_fpr32 when we need the CTX parameter for
1444 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1445 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1446 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1447 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1448 int ft, int fs, int cc) \
1450 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1451 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1454 check_cp1_64bitmode(ctx); \
1460 check_cp1_registers(ctx, fs | ft); \
1468 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1469 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1471 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1472 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1473 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1474 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1475 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1476 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1477 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1478 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1479 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1480 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1481 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1482 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1483 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1484 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1485 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1486 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1489 tcg_temp_free_i##bits (fp0); \
1490 tcg_temp_free_i##bits (fp1); \
1493 FOP_CONDS(, 0, d
, FMT_D
, 64)
1494 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1495 FOP_CONDS(, 0, s
, FMT_S
, 32)
1496 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1497 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1498 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1500 #undef gen_ldcmp_fpr32
1501 #undef gen_ldcmp_fpr64
1503 /* load/store instructions. */
1504 #ifdef CONFIG_USER_ONLY
1505 #define OP_LD_ATOMIC(insn,fname) \
1506 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1508 TCGv t0 = tcg_temp_new(); \
1509 tcg_gen_mov_tl(t0, arg1); \
1510 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1511 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1512 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1513 tcg_temp_free(t0); \
1516 #define OP_LD_ATOMIC(insn,fname) \
1517 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1519 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1522 OP_LD_ATOMIC(ll
,ld32s
);
1523 #if defined(TARGET_MIPS64)
1524 OP_LD_ATOMIC(lld
,ld64
);
1528 #ifdef CONFIG_USER_ONLY
1529 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1530 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1532 TCGv t0 = tcg_temp_new(); \
1533 int l1 = gen_new_label(); \
1534 int l2 = gen_new_label(); \
1536 tcg_gen_andi_tl(t0, arg2, almask); \
1537 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1538 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1539 generate_exception(ctx, EXCP_AdES); \
1540 gen_set_label(l1); \
1541 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1542 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1543 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1544 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1545 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1546 gen_helper_0e0i(raise_exception, EXCP_SC); \
1547 gen_set_label(l2); \
1548 tcg_gen_movi_tl(t0, 0); \
1549 gen_store_gpr(t0, rt); \
1550 tcg_temp_free(t0); \
1553 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1554 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1556 TCGv t0 = tcg_temp_new(); \
1557 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1558 gen_store_gpr(t0, rt); \
1559 tcg_temp_free(t0); \
1562 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1563 #if defined(TARGET_MIPS64)
1564 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1568 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1569 int base
, int16_t offset
)
1572 tcg_gen_movi_tl(addr
, offset
);
1573 } else if (offset
== 0) {
1574 gen_load_gpr(addr
, base
);
1576 tcg_gen_movi_tl(addr
, offset
);
1577 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1581 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1583 target_ulong pc
= ctx
->pc
;
1585 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1586 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1591 pc
&= ~(target_ulong
)3;
1596 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1597 int rt
, int base
, int16_t offset
)
1599 const char *opn
= "ld";
1602 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1603 /* Loongson CPU uses a load to zero register for prefetch.
1604 We emulate it as a NOP. On other CPU we must perform the
1605 actual memory access. */
1610 t0
= tcg_temp_new();
1611 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1614 #if defined(TARGET_MIPS64)
1616 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1617 gen_store_gpr(t0
, rt
);
1621 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1622 gen_store_gpr(t0
, rt
);
1626 save_cpu_state(ctx
, 1);
1627 op_ld_lld(t0
, t0
, ctx
);
1628 gen_store_gpr(t0
, rt
);
1632 t1
= tcg_temp_new();
1633 tcg_gen_andi_tl(t1
, t0
, 7);
1634 #ifndef TARGET_WORDS_BIGENDIAN
1635 tcg_gen_xori_tl(t1
, t1
, 7);
1637 tcg_gen_shli_tl(t1
, t1
, 3);
1638 tcg_gen_andi_tl(t0
, t0
, ~7);
1639 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1640 tcg_gen_shl_tl(t0
, t0
, t1
);
1641 tcg_gen_xori_tl(t1
, t1
, 63);
1642 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1643 tcg_gen_shr_tl(t2
, t2
, t1
);
1644 gen_load_gpr(t1
, rt
);
1645 tcg_gen_and_tl(t1
, t1
, t2
);
1647 tcg_gen_or_tl(t0
, t0
, t1
);
1649 gen_store_gpr(t0
, rt
);
1653 t1
= tcg_temp_new();
1654 tcg_gen_andi_tl(t1
, t0
, 7);
1655 #ifdef TARGET_WORDS_BIGENDIAN
1656 tcg_gen_xori_tl(t1
, t1
, 7);
1658 tcg_gen_shli_tl(t1
, t1
, 3);
1659 tcg_gen_andi_tl(t0
, t0
, ~7);
1660 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1661 tcg_gen_shr_tl(t0
, t0
, t1
);
1662 tcg_gen_xori_tl(t1
, t1
, 63);
1663 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1664 tcg_gen_shl_tl(t2
, t2
, t1
);
1665 gen_load_gpr(t1
, rt
);
1666 tcg_gen_and_tl(t1
, t1
, t2
);
1668 tcg_gen_or_tl(t0
, t0
, t1
);
1670 gen_store_gpr(t0
, rt
);
1674 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1675 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1677 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1678 gen_store_gpr(t0
, rt
);
1683 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1684 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1686 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1687 gen_store_gpr(t0
, rt
);
1691 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1692 gen_store_gpr(t0
, rt
);
1696 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
1697 gen_store_gpr(t0
, rt
);
1701 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
1702 gen_store_gpr(t0
, rt
);
1706 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
1707 gen_store_gpr(t0
, rt
);
1711 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
1712 gen_store_gpr(t0
, rt
);
1716 t1
= tcg_temp_new();
1717 tcg_gen_andi_tl(t1
, t0
, 3);
1718 #ifndef TARGET_WORDS_BIGENDIAN
1719 tcg_gen_xori_tl(t1
, t1
, 3);
1721 tcg_gen_shli_tl(t1
, t1
, 3);
1722 tcg_gen_andi_tl(t0
, t0
, ~3);
1723 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1724 tcg_gen_shl_tl(t0
, t0
, t1
);
1725 tcg_gen_xori_tl(t1
, t1
, 31);
1726 t2
= tcg_const_tl(0x7fffffffull
);
1727 tcg_gen_shr_tl(t2
, t2
, t1
);
1728 gen_load_gpr(t1
, rt
);
1729 tcg_gen_and_tl(t1
, t1
, t2
);
1731 tcg_gen_or_tl(t0
, t0
, t1
);
1733 tcg_gen_ext32s_tl(t0
, t0
);
1734 gen_store_gpr(t0
, rt
);
1738 t1
= tcg_temp_new();
1739 tcg_gen_andi_tl(t1
, t0
, 3);
1740 #ifdef TARGET_WORDS_BIGENDIAN
1741 tcg_gen_xori_tl(t1
, t1
, 3);
1743 tcg_gen_shli_tl(t1
, t1
, 3);
1744 tcg_gen_andi_tl(t0
, t0
, ~3);
1745 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1746 tcg_gen_shr_tl(t0
, t0
, t1
);
1747 tcg_gen_xori_tl(t1
, t1
, 31);
1748 t2
= tcg_const_tl(0xfffffffeull
);
1749 tcg_gen_shl_tl(t2
, t2
, t1
);
1750 gen_load_gpr(t1
, rt
);
1751 tcg_gen_and_tl(t1
, t1
, t2
);
1753 tcg_gen_or_tl(t0
, t0
, t1
);
1755 tcg_gen_ext32s_tl(t0
, t0
);
1756 gen_store_gpr(t0
, rt
);
1760 save_cpu_state(ctx
, 1);
1761 op_ld_ll(t0
, t0
, ctx
);
1762 gen_store_gpr(t0
, rt
);
1766 (void)opn
; /* avoid a compiler warning */
1767 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1772 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1773 int base
, int16_t offset
)
1775 const char *opn
= "st";
1776 TCGv t0
= tcg_temp_new();
1777 TCGv t1
= tcg_temp_new();
1779 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1780 gen_load_gpr(t1
, rt
);
1782 #if defined(TARGET_MIPS64)
1784 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
1788 save_cpu_state(ctx
, 1);
1789 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1793 save_cpu_state(ctx
, 1);
1794 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
1799 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
1803 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
1807 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
1811 save_cpu_state(ctx
, 1);
1812 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
1816 save_cpu_state(ctx
, 1);
1817 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
1821 (void)opn
; /* avoid a compiler warning */
1822 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1828 /* Store conditional */
1829 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
1830 int base
, int16_t offset
)
1832 const char *opn
= "st_cond";
1835 #ifdef CONFIG_USER_ONLY
1836 t0
= tcg_temp_local_new();
1837 t1
= tcg_temp_local_new();
1839 t0
= tcg_temp_new();
1840 t1
= tcg_temp_new();
1842 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1843 gen_load_gpr(t1
, rt
);
1845 #if defined(TARGET_MIPS64)
1847 save_cpu_state(ctx
, 1);
1848 op_st_scd(t1
, t0
, rt
, ctx
);
1853 save_cpu_state(ctx
, 1);
1854 op_st_sc(t1
, t0
, rt
, ctx
);
1858 (void)opn
; /* avoid a compiler warning */
1859 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1864 /* Load and store */
1865 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
1866 int base
, int16_t offset
)
1868 const char *opn
= "flt_ldst";
1869 TCGv t0
= tcg_temp_new();
1871 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1872 /* Don't do NOP if destination is zero: we must perform the actual
1877 TCGv_i32 fp0
= tcg_temp_new_i32();
1878 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
1879 gen_store_fpr32(fp0
, ft
);
1880 tcg_temp_free_i32(fp0
);
1886 TCGv_i32 fp0
= tcg_temp_new_i32();
1887 gen_load_fpr32(fp0
, ft
);
1888 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1889 tcg_temp_free_i32(fp0
);
1895 TCGv_i64 fp0
= tcg_temp_new_i64();
1896 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1897 gen_store_fpr64(ctx
, fp0
, ft
);
1898 tcg_temp_free_i64(fp0
);
1904 TCGv_i64 fp0
= tcg_temp_new_i64();
1905 gen_load_fpr64(ctx
, fp0
, ft
);
1906 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1907 tcg_temp_free_i64(fp0
);
1913 generate_exception(ctx
, EXCP_RI
);
1916 (void)opn
; /* avoid a compiler warning */
1917 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
1922 static void gen_cop1_ldst(CPUMIPSState
*env
, DisasContext
*ctx
,
1923 uint32_t op
, int rt
, int rs
, int16_t imm
)
1925 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
1926 check_cp1_enabled(ctx
);
1927 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
1929 generate_exception_err(ctx
, EXCP_CpU
, 1);
1933 /* Arithmetic with immediate operand */
1934 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
1935 int rt
, int rs
, int16_t imm
)
1937 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
1938 const char *opn
= "imm arith";
1940 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
1941 /* If no destination, treat it as a NOP.
1942 For addi, we must generate the overflow exception when needed. */
1949 TCGv t0
= tcg_temp_local_new();
1950 TCGv t1
= tcg_temp_new();
1951 TCGv t2
= tcg_temp_new();
1952 int l1
= gen_new_label();
1954 gen_load_gpr(t1
, rs
);
1955 tcg_gen_addi_tl(t0
, t1
, uimm
);
1956 tcg_gen_ext32s_tl(t0
, t0
);
1958 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1959 tcg_gen_xori_tl(t2
, t0
, uimm
);
1960 tcg_gen_and_tl(t1
, t1
, t2
);
1962 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1964 /* operands of same sign, result different sign */
1965 generate_exception(ctx
, EXCP_OVERFLOW
);
1967 tcg_gen_ext32s_tl(t0
, t0
);
1968 gen_store_gpr(t0
, rt
);
1975 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1976 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
1978 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1982 #if defined(TARGET_MIPS64)
1985 TCGv t0
= tcg_temp_local_new();
1986 TCGv t1
= tcg_temp_new();
1987 TCGv t2
= tcg_temp_new();
1988 int l1
= gen_new_label();
1990 gen_load_gpr(t1
, rs
);
1991 tcg_gen_addi_tl(t0
, t1
, uimm
);
1993 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1994 tcg_gen_xori_tl(t2
, t0
, uimm
);
1995 tcg_gen_and_tl(t1
, t1
, t2
);
1997 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1999 /* operands of same sign, result different sign */
2000 generate_exception(ctx
, EXCP_OVERFLOW
);
2002 gen_store_gpr(t0
, rt
);
2009 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2011 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2017 (void)opn
; /* avoid a compiler warning */
2018 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2021 /* Logic with immediate operand */
2022 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2023 int rt
, int rs
, int16_t imm
)
2028 /* If no destination, treat it as a NOP. */
2032 uimm
= (uint16_t)imm
;
2035 if (likely(rs
!= 0))
2036 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2038 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2039 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2040 regnames
[rs
], uimm
);
2044 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2046 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2047 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2048 regnames
[rs
], uimm
);
2051 if (likely(rs
!= 0))
2052 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2054 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2055 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2056 regnames
[rs
], uimm
);
2059 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2060 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2064 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2069 /* Set on less than with immediate operand */
2070 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2071 int rt
, int rs
, int16_t imm
)
2073 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2074 const char *opn
= "imm arith";
2078 /* If no destination, treat it as a NOP. */
2082 t0
= tcg_temp_new();
2083 gen_load_gpr(t0
, rs
);
2086 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2090 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2094 (void)opn
; /* avoid a compiler warning */
2095 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2099 /* Shifts with immediate operand */
2100 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2101 int rt
, int rs
, int16_t imm
)
2103 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2104 const char *opn
= "imm shift";
2108 /* If no destination, treat it as a NOP. */
2113 t0
= tcg_temp_new();
2114 gen_load_gpr(t0
, rs
);
2117 tcg_gen_shli_tl(t0
, t0
, uimm
);
2118 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2122 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2127 tcg_gen_ext32u_tl(t0
, t0
);
2128 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2130 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2136 TCGv_i32 t1
= tcg_temp_new_i32();
2138 tcg_gen_trunc_tl_i32(t1
, t0
);
2139 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2140 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2141 tcg_temp_free_i32(t1
);
2143 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2147 #if defined(TARGET_MIPS64)
2149 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2153 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2157 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2162 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2164 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2169 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2173 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2177 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2181 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2186 (void)opn
; /* avoid a compiler warning */
2187 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2192 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2193 int rd
, int rs
, int rt
)
2195 const char *opn
= "arith";
2197 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2198 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2199 /* If no destination, treat it as a NOP.
2200 For add & sub, we must generate the overflow exception when needed. */
2208 TCGv t0
= tcg_temp_local_new();
2209 TCGv t1
= tcg_temp_new();
2210 TCGv t2
= tcg_temp_new();
2211 int l1
= gen_new_label();
2213 gen_load_gpr(t1
, rs
);
2214 gen_load_gpr(t2
, rt
);
2215 tcg_gen_add_tl(t0
, t1
, t2
);
2216 tcg_gen_ext32s_tl(t0
, t0
);
2217 tcg_gen_xor_tl(t1
, t1
, t2
);
2218 tcg_gen_xor_tl(t2
, t0
, t2
);
2219 tcg_gen_andc_tl(t1
, t2
, t1
);
2221 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2223 /* operands of same sign, result different sign */
2224 generate_exception(ctx
, EXCP_OVERFLOW
);
2226 gen_store_gpr(t0
, rd
);
2232 if (rs
!= 0 && rt
!= 0) {
2233 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2234 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2235 } else if (rs
== 0 && rt
!= 0) {
2236 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2237 } else if (rs
!= 0 && rt
== 0) {
2238 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2240 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2246 TCGv t0
= tcg_temp_local_new();
2247 TCGv t1
= tcg_temp_new();
2248 TCGv t2
= tcg_temp_new();
2249 int l1
= gen_new_label();
2251 gen_load_gpr(t1
, rs
);
2252 gen_load_gpr(t2
, rt
);
2253 tcg_gen_sub_tl(t0
, t1
, t2
);
2254 tcg_gen_ext32s_tl(t0
, t0
);
2255 tcg_gen_xor_tl(t2
, t1
, t2
);
2256 tcg_gen_xor_tl(t1
, t0
, t1
);
2257 tcg_gen_and_tl(t1
, t1
, t2
);
2259 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2261 /* operands of different sign, first operand and result different sign */
2262 generate_exception(ctx
, EXCP_OVERFLOW
);
2264 gen_store_gpr(t0
, rd
);
2270 if (rs
!= 0 && rt
!= 0) {
2271 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2272 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2273 } else if (rs
== 0 && rt
!= 0) {
2274 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2275 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2276 } else if (rs
!= 0 && rt
== 0) {
2277 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2279 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2283 #if defined(TARGET_MIPS64)
2286 TCGv t0
= tcg_temp_local_new();
2287 TCGv t1
= tcg_temp_new();
2288 TCGv t2
= tcg_temp_new();
2289 int l1
= gen_new_label();
2291 gen_load_gpr(t1
, rs
);
2292 gen_load_gpr(t2
, rt
);
2293 tcg_gen_add_tl(t0
, t1
, t2
);
2294 tcg_gen_xor_tl(t1
, t1
, t2
);
2295 tcg_gen_xor_tl(t2
, t0
, t2
);
2296 tcg_gen_andc_tl(t1
, t2
, t1
);
2298 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2300 /* operands of same sign, result different sign */
2301 generate_exception(ctx
, EXCP_OVERFLOW
);
2303 gen_store_gpr(t0
, rd
);
2309 if (rs
!= 0 && rt
!= 0) {
2310 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2311 } else if (rs
== 0 && rt
!= 0) {
2312 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2313 } else if (rs
!= 0 && rt
== 0) {
2314 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2316 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2322 TCGv t0
= tcg_temp_local_new();
2323 TCGv t1
= tcg_temp_new();
2324 TCGv t2
= tcg_temp_new();
2325 int l1
= gen_new_label();
2327 gen_load_gpr(t1
, rs
);
2328 gen_load_gpr(t2
, rt
);
2329 tcg_gen_sub_tl(t0
, t1
, t2
);
2330 tcg_gen_xor_tl(t2
, t1
, t2
);
2331 tcg_gen_xor_tl(t1
, t0
, t1
);
2332 tcg_gen_and_tl(t1
, t1
, t2
);
2334 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2336 /* operands of different sign, first operand and result different sign */
2337 generate_exception(ctx
, EXCP_OVERFLOW
);
2339 gen_store_gpr(t0
, rd
);
2345 if (rs
!= 0 && rt
!= 0) {
2346 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2347 } else if (rs
== 0 && rt
!= 0) {
2348 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2349 } else if (rs
!= 0 && rt
== 0) {
2350 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2352 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2358 if (likely(rs
!= 0 && rt
!= 0)) {
2359 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2360 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2362 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2367 (void)opn
; /* avoid a compiler warning */
2368 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2371 /* Conditional move */
2372 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2373 int rd
, int rs
, int rt
)
2375 const char *opn
= "cond move";
2379 /* If no destination, treat it as a NOP. */
2384 t0
= tcg_temp_new();
2385 gen_load_gpr(t0
, rt
);
2386 t1
= tcg_const_tl(0);
2387 t2
= tcg_temp_new();
2388 gen_load_gpr(t2
, rs
);
2391 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2395 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2403 (void)opn
; /* avoid a compiler warning */
2404 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2408 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2409 int rd
, int rs
, int rt
)
2411 const char *opn
= "logic";
2414 /* If no destination, treat it as a NOP. */
2421 if (likely(rs
!= 0 && rt
!= 0)) {
2422 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2424 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2429 if (rs
!= 0 && rt
!= 0) {
2430 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2431 } else if (rs
== 0 && rt
!= 0) {
2432 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2433 } else if (rs
!= 0 && rt
== 0) {
2434 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2436 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2441 if (likely(rs
!= 0 && rt
!= 0)) {
2442 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2443 } else if (rs
== 0 && rt
!= 0) {
2444 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2445 } else if (rs
!= 0 && rt
== 0) {
2446 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2448 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2453 if (likely(rs
!= 0 && rt
!= 0)) {
2454 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2455 } else if (rs
== 0 && rt
!= 0) {
2456 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2457 } else if (rs
!= 0 && rt
== 0) {
2458 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2460 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2465 (void)opn
; /* avoid a compiler warning */
2466 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2469 /* Set on lower than */
2470 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2471 int rd
, int rs
, int rt
)
2473 const char *opn
= "slt";
2477 /* If no destination, treat it as a NOP. */
2482 t0
= tcg_temp_new();
2483 t1
= tcg_temp_new();
2484 gen_load_gpr(t0
, rs
);
2485 gen_load_gpr(t1
, rt
);
2488 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2492 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2496 (void)opn
; /* avoid a compiler warning */
2497 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2503 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2504 int rd
, int rs
, int rt
)
2506 const char *opn
= "shifts";
2510 /* If no destination, treat it as a NOP.
2511 For add & sub, we must generate the overflow exception when needed. */
2516 t0
= tcg_temp_new();
2517 t1
= tcg_temp_new();
2518 gen_load_gpr(t0
, rs
);
2519 gen_load_gpr(t1
, rt
);
2522 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2523 tcg_gen_shl_tl(t0
, t1
, t0
);
2524 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2528 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2529 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2533 tcg_gen_ext32u_tl(t1
, t1
);
2534 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2535 tcg_gen_shr_tl(t0
, t1
, t0
);
2536 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2541 TCGv_i32 t2
= tcg_temp_new_i32();
2542 TCGv_i32 t3
= tcg_temp_new_i32();
2544 tcg_gen_trunc_tl_i32(t2
, t0
);
2545 tcg_gen_trunc_tl_i32(t3
, t1
);
2546 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2547 tcg_gen_rotr_i32(t2
, t3
, t2
);
2548 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2549 tcg_temp_free_i32(t2
);
2550 tcg_temp_free_i32(t3
);
2554 #if defined(TARGET_MIPS64)
2556 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2557 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2561 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2562 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2566 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2567 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2571 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2572 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2577 (void)opn
; /* avoid a compiler warning */
2578 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2583 /* Arithmetic on HI/LO registers */
2584 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2586 const char *opn
= "hilo";
2588 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2600 #if defined(TARGET_MIPS64)
2602 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2606 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2611 #if defined(TARGET_MIPS64)
2613 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2617 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2623 #if defined(TARGET_MIPS64)
2625 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2629 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2632 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2638 #if defined(TARGET_MIPS64)
2640 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2644 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2647 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2652 (void)opn
; /* avoid a compiler warning */
2653 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2656 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
2657 int acc
, int rs
, int rt
)
2659 const char *opn
= "mul/div";
2662 t0
= tcg_temp_new();
2663 t1
= tcg_temp_new();
2665 gen_load_gpr(t0
, rs
);
2666 gen_load_gpr(t1
, rt
);
2675 TCGv t2
= tcg_temp_new();
2676 TCGv t3
= tcg_temp_new();
2677 tcg_gen_ext32s_tl(t0
, t0
);
2678 tcg_gen_ext32s_tl(t1
, t1
);
2679 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2680 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2681 tcg_gen_and_tl(t2
, t2
, t3
);
2682 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2683 tcg_gen_or_tl(t2
, t2
, t3
);
2684 tcg_gen_movi_tl(t3
, 0);
2685 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2686 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2687 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2688 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2689 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2697 TCGv t2
= tcg_const_tl(0);
2698 TCGv t3
= tcg_const_tl(1);
2699 tcg_gen_ext32u_tl(t0
, t0
);
2700 tcg_gen_ext32u_tl(t1
, t1
);
2701 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2702 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
2703 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
2704 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2705 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2713 TCGv_i32 t2
= tcg_temp_new_i32();
2714 TCGv_i32 t3
= tcg_temp_new_i32();
2715 tcg_gen_trunc_tl_i32(t2
, t0
);
2716 tcg_gen_trunc_tl_i32(t3
, t1
);
2717 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
2718 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2719 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2720 tcg_temp_free_i32(t2
);
2721 tcg_temp_free_i32(t3
);
2727 TCGv_i32 t2
= tcg_temp_new_i32();
2728 TCGv_i32 t3
= tcg_temp_new_i32();
2729 tcg_gen_trunc_tl_i32(t2
, t0
);
2730 tcg_gen_trunc_tl_i32(t3
, t1
);
2731 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
2732 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2733 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2734 tcg_temp_free_i32(t2
);
2735 tcg_temp_free_i32(t3
);
2739 #if defined(TARGET_MIPS64)
2742 TCGv t2
= tcg_temp_new();
2743 TCGv t3
= tcg_temp_new();
2744 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2745 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2746 tcg_gen_and_tl(t2
, t2
, t3
);
2747 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2748 tcg_gen_or_tl(t2
, t2
, t3
);
2749 tcg_gen_movi_tl(t3
, 0);
2750 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2751 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2752 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2760 TCGv t2
= tcg_const_tl(0);
2761 TCGv t3
= tcg_const_tl(1);
2762 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2763 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
2764 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
2771 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2775 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2781 TCGv_i64 t2
= tcg_temp_new_i64();
2782 TCGv_i64 t3
= tcg_temp_new_i64();
2784 tcg_gen_ext_tl_i64(t2
, t0
);
2785 tcg_gen_ext_tl_i64(t3
, t1
);
2786 tcg_gen_mul_i64(t2
, t2
, t3
);
2787 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2788 tcg_gen_add_i64(t2
, t2
, t3
);
2789 tcg_temp_free_i64(t3
);
2790 tcg_gen_trunc_i64_tl(t0
, t2
);
2791 tcg_gen_shri_i64(t2
, t2
, 32);
2792 tcg_gen_trunc_i64_tl(t1
, t2
);
2793 tcg_temp_free_i64(t2
);
2794 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2795 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2801 TCGv_i64 t2
= tcg_temp_new_i64();
2802 TCGv_i64 t3
= tcg_temp_new_i64();
2804 tcg_gen_ext32u_tl(t0
, t0
);
2805 tcg_gen_ext32u_tl(t1
, t1
);
2806 tcg_gen_extu_tl_i64(t2
, t0
);
2807 tcg_gen_extu_tl_i64(t3
, t1
);
2808 tcg_gen_mul_i64(t2
, t2
, t3
);
2809 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2810 tcg_gen_add_i64(t2
, t2
, t3
);
2811 tcg_temp_free_i64(t3
);
2812 tcg_gen_trunc_i64_tl(t0
, t2
);
2813 tcg_gen_shri_i64(t2
, t2
, 32);
2814 tcg_gen_trunc_i64_tl(t1
, t2
);
2815 tcg_temp_free_i64(t2
);
2816 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2817 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2823 TCGv_i64 t2
= tcg_temp_new_i64();
2824 TCGv_i64 t3
= tcg_temp_new_i64();
2826 tcg_gen_ext_tl_i64(t2
, t0
);
2827 tcg_gen_ext_tl_i64(t3
, t1
);
2828 tcg_gen_mul_i64(t2
, t2
, t3
);
2829 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2830 tcg_gen_sub_i64(t2
, t3
, t2
);
2831 tcg_temp_free_i64(t3
);
2832 tcg_gen_trunc_i64_tl(t0
, t2
);
2833 tcg_gen_shri_i64(t2
, t2
, 32);
2834 tcg_gen_trunc_i64_tl(t1
, t2
);
2835 tcg_temp_free_i64(t2
);
2836 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2837 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2843 TCGv_i64 t2
= tcg_temp_new_i64();
2844 TCGv_i64 t3
= tcg_temp_new_i64();
2846 tcg_gen_ext32u_tl(t0
, t0
);
2847 tcg_gen_ext32u_tl(t1
, t1
);
2848 tcg_gen_extu_tl_i64(t2
, t0
);
2849 tcg_gen_extu_tl_i64(t3
, t1
);
2850 tcg_gen_mul_i64(t2
, t2
, t3
);
2851 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2852 tcg_gen_sub_i64(t2
, t3
, t2
);
2853 tcg_temp_free_i64(t3
);
2854 tcg_gen_trunc_i64_tl(t0
, t2
);
2855 tcg_gen_shri_i64(t2
, t2
, 32);
2856 tcg_gen_trunc_i64_tl(t1
, t2
);
2857 tcg_temp_free_i64(t2
);
2858 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2859 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2865 generate_exception(ctx
, EXCP_RI
);
2868 (void)opn
; /* avoid a compiler warning */
2869 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2875 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2876 int rd
, int rs
, int rt
)
2878 const char *opn
= "mul vr54xx";
2879 TCGv t0
= tcg_temp_new();
2880 TCGv t1
= tcg_temp_new();
2882 gen_load_gpr(t0
, rs
);
2883 gen_load_gpr(t1
, rt
);
2886 case OPC_VR54XX_MULS
:
2887 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2890 case OPC_VR54XX_MULSU
:
2891 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2894 case OPC_VR54XX_MACC
:
2895 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2898 case OPC_VR54XX_MACCU
:
2899 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2902 case OPC_VR54XX_MSAC
:
2903 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2906 case OPC_VR54XX_MSACU
:
2907 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2910 case OPC_VR54XX_MULHI
:
2911 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2914 case OPC_VR54XX_MULHIU
:
2915 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2918 case OPC_VR54XX_MULSHI
:
2919 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2922 case OPC_VR54XX_MULSHIU
:
2923 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2926 case OPC_VR54XX_MACCHI
:
2927 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2930 case OPC_VR54XX_MACCHIU
:
2931 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2934 case OPC_VR54XX_MSACHI
:
2935 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2938 case OPC_VR54XX_MSACHIU
:
2939 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2943 MIPS_INVAL("mul vr54xx");
2944 generate_exception(ctx
, EXCP_RI
);
2947 gen_store_gpr(t0
, rd
);
2948 (void)opn
; /* avoid a compiler warning */
2949 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2956 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2959 const char *opn
= "CLx";
2967 t0
= tcg_temp_new();
2968 gen_load_gpr(t0
, rs
);
2971 gen_helper_clo(cpu_gpr
[rd
], t0
);
2975 gen_helper_clz(cpu_gpr
[rd
], t0
);
2978 #if defined(TARGET_MIPS64)
2980 gen_helper_dclo(cpu_gpr
[rd
], t0
);
2984 gen_helper_dclz(cpu_gpr
[rd
], t0
);
2989 (void)opn
; /* avoid a compiler warning */
2990 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
2994 /* Godson integer instructions */
2995 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
2996 int rd
, int rs
, int rt
)
2998 const char *opn
= "loongson";
3010 case OPC_MULTU_G_2E
:
3011 case OPC_MULTU_G_2F
:
3012 #if defined(TARGET_MIPS64)
3013 case OPC_DMULT_G_2E
:
3014 case OPC_DMULT_G_2F
:
3015 case OPC_DMULTU_G_2E
:
3016 case OPC_DMULTU_G_2F
:
3018 t0
= tcg_temp_new();
3019 t1
= tcg_temp_new();
3022 t0
= tcg_temp_local_new();
3023 t1
= tcg_temp_local_new();
3027 gen_load_gpr(t0
, rs
);
3028 gen_load_gpr(t1
, rt
);
3033 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3034 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3037 case OPC_MULTU_G_2E
:
3038 case OPC_MULTU_G_2F
:
3039 tcg_gen_ext32u_tl(t0
, t0
);
3040 tcg_gen_ext32u_tl(t1
, t1
);
3041 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3042 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3048 int l1
= gen_new_label();
3049 int l2
= gen_new_label();
3050 int l3
= gen_new_label();
3051 tcg_gen_ext32s_tl(t0
, t0
);
3052 tcg_gen_ext32s_tl(t1
, t1
);
3053 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3054 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3057 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3058 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3059 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3062 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3063 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3071 int l1
= gen_new_label();
3072 int l2
= gen_new_label();
3073 tcg_gen_ext32u_tl(t0
, t0
);
3074 tcg_gen_ext32u_tl(t1
, t1
);
3075 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3076 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3079 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3080 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3088 int l1
= gen_new_label();
3089 int l2
= gen_new_label();
3090 int l3
= gen_new_label();
3091 tcg_gen_ext32u_tl(t0
, t0
);
3092 tcg_gen_ext32u_tl(t1
, t1
);
3093 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3094 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3095 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3097 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3100 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3101 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3109 int l1
= gen_new_label();
3110 int l2
= gen_new_label();
3111 tcg_gen_ext32u_tl(t0
, t0
);
3112 tcg_gen_ext32u_tl(t1
, t1
);
3113 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3114 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3117 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3118 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3123 #if defined(TARGET_MIPS64)
3124 case OPC_DMULT_G_2E
:
3125 case OPC_DMULT_G_2F
:
3126 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3129 case OPC_DMULTU_G_2E
:
3130 case OPC_DMULTU_G_2F
:
3131 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3137 int l1
= gen_new_label();
3138 int l2
= gen_new_label();
3139 int l3
= gen_new_label();
3140 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3141 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3144 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3145 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3146 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3149 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3154 case OPC_DDIVU_G_2E
:
3155 case OPC_DDIVU_G_2F
:
3157 int l1
= gen_new_label();
3158 int l2
= gen_new_label();
3159 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3160 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3163 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3171 int l1
= gen_new_label();
3172 int l2
= gen_new_label();
3173 int l3
= gen_new_label();
3174 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3175 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3176 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3178 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3181 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3186 case OPC_DMODU_G_2E
:
3187 case OPC_DMODU_G_2F
:
3189 int l1
= gen_new_label();
3190 int l2
= gen_new_label();
3191 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3192 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3195 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3203 (void)opn
; /* avoid a compiler warning */
3204 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3209 /* Loongson multimedia instructions */
3210 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3212 const char *opn
= "loongson_cp2";
3213 uint32_t opc
, shift_max
;
3216 opc
= MASK_LMI(ctx
->opcode
);
3222 t0
= tcg_temp_local_new_i64();
3223 t1
= tcg_temp_local_new_i64();
3226 t0
= tcg_temp_new_i64();
3227 t1
= tcg_temp_new_i64();
3231 gen_load_fpr64(ctx
, t0
, rs
);
3232 gen_load_fpr64(ctx
, t1
, rt
);
3234 #define LMI_HELPER(UP, LO) \
3235 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3236 #define LMI_HELPER_1(UP, LO) \
3237 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3238 #define LMI_DIRECT(UP, LO, OP) \
3239 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3242 LMI_HELPER(PADDSH
, paddsh
);
3243 LMI_HELPER(PADDUSH
, paddush
);
3244 LMI_HELPER(PADDH
, paddh
);
3245 LMI_HELPER(PADDW
, paddw
);
3246 LMI_HELPER(PADDSB
, paddsb
);
3247 LMI_HELPER(PADDUSB
, paddusb
);
3248 LMI_HELPER(PADDB
, paddb
);
3250 LMI_HELPER(PSUBSH
, psubsh
);
3251 LMI_HELPER(PSUBUSH
, psubush
);
3252 LMI_HELPER(PSUBH
, psubh
);
3253 LMI_HELPER(PSUBW
, psubw
);
3254 LMI_HELPER(PSUBSB
, psubsb
);
3255 LMI_HELPER(PSUBUSB
, psubusb
);
3256 LMI_HELPER(PSUBB
, psubb
);
3258 LMI_HELPER(PSHUFH
, pshufh
);
3259 LMI_HELPER(PACKSSWH
, packsswh
);
3260 LMI_HELPER(PACKSSHB
, packsshb
);
3261 LMI_HELPER(PACKUSHB
, packushb
);
3263 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3264 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3265 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3266 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3267 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3268 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3270 LMI_HELPER(PAVGH
, pavgh
);
3271 LMI_HELPER(PAVGB
, pavgb
);
3272 LMI_HELPER(PMAXSH
, pmaxsh
);
3273 LMI_HELPER(PMINSH
, pminsh
);
3274 LMI_HELPER(PMAXUB
, pmaxub
);
3275 LMI_HELPER(PMINUB
, pminub
);
3277 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3278 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3279 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3280 LMI_HELPER(PCMPGTH
, pcmpgth
);
3281 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3282 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3284 LMI_HELPER(PSLLW
, psllw
);
3285 LMI_HELPER(PSLLH
, psllh
);
3286 LMI_HELPER(PSRLW
, psrlw
);
3287 LMI_HELPER(PSRLH
, psrlh
);
3288 LMI_HELPER(PSRAW
, psraw
);
3289 LMI_HELPER(PSRAH
, psrah
);
3291 LMI_HELPER(PMULLH
, pmullh
);
3292 LMI_HELPER(PMULHH
, pmulhh
);
3293 LMI_HELPER(PMULHUH
, pmulhuh
);
3294 LMI_HELPER(PMADDHW
, pmaddhw
);
3296 LMI_HELPER(PASUBUB
, pasubub
);
3297 LMI_HELPER_1(BIADD
, biadd
);
3298 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3300 LMI_DIRECT(PADDD
, paddd
, add
);
3301 LMI_DIRECT(PSUBD
, psubd
, sub
);
3302 LMI_DIRECT(XOR_CP2
, xor, xor);
3303 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3304 LMI_DIRECT(AND_CP2
, and, and);
3305 LMI_DIRECT(PANDN
, pandn
, andc
);
3306 LMI_DIRECT(OR
, or, or);
3309 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3313 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3317 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3321 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3326 tcg_gen_andi_i64(t1
, t1
, 3);
3327 tcg_gen_shli_i64(t1
, t1
, 4);
3328 tcg_gen_shr_i64(t0
, t0
, t1
);
3329 tcg_gen_ext16u_i64(t0
, t0
);
3334 tcg_gen_add_i64(t0
, t0
, t1
);
3335 tcg_gen_ext32s_i64(t0
, t0
);
3339 tcg_gen_sub_i64(t0
, t0
, t1
);
3340 tcg_gen_ext32s_i64(t0
, t0
);
3369 /* Make sure shift count isn't TCG undefined behaviour. */
3370 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3375 tcg_gen_shl_i64(t0
, t0
, t1
);
3379 /* Since SRA is UndefinedResult without sign-extended inputs,
3380 we can treat SRA and DSRA the same. */
3381 tcg_gen_sar_i64(t0
, t0
, t1
);
3384 /* We want to shift in zeros for SRL; zero-extend first. */
3385 tcg_gen_ext32u_i64(t0
, t0
);
3388 tcg_gen_shr_i64(t0
, t0
, t1
);
3392 if (shift_max
== 32) {
3393 tcg_gen_ext32s_i64(t0
, t0
);
3396 /* Shifts larger than MAX produce zero. */
3397 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3398 tcg_gen_neg_i64(t1
, t1
);
3399 tcg_gen_and_i64(t0
, t0
, t1
);
3405 TCGv_i64 t2
= tcg_temp_new_i64();
3406 int lab
= gen_new_label();
3408 tcg_gen_mov_i64(t2
, t0
);
3409 tcg_gen_add_i64(t0
, t1
, t2
);
3410 if (opc
== OPC_ADD_CP2
) {
3411 tcg_gen_ext32s_i64(t0
, t0
);
3413 tcg_gen_xor_i64(t1
, t1
, t2
);
3414 tcg_gen_xor_i64(t2
, t2
, t0
);
3415 tcg_gen_andc_i64(t1
, t2
, t1
);
3416 tcg_temp_free_i64(t2
);
3417 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3418 generate_exception(ctx
, EXCP_OVERFLOW
);
3421 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3428 TCGv_i64 t2
= tcg_temp_new_i64();
3429 int lab
= gen_new_label();
3431 tcg_gen_mov_i64(t2
, t0
);
3432 tcg_gen_sub_i64(t0
, t1
, t2
);
3433 if (opc
== OPC_SUB_CP2
) {
3434 tcg_gen_ext32s_i64(t0
, t0
);
3436 tcg_gen_xor_i64(t1
, t1
, t2
);
3437 tcg_gen_xor_i64(t2
, t2
, t0
);
3438 tcg_gen_and_i64(t1
, t1
, t2
);
3439 tcg_temp_free_i64(t2
);
3440 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3441 generate_exception(ctx
, EXCP_OVERFLOW
);
3444 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3449 tcg_gen_ext32u_i64(t0
, t0
);
3450 tcg_gen_ext32u_i64(t1
, t1
);
3451 tcg_gen_mul_i64(t0
, t0
, t1
);
3461 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3462 FD field is the CC field? */
3465 generate_exception(ctx
, EXCP_RI
);
3472 gen_store_fpr64(ctx
, t0
, rd
);
3474 (void)opn
; /* avoid a compiler warning */
3475 MIPS_DEBUG("%s %s, %s, %s", opn
,
3476 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3477 tcg_temp_free_i64(t0
);
3478 tcg_temp_free_i64(t1
);
3482 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3483 int rs
, int rt
, int16_t imm
)
3486 TCGv t0
= tcg_temp_new();
3487 TCGv t1
= tcg_temp_new();
3490 /* Load needed operands */
3498 /* Compare two registers */
3500 gen_load_gpr(t0
, rs
);
3501 gen_load_gpr(t1
, rt
);
3511 /* Compare register to immediate */
3512 if (rs
!= 0 || imm
!= 0) {
3513 gen_load_gpr(t0
, rs
);
3514 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3521 case OPC_TEQ
: /* rs == rs */
3522 case OPC_TEQI
: /* r0 == 0 */
3523 case OPC_TGE
: /* rs >= rs */
3524 case OPC_TGEI
: /* r0 >= 0 */
3525 case OPC_TGEU
: /* rs >= rs unsigned */
3526 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3528 generate_exception(ctx
, EXCP_TRAP
);
3530 case OPC_TLT
: /* rs < rs */
3531 case OPC_TLTI
: /* r0 < 0 */
3532 case OPC_TLTU
: /* rs < rs unsigned */
3533 case OPC_TLTIU
: /* r0 < 0 unsigned */
3534 case OPC_TNE
: /* rs != rs */
3535 case OPC_TNEI
: /* r0 != 0 */
3536 /* Never trap: treat as NOP. */
3540 int l1
= gen_new_label();
3545 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3549 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3553 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3557 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3561 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3565 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3568 generate_exception(ctx
, EXCP_TRAP
);
3575 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3577 TranslationBlock
*tb
;
3579 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3580 likely(!ctx
->singlestep_enabled
)) {
3583 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3586 if (ctx
->singlestep_enabled
) {
3587 save_cpu_state(ctx
, 0);
3588 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3594 /* Branches (before delay slot) */
3595 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3597 int rs
, int rt
, int32_t offset
)
3599 target_ulong btgt
= -1;
3601 int bcond_compute
= 0;
3602 TCGv t0
= tcg_temp_new();
3603 TCGv t1
= tcg_temp_new();
3605 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3606 #ifdef MIPS_DEBUG_DISAS
3607 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3609 generate_exception(ctx
, EXCP_RI
);
3613 /* Load needed operands */
3619 /* Compare two registers */
3621 gen_load_gpr(t0
, rs
);
3622 gen_load_gpr(t1
, rt
);
3625 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3641 /* Compare to zero */
3643 gen_load_gpr(t0
, rs
);
3646 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3649 #if defined(TARGET_MIPS64)
3651 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3653 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3656 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3663 /* Jump to immediate */
3664 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3670 /* Jump to register */
3671 if (offset
!= 0 && offset
!= 16) {
3672 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3673 others are reserved. */
3674 MIPS_INVAL("jump hint");
3675 generate_exception(ctx
, EXCP_RI
);
3678 gen_load_gpr(btarget
, rs
);
3681 MIPS_INVAL("branch/jump");
3682 generate_exception(ctx
, EXCP_RI
);
3685 if (bcond_compute
== 0) {
3686 /* No condition to be computed */
3688 case OPC_BEQ
: /* rx == rx */
3689 case OPC_BEQL
: /* rx == rx likely */
3690 case OPC_BGEZ
: /* 0 >= 0 */
3691 case OPC_BGEZL
: /* 0 >= 0 likely */
3692 case OPC_BLEZ
: /* 0 <= 0 */
3693 case OPC_BLEZL
: /* 0 <= 0 likely */
3695 ctx
->hflags
|= MIPS_HFLAG_B
;
3696 MIPS_DEBUG("balways");
3699 case OPC_BGEZAL
: /* 0 >= 0 */
3700 case OPC_BGEZALL
: /* 0 >= 0 likely */
3701 ctx
->hflags
|= (opc
== OPC_BGEZALS
3703 : MIPS_HFLAG_BDS32
);
3704 /* Always take and link */
3706 ctx
->hflags
|= MIPS_HFLAG_B
;
3707 MIPS_DEBUG("balways and link");
3709 case OPC_BNE
: /* rx != rx */
3710 case OPC_BGTZ
: /* 0 > 0 */
3711 case OPC_BLTZ
: /* 0 < 0 */
3713 MIPS_DEBUG("bnever (NOP)");
3716 case OPC_BLTZAL
: /* 0 < 0 */
3717 ctx
->hflags
|= (opc
== OPC_BLTZALS
3719 : MIPS_HFLAG_BDS32
);
3720 /* Handle as an unconditional branch to get correct delay
3723 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3724 ctx
->hflags
|= MIPS_HFLAG_B
;
3725 MIPS_DEBUG("bnever and link");
3727 case OPC_BLTZALL
: /* 0 < 0 likely */
3728 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3729 /* Skip the instruction in the delay slot */
3730 MIPS_DEBUG("bnever, link and skip");
3733 case OPC_BNEL
: /* rx != rx likely */
3734 case OPC_BGTZL
: /* 0 > 0 likely */
3735 case OPC_BLTZL
: /* 0 < 0 likely */
3736 /* Skip the instruction in the delay slot */
3737 MIPS_DEBUG("bnever and skip");
3741 ctx
->hflags
|= MIPS_HFLAG_B
;
3742 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3746 ctx
->hflags
|= MIPS_HFLAG_BX
;
3751 ctx
->hflags
|= MIPS_HFLAG_B
;
3752 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3754 : MIPS_HFLAG_BDS32
);
3755 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3758 ctx
->hflags
|= MIPS_HFLAG_BR
;
3759 if (insn_bytes
== 4)
3760 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3761 MIPS_DEBUG("jr %s", regnames
[rs
]);
3767 ctx
->hflags
|= MIPS_HFLAG_BR
;
3768 ctx
->hflags
|= (opc
== OPC_JALRS
3770 : MIPS_HFLAG_BDS32
);
3771 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3774 MIPS_INVAL("branch/jump");
3775 generate_exception(ctx
, EXCP_RI
);
3781 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3782 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3783 regnames
[rs
], regnames
[rt
], btgt
);
3786 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3787 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3788 regnames
[rs
], regnames
[rt
], btgt
);
3791 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3792 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3793 regnames
[rs
], regnames
[rt
], btgt
);
3796 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3797 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3798 regnames
[rs
], regnames
[rt
], btgt
);
3801 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3802 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3805 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3806 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3810 ctx
->hflags
|= (opc
== OPC_BGEZALS
3812 : MIPS_HFLAG_BDS32
);
3813 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3814 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3818 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3820 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3823 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3824 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3827 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3828 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3831 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3832 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3835 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3836 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3839 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3840 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3843 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3844 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3847 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3848 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3850 #if defined(TARGET_MIPS64)
3852 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3853 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3858 ctx
->hflags
|= (opc
== OPC_BLTZALS
3860 : MIPS_HFLAG_BDS32
);
3861 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3863 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3865 ctx
->hflags
|= MIPS_HFLAG_BC
;
3868 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3870 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3872 ctx
->hflags
|= MIPS_HFLAG_BL
;
3875 MIPS_INVAL("conditional branch/jump");
3876 generate_exception(ctx
, EXCP_RI
);
3880 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3881 blink
, ctx
->hflags
, btgt
);
3883 ctx
->btarget
= btgt
;
3885 int post_delay
= insn_bytes
;
3886 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3888 if (opc
!= OPC_JALRC
)
3889 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3891 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3895 if (insn_bytes
== 2)
3896 ctx
->hflags
|= MIPS_HFLAG_B16
;
3901 /* special3 bitfield operations */
3902 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3903 int rs
, int lsb
, int msb
)
3905 TCGv t0
= tcg_temp_new();
3906 TCGv t1
= tcg_temp_new();
3908 gen_load_gpr(t1
, rs
);
3913 tcg_gen_shri_tl(t0
, t1
, lsb
);
3915 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3917 tcg_gen_ext32s_tl(t0
, t0
);
3920 #if defined(TARGET_MIPS64)
3922 tcg_gen_shri_tl(t0
, t1
, lsb
);
3924 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3928 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3929 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3932 tcg_gen_shri_tl(t0
, t1
, lsb
);
3933 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3939 gen_load_gpr(t0
, rt
);
3940 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3941 tcg_gen_ext32s_tl(t0
, t0
);
3943 #if defined(TARGET_MIPS64)
3945 gen_load_gpr(t0
, rt
);
3946 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3949 gen_load_gpr(t0
, rt
);
3950 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3953 gen_load_gpr(t0
, rt
);
3954 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3959 MIPS_INVAL("bitops");
3960 generate_exception(ctx
, EXCP_RI
);
3965 gen_store_gpr(t0
, rt
);
3970 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
3975 /* If no destination, treat it as a NOP. */
3980 t0
= tcg_temp_new();
3981 gen_load_gpr(t0
, rt
);
3985 TCGv t1
= tcg_temp_new();
3987 tcg_gen_shri_tl(t1
, t0
, 8);
3988 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
3989 tcg_gen_shli_tl(t0
, t0
, 8);
3990 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
3991 tcg_gen_or_tl(t0
, t0
, t1
);
3993 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3997 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4000 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4002 #if defined(TARGET_MIPS64)
4005 TCGv t1
= tcg_temp_new();
4007 tcg_gen_shri_tl(t1
, t0
, 8);
4008 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4009 tcg_gen_shli_tl(t0
, t0
, 8);
4010 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4011 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4017 TCGv t1
= tcg_temp_new();
4019 tcg_gen_shri_tl(t1
, t0
, 16);
4020 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4021 tcg_gen_shli_tl(t0
, t0
, 16);
4022 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4023 tcg_gen_or_tl(t0
, t0
, t1
);
4024 tcg_gen_shri_tl(t1
, t0
, 32);
4025 tcg_gen_shli_tl(t0
, t0
, 32);
4026 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4032 MIPS_INVAL("bsfhl");
4033 generate_exception(ctx
, EXCP_RI
);
4040 #ifndef CONFIG_USER_ONLY
4041 /* CP0 (MMU and control) */
4042 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4044 TCGv_i32 t0
= tcg_temp_new_i32();
4046 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4047 tcg_gen_ext_i32_tl(arg
, t0
);
4048 tcg_temp_free_i32(t0
);
4051 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4053 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4054 tcg_gen_ext32s_tl(arg
, arg
);
4057 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4059 TCGv_i32 t0
= tcg_temp_new_i32();
4061 tcg_gen_trunc_tl_i32(t0
, arg
);
4062 tcg_gen_st_i32(t0
, cpu_env
, off
);
4063 tcg_temp_free_i32(t0
);
4066 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4068 tcg_gen_ext32s_tl(arg
, arg
);
4069 tcg_gen_st_tl(arg
, cpu_env
, off
);
4072 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4074 const char *rn
= "invalid";
4077 check_insn(ctx
, ISA_MIPS32
);
4083 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4087 check_insn(ctx
, ASE_MT
);
4088 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4092 check_insn(ctx
, ASE_MT
);
4093 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4097 check_insn(ctx
, ASE_MT
);
4098 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4108 gen_helper_mfc0_random(arg
, cpu_env
);
4112 check_insn(ctx
, ASE_MT
);
4113 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4117 check_insn(ctx
, ASE_MT
);
4118 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4122 check_insn(ctx
, ASE_MT
);
4123 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4127 check_insn(ctx
, ASE_MT
);
4128 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4132 check_insn(ctx
, ASE_MT
);
4133 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4137 check_insn(ctx
, ASE_MT
);
4138 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4139 rn
= "VPEScheFBack";
4142 check_insn(ctx
, ASE_MT
);
4143 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4153 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4154 tcg_gen_ext32s_tl(arg
, arg
);
4158 check_insn(ctx
, ASE_MT
);
4159 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4163 check_insn(ctx
, ASE_MT
);
4164 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4168 check_insn(ctx
, ASE_MT
);
4169 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4173 check_insn(ctx
, ASE_MT
);
4174 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4178 check_insn(ctx
, ASE_MT
);
4179 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4183 check_insn(ctx
, ASE_MT
);
4184 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4188 check_insn(ctx
, ASE_MT
);
4189 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4199 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4200 tcg_gen_ext32s_tl(arg
, arg
);
4210 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4211 tcg_gen_ext32s_tl(arg
, arg
);
4215 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4216 rn
= "ContextConfig";
4225 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4229 check_insn(ctx
, ISA_MIPS32R2
);
4230 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4240 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4244 check_insn(ctx
, ISA_MIPS32R2
);
4245 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4249 check_insn(ctx
, ISA_MIPS32R2
);
4250 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4254 check_insn(ctx
, ISA_MIPS32R2
);
4255 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4259 check_insn(ctx
, ISA_MIPS32R2
);
4260 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4264 check_insn(ctx
, ISA_MIPS32R2
);
4265 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4275 check_insn(ctx
, ISA_MIPS32R2
);
4276 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4286 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4287 tcg_gen_ext32s_tl(arg
, arg
);
4297 /* Mark as an IO operation because we read the time. */
4300 gen_helper_mfc0_count(arg
, cpu_env
);
4304 /* Break the TB to be able to take timer interrupts immediately
4305 after reading count. */
4306 ctx
->bstate
= BS_STOP
;
4309 /* 6,7 are implementation dependent */
4317 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4318 tcg_gen_ext32s_tl(arg
, arg
);
4328 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4331 /* 6,7 are implementation dependent */
4339 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4343 check_insn(ctx
, ISA_MIPS32R2
);
4344 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4348 check_insn(ctx
, ISA_MIPS32R2
);
4349 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4353 check_insn(ctx
, ISA_MIPS32R2
);
4354 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4364 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4374 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4375 tcg_gen_ext32s_tl(arg
, arg
);
4385 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4389 check_insn(ctx
, ISA_MIPS32R2
);
4390 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4400 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4404 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4408 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4412 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4416 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
4420 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
4423 /* 6,7 are implementation dependent */
4425 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4429 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4439 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4449 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4459 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4469 #if defined(TARGET_MIPS64)
4470 check_insn(ctx
, ISA_MIPS3
);
4471 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4472 tcg_gen_ext32s_tl(arg
, arg
);
4481 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4484 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4492 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4493 rn
= "'Diagnostic"; /* implementation dependent */
4498 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4502 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4503 rn
= "TraceControl";
4506 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4507 rn
= "TraceControl2";
4510 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4511 rn
= "UserTraceData";
4514 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4525 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4526 tcg_gen_ext32s_tl(arg
, arg
);
4536 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4537 rn
= "Performance0";
4540 // gen_helper_mfc0_performance1(arg);
4541 rn
= "Performance1";
4544 // gen_helper_mfc0_performance2(arg);
4545 rn
= "Performance2";
4548 // gen_helper_mfc0_performance3(arg);
4549 rn
= "Performance3";
4552 // gen_helper_mfc0_performance4(arg);
4553 rn
= "Performance4";
4556 // gen_helper_mfc0_performance5(arg);
4557 rn
= "Performance5";
4560 // gen_helper_mfc0_performance6(arg);
4561 rn
= "Performance6";
4564 // gen_helper_mfc0_performance7(arg);
4565 rn
= "Performance7";
4572 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4578 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4591 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4598 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4611 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4618 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4628 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4629 tcg_gen_ext32s_tl(arg
, arg
);
4640 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4650 (void)rn
; /* avoid a compiler warning */
4651 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4655 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4656 generate_exception(ctx
, EXCP_RI
);
4659 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4661 const char *rn
= "invalid";
4664 check_insn(ctx
, ISA_MIPS32
);
4673 gen_helper_mtc0_index(cpu_env
, arg
);
4677 check_insn(ctx
, ASE_MT
);
4678 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4682 check_insn(ctx
, ASE_MT
);
4687 check_insn(ctx
, ASE_MT
);
4702 check_insn(ctx
, ASE_MT
);
4703 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4707 check_insn(ctx
, ASE_MT
);
4708 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4712 check_insn(ctx
, ASE_MT
);
4713 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4717 check_insn(ctx
, ASE_MT
);
4718 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4722 check_insn(ctx
, ASE_MT
);
4723 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4727 check_insn(ctx
, ASE_MT
);
4728 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4729 rn
= "VPEScheFBack";
4732 check_insn(ctx
, ASE_MT
);
4733 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4743 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4747 check_insn(ctx
, ASE_MT
);
4748 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4752 check_insn(ctx
, ASE_MT
);
4753 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4757 check_insn(ctx
, ASE_MT
);
4758 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4762 check_insn(ctx
, ASE_MT
);
4763 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4767 check_insn(ctx
, ASE_MT
);
4768 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4772 check_insn(ctx
, ASE_MT
);
4773 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4777 check_insn(ctx
, ASE_MT
);
4778 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4788 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4798 gen_helper_mtc0_context(cpu_env
, arg
);
4802 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4803 rn
= "ContextConfig";
4812 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4816 check_insn(ctx
, ISA_MIPS32R2
);
4817 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4827 gen_helper_mtc0_wired(cpu_env
, arg
);
4831 check_insn(ctx
, ISA_MIPS32R2
);
4832 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4836 check_insn(ctx
, ISA_MIPS32R2
);
4837 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4841 check_insn(ctx
, ISA_MIPS32R2
);
4842 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4846 check_insn(ctx
, ISA_MIPS32R2
);
4847 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4851 check_insn(ctx
, ISA_MIPS32R2
);
4852 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4862 check_insn(ctx
, ISA_MIPS32R2
);
4863 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4877 gen_helper_mtc0_count(cpu_env
, arg
);
4880 /* 6,7 are implementation dependent */
4888 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4898 gen_helper_mtc0_compare(cpu_env
, arg
);
4901 /* 6,7 are implementation dependent */
4909 save_cpu_state(ctx
, 1);
4910 gen_helper_mtc0_status(cpu_env
, arg
);
4911 /* BS_STOP isn't good enough here, hflags may have changed. */
4912 gen_save_pc(ctx
->pc
+ 4);
4913 ctx
->bstate
= BS_EXCP
;
4917 check_insn(ctx
, ISA_MIPS32R2
);
4918 gen_helper_mtc0_intctl(cpu_env
, arg
);
4919 /* Stop translation as we may have switched the execution mode */
4920 ctx
->bstate
= BS_STOP
;
4924 check_insn(ctx
, ISA_MIPS32R2
);
4925 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4926 /* Stop translation as we may have switched the execution mode */
4927 ctx
->bstate
= BS_STOP
;
4931 check_insn(ctx
, ISA_MIPS32R2
);
4932 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4933 /* Stop translation as we may have switched the execution mode */
4934 ctx
->bstate
= BS_STOP
;
4944 save_cpu_state(ctx
, 1);
4945 gen_helper_mtc0_cause(cpu_env
, arg
);
4955 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4969 check_insn(ctx
, ISA_MIPS32R2
);
4970 gen_helper_mtc0_ebase(cpu_env
, arg
);
4980 gen_helper_mtc0_config0(cpu_env
, arg
);
4982 /* Stop translation as we may have switched the execution mode */
4983 ctx
->bstate
= BS_STOP
;
4986 /* ignored, read only */
4990 gen_helper_mtc0_config2(cpu_env
, arg
);
4992 /* Stop translation as we may have switched the execution mode */
4993 ctx
->bstate
= BS_STOP
;
4996 /* ignored, read only */
5000 gen_helper_mtc0_config4(cpu_env
, arg
);
5002 ctx
->bstate
= BS_STOP
;
5005 gen_helper_mtc0_config5(cpu_env
, arg
);
5007 /* Stop translation as we may have switched the execution mode */
5008 ctx
->bstate
= BS_STOP
;
5010 /* 6,7 are implementation dependent */
5020 rn
= "Invalid config selector";
5027 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5037 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5047 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5057 #if defined(TARGET_MIPS64)
5058 check_insn(ctx
, ISA_MIPS3
);
5059 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5068 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5071 gen_helper_mtc0_framemask(cpu_env
, arg
);
5080 rn
= "Diagnostic"; /* implementation dependent */
5085 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5086 /* BS_STOP isn't good enough here, hflags may have changed. */
5087 gen_save_pc(ctx
->pc
+ 4);
5088 ctx
->bstate
= BS_EXCP
;
5092 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5093 rn
= "TraceControl";
5094 /* Stop translation as we may have switched the execution mode */
5095 ctx
->bstate
= BS_STOP
;
5098 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5099 rn
= "TraceControl2";
5100 /* Stop translation as we may have switched the execution mode */
5101 ctx
->bstate
= BS_STOP
;
5104 /* Stop translation as we may have switched the execution mode */
5105 ctx
->bstate
= BS_STOP
;
5106 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5107 rn
= "UserTraceData";
5108 /* Stop translation as we may have switched the execution mode */
5109 ctx
->bstate
= BS_STOP
;
5112 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5113 /* Stop translation as we may have switched the execution mode */
5114 ctx
->bstate
= BS_STOP
;
5125 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5135 gen_helper_mtc0_performance0(cpu_env
, arg
);
5136 rn
= "Performance0";
5139 // gen_helper_mtc0_performance1(arg);
5140 rn
= "Performance1";
5143 // gen_helper_mtc0_performance2(arg);
5144 rn
= "Performance2";
5147 // gen_helper_mtc0_performance3(arg);
5148 rn
= "Performance3";
5151 // gen_helper_mtc0_performance4(arg);
5152 rn
= "Performance4";
5155 // gen_helper_mtc0_performance5(arg);
5156 rn
= "Performance5";
5159 // gen_helper_mtc0_performance6(arg);
5160 rn
= "Performance6";
5163 // gen_helper_mtc0_performance7(arg);
5164 rn
= "Performance7";
5190 gen_helper_mtc0_taglo(cpu_env
, arg
);
5197 gen_helper_mtc0_datalo(cpu_env
, arg
);
5210 gen_helper_mtc0_taghi(cpu_env
, arg
);
5217 gen_helper_mtc0_datahi(cpu_env
, arg
);
5228 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5239 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5245 /* Stop translation as we may have switched the execution mode */
5246 ctx
->bstate
= BS_STOP
;
5251 (void)rn
; /* avoid a compiler warning */
5252 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5253 /* For simplicity assume that all writes can cause interrupts. */
5256 ctx
->bstate
= BS_STOP
;
5261 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5262 generate_exception(ctx
, EXCP_RI
);
5265 #if defined(TARGET_MIPS64)
5266 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5268 const char *rn
= "invalid";
5271 check_insn(ctx
, ISA_MIPS64
);
5277 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5281 check_insn(ctx
, ASE_MT
);
5282 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5286 check_insn(ctx
, ASE_MT
);
5287 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5291 check_insn(ctx
, ASE_MT
);
5292 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5302 gen_helper_mfc0_random(arg
, cpu_env
);
5306 check_insn(ctx
, ASE_MT
);
5307 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5311 check_insn(ctx
, ASE_MT
);
5312 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5316 check_insn(ctx
, ASE_MT
);
5317 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5321 check_insn(ctx
, ASE_MT
);
5322 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5326 check_insn(ctx
, ASE_MT
);
5327 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5331 check_insn(ctx
, ASE_MT
);
5332 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5333 rn
= "VPEScheFBack";
5336 check_insn(ctx
, ASE_MT
);
5337 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5347 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5351 check_insn(ctx
, ASE_MT
);
5352 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5356 check_insn(ctx
, ASE_MT
);
5357 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5361 check_insn(ctx
, ASE_MT
);
5362 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5366 check_insn(ctx
, ASE_MT
);
5367 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5371 check_insn(ctx
, ASE_MT
);
5372 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5376 check_insn(ctx
, ASE_MT
);
5377 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5381 check_insn(ctx
, ASE_MT
);
5382 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5392 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5402 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5406 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5407 rn
= "ContextConfig";
5416 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5420 check_insn(ctx
, ISA_MIPS32R2
);
5421 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5431 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5435 check_insn(ctx
, ISA_MIPS32R2
);
5436 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5440 check_insn(ctx
, ISA_MIPS32R2
);
5441 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5445 check_insn(ctx
, ISA_MIPS32R2
);
5446 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5450 check_insn(ctx
, ISA_MIPS32R2
);
5451 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5455 check_insn(ctx
, ISA_MIPS32R2
);
5456 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5466 check_insn(ctx
, ISA_MIPS32R2
);
5467 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5477 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5487 /* Mark as an IO operation because we read the time. */
5490 gen_helper_mfc0_count(arg
, cpu_env
);
5494 /* Break the TB to be able to take timer interrupts immediately
5495 after reading count. */
5496 ctx
->bstate
= BS_STOP
;
5499 /* 6,7 are implementation dependent */
5507 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5517 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5520 /* 6,7 are implementation dependent */
5528 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5532 check_insn(ctx
, ISA_MIPS32R2
);
5533 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5537 check_insn(ctx
, ISA_MIPS32R2
);
5538 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5542 check_insn(ctx
, ISA_MIPS32R2
);
5543 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5553 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5563 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5573 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5577 check_insn(ctx
, ISA_MIPS32R2
);
5578 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5588 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5592 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5596 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5600 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5603 /* 6,7 are implementation dependent */
5605 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5609 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5619 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5629 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5639 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5649 check_insn(ctx
, ISA_MIPS3
);
5650 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5658 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5661 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5669 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5670 rn
= "'Diagnostic"; /* implementation dependent */
5675 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5679 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5680 rn
= "TraceControl";
5683 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5684 rn
= "TraceControl2";
5687 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5688 rn
= "UserTraceData";
5691 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5702 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5712 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5713 rn
= "Performance0";
5716 // gen_helper_dmfc0_performance1(arg);
5717 rn
= "Performance1";
5720 // gen_helper_dmfc0_performance2(arg);
5721 rn
= "Performance2";
5724 // gen_helper_dmfc0_performance3(arg);
5725 rn
= "Performance3";
5728 // gen_helper_dmfc0_performance4(arg);
5729 rn
= "Performance4";
5732 // gen_helper_dmfc0_performance5(arg);
5733 rn
= "Performance5";
5736 // gen_helper_dmfc0_performance6(arg);
5737 rn
= "Performance6";
5740 // gen_helper_dmfc0_performance7(arg);
5741 rn
= "Performance7";
5748 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5755 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5768 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5775 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5788 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5795 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5805 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5816 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5826 (void)rn
; /* avoid a compiler warning */
5827 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5831 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5832 generate_exception(ctx
, EXCP_RI
);
5835 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5837 const char *rn
= "invalid";
5840 check_insn(ctx
, ISA_MIPS64
);
5849 gen_helper_mtc0_index(cpu_env
, arg
);
5853 check_insn(ctx
, ASE_MT
);
5854 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5858 check_insn(ctx
, ASE_MT
);
5863 check_insn(ctx
, ASE_MT
);
5878 check_insn(ctx
, ASE_MT
);
5879 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5883 check_insn(ctx
, ASE_MT
);
5884 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5888 check_insn(ctx
, ASE_MT
);
5889 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5893 check_insn(ctx
, ASE_MT
);
5894 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5898 check_insn(ctx
, ASE_MT
);
5899 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5903 check_insn(ctx
, ASE_MT
);
5904 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5905 rn
= "VPEScheFBack";
5908 check_insn(ctx
, ASE_MT
);
5909 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5919 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5923 check_insn(ctx
, ASE_MT
);
5924 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5928 check_insn(ctx
, ASE_MT
);
5929 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5933 check_insn(ctx
, ASE_MT
);
5934 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5938 check_insn(ctx
, ASE_MT
);
5939 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5943 check_insn(ctx
, ASE_MT
);
5944 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5948 check_insn(ctx
, ASE_MT
);
5949 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5953 check_insn(ctx
, ASE_MT
);
5954 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5964 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5974 gen_helper_mtc0_context(cpu_env
, arg
);
5978 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5979 rn
= "ContextConfig";
5988 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5992 check_insn(ctx
, ISA_MIPS32R2
);
5993 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6003 gen_helper_mtc0_wired(cpu_env
, arg
);
6007 check_insn(ctx
, ISA_MIPS32R2
);
6008 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6012 check_insn(ctx
, ISA_MIPS32R2
);
6013 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6017 check_insn(ctx
, ISA_MIPS32R2
);
6018 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6022 check_insn(ctx
, ISA_MIPS32R2
);
6023 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6027 check_insn(ctx
, ISA_MIPS32R2
);
6028 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6038 check_insn(ctx
, ISA_MIPS32R2
);
6039 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6053 gen_helper_mtc0_count(cpu_env
, arg
);
6056 /* 6,7 are implementation dependent */
6060 /* Stop translation as we may have switched the execution mode */
6061 ctx
->bstate
= BS_STOP
;
6066 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6076 gen_helper_mtc0_compare(cpu_env
, arg
);
6079 /* 6,7 are implementation dependent */
6083 /* Stop translation as we may have switched the execution mode */
6084 ctx
->bstate
= BS_STOP
;
6089 save_cpu_state(ctx
, 1);
6090 gen_helper_mtc0_status(cpu_env
, arg
);
6091 /* BS_STOP isn't good enough here, hflags may have changed. */
6092 gen_save_pc(ctx
->pc
+ 4);
6093 ctx
->bstate
= BS_EXCP
;
6097 check_insn(ctx
, ISA_MIPS32R2
);
6098 gen_helper_mtc0_intctl(cpu_env
, arg
);
6099 /* Stop translation as we may have switched the execution mode */
6100 ctx
->bstate
= BS_STOP
;
6104 check_insn(ctx
, ISA_MIPS32R2
);
6105 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6106 /* Stop translation as we may have switched the execution mode */
6107 ctx
->bstate
= BS_STOP
;
6111 check_insn(ctx
, ISA_MIPS32R2
);
6112 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6113 /* Stop translation as we may have switched the execution mode */
6114 ctx
->bstate
= BS_STOP
;
6124 save_cpu_state(ctx
, 1);
6125 /* Mark as an IO operation because we may trigger a software
6130 gen_helper_mtc0_cause(cpu_env
, arg
);
6134 /* Stop translation as we may have triggered an intetrupt */
6135 ctx
->bstate
= BS_STOP
;
6145 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6159 check_insn(ctx
, ISA_MIPS32R2
);
6160 gen_helper_mtc0_ebase(cpu_env
, arg
);
6170 gen_helper_mtc0_config0(cpu_env
, arg
);
6172 /* Stop translation as we may have switched the execution mode */
6173 ctx
->bstate
= BS_STOP
;
6176 /* ignored, read only */
6180 gen_helper_mtc0_config2(cpu_env
, arg
);
6182 /* Stop translation as we may have switched the execution mode */
6183 ctx
->bstate
= BS_STOP
;
6189 /* 6,7 are implementation dependent */
6191 rn
= "Invalid config selector";
6198 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6208 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6218 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6228 check_insn(ctx
, ISA_MIPS3
);
6229 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6237 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6240 gen_helper_mtc0_framemask(cpu_env
, arg
);
6249 rn
= "Diagnostic"; /* implementation dependent */
6254 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6255 /* BS_STOP isn't good enough here, hflags may have changed. */
6256 gen_save_pc(ctx
->pc
+ 4);
6257 ctx
->bstate
= BS_EXCP
;
6261 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6262 /* Stop translation as we may have switched the execution mode */
6263 ctx
->bstate
= BS_STOP
;
6264 rn
= "TraceControl";
6267 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6268 /* Stop translation as we may have switched the execution mode */
6269 ctx
->bstate
= BS_STOP
;
6270 rn
= "TraceControl2";
6273 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6274 /* Stop translation as we may have switched the execution mode */
6275 ctx
->bstate
= BS_STOP
;
6276 rn
= "UserTraceData";
6279 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6280 /* Stop translation as we may have switched the execution mode */
6281 ctx
->bstate
= BS_STOP
;
6292 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6302 gen_helper_mtc0_performance0(cpu_env
, arg
);
6303 rn
= "Performance0";
6306 // gen_helper_mtc0_performance1(cpu_env, arg);
6307 rn
= "Performance1";
6310 // gen_helper_mtc0_performance2(cpu_env, arg);
6311 rn
= "Performance2";
6314 // gen_helper_mtc0_performance3(cpu_env, arg);
6315 rn
= "Performance3";
6318 // gen_helper_mtc0_performance4(cpu_env, arg);
6319 rn
= "Performance4";
6322 // gen_helper_mtc0_performance5(cpu_env, arg);
6323 rn
= "Performance5";
6326 // gen_helper_mtc0_performance6(cpu_env, arg);
6327 rn
= "Performance6";
6330 // gen_helper_mtc0_performance7(cpu_env, arg);
6331 rn
= "Performance7";
6357 gen_helper_mtc0_taglo(cpu_env
, arg
);
6364 gen_helper_mtc0_datalo(cpu_env
, arg
);
6377 gen_helper_mtc0_taghi(cpu_env
, arg
);
6384 gen_helper_mtc0_datahi(cpu_env
, arg
);
6395 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6406 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6412 /* Stop translation as we may have switched the execution mode */
6413 ctx
->bstate
= BS_STOP
;
6418 (void)rn
; /* avoid a compiler warning */
6419 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6420 /* For simplicity assume that all writes can cause interrupts. */
6423 ctx
->bstate
= BS_STOP
;
6428 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6429 generate_exception(ctx
, EXCP_RI
);
6431 #endif /* TARGET_MIPS64 */
6433 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6434 int u
, int sel
, int h
)
6436 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6437 TCGv t0
= tcg_temp_local_new();
6439 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6440 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6441 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6442 tcg_gen_movi_tl(t0
, -1);
6443 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6444 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6445 tcg_gen_movi_tl(t0
, -1);
6451 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6454 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6464 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6467 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6470 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6473 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6476 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6479 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6482 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6485 gen_mfc0(ctx
, t0
, rt
, sel
);
6492 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6495 gen_mfc0(ctx
, t0
, rt
, sel
);
6501 gen_helper_mftc0_status(t0
, cpu_env
);
6504 gen_mfc0(ctx
, t0
, rt
, sel
);
6510 gen_helper_mftc0_cause(t0
, cpu_env
);
6520 gen_helper_mftc0_epc(t0
, cpu_env
);
6530 gen_helper_mftc0_ebase(t0
, cpu_env
);
6540 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6550 gen_helper_mftc0_debug(t0
, cpu_env
);
6553 gen_mfc0(ctx
, t0
, rt
, sel
);
6558 gen_mfc0(ctx
, t0
, rt
, sel
);
6560 } else switch (sel
) {
6561 /* GPR registers. */
6563 gen_helper_1e0i(mftgpr
, t0
, rt
);
6565 /* Auxiliary CPU registers */
6569 gen_helper_1e0i(mftlo
, t0
, 0);
6572 gen_helper_1e0i(mfthi
, t0
, 0);
6575 gen_helper_1e0i(mftacx
, t0
, 0);
6578 gen_helper_1e0i(mftlo
, t0
, 1);
6581 gen_helper_1e0i(mfthi
, t0
, 1);
6584 gen_helper_1e0i(mftacx
, t0
, 1);
6587 gen_helper_1e0i(mftlo
, t0
, 2);
6590 gen_helper_1e0i(mfthi
, t0
, 2);
6593 gen_helper_1e0i(mftacx
, t0
, 2);
6596 gen_helper_1e0i(mftlo
, t0
, 3);
6599 gen_helper_1e0i(mfthi
, t0
, 3);
6602 gen_helper_1e0i(mftacx
, t0
, 3);
6605 gen_helper_mftdsp(t0
, cpu_env
);
6611 /* Floating point (COP1). */
6613 /* XXX: For now we support only a single FPU context. */
6615 TCGv_i32 fp0
= tcg_temp_new_i32();
6617 gen_load_fpr32(fp0
, rt
);
6618 tcg_gen_ext_i32_tl(t0
, fp0
);
6619 tcg_temp_free_i32(fp0
);
6621 TCGv_i32 fp0
= tcg_temp_new_i32();
6623 gen_load_fpr32h(ctx
, fp0
, rt
);
6624 tcg_gen_ext_i32_tl(t0
, fp0
);
6625 tcg_temp_free_i32(fp0
);
6629 /* XXX: For now we support only a single FPU context. */
6630 gen_helper_1e0i(cfc1
, t0
, rt
);
6632 /* COP2: Not implemented. */
6639 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6640 gen_store_gpr(t0
, rd
);
6646 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6647 generate_exception(ctx
, EXCP_RI
);
6650 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6651 int u
, int sel
, int h
)
6653 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6654 TCGv t0
= tcg_temp_local_new();
6656 gen_load_gpr(t0
, rt
);
6657 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6658 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6659 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6661 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6662 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6669 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6672 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6682 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6685 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6688 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6691 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6694 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6697 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6700 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6703 gen_mtc0(ctx
, t0
, rd
, sel
);
6710 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6713 gen_mtc0(ctx
, t0
, rd
, sel
);
6719 gen_helper_mttc0_status(cpu_env
, t0
);
6722 gen_mtc0(ctx
, t0
, rd
, sel
);
6728 gen_helper_mttc0_cause(cpu_env
, t0
);
6738 gen_helper_mttc0_ebase(cpu_env
, t0
);
6748 gen_helper_mttc0_debug(cpu_env
, t0
);
6751 gen_mtc0(ctx
, t0
, rd
, sel
);
6756 gen_mtc0(ctx
, t0
, rd
, sel
);
6758 } else switch (sel
) {
6759 /* GPR registers. */
6761 gen_helper_0e1i(mttgpr
, t0
, rd
);
6763 /* Auxiliary CPU registers */
6767 gen_helper_0e1i(mttlo
, t0
, 0);
6770 gen_helper_0e1i(mtthi
, t0
, 0);
6773 gen_helper_0e1i(mttacx
, t0
, 0);
6776 gen_helper_0e1i(mttlo
, t0
, 1);
6779 gen_helper_0e1i(mtthi
, t0
, 1);
6782 gen_helper_0e1i(mttacx
, t0
, 1);
6785 gen_helper_0e1i(mttlo
, t0
, 2);
6788 gen_helper_0e1i(mtthi
, t0
, 2);
6791 gen_helper_0e1i(mttacx
, t0
, 2);
6794 gen_helper_0e1i(mttlo
, t0
, 3);
6797 gen_helper_0e1i(mtthi
, t0
, 3);
6800 gen_helper_0e1i(mttacx
, t0
, 3);
6803 gen_helper_mttdsp(cpu_env
, t0
);
6809 /* Floating point (COP1). */
6811 /* XXX: For now we support only a single FPU context. */
6813 TCGv_i32 fp0
= tcg_temp_new_i32();
6815 tcg_gen_trunc_tl_i32(fp0
, t0
);
6816 gen_store_fpr32(fp0
, rd
);
6817 tcg_temp_free_i32(fp0
);
6819 TCGv_i32 fp0
= tcg_temp_new_i32();
6821 tcg_gen_trunc_tl_i32(fp0
, t0
);
6822 gen_store_fpr32h(ctx
, fp0
, rd
);
6823 tcg_temp_free_i32(fp0
);
6827 /* XXX: For now we support only a single FPU context. */
6829 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
6831 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
6832 tcg_temp_free_i32(fs_tmp
);
6835 /* COP2: Not implemented. */
6842 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6848 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6849 generate_exception(ctx
, EXCP_RI
);
6852 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6854 const char *opn
= "ldst";
6856 check_cp0_enabled(ctx
);
6863 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6868 TCGv t0
= tcg_temp_new();
6870 gen_load_gpr(t0
, rt
);
6871 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6876 #if defined(TARGET_MIPS64)
6878 check_insn(ctx
, ISA_MIPS3
);
6883 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6887 check_insn(ctx
, ISA_MIPS3
);
6889 TCGv t0
= tcg_temp_new();
6891 gen_load_gpr(t0
, rt
);
6892 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6899 check_insn(ctx
, ASE_MT
);
6904 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6905 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6909 check_insn(ctx
, ASE_MT
);
6910 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6911 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6916 if (!env
->tlb
->helper_tlbwi
)
6918 gen_helper_tlbwi(cpu_env
);
6922 if (!env
->tlb
->helper_tlbwr
)
6924 gen_helper_tlbwr(cpu_env
);
6928 if (!env
->tlb
->helper_tlbp
)
6930 gen_helper_tlbp(cpu_env
);
6934 if (!env
->tlb
->helper_tlbr
)
6936 gen_helper_tlbr(cpu_env
);
6940 check_insn(ctx
, ISA_MIPS2
);
6941 gen_helper_eret(cpu_env
);
6942 ctx
->bstate
= BS_EXCP
;
6946 check_insn(ctx
, ISA_MIPS32
);
6947 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6949 generate_exception(ctx
, EXCP_RI
);
6951 gen_helper_deret(cpu_env
);
6952 ctx
->bstate
= BS_EXCP
;
6957 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
6958 /* If we get an exception, we want to restart at next instruction */
6960 save_cpu_state(ctx
, 1);
6962 gen_helper_wait(cpu_env
);
6963 ctx
->bstate
= BS_EXCP
;
6968 generate_exception(ctx
, EXCP_RI
);
6971 (void)opn
; /* avoid a compiler warning */
6972 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
6974 #endif /* !CONFIG_USER_ONLY */
6976 /* CP1 Branches (before delay slot) */
6977 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
6978 int32_t cc
, int32_t offset
)
6980 target_ulong btarget
;
6981 const char *opn
= "cp1 cond branch";
6982 TCGv_i32 t0
= tcg_temp_new_i32();
6985 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
6987 btarget
= ctx
->pc
+ 4 + offset
;
6991 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6992 tcg_gen_not_i32(t0
, t0
);
6993 tcg_gen_andi_i32(t0
, t0
, 1);
6994 tcg_gen_extu_i32_tl(bcond
, t0
);
6998 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6999 tcg_gen_not_i32(t0
, t0
);
7000 tcg_gen_andi_i32(t0
, t0
, 1);
7001 tcg_gen_extu_i32_tl(bcond
, t0
);
7005 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7006 tcg_gen_andi_i32(t0
, t0
, 1);
7007 tcg_gen_extu_i32_tl(bcond
, t0
);
7011 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7012 tcg_gen_andi_i32(t0
, t0
, 1);
7013 tcg_gen_extu_i32_tl(bcond
, t0
);
7016 ctx
->hflags
|= MIPS_HFLAG_BL
;
7020 TCGv_i32 t1
= tcg_temp_new_i32();
7021 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7022 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7023 tcg_gen_nand_i32(t0
, t0
, t1
);
7024 tcg_temp_free_i32(t1
);
7025 tcg_gen_andi_i32(t0
, t0
, 1);
7026 tcg_gen_extu_i32_tl(bcond
, t0
);
7032 TCGv_i32 t1
= tcg_temp_new_i32();
7033 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7034 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7035 tcg_gen_or_i32(t0
, t0
, t1
);
7036 tcg_temp_free_i32(t1
);
7037 tcg_gen_andi_i32(t0
, t0
, 1);
7038 tcg_gen_extu_i32_tl(bcond
, t0
);
7044 TCGv_i32 t1
= tcg_temp_new_i32();
7045 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7046 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7047 tcg_gen_and_i32(t0
, t0
, t1
);
7048 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7049 tcg_gen_and_i32(t0
, t0
, t1
);
7050 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7051 tcg_gen_nand_i32(t0
, t0
, t1
);
7052 tcg_temp_free_i32(t1
);
7053 tcg_gen_andi_i32(t0
, t0
, 1);
7054 tcg_gen_extu_i32_tl(bcond
, t0
);
7060 TCGv_i32 t1
= tcg_temp_new_i32();
7061 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7062 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7063 tcg_gen_or_i32(t0
, t0
, t1
);
7064 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7065 tcg_gen_or_i32(t0
, t0
, t1
);
7066 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7067 tcg_gen_or_i32(t0
, t0
, t1
);
7068 tcg_temp_free_i32(t1
);
7069 tcg_gen_andi_i32(t0
, t0
, 1);
7070 tcg_gen_extu_i32_tl(bcond
, t0
);
7074 ctx
->hflags
|= MIPS_HFLAG_BC
;
7078 generate_exception (ctx
, EXCP_RI
);
7081 (void)opn
; /* avoid a compiler warning */
7082 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7083 ctx
->hflags
, btarget
);
7084 ctx
->btarget
= btarget
;
7087 tcg_temp_free_i32(t0
);
7090 /* Coprocessor 1 (FPU) */
7092 #define FOP(func, fmt) (((fmt) << 21) | (func))
7095 OPC_ADD_S
= FOP(0, FMT_S
),
7096 OPC_SUB_S
= FOP(1, FMT_S
),
7097 OPC_MUL_S
= FOP(2, FMT_S
),
7098 OPC_DIV_S
= FOP(3, FMT_S
),
7099 OPC_SQRT_S
= FOP(4, FMT_S
),
7100 OPC_ABS_S
= FOP(5, FMT_S
),
7101 OPC_MOV_S
= FOP(6, FMT_S
),
7102 OPC_NEG_S
= FOP(7, FMT_S
),
7103 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7104 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7105 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7106 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7107 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7108 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7109 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7110 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7111 OPC_MOVCF_S
= FOP(17, FMT_S
),
7112 OPC_MOVZ_S
= FOP(18, FMT_S
),
7113 OPC_MOVN_S
= FOP(19, FMT_S
),
7114 OPC_RECIP_S
= FOP(21, FMT_S
),
7115 OPC_RSQRT_S
= FOP(22, FMT_S
),
7116 OPC_RECIP2_S
= FOP(28, FMT_S
),
7117 OPC_RECIP1_S
= FOP(29, FMT_S
),
7118 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7119 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7120 OPC_CVT_D_S
= FOP(33, FMT_S
),
7121 OPC_CVT_W_S
= FOP(36, FMT_S
),
7122 OPC_CVT_L_S
= FOP(37, FMT_S
),
7123 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7124 OPC_CMP_F_S
= FOP (48, FMT_S
),
7125 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7126 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7127 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7128 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7129 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7130 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7131 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7132 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7133 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7134 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7135 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7136 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7137 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7138 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7139 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7141 OPC_ADD_D
= FOP(0, FMT_D
),
7142 OPC_SUB_D
= FOP(1, FMT_D
),
7143 OPC_MUL_D
= FOP(2, FMT_D
),
7144 OPC_DIV_D
= FOP(3, FMT_D
),
7145 OPC_SQRT_D
= FOP(4, FMT_D
),
7146 OPC_ABS_D
= FOP(5, FMT_D
),
7147 OPC_MOV_D
= FOP(6, FMT_D
),
7148 OPC_NEG_D
= FOP(7, FMT_D
),
7149 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7150 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7151 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7152 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7153 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7154 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7155 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7156 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7157 OPC_MOVCF_D
= FOP(17, FMT_D
),
7158 OPC_MOVZ_D
= FOP(18, FMT_D
),
7159 OPC_MOVN_D
= FOP(19, FMT_D
),
7160 OPC_RECIP_D
= FOP(21, FMT_D
),
7161 OPC_RSQRT_D
= FOP(22, FMT_D
),
7162 OPC_RECIP2_D
= FOP(28, FMT_D
),
7163 OPC_RECIP1_D
= FOP(29, FMT_D
),
7164 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7165 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7166 OPC_CVT_S_D
= FOP(32, FMT_D
),
7167 OPC_CVT_W_D
= FOP(36, FMT_D
),
7168 OPC_CVT_L_D
= FOP(37, FMT_D
),
7169 OPC_CMP_F_D
= FOP (48, FMT_D
),
7170 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7171 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7172 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7173 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7174 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7175 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7176 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7177 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7178 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7179 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7180 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7181 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7182 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7183 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7184 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7186 OPC_CVT_S_W
= FOP(32, FMT_W
),
7187 OPC_CVT_D_W
= FOP(33, FMT_W
),
7188 OPC_CVT_S_L
= FOP(32, FMT_L
),
7189 OPC_CVT_D_L
= FOP(33, FMT_L
),
7190 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7192 OPC_ADD_PS
= FOP(0, FMT_PS
),
7193 OPC_SUB_PS
= FOP(1, FMT_PS
),
7194 OPC_MUL_PS
= FOP(2, FMT_PS
),
7195 OPC_DIV_PS
= FOP(3, FMT_PS
),
7196 OPC_ABS_PS
= FOP(5, FMT_PS
),
7197 OPC_MOV_PS
= FOP(6, FMT_PS
),
7198 OPC_NEG_PS
= FOP(7, FMT_PS
),
7199 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7200 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7201 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7202 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7203 OPC_MULR_PS
= FOP(26, FMT_PS
),
7204 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7205 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7206 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7207 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7209 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7210 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7211 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7212 OPC_PLL_PS
= FOP(44, FMT_PS
),
7213 OPC_PLU_PS
= FOP(45, FMT_PS
),
7214 OPC_PUL_PS
= FOP(46, FMT_PS
),
7215 OPC_PUU_PS
= FOP(47, FMT_PS
),
7216 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7217 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7218 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7219 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7220 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7221 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7222 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7223 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7224 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7225 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7226 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7227 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7228 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7229 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7230 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7231 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7234 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7236 const char *opn
= "cp1 move";
7237 TCGv t0
= tcg_temp_new();
7242 TCGv_i32 fp0
= tcg_temp_new_i32();
7244 gen_load_fpr32(fp0
, fs
);
7245 tcg_gen_ext_i32_tl(t0
, fp0
);
7246 tcg_temp_free_i32(fp0
);
7248 gen_store_gpr(t0
, rt
);
7252 gen_load_gpr(t0
, rt
);
7254 TCGv_i32 fp0
= tcg_temp_new_i32();
7256 tcg_gen_trunc_tl_i32(fp0
, t0
);
7257 gen_store_fpr32(fp0
, fs
);
7258 tcg_temp_free_i32(fp0
);
7263 gen_helper_1e0i(cfc1
, t0
, fs
);
7264 gen_store_gpr(t0
, rt
);
7268 gen_load_gpr(t0
, rt
);
7270 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
7272 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7273 tcg_temp_free_i32(fs_tmp
);
7277 #if defined(TARGET_MIPS64)
7279 gen_load_fpr64(ctx
, t0
, fs
);
7280 gen_store_gpr(t0
, rt
);
7284 gen_load_gpr(t0
, rt
);
7285 gen_store_fpr64(ctx
, t0
, fs
);
7291 TCGv_i32 fp0
= tcg_temp_new_i32();
7293 gen_load_fpr32h(ctx
, fp0
, fs
);
7294 tcg_gen_ext_i32_tl(t0
, fp0
);
7295 tcg_temp_free_i32(fp0
);
7297 gen_store_gpr(t0
, rt
);
7301 gen_load_gpr(t0
, rt
);
7303 TCGv_i32 fp0
= tcg_temp_new_i32();
7305 tcg_gen_trunc_tl_i32(fp0
, t0
);
7306 gen_store_fpr32h(ctx
, fp0
, fs
);
7307 tcg_temp_free_i32(fp0
);
7313 generate_exception (ctx
, EXCP_RI
);
7316 (void)opn
; /* avoid a compiler warning */
7317 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7323 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7339 l1
= gen_new_label();
7340 t0
= tcg_temp_new_i32();
7341 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7342 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7343 tcg_temp_free_i32(t0
);
7345 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7347 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7352 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7355 TCGv_i32 t0
= tcg_temp_new_i32();
7356 int l1
= gen_new_label();
7363 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7364 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7365 gen_load_fpr32(t0
, fs
);
7366 gen_store_fpr32(t0
, fd
);
7368 tcg_temp_free_i32(t0
);
7371 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7374 TCGv_i32 t0
= tcg_temp_new_i32();
7376 int l1
= gen_new_label();
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
);
7386 fp0
= tcg_temp_new_i64();
7387 gen_load_fpr64(ctx
, fp0
, fs
);
7388 gen_store_fpr64(ctx
, fp0
, fd
);
7389 tcg_temp_free_i64(fp0
);
7393 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
7397 TCGv_i32 t0
= tcg_temp_new_i32();
7398 int l1
= gen_new_label();
7399 int l2
= gen_new_label();
7406 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7407 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7408 gen_load_fpr32(t0
, fs
);
7409 gen_store_fpr32(t0
, fd
);
7412 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7413 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7414 gen_load_fpr32h(ctx
, t0
, fs
);
7415 gen_store_fpr32h(ctx
, t0
, fd
);
7416 tcg_temp_free_i32(t0
);
7421 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7422 int ft
, int fs
, int fd
, int cc
)
7424 const char *opn
= "farith";
7425 const char *condnames
[] = {
7443 const char *condnames_abs
[] = {
7461 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7462 uint32_t func
= ctx
->opcode
& 0x3f;
7467 TCGv_i32 fp0
= tcg_temp_new_i32();
7468 TCGv_i32 fp1
= tcg_temp_new_i32();
7470 gen_load_fpr32(fp0
, fs
);
7471 gen_load_fpr32(fp1
, ft
);
7472 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7473 tcg_temp_free_i32(fp1
);
7474 gen_store_fpr32(fp0
, fd
);
7475 tcg_temp_free_i32(fp0
);
7482 TCGv_i32 fp0
= tcg_temp_new_i32();
7483 TCGv_i32 fp1
= tcg_temp_new_i32();
7485 gen_load_fpr32(fp0
, fs
);
7486 gen_load_fpr32(fp1
, ft
);
7487 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7488 tcg_temp_free_i32(fp1
);
7489 gen_store_fpr32(fp0
, fd
);
7490 tcg_temp_free_i32(fp0
);
7497 TCGv_i32 fp0
= tcg_temp_new_i32();
7498 TCGv_i32 fp1
= tcg_temp_new_i32();
7500 gen_load_fpr32(fp0
, fs
);
7501 gen_load_fpr32(fp1
, ft
);
7502 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7503 tcg_temp_free_i32(fp1
);
7504 gen_store_fpr32(fp0
, fd
);
7505 tcg_temp_free_i32(fp0
);
7512 TCGv_i32 fp0
= tcg_temp_new_i32();
7513 TCGv_i32 fp1
= tcg_temp_new_i32();
7515 gen_load_fpr32(fp0
, fs
);
7516 gen_load_fpr32(fp1
, ft
);
7517 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7518 tcg_temp_free_i32(fp1
);
7519 gen_store_fpr32(fp0
, fd
);
7520 tcg_temp_free_i32(fp0
);
7527 TCGv_i32 fp0
= tcg_temp_new_i32();
7529 gen_load_fpr32(fp0
, fs
);
7530 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7531 gen_store_fpr32(fp0
, fd
);
7532 tcg_temp_free_i32(fp0
);
7538 TCGv_i32 fp0
= tcg_temp_new_i32();
7540 gen_load_fpr32(fp0
, fs
);
7541 gen_helper_float_abs_s(fp0
, fp0
);
7542 gen_store_fpr32(fp0
, fd
);
7543 tcg_temp_free_i32(fp0
);
7549 TCGv_i32 fp0
= tcg_temp_new_i32();
7551 gen_load_fpr32(fp0
, fs
);
7552 gen_store_fpr32(fp0
, fd
);
7553 tcg_temp_free_i32(fp0
);
7559 TCGv_i32 fp0
= tcg_temp_new_i32();
7561 gen_load_fpr32(fp0
, fs
);
7562 gen_helper_float_chs_s(fp0
, fp0
);
7563 gen_store_fpr32(fp0
, fd
);
7564 tcg_temp_free_i32(fp0
);
7569 check_cp1_64bitmode(ctx
);
7571 TCGv_i32 fp32
= tcg_temp_new_i32();
7572 TCGv_i64 fp64
= tcg_temp_new_i64();
7574 gen_load_fpr32(fp32
, fs
);
7575 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7576 tcg_temp_free_i32(fp32
);
7577 gen_store_fpr64(ctx
, fp64
, fd
);
7578 tcg_temp_free_i64(fp64
);
7583 check_cp1_64bitmode(ctx
);
7585 TCGv_i32 fp32
= tcg_temp_new_i32();
7586 TCGv_i64 fp64
= tcg_temp_new_i64();
7588 gen_load_fpr32(fp32
, fs
);
7589 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7590 tcg_temp_free_i32(fp32
);
7591 gen_store_fpr64(ctx
, fp64
, fd
);
7592 tcg_temp_free_i64(fp64
);
7597 check_cp1_64bitmode(ctx
);
7599 TCGv_i32 fp32
= tcg_temp_new_i32();
7600 TCGv_i64 fp64
= tcg_temp_new_i64();
7602 gen_load_fpr32(fp32
, fs
);
7603 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7604 tcg_temp_free_i32(fp32
);
7605 gen_store_fpr64(ctx
, fp64
, fd
);
7606 tcg_temp_free_i64(fp64
);
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_floorl_s(fp64
, cpu_env
, fp32
);
7618 tcg_temp_free_i32(fp32
);
7619 gen_store_fpr64(ctx
, fp64
, fd
);
7620 tcg_temp_free_i64(fp64
);
7626 TCGv_i32 fp0
= tcg_temp_new_i32();
7628 gen_load_fpr32(fp0
, fs
);
7629 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7630 gen_store_fpr32(fp0
, fd
);
7631 tcg_temp_free_i32(fp0
);
7637 TCGv_i32 fp0
= tcg_temp_new_i32();
7639 gen_load_fpr32(fp0
, fs
);
7640 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7641 gen_store_fpr32(fp0
, fd
);
7642 tcg_temp_free_i32(fp0
);
7648 TCGv_i32 fp0
= tcg_temp_new_i32();
7650 gen_load_fpr32(fp0
, fs
);
7651 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7652 gen_store_fpr32(fp0
, fd
);
7653 tcg_temp_free_i32(fp0
);
7659 TCGv_i32 fp0
= tcg_temp_new_i32();
7661 gen_load_fpr32(fp0
, fs
);
7662 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7663 gen_store_fpr32(fp0
, fd
);
7664 tcg_temp_free_i32(fp0
);
7669 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7674 int l1
= gen_new_label();
7678 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7680 fp0
= tcg_temp_new_i32();
7681 gen_load_fpr32(fp0
, fs
);
7682 gen_store_fpr32(fp0
, fd
);
7683 tcg_temp_free_i32(fp0
);
7690 int l1
= gen_new_label();
7694 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7695 fp0
= tcg_temp_new_i32();
7696 gen_load_fpr32(fp0
, fs
);
7697 gen_store_fpr32(fp0
, fd
);
7698 tcg_temp_free_i32(fp0
);
7707 TCGv_i32 fp0
= tcg_temp_new_i32();
7709 gen_load_fpr32(fp0
, fs
);
7710 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7711 gen_store_fpr32(fp0
, fd
);
7712 tcg_temp_free_i32(fp0
);
7719 TCGv_i32 fp0
= tcg_temp_new_i32();
7721 gen_load_fpr32(fp0
, fs
);
7722 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7723 gen_store_fpr32(fp0
, fd
);
7724 tcg_temp_free_i32(fp0
);
7729 check_cp1_64bitmode(ctx
);
7731 TCGv_i32 fp0
= tcg_temp_new_i32();
7732 TCGv_i32 fp1
= tcg_temp_new_i32();
7734 gen_load_fpr32(fp0
, fs
);
7735 gen_load_fpr32(fp1
, ft
);
7736 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7737 tcg_temp_free_i32(fp1
);
7738 gen_store_fpr32(fp0
, fd
);
7739 tcg_temp_free_i32(fp0
);
7744 check_cp1_64bitmode(ctx
);
7746 TCGv_i32 fp0
= tcg_temp_new_i32();
7748 gen_load_fpr32(fp0
, fs
);
7749 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7750 gen_store_fpr32(fp0
, fd
);
7751 tcg_temp_free_i32(fp0
);
7756 check_cp1_64bitmode(ctx
);
7758 TCGv_i32 fp0
= tcg_temp_new_i32();
7760 gen_load_fpr32(fp0
, fs
);
7761 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7762 gen_store_fpr32(fp0
, fd
);
7763 tcg_temp_free_i32(fp0
);
7768 check_cp1_64bitmode(ctx
);
7770 TCGv_i32 fp0
= tcg_temp_new_i32();
7771 TCGv_i32 fp1
= tcg_temp_new_i32();
7773 gen_load_fpr32(fp0
, fs
);
7774 gen_load_fpr32(fp1
, ft
);
7775 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7776 tcg_temp_free_i32(fp1
);
7777 gen_store_fpr32(fp0
, fd
);
7778 tcg_temp_free_i32(fp0
);
7783 check_cp1_registers(ctx
, fd
);
7785 TCGv_i32 fp32
= tcg_temp_new_i32();
7786 TCGv_i64 fp64
= tcg_temp_new_i64();
7788 gen_load_fpr32(fp32
, fs
);
7789 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7790 tcg_temp_free_i32(fp32
);
7791 gen_store_fpr64(ctx
, fp64
, fd
);
7792 tcg_temp_free_i64(fp64
);
7798 TCGv_i32 fp0
= tcg_temp_new_i32();
7800 gen_load_fpr32(fp0
, fs
);
7801 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7802 gen_store_fpr32(fp0
, fd
);
7803 tcg_temp_free_i32(fp0
);
7808 check_cp1_64bitmode(ctx
);
7810 TCGv_i32 fp32
= tcg_temp_new_i32();
7811 TCGv_i64 fp64
= tcg_temp_new_i64();
7813 gen_load_fpr32(fp32
, fs
);
7814 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7815 tcg_temp_free_i32(fp32
);
7816 gen_store_fpr64(ctx
, fp64
, fd
);
7817 tcg_temp_free_i64(fp64
);
7822 check_cp1_64bitmode(ctx
);
7824 TCGv_i64 fp64
= tcg_temp_new_i64();
7825 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7826 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7828 gen_load_fpr32(fp32_0
, fs
);
7829 gen_load_fpr32(fp32_1
, ft
);
7830 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7831 tcg_temp_free_i32(fp32_1
);
7832 tcg_temp_free_i32(fp32_0
);
7833 gen_store_fpr64(ctx
, fp64
, fd
);
7834 tcg_temp_free_i64(fp64
);
7847 case OPC_CMP_NGLE_S
:
7854 if (ctx
->opcode
& (1 << 6)) {
7855 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7856 opn
= condnames_abs
[func
-48];
7858 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7859 opn
= condnames
[func
-48];
7863 check_cp1_registers(ctx
, fs
| ft
| fd
);
7865 TCGv_i64 fp0
= tcg_temp_new_i64();
7866 TCGv_i64 fp1
= tcg_temp_new_i64();
7868 gen_load_fpr64(ctx
, fp0
, fs
);
7869 gen_load_fpr64(ctx
, fp1
, ft
);
7870 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7871 tcg_temp_free_i64(fp1
);
7872 gen_store_fpr64(ctx
, fp0
, fd
);
7873 tcg_temp_free_i64(fp0
);
7879 check_cp1_registers(ctx
, fs
| ft
| fd
);
7881 TCGv_i64 fp0
= tcg_temp_new_i64();
7882 TCGv_i64 fp1
= tcg_temp_new_i64();
7884 gen_load_fpr64(ctx
, fp0
, fs
);
7885 gen_load_fpr64(ctx
, fp1
, ft
);
7886 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7887 tcg_temp_free_i64(fp1
);
7888 gen_store_fpr64(ctx
, fp0
, fd
);
7889 tcg_temp_free_i64(fp0
);
7895 check_cp1_registers(ctx
, fs
| ft
| fd
);
7897 TCGv_i64 fp0
= tcg_temp_new_i64();
7898 TCGv_i64 fp1
= tcg_temp_new_i64();
7900 gen_load_fpr64(ctx
, fp0
, fs
);
7901 gen_load_fpr64(ctx
, fp1
, ft
);
7902 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7903 tcg_temp_free_i64(fp1
);
7904 gen_store_fpr64(ctx
, fp0
, fd
);
7905 tcg_temp_free_i64(fp0
);
7911 check_cp1_registers(ctx
, fs
| ft
| fd
);
7913 TCGv_i64 fp0
= tcg_temp_new_i64();
7914 TCGv_i64 fp1
= tcg_temp_new_i64();
7916 gen_load_fpr64(ctx
, fp0
, fs
);
7917 gen_load_fpr64(ctx
, fp1
, ft
);
7918 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7919 tcg_temp_free_i64(fp1
);
7920 gen_store_fpr64(ctx
, fp0
, fd
);
7921 tcg_temp_free_i64(fp0
);
7927 check_cp1_registers(ctx
, fs
| fd
);
7929 TCGv_i64 fp0
= tcg_temp_new_i64();
7931 gen_load_fpr64(ctx
, fp0
, fs
);
7932 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7933 gen_store_fpr64(ctx
, fp0
, fd
);
7934 tcg_temp_free_i64(fp0
);
7939 check_cp1_registers(ctx
, fs
| fd
);
7941 TCGv_i64 fp0
= tcg_temp_new_i64();
7943 gen_load_fpr64(ctx
, fp0
, fs
);
7944 gen_helper_float_abs_d(fp0
, fp0
);
7945 gen_store_fpr64(ctx
, fp0
, fd
);
7946 tcg_temp_free_i64(fp0
);
7951 check_cp1_registers(ctx
, fs
| fd
);
7953 TCGv_i64 fp0
= tcg_temp_new_i64();
7955 gen_load_fpr64(ctx
, fp0
, fs
);
7956 gen_store_fpr64(ctx
, fp0
, fd
);
7957 tcg_temp_free_i64(fp0
);
7962 check_cp1_registers(ctx
, fs
| fd
);
7964 TCGv_i64 fp0
= tcg_temp_new_i64();
7966 gen_load_fpr64(ctx
, fp0
, fs
);
7967 gen_helper_float_chs_d(fp0
, fp0
);
7968 gen_store_fpr64(ctx
, fp0
, fd
);
7969 tcg_temp_free_i64(fp0
);
7974 check_cp1_64bitmode(ctx
);
7976 TCGv_i64 fp0
= tcg_temp_new_i64();
7978 gen_load_fpr64(ctx
, fp0
, fs
);
7979 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
7980 gen_store_fpr64(ctx
, fp0
, fd
);
7981 tcg_temp_free_i64(fp0
);
7986 check_cp1_64bitmode(ctx
);
7988 TCGv_i64 fp0
= tcg_temp_new_i64();
7990 gen_load_fpr64(ctx
, fp0
, fs
);
7991 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
7992 gen_store_fpr64(ctx
, fp0
, fd
);
7993 tcg_temp_free_i64(fp0
);
7998 check_cp1_64bitmode(ctx
);
8000 TCGv_i64 fp0
= tcg_temp_new_i64();
8002 gen_load_fpr64(ctx
, fp0
, fs
);
8003 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
8004 gen_store_fpr64(ctx
, fp0
, fd
);
8005 tcg_temp_free_i64(fp0
);
8010 check_cp1_64bitmode(ctx
);
8012 TCGv_i64 fp0
= tcg_temp_new_i64();
8014 gen_load_fpr64(ctx
, fp0
, fs
);
8015 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8016 gen_store_fpr64(ctx
, fp0
, fd
);
8017 tcg_temp_free_i64(fp0
);
8022 check_cp1_registers(ctx
, fs
);
8024 TCGv_i32 fp32
= tcg_temp_new_i32();
8025 TCGv_i64 fp64
= tcg_temp_new_i64();
8027 gen_load_fpr64(ctx
, fp64
, fs
);
8028 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8029 tcg_temp_free_i64(fp64
);
8030 gen_store_fpr32(fp32
, fd
);
8031 tcg_temp_free_i32(fp32
);
8036 check_cp1_registers(ctx
, fs
);
8038 TCGv_i32 fp32
= tcg_temp_new_i32();
8039 TCGv_i64 fp64
= tcg_temp_new_i64();
8041 gen_load_fpr64(ctx
, fp64
, fs
);
8042 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8043 tcg_temp_free_i64(fp64
);
8044 gen_store_fpr32(fp32
, fd
);
8045 tcg_temp_free_i32(fp32
);
8050 check_cp1_registers(ctx
, fs
);
8052 TCGv_i32 fp32
= tcg_temp_new_i32();
8053 TCGv_i64 fp64
= tcg_temp_new_i64();
8055 gen_load_fpr64(ctx
, fp64
, fs
);
8056 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8057 tcg_temp_free_i64(fp64
);
8058 gen_store_fpr32(fp32
, fd
);
8059 tcg_temp_free_i32(fp32
);
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_floorw_d(fp32
, cpu_env
, fp64
);
8071 tcg_temp_free_i64(fp64
);
8072 gen_store_fpr32(fp32
, fd
);
8073 tcg_temp_free_i32(fp32
);
8078 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8083 int l1
= gen_new_label();
8087 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8089 fp0
= tcg_temp_new_i64();
8090 gen_load_fpr64(ctx
, fp0
, fs
);
8091 gen_store_fpr64(ctx
, fp0
, fd
);
8092 tcg_temp_free_i64(fp0
);
8099 int l1
= gen_new_label();
8103 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8104 fp0
= tcg_temp_new_i64();
8105 gen_load_fpr64(ctx
, fp0
, fs
);
8106 gen_store_fpr64(ctx
, fp0
, fd
);
8107 tcg_temp_free_i64(fp0
);
8114 check_cp1_64bitmode(ctx
);
8116 TCGv_i64 fp0
= tcg_temp_new_i64();
8118 gen_load_fpr64(ctx
, fp0
, fs
);
8119 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8120 gen_store_fpr64(ctx
, fp0
, fd
);
8121 tcg_temp_free_i64(fp0
);
8126 check_cp1_64bitmode(ctx
);
8128 TCGv_i64 fp0
= tcg_temp_new_i64();
8130 gen_load_fpr64(ctx
, fp0
, fs
);
8131 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8132 gen_store_fpr64(ctx
, fp0
, fd
);
8133 tcg_temp_free_i64(fp0
);
8138 check_cp1_64bitmode(ctx
);
8140 TCGv_i64 fp0
= tcg_temp_new_i64();
8141 TCGv_i64 fp1
= tcg_temp_new_i64();
8143 gen_load_fpr64(ctx
, fp0
, fs
);
8144 gen_load_fpr64(ctx
, fp1
, ft
);
8145 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8146 tcg_temp_free_i64(fp1
);
8147 gen_store_fpr64(ctx
, fp0
, fd
);
8148 tcg_temp_free_i64(fp0
);
8153 check_cp1_64bitmode(ctx
);
8155 TCGv_i64 fp0
= tcg_temp_new_i64();
8157 gen_load_fpr64(ctx
, fp0
, fs
);
8158 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8159 gen_store_fpr64(ctx
, fp0
, fd
);
8160 tcg_temp_free_i64(fp0
);
8165 check_cp1_64bitmode(ctx
);
8167 TCGv_i64 fp0
= tcg_temp_new_i64();
8169 gen_load_fpr64(ctx
, fp0
, fs
);
8170 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8171 gen_store_fpr64(ctx
, fp0
, fd
);
8172 tcg_temp_free_i64(fp0
);
8177 check_cp1_64bitmode(ctx
);
8179 TCGv_i64 fp0
= tcg_temp_new_i64();
8180 TCGv_i64 fp1
= tcg_temp_new_i64();
8182 gen_load_fpr64(ctx
, fp0
, fs
);
8183 gen_load_fpr64(ctx
, fp1
, ft
);
8184 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8185 tcg_temp_free_i64(fp1
);
8186 gen_store_fpr64(ctx
, fp0
, fd
);
8187 tcg_temp_free_i64(fp0
);
8200 case OPC_CMP_NGLE_D
:
8207 if (ctx
->opcode
& (1 << 6)) {
8208 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8209 opn
= condnames_abs
[func
-48];
8211 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8212 opn
= condnames
[func
-48];
8216 check_cp1_registers(ctx
, fs
);
8218 TCGv_i32 fp32
= tcg_temp_new_i32();
8219 TCGv_i64 fp64
= tcg_temp_new_i64();
8221 gen_load_fpr64(ctx
, fp64
, fs
);
8222 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8223 tcg_temp_free_i64(fp64
);
8224 gen_store_fpr32(fp32
, fd
);
8225 tcg_temp_free_i32(fp32
);
8230 check_cp1_registers(ctx
, fs
);
8232 TCGv_i32 fp32
= tcg_temp_new_i32();
8233 TCGv_i64 fp64
= tcg_temp_new_i64();
8235 gen_load_fpr64(ctx
, fp64
, fs
);
8236 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8237 tcg_temp_free_i64(fp64
);
8238 gen_store_fpr32(fp32
, fd
);
8239 tcg_temp_free_i32(fp32
);
8244 check_cp1_64bitmode(ctx
);
8246 TCGv_i64 fp0
= tcg_temp_new_i64();
8248 gen_load_fpr64(ctx
, fp0
, fs
);
8249 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8250 gen_store_fpr64(ctx
, fp0
, fd
);
8251 tcg_temp_free_i64(fp0
);
8257 TCGv_i32 fp0
= tcg_temp_new_i32();
8259 gen_load_fpr32(fp0
, fs
);
8260 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8261 gen_store_fpr32(fp0
, fd
);
8262 tcg_temp_free_i32(fp0
);
8267 check_cp1_registers(ctx
, fd
);
8269 TCGv_i32 fp32
= tcg_temp_new_i32();
8270 TCGv_i64 fp64
= tcg_temp_new_i64();
8272 gen_load_fpr32(fp32
, fs
);
8273 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8274 tcg_temp_free_i32(fp32
);
8275 gen_store_fpr64(ctx
, fp64
, fd
);
8276 tcg_temp_free_i64(fp64
);
8281 check_cp1_64bitmode(ctx
);
8283 TCGv_i32 fp32
= tcg_temp_new_i32();
8284 TCGv_i64 fp64
= tcg_temp_new_i64();
8286 gen_load_fpr64(ctx
, fp64
, fs
);
8287 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8288 tcg_temp_free_i64(fp64
);
8289 gen_store_fpr32(fp32
, fd
);
8290 tcg_temp_free_i32(fp32
);
8295 check_cp1_64bitmode(ctx
);
8297 TCGv_i64 fp0
= tcg_temp_new_i64();
8299 gen_load_fpr64(ctx
, fp0
, fs
);
8300 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8301 gen_store_fpr64(ctx
, fp0
, fd
);
8302 tcg_temp_free_i64(fp0
);
8307 check_cp1_64bitmode(ctx
);
8309 TCGv_i64 fp0
= tcg_temp_new_i64();
8311 gen_load_fpr64(ctx
, fp0
, fs
);
8312 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8313 gen_store_fpr64(ctx
, fp0
, fd
);
8314 tcg_temp_free_i64(fp0
);
8319 check_cp1_64bitmode(ctx
);
8321 TCGv_i64 fp0
= tcg_temp_new_i64();
8322 TCGv_i64 fp1
= tcg_temp_new_i64();
8324 gen_load_fpr64(ctx
, fp0
, fs
);
8325 gen_load_fpr64(ctx
, fp1
, ft
);
8326 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8327 tcg_temp_free_i64(fp1
);
8328 gen_store_fpr64(ctx
, fp0
, fd
);
8329 tcg_temp_free_i64(fp0
);
8334 check_cp1_64bitmode(ctx
);
8336 TCGv_i64 fp0
= tcg_temp_new_i64();
8337 TCGv_i64 fp1
= tcg_temp_new_i64();
8339 gen_load_fpr64(ctx
, fp0
, fs
);
8340 gen_load_fpr64(ctx
, fp1
, ft
);
8341 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8342 tcg_temp_free_i64(fp1
);
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();
8352 TCGv_i64 fp1
= tcg_temp_new_i64();
8354 gen_load_fpr64(ctx
, fp0
, fs
);
8355 gen_load_fpr64(ctx
, fp1
, ft
);
8356 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8357 tcg_temp_free_i64(fp1
);
8358 gen_store_fpr64(ctx
, fp0
, fd
);
8359 tcg_temp_free_i64(fp0
);
8364 check_cp1_64bitmode(ctx
);
8366 TCGv_i64 fp0
= tcg_temp_new_i64();
8368 gen_load_fpr64(ctx
, fp0
, fs
);
8369 gen_helper_float_abs_ps(fp0
, fp0
);
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();
8380 gen_load_fpr64(ctx
, fp0
, fs
);
8381 gen_store_fpr64(ctx
, fp0
, fd
);
8382 tcg_temp_free_i64(fp0
);
8387 check_cp1_64bitmode(ctx
);
8389 TCGv_i64 fp0
= tcg_temp_new_i64();
8391 gen_load_fpr64(ctx
, fp0
, fs
);
8392 gen_helper_float_chs_ps(fp0
, fp0
);
8393 gen_store_fpr64(ctx
, fp0
, fd
);
8394 tcg_temp_free_i64(fp0
);
8399 check_cp1_64bitmode(ctx
);
8400 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8404 check_cp1_64bitmode(ctx
);
8406 int l1
= gen_new_label();
8410 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8411 fp0
= tcg_temp_new_i64();
8412 gen_load_fpr64(ctx
, fp0
, fs
);
8413 gen_store_fpr64(ctx
, fp0
, fd
);
8414 tcg_temp_free_i64(fp0
);
8420 check_cp1_64bitmode(ctx
);
8422 int l1
= gen_new_label();
8426 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8427 fp0
= tcg_temp_new_i64();
8428 gen_load_fpr64(ctx
, fp0
, fs
);
8429 gen_store_fpr64(ctx
, fp0
, fd
);
8430 tcg_temp_free_i64(fp0
);
8437 check_cp1_64bitmode(ctx
);
8439 TCGv_i64 fp0
= tcg_temp_new_i64();
8440 TCGv_i64 fp1
= tcg_temp_new_i64();
8442 gen_load_fpr64(ctx
, fp0
, ft
);
8443 gen_load_fpr64(ctx
, fp1
, fs
);
8444 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8445 tcg_temp_free_i64(fp1
);
8446 gen_store_fpr64(ctx
, fp0
, fd
);
8447 tcg_temp_free_i64(fp0
);
8452 check_cp1_64bitmode(ctx
);
8454 TCGv_i64 fp0
= tcg_temp_new_i64();
8455 TCGv_i64 fp1
= tcg_temp_new_i64();
8457 gen_load_fpr64(ctx
, fp0
, ft
);
8458 gen_load_fpr64(ctx
, fp1
, fs
);
8459 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8460 tcg_temp_free_i64(fp1
);
8461 gen_store_fpr64(ctx
, fp0
, fd
);
8462 tcg_temp_free_i64(fp0
);
8467 check_cp1_64bitmode(ctx
);
8469 TCGv_i64 fp0
= tcg_temp_new_i64();
8470 TCGv_i64 fp1
= tcg_temp_new_i64();
8472 gen_load_fpr64(ctx
, fp0
, fs
);
8473 gen_load_fpr64(ctx
, fp1
, ft
);
8474 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8475 tcg_temp_free_i64(fp1
);
8476 gen_store_fpr64(ctx
, fp0
, fd
);
8477 tcg_temp_free_i64(fp0
);
8482 check_cp1_64bitmode(ctx
);
8484 TCGv_i64 fp0
= tcg_temp_new_i64();
8486 gen_load_fpr64(ctx
, fp0
, fs
);
8487 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
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();
8498 gen_load_fpr64(ctx
, fp0
, fs
);
8499 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8500 gen_store_fpr64(ctx
, fp0
, fd
);
8501 tcg_temp_free_i64(fp0
);
8506 check_cp1_64bitmode(ctx
);
8508 TCGv_i64 fp0
= tcg_temp_new_i64();
8509 TCGv_i64 fp1
= tcg_temp_new_i64();
8511 gen_load_fpr64(ctx
, fp0
, fs
);
8512 gen_load_fpr64(ctx
, fp1
, ft
);
8513 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8514 tcg_temp_free_i64(fp1
);
8515 gen_store_fpr64(ctx
, fp0
, fd
);
8516 tcg_temp_free_i64(fp0
);
8521 check_cp1_64bitmode(ctx
);
8523 TCGv_i32 fp0
= tcg_temp_new_i32();
8525 gen_load_fpr32h(ctx
, fp0
, fs
);
8526 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8527 gen_store_fpr32(fp0
, fd
);
8528 tcg_temp_free_i32(fp0
);
8533 check_cp1_64bitmode(ctx
);
8535 TCGv_i64 fp0
= tcg_temp_new_i64();
8537 gen_load_fpr64(ctx
, fp0
, fs
);
8538 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8539 gen_store_fpr64(ctx
, fp0
, fd
);
8540 tcg_temp_free_i64(fp0
);
8545 check_cp1_64bitmode(ctx
);
8547 TCGv_i32 fp0
= tcg_temp_new_i32();
8549 gen_load_fpr32(fp0
, fs
);
8550 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8551 gen_store_fpr32(fp0
, fd
);
8552 tcg_temp_free_i32(fp0
);
8557 check_cp1_64bitmode(ctx
);
8559 TCGv_i32 fp0
= tcg_temp_new_i32();
8560 TCGv_i32 fp1
= tcg_temp_new_i32();
8562 gen_load_fpr32(fp0
, fs
);
8563 gen_load_fpr32(fp1
, ft
);
8564 gen_store_fpr32h(ctx
, fp0
, fd
);
8565 gen_store_fpr32(fp1
, fd
);
8566 tcg_temp_free_i32(fp0
);
8567 tcg_temp_free_i32(fp1
);
8572 check_cp1_64bitmode(ctx
);
8574 TCGv_i32 fp0
= tcg_temp_new_i32();
8575 TCGv_i32 fp1
= tcg_temp_new_i32();
8577 gen_load_fpr32(fp0
, fs
);
8578 gen_load_fpr32h(ctx
, fp1
, ft
);
8579 gen_store_fpr32(fp1
, fd
);
8580 gen_store_fpr32h(ctx
, fp0
, fd
);
8581 tcg_temp_free_i32(fp0
);
8582 tcg_temp_free_i32(fp1
);
8587 check_cp1_64bitmode(ctx
);
8589 TCGv_i32 fp0
= tcg_temp_new_i32();
8590 TCGv_i32 fp1
= tcg_temp_new_i32();
8592 gen_load_fpr32h(ctx
, fp0
, fs
);
8593 gen_load_fpr32(fp1
, ft
);
8594 gen_store_fpr32(fp1
, fd
);
8595 gen_store_fpr32h(ctx
, fp0
, fd
);
8596 tcg_temp_free_i32(fp0
);
8597 tcg_temp_free_i32(fp1
);
8602 check_cp1_64bitmode(ctx
);
8604 TCGv_i32 fp0
= tcg_temp_new_i32();
8605 TCGv_i32 fp1
= tcg_temp_new_i32();
8607 gen_load_fpr32h(ctx
, fp0
, fs
);
8608 gen_load_fpr32h(ctx
, fp1
, ft
);
8609 gen_store_fpr32(fp1
, fd
);
8610 gen_store_fpr32h(ctx
, fp0
, fd
);
8611 tcg_temp_free_i32(fp0
);
8612 tcg_temp_free_i32(fp1
);
8619 case OPC_CMP_UEQ_PS
:
8620 case OPC_CMP_OLT_PS
:
8621 case OPC_CMP_ULT_PS
:
8622 case OPC_CMP_OLE_PS
:
8623 case OPC_CMP_ULE_PS
:
8625 case OPC_CMP_NGLE_PS
:
8626 case OPC_CMP_SEQ_PS
:
8627 case OPC_CMP_NGL_PS
:
8629 case OPC_CMP_NGE_PS
:
8631 case OPC_CMP_NGT_PS
:
8632 if (ctx
->opcode
& (1 << 6)) {
8633 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8634 opn
= condnames_abs
[func
-48];
8636 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8637 opn
= condnames
[func
-48];
8642 generate_exception (ctx
, EXCP_RI
);
8645 (void)opn
; /* avoid a compiler warning */
8648 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8651 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8654 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8659 /* Coprocessor 3 (FPU) */
8660 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8661 int fd
, int fs
, int base
, int index
)
8663 const char *opn
= "extended float load/store";
8665 TCGv t0
= tcg_temp_new();
8668 gen_load_gpr(t0
, index
);
8669 } else if (index
== 0) {
8670 gen_load_gpr(t0
, base
);
8672 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8674 /* Don't do NOP if destination is zero: we must perform the actual
8680 TCGv_i32 fp0
= tcg_temp_new_i32();
8682 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
8683 tcg_gen_trunc_tl_i32(fp0
, t0
);
8684 gen_store_fpr32(fp0
, fd
);
8685 tcg_temp_free_i32(fp0
);
8691 check_cp1_registers(ctx
, fd
);
8693 TCGv_i64 fp0
= tcg_temp_new_i64();
8694 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8695 gen_store_fpr64(ctx
, fp0
, fd
);
8696 tcg_temp_free_i64(fp0
);
8701 check_cp1_64bitmode(ctx
);
8702 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8704 TCGv_i64 fp0
= tcg_temp_new_i64();
8706 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8707 gen_store_fpr64(ctx
, fp0
, fd
);
8708 tcg_temp_free_i64(fp0
);
8715 TCGv_i32 fp0
= tcg_temp_new_i32();
8716 gen_load_fpr32(fp0
, fs
);
8717 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
8718 tcg_temp_free_i32(fp0
);
8725 check_cp1_registers(ctx
, fs
);
8727 TCGv_i64 fp0
= tcg_temp_new_i64();
8728 gen_load_fpr64(ctx
, fp0
, fs
);
8729 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8730 tcg_temp_free_i64(fp0
);
8736 check_cp1_64bitmode(ctx
);
8737 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8739 TCGv_i64 fp0
= tcg_temp_new_i64();
8740 gen_load_fpr64(ctx
, fp0
, fs
);
8741 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8742 tcg_temp_free_i64(fp0
);
8749 (void)opn
; (void)store
; /* avoid compiler warnings */
8750 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8751 regnames
[index
], regnames
[base
]);
8754 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8755 int fd
, int fr
, int fs
, int ft
)
8757 const char *opn
= "flt3_arith";
8761 check_cp1_64bitmode(ctx
);
8763 TCGv t0
= tcg_temp_local_new();
8764 TCGv_i32 fp
= tcg_temp_new_i32();
8765 TCGv_i32 fph
= tcg_temp_new_i32();
8766 int l1
= gen_new_label();
8767 int l2
= gen_new_label();
8769 gen_load_gpr(t0
, fr
);
8770 tcg_gen_andi_tl(t0
, t0
, 0x7);
8772 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8773 gen_load_fpr32(fp
, fs
);
8774 gen_load_fpr32h(ctx
, fph
, fs
);
8775 gen_store_fpr32(fp
, fd
);
8776 gen_store_fpr32h(ctx
, fph
, fd
);
8779 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8781 #ifdef TARGET_WORDS_BIGENDIAN
8782 gen_load_fpr32(fp
, fs
);
8783 gen_load_fpr32h(ctx
, fph
, ft
);
8784 gen_store_fpr32h(ctx
, fp
, fd
);
8785 gen_store_fpr32(fph
, fd
);
8787 gen_load_fpr32h(ctx
, fph
, fs
);
8788 gen_load_fpr32(fp
, ft
);
8789 gen_store_fpr32(fph
, fd
);
8790 gen_store_fpr32h(ctx
, fp
, fd
);
8793 tcg_temp_free_i32(fp
);
8794 tcg_temp_free_i32(fph
);
8801 TCGv_i32 fp0
= tcg_temp_new_i32();
8802 TCGv_i32 fp1
= tcg_temp_new_i32();
8803 TCGv_i32 fp2
= tcg_temp_new_i32();
8805 gen_load_fpr32(fp0
, fs
);
8806 gen_load_fpr32(fp1
, ft
);
8807 gen_load_fpr32(fp2
, fr
);
8808 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8809 tcg_temp_free_i32(fp0
);
8810 tcg_temp_free_i32(fp1
);
8811 gen_store_fpr32(fp2
, fd
);
8812 tcg_temp_free_i32(fp2
);
8818 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8820 TCGv_i64 fp0
= tcg_temp_new_i64();
8821 TCGv_i64 fp1
= tcg_temp_new_i64();
8822 TCGv_i64 fp2
= tcg_temp_new_i64();
8824 gen_load_fpr64(ctx
, fp0
, fs
);
8825 gen_load_fpr64(ctx
, fp1
, ft
);
8826 gen_load_fpr64(ctx
, fp2
, fr
);
8827 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8828 tcg_temp_free_i64(fp0
);
8829 tcg_temp_free_i64(fp1
);
8830 gen_store_fpr64(ctx
, fp2
, fd
);
8831 tcg_temp_free_i64(fp2
);
8836 check_cp1_64bitmode(ctx
);
8838 TCGv_i64 fp0
= tcg_temp_new_i64();
8839 TCGv_i64 fp1
= tcg_temp_new_i64();
8840 TCGv_i64 fp2
= tcg_temp_new_i64();
8842 gen_load_fpr64(ctx
, fp0
, fs
);
8843 gen_load_fpr64(ctx
, fp1
, ft
);
8844 gen_load_fpr64(ctx
, fp2
, fr
);
8845 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8846 tcg_temp_free_i64(fp0
);
8847 tcg_temp_free_i64(fp1
);
8848 gen_store_fpr64(ctx
, fp2
, fd
);
8849 tcg_temp_free_i64(fp2
);
8856 TCGv_i32 fp0
= tcg_temp_new_i32();
8857 TCGv_i32 fp1
= tcg_temp_new_i32();
8858 TCGv_i32 fp2
= tcg_temp_new_i32();
8860 gen_load_fpr32(fp0
, fs
);
8861 gen_load_fpr32(fp1
, ft
);
8862 gen_load_fpr32(fp2
, fr
);
8863 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8864 tcg_temp_free_i32(fp0
);
8865 tcg_temp_free_i32(fp1
);
8866 gen_store_fpr32(fp2
, fd
);
8867 tcg_temp_free_i32(fp2
);
8873 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8875 TCGv_i64 fp0
= tcg_temp_new_i64();
8876 TCGv_i64 fp1
= tcg_temp_new_i64();
8877 TCGv_i64 fp2
= tcg_temp_new_i64();
8879 gen_load_fpr64(ctx
, fp0
, fs
);
8880 gen_load_fpr64(ctx
, fp1
, ft
);
8881 gen_load_fpr64(ctx
, fp2
, fr
);
8882 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8883 tcg_temp_free_i64(fp0
);
8884 tcg_temp_free_i64(fp1
);
8885 gen_store_fpr64(ctx
, fp2
, fd
);
8886 tcg_temp_free_i64(fp2
);
8891 check_cp1_64bitmode(ctx
);
8893 TCGv_i64 fp0
= tcg_temp_new_i64();
8894 TCGv_i64 fp1
= tcg_temp_new_i64();
8895 TCGv_i64 fp2
= tcg_temp_new_i64();
8897 gen_load_fpr64(ctx
, fp0
, fs
);
8898 gen_load_fpr64(ctx
, fp1
, ft
);
8899 gen_load_fpr64(ctx
, fp2
, fr
);
8900 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8901 tcg_temp_free_i64(fp0
);
8902 tcg_temp_free_i64(fp1
);
8903 gen_store_fpr64(ctx
, fp2
, fd
);
8904 tcg_temp_free_i64(fp2
);
8911 TCGv_i32 fp0
= tcg_temp_new_i32();
8912 TCGv_i32 fp1
= tcg_temp_new_i32();
8913 TCGv_i32 fp2
= tcg_temp_new_i32();
8915 gen_load_fpr32(fp0
, fs
);
8916 gen_load_fpr32(fp1
, ft
);
8917 gen_load_fpr32(fp2
, fr
);
8918 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8919 tcg_temp_free_i32(fp0
);
8920 tcg_temp_free_i32(fp1
);
8921 gen_store_fpr32(fp2
, fd
);
8922 tcg_temp_free_i32(fp2
);
8928 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8930 TCGv_i64 fp0
= tcg_temp_new_i64();
8931 TCGv_i64 fp1
= tcg_temp_new_i64();
8932 TCGv_i64 fp2
= tcg_temp_new_i64();
8934 gen_load_fpr64(ctx
, fp0
, fs
);
8935 gen_load_fpr64(ctx
, fp1
, ft
);
8936 gen_load_fpr64(ctx
, fp2
, fr
);
8937 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8938 tcg_temp_free_i64(fp0
);
8939 tcg_temp_free_i64(fp1
);
8940 gen_store_fpr64(ctx
, fp2
, fd
);
8941 tcg_temp_free_i64(fp2
);
8946 check_cp1_64bitmode(ctx
);
8948 TCGv_i64 fp0
= tcg_temp_new_i64();
8949 TCGv_i64 fp1
= tcg_temp_new_i64();
8950 TCGv_i64 fp2
= tcg_temp_new_i64();
8952 gen_load_fpr64(ctx
, fp0
, fs
);
8953 gen_load_fpr64(ctx
, fp1
, ft
);
8954 gen_load_fpr64(ctx
, fp2
, fr
);
8955 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8956 tcg_temp_free_i64(fp0
);
8957 tcg_temp_free_i64(fp1
);
8958 gen_store_fpr64(ctx
, fp2
, fd
);
8959 tcg_temp_free_i64(fp2
);
8966 TCGv_i32 fp0
= tcg_temp_new_i32();
8967 TCGv_i32 fp1
= tcg_temp_new_i32();
8968 TCGv_i32 fp2
= tcg_temp_new_i32();
8970 gen_load_fpr32(fp0
, fs
);
8971 gen_load_fpr32(fp1
, ft
);
8972 gen_load_fpr32(fp2
, fr
);
8973 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8974 tcg_temp_free_i32(fp0
);
8975 tcg_temp_free_i32(fp1
);
8976 gen_store_fpr32(fp2
, fd
);
8977 tcg_temp_free_i32(fp2
);
8983 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8985 TCGv_i64 fp0
= tcg_temp_new_i64();
8986 TCGv_i64 fp1
= tcg_temp_new_i64();
8987 TCGv_i64 fp2
= tcg_temp_new_i64();
8989 gen_load_fpr64(ctx
, fp0
, fs
);
8990 gen_load_fpr64(ctx
, fp1
, ft
);
8991 gen_load_fpr64(ctx
, fp2
, fr
);
8992 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8993 tcg_temp_free_i64(fp0
);
8994 tcg_temp_free_i64(fp1
);
8995 gen_store_fpr64(ctx
, fp2
, fd
);
8996 tcg_temp_free_i64(fp2
);
9001 check_cp1_64bitmode(ctx
);
9003 TCGv_i64 fp0
= tcg_temp_new_i64();
9004 TCGv_i64 fp1
= tcg_temp_new_i64();
9005 TCGv_i64 fp2
= tcg_temp_new_i64();
9007 gen_load_fpr64(ctx
, fp0
, fs
);
9008 gen_load_fpr64(ctx
, fp1
, ft
);
9009 gen_load_fpr64(ctx
, fp2
, fr
);
9010 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9011 tcg_temp_free_i64(fp0
);
9012 tcg_temp_free_i64(fp1
);
9013 gen_store_fpr64(ctx
, fp2
, fd
);
9014 tcg_temp_free_i64(fp2
);
9020 generate_exception (ctx
, EXCP_RI
);
9023 (void)opn
; /* avoid a compiler warning */
9024 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9025 fregnames
[fs
], fregnames
[ft
]);
9028 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
9032 #if !defined(CONFIG_USER_ONLY)
9033 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9034 Therefore only check the ISA in system mode. */
9035 check_insn(ctx
, ISA_MIPS32R2
);
9037 t0
= tcg_temp_new();
9041 save_cpu_state(ctx
, 1);
9042 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9043 gen_store_gpr(t0
, rt
);
9046 save_cpu_state(ctx
, 1);
9047 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9048 gen_store_gpr(t0
, rt
);
9051 save_cpu_state(ctx
, 1);
9052 gen_helper_rdhwr_cc(t0
, cpu_env
);
9053 gen_store_gpr(t0
, rt
);
9056 save_cpu_state(ctx
, 1);
9057 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9058 gen_store_gpr(t0
, rt
);
9061 #if defined(CONFIG_USER_ONLY)
9062 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUMIPSState
, tls_value
));
9063 gen_store_gpr(t0
, rt
);
9066 /* XXX: Some CPUs implement this in hardware.
9067 Not supported yet. */
9069 default: /* Invalid */
9070 MIPS_INVAL("rdhwr");
9071 generate_exception(ctx
, EXCP_RI
);
9077 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9079 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9080 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9081 /* Branches completion */
9082 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9083 ctx
->bstate
= BS_BRANCH
;
9084 save_cpu_state(ctx
, 0);
9085 /* FIXME: Need to clear can_do_io. */
9086 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9088 /* unconditional branch */
9089 MIPS_DEBUG("unconditional branch");
9090 if (proc_hflags
& MIPS_HFLAG_BX
) {
9091 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9093 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9096 /* blikely taken case */
9097 MIPS_DEBUG("blikely branch taken");
9098 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9101 /* Conditional branch */
9102 MIPS_DEBUG("conditional branch");
9104 int l1
= gen_new_label();
9106 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9107 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9109 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9113 /* unconditional branch to register */
9114 MIPS_DEBUG("branch to register");
9115 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9116 TCGv t0
= tcg_temp_new();
9117 TCGv_i32 t1
= tcg_temp_new_i32();
9119 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9120 tcg_gen_trunc_tl_i32(t1
, t0
);
9122 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9123 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9124 tcg_gen_or_i32(hflags
, hflags
, t1
);
9125 tcg_temp_free_i32(t1
);
9127 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9129 tcg_gen_mov_tl(cpu_PC
, btarget
);
9131 if (ctx
->singlestep_enabled
) {
9132 save_cpu_state(ctx
, 0);
9133 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9138 MIPS_DEBUG("unknown branch");
9144 /* ISA extensions (ASEs) */
9145 /* MIPS16 extension to MIPS32 */
9147 /* MIPS16 major opcodes */
9149 M16_OPC_ADDIUSP
= 0x00,
9150 M16_OPC_ADDIUPC
= 0x01,
9153 M16_OPC_BEQZ
= 0x04,
9154 M16_OPC_BNEQZ
= 0x05,
9155 M16_OPC_SHIFT
= 0x06,
9157 M16_OPC_RRIA
= 0x08,
9158 M16_OPC_ADDIU8
= 0x09,
9159 M16_OPC_SLTI
= 0x0a,
9160 M16_OPC_SLTIU
= 0x0b,
9163 M16_OPC_CMPI
= 0x0e,
9167 M16_OPC_LWSP
= 0x12,
9171 M16_OPC_LWPC
= 0x16,
9175 M16_OPC_SWSP
= 0x1a,
9179 M16_OPC_EXTEND
= 0x1e,
9183 /* I8 funct field */
9202 /* RR funct field */
9236 /* I64 funct field */
9248 /* RR ry field for CNVT */
9250 RR_RY_CNVT_ZEB
= 0x0,
9251 RR_RY_CNVT_ZEH
= 0x1,
9252 RR_RY_CNVT_ZEW
= 0x2,
9253 RR_RY_CNVT_SEB
= 0x4,
9254 RR_RY_CNVT_SEH
= 0x5,
9255 RR_RY_CNVT_SEW
= 0x6,
9258 static int xlat (int r
)
9260 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9265 static void gen_mips16_save (DisasContext
*ctx
,
9266 int xsregs
, int aregs
,
9267 int do_ra
, int do_s0
, int do_s1
,
9270 TCGv t0
= tcg_temp_new();
9271 TCGv t1
= tcg_temp_new();
9301 generate_exception(ctx
, EXCP_RI
);
9307 gen_base_offset_addr(ctx
, t0
, 29, 12);
9308 gen_load_gpr(t1
, 7);
9309 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9312 gen_base_offset_addr(ctx
, t0
, 29, 8);
9313 gen_load_gpr(t1
, 6);
9314 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9317 gen_base_offset_addr(ctx
, t0
, 29, 4);
9318 gen_load_gpr(t1
, 5);
9319 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9322 gen_base_offset_addr(ctx
, t0
, 29, 0);
9323 gen_load_gpr(t1
, 4);
9324 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9327 gen_load_gpr(t0
, 29);
9329 #define DECR_AND_STORE(reg) do { \
9330 tcg_gen_subi_tl(t0, t0, 4); \
9331 gen_load_gpr(t1, reg); \
9332 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9396 generate_exception(ctx
, EXCP_RI
);
9412 #undef DECR_AND_STORE
9414 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9419 static void gen_mips16_restore (DisasContext
*ctx
,
9420 int xsregs
, int aregs
,
9421 int do_ra
, int do_s0
, int do_s1
,
9425 TCGv t0
= tcg_temp_new();
9426 TCGv t1
= tcg_temp_new();
9428 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9430 #define DECR_AND_LOAD(reg) do { \
9431 tcg_gen_subi_tl(t0, t0, 4); \
9432 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9433 gen_store_gpr(t1, reg); \
9497 generate_exception(ctx
, EXCP_RI
);
9513 #undef DECR_AND_LOAD
9515 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9520 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9521 int is_64_bit
, int extended
)
9525 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9526 generate_exception(ctx
, EXCP_RI
);
9530 t0
= tcg_temp_new();
9532 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9533 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9535 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9541 #if defined(TARGET_MIPS64)
9542 static void decode_i64_mips16 (DisasContext
*ctx
,
9543 int ry
, int funct
, int16_t offset
,
9549 offset
= extended
? offset
: offset
<< 3;
9550 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9554 offset
= extended
? offset
: offset
<< 3;
9555 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9559 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9560 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9564 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9565 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9568 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9569 generate_exception(ctx
, EXCP_RI
);
9571 offset
= extended
? offset
: offset
<< 3;
9572 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9577 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9578 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9582 offset
= extended
? offset
: offset
<< 2;
9583 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9587 offset
= extended
? offset
: offset
<< 2;
9588 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9594 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9596 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9597 int op
, rx
, ry
, funct
, sa
;
9598 int16_t imm
, offset
;
9600 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9601 op
= (ctx
->opcode
>> 11) & 0x1f;
9602 sa
= (ctx
->opcode
>> 22) & 0x1f;
9603 funct
= (ctx
->opcode
>> 8) & 0x7;
9604 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9605 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9606 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9607 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9608 | (ctx
->opcode
& 0x1f));
9610 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9613 case M16_OPC_ADDIUSP
:
9614 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9616 case M16_OPC_ADDIUPC
:
9617 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9620 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9621 /* No delay slot, so just process as a normal instruction */
9624 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9625 /* No delay slot, so just process as a normal instruction */
9628 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9629 /* No delay slot, so just process as a normal instruction */
9632 switch (ctx
->opcode
& 0x3) {
9634 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9637 #if defined(TARGET_MIPS64)
9639 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9641 generate_exception(ctx
, EXCP_RI
);
9645 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9648 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9652 #if defined(TARGET_MIPS64)
9655 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9659 imm
= ctx
->opcode
& 0xf;
9660 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9661 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9662 imm
= (int16_t) (imm
<< 1) >> 1;
9663 if ((ctx
->opcode
>> 4) & 0x1) {
9664 #if defined(TARGET_MIPS64)
9666 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9668 generate_exception(ctx
, EXCP_RI
);
9671 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9674 case M16_OPC_ADDIU8
:
9675 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9678 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9681 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9686 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9689 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9692 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9695 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9699 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9700 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9701 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9702 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9703 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9704 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9705 | (ctx
->opcode
& 0xf)) << 3;
9707 if (ctx
->opcode
& (1 << 7)) {
9708 gen_mips16_save(ctx
, xsregs
, aregs
,
9709 do_ra
, do_s0
, do_s1
,
9712 gen_mips16_restore(ctx
, xsregs
, aregs
,
9713 do_ra
, do_s0
, do_s1
,
9719 generate_exception(ctx
, EXCP_RI
);
9724 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9727 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9729 #if defined(TARGET_MIPS64)
9731 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9735 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9738 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9741 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9744 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9747 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9750 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9753 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9755 #if defined(TARGET_MIPS64)
9757 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9761 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9764 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9767 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9770 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9772 #if defined(TARGET_MIPS64)
9774 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9778 generate_exception(ctx
, EXCP_RI
);
9785 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9789 int op
, cnvt_op
, op1
, offset
;
9793 op
= (ctx
->opcode
>> 11) & 0x1f;
9794 sa
= (ctx
->opcode
>> 2) & 0x7;
9795 sa
= sa
== 0 ? 8 : sa
;
9796 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9797 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9798 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9799 op1
= offset
= ctx
->opcode
& 0x1f;
9804 case M16_OPC_ADDIUSP
:
9806 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9808 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9811 case M16_OPC_ADDIUPC
:
9812 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9815 offset
= (ctx
->opcode
& 0x7ff) << 1;
9816 offset
= (int16_t)(offset
<< 4) >> 4;
9817 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9818 /* No delay slot, so just process as a normal instruction */
9821 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9822 offset
= (((ctx
->opcode
& 0x1f) << 21)
9823 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9825 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9826 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9830 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9831 /* No delay slot, so just process as a normal instruction */
9834 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9835 /* No delay slot, so just process as a normal instruction */
9838 switch (ctx
->opcode
& 0x3) {
9840 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9843 #if defined(TARGET_MIPS64)
9845 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9847 generate_exception(ctx
, EXCP_RI
);
9851 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9854 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9858 #if defined(TARGET_MIPS64)
9861 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9866 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9868 if ((ctx
->opcode
>> 4) & 1) {
9869 #if defined(TARGET_MIPS64)
9871 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9873 generate_exception(ctx
, EXCP_RI
);
9876 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9880 case M16_OPC_ADDIU8
:
9882 int16_t imm
= (int8_t) ctx
->opcode
;
9884 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9889 int16_t imm
= (uint8_t) ctx
->opcode
;
9890 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9895 int16_t imm
= (uint8_t) ctx
->opcode
;
9896 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9903 funct
= (ctx
->opcode
>> 8) & 0x7;
9906 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9907 ((int8_t)ctx
->opcode
) << 1);
9910 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9911 ((int8_t)ctx
->opcode
) << 1);
9914 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9917 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9918 ((int8_t)ctx
->opcode
) << 3);
9922 int do_ra
= ctx
->opcode
& (1 << 6);
9923 int do_s0
= ctx
->opcode
& (1 << 5);
9924 int do_s1
= ctx
->opcode
& (1 << 4);
9925 int framesize
= ctx
->opcode
& 0xf;
9927 if (framesize
== 0) {
9930 framesize
= framesize
<< 3;
9933 if (ctx
->opcode
& (1 << 7)) {
9934 gen_mips16_save(ctx
, 0, 0,
9935 do_ra
, do_s0
, do_s1
, framesize
);
9937 gen_mips16_restore(ctx
, 0, 0,
9938 do_ra
, do_s0
, do_s1
, framesize
);
9944 int rz
= xlat(ctx
->opcode
& 0x7);
9946 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9947 ((ctx
->opcode
>> 5) & 0x7);
9948 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
9952 reg32
= ctx
->opcode
& 0x1f;
9953 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
9956 generate_exception(ctx
, EXCP_RI
);
9963 int16_t imm
= (uint8_t) ctx
->opcode
;
9965 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
9970 int16_t imm
= (uint8_t) ctx
->opcode
;
9971 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
9974 #if defined(TARGET_MIPS64)
9977 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
9981 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9984 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
9987 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
9990 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
9993 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9996 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
9999 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
10001 #if defined (TARGET_MIPS64)
10003 check_mips_64(ctx
);
10004 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
10008 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10011 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
10014 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10017 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10021 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10024 switch (ctx
->opcode
& 0x3) {
10026 mips32_op
= OPC_ADDU
;
10029 mips32_op
= OPC_SUBU
;
10031 #if defined(TARGET_MIPS64)
10033 mips32_op
= OPC_DADDU
;
10034 check_mips_64(ctx
);
10037 mips32_op
= OPC_DSUBU
;
10038 check_mips_64(ctx
);
10042 generate_exception(ctx
, EXCP_RI
);
10046 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10055 int nd
= (ctx
->opcode
>> 7) & 0x1;
10056 int link
= (ctx
->opcode
>> 6) & 0x1;
10057 int ra
= (ctx
->opcode
>> 5) & 0x1;
10060 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10065 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10069 /* XXX: not clear which exception should be raised
10070 * when in debug mode...
10072 check_insn(ctx
, ISA_MIPS32
);
10073 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10074 generate_exception(ctx
, EXCP_DBp
);
10076 generate_exception(ctx
, EXCP_DBp
);
10080 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10083 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10086 generate_exception(ctx
, EXCP_BREAK
);
10089 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10092 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10095 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10097 #if defined (TARGET_MIPS64)
10099 check_mips_64(ctx
);
10100 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10104 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10107 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10110 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10113 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10116 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10119 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10122 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
10126 case RR_RY_CNVT_ZEB
:
10127 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10129 case RR_RY_CNVT_ZEH
:
10130 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10132 case RR_RY_CNVT_SEB
:
10133 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10135 case RR_RY_CNVT_SEH
:
10136 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10138 #if defined (TARGET_MIPS64)
10139 case RR_RY_CNVT_ZEW
:
10140 check_mips_64(ctx
);
10141 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10143 case RR_RY_CNVT_SEW
:
10144 check_mips_64(ctx
);
10145 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10149 generate_exception(ctx
, EXCP_RI
);
10154 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
10156 #if defined (TARGET_MIPS64)
10158 check_mips_64(ctx
);
10159 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10162 check_mips_64(ctx
);
10163 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10166 check_mips_64(ctx
);
10167 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10170 check_mips_64(ctx
);
10171 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10175 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
10178 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
10181 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
10184 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
10186 #if defined (TARGET_MIPS64)
10188 check_mips_64(ctx
);
10189 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
10192 check_mips_64(ctx
);
10193 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
10196 check_mips_64(ctx
);
10197 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
10200 check_mips_64(ctx
);
10201 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
10205 generate_exception(ctx
, EXCP_RI
);
10209 case M16_OPC_EXTEND
:
10210 decode_extended_mips16_opc(env
, ctx
);
10213 #if defined(TARGET_MIPS64)
10215 funct
= (ctx
->opcode
>> 8) & 0x7;
10216 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10220 generate_exception(ctx
, EXCP_RI
);
10227 /* microMIPS extension to MIPS32/MIPS64 */
10230 * microMIPS32/microMIPS64 major opcodes
10232 * 1. MIPS Architecture for Programmers Volume II-B:
10233 * The microMIPS32 Instruction Set (Revision 3.05)
10235 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10237 * 2. MIPS Architecture For Programmers Volume II-A:
10238 * The MIPS64 Instruction Set (Revision 3.51)
10266 POOL32S
= 0x16, /* MIPS64 */
10267 DADDIU32
= 0x17, /* MIPS64 */
10269 /* 0x1f is reserved */
10278 /* 0x20 is reserved */
10288 /* 0x28 and 0x29 are reserved */
10298 /* 0x30 and 0x31 are reserved */
10305 SD32
= 0x36, /* MIPS64 */
10306 LD32
= 0x37, /* MIPS64 */
10308 /* 0x38 and 0x39 are reserved */
10319 /* POOL32A encoding of minor opcode field */
10322 /* These opcodes are distinguished only by bits 9..6; those bits are
10323 * what are recorded below. */
10349 /* The following can be distinguished by their lower 6 bits. */
10355 /* POOL32AXF encoding of minor opcode field extension */
10358 * 1. MIPS Architecture for Programmers Volume II-B:
10359 * The microMIPS32 Instruction Set (Revision 3.05)
10361 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10363 * 2. MIPS Architecture for Programmers VolumeIV-e:
10364 * The MIPS DSP Application-Specific Extension
10365 * to the microMIPS32 Architecture (Revision 2.34)
10367 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10382 /* begin of microMIPS32 DSP */
10384 /* bits 13..12 for 0x01 */
10390 /* bits 13..12 for 0x2a */
10396 /* bits 13..12 for 0x32 */
10400 /* end of microMIPS32 DSP */
10402 /* bits 15..12 for 0x2c */
10418 /* bits 15..12 for 0x34 */
10426 /* bits 15..12 for 0x3c */
10428 JR
= 0x0, /* alias */
10433 /* bits 15..12 for 0x05 */
10437 /* bits 15..12 for 0x0d */
10447 /* bits 15..12 for 0x15 */
10453 /* bits 15..12 for 0x1d */
10457 /* bits 15..12 for 0x2d */
10462 /* bits 15..12 for 0x35 */
10469 /* POOL32B encoding of minor opcode field (bits 15..12) */
10485 /* POOL32C encoding of minor opcode field (bits 15..12) */
10493 /* 0xa is reserved */
10500 /* 0x6 is reserved */
10506 /* POOL32F encoding of minor opcode field (bits 5..0) */
10509 /* These are the bit 7..6 values */
10520 /* These are the bit 8..6 values */
10564 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10568 /* POOL32Fxf encoding of minor opcode extension field */
10606 /* POOL32I encoding of minor opcode field (bits 25..21) */
10631 /* These overlap and are distinguished by bit16 of the instruction */
10640 /* POOL16A encoding of minor opcode field */
10647 /* POOL16B encoding of minor opcode field */
10654 /* POOL16C encoding of minor opcode field */
10674 /* POOL16D encoding of minor opcode field */
10681 /* POOL16E encoding of minor opcode field */
10688 static int mmreg (int r
)
10690 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10695 /* Used for 16-bit store instructions. */
10696 static int mmreg2 (int r
)
10698 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10703 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10704 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10705 #define uMIPS_RS2(op) uMIPS_RS(op)
10706 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10707 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10708 #define uMIPS_RS5(op) (op & 0x1f)
10710 /* Signed immediate */
10711 #define SIMM(op, start, width) \
10712 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10715 /* Zero-extended immediate */
10716 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10718 static void gen_addiur1sp(DisasContext
*ctx
)
10720 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10722 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10725 static void gen_addiur2(DisasContext
*ctx
)
10727 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10728 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10729 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10731 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10734 static void gen_addiusp(DisasContext
*ctx
)
10736 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10739 if (encoded
<= 1) {
10740 decoded
= 256 + encoded
;
10741 } else if (encoded
<= 255) {
10743 } else if (encoded
<= 509) {
10744 decoded
= encoded
- 512;
10746 decoded
= encoded
- 768;
10749 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10752 static void gen_addius5(DisasContext
*ctx
)
10754 int imm
= SIMM(ctx
->opcode
, 1, 4);
10755 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10757 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10760 static void gen_andi16(DisasContext
*ctx
)
10762 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10763 31, 32, 63, 64, 255, 32768, 65535 };
10764 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10765 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10766 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10768 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10771 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10772 int base
, int16_t offset
)
10774 const char *opn
= "ldst_multiple";
10778 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10779 generate_exception(ctx
, EXCP_RI
);
10783 t0
= tcg_temp_new();
10785 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10787 t1
= tcg_const_tl(reglist
);
10788 t2
= tcg_const_i32(ctx
->mem_idx
);
10790 save_cpu_state(ctx
, 1);
10793 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10797 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10800 #ifdef TARGET_MIPS64
10802 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10806 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10812 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10815 tcg_temp_free_i32(t2
);
10819 static void gen_pool16c_insn(DisasContext
*ctx
)
10821 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10822 int rs
= mmreg(ctx
->opcode
& 0x7);
10825 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10830 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10836 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10842 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10848 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10855 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10856 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10858 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10867 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10868 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10870 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10877 int reg
= ctx
->opcode
& 0x1f;
10879 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10885 int reg
= ctx
->opcode
& 0x1f;
10887 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10888 /* Let normal delay slot handling in our caller take us
10889 to the branch target. */
10901 int reg
= ctx
->opcode
& 0x1f;
10903 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10908 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
10912 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
10915 generate_exception(ctx
, EXCP_BREAK
);
10918 /* XXX: not clear which exception should be raised
10919 * when in debug mode...
10921 check_insn(ctx
, ISA_MIPS32
);
10922 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10923 generate_exception(ctx
, EXCP_DBp
);
10925 generate_exception(ctx
, EXCP_DBp
);
10928 case JRADDIUSP
+ 0:
10929 case JRADDIUSP
+ 1:
10931 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10933 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10934 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10935 /* Let normal delay slot handling in our caller take us
10936 to the branch target. */
10940 generate_exception(ctx
, EXCP_RI
);
10945 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10947 TCGv t0
= tcg_temp_new();
10948 TCGv t1
= tcg_temp_new();
10950 gen_load_gpr(t0
, base
);
10953 gen_load_gpr(t1
, index
);
10954 tcg_gen_shli_tl(t1
, t1
, 2);
10955 gen_op_addr_add(ctx
, t0
, t1
, t0
);
10958 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
10959 gen_store_gpr(t1
, rd
);
10965 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
10966 int base
, int16_t offset
)
10968 const char *opn
= "ldst_pair";
10971 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
10972 generate_exception(ctx
, EXCP_RI
);
10976 t0
= tcg_temp_new();
10977 t1
= tcg_temp_new();
10979 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10984 generate_exception(ctx
, EXCP_RI
);
10987 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
10988 gen_store_gpr(t1
, rd
);
10989 tcg_gen_movi_tl(t1
, 4);
10990 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10991 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
10992 gen_store_gpr(t1
, rd
+1);
10996 gen_load_gpr(t1
, rd
);
10997 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10998 tcg_gen_movi_tl(t1
, 4);
10999 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11000 gen_load_gpr(t1
, rd
+1);
11001 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11004 #ifdef TARGET_MIPS64
11007 generate_exception(ctx
, EXCP_RI
);
11010 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11011 gen_store_gpr(t1
, rd
);
11012 tcg_gen_movi_tl(t1
, 8);
11013 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11014 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11015 gen_store_gpr(t1
, rd
+1);
11019 gen_load_gpr(t1
, rd
);
11020 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11021 tcg_gen_movi_tl(t1
, 8);
11022 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11023 gen_load_gpr(t1
, rd
+1);
11024 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11029 (void)opn
; /* avoid a compiler warning */
11030 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11035 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
11037 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11038 int minor
= (ctx
->opcode
>> 12) & 0xf;
11039 uint32_t mips32_op
;
11041 switch (extension
) {
11043 mips32_op
= OPC_TEQ
;
11046 mips32_op
= OPC_TGE
;
11049 mips32_op
= OPC_TGEU
;
11052 mips32_op
= OPC_TLT
;
11055 mips32_op
= OPC_TLTU
;
11058 mips32_op
= OPC_TNE
;
11060 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11062 #ifndef CONFIG_USER_ONLY
11065 check_cp0_enabled(ctx
);
11067 /* Treat as NOP. */
11070 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11074 check_cp0_enabled(ctx
);
11076 TCGv t0
= tcg_temp_new();
11078 gen_load_gpr(t0
, rt
);
11079 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11085 switch (minor
& 3) {
11087 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11090 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11093 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11096 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11099 goto pool32axf_invalid
;
11103 switch (minor
& 3) {
11105 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11108 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11111 goto pool32axf_invalid
;
11117 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11120 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11123 mips32_op
= OPC_CLO
;
11126 mips32_op
= OPC_CLZ
;
11128 check_insn(ctx
, ISA_MIPS32
);
11129 gen_cl(ctx
, mips32_op
, rt
, rs
);
11132 gen_rdhwr(ctx
, rt
, rs
);
11135 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11138 mips32_op
= OPC_MULT
;
11141 mips32_op
= OPC_MULTU
;
11144 mips32_op
= OPC_DIV
;
11147 mips32_op
= OPC_DIVU
;
11150 check_insn(ctx
, ISA_MIPS32
);
11151 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11154 mips32_op
= OPC_MADD
;
11157 mips32_op
= OPC_MADDU
;
11160 mips32_op
= OPC_MSUB
;
11163 mips32_op
= OPC_MSUBU
;
11165 check_insn(ctx
, ISA_MIPS32
);
11166 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11169 goto pool32axf_invalid
;
11180 generate_exception_err(ctx
, EXCP_CpU
, 2);
11183 goto pool32axf_invalid
;
11190 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11194 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11197 goto pool32axf_invalid
;
11203 check_cp0_enabled(ctx
);
11204 check_insn(ctx
, ISA_MIPS32R2
);
11205 gen_load_srsgpr(rt
, rs
);
11208 check_cp0_enabled(ctx
);
11209 check_insn(ctx
, ISA_MIPS32R2
);
11210 gen_store_srsgpr(rt
, rs
);
11213 goto pool32axf_invalid
;
11216 #ifndef CONFIG_USER_ONLY
11220 mips32_op
= OPC_TLBP
;
11223 mips32_op
= OPC_TLBR
;
11226 mips32_op
= OPC_TLBWI
;
11229 mips32_op
= OPC_TLBWR
;
11232 mips32_op
= OPC_WAIT
;
11235 mips32_op
= OPC_DERET
;
11238 mips32_op
= OPC_ERET
;
11240 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11243 goto pool32axf_invalid
;
11249 check_cp0_enabled(ctx
);
11251 TCGv t0
= tcg_temp_new();
11253 save_cpu_state(ctx
, 1);
11254 gen_helper_di(t0
, cpu_env
);
11255 gen_store_gpr(t0
, rs
);
11256 /* Stop translation as we may have switched the execution mode */
11257 ctx
->bstate
= BS_STOP
;
11262 check_cp0_enabled(ctx
);
11264 TCGv t0
= tcg_temp_new();
11266 save_cpu_state(ctx
, 1);
11267 gen_helper_ei(t0
, cpu_env
);
11268 gen_store_gpr(t0
, rs
);
11269 /* Stop translation as we may have switched the execution mode */
11270 ctx
->bstate
= BS_STOP
;
11275 goto pool32axf_invalid
;
11285 generate_exception(ctx
, EXCP_SYSCALL
);
11286 ctx
->bstate
= BS_STOP
;
11289 check_insn(ctx
, ISA_MIPS32
);
11290 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11291 generate_exception(ctx
, EXCP_DBp
);
11293 generate_exception(ctx
, EXCP_DBp
);
11297 goto pool32axf_invalid
;
11301 switch (minor
& 3) {
11303 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
11306 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
11309 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
11312 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
11315 goto pool32axf_invalid
;
11321 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
11324 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
11327 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
11330 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
11333 goto pool32axf_invalid
;
11338 MIPS_INVAL("pool32axf");
11339 generate_exception(ctx
, EXCP_RI
);
11344 /* Values for microMIPS fmt field. Variable-width, depending on which
11345 formats the instruction supports. */
11364 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11366 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11367 uint32_t mips32_op
;
11369 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11370 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11371 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11373 switch (extension
) {
11374 case FLOAT_1BIT_FMT(CFC1
, 0):
11375 mips32_op
= OPC_CFC1
;
11377 case FLOAT_1BIT_FMT(CTC1
, 0):
11378 mips32_op
= OPC_CTC1
;
11380 case FLOAT_1BIT_FMT(MFC1
, 0):
11381 mips32_op
= OPC_MFC1
;
11383 case FLOAT_1BIT_FMT(MTC1
, 0):
11384 mips32_op
= OPC_MTC1
;
11386 case FLOAT_1BIT_FMT(MFHC1
, 0):
11387 mips32_op
= OPC_MFHC1
;
11389 case FLOAT_1BIT_FMT(MTHC1
, 0):
11390 mips32_op
= OPC_MTHC1
;
11392 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11395 /* Reciprocal square root */
11396 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11397 mips32_op
= OPC_RSQRT_S
;
11399 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11400 mips32_op
= OPC_RSQRT_D
;
11404 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11405 mips32_op
= OPC_SQRT_S
;
11407 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11408 mips32_op
= OPC_SQRT_D
;
11412 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11413 mips32_op
= OPC_RECIP_S
;
11415 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11416 mips32_op
= OPC_RECIP_D
;
11420 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11421 mips32_op
= OPC_FLOOR_L_S
;
11423 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11424 mips32_op
= OPC_FLOOR_L_D
;
11426 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11427 mips32_op
= OPC_FLOOR_W_S
;
11429 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11430 mips32_op
= OPC_FLOOR_W_D
;
11434 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11435 mips32_op
= OPC_CEIL_L_S
;
11437 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11438 mips32_op
= OPC_CEIL_L_D
;
11440 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11441 mips32_op
= OPC_CEIL_W_S
;
11443 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11444 mips32_op
= OPC_CEIL_W_D
;
11448 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11449 mips32_op
= OPC_TRUNC_L_S
;
11451 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11452 mips32_op
= OPC_TRUNC_L_D
;
11454 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11455 mips32_op
= OPC_TRUNC_W_S
;
11457 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11458 mips32_op
= OPC_TRUNC_W_D
;
11462 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11463 mips32_op
= OPC_ROUND_L_S
;
11465 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11466 mips32_op
= OPC_ROUND_L_D
;
11468 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11469 mips32_op
= OPC_ROUND_W_S
;
11471 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11472 mips32_op
= OPC_ROUND_W_D
;
11475 /* Integer to floating-point conversion */
11476 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11477 mips32_op
= OPC_CVT_L_S
;
11479 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11480 mips32_op
= OPC_CVT_L_D
;
11482 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11483 mips32_op
= OPC_CVT_W_S
;
11485 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11486 mips32_op
= OPC_CVT_W_D
;
11489 /* Paired-foo conversions */
11490 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11491 mips32_op
= OPC_CVT_S_PL
;
11493 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11494 mips32_op
= OPC_CVT_S_PU
;
11496 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11497 mips32_op
= OPC_CVT_PW_PS
;
11499 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11500 mips32_op
= OPC_CVT_PS_PW
;
11503 /* Floating-point moves */
11504 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11505 mips32_op
= OPC_MOV_S
;
11507 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11508 mips32_op
= OPC_MOV_D
;
11510 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11511 mips32_op
= OPC_MOV_PS
;
11514 /* Absolute value */
11515 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11516 mips32_op
= OPC_ABS_S
;
11518 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11519 mips32_op
= OPC_ABS_D
;
11521 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11522 mips32_op
= OPC_ABS_PS
;
11526 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11527 mips32_op
= OPC_NEG_S
;
11529 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11530 mips32_op
= OPC_NEG_D
;
11532 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11533 mips32_op
= OPC_NEG_PS
;
11536 /* Reciprocal square root step */
11537 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11538 mips32_op
= OPC_RSQRT1_S
;
11540 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11541 mips32_op
= OPC_RSQRT1_D
;
11543 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11544 mips32_op
= OPC_RSQRT1_PS
;
11547 /* Reciprocal step */
11548 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11549 mips32_op
= OPC_RECIP1_S
;
11551 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11552 mips32_op
= OPC_RECIP1_S
;
11554 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11555 mips32_op
= OPC_RECIP1_PS
;
11558 /* Conversions from double */
11559 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11560 mips32_op
= OPC_CVT_D_S
;
11562 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11563 mips32_op
= OPC_CVT_D_W
;
11565 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11566 mips32_op
= OPC_CVT_D_L
;
11569 /* Conversions from single */
11570 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11571 mips32_op
= OPC_CVT_S_D
;
11573 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11574 mips32_op
= OPC_CVT_S_W
;
11576 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11577 mips32_op
= OPC_CVT_S_L
;
11579 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11582 /* Conditional moves on floating-point codes */
11583 case COND_FLOAT_MOV(MOVT
, 0):
11584 case COND_FLOAT_MOV(MOVT
, 1):
11585 case COND_FLOAT_MOV(MOVT
, 2):
11586 case COND_FLOAT_MOV(MOVT
, 3):
11587 case COND_FLOAT_MOV(MOVT
, 4):
11588 case COND_FLOAT_MOV(MOVT
, 5):
11589 case COND_FLOAT_MOV(MOVT
, 6):
11590 case COND_FLOAT_MOV(MOVT
, 7):
11591 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11593 case COND_FLOAT_MOV(MOVF
, 0):
11594 case COND_FLOAT_MOV(MOVF
, 1):
11595 case COND_FLOAT_MOV(MOVF
, 2):
11596 case COND_FLOAT_MOV(MOVF
, 3):
11597 case COND_FLOAT_MOV(MOVF
, 4):
11598 case COND_FLOAT_MOV(MOVF
, 5):
11599 case COND_FLOAT_MOV(MOVF
, 6):
11600 case COND_FLOAT_MOV(MOVF
, 7):
11601 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11604 MIPS_INVAL("pool32fxf");
11605 generate_exception(ctx
, EXCP_RI
);
11610 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11615 int rt
, rs
, rd
, rr
;
11617 uint32_t op
, minor
, mips32_op
;
11618 uint32_t cond
, fmt
, cc
;
11620 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11621 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11623 rt
= (ctx
->opcode
>> 21) & 0x1f;
11624 rs
= (ctx
->opcode
>> 16) & 0x1f;
11625 rd
= (ctx
->opcode
>> 11) & 0x1f;
11626 rr
= (ctx
->opcode
>> 6) & 0x1f;
11627 imm
= (int16_t) ctx
->opcode
;
11629 op
= (ctx
->opcode
>> 26) & 0x3f;
11632 minor
= ctx
->opcode
& 0x3f;
11635 minor
= (ctx
->opcode
>> 6) & 0xf;
11638 mips32_op
= OPC_SLL
;
11641 mips32_op
= OPC_SRA
;
11644 mips32_op
= OPC_SRL
;
11647 mips32_op
= OPC_ROTR
;
11649 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11652 goto pool32a_invalid
;
11656 minor
= (ctx
->opcode
>> 6) & 0xf;
11660 mips32_op
= OPC_ADD
;
11663 mips32_op
= OPC_ADDU
;
11666 mips32_op
= OPC_SUB
;
11669 mips32_op
= OPC_SUBU
;
11672 mips32_op
= OPC_MUL
;
11674 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11678 mips32_op
= OPC_SLLV
;
11681 mips32_op
= OPC_SRLV
;
11684 mips32_op
= OPC_SRAV
;
11687 mips32_op
= OPC_ROTRV
;
11689 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11691 /* Logical operations */
11693 mips32_op
= OPC_AND
;
11696 mips32_op
= OPC_OR
;
11699 mips32_op
= OPC_NOR
;
11702 mips32_op
= OPC_XOR
;
11704 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11706 /* Set less than */
11708 mips32_op
= OPC_SLT
;
11711 mips32_op
= OPC_SLTU
;
11713 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11716 goto pool32a_invalid
;
11720 minor
= (ctx
->opcode
>> 6) & 0xf;
11722 /* Conditional moves */
11724 mips32_op
= OPC_MOVN
;
11727 mips32_op
= OPC_MOVZ
;
11729 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11732 gen_ldxs(ctx
, rs
, rt
, rd
);
11735 goto pool32a_invalid
;
11739 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11742 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11745 gen_pool32axf(env
, ctx
, rt
, rs
);
11748 generate_exception(ctx
, EXCP_BREAK
);
11752 MIPS_INVAL("pool32a");
11753 generate_exception(ctx
, EXCP_RI
);
11758 minor
= (ctx
->opcode
>> 12) & 0xf;
11761 check_cp0_enabled(ctx
);
11762 /* Treat as no-op. */
11766 /* COP2: Not implemented. */
11767 generate_exception_err(ctx
, EXCP_CpU
, 2);
11771 #ifdef TARGET_MIPS64
11775 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11779 #ifdef TARGET_MIPS64
11783 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11786 MIPS_INVAL("pool32b");
11787 generate_exception(ctx
, EXCP_RI
);
11792 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
11793 minor
= ctx
->opcode
& 0x3f;
11794 check_cp1_enabled(ctx
);
11797 mips32_op
= OPC_ALNV_PS
;
11800 mips32_op
= OPC_MADD_S
;
11803 mips32_op
= OPC_MADD_D
;
11806 mips32_op
= OPC_MADD_PS
;
11809 mips32_op
= OPC_MSUB_S
;
11812 mips32_op
= OPC_MSUB_D
;
11815 mips32_op
= OPC_MSUB_PS
;
11818 mips32_op
= OPC_NMADD_S
;
11821 mips32_op
= OPC_NMADD_D
;
11824 mips32_op
= OPC_NMADD_PS
;
11827 mips32_op
= OPC_NMSUB_S
;
11830 mips32_op
= OPC_NMSUB_D
;
11833 mips32_op
= OPC_NMSUB_PS
;
11835 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11837 case CABS_COND_FMT
:
11838 cond
= (ctx
->opcode
>> 6) & 0xf;
11839 cc
= (ctx
->opcode
>> 13) & 0x7;
11840 fmt
= (ctx
->opcode
>> 10) & 0x3;
11843 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11846 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11849 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11852 goto pool32f_invalid
;
11856 cond
= (ctx
->opcode
>> 6) & 0xf;
11857 cc
= (ctx
->opcode
>> 13) & 0x7;
11858 fmt
= (ctx
->opcode
>> 10) & 0x3;
11861 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11864 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11867 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11870 goto pool32f_invalid
;
11874 gen_pool32fxf(ctx
, rt
, rs
);
11878 switch ((ctx
->opcode
>> 6) & 0x7) {
11880 mips32_op
= OPC_PLL_PS
;
11883 mips32_op
= OPC_PLU_PS
;
11886 mips32_op
= OPC_PUL_PS
;
11889 mips32_op
= OPC_PUU_PS
;
11892 mips32_op
= OPC_CVT_PS_S
;
11894 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11897 goto pool32f_invalid
;
11902 switch ((ctx
->opcode
>> 6) & 0x7) {
11904 mips32_op
= OPC_LWXC1
;
11907 mips32_op
= OPC_SWXC1
;
11910 mips32_op
= OPC_LDXC1
;
11913 mips32_op
= OPC_SDXC1
;
11916 mips32_op
= OPC_LUXC1
;
11919 mips32_op
= OPC_SUXC1
;
11921 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11924 goto pool32f_invalid
;
11929 fmt
= (ctx
->opcode
>> 9) & 0x3;
11930 switch ((ctx
->opcode
>> 6) & 0x7) {
11934 mips32_op
= OPC_RSQRT2_S
;
11937 mips32_op
= OPC_RSQRT2_D
;
11940 mips32_op
= OPC_RSQRT2_PS
;
11943 goto pool32f_invalid
;
11949 mips32_op
= OPC_RECIP2_S
;
11952 mips32_op
= OPC_RECIP2_D
;
11955 mips32_op
= OPC_RECIP2_PS
;
11958 goto pool32f_invalid
;
11962 mips32_op
= OPC_ADDR_PS
;
11965 mips32_op
= OPC_MULR_PS
;
11967 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11970 goto pool32f_invalid
;
11974 /* MOV[FT].fmt and PREFX */
11975 cc
= (ctx
->opcode
>> 13) & 0x7;
11976 fmt
= (ctx
->opcode
>> 9) & 0x3;
11977 switch ((ctx
->opcode
>> 6) & 0x7) {
11981 gen_movcf_s(rs
, rt
, cc
, 0);
11984 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
11987 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
11990 goto pool32f_invalid
;
11996 gen_movcf_s(rs
, rt
, cc
, 1);
11999 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
12002 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
12005 goto pool32f_invalid
;
12011 goto pool32f_invalid
;
12014 #define FINSN_3ARG_SDPS(prfx) \
12015 switch ((ctx->opcode >> 8) & 0x3) { \
12017 mips32_op = OPC_##prfx##_S; \
12020 mips32_op = OPC_##prfx##_D; \
12022 case FMT_SDPS_PS: \
12023 mips32_op = OPC_##prfx##_PS; \
12026 goto pool32f_invalid; \
12029 /* regular FP ops */
12030 switch ((ctx
->opcode
>> 6) & 0x3) {
12032 FINSN_3ARG_SDPS(ADD
);
12035 FINSN_3ARG_SDPS(SUB
);
12038 FINSN_3ARG_SDPS(MUL
);
12041 fmt
= (ctx
->opcode
>> 8) & 0x3;
12043 mips32_op
= OPC_DIV_D
;
12044 } else if (fmt
== 0) {
12045 mips32_op
= OPC_DIV_S
;
12047 goto pool32f_invalid
;
12051 goto pool32f_invalid
;
12056 switch ((ctx
->opcode
>> 6) & 0x3) {
12058 FINSN_3ARG_SDPS(MOVN
);
12061 FINSN_3ARG_SDPS(MOVZ
);
12064 goto pool32f_invalid
;
12068 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12072 MIPS_INVAL("pool32f");
12073 generate_exception(ctx
, EXCP_RI
);
12077 generate_exception_err(ctx
, EXCP_CpU
, 1);
12081 minor
= (ctx
->opcode
>> 21) & 0x1f;
12084 mips32_op
= OPC_BLTZ
;
12087 mips32_op
= OPC_BLTZAL
;
12090 mips32_op
= OPC_BLTZALS
;
12093 mips32_op
= OPC_BGEZ
;
12096 mips32_op
= OPC_BGEZAL
;
12099 mips32_op
= OPC_BGEZALS
;
12102 mips32_op
= OPC_BLEZ
;
12105 mips32_op
= OPC_BGTZ
;
12107 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12112 mips32_op
= OPC_TLTI
;
12115 mips32_op
= OPC_TGEI
;
12118 mips32_op
= OPC_TLTIU
;
12121 mips32_op
= OPC_TGEIU
;
12124 mips32_op
= OPC_TNEI
;
12127 mips32_op
= OPC_TEQI
;
12129 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12134 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12135 4, rs
, 0, imm
<< 1);
12136 /* Compact branches don't have a delay slot, so just let
12137 the normal delay slot handling take us to the branch
12141 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12147 /* COP2: Not implemented. */
12148 generate_exception_err(ctx
, EXCP_CpU
, 2);
12151 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12154 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12157 mips32_op
= OPC_BC1FANY4
;
12160 mips32_op
= OPC_BC1TANY4
;
12163 check_insn(ctx
, ASE_MIPS3D
);
12166 gen_compute_branch1(ctx
, mips32_op
,
12167 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12171 /* MIPS DSP: not implemented */
12174 MIPS_INVAL("pool32i");
12175 generate_exception(ctx
, EXCP_RI
);
12180 minor
= (ctx
->opcode
>> 12) & 0xf;
12183 mips32_op
= OPC_LWL
;
12186 mips32_op
= OPC_SWL
;
12189 mips32_op
= OPC_LWR
;
12192 mips32_op
= OPC_SWR
;
12194 #if defined(TARGET_MIPS64)
12196 mips32_op
= OPC_LDL
;
12199 mips32_op
= OPC_SDL
;
12202 mips32_op
= OPC_LDR
;
12205 mips32_op
= OPC_SDR
;
12208 mips32_op
= OPC_LWU
;
12211 mips32_op
= OPC_LLD
;
12215 mips32_op
= OPC_LL
;
12218 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12221 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12224 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12226 #if defined(TARGET_MIPS64)
12228 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12232 /* Treat as no-op */
12235 MIPS_INVAL("pool32c");
12236 generate_exception(ctx
, EXCP_RI
);
12241 mips32_op
= OPC_ADDI
;
12244 mips32_op
= OPC_ADDIU
;
12246 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12249 /* Logical operations */
12251 mips32_op
= OPC_ORI
;
12254 mips32_op
= OPC_XORI
;
12257 mips32_op
= OPC_ANDI
;
12259 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12262 /* Set less than immediate */
12264 mips32_op
= OPC_SLTI
;
12267 mips32_op
= OPC_SLTIU
;
12269 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12272 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12273 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12276 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12277 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12280 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12283 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12286 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12287 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12290 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12291 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12293 /* Floating point (COP1) */
12295 mips32_op
= OPC_LWC1
;
12298 mips32_op
= OPC_LDC1
;
12301 mips32_op
= OPC_SWC1
;
12304 mips32_op
= OPC_SDC1
;
12306 gen_cop1_ldst(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12310 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12311 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12313 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12316 /* Loads and stores */
12318 mips32_op
= OPC_LB
;
12321 mips32_op
= OPC_LBU
;
12324 mips32_op
= OPC_LH
;
12327 mips32_op
= OPC_LHU
;
12330 mips32_op
= OPC_LW
;
12332 #ifdef TARGET_MIPS64
12334 mips32_op
= OPC_LD
;
12337 mips32_op
= OPC_SD
;
12341 mips32_op
= OPC_SB
;
12344 mips32_op
= OPC_SH
;
12347 mips32_op
= OPC_SW
;
12350 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12353 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12356 generate_exception(ctx
, EXCP_RI
);
12361 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
12365 /* make sure instructions are on a halfword boundary */
12366 if (ctx
->pc
& 0x1) {
12367 env
->CP0_BadVAddr
= ctx
->pc
;
12368 generate_exception(ctx
, EXCP_AdEL
);
12369 ctx
->bstate
= BS_STOP
;
12373 op
= (ctx
->opcode
>> 10) & 0x3f;
12374 /* Enforce properly-sized instructions in a delay slot */
12375 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12376 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12414 if (bits
& MIPS_HFLAG_BDS16
) {
12415 generate_exception(ctx
, EXCP_RI
);
12416 /* Just stop translation; the user is confused. */
12417 ctx
->bstate
= BS_STOP
;
12442 if (bits
& MIPS_HFLAG_BDS32
) {
12443 generate_exception(ctx
, EXCP_RI
);
12444 /* Just stop translation; the user is confused. */
12445 ctx
->bstate
= BS_STOP
;
12456 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12457 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12458 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12461 switch (ctx
->opcode
& 0x1) {
12470 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12475 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12476 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12477 int amount
= (ctx
->opcode
>> 1) & 0x7;
12479 amount
= amount
== 0 ? 8 : amount
;
12481 switch (ctx
->opcode
& 0x1) {
12490 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12494 gen_pool16c_insn(ctx
);
12498 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12499 int rb
= 28; /* GP */
12500 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12502 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12506 if (ctx
->opcode
& 1) {
12507 generate_exception(ctx
, EXCP_RI
);
12510 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12511 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12512 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12513 int rd
, rs
, re
, rt
;
12514 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12515 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12516 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12518 rd
= rd_enc
[enc_dest
];
12519 re
= re_enc
[enc_dest
];
12520 rs
= rs_rt_enc
[enc_rs
];
12521 rt
= rs_rt_enc
[enc_rt
];
12523 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12524 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12529 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12530 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12531 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12532 offset
= (offset
== 0xf ? -1 : offset
);
12534 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12539 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12540 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12541 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12543 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12548 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12549 int rb
= 29; /* SP */
12550 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12552 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12557 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12558 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12559 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12561 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12566 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12567 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12568 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12570 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12575 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12576 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12577 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12579 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12584 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12585 int rb
= 29; /* SP */
12586 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12588 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12593 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12594 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12595 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12597 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12602 int rd
= uMIPS_RD5(ctx
->opcode
);
12603 int rs
= uMIPS_RS5(ctx
->opcode
);
12605 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12612 switch (ctx
->opcode
& 0x1) {
12622 switch (ctx
->opcode
& 0x1) {
12627 gen_addiur1sp(ctx
);
12632 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12633 SIMM(ctx
->opcode
, 0, 10) << 1);
12637 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12638 mmreg(uMIPS_RD(ctx
->opcode
)),
12639 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12643 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12644 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12646 imm
= (imm
== 0x7f ? -1 : imm
);
12647 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12657 generate_exception(ctx
, EXCP_RI
);
12660 decode_micromips32_opc (env
, ctx
, op
);
12667 /* SmartMIPS extension to MIPS32 */
12669 #if defined(TARGET_MIPS64)
12671 /* MDMX extension to MIPS64 */
12675 /* MIPSDSP functions. */
12676 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12677 int rd
, int base
, int offset
)
12679 const char *opn
= "ldx";
12683 t0
= tcg_temp_new();
12686 gen_load_gpr(t0
, offset
);
12687 } else if (offset
== 0) {
12688 gen_load_gpr(t0
, base
);
12690 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12695 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
12696 gen_store_gpr(t0
, rd
);
12700 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
12701 gen_store_gpr(t0
, rd
);
12705 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12706 gen_store_gpr(t0
, rd
);
12709 #if defined(TARGET_MIPS64)
12711 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12712 gen_store_gpr(t0
, rd
);
12717 (void)opn
; /* avoid a compiler warning */
12718 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12719 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12723 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12724 int ret
, int v1
, int v2
)
12726 const char *opn
= "mipsdsp arith";
12731 /* Treat as NOP. */
12736 v1_t
= tcg_temp_new();
12737 v2_t
= tcg_temp_new();
12739 gen_load_gpr(v1_t
, v1
);
12740 gen_load_gpr(v2_t
, v2
);
12743 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12744 case OPC_MULT_G_2E
:
12748 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12750 case OPC_ADDUH_R_QB
:
12751 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12754 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12756 case OPC_ADDQH_R_PH
:
12757 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12760 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12762 case OPC_ADDQH_R_W
:
12763 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12766 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12768 case OPC_SUBUH_R_QB
:
12769 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12772 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12774 case OPC_SUBQH_R_PH
:
12775 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12778 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12780 case OPC_SUBQH_R_W
:
12781 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12785 case OPC_ABSQ_S_PH_DSP
:
12787 case OPC_ABSQ_S_QB
:
12789 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12791 case OPC_ABSQ_S_PH
:
12793 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12797 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12799 case OPC_PRECEQ_W_PHL
:
12801 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12802 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12804 case OPC_PRECEQ_W_PHR
:
12806 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12807 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12808 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12810 case OPC_PRECEQU_PH_QBL
:
12812 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12814 case OPC_PRECEQU_PH_QBR
:
12816 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12818 case OPC_PRECEQU_PH_QBLA
:
12820 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12822 case OPC_PRECEQU_PH_QBRA
:
12824 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12826 case OPC_PRECEU_PH_QBL
:
12828 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12830 case OPC_PRECEU_PH_QBR
:
12832 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12834 case OPC_PRECEU_PH_QBLA
:
12836 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12838 case OPC_PRECEU_PH_QBRA
:
12840 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12844 case OPC_ADDU_QB_DSP
:
12848 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12850 case OPC_ADDQ_S_PH
:
12852 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12856 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12860 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12862 case OPC_ADDU_S_QB
:
12864 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12868 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12870 case OPC_ADDU_S_PH
:
12872 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12876 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12878 case OPC_SUBQ_S_PH
:
12880 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12884 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12888 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12890 case OPC_SUBU_S_QB
:
12892 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12896 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12898 case OPC_SUBU_S_PH
:
12900 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12904 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12908 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12912 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12914 case OPC_RADDU_W_QB
:
12916 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12920 case OPC_CMPU_EQ_QB_DSP
:
12922 case OPC_PRECR_QB_PH
:
12924 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12926 case OPC_PRECRQ_QB_PH
:
12928 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12930 case OPC_PRECR_SRA_PH_W
:
12933 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12934 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12936 tcg_temp_free_i32(sa_t
);
12939 case OPC_PRECR_SRA_R_PH_W
:
12942 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12943 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12945 tcg_temp_free_i32(sa_t
);
12948 case OPC_PRECRQ_PH_W
:
12950 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12952 case OPC_PRECRQ_RS_PH_W
:
12954 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12956 case OPC_PRECRQU_S_QB_PH
:
12958 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12962 #ifdef TARGET_MIPS64
12963 case OPC_ABSQ_S_QH_DSP
:
12965 case OPC_PRECEQ_L_PWL
:
12967 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
12969 case OPC_PRECEQ_L_PWR
:
12971 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
12973 case OPC_PRECEQ_PW_QHL
:
12975 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
12977 case OPC_PRECEQ_PW_QHR
:
12979 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
12981 case OPC_PRECEQ_PW_QHLA
:
12983 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
12985 case OPC_PRECEQ_PW_QHRA
:
12987 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
12989 case OPC_PRECEQU_QH_OBL
:
12991 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
12993 case OPC_PRECEQU_QH_OBR
:
12995 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
12997 case OPC_PRECEQU_QH_OBLA
:
12999 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
13001 case OPC_PRECEQU_QH_OBRA
:
13003 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
13005 case OPC_PRECEU_QH_OBL
:
13007 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
13009 case OPC_PRECEU_QH_OBR
:
13011 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
13013 case OPC_PRECEU_QH_OBLA
:
13015 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
13017 case OPC_PRECEU_QH_OBRA
:
13019 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
13021 case OPC_ABSQ_S_OB
:
13023 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
13025 case OPC_ABSQ_S_PW
:
13027 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
13029 case OPC_ABSQ_S_QH
:
13031 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
13035 case OPC_ADDU_OB_DSP
:
13037 case OPC_RADDU_L_OB
:
13039 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
13043 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13045 case OPC_SUBQ_S_PW
:
13047 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13051 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13053 case OPC_SUBQ_S_QH
:
13055 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13059 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13061 case OPC_SUBU_S_OB
:
13063 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13067 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13069 case OPC_SUBU_S_QH
:
13071 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13075 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13077 case OPC_SUBUH_R_OB
:
13079 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13083 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13085 case OPC_ADDQ_S_PW
:
13087 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13091 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13093 case OPC_ADDQ_S_QH
:
13095 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13099 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13101 case OPC_ADDU_S_OB
:
13103 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13107 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13109 case OPC_ADDU_S_QH
:
13111 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13115 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13117 case OPC_ADDUH_R_OB
:
13119 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13123 case OPC_CMPU_EQ_OB_DSP
:
13125 case OPC_PRECR_OB_QH
:
13127 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13129 case OPC_PRECR_SRA_QH_PW
:
13132 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13133 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13134 tcg_temp_free_i32(ret_t
);
13137 case OPC_PRECR_SRA_R_QH_PW
:
13140 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13141 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13142 tcg_temp_free_i32(sa_v
);
13145 case OPC_PRECRQ_OB_QH
:
13147 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13149 case OPC_PRECRQ_PW_L
:
13151 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13153 case OPC_PRECRQ_QH_PW
:
13155 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13157 case OPC_PRECRQ_RS_QH_PW
:
13159 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13161 case OPC_PRECRQU_S_OB_QH
:
13163 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13170 tcg_temp_free(v1_t
);
13171 tcg_temp_free(v2_t
);
13173 (void)opn
; /* avoid a compiler warning */
13174 MIPS_DEBUG("%s", opn
);
13177 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13178 int ret
, int v1
, int v2
)
13181 const char *opn
= "mipsdsp shift";
13187 /* Treat as NOP. */
13192 t0
= tcg_temp_new();
13193 v1_t
= tcg_temp_new();
13194 v2_t
= tcg_temp_new();
13196 tcg_gen_movi_tl(t0
, v1
);
13197 gen_load_gpr(v1_t
, v1
);
13198 gen_load_gpr(v2_t
, v2
);
13201 case OPC_SHLL_QB_DSP
:
13203 op2
= MASK_SHLL_QB(ctx
->opcode
);
13207 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13211 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13215 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13219 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13221 case OPC_SHLL_S_PH
:
13223 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13225 case OPC_SHLLV_S_PH
:
13227 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13231 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13233 case OPC_SHLLV_S_W
:
13235 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13239 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13243 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13247 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13251 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13255 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13257 case OPC_SHRA_R_QB
:
13259 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13263 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13265 case OPC_SHRAV_R_QB
:
13267 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13271 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13273 case OPC_SHRA_R_PH
:
13275 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13279 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13281 case OPC_SHRAV_R_PH
:
13283 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13287 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13289 case OPC_SHRAV_R_W
:
13291 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13293 default: /* Invalid */
13294 MIPS_INVAL("MASK SHLL.QB");
13295 generate_exception(ctx
, EXCP_RI
);
13300 #ifdef TARGET_MIPS64
13301 case OPC_SHLL_OB_DSP
:
13302 op2
= MASK_SHLL_OB(ctx
->opcode
);
13306 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13310 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13312 case OPC_SHLL_S_PW
:
13314 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13316 case OPC_SHLLV_S_PW
:
13318 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13322 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13326 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13330 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13334 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13336 case OPC_SHLL_S_QH
:
13338 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13340 case OPC_SHLLV_S_QH
:
13342 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13346 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13350 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13352 case OPC_SHRA_R_OB
:
13354 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13356 case OPC_SHRAV_R_OB
:
13358 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13362 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13366 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13368 case OPC_SHRA_R_PW
:
13370 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13372 case OPC_SHRAV_R_PW
:
13374 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13378 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13382 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13384 case OPC_SHRA_R_QH
:
13386 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13388 case OPC_SHRAV_R_QH
:
13390 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13394 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13398 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13402 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13406 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13408 default: /* Invalid */
13409 MIPS_INVAL("MASK SHLL.OB");
13410 generate_exception(ctx
, EXCP_RI
);
13418 tcg_temp_free(v1_t
);
13419 tcg_temp_free(v2_t
);
13420 (void)opn
; /* avoid a compiler warning */
13421 MIPS_DEBUG("%s", opn
);
13424 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13425 int ret
, int v1
, int v2
, int check_ret
)
13427 const char *opn
= "mipsdsp multiply";
13432 if ((ret
== 0) && (check_ret
== 1)) {
13433 /* Treat as NOP. */
13438 t0
= tcg_temp_new_i32();
13439 v1_t
= tcg_temp_new();
13440 v2_t
= tcg_temp_new();
13442 tcg_gen_movi_i32(t0
, ret
);
13443 gen_load_gpr(v1_t
, v1
);
13444 gen_load_gpr(v2_t
, v2
);
13447 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13448 * the same mask and op1. */
13449 case OPC_MULT_G_2E
:
13453 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13456 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13459 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13461 case OPC_MULQ_RS_W
:
13462 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13466 case OPC_DPA_W_PH_DSP
:
13468 case OPC_DPAU_H_QBL
:
13470 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13472 case OPC_DPAU_H_QBR
:
13474 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13476 case OPC_DPSU_H_QBL
:
13478 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13480 case OPC_DPSU_H_QBR
:
13482 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13486 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13488 case OPC_DPAX_W_PH
:
13490 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13492 case OPC_DPAQ_S_W_PH
:
13494 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13496 case OPC_DPAQX_S_W_PH
:
13498 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13500 case OPC_DPAQX_SA_W_PH
:
13502 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13506 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13508 case OPC_DPSX_W_PH
:
13510 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13512 case OPC_DPSQ_S_W_PH
:
13514 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13516 case OPC_DPSQX_S_W_PH
:
13518 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13520 case OPC_DPSQX_SA_W_PH
:
13522 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13524 case OPC_MULSAQ_S_W_PH
:
13526 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13528 case OPC_DPAQ_SA_L_W
:
13530 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13532 case OPC_DPSQ_SA_L_W
:
13534 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13536 case OPC_MAQ_S_W_PHL
:
13538 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13540 case OPC_MAQ_S_W_PHR
:
13542 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13544 case OPC_MAQ_SA_W_PHL
:
13546 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13548 case OPC_MAQ_SA_W_PHR
:
13550 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13552 case OPC_MULSA_W_PH
:
13554 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13558 #ifdef TARGET_MIPS64
13559 case OPC_DPAQ_W_QH_DSP
:
13561 int ac
= ret
& 0x03;
13562 tcg_gen_movi_i32(t0
, ac
);
13567 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13571 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13575 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13579 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13583 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13585 case OPC_DPAQ_S_W_QH
:
13587 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13589 case OPC_DPAQ_SA_L_PW
:
13591 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13593 case OPC_DPAU_H_OBL
:
13595 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13597 case OPC_DPAU_H_OBR
:
13599 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13603 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13605 case OPC_DPSQ_S_W_QH
:
13607 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13609 case OPC_DPSQ_SA_L_PW
:
13611 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13613 case OPC_DPSU_H_OBL
:
13615 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13617 case OPC_DPSU_H_OBR
:
13619 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13621 case OPC_MAQ_S_L_PWL
:
13623 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13625 case OPC_MAQ_S_L_PWR
:
13627 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13629 case OPC_MAQ_S_W_QHLL
:
13631 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13633 case OPC_MAQ_SA_W_QHLL
:
13635 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13637 case OPC_MAQ_S_W_QHLR
:
13639 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13641 case OPC_MAQ_SA_W_QHLR
:
13643 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13645 case OPC_MAQ_S_W_QHRL
:
13647 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13649 case OPC_MAQ_SA_W_QHRL
:
13651 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13653 case OPC_MAQ_S_W_QHRR
:
13655 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13657 case OPC_MAQ_SA_W_QHRR
:
13659 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13661 case OPC_MULSAQ_S_L_PW
:
13663 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13665 case OPC_MULSAQ_S_W_QH
:
13667 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13673 case OPC_ADDU_QB_DSP
:
13675 case OPC_MULEU_S_PH_QBL
:
13677 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13679 case OPC_MULEU_S_PH_QBR
:
13681 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13683 case OPC_MULQ_RS_PH
:
13685 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13687 case OPC_MULEQ_S_W_PHL
:
13689 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13691 case OPC_MULEQ_S_W_PHR
:
13693 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13695 case OPC_MULQ_S_PH
:
13697 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13701 #ifdef TARGET_MIPS64
13702 case OPC_ADDU_OB_DSP
:
13704 case OPC_MULEQ_S_PW_QHL
:
13706 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13708 case OPC_MULEQ_S_PW_QHR
:
13710 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13712 case OPC_MULEU_S_QH_OBL
:
13714 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13716 case OPC_MULEU_S_QH_OBR
:
13718 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13720 case OPC_MULQ_RS_QH
:
13722 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13729 tcg_temp_free_i32(t0
);
13730 tcg_temp_free(v1_t
);
13731 tcg_temp_free(v2_t
);
13733 (void)opn
; /* avoid a compiler warning */
13734 MIPS_DEBUG("%s", opn
);
13738 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13741 const char *opn
= "mipsdsp Bit/ Manipulation";
13747 /* Treat as NOP. */
13752 t0
= tcg_temp_new();
13753 val_t
= tcg_temp_new();
13754 gen_load_gpr(val_t
, val
);
13757 case OPC_ABSQ_S_PH_DSP
:
13761 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13766 target_long result
;
13767 imm
= (ctx
->opcode
>> 16) & 0xFF;
13768 result
= (uint32_t)imm
<< 24 |
13769 (uint32_t)imm
<< 16 |
13770 (uint32_t)imm
<< 8 |
13772 result
= (int32_t)result
;
13773 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13778 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13779 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13780 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13781 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13782 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13783 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13788 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13789 imm
= (int16_t)(imm
<< 6) >> 6;
13790 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13791 (target_long
)((int32_t)imm
<< 16 | \
13797 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13798 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13799 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13800 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13804 #ifdef TARGET_MIPS64
13805 case OPC_ABSQ_S_QH_DSP
:
13812 imm
= (ctx
->opcode
>> 16) & 0xFF;
13813 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13814 temp
= (temp
<< 16) | temp
;
13815 temp
= (temp
<< 32) | temp
;
13816 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13824 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13825 imm
= (int16_t)(imm
<< 6) >> 6;
13826 temp
= ((target_long
)imm
<< 32) \
13827 | ((target_long
)imm
& 0xFFFFFFFF);
13828 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13836 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13837 imm
= (int16_t)(imm
<< 6) >> 6;
13839 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13840 ((uint64_t)(uint16_t)imm
<< 32) |
13841 ((uint64_t)(uint16_t)imm
<< 16) |
13842 (uint64_t)(uint16_t)imm
;
13843 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13848 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13849 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13850 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13851 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13852 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13853 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13854 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13858 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13859 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13860 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13864 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13865 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13866 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13867 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13868 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13875 tcg_temp_free(val_t
);
13877 (void)opn
; /* avoid a compiler warning */
13878 MIPS_DEBUG("%s", opn
);
13881 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13882 uint32_t op1
, uint32_t op2
,
13883 int ret
, int v1
, int v2
, int check_ret
)
13885 const char *opn
= "mipsdsp add compare pick";
13890 if ((ret
== 0) && (check_ret
== 1)) {
13891 /* Treat as NOP. */
13896 t1
= tcg_temp_new();
13897 v1_t
= tcg_temp_new();
13898 v2_t
= tcg_temp_new();
13900 gen_load_gpr(v1_t
, v1
);
13901 gen_load_gpr(v2_t
, v2
);
13904 case OPC_CMPU_EQ_QB_DSP
:
13906 case OPC_CMPU_EQ_QB
:
13908 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13910 case OPC_CMPU_LT_QB
:
13912 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13914 case OPC_CMPU_LE_QB
:
13916 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13918 case OPC_CMPGU_EQ_QB
:
13920 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13922 case OPC_CMPGU_LT_QB
:
13924 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13926 case OPC_CMPGU_LE_QB
:
13928 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13930 case OPC_CMPGDU_EQ_QB
:
13932 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13933 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13934 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13935 tcg_gen_shli_tl(t1
, t1
, 24);
13936 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13938 case OPC_CMPGDU_LT_QB
:
13940 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
13941 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13942 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13943 tcg_gen_shli_tl(t1
, t1
, 24);
13944 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13946 case OPC_CMPGDU_LE_QB
:
13948 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
13949 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13950 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13951 tcg_gen_shli_tl(t1
, t1
, 24);
13952 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13954 case OPC_CMP_EQ_PH
:
13956 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
13958 case OPC_CMP_LT_PH
:
13960 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
13962 case OPC_CMP_LE_PH
:
13964 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
13968 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13972 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13974 case OPC_PACKRL_PH
:
13976 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13980 #ifdef TARGET_MIPS64
13981 case OPC_CMPU_EQ_OB_DSP
:
13983 case OPC_CMP_EQ_PW
:
13985 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
13987 case OPC_CMP_LT_PW
:
13989 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
13991 case OPC_CMP_LE_PW
:
13993 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
13995 case OPC_CMP_EQ_QH
:
13997 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
13999 case OPC_CMP_LT_QH
:
14001 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
14003 case OPC_CMP_LE_QH
:
14005 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
14007 case OPC_CMPGDU_EQ_OB
:
14009 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14011 case OPC_CMPGDU_LT_OB
:
14013 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14015 case OPC_CMPGDU_LE_OB
:
14017 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14019 case OPC_CMPGU_EQ_OB
:
14021 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14023 case OPC_CMPGU_LT_OB
:
14025 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14027 case OPC_CMPGU_LE_OB
:
14029 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14031 case OPC_CMPU_EQ_OB
:
14033 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
14035 case OPC_CMPU_LT_OB
:
14037 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
14039 case OPC_CMPU_LE_OB
:
14041 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
14043 case OPC_PACKRL_PW
:
14045 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14049 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14053 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14057 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14065 tcg_temp_free(v1_t
);
14066 tcg_temp_free(v2_t
);
14068 (void)opn
; /* avoid a compiler warning */
14069 MIPS_DEBUG("%s", opn
);
14072 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14073 uint32_t op1
, int rt
, int rs
, int sa
)
14075 const char *opn
= "mipsdsp append/dappend";
14081 /* Treat as NOP. */
14086 t0
= tcg_temp_new();
14087 gen_load_gpr(t0
, rs
);
14090 case OPC_APPEND_DSP
:
14091 switch (MASK_APPEND(ctx
->opcode
)) {
14094 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14096 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14100 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14101 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14102 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14103 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14105 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14109 if (sa
!= 0 && sa
!= 2) {
14110 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14111 tcg_gen_ext32u_tl(t0
, t0
);
14112 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14113 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14115 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14117 default: /* Invalid */
14118 MIPS_INVAL("MASK APPEND");
14119 generate_exception(ctx
, EXCP_RI
);
14123 #ifdef TARGET_MIPS64
14124 case OPC_DAPPEND_DSP
:
14125 switch (MASK_DAPPEND(ctx
->opcode
)) {
14128 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14132 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14133 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14134 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14138 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14139 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14140 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14145 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14146 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14147 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14148 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14151 default: /* Invalid */
14152 MIPS_INVAL("MASK DAPPEND");
14153 generate_exception(ctx
, EXCP_RI
);
14160 (void)opn
; /* avoid a compiler warning */
14161 MIPS_DEBUG("%s", opn
);
14164 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14165 int ret
, int v1
, int v2
, int check_ret
)
14168 const char *opn
= "mipsdsp accumulator";
14175 if ((ret
== 0) && (check_ret
== 1)) {
14176 /* Treat as NOP. */
14181 t0
= tcg_temp_new();
14182 t1
= tcg_temp_new();
14183 v1_t
= tcg_temp_new();
14184 v2_t
= tcg_temp_new();
14186 gen_load_gpr(v1_t
, v1
);
14187 gen_load_gpr(v2_t
, v2
);
14190 case OPC_EXTR_W_DSP
:
14194 tcg_gen_movi_tl(t0
, v2
);
14195 tcg_gen_movi_tl(t1
, v1
);
14196 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14199 tcg_gen_movi_tl(t0
, v2
);
14200 tcg_gen_movi_tl(t1
, v1
);
14201 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14203 case OPC_EXTR_RS_W
:
14204 tcg_gen_movi_tl(t0
, v2
);
14205 tcg_gen_movi_tl(t1
, v1
);
14206 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14209 tcg_gen_movi_tl(t0
, v2
);
14210 tcg_gen_movi_tl(t1
, v1
);
14211 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14213 case OPC_EXTRV_S_H
:
14214 tcg_gen_movi_tl(t0
, v2
);
14215 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14218 tcg_gen_movi_tl(t0
, v2
);
14219 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14221 case OPC_EXTRV_R_W
:
14222 tcg_gen_movi_tl(t0
, v2
);
14223 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14225 case OPC_EXTRV_RS_W
:
14226 tcg_gen_movi_tl(t0
, v2
);
14227 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14230 tcg_gen_movi_tl(t0
, v2
);
14231 tcg_gen_movi_tl(t1
, v1
);
14232 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14235 tcg_gen_movi_tl(t0
, v2
);
14236 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14239 tcg_gen_movi_tl(t0
, v2
);
14240 tcg_gen_movi_tl(t1
, v1
);
14241 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14244 tcg_gen_movi_tl(t0
, v2
);
14245 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14248 imm
= (ctx
->opcode
>> 20) & 0x3F;
14249 tcg_gen_movi_tl(t0
, ret
);
14250 tcg_gen_movi_tl(t1
, imm
);
14251 gen_helper_shilo(t0
, t1
, cpu_env
);
14254 tcg_gen_movi_tl(t0
, ret
);
14255 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14258 tcg_gen_movi_tl(t0
, ret
);
14259 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14262 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14263 tcg_gen_movi_tl(t0
, imm
);
14264 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14267 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14268 tcg_gen_movi_tl(t0
, imm
);
14269 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14273 #ifdef TARGET_MIPS64
14274 case OPC_DEXTR_W_DSP
:
14278 tcg_gen_movi_tl(t0
, ret
);
14279 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14283 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14284 int ac
= (ctx
->opcode
>> 11) & 0x03;
14285 tcg_gen_movi_tl(t0
, shift
);
14286 tcg_gen_movi_tl(t1
, ac
);
14287 gen_helper_dshilo(t0
, t1
, cpu_env
);
14292 int ac
= (ctx
->opcode
>> 11) & 0x03;
14293 tcg_gen_movi_tl(t0
, ac
);
14294 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14298 tcg_gen_movi_tl(t0
, v2
);
14299 tcg_gen_movi_tl(t1
, v1
);
14301 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14304 tcg_gen_movi_tl(t0
, v2
);
14305 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14308 tcg_gen_movi_tl(t0
, v2
);
14309 tcg_gen_movi_tl(t1
, v1
);
14310 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14313 tcg_gen_movi_tl(t0
, v2
);
14314 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14317 tcg_gen_movi_tl(t0
, v2
);
14318 tcg_gen_movi_tl(t1
, v1
);
14319 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14321 case OPC_DEXTR_R_L
:
14322 tcg_gen_movi_tl(t0
, v2
);
14323 tcg_gen_movi_tl(t1
, v1
);
14324 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14326 case OPC_DEXTR_RS_L
:
14327 tcg_gen_movi_tl(t0
, v2
);
14328 tcg_gen_movi_tl(t1
, v1
);
14329 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14332 tcg_gen_movi_tl(t0
, v2
);
14333 tcg_gen_movi_tl(t1
, v1
);
14334 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14336 case OPC_DEXTR_R_W
:
14337 tcg_gen_movi_tl(t0
, v2
);
14338 tcg_gen_movi_tl(t1
, v1
);
14339 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14341 case OPC_DEXTR_RS_W
:
14342 tcg_gen_movi_tl(t0
, v2
);
14343 tcg_gen_movi_tl(t1
, v1
);
14344 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14346 case OPC_DEXTR_S_H
:
14347 tcg_gen_movi_tl(t0
, v2
);
14348 tcg_gen_movi_tl(t1
, v1
);
14349 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14351 case OPC_DEXTRV_S_H
:
14352 tcg_gen_movi_tl(t0
, v2
);
14353 tcg_gen_movi_tl(t1
, v1
);
14354 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14357 tcg_gen_movi_tl(t0
, v2
);
14358 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14360 case OPC_DEXTRV_R_L
:
14361 tcg_gen_movi_tl(t0
, v2
);
14362 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14364 case OPC_DEXTRV_RS_L
:
14365 tcg_gen_movi_tl(t0
, v2
);
14366 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14369 tcg_gen_movi_tl(t0
, v2
);
14370 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14372 case OPC_DEXTRV_R_W
:
14373 tcg_gen_movi_tl(t0
, v2
);
14374 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14376 case OPC_DEXTRV_RS_W
:
14377 tcg_gen_movi_tl(t0
, v2
);
14378 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14387 tcg_temp_free(v1_t
);
14388 tcg_temp_free(v2_t
);
14390 (void)opn
; /* avoid a compiler warning */
14391 MIPS_DEBUG("%s", opn
);
14394 /* End MIPSDSP functions. */
14396 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
14399 int rs
, rt
, rd
, sa
;
14400 uint32_t op
, op1
, op2
;
14403 /* make sure instructions are on a word boundary */
14404 if (ctx
->pc
& 0x3) {
14405 env
->CP0_BadVAddr
= ctx
->pc
;
14406 generate_exception(ctx
, EXCP_AdEL
);
14410 /* Handle blikely not taken case */
14411 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14412 int l1
= gen_new_label();
14414 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14415 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14416 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14417 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14421 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14422 tcg_gen_debug_insn_start(ctx
->pc
);
14425 op
= MASK_OP_MAJOR(ctx
->opcode
);
14426 rs
= (ctx
->opcode
>> 21) & 0x1f;
14427 rt
= (ctx
->opcode
>> 16) & 0x1f;
14428 rd
= (ctx
->opcode
>> 11) & 0x1f;
14429 sa
= (ctx
->opcode
>> 6) & 0x1f;
14430 imm
= (int16_t)ctx
->opcode
;
14433 op1
= MASK_SPECIAL(ctx
->opcode
);
14435 case OPC_SLL
: /* Shift with immediate */
14437 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14440 switch ((ctx
->opcode
>> 21) & 0x1f) {
14442 /* rotr is decoded as srl on non-R2 CPUs */
14443 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14448 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14451 generate_exception(ctx
, EXCP_RI
);
14455 case OPC_MOVN
: /* Conditional move */
14457 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14458 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14459 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14461 case OPC_ADD
... OPC_SUBU
:
14462 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14464 case OPC_SLLV
: /* Shifts */
14466 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14469 switch ((ctx
->opcode
>> 6) & 0x1f) {
14471 /* rotrv is decoded as srlv on non-R2 CPUs */
14472 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14477 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14480 generate_exception(ctx
, EXCP_RI
);
14484 case OPC_SLT
: /* Set on less than */
14486 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14488 case OPC_AND
: /* Logic*/
14492 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14497 check_insn(ctx
, INSN_VR54XX
);
14498 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14499 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14501 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14506 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14508 case OPC_JR
... OPC_JALR
:
14509 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14511 case OPC_TGE
... OPC_TEQ
: /* Traps */
14513 gen_trap(ctx
, op1
, rs
, rt
, -1);
14515 case OPC_MFHI
: /* Move from HI/LO */
14517 gen_HILO(ctx
, op1
, rs
& 3, rd
);
14520 case OPC_MTLO
: /* Move to HI/LO */
14521 gen_HILO(ctx
, op1
, rd
& 3, rs
);
14523 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14524 #ifdef MIPS_STRICT_STANDARD
14525 MIPS_INVAL("PMON / selsl");
14526 generate_exception(ctx
, EXCP_RI
);
14528 gen_helper_0e0i(pmon
, sa
);
14532 generate_exception(ctx
, EXCP_SYSCALL
);
14533 ctx
->bstate
= BS_STOP
;
14536 generate_exception(ctx
, EXCP_BREAK
);
14539 #ifdef MIPS_STRICT_STANDARD
14540 MIPS_INVAL("SPIM");
14541 generate_exception(ctx
, EXCP_RI
);
14543 /* Implemented as RI exception for now. */
14544 MIPS_INVAL("spim (unofficial)");
14545 generate_exception(ctx
, EXCP_RI
);
14549 /* Treat as NOP. */
14553 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14554 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14555 check_cp1_enabled(ctx
);
14556 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14557 (ctx
->opcode
>> 16) & 1);
14559 generate_exception_err(ctx
, EXCP_CpU
, 1);
14563 #if defined(TARGET_MIPS64)
14564 /* MIPS64 specific opcodes */
14569 check_insn(ctx
, ISA_MIPS3
);
14570 check_mips_64(ctx
);
14571 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14574 switch ((ctx
->opcode
>> 21) & 0x1f) {
14576 /* drotr is decoded as dsrl on non-R2 CPUs */
14577 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14582 check_insn(ctx
, ISA_MIPS3
);
14583 check_mips_64(ctx
);
14584 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14587 generate_exception(ctx
, EXCP_RI
);
14592 switch ((ctx
->opcode
>> 21) & 0x1f) {
14594 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14595 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14600 check_insn(ctx
, ISA_MIPS3
);
14601 check_mips_64(ctx
);
14602 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14605 generate_exception(ctx
, EXCP_RI
);
14609 case OPC_DADD
... OPC_DSUBU
:
14610 check_insn(ctx
, ISA_MIPS3
);
14611 check_mips_64(ctx
);
14612 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14616 check_insn(ctx
, ISA_MIPS3
);
14617 check_mips_64(ctx
);
14618 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14621 switch ((ctx
->opcode
>> 6) & 0x1f) {
14623 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14624 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14629 check_insn(ctx
, ISA_MIPS3
);
14630 check_mips_64(ctx
);
14631 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14634 generate_exception(ctx
, EXCP_RI
);
14638 case OPC_DMULT
... OPC_DDIVU
:
14639 check_insn(ctx
, ISA_MIPS3
);
14640 check_mips_64(ctx
);
14641 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14644 default: /* Invalid */
14645 MIPS_INVAL("special");
14646 generate_exception(ctx
, EXCP_RI
);
14651 op1
= MASK_SPECIAL2(ctx
->opcode
);
14653 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14654 case OPC_MSUB
... OPC_MSUBU
:
14655 check_insn(ctx
, ISA_MIPS32
);
14656 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14659 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14663 check_insn(ctx
, ISA_MIPS32
);
14664 gen_cl(ctx
, op1
, rd
, rs
);
14667 /* XXX: not clear which exception should be raised
14668 * when in debug mode...
14670 check_insn(ctx
, ISA_MIPS32
);
14671 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14672 generate_exception(ctx
, EXCP_DBp
);
14674 generate_exception(ctx
, EXCP_DBp
);
14676 /* Treat as NOP. */
14679 case OPC_DIVU_G_2F
:
14680 case OPC_MULT_G_2F
:
14681 case OPC_MULTU_G_2F
:
14683 case OPC_MODU_G_2F
:
14684 check_insn(ctx
, INSN_LOONGSON2F
);
14685 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14687 #if defined(TARGET_MIPS64)
14690 check_insn(ctx
, ISA_MIPS64
);
14691 check_mips_64(ctx
);
14692 gen_cl(ctx
, op1
, rd
, rs
);
14694 case OPC_DMULT_G_2F
:
14695 case OPC_DMULTU_G_2F
:
14696 case OPC_DDIV_G_2F
:
14697 case OPC_DDIVU_G_2F
:
14698 case OPC_DMOD_G_2F
:
14699 case OPC_DMODU_G_2F
:
14700 check_insn(ctx
, INSN_LOONGSON2F
);
14701 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14704 default: /* Invalid */
14705 MIPS_INVAL("special2");
14706 generate_exception(ctx
, EXCP_RI
);
14711 op1
= MASK_SPECIAL3(ctx
->opcode
);
14715 check_insn(ctx
, ISA_MIPS32R2
);
14716 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14719 check_insn(ctx
, ISA_MIPS32R2
);
14720 op2
= MASK_BSHFL(ctx
->opcode
);
14721 gen_bshfl(ctx
, op2
, rt
, rd
);
14724 gen_rdhwr(ctx
, rt
, rd
);
14727 check_insn(ctx
, ASE_MT
);
14729 TCGv t0
= tcg_temp_new();
14730 TCGv t1
= tcg_temp_new();
14732 gen_load_gpr(t0
, rt
);
14733 gen_load_gpr(t1
, rs
);
14734 gen_helper_fork(t0
, t1
);
14740 check_insn(ctx
, ASE_MT
);
14742 TCGv t0
= tcg_temp_new();
14744 save_cpu_state(ctx
, 1);
14745 gen_load_gpr(t0
, rs
);
14746 gen_helper_yield(t0
, cpu_env
, t0
);
14747 gen_store_gpr(t0
, rd
);
14751 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14752 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14753 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14754 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14755 * the same mask and op1. */
14756 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14757 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14760 case OPC_ADDUH_R_QB
:
14762 case OPC_ADDQH_R_PH
:
14764 case OPC_ADDQH_R_W
:
14766 case OPC_SUBUH_R_QB
:
14768 case OPC_SUBQH_R_PH
:
14770 case OPC_SUBQH_R_W
:
14771 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14776 case OPC_MULQ_RS_W
:
14777 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14780 MIPS_INVAL("MASK ADDUH.QB");
14781 generate_exception(ctx
, EXCP_RI
);
14784 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14785 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14787 generate_exception(ctx
, EXCP_RI
);
14791 op2
= MASK_LX(ctx
->opcode
);
14793 #if defined(TARGET_MIPS64)
14799 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14801 default: /* Invalid */
14802 MIPS_INVAL("MASK LX");
14803 generate_exception(ctx
, EXCP_RI
);
14807 case OPC_ABSQ_S_PH_DSP
:
14808 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14810 case OPC_ABSQ_S_QB
:
14811 case OPC_ABSQ_S_PH
:
14813 case OPC_PRECEQ_W_PHL
:
14814 case OPC_PRECEQ_W_PHR
:
14815 case OPC_PRECEQU_PH_QBL
:
14816 case OPC_PRECEQU_PH_QBR
:
14817 case OPC_PRECEQU_PH_QBLA
:
14818 case OPC_PRECEQU_PH_QBRA
:
14819 case OPC_PRECEU_PH_QBL
:
14820 case OPC_PRECEU_PH_QBR
:
14821 case OPC_PRECEU_PH_QBLA
:
14822 case OPC_PRECEU_PH_QBRA
:
14823 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14830 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14833 MIPS_INVAL("MASK ABSQ_S.PH");
14834 generate_exception(ctx
, EXCP_RI
);
14838 case OPC_ADDU_QB_DSP
:
14839 op2
= MASK_ADDU_QB(ctx
->opcode
);
14842 case OPC_ADDQ_S_PH
:
14845 case OPC_ADDU_S_QB
:
14847 case OPC_ADDU_S_PH
:
14849 case OPC_SUBQ_S_PH
:
14852 case OPC_SUBU_S_QB
:
14854 case OPC_SUBU_S_PH
:
14858 case OPC_RADDU_W_QB
:
14859 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14861 case OPC_MULEU_S_PH_QBL
:
14862 case OPC_MULEU_S_PH_QBR
:
14863 case OPC_MULQ_RS_PH
:
14864 case OPC_MULEQ_S_W_PHL
:
14865 case OPC_MULEQ_S_W_PHR
:
14866 case OPC_MULQ_S_PH
:
14867 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14869 default: /* Invalid */
14870 MIPS_INVAL("MASK ADDU.QB");
14871 generate_exception(ctx
, EXCP_RI
);
14876 case OPC_CMPU_EQ_QB_DSP
:
14877 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14879 case OPC_PRECR_SRA_PH_W
:
14880 case OPC_PRECR_SRA_R_PH_W
:
14881 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14883 case OPC_PRECR_QB_PH
:
14884 case OPC_PRECRQ_QB_PH
:
14885 case OPC_PRECRQ_PH_W
:
14886 case OPC_PRECRQ_RS_PH_W
:
14887 case OPC_PRECRQU_S_QB_PH
:
14888 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14890 case OPC_CMPU_EQ_QB
:
14891 case OPC_CMPU_LT_QB
:
14892 case OPC_CMPU_LE_QB
:
14893 case OPC_CMP_EQ_PH
:
14894 case OPC_CMP_LT_PH
:
14895 case OPC_CMP_LE_PH
:
14896 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14898 case OPC_CMPGU_EQ_QB
:
14899 case OPC_CMPGU_LT_QB
:
14900 case OPC_CMPGU_LE_QB
:
14901 case OPC_CMPGDU_EQ_QB
:
14902 case OPC_CMPGDU_LT_QB
:
14903 case OPC_CMPGDU_LE_QB
:
14906 case OPC_PACKRL_PH
:
14907 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14909 default: /* Invalid */
14910 MIPS_INVAL("MASK CMPU.EQ.QB");
14911 generate_exception(ctx
, EXCP_RI
);
14915 case OPC_SHLL_QB_DSP
:
14916 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14918 case OPC_DPA_W_PH_DSP
:
14919 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14921 case OPC_DPAU_H_QBL
:
14922 case OPC_DPAU_H_QBR
:
14923 case OPC_DPSU_H_QBL
:
14924 case OPC_DPSU_H_QBR
:
14926 case OPC_DPAX_W_PH
:
14927 case OPC_DPAQ_S_W_PH
:
14928 case OPC_DPAQX_S_W_PH
:
14929 case OPC_DPAQX_SA_W_PH
:
14931 case OPC_DPSX_W_PH
:
14932 case OPC_DPSQ_S_W_PH
:
14933 case OPC_DPSQX_S_W_PH
:
14934 case OPC_DPSQX_SA_W_PH
:
14935 case OPC_MULSAQ_S_W_PH
:
14936 case OPC_DPAQ_SA_L_W
:
14937 case OPC_DPSQ_SA_L_W
:
14938 case OPC_MAQ_S_W_PHL
:
14939 case OPC_MAQ_S_W_PHR
:
14940 case OPC_MAQ_SA_W_PHL
:
14941 case OPC_MAQ_SA_W_PHR
:
14942 case OPC_MULSA_W_PH
:
14943 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14945 default: /* Invalid */
14946 MIPS_INVAL("MASK DPAW.PH");
14947 generate_exception(ctx
, EXCP_RI
);
14952 op2
= MASK_INSV(ctx
->opcode
);
14964 t0
= tcg_temp_new();
14965 t1
= tcg_temp_new();
14967 gen_load_gpr(t0
, rt
);
14968 gen_load_gpr(t1
, rs
);
14970 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
14976 default: /* Invalid */
14977 MIPS_INVAL("MASK INSV");
14978 generate_exception(ctx
, EXCP_RI
);
14982 case OPC_APPEND_DSP
:
14983 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
14985 case OPC_EXTR_W_DSP
:
14986 op2
= MASK_EXTR_W(ctx
->opcode
);
14990 case OPC_EXTR_RS_W
:
14992 case OPC_EXTRV_S_H
:
14994 case OPC_EXTRV_R_W
:
14995 case OPC_EXTRV_RS_W
:
15000 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15003 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15009 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15011 default: /* Invalid */
15012 MIPS_INVAL("MASK EXTR.W");
15013 generate_exception(ctx
, EXCP_RI
);
15017 #if defined(TARGET_MIPS64)
15018 case OPC_DEXTM
... OPC_DEXT
:
15019 case OPC_DINSM
... OPC_DINS
:
15020 check_insn(ctx
, ISA_MIPS64R2
);
15021 check_mips_64(ctx
);
15022 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
15025 check_insn(ctx
, ISA_MIPS64R2
);
15026 check_mips_64(ctx
);
15027 op2
= MASK_DBSHFL(ctx
->opcode
);
15028 gen_bshfl(ctx
, op2
, rt
, rd
);
15030 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
15031 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
15032 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
15033 check_insn(ctx
, INSN_LOONGSON2E
);
15034 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
15036 case OPC_ABSQ_S_QH_DSP
:
15037 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
15039 case OPC_PRECEQ_L_PWL
:
15040 case OPC_PRECEQ_L_PWR
:
15041 case OPC_PRECEQ_PW_QHL
:
15042 case OPC_PRECEQ_PW_QHR
:
15043 case OPC_PRECEQ_PW_QHLA
:
15044 case OPC_PRECEQ_PW_QHRA
:
15045 case OPC_PRECEQU_QH_OBL
:
15046 case OPC_PRECEQU_QH_OBR
:
15047 case OPC_PRECEQU_QH_OBLA
:
15048 case OPC_PRECEQU_QH_OBRA
:
15049 case OPC_PRECEU_QH_OBL
:
15050 case OPC_PRECEU_QH_OBR
:
15051 case OPC_PRECEU_QH_OBLA
:
15052 case OPC_PRECEU_QH_OBRA
:
15053 case OPC_ABSQ_S_OB
:
15054 case OPC_ABSQ_S_PW
:
15055 case OPC_ABSQ_S_QH
:
15056 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15064 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
15066 default: /* Invalid */
15067 MIPS_INVAL("MASK ABSQ_S.QH");
15068 generate_exception(ctx
, EXCP_RI
);
15072 case OPC_ADDU_OB_DSP
:
15073 op2
= MASK_ADDU_OB(ctx
->opcode
);
15075 case OPC_RADDU_L_OB
:
15077 case OPC_SUBQ_S_PW
:
15079 case OPC_SUBQ_S_QH
:
15081 case OPC_SUBU_S_OB
:
15083 case OPC_SUBU_S_QH
:
15085 case OPC_SUBUH_R_OB
:
15087 case OPC_ADDQ_S_PW
:
15089 case OPC_ADDQ_S_QH
:
15091 case OPC_ADDU_S_OB
:
15093 case OPC_ADDU_S_QH
:
15095 case OPC_ADDUH_R_OB
:
15096 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15098 case OPC_MULEQ_S_PW_QHL
:
15099 case OPC_MULEQ_S_PW_QHR
:
15100 case OPC_MULEU_S_QH_OBL
:
15101 case OPC_MULEU_S_QH_OBR
:
15102 case OPC_MULQ_RS_QH
:
15103 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15105 default: /* Invalid */
15106 MIPS_INVAL("MASK ADDU.OB");
15107 generate_exception(ctx
, EXCP_RI
);
15111 case OPC_CMPU_EQ_OB_DSP
:
15112 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15114 case OPC_PRECR_SRA_QH_PW
:
15115 case OPC_PRECR_SRA_R_QH_PW
:
15116 /* Return value is rt. */
15117 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15119 case OPC_PRECR_OB_QH
:
15120 case OPC_PRECRQ_OB_QH
:
15121 case OPC_PRECRQ_PW_L
:
15122 case OPC_PRECRQ_QH_PW
:
15123 case OPC_PRECRQ_RS_QH_PW
:
15124 case OPC_PRECRQU_S_OB_QH
:
15125 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15127 case OPC_CMPU_EQ_OB
:
15128 case OPC_CMPU_LT_OB
:
15129 case OPC_CMPU_LE_OB
:
15130 case OPC_CMP_EQ_QH
:
15131 case OPC_CMP_LT_QH
:
15132 case OPC_CMP_LE_QH
:
15133 case OPC_CMP_EQ_PW
:
15134 case OPC_CMP_LT_PW
:
15135 case OPC_CMP_LE_PW
:
15136 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15138 case OPC_CMPGDU_EQ_OB
:
15139 case OPC_CMPGDU_LT_OB
:
15140 case OPC_CMPGDU_LE_OB
:
15141 case OPC_CMPGU_EQ_OB
:
15142 case OPC_CMPGU_LT_OB
:
15143 case OPC_CMPGU_LE_OB
:
15144 case OPC_PACKRL_PW
:
15148 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15150 default: /* Invalid */
15151 MIPS_INVAL("MASK CMPU_EQ.OB");
15152 generate_exception(ctx
, EXCP_RI
);
15156 case OPC_DAPPEND_DSP
:
15157 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15159 case OPC_DEXTR_W_DSP
:
15160 op2
= MASK_DEXTR_W(ctx
->opcode
);
15167 case OPC_DEXTR_R_L
:
15168 case OPC_DEXTR_RS_L
:
15170 case OPC_DEXTR_R_W
:
15171 case OPC_DEXTR_RS_W
:
15172 case OPC_DEXTR_S_H
:
15174 case OPC_DEXTRV_R_L
:
15175 case OPC_DEXTRV_RS_L
:
15176 case OPC_DEXTRV_S_H
:
15178 case OPC_DEXTRV_R_W
:
15179 case OPC_DEXTRV_RS_W
:
15180 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15185 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15187 default: /* Invalid */
15188 MIPS_INVAL("MASK EXTR.W");
15189 generate_exception(ctx
, EXCP_RI
);
15193 case OPC_DPAQ_W_QH_DSP
:
15194 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15196 case OPC_DPAU_H_OBL
:
15197 case OPC_DPAU_H_OBR
:
15198 case OPC_DPSU_H_OBL
:
15199 case OPC_DPSU_H_OBR
:
15201 case OPC_DPAQ_S_W_QH
:
15203 case OPC_DPSQ_S_W_QH
:
15204 case OPC_MULSAQ_S_W_QH
:
15205 case OPC_DPAQ_SA_L_PW
:
15206 case OPC_DPSQ_SA_L_PW
:
15207 case OPC_MULSAQ_S_L_PW
:
15208 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15210 case OPC_MAQ_S_W_QHLL
:
15211 case OPC_MAQ_S_W_QHLR
:
15212 case OPC_MAQ_S_W_QHRL
:
15213 case OPC_MAQ_S_W_QHRR
:
15214 case OPC_MAQ_SA_W_QHLL
:
15215 case OPC_MAQ_SA_W_QHLR
:
15216 case OPC_MAQ_SA_W_QHRL
:
15217 case OPC_MAQ_SA_W_QHRR
:
15218 case OPC_MAQ_S_L_PWL
:
15219 case OPC_MAQ_S_L_PWR
:
15224 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15226 default: /* Invalid */
15227 MIPS_INVAL("MASK DPAQ.W.QH");
15228 generate_exception(ctx
, EXCP_RI
);
15232 case OPC_DINSV_DSP
:
15233 op2
= MASK_INSV(ctx
->opcode
);
15245 t0
= tcg_temp_new();
15246 t1
= tcg_temp_new();
15248 gen_load_gpr(t0
, rt
);
15249 gen_load_gpr(t1
, rs
);
15251 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15254 default: /* Invalid */
15255 MIPS_INVAL("MASK DINSV");
15256 generate_exception(ctx
, EXCP_RI
);
15260 case OPC_SHLL_OB_DSP
:
15261 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15264 default: /* Invalid */
15265 MIPS_INVAL("special3");
15266 generate_exception(ctx
, EXCP_RI
);
15271 op1
= MASK_REGIMM(ctx
->opcode
);
15273 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15274 case OPC_BLTZAL
... OPC_BGEZALL
:
15275 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15277 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15279 gen_trap(ctx
, op1
, rs
, -1, imm
);
15282 check_insn(ctx
, ISA_MIPS32R2
);
15283 /* Treat as NOP. */
15285 case OPC_BPOSGE32
: /* MIPS DSP branch */
15286 #if defined(TARGET_MIPS64)
15290 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15292 default: /* Invalid */
15293 MIPS_INVAL("regimm");
15294 generate_exception(ctx
, EXCP_RI
);
15299 check_cp0_enabled(ctx
);
15300 op1
= MASK_CP0(ctx
->opcode
);
15306 #if defined(TARGET_MIPS64)
15310 #ifndef CONFIG_USER_ONLY
15311 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15312 #endif /* !CONFIG_USER_ONLY */
15314 case OPC_C0_FIRST
... OPC_C0_LAST
:
15315 #ifndef CONFIG_USER_ONLY
15316 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15317 #endif /* !CONFIG_USER_ONLY */
15320 #ifndef CONFIG_USER_ONLY
15322 TCGv t0
= tcg_temp_new();
15324 op2
= MASK_MFMC0(ctx
->opcode
);
15327 check_insn(ctx
, ASE_MT
);
15328 gen_helper_dmt(t0
);
15329 gen_store_gpr(t0
, rt
);
15332 check_insn(ctx
, ASE_MT
);
15333 gen_helper_emt(t0
);
15334 gen_store_gpr(t0
, rt
);
15337 check_insn(ctx
, ASE_MT
);
15338 gen_helper_dvpe(t0
, cpu_env
);
15339 gen_store_gpr(t0
, rt
);
15342 check_insn(ctx
, ASE_MT
);
15343 gen_helper_evpe(t0
, cpu_env
);
15344 gen_store_gpr(t0
, rt
);
15347 check_insn(ctx
, ISA_MIPS32R2
);
15348 save_cpu_state(ctx
, 1);
15349 gen_helper_di(t0
, cpu_env
);
15350 gen_store_gpr(t0
, rt
);
15351 /* Stop translation as we may have switched the execution mode */
15352 ctx
->bstate
= BS_STOP
;
15355 check_insn(ctx
, ISA_MIPS32R2
);
15356 save_cpu_state(ctx
, 1);
15357 gen_helper_ei(t0
, cpu_env
);
15358 gen_store_gpr(t0
, rt
);
15359 /* Stop translation as we may have switched the execution mode */
15360 ctx
->bstate
= BS_STOP
;
15362 default: /* Invalid */
15363 MIPS_INVAL("mfmc0");
15364 generate_exception(ctx
, EXCP_RI
);
15369 #endif /* !CONFIG_USER_ONLY */
15372 check_insn(ctx
, ISA_MIPS32R2
);
15373 gen_load_srsgpr(rt
, rd
);
15376 check_insn(ctx
, ISA_MIPS32R2
);
15377 gen_store_srsgpr(rt
, rd
);
15381 generate_exception(ctx
, EXCP_RI
);
15385 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15387 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15389 case OPC_SLTI
: /* Set on less than with immediate opcode */
15391 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15393 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15397 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15399 case OPC_J
... OPC_JAL
: /* Jump */
15400 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15401 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15403 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15404 case OPC_BEQL
... OPC_BGTZL
:
15405 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15407 case OPC_LB
... OPC_LWR
: /* Load and stores */
15409 gen_ld(ctx
, op
, rt
, rs
, imm
);
15411 case OPC_SB
... OPC_SW
:
15413 gen_st(ctx
, op
, rt
, rs
, imm
);
15416 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15419 check_cp0_enabled(ctx
);
15420 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15421 /* Treat as NOP. */
15424 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15425 /* Treat as NOP. */
15428 /* Floating point (COP1). */
15433 gen_cop1_ldst(env
, ctx
, op
, rt
, rs
, imm
);
15437 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15438 check_cp1_enabled(ctx
);
15439 op1
= MASK_CP1(ctx
->opcode
);
15443 check_insn(ctx
, ISA_MIPS32R2
);
15448 gen_cp1(ctx
, op1
, rt
, rd
);
15450 #if defined(TARGET_MIPS64)
15453 check_insn(ctx
, ISA_MIPS3
);
15454 gen_cp1(ctx
, op1
, rt
, rd
);
15460 check_insn(ctx
, ASE_MIPS3D
);
15463 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15464 (rt
>> 2) & 0x7, imm
<< 2);
15471 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15476 generate_exception (ctx
, EXCP_RI
);
15480 generate_exception_err(ctx
, EXCP_CpU
, 1);
15489 /* COP2: Not implemented. */
15490 generate_exception_err(ctx
, EXCP_CpU
, 2);
15493 check_insn(ctx
, INSN_LOONGSON2F
);
15494 /* Note that these instructions use different fields. */
15495 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15499 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15500 check_cp1_enabled(ctx
);
15501 op1
= MASK_CP3(ctx
->opcode
);
15509 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15512 /* Treat as NOP. */
15527 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15531 generate_exception (ctx
, EXCP_RI
);
15535 generate_exception_err(ctx
, EXCP_CpU
, 1);
15539 #if defined(TARGET_MIPS64)
15540 /* MIPS64 opcodes */
15542 case OPC_LDL
... OPC_LDR
:
15545 check_insn(ctx
, ISA_MIPS3
);
15546 check_mips_64(ctx
);
15547 gen_ld(ctx
, op
, rt
, rs
, imm
);
15549 case OPC_SDL
... OPC_SDR
:
15551 check_insn(ctx
, ISA_MIPS3
);
15552 check_mips_64(ctx
);
15553 gen_st(ctx
, op
, rt
, rs
, imm
);
15556 check_insn(ctx
, ISA_MIPS3
);
15557 check_mips_64(ctx
);
15558 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15562 check_insn(ctx
, ISA_MIPS3
);
15563 check_mips_64(ctx
);
15564 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15568 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15569 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15570 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15573 check_insn(ctx
, ASE_MDMX
);
15574 /* MDMX: Not implemented. */
15575 default: /* Invalid */
15576 MIPS_INVAL("major opcode");
15577 generate_exception(ctx
, EXCP_RI
);
15583 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
15586 CPUState
*cs
= CPU(cpu
);
15587 CPUMIPSState
*env
= &cpu
->env
;
15589 target_ulong pc_start
;
15590 uint16_t *gen_opc_end
;
15599 qemu_log("search pc %d\n", search_pc
);
15602 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15605 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
15606 ctx
.insn_flags
= env
->insn_flags
;
15608 ctx
.bstate
= BS_NONE
;
15609 /* Restore delay slot state from the tb context. */
15610 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15611 restore_cpu_state(env
, &ctx
);
15612 #ifdef CONFIG_USER_ONLY
15613 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15615 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15618 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15619 if (max_insns
== 0)
15620 max_insns
= CF_COUNT_MASK
;
15621 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15623 while (ctx
.bstate
== BS_NONE
) {
15624 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
15625 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
15626 if (bp
->pc
== ctx
.pc
) {
15627 save_cpu_state(&ctx
, 1);
15628 ctx
.bstate
= BS_BRANCH
;
15629 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15630 /* Include the breakpoint location or the tb won't
15631 * be flushed when it must be. */
15633 goto done_generating
;
15639 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15643 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15645 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15646 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15647 gen_opc_btarget
[lj
] = ctx
.btarget
;
15648 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15649 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15651 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15654 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
15655 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15656 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15658 decode_opc(env
, &ctx
);
15659 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15660 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15661 insn_bytes
= decode_micromips_opc(env
, &ctx
);
15662 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15663 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15664 insn_bytes
= decode_mips16_opc(env
, &ctx
);
15666 generate_exception(&ctx
, EXCP_RI
);
15667 ctx
.bstate
= BS_STOP
;
15671 handle_delay_slot(&ctx
, insn_bytes
);
15673 ctx
.pc
+= insn_bytes
;
15677 /* Execute a branch and its delay slot as a single instruction.
15678 This is what GDB expects and is consistent with what the
15679 hardware does (e.g. if a delay slot instruction faults, the
15680 reported PC is the PC of the branch). */
15681 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
15685 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15688 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15692 if (num_insns
>= max_insns
)
15698 if (tb
->cflags
& CF_LAST_IO
) {
15701 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15702 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15703 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15705 switch (ctx
.bstate
) {
15707 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15710 save_cpu_state(&ctx
, 0);
15711 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15714 tcg_gen_exit_tb(0);
15722 gen_tb_end(tb
, num_insns
);
15723 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15725 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15728 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15730 tb
->size
= ctx
.pc
- pc_start
;
15731 tb
->icount
= num_insns
;
15735 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15736 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15737 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15743 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15745 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
15748 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15750 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
15753 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15757 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15759 #define printfpr(fp) \
15762 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15763 " fd:%13g fs:%13g psu: %13g\n", \
15764 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15765 (double)(fp)->fd, \
15766 (double)(fp)->fs[FP_ENDIAN_IDX], \
15767 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15770 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15771 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15772 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15773 " fd:%13g fs:%13g psu:%13g\n", \
15774 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15776 (double)tmp.fs[FP_ENDIAN_IDX], \
15777 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15782 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15783 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15784 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15785 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15786 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15787 printfpr(&env
->active_fpu
.fpr
[i
]);
15793 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15794 /* Debug help: The architecture requires 32bit code to maintain proper
15795 sign-extended values on 64bit machines. */
15797 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15800 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15801 fprintf_function cpu_fprintf
,
15806 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15807 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15808 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15809 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15810 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15811 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15812 if (!SIGN_EXT_P(env
->btarget
))
15813 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15815 for (i
= 0; i
< 32; i
++) {
15816 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15817 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15820 if (!SIGN_EXT_P(env
->CP0_EPC
))
15821 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15822 if (!SIGN_EXT_P(env
->lladdr
))
15823 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15827 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
15830 MIPSCPU
*cpu
= MIPS_CPU(cs
);
15831 CPUMIPSState
*env
= &cpu
->env
;
15834 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15835 " LO=0x" TARGET_FMT_lx
" ds %04x "
15836 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15837 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15838 env
->hflags
, env
->btarget
, env
->bcond
);
15839 for (i
= 0; i
< 32; i
++) {
15841 cpu_fprintf(f
, "GPR%02d:", i
);
15842 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15844 cpu_fprintf(f
, "\n");
15847 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15848 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15849 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15850 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15851 if (env
->hflags
& MIPS_HFLAG_FPU
)
15852 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15853 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15854 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15858 void mips_tcg_init(void)
15863 /* Initialize various static tables. */
15867 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15868 TCGV_UNUSED(cpu_gpr
[0]);
15869 for (i
= 1; i
< 32; i
++)
15870 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15871 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15874 for (i
= 0; i
< 32; i
++) {
15875 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15876 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15879 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15880 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15881 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15882 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15883 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15885 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15886 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15888 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15889 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15892 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15893 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15895 bcond
= tcg_global_mem_new(TCG_AREG0
,
15896 offsetof(CPUMIPSState
, bcond
), "bcond");
15897 btarget
= tcg_global_mem_new(TCG_AREG0
,
15898 offsetof(CPUMIPSState
, btarget
), "btarget");
15899 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15900 offsetof(CPUMIPSState
, hflags
), "hflags");
15902 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15903 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15905 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15906 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15912 #include "translate_init.c"
15914 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15918 const mips_def_t
*def
;
15920 def
= cpu_mips_find_by_name(cpu_model
);
15923 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15925 env
->cpu_model
= def
;
15927 #ifndef CONFIG_USER_ONLY
15928 mmu_init(env
, def
);
15930 fpu_init(env
, def
);
15931 mvp_init(env
, def
);
15933 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15938 void cpu_state_reset(CPUMIPSState
*env
)
15940 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
15941 CPUState
*cs
= CPU(cpu
);
15943 /* Reset registers to their default values */
15944 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15945 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15946 #ifdef TARGET_WORDS_BIGENDIAN
15947 env
->CP0_Config0
|= (1 << CP0C0_BE
);
15949 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
15950 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
15951 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
15952 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
15953 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
15954 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
15955 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
15956 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
15957 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
15958 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
15959 << env
->cpu_model
->CP0_LLAddr_shift
;
15960 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
15961 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
15962 env
->CCRes
= env
->cpu_model
->CCRes
;
15963 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
15964 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
15965 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
15966 env
->current_tc
= 0;
15967 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
15968 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
15969 #if defined(TARGET_MIPS64)
15970 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
15971 env
->SEGMask
|= 3ULL << 62;
15974 env
->PABITS
= env
->cpu_model
->PABITS
;
15975 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
15976 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
15977 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
15978 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
15979 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
15980 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
15981 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
15982 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
15983 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
15984 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
15985 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
15986 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
15987 env
->insn_flags
= env
->cpu_model
->insn_flags
;
15989 #if defined(CONFIG_USER_ONLY)
15990 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
15991 # ifdef TARGET_MIPS64
15992 /* Enable 64-bit register mode. */
15993 env
->CP0_Status
|= (1 << CP0St_PX
);
15995 # ifdef TARGET_ABI_MIPSN64
15996 /* Enable 64-bit address mode. */
15997 env
->CP0_Status
|= (1 << CP0St_UX
);
15999 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16000 hardware registers. */
16001 env
->CP0_HWREna
|= 0x0000000F;
16002 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16003 env
->CP0_Status
|= (1 << CP0St_CU1
);
16005 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
16006 env
->CP0_Status
|= (1 << CP0St_MX
);
16008 # if defined(TARGET_MIPS64)
16009 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16010 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
16011 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
16012 env
->CP0_Status
|= (1 << CP0St_FR
);
16016 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
16017 /* If the exception was raised from a delay slot,
16018 come back to the jump. */
16019 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
16021 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
16023 env
->active_tc
.PC
= (int32_t)0xBFC00000;
16024 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
16025 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
16026 env
->CP0_Wired
= 0;
16027 env
->CP0_EBase
= 0x80000000 | (cs
->cpu_index
& 0x3FF);
16028 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
16029 /* vectored interrupts not implemented, timer on int 7,
16030 no performance counters. */
16031 env
->CP0_IntCtl
= 0xe0000000;
16035 for (i
= 0; i
< 7; i
++) {
16036 env
->CP0_WatchLo
[i
] = 0;
16037 env
->CP0_WatchHi
[i
] = 0x80000000;
16039 env
->CP0_WatchLo
[7] = 0;
16040 env
->CP0_WatchHi
[7] = 0;
16042 /* Count register increments in debug mode, EJTAG version 1 */
16043 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
16045 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
16048 /* Only TC0 on VPE 0 starts as active. */
16049 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
16050 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
16051 env
->tcs
[i
].CP0_TCHalt
= 1;
16053 env
->active_tc
.CP0_TCHalt
= 1;
16056 if (cs
->cpu_index
== 0) {
16057 /* VPE0 starts up enabled. */
16058 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
16059 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
16061 /* TC0 starts up unhalted. */
16063 env
->active_tc
.CP0_TCHalt
= 0;
16064 env
->tcs
[0].CP0_TCHalt
= 0;
16065 /* With thread 0 active. */
16066 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
16067 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16071 compute_hflags(env
);
16072 cs
->exception_index
= EXCP_NONE
;
16075 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16077 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16078 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16079 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16080 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16081 case MIPS_HFLAG_BR
:
16083 case MIPS_HFLAG_BC
:
16084 case MIPS_HFLAG_BL
:
16086 env
->btarget
= gen_opc_btarget
[pc_pos
];