2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "disas/disas.h"
32 #define MIPS_DEBUG_DISAS 0
33 //#define MIPS_DEBUG_SIGN_EXTENSIONS
35 /* MIPS major opcodes */
36 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
39 /* indirect opcode tables */
40 OPC_SPECIAL
= (0x00 << 26),
41 OPC_REGIMM
= (0x01 << 26),
42 OPC_CP0
= (0x10 << 26),
43 OPC_CP1
= (0x11 << 26),
44 OPC_CP2
= (0x12 << 26),
45 OPC_CP3
= (0x13 << 26),
46 OPC_SPECIAL2
= (0x1C << 26),
47 OPC_SPECIAL3
= (0x1F << 26),
48 /* arithmetic with immediate */
49 OPC_ADDI
= (0x08 << 26),
50 OPC_ADDIU
= (0x09 << 26),
51 OPC_SLTI
= (0x0A << 26),
52 OPC_SLTIU
= (0x0B << 26),
53 /* logic with immediate */
54 OPC_ANDI
= (0x0C << 26),
55 OPC_ORI
= (0x0D << 26),
56 OPC_XORI
= (0x0E << 26),
57 OPC_LUI
= (0x0F << 26),
58 /* arithmetic with immediate */
59 OPC_DADDI
= (0x18 << 26),
60 OPC_DADDIU
= (0x19 << 26),
61 /* Jump and branches */
63 OPC_JAL
= (0x03 << 26),
64 OPC_JALS
= OPC_JAL
| 0x5,
65 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
66 OPC_BEQL
= (0x14 << 26),
67 OPC_BNE
= (0x05 << 26),
68 OPC_BNEL
= (0x15 << 26),
69 OPC_BLEZ
= (0x06 << 26),
70 OPC_BLEZL
= (0x16 << 26),
71 OPC_BGTZ
= (0x07 << 26),
72 OPC_BGTZL
= (0x17 << 26),
73 OPC_JALX
= (0x1D << 26), /* MIPS 16 only */
74 OPC_JALXS
= OPC_JALX
| 0x5,
76 OPC_LDL
= (0x1A << 26),
77 OPC_LDR
= (0x1B << 26),
78 OPC_LB
= (0x20 << 26),
79 OPC_LH
= (0x21 << 26),
80 OPC_LWL
= (0x22 << 26),
81 OPC_LW
= (0x23 << 26),
82 OPC_LWPC
= OPC_LW
| 0x5,
83 OPC_LBU
= (0x24 << 26),
84 OPC_LHU
= (0x25 << 26),
85 OPC_LWR
= (0x26 << 26),
86 OPC_LWU
= (0x27 << 26),
87 OPC_SB
= (0x28 << 26),
88 OPC_SH
= (0x29 << 26),
89 OPC_SWL
= (0x2A << 26),
90 OPC_SW
= (0x2B << 26),
91 OPC_SDL
= (0x2C << 26),
92 OPC_SDR
= (0x2D << 26),
93 OPC_SWR
= (0x2E << 26),
94 OPC_LL
= (0x30 << 26),
95 OPC_LLD
= (0x34 << 26),
96 OPC_LD
= (0x37 << 26),
97 OPC_LDPC
= OPC_LD
| 0x5,
98 OPC_SC
= (0x38 << 26),
99 OPC_SCD
= (0x3C << 26),
100 OPC_SD
= (0x3F << 26),
101 /* Floating point load/store */
102 OPC_LWC1
= (0x31 << 26),
103 OPC_LWC2
= (0x32 << 26),
104 OPC_LDC1
= (0x35 << 26),
105 OPC_LDC2
= (0x36 << 26),
106 OPC_SWC1
= (0x39 << 26),
107 OPC_SWC2
= (0x3A << 26),
108 OPC_SDC1
= (0x3D << 26),
109 OPC_SDC2
= (0x3E << 26),
110 /* MDMX ASE specific */
111 OPC_MDMX
= (0x1E << 26),
112 /* Cache and prefetch */
113 OPC_CACHE
= (0x2F << 26),
114 OPC_PREF
= (0x33 << 26),
115 /* Reserved major opcode */
116 OPC_MAJOR3B_RESERVED
= (0x3B << 26),
119 /* MIPS special opcodes */
120 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
124 OPC_SLL
= 0x00 | OPC_SPECIAL
,
125 /* NOP is SLL r0, r0, 0 */
126 /* SSNOP is SLL r0, r0, 1 */
127 /* EHB is SLL r0, r0, 3 */
128 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
129 OPC_ROTR
= OPC_SRL
| (1 << 21),
130 OPC_SRA
= 0x03 | OPC_SPECIAL
,
131 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
132 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
133 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
134 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
135 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
136 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
137 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
138 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
139 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
140 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
141 OPC_DROTR
= OPC_DSRL
| (1 << 21),
142 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
143 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
144 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
145 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
146 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
147 /* Multiplication / division */
148 OPC_MULT
= 0x18 | OPC_SPECIAL
,
149 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
150 OPC_DIV
= 0x1A | OPC_SPECIAL
,
151 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
152 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
153 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
154 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
155 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
156 /* 2 registers arithmetic / logic */
157 OPC_ADD
= 0x20 | OPC_SPECIAL
,
158 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
159 OPC_SUB
= 0x22 | OPC_SPECIAL
,
160 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
161 OPC_AND
= 0x24 | OPC_SPECIAL
,
162 OPC_OR
= 0x25 | OPC_SPECIAL
,
163 OPC_XOR
= 0x26 | OPC_SPECIAL
,
164 OPC_NOR
= 0x27 | OPC_SPECIAL
,
165 OPC_SLT
= 0x2A | OPC_SPECIAL
,
166 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
167 OPC_DADD
= 0x2C | OPC_SPECIAL
,
168 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
169 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
170 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
172 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
173 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
174 OPC_JALRC
= OPC_JALR
| (0x5 << 6),
175 OPC_JALRS
= 0x10 | OPC_SPECIAL
| (0x5 << 6),
177 OPC_TGE
= 0x30 | OPC_SPECIAL
,
178 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
179 OPC_TLT
= 0x32 | OPC_SPECIAL
,
180 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
181 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
182 OPC_TNE
= 0x36 | OPC_SPECIAL
,
183 /* HI / LO registers load & stores */
184 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
185 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
186 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
187 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
188 /* Conditional moves */
189 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
190 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
192 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
195 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
196 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
197 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
198 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
199 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
201 OPC_SPECIAL15_RESERVED
= 0x15 | OPC_SPECIAL
,
202 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
203 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
204 OPC_SPECIAL35_RESERVED
= 0x35 | OPC_SPECIAL
,
205 OPC_SPECIAL37_RESERVED
= 0x37 | OPC_SPECIAL
,
206 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
207 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
210 /* Multiplication variants of the vr54xx. */
211 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
214 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
215 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
216 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
217 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
218 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
219 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
220 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
221 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
222 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
223 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
224 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
225 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
226 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
227 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
230 /* REGIMM (rt field) opcodes */
231 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
234 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
235 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
236 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
237 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
238 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
239 OPC_BLTZALS
= OPC_BLTZAL
| 0x5, /* microMIPS */
240 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
241 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
242 OPC_BGEZALS
= OPC_BGEZAL
| 0x5, /* microMIPS */
243 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
244 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
245 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
246 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
247 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
248 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
249 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
250 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
253 /* Special2 opcodes */
254 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
257 /* Multiply & xxx operations */
258 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
259 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
260 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
261 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
262 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
264 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
265 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
266 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
267 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
268 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
269 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
270 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
271 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
272 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
273 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
274 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
275 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
277 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
278 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
279 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
280 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
282 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
285 /* Special3 opcodes */
286 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
289 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
290 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
291 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
292 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
293 OPC_INS
= 0x04 | OPC_SPECIAL3
,
294 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
295 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
296 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
297 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
298 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
299 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
300 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
301 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
304 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
305 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
306 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
307 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
308 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
309 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
310 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
311 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
312 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
313 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
314 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
315 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
318 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
319 /* MIPS DSP Arithmetic */
320 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
321 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
322 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
323 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
324 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
325 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
326 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
327 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
328 /* MIPS DSP GPR-Based Shift Sub-class */
329 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
330 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
331 /* MIPS DSP Multiply Sub-class insns */
332 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
333 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
334 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
335 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
336 /* DSP Bit/Manipulation Sub-class */
337 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
338 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
339 /* MIPS DSP Append Sub-class */
340 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
341 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
342 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
343 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
344 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
348 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
351 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
352 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
353 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
357 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
360 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
361 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
364 /* MIPS DSP REGIMM opcodes */
366 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
367 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
370 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
373 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
374 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
375 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
376 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
379 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
381 /* MIPS DSP Arithmetic Sub-class */
382 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
383 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
384 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
385 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
386 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
387 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
388 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
389 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
390 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
391 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
392 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
393 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
394 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
395 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
396 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
397 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
398 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
399 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
400 /* MIPS DSP Multiply Sub-class insns */
401 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
402 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
403 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
404 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
405 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
406 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
409 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
410 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
412 /* MIPS DSP Arithmetic Sub-class */
413 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
414 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
415 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
416 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
417 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
418 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
419 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
420 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
421 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
422 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
423 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
424 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
425 /* MIPS DSP Multiply Sub-class insns */
426 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
427 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
428 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
429 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
432 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
434 /* MIPS DSP Arithmetic Sub-class */
435 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
436 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
437 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
438 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
439 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
440 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
441 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
442 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
443 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
444 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
445 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
446 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
447 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
448 /* DSP Bit/Manipulation Sub-class */
449 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
450 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
451 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
452 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
453 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
456 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
458 /* MIPS DSP Arithmetic Sub-class */
459 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
460 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
461 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
462 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
463 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
464 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
465 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
466 /* DSP Compare-Pick Sub-class */
467 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
468 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
469 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
470 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
471 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
472 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
473 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
474 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
475 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
476 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
477 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
478 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
479 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
480 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
481 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
484 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
486 /* MIPS DSP GPR-Based Shift Sub-class */
487 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
488 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
489 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
490 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
491 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
492 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
493 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
494 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
495 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
496 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
497 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
498 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
499 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
500 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
501 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
502 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
503 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
504 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
505 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
506 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
507 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
508 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
511 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
513 /* MIPS DSP Multiply Sub-class insns */
514 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
515 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
516 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
517 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
518 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
519 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
520 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
521 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
522 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
523 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
524 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
525 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
526 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
527 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
528 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
529 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
530 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
531 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
532 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
533 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
534 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
535 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
538 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
540 /* DSP Bit/Manipulation Sub-class */
541 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
544 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
546 /* MIPS DSP Append Sub-class */
547 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
548 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
549 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
552 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
554 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
555 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
556 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
557 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
558 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
559 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
560 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
561 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
562 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
563 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
564 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
565 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
566 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
567 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
568 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
569 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
570 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
571 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
574 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
576 /* MIPS DSP Arithmetic Sub-class */
577 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
578 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
579 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
580 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
581 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
582 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
583 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
584 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
585 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
586 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
587 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
588 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
589 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
590 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
591 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
592 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
593 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
594 /* DSP Bit/Manipulation Sub-class */
595 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
596 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
597 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
598 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
599 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
600 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
603 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
605 /* MIPS DSP Multiply Sub-class insns */
606 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
607 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
608 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
609 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
610 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
611 /* MIPS DSP Arithmetic Sub-class */
612 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
613 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
614 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
615 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
616 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
617 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
618 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
619 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
620 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
621 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
622 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
623 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
624 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
625 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
626 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
627 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
628 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
629 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
630 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
631 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
632 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
635 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
637 /* DSP Compare-Pick Sub-class */
638 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
639 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
640 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
641 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
642 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
643 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
644 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
645 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
646 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
647 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
648 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
649 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
650 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
651 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
652 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
653 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
654 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
655 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
656 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
657 /* MIPS DSP Arithmetic Sub-class */
658 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
659 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
660 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
661 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
662 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
663 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
664 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
665 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
668 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
670 /* DSP Append Sub-class */
671 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
672 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
673 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
674 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
677 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
680 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
681 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
682 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
683 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
684 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
685 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
686 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
687 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
688 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
689 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
690 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
691 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
692 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
693 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
694 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
695 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
696 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
697 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
698 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
699 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
700 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
703 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
705 /* DSP Bit/Manipulation Sub-class */
706 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
709 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
711 /* MIPS DSP Multiply Sub-class insns */
712 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
713 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
714 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
715 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
716 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
717 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
718 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
719 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
720 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
721 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
722 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
723 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
724 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
725 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
726 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
727 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
728 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
729 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
730 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
731 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
732 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
733 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
734 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
735 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
736 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
737 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
740 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
742 /* MIPS DSP GPR-Based Shift Sub-class */
743 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
744 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
745 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
746 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
747 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
748 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
749 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
750 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
751 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
752 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
753 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
754 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
755 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
756 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
757 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
758 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
759 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
760 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
761 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
762 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
763 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
764 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
765 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
766 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
767 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
768 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
771 /* Coprocessor 0 (rs field) */
772 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
775 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
776 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
777 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
778 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
779 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
780 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
781 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
782 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
783 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
784 OPC_C0
= (0x10 << 21) | OPC_CP0
,
785 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
786 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
790 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
793 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
794 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
795 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
796 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
797 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
798 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
801 /* Coprocessor 0 (with rs == C0) */
802 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
805 OPC_TLBR
= 0x01 | OPC_C0
,
806 OPC_TLBWI
= 0x02 | OPC_C0
,
807 OPC_TLBWR
= 0x06 | OPC_C0
,
808 OPC_TLBP
= 0x08 | OPC_C0
,
809 OPC_RFE
= 0x10 | OPC_C0
,
810 OPC_ERET
= 0x18 | OPC_C0
,
811 OPC_DERET
= 0x1F | OPC_C0
,
812 OPC_WAIT
= 0x20 | OPC_C0
,
815 /* Coprocessor 1 (rs field) */
816 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
818 /* Values for the fmt field in FP instructions */
820 /* 0 - 15 are reserved */
821 FMT_S
= 16, /* single fp */
822 FMT_D
= 17, /* double fp */
823 FMT_E
= 18, /* extended fp */
824 FMT_Q
= 19, /* quad fp */
825 FMT_W
= 20, /* 32-bit fixed */
826 FMT_L
= 21, /* 64-bit fixed */
827 FMT_PS
= 22, /* paired single fp */
828 /* 23 - 31 are reserved */
832 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
833 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
834 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
835 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
836 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
837 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
838 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
839 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
840 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
841 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
842 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
843 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
844 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
845 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
846 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
847 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
848 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
849 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
852 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
853 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
856 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
857 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
858 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
859 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
863 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
864 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
868 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
869 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
872 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
875 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
876 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
877 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
878 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
879 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
880 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
881 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
882 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
883 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
886 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
889 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
890 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
891 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
892 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
893 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
894 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
895 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
896 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
898 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
899 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
900 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
901 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
902 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
903 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
904 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
905 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
907 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
908 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
909 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
910 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
911 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
912 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
913 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
914 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
916 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
917 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
918 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
919 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
920 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
921 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
922 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
923 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
925 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
926 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
927 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
928 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
929 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
930 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
932 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
933 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
934 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
935 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
936 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
937 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
939 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
940 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
941 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
942 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
943 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
944 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
946 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
947 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
948 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
949 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
950 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
951 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
953 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
954 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
955 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
956 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
957 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
958 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
960 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
961 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
962 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
963 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
964 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
965 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
967 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
968 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
969 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
970 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
971 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
972 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
974 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
975 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
976 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
977 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
978 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
979 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
983 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
986 OPC_LWXC1
= 0x00 | OPC_CP3
,
987 OPC_LDXC1
= 0x01 | OPC_CP3
,
988 OPC_LUXC1
= 0x05 | OPC_CP3
,
989 OPC_SWXC1
= 0x08 | OPC_CP3
,
990 OPC_SDXC1
= 0x09 | OPC_CP3
,
991 OPC_SUXC1
= 0x0D | OPC_CP3
,
992 OPC_PREFX
= 0x0F | OPC_CP3
,
993 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
994 OPC_MADD_S
= 0x20 | OPC_CP3
,
995 OPC_MADD_D
= 0x21 | OPC_CP3
,
996 OPC_MADD_PS
= 0x26 | OPC_CP3
,
997 OPC_MSUB_S
= 0x28 | OPC_CP3
,
998 OPC_MSUB_D
= 0x29 | OPC_CP3
,
999 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1000 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1001 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1002 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1003 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1004 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1005 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1008 /* global register indices */
1009 static TCGv_ptr cpu_env
;
1010 static TCGv cpu_gpr
[32], cpu_PC
;
1011 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
], cpu_ACX
[MIPS_DSP_ACC
];
1012 static TCGv cpu_dspctrl
, btarget
, bcond
;
1013 static TCGv_i32 hflags
;
1014 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1015 static TCGv_i64 fpu_f64
[32];
1017 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1018 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1020 #include "exec/gen-icount.h"
1022 #define gen_helper_0e0i(name, arg) do { \
1023 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1024 gen_helper_##name(cpu_env, helper_tmp); \
1025 tcg_temp_free_i32(helper_tmp); \
1028 #define gen_helper_0e1i(name, arg1, arg2) do { \
1029 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1030 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1031 tcg_temp_free_i32(helper_tmp); \
1034 #define gen_helper_1e0i(name, ret, arg1) do { \
1035 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1036 gen_helper_##name(ret, cpu_env, helper_tmp); \
1037 tcg_temp_free_i32(helper_tmp); \
1040 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1041 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1042 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1043 tcg_temp_free_i32(helper_tmp); \
1046 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1047 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1048 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1049 tcg_temp_free_i32(helper_tmp); \
1052 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1053 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1054 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1055 tcg_temp_free_i32(helper_tmp); \
1058 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1059 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1060 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1061 tcg_temp_free_i32(helper_tmp); \
1064 typedef struct DisasContext
{
1065 struct TranslationBlock
*tb
;
1066 target_ulong pc
, saved_pc
;
1068 int singlestep_enabled
;
1070 /* Routine used to access memory */
1072 uint32_t hflags
, saved_hflags
;
1074 target_ulong btarget
;
1078 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1079 * exception condition */
1080 BS_STOP
= 1, /* We want to stop translation for any reason */
1081 BS_BRANCH
= 2, /* We reached a branch condition */
1082 BS_EXCP
= 3, /* We reached an exception condition */
1085 static const char * const regnames
[] = {
1086 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1092 static const char * const regnames_HI
[] = {
1093 "HI0", "HI1", "HI2", "HI3",
1096 static const char * const regnames_LO
[] = {
1097 "LO0", "LO1", "LO2", "LO3",
1100 static const char * const regnames_ACX
[] = {
1101 "ACX0", "ACX1", "ACX2", "ACX3",
1104 static const char * const fregnames
[] = {
1105 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1106 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1107 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1111 #define MIPS_DEBUG(fmt, ...) \
1113 if (MIPS_DEBUG_DISAS) { \
1114 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1115 TARGET_FMT_lx ": %08x " fmt "\n", \
1116 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1120 #define LOG_DISAS(...) \
1122 if (MIPS_DEBUG_DISAS) { \
1123 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1127 #define MIPS_INVAL(op) \
1128 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1129 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1131 /* General purpose registers moves. */
1132 static inline void gen_load_gpr (TCGv t
, int reg
)
1135 tcg_gen_movi_tl(t
, 0);
1137 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1140 static inline void gen_store_gpr (TCGv t
, int reg
)
1143 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1146 /* Moves to/from ACX register. */
1147 static inline void gen_load_ACX (TCGv t
, int reg
)
1149 tcg_gen_mov_tl(t
, cpu_ACX
[reg
]);
1152 static inline void gen_store_ACX (TCGv t
, int reg
)
1154 tcg_gen_mov_tl(cpu_ACX
[reg
], t
);
1157 /* Moves to/from shadow registers. */
1158 static inline void gen_load_srsgpr (int from
, int to
)
1160 TCGv t0
= tcg_temp_new();
1163 tcg_gen_movi_tl(t0
, 0);
1165 TCGv_i32 t2
= tcg_temp_new_i32();
1166 TCGv_ptr addr
= tcg_temp_new_ptr();
1168 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1169 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1170 tcg_gen_andi_i32(t2
, t2
, 0xf);
1171 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1172 tcg_gen_ext_i32_ptr(addr
, t2
);
1173 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1175 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1176 tcg_temp_free_ptr(addr
);
1177 tcg_temp_free_i32(t2
);
1179 gen_store_gpr(t0
, to
);
1183 static inline void gen_store_srsgpr (int from
, int to
)
1186 TCGv t0
= tcg_temp_new();
1187 TCGv_i32 t2
= tcg_temp_new_i32();
1188 TCGv_ptr addr
= tcg_temp_new_ptr();
1190 gen_load_gpr(t0
, from
);
1191 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1192 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1193 tcg_gen_andi_i32(t2
, t2
, 0xf);
1194 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1195 tcg_gen_ext_i32_ptr(addr
, t2
);
1196 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1198 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1199 tcg_temp_free_ptr(addr
);
1200 tcg_temp_free_i32(t2
);
1205 /* Floating point register moves. */
1206 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1208 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1211 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1213 TCGv_i64 t64
= tcg_temp_new_i64();
1214 tcg_gen_extu_i32_i64(t64
, t
);
1215 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1216 tcg_temp_free_i64(t64
);
1219 static void gen_load_fpr32h(TCGv_i32 t
, int reg
)
1221 TCGv_i64 t64
= tcg_temp_new_i64();
1222 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1223 tcg_gen_trunc_i64_i32(t
, t64
);
1224 tcg_temp_free_i64(t64
);
1227 static void gen_store_fpr32h(TCGv_i32 t
, int reg
)
1229 TCGv_i64 t64
= tcg_temp_new_i64();
1230 tcg_gen_extu_i32_i64(t64
, t
);
1231 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1232 tcg_temp_free_i64(t64
);
1235 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1237 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1238 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1240 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1244 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1246 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1247 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1250 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1251 t0
= tcg_temp_new_i64();
1252 tcg_gen_shri_i64(t0
, t
, 32);
1253 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1254 tcg_temp_free_i64(t0
);
1258 static inline int get_fp_bit (int cc
)
1267 static inline void gen_save_pc(target_ulong pc
)
1269 tcg_gen_movi_tl(cpu_PC
, pc
);
1272 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1274 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1275 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1276 gen_save_pc(ctx
->pc
);
1277 ctx
->saved_pc
= ctx
->pc
;
1279 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1280 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1281 ctx
->saved_hflags
= ctx
->hflags
;
1282 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1288 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1294 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1296 ctx
->saved_hflags
= ctx
->hflags
;
1297 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1303 ctx
->btarget
= env
->btarget
;
1309 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1311 TCGv_i32 texcp
= tcg_const_i32(excp
);
1312 TCGv_i32 terr
= tcg_const_i32(err
);
1313 save_cpu_state(ctx
, 1);
1314 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1315 tcg_temp_free_i32(terr
);
1316 tcg_temp_free_i32(texcp
);
1320 generate_exception (DisasContext
*ctx
, int excp
)
1322 save_cpu_state(ctx
, 1);
1323 gen_helper_0e0i(raise_exception
, excp
);
1326 /* Addresses computation */
1327 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1329 tcg_gen_add_tl(ret
, arg0
, arg1
);
1331 #if defined(TARGET_MIPS64)
1332 /* For compatibility with 32-bit code, data reference in user mode
1333 with Status_UX = 0 should be casted to 32-bit and sign extended.
1334 See the MIPS64 PRA manual, section 4.10. */
1335 if (((ctx
->hflags
& MIPS_HFLAG_KSU
) == MIPS_HFLAG_UM
) &&
1336 !(ctx
->hflags
& MIPS_HFLAG_UX
)) {
1337 tcg_gen_ext32s_i64(ret
, ret
);
1342 static inline void check_cp0_enabled(DisasContext
*ctx
)
1344 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1345 generate_exception_err(ctx
, EXCP_CpU
, 0);
1348 static inline void check_cp1_enabled(DisasContext
*ctx
)
1350 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1351 generate_exception_err(ctx
, EXCP_CpU
, 1);
1354 /* Verify that the processor is running with COP1X instructions enabled.
1355 This is associated with the nabla symbol in the MIPS32 and MIPS64
1358 static inline void check_cop1x(DisasContext
*ctx
)
1360 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1361 generate_exception(ctx
, EXCP_RI
);
1364 /* Verify that the processor is running with 64-bit floating-point
1365 operations enabled. */
1367 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1369 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1370 generate_exception(ctx
, EXCP_RI
);
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1384 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1386 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1387 generate_exception(ctx
, EXCP_RI
);
1390 /* Verify that the processor is running with DSP instructions enabled.
1391 This is enabled by CP0 Status register MX(24) bit.
1394 static inline void check_dsp(DisasContext
*ctx
)
1396 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1397 if (ctx
->insn_flags
& ASE_DSP
) {
1398 generate_exception(ctx
, EXCP_DSPDIS
);
1400 generate_exception(ctx
, EXCP_RI
);
1405 static inline void check_dspr2(DisasContext
*ctx
)
1407 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1408 if (ctx
->insn_flags
& ASE_DSP
) {
1409 generate_exception(ctx
, EXCP_DSPDIS
);
1411 generate_exception(ctx
, EXCP_RI
);
1416 /* This code generates a "reserved instruction" exception if the
1417 CPU does not support the instruction set corresponding to flags. */
1418 static inline void check_insn(DisasContext
*ctx
, int flags
)
1420 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1421 generate_exception(ctx
, EXCP_RI
);
1425 /* This code generates a "reserved instruction" exception if 64-bit
1426 instructions are not enabled. */
1427 static inline void check_mips_64(DisasContext
*ctx
)
1429 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1430 generate_exception(ctx
, EXCP_RI
);
1433 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1434 calling interface for 32 and 64-bit FPRs. No sense in changing
1435 all callers for gen_load_fpr32 when we need the CTX parameter for
1437 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1440 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1441 int ft, int fs, int cc) \
1443 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1444 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1447 check_cp1_64bitmode(ctx); \
1453 check_cp1_registers(ctx, fs | ft); \
1461 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1462 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1464 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1465 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1466 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1467 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1468 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1469 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1470 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1471 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1472 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1473 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1475 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1476 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1477 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1478 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1479 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1482 tcg_temp_free_i##bits (fp0); \
1483 tcg_temp_free_i##bits (fp1); \
1486 FOP_CONDS(, 0, d
, FMT_D
, 64)
1487 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1488 FOP_CONDS(, 0, s
, FMT_S
, 32)
1489 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1490 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1491 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1493 #undef gen_ldcmp_fpr32
1494 #undef gen_ldcmp_fpr64
1496 /* load/store instructions. */
1497 #ifdef CONFIG_USER_ONLY
1498 #define OP_LD_ATOMIC(insn,fname) \
1499 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1501 TCGv t0 = tcg_temp_new(); \
1502 tcg_gen_mov_tl(t0, arg1); \
1503 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1504 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1505 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1506 tcg_temp_free(t0); \
1509 #define OP_LD_ATOMIC(insn,fname) \
1510 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1512 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1515 OP_LD_ATOMIC(ll
,ld32s
);
1516 #if defined(TARGET_MIPS64)
1517 OP_LD_ATOMIC(lld
,ld64
);
1521 #ifdef CONFIG_USER_ONLY
1522 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1523 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1525 TCGv t0 = tcg_temp_new(); \
1526 int l1 = gen_new_label(); \
1527 int l2 = gen_new_label(); \
1529 tcg_gen_andi_tl(t0, arg2, almask); \
1530 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1531 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1532 generate_exception(ctx, EXCP_AdES); \
1533 gen_set_label(l1); \
1534 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1535 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1536 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1537 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1538 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1539 gen_helper_0e0i(raise_exception, EXCP_SC); \
1540 gen_set_label(l2); \
1541 tcg_gen_movi_tl(t0, 0); \
1542 gen_store_gpr(t0, rt); \
1543 tcg_temp_free(t0); \
1546 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1547 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1549 TCGv t0 = tcg_temp_new(); \
1550 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1551 gen_store_gpr(t0, rt); \
1552 tcg_temp_free(t0); \
1555 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1556 #if defined(TARGET_MIPS64)
1557 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1561 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1562 int base
, int16_t offset
)
1565 tcg_gen_movi_tl(addr
, offset
);
1566 } else if (offset
== 0) {
1567 gen_load_gpr(addr
, base
);
1569 tcg_gen_movi_tl(addr
, offset
);
1570 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1574 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1576 target_ulong pc
= ctx
->pc
;
1578 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1579 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1584 pc
&= ~(target_ulong
)3;
1589 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1590 int rt
, int base
, int16_t offset
)
1592 const char *opn
= "ld";
1595 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1596 /* Loongson CPU uses a load to zero register for prefetch.
1597 We emulate it as a NOP. On other CPU we must perform the
1598 actual memory access. */
1603 t0
= tcg_temp_new();
1604 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1607 #if defined(TARGET_MIPS64)
1609 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1610 gen_store_gpr(t0
, rt
);
1614 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1615 gen_store_gpr(t0
, rt
);
1619 save_cpu_state(ctx
, 1);
1620 op_ld_lld(t0
, t0
, ctx
);
1621 gen_store_gpr(t0
, rt
);
1625 t1
= tcg_temp_new();
1626 tcg_gen_andi_tl(t1
, t0
, 7);
1627 #ifndef TARGET_WORDS_BIGENDIAN
1628 tcg_gen_xori_tl(t1
, t1
, 7);
1630 tcg_gen_shli_tl(t1
, t1
, 3);
1631 tcg_gen_andi_tl(t0
, t0
, ~7);
1632 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1633 tcg_gen_shl_tl(t0
, t0
, t1
);
1634 tcg_gen_xori_tl(t1
, t1
, 63);
1635 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1636 tcg_gen_shr_tl(t2
, t2
, t1
);
1637 gen_load_gpr(t1
, rt
);
1638 tcg_gen_and_tl(t1
, t1
, t2
);
1640 tcg_gen_or_tl(t0
, t0
, t1
);
1642 gen_store_gpr(t0
, rt
);
1646 t1
= tcg_temp_new();
1647 tcg_gen_andi_tl(t1
, t0
, 7);
1648 #ifdef TARGET_WORDS_BIGENDIAN
1649 tcg_gen_xori_tl(t1
, t1
, 7);
1651 tcg_gen_shli_tl(t1
, t1
, 3);
1652 tcg_gen_andi_tl(t0
, t0
, ~7);
1653 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1654 tcg_gen_shr_tl(t0
, t0
, t1
);
1655 tcg_gen_xori_tl(t1
, t1
, 63);
1656 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1657 tcg_gen_shl_tl(t2
, t2
, t1
);
1658 gen_load_gpr(t1
, rt
);
1659 tcg_gen_and_tl(t1
, t1
, t2
);
1661 tcg_gen_or_tl(t0
, t0
, t1
);
1663 gen_store_gpr(t0
, rt
);
1667 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1668 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1670 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1671 gen_store_gpr(t0
, rt
);
1676 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1677 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1679 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1680 gen_store_gpr(t0
, rt
);
1684 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1685 gen_store_gpr(t0
, rt
);
1689 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
1690 gen_store_gpr(t0
, rt
);
1694 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
1695 gen_store_gpr(t0
, rt
);
1699 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
1700 gen_store_gpr(t0
, rt
);
1704 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
1705 gen_store_gpr(t0
, rt
);
1709 t1
= tcg_temp_new();
1710 tcg_gen_andi_tl(t1
, t0
, 3);
1711 #ifndef TARGET_WORDS_BIGENDIAN
1712 tcg_gen_xori_tl(t1
, t1
, 3);
1714 tcg_gen_shli_tl(t1
, t1
, 3);
1715 tcg_gen_andi_tl(t0
, t0
, ~3);
1716 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1717 tcg_gen_shl_tl(t0
, t0
, t1
);
1718 tcg_gen_xori_tl(t1
, t1
, 31);
1719 t2
= tcg_const_tl(0x7fffffffull
);
1720 tcg_gen_shr_tl(t2
, t2
, t1
);
1721 gen_load_gpr(t1
, rt
);
1722 tcg_gen_and_tl(t1
, t1
, t2
);
1724 tcg_gen_or_tl(t0
, t0
, t1
);
1726 tcg_gen_ext32s_tl(t0
, t0
);
1727 gen_store_gpr(t0
, rt
);
1731 t1
= tcg_temp_new();
1732 tcg_gen_andi_tl(t1
, t0
, 3);
1733 #ifdef TARGET_WORDS_BIGENDIAN
1734 tcg_gen_xori_tl(t1
, t1
, 3);
1736 tcg_gen_shli_tl(t1
, t1
, 3);
1737 tcg_gen_andi_tl(t0
, t0
, ~3);
1738 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1739 tcg_gen_shr_tl(t0
, t0
, t1
);
1740 tcg_gen_xori_tl(t1
, t1
, 31);
1741 t2
= tcg_const_tl(0xfffffffeull
);
1742 tcg_gen_shl_tl(t2
, t2
, t1
);
1743 gen_load_gpr(t1
, rt
);
1744 tcg_gen_and_tl(t1
, t1
, t2
);
1746 tcg_gen_or_tl(t0
, t0
, t1
);
1748 tcg_gen_ext32s_tl(t0
, t0
);
1749 gen_store_gpr(t0
, rt
);
1753 save_cpu_state(ctx
, 1);
1754 op_ld_ll(t0
, t0
, ctx
);
1755 gen_store_gpr(t0
, rt
);
1759 (void)opn
; /* avoid a compiler warning */
1760 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1765 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1766 int base
, int16_t offset
)
1768 const char *opn
= "st";
1769 TCGv t0
= tcg_temp_new();
1770 TCGv t1
= tcg_temp_new();
1772 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1773 gen_load_gpr(t1
, rt
);
1775 #if defined(TARGET_MIPS64)
1777 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
1781 save_cpu_state(ctx
, 1);
1782 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1786 save_cpu_state(ctx
, 1);
1787 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
1792 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
1796 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
1800 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
1804 save_cpu_state(ctx
, 1);
1805 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
1809 save_cpu_state(ctx
, 1);
1810 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
1814 (void)opn
; /* avoid a compiler warning */
1815 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1821 /* Store conditional */
1822 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
1823 int base
, int16_t offset
)
1825 const char *opn
= "st_cond";
1828 #ifdef CONFIG_USER_ONLY
1829 t0
= tcg_temp_local_new();
1830 t1
= tcg_temp_local_new();
1832 t0
= tcg_temp_new();
1833 t1
= tcg_temp_new();
1835 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1836 gen_load_gpr(t1
, rt
);
1838 #if defined(TARGET_MIPS64)
1840 save_cpu_state(ctx
, 1);
1841 op_st_scd(t1
, t0
, rt
, ctx
);
1846 save_cpu_state(ctx
, 1);
1847 op_st_sc(t1
, t0
, rt
, ctx
);
1851 (void)opn
; /* avoid a compiler warning */
1852 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1857 /* Load and store */
1858 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
1859 int base
, int16_t offset
)
1861 const char *opn
= "flt_ldst";
1862 TCGv t0
= tcg_temp_new();
1864 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1865 /* Don't do NOP if destination is zero: we must perform the actual
1870 TCGv_i32 fp0
= tcg_temp_new_i32();
1871 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
1872 gen_store_fpr32(fp0
, ft
);
1873 tcg_temp_free_i32(fp0
);
1879 TCGv_i32 fp0
= tcg_temp_new_i32();
1880 gen_load_fpr32(fp0
, ft
);
1881 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1882 tcg_temp_free_i32(fp0
);
1888 TCGv_i64 fp0
= tcg_temp_new_i64();
1889 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1890 gen_store_fpr64(ctx
, fp0
, ft
);
1891 tcg_temp_free_i64(fp0
);
1897 TCGv_i64 fp0
= tcg_temp_new_i64();
1898 gen_load_fpr64(ctx
, fp0
, ft
);
1899 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1900 tcg_temp_free_i64(fp0
);
1906 generate_exception(ctx
, EXCP_RI
);
1909 (void)opn
; /* avoid a compiler warning */
1910 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
1915 static void gen_cop1_ldst(CPUMIPSState
*env
, DisasContext
*ctx
,
1916 uint32_t op
, int rt
, int rs
, int16_t imm
)
1918 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
1919 check_cp1_enabled(ctx
);
1920 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
1922 generate_exception_err(ctx
, EXCP_CpU
, 1);
1926 /* Arithmetic with immediate operand */
1927 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
1928 int rt
, int rs
, int16_t imm
)
1930 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
1931 const char *opn
= "imm arith";
1933 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
1934 /* If no destination, treat it as a NOP.
1935 For addi, we must generate the overflow exception when needed. */
1942 TCGv t0
= tcg_temp_local_new();
1943 TCGv t1
= tcg_temp_new();
1944 TCGv t2
= tcg_temp_new();
1945 int l1
= gen_new_label();
1947 gen_load_gpr(t1
, rs
);
1948 tcg_gen_addi_tl(t0
, t1
, uimm
);
1949 tcg_gen_ext32s_tl(t0
, t0
);
1951 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1952 tcg_gen_xori_tl(t2
, t0
, uimm
);
1953 tcg_gen_and_tl(t1
, t1
, t2
);
1955 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1957 /* operands of same sign, result different sign */
1958 generate_exception(ctx
, EXCP_OVERFLOW
);
1960 tcg_gen_ext32s_tl(t0
, t0
);
1961 gen_store_gpr(t0
, rt
);
1968 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1969 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
1971 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1975 #if defined(TARGET_MIPS64)
1978 TCGv t0
= tcg_temp_local_new();
1979 TCGv t1
= tcg_temp_new();
1980 TCGv t2
= tcg_temp_new();
1981 int l1
= gen_new_label();
1983 gen_load_gpr(t1
, rs
);
1984 tcg_gen_addi_tl(t0
, t1
, uimm
);
1986 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1987 tcg_gen_xori_tl(t2
, t0
, uimm
);
1988 tcg_gen_and_tl(t1
, t1
, t2
);
1990 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1992 /* operands of same sign, result different sign */
1993 generate_exception(ctx
, EXCP_OVERFLOW
);
1995 gen_store_gpr(t0
, rt
);
2002 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2004 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2010 (void)opn
; /* avoid a compiler warning */
2011 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2014 /* Logic with immediate operand */
2015 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2016 int rt
, int rs
, int16_t imm
)
2021 /* If no destination, treat it as a NOP. */
2025 uimm
= (uint16_t)imm
;
2028 if (likely(rs
!= 0))
2029 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2031 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2032 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2033 regnames
[rs
], uimm
);
2037 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2039 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2040 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2041 regnames
[rs
], uimm
);
2044 if (likely(rs
!= 0))
2045 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2047 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2048 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2049 regnames
[rs
], uimm
);
2052 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2053 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2057 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2062 /* Set on less than with immediate operand */
2063 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2064 int rt
, int rs
, int16_t imm
)
2066 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2067 const char *opn
= "imm arith";
2071 /* If no destination, treat it as a NOP. */
2075 t0
= tcg_temp_new();
2076 gen_load_gpr(t0
, rs
);
2079 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2083 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2087 (void)opn
; /* avoid a compiler warning */
2088 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2092 /* Shifts with immediate operand */
2093 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2094 int rt
, int rs
, int16_t imm
)
2096 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2097 const char *opn
= "imm shift";
2101 /* If no destination, treat it as a NOP. */
2106 t0
= tcg_temp_new();
2107 gen_load_gpr(t0
, rs
);
2110 tcg_gen_shli_tl(t0
, t0
, uimm
);
2111 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2115 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2120 tcg_gen_ext32u_tl(t0
, t0
);
2121 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2123 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2129 TCGv_i32 t1
= tcg_temp_new_i32();
2131 tcg_gen_trunc_tl_i32(t1
, t0
);
2132 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2133 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2134 tcg_temp_free_i32(t1
);
2136 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2140 #if defined(TARGET_MIPS64)
2142 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2146 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2150 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2155 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2157 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2162 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2166 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2170 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2174 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2179 (void)opn
; /* avoid a compiler warning */
2180 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2185 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2186 int rd
, int rs
, int rt
)
2188 const char *opn
= "arith";
2190 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2191 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2192 /* If no destination, treat it as a NOP.
2193 For add & sub, we must generate the overflow exception when needed. */
2201 TCGv t0
= tcg_temp_local_new();
2202 TCGv t1
= tcg_temp_new();
2203 TCGv t2
= tcg_temp_new();
2204 int l1
= gen_new_label();
2206 gen_load_gpr(t1
, rs
);
2207 gen_load_gpr(t2
, rt
);
2208 tcg_gen_add_tl(t0
, t1
, t2
);
2209 tcg_gen_ext32s_tl(t0
, t0
);
2210 tcg_gen_xor_tl(t1
, t1
, t2
);
2211 tcg_gen_xor_tl(t2
, t0
, t2
);
2212 tcg_gen_andc_tl(t1
, t2
, t1
);
2214 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2216 /* operands of same sign, result different sign */
2217 generate_exception(ctx
, EXCP_OVERFLOW
);
2219 gen_store_gpr(t0
, rd
);
2225 if (rs
!= 0 && rt
!= 0) {
2226 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2227 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2228 } else if (rs
== 0 && rt
!= 0) {
2229 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2230 } else if (rs
!= 0 && rt
== 0) {
2231 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2233 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2239 TCGv t0
= tcg_temp_local_new();
2240 TCGv t1
= tcg_temp_new();
2241 TCGv t2
= tcg_temp_new();
2242 int l1
= gen_new_label();
2244 gen_load_gpr(t1
, rs
);
2245 gen_load_gpr(t2
, rt
);
2246 tcg_gen_sub_tl(t0
, t1
, t2
);
2247 tcg_gen_ext32s_tl(t0
, t0
);
2248 tcg_gen_xor_tl(t2
, t1
, t2
);
2249 tcg_gen_xor_tl(t1
, t0
, t1
);
2250 tcg_gen_and_tl(t1
, t1
, t2
);
2252 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2254 /* operands of different sign, first operand and result different sign */
2255 generate_exception(ctx
, EXCP_OVERFLOW
);
2257 gen_store_gpr(t0
, rd
);
2263 if (rs
!= 0 && rt
!= 0) {
2264 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2265 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2266 } else if (rs
== 0 && rt
!= 0) {
2267 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2268 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2269 } else if (rs
!= 0 && rt
== 0) {
2270 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2272 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2276 #if defined(TARGET_MIPS64)
2279 TCGv t0
= tcg_temp_local_new();
2280 TCGv t1
= tcg_temp_new();
2281 TCGv t2
= tcg_temp_new();
2282 int l1
= gen_new_label();
2284 gen_load_gpr(t1
, rs
);
2285 gen_load_gpr(t2
, rt
);
2286 tcg_gen_add_tl(t0
, t1
, t2
);
2287 tcg_gen_xor_tl(t1
, t1
, t2
);
2288 tcg_gen_xor_tl(t2
, t0
, t2
);
2289 tcg_gen_andc_tl(t1
, t2
, t1
);
2291 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2293 /* operands of same sign, result different sign */
2294 generate_exception(ctx
, EXCP_OVERFLOW
);
2296 gen_store_gpr(t0
, rd
);
2302 if (rs
!= 0 && rt
!= 0) {
2303 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2304 } else if (rs
== 0 && rt
!= 0) {
2305 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2306 } else if (rs
!= 0 && rt
== 0) {
2307 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2309 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2315 TCGv t0
= tcg_temp_local_new();
2316 TCGv t1
= tcg_temp_new();
2317 TCGv t2
= tcg_temp_new();
2318 int l1
= gen_new_label();
2320 gen_load_gpr(t1
, rs
);
2321 gen_load_gpr(t2
, rt
);
2322 tcg_gen_sub_tl(t0
, t1
, t2
);
2323 tcg_gen_xor_tl(t2
, t1
, t2
);
2324 tcg_gen_xor_tl(t1
, t0
, t1
);
2325 tcg_gen_and_tl(t1
, t1
, t2
);
2327 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2329 /* operands of different sign, first operand and result different sign */
2330 generate_exception(ctx
, EXCP_OVERFLOW
);
2332 gen_store_gpr(t0
, rd
);
2338 if (rs
!= 0 && rt
!= 0) {
2339 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2340 } else if (rs
== 0 && rt
!= 0) {
2341 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2342 } else if (rs
!= 0 && rt
== 0) {
2343 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2345 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2351 if (likely(rs
!= 0 && rt
!= 0)) {
2352 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2353 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2355 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2360 (void)opn
; /* avoid a compiler warning */
2361 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2364 /* Conditional move */
2365 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2366 int rd
, int rs
, int rt
)
2368 const char *opn
= "cond move";
2372 /* If no destination, treat it as a NOP. */
2377 t0
= tcg_temp_new();
2378 gen_load_gpr(t0
, rt
);
2379 t1
= tcg_const_tl(0);
2380 t2
= tcg_temp_new();
2381 gen_load_gpr(t2
, rs
);
2384 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2388 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2396 (void)opn
; /* avoid a compiler warning */
2397 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2401 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2402 int rd
, int rs
, int rt
)
2404 const char *opn
= "logic";
2407 /* If no destination, treat it as a NOP. */
2414 if (likely(rs
!= 0 && rt
!= 0)) {
2415 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2417 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2422 if (rs
!= 0 && rt
!= 0) {
2423 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2424 } else if (rs
== 0 && rt
!= 0) {
2425 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2426 } else if (rs
!= 0 && rt
== 0) {
2427 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2429 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2434 if (likely(rs
!= 0 && rt
!= 0)) {
2435 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2436 } else if (rs
== 0 && rt
!= 0) {
2437 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2438 } else if (rs
!= 0 && rt
== 0) {
2439 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2441 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2446 if (likely(rs
!= 0 && rt
!= 0)) {
2447 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2448 } else if (rs
== 0 && rt
!= 0) {
2449 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2450 } else if (rs
!= 0 && rt
== 0) {
2451 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2453 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2458 (void)opn
; /* avoid a compiler warning */
2459 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2462 /* Set on lower than */
2463 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2464 int rd
, int rs
, int rt
)
2466 const char *opn
= "slt";
2470 /* If no destination, treat it as a NOP. */
2475 t0
= tcg_temp_new();
2476 t1
= tcg_temp_new();
2477 gen_load_gpr(t0
, rs
);
2478 gen_load_gpr(t1
, rt
);
2481 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2485 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2489 (void)opn
; /* avoid a compiler warning */
2490 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2496 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2497 int rd
, int rs
, int rt
)
2499 const char *opn
= "shifts";
2503 /* If no destination, treat it as a NOP.
2504 For add & sub, we must generate the overflow exception when needed. */
2509 t0
= tcg_temp_new();
2510 t1
= tcg_temp_new();
2511 gen_load_gpr(t0
, rs
);
2512 gen_load_gpr(t1
, rt
);
2515 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2516 tcg_gen_shl_tl(t0
, t1
, t0
);
2517 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2521 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2522 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2526 tcg_gen_ext32u_tl(t1
, t1
);
2527 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2528 tcg_gen_shr_tl(t0
, t1
, t0
);
2529 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2534 TCGv_i32 t2
= tcg_temp_new_i32();
2535 TCGv_i32 t3
= tcg_temp_new_i32();
2537 tcg_gen_trunc_tl_i32(t2
, t0
);
2538 tcg_gen_trunc_tl_i32(t3
, t1
);
2539 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2540 tcg_gen_rotr_i32(t2
, t3
, t2
);
2541 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2542 tcg_temp_free_i32(t2
);
2543 tcg_temp_free_i32(t3
);
2547 #if defined(TARGET_MIPS64)
2549 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2550 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2554 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2555 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2559 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2560 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2564 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2565 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2570 (void)opn
; /* avoid a compiler warning */
2571 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2576 /* Arithmetic on HI/LO registers */
2577 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2579 const char *opn
= "hilo";
2581 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2593 #if defined(TARGET_MIPS64)
2595 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2599 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2604 #if defined(TARGET_MIPS64)
2606 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2610 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2616 #if defined(TARGET_MIPS64)
2618 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2622 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2625 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2631 #if defined(TARGET_MIPS64)
2633 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2637 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2640 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2645 (void)opn
; /* avoid a compiler warning */
2646 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2649 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
2650 int acc
, int rs
, int rt
)
2652 const char *opn
= "mul/div";
2655 t0
= tcg_temp_new();
2656 t1
= tcg_temp_new();
2658 gen_load_gpr(t0
, rs
);
2659 gen_load_gpr(t1
, rt
);
2668 TCGv t2
= tcg_temp_new();
2669 TCGv t3
= tcg_temp_new();
2670 tcg_gen_ext32s_tl(t0
, t0
);
2671 tcg_gen_ext32s_tl(t1
, t1
);
2672 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2673 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2674 tcg_gen_and_tl(t2
, t2
, t3
);
2675 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2676 tcg_gen_or_tl(t2
, t2
, t3
);
2677 tcg_gen_movi_tl(t3
, 0);
2678 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2679 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2680 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2681 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2682 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2690 TCGv t2
= tcg_const_tl(0);
2691 TCGv t3
= tcg_const_tl(1);
2692 tcg_gen_ext32u_tl(t0
, t0
);
2693 tcg_gen_ext32u_tl(t1
, t1
);
2694 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2695 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
2696 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
2697 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2698 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2706 TCGv_i32 t2
= tcg_temp_new_i32();
2707 TCGv_i32 t3
= tcg_temp_new_i32();
2708 tcg_gen_trunc_tl_i32(t2
, t0
);
2709 tcg_gen_trunc_tl_i32(t3
, t1
);
2710 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
2711 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2712 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2713 tcg_temp_free_i32(t2
);
2714 tcg_temp_free_i32(t3
);
2720 TCGv_i32 t2
= tcg_temp_new_i32();
2721 TCGv_i32 t3
= tcg_temp_new_i32();
2722 tcg_gen_trunc_tl_i32(t2
, t0
);
2723 tcg_gen_trunc_tl_i32(t3
, t1
);
2724 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
2725 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2726 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2727 tcg_temp_free_i32(t2
);
2728 tcg_temp_free_i32(t3
);
2732 #if defined(TARGET_MIPS64)
2735 TCGv t2
= tcg_temp_new();
2736 TCGv t3
= tcg_temp_new();
2737 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2738 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2739 tcg_gen_and_tl(t2
, t2
, t3
);
2740 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2741 tcg_gen_or_tl(t2
, t2
, t3
);
2742 tcg_gen_movi_tl(t3
, 0);
2743 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2744 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2745 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2753 TCGv t2
= tcg_const_tl(0);
2754 TCGv t3
= tcg_const_tl(1);
2755 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2756 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
2757 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
2764 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2768 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2774 TCGv_i64 t2
= tcg_temp_new_i64();
2775 TCGv_i64 t3
= tcg_temp_new_i64();
2777 tcg_gen_ext_tl_i64(t2
, t0
);
2778 tcg_gen_ext_tl_i64(t3
, t1
);
2779 tcg_gen_mul_i64(t2
, t2
, t3
);
2780 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2781 tcg_gen_add_i64(t2
, t2
, t3
);
2782 tcg_temp_free_i64(t3
);
2783 tcg_gen_trunc_i64_tl(t0
, t2
);
2784 tcg_gen_shri_i64(t2
, t2
, 32);
2785 tcg_gen_trunc_i64_tl(t1
, t2
);
2786 tcg_temp_free_i64(t2
);
2787 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2788 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2794 TCGv_i64 t2
= tcg_temp_new_i64();
2795 TCGv_i64 t3
= tcg_temp_new_i64();
2797 tcg_gen_ext32u_tl(t0
, t0
);
2798 tcg_gen_ext32u_tl(t1
, t1
);
2799 tcg_gen_extu_tl_i64(t2
, t0
);
2800 tcg_gen_extu_tl_i64(t3
, t1
);
2801 tcg_gen_mul_i64(t2
, t2
, t3
);
2802 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2803 tcg_gen_add_i64(t2
, t2
, t3
);
2804 tcg_temp_free_i64(t3
);
2805 tcg_gen_trunc_i64_tl(t0
, t2
);
2806 tcg_gen_shri_i64(t2
, t2
, 32);
2807 tcg_gen_trunc_i64_tl(t1
, t2
);
2808 tcg_temp_free_i64(t2
);
2809 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2810 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2816 TCGv_i64 t2
= tcg_temp_new_i64();
2817 TCGv_i64 t3
= tcg_temp_new_i64();
2819 tcg_gen_ext_tl_i64(t2
, t0
);
2820 tcg_gen_ext_tl_i64(t3
, t1
);
2821 tcg_gen_mul_i64(t2
, t2
, t3
);
2822 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2823 tcg_gen_sub_i64(t2
, t3
, t2
);
2824 tcg_temp_free_i64(t3
);
2825 tcg_gen_trunc_i64_tl(t0
, t2
);
2826 tcg_gen_shri_i64(t2
, t2
, 32);
2827 tcg_gen_trunc_i64_tl(t1
, t2
);
2828 tcg_temp_free_i64(t2
);
2829 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2830 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2836 TCGv_i64 t2
= tcg_temp_new_i64();
2837 TCGv_i64 t3
= tcg_temp_new_i64();
2839 tcg_gen_ext32u_tl(t0
, t0
);
2840 tcg_gen_ext32u_tl(t1
, t1
);
2841 tcg_gen_extu_tl_i64(t2
, t0
);
2842 tcg_gen_extu_tl_i64(t3
, t1
);
2843 tcg_gen_mul_i64(t2
, t2
, t3
);
2844 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2845 tcg_gen_sub_i64(t2
, t3
, t2
);
2846 tcg_temp_free_i64(t3
);
2847 tcg_gen_trunc_i64_tl(t0
, t2
);
2848 tcg_gen_shri_i64(t2
, t2
, 32);
2849 tcg_gen_trunc_i64_tl(t1
, t2
);
2850 tcg_temp_free_i64(t2
);
2851 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2852 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2858 generate_exception(ctx
, EXCP_RI
);
2861 (void)opn
; /* avoid a compiler warning */
2862 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2868 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2869 int rd
, int rs
, int rt
)
2871 const char *opn
= "mul vr54xx";
2872 TCGv t0
= tcg_temp_new();
2873 TCGv t1
= tcg_temp_new();
2875 gen_load_gpr(t0
, rs
);
2876 gen_load_gpr(t1
, rt
);
2879 case OPC_VR54XX_MULS
:
2880 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2883 case OPC_VR54XX_MULSU
:
2884 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2887 case OPC_VR54XX_MACC
:
2888 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2891 case OPC_VR54XX_MACCU
:
2892 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2895 case OPC_VR54XX_MSAC
:
2896 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2899 case OPC_VR54XX_MSACU
:
2900 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2903 case OPC_VR54XX_MULHI
:
2904 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2907 case OPC_VR54XX_MULHIU
:
2908 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2911 case OPC_VR54XX_MULSHI
:
2912 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2915 case OPC_VR54XX_MULSHIU
:
2916 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2919 case OPC_VR54XX_MACCHI
:
2920 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2923 case OPC_VR54XX_MACCHIU
:
2924 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2927 case OPC_VR54XX_MSACHI
:
2928 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2931 case OPC_VR54XX_MSACHIU
:
2932 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2936 MIPS_INVAL("mul vr54xx");
2937 generate_exception(ctx
, EXCP_RI
);
2940 gen_store_gpr(t0
, rd
);
2941 (void)opn
; /* avoid a compiler warning */
2942 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2949 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2952 const char *opn
= "CLx";
2960 t0
= tcg_temp_new();
2961 gen_load_gpr(t0
, rs
);
2964 gen_helper_clo(cpu_gpr
[rd
], t0
);
2968 gen_helper_clz(cpu_gpr
[rd
], t0
);
2971 #if defined(TARGET_MIPS64)
2973 gen_helper_dclo(cpu_gpr
[rd
], t0
);
2977 gen_helper_dclz(cpu_gpr
[rd
], t0
);
2982 (void)opn
; /* avoid a compiler warning */
2983 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
2987 /* Godson integer instructions */
2988 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
2989 int rd
, int rs
, int rt
)
2991 const char *opn
= "loongson";
3003 case OPC_MULTU_G_2E
:
3004 case OPC_MULTU_G_2F
:
3005 #if defined(TARGET_MIPS64)
3006 case OPC_DMULT_G_2E
:
3007 case OPC_DMULT_G_2F
:
3008 case OPC_DMULTU_G_2E
:
3009 case OPC_DMULTU_G_2F
:
3011 t0
= tcg_temp_new();
3012 t1
= tcg_temp_new();
3015 t0
= tcg_temp_local_new();
3016 t1
= tcg_temp_local_new();
3020 gen_load_gpr(t0
, rs
);
3021 gen_load_gpr(t1
, rt
);
3026 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3027 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3030 case OPC_MULTU_G_2E
:
3031 case OPC_MULTU_G_2F
:
3032 tcg_gen_ext32u_tl(t0
, t0
);
3033 tcg_gen_ext32u_tl(t1
, t1
);
3034 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3035 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3041 int l1
= gen_new_label();
3042 int l2
= gen_new_label();
3043 int l3
= gen_new_label();
3044 tcg_gen_ext32s_tl(t0
, t0
);
3045 tcg_gen_ext32s_tl(t1
, t1
);
3046 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3047 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3050 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3051 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3052 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3055 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3056 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3064 int l1
= gen_new_label();
3065 int l2
= gen_new_label();
3066 tcg_gen_ext32u_tl(t0
, t0
);
3067 tcg_gen_ext32u_tl(t1
, t1
);
3068 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3069 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3072 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3073 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3081 int l1
= gen_new_label();
3082 int l2
= gen_new_label();
3083 int l3
= gen_new_label();
3084 tcg_gen_ext32u_tl(t0
, t0
);
3085 tcg_gen_ext32u_tl(t1
, t1
);
3086 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3087 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3088 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3090 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3093 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3094 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3102 int l1
= gen_new_label();
3103 int l2
= gen_new_label();
3104 tcg_gen_ext32u_tl(t0
, t0
);
3105 tcg_gen_ext32u_tl(t1
, t1
);
3106 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3107 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3110 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3111 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3116 #if defined(TARGET_MIPS64)
3117 case OPC_DMULT_G_2E
:
3118 case OPC_DMULT_G_2F
:
3119 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3122 case OPC_DMULTU_G_2E
:
3123 case OPC_DMULTU_G_2F
:
3124 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3130 int l1
= gen_new_label();
3131 int l2
= gen_new_label();
3132 int l3
= gen_new_label();
3133 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3134 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3137 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3138 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3139 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3142 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3147 case OPC_DDIVU_G_2E
:
3148 case OPC_DDIVU_G_2F
:
3150 int l1
= gen_new_label();
3151 int l2
= gen_new_label();
3152 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3153 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3156 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3164 int l1
= gen_new_label();
3165 int l2
= gen_new_label();
3166 int l3
= gen_new_label();
3167 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3168 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3169 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3171 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3174 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3179 case OPC_DMODU_G_2E
:
3180 case OPC_DMODU_G_2F
:
3182 int l1
= gen_new_label();
3183 int l2
= gen_new_label();
3184 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3185 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3188 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3196 (void)opn
; /* avoid a compiler warning */
3197 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3202 /* Loongson multimedia instructions */
3203 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3205 const char *opn
= "loongson_cp2";
3206 uint32_t opc
, shift_max
;
3209 opc
= MASK_LMI(ctx
->opcode
);
3215 t0
= tcg_temp_local_new_i64();
3216 t1
= tcg_temp_local_new_i64();
3219 t0
= tcg_temp_new_i64();
3220 t1
= tcg_temp_new_i64();
3224 gen_load_fpr64(ctx
, t0
, rs
);
3225 gen_load_fpr64(ctx
, t1
, rt
);
3227 #define LMI_HELPER(UP, LO) \
3228 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3229 #define LMI_HELPER_1(UP, LO) \
3230 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3231 #define LMI_DIRECT(UP, LO, OP) \
3232 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3235 LMI_HELPER(PADDSH
, paddsh
);
3236 LMI_HELPER(PADDUSH
, paddush
);
3237 LMI_HELPER(PADDH
, paddh
);
3238 LMI_HELPER(PADDW
, paddw
);
3239 LMI_HELPER(PADDSB
, paddsb
);
3240 LMI_HELPER(PADDUSB
, paddusb
);
3241 LMI_HELPER(PADDB
, paddb
);
3243 LMI_HELPER(PSUBSH
, psubsh
);
3244 LMI_HELPER(PSUBUSH
, psubush
);
3245 LMI_HELPER(PSUBH
, psubh
);
3246 LMI_HELPER(PSUBW
, psubw
);
3247 LMI_HELPER(PSUBSB
, psubsb
);
3248 LMI_HELPER(PSUBUSB
, psubusb
);
3249 LMI_HELPER(PSUBB
, psubb
);
3251 LMI_HELPER(PSHUFH
, pshufh
);
3252 LMI_HELPER(PACKSSWH
, packsswh
);
3253 LMI_HELPER(PACKSSHB
, packsshb
);
3254 LMI_HELPER(PACKUSHB
, packushb
);
3256 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3257 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3258 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3259 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3260 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3261 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3263 LMI_HELPER(PAVGH
, pavgh
);
3264 LMI_HELPER(PAVGB
, pavgb
);
3265 LMI_HELPER(PMAXSH
, pmaxsh
);
3266 LMI_HELPER(PMINSH
, pminsh
);
3267 LMI_HELPER(PMAXUB
, pmaxub
);
3268 LMI_HELPER(PMINUB
, pminub
);
3270 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3271 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3272 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3273 LMI_HELPER(PCMPGTH
, pcmpgth
);
3274 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3275 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3277 LMI_HELPER(PSLLW
, psllw
);
3278 LMI_HELPER(PSLLH
, psllh
);
3279 LMI_HELPER(PSRLW
, psrlw
);
3280 LMI_HELPER(PSRLH
, psrlh
);
3281 LMI_HELPER(PSRAW
, psraw
);
3282 LMI_HELPER(PSRAH
, psrah
);
3284 LMI_HELPER(PMULLH
, pmullh
);
3285 LMI_HELPER(PMULHH
, pmulhh
);
3286 LMI_HELPER(PMULHUH
, pmulhuh
);
3287 LMI_HELPER(PMADDHW
, pmaddhw
);
3289 LMI_HELPER(PASUBUB
, pasubub
);
3290 LMI_HELPER_1(BIADD
, biadd
);
3291 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3293 LMI_DIRECT(PADDD
, paddd
, add
);
3294 LMI_DIRECT(PSUBD
, psubd
, sub
);
3295 LMI_DIRECT(XOR_CP2
, xor, xor);
3296 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3297 LMI_DIRECT(AND_CP2
, and, and);
3298 LMI_DIRECT(PANDN
, pandn
, andc
);
3299 LMI_DIRECT(OR
, or, or);
3302 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3306 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3310 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3314 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3319 tcg_gen_andi_i64(t1
, t1
, 3);
3320 tcg_gen_shli_i64(t1
, t1
, 4);
3321 tcg_gen_shr_i64(t0
, t0
, t1
);
3322 tcg_gen_ext16u_i64(t0
, t0
);
3327 tcg_gen_add_i64(t0
, t0
, t1
);
3328 tcg_gen_ext32s_i64(t0
, t0
);
3332 tcg_gen_sub_i64(t0
, t0
, t1
);
3333 tcg_gen_ext32s_i64(t0
, t0
);
3362 /* Make sure shift count isn't TCG undefined behaviour. */
3363 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3368 tcg_gen_shl_i64(t0
, t0
, t1
);
3372 /* Since SRA is UndefinedResult without sign-extended inputs,
3373 we can treat SRA and DSRA the same. */
3374 tcg_gen_sar_i64(t0
, t0
, t1
);
3377 /* We want to shift in zeros for SRL; zero-extend first. */
3378 tcg_gen_ext32u_i64(t0
, t0
);
3381 tcg_gen_shr_i64(t0
, t0
, t1
);
3385 if (shift_max
== 32) {
3386 tcg_gen_ext32s_i64(t0
, t0
);
3389 /* Shifts larger than MAX produce zero. */
3390 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3391 tcg_gen_neg_i64(t1
, t1
);
3392 tcg_gen_and_i64(t0
, t0
, t1
);
3398 TCGv_i64 t2
= tcg_temp_new_i64();
3399 int lab
= gen_new_label();
3401 tcg_gen_mov_i64(t2
, t0
);
3402 tcg_gen_add_i64(t0
, t1
, t2
);
3403 if (opc
== OPC_ADD_CP2
) {
3404 tcg_gen_ext32s_i64(t0
, t0
);
3406 tcg_gen_xor_i64(t1
, t1
, t2
);
3407 tcg_gen_xor_i64(t2
, t2
, t0
);
3408 tcg_gen_andc_i64(t1
, t2
, t1
);
3409 tcg_temp_free_i64(t2
);
3410 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3411 generate_exception(ctx
, EXCP_OVERFLOW
);
3414 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3421 TCGv_i64 t2
= tcg_temp_new_i64();
3422 int lab
= gen_new_label();
3424 tcg_gen_mov_i64(t2
, t0
);
3425 tcg_gen_sub_i64(t0
, t1
, t2
);
3426 if (opc
== OPC_SUB_CP2
) {
3427 tcg_gen_ext32s_i64(t0
, t0
);
3429 tcg_gen_xor_i64(t1
, t1
, t2
);
3430 tcg_gen_xor_i64(t2
, t2
, t0
);
3431 tcg_gen_and_i64(t1
, t1
, t2
);
3432 tcg_temp_free_i64(t2
);
3433 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3434 generate_exception(ctx
, EXCP_OVERFLOW
);
3437 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3442 tcg_gen_ext32u_i64(t0
, t0
);
3443 tcg_gen_ext32u_i64(t1
, t1
);
3444 tcg_gen_mul_i64(t0
, t0
, t1
);
3454 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3455 FD field is the CC field? */
3458 generate_exception(ctx
, EXCP_RI
);
3465 gen_store_fpr64(ctx
, t0
, rd
);
3467 (void)opn
; /* avoid a compiler warning */
3468 MIPS_DEBUG("%s %s, %s, %s", opn
,
3469 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3470 tcg_temp_free_i64(t0
);
3471 tcg_temp_free_i64(t1
);
3475 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3476 int rs
, int rt
, int16_t imm
)
3479 TCGv t0
= tcg_temp_new();
3480 TCGv t1
= tcg_temp_new();
3483 /* Load needed operands */
3491 /* Compare two registers */
3493 gen_load_gpr(t0
, rs
);
3494 gen_load_gpr(t1
, rt
);
3504 /* Compare register to immediate */
3505 if (rs
!= 0 || imm
!= 0) {
3506 gen_load_gpr(t0
, rs
);
3507 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3514 case OPC_TEQ
: /* rs == rs */
3515 case OPC_TEQI
: /* r0 == 0 */
3516 case OPC_TGE
: /* rs >= rs */
3517 case OPC_TGEI
: /* r0 >= 0 */
3518 case OPC_TGEU
: /* rs >= rs unsigned */
3519 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3521 generate_exception(ctx
, EXCP_TRAP
);
3523 case OPC_TLT
: /* rs < rs */
3524 case OPC_TLTI
: /* r0 < 0 */
3525 case OPC_TLTU
: /* rs < rs unsigned */
3526 case OPC_TLTIU
: /* r0 < 0 unsigned */
3527 case OPC_TNE
: /* rs != rs */
3528 case OPC_TNEI
: /* r0 != 0 */
3529 /* Never trap: treat as NOP. */
3533 int l1
= gen_new_label();
3538 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3542 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3546 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3550 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3554 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3558 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3561 generate_exception(ctx
, EXCP_TRAP
);
3568 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3570 TranslationBlock
*tb
;
3572 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3573 likely(!ctx
->singlestep_enabled
)) {
3576 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3579 if (ctx
->singlestep_enabled
) {
3580 save_cpu_state(ctx
, 0);
3581 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3587 /* Branches (before delay slot) */
3588 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3590 int rs
, int rt
, int32_t offset
)
3592 target_ulong btgt
= -1;
3594 int bcond_compute
= 0;
3595 TCGv t0
= tcg_temp_new();
3596 TCGv t1
= tcg_temp_new();
3598 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3599 #ifdef MIPS_DEBUG_DISAS
3600 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3602 generate_exception(ctx
, EXCP_RI
);
3606 /* Load needed operands */
3612 /* Compare two registers */
3614 gen_load_gpr(t0
, rs
);
3615 gen_load_gpr(t1
, rt
);
3618 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3634 /* Compare to zero */
3636 gen_load_gpr(t0
, rs
);
3639 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3642 #if defined(TARGET_MIPS64)
3644 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3646 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3649 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3656 /* Jump to immediate */
3657 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3663 /* Jump to register */
3664 if (offset
!= 0 && offset
!= 16) {
3665 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3666 others are reserved. */
3667 MIPS_INVAL("jump hint");
3668 generate_exception(ctx
, EXCP_RI
);
3671 gen_load_gpr(btarget
, rs
);
3674 MIPS_INVAL("branch/jump");
3675 generate_exception(ctx
, EXCP_RI
);
3678 if (bcond_compute
== 0) {
3679 /* No condition to be computed */
3681 case OPC_BEQ
: /* rx == rx */
3682 case OPC_BEQL
: /* rx == rx likely */
3683 case OPC_BGEZ
: /* 0 >= 0 */
3684 case OPC_BGEZL
: /* 0 >= 0 likely */
3685 case OPC_BLEZ
: /* 0 <= 0 */
3686 case OPC_BLEZL
: /* 0 <= 0 likely */
3688 ctx
->hflags
|= MIPS_HFLAG_B
;
3689 MIPS_DEBUG("balways");
3692 case OPC_BGEZAL
: /* 0 >= 0 */
3693 case OPC_BGEZALL
: /* 0 >= 0 likely */
3694 ctx
->hflags
|= (opc
== OPC_BGEZALS
3696 : MIPS_HFLAG_BDS32
);
3697 /* Always take and link */
3699 ctx
->hflags
|= MIPS_HFLAG_B
;
3700 MIPS_DEBUG("balways and link");
3702 case OPC_BNE
: /* rx != rx */
3703 case OPC_BGTZ
: /* 0 > 0 */
3704 case OPC_BLTZ
: /* 0 < 0 */
3706 MIPS_DEBUG("bnever (NOP)");
3709 case OPC_BLTZAL
: /* 0 < 0 */
3710 ctx
->hflags
|= (opc
== OPC_BLTZALS
3712 : MIPS_HFLAG_BDS32
);
3713 /* Handle as an unconditional branch to get correct delay
3716 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3717 ctx
->hflags
|= MIPS_HFLAG_B
;
3718 MIPS_DEBUG("bnever and link");
3720 case OPC_BLTZALL
: /* 0 < 0 likely */
3721 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3722 /* Skip the instruction in the delay slot */
3723 MIPS_DEBUG("bnever, link and skip");
3726 case OPC_BNEL
: /* rx != rx likely */
3727 case OPC_BGTZL
: /* 0 > 0 likely */
3728 case OPC_BLTZL
: /* 0 < 0 likely */
3729 /* Skip the instruction in the delay slot */
3730 MIPS_DEBUG("bnever and skip");
3734 ctx
->hflags
|= MIPS_HFLAG_B
;
3735 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3739 ctx
->hflags
|= MIPS_HFLAG_BX
;
3744 ctx
->hflags
|= MIPS_HFLAG_B
;
3745 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3747 : MIPS_HFLAG_BDS32
);
3748 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3751 ctx
->hflags
|= MIPS_HFLAG_BR
;
3752 if (insn_bytes
== 4)
3753 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3754 MIPS_DEBUG("jr %s", regnames
[rs
]);
3760 ctx
->hflags
|= MIPS_HFLAG_BR
;
3761 ctx
->hflags
|= (opc
== OPC_JALRS
3763 : MIPS_HFLAG_BDS32
);
3764 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3767 MIPS_INVAL("branch/jump");
3768 generate_exception(ctx
, EXCP_RI
);
3774 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3775 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3776 regnames
[rs
], regnames
[rt
], btgt
);
3779 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3780 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3781 regnames
[rs
], regnames
[rt
], btgt
);
3784 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3785 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3786 regnames
[rs
], regnames
[rt
], btgt
);
3789 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3790 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3791 regnames
[rs
], regnames
[rt
], btgt
);
3794 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3795 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3798 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3799 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3803 ctx
->hflags
|= (opc
== OPC_BGEZALS
3805 : MIPS_HFLAG_BDS32
);
3806 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3807 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3811 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3813 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3816 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3817 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3820 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3821 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3824 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3825 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3828 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3829 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3832 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3833 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3836 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3837 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3840 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3841 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3843 #if defined(TARGET_MIPS64)
3845 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3846 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3851 ctx
->hflags
|= (opc
== OPC_BLTZALS
3853 : MIPS_HFLAG_BDS32
);
3854 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3856 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3858 ctx
->hflags
|= MIPS_HFLAG_BC
;
3861 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3863 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3865 ctx
->hflags
|= MIPS_HFLAG_BL
;
3868 MIPS_INVAL("conditional branch/jump");
3869 generate_exception(ctx
, EXCP_RI
);
3873 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3874 blink
, ctx
->hflags
, btgt
);
3876 ctx
->btarget
= btgt
;
3878 int post_delay
= insn_bytes
;
3879 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3881 if (opc
!= OPC_JALRC
)
3882 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3884 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3888 if (insn_bytes
== 2)
3889 ctx
->hflags
|= MIPS_HFLAG_B16
;
3894 /* special3 bitfield operations */
3895 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3896 int rs
, int lsb
, int msb
)
3898 TCGv t0
= tcg_temp_new();
3899 TCGv t1
= tcg_temp_new();
3901 gen_load_gpr(t1
, rs
);
3906 tcg_gen_shri_tl(t0
, t1
, lsb
);
3908 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3910 tcg_gen_ext32s_tl(t0
, t0
);
3913 #if defined(TARGET_MIPS64)
3915 tcg_gen_shri_tl(t0
, t1
, lsb
);
3917 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3921 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3922 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3925 tcg_gen_shri_tl(t0
, t1
, lsb
);
3926 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3932 gen_load_gpr(t0
, rt
);
3933 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3934 tcg_gen_ext32s_tl(t0
, t0
);
3936 #if defined(TARGET_MIPS64)
3938 gen_load_gpr(t0
, rt
);
3939 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3942 gen_load_gpr(t0
, rt
);
3943 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3946 gen_load_gpr(t0
, rt
);
3947 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3952 MIPS_INVAL("bitops");
3953 generate_exception(ctx
, EXCP_RI
);
3958 gen_store_gpr(t0
, rt
);
3963 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
3968 /* If no destination, treat it as a NOP. */
3973 t0
= tcg_temp_new();
3974 gen_load_gpr(t0
, rt
);
3978 TCGv t1
= tcg_temp_new();
3980 tcg_gen_shri_tl(t1
, t0
, 8);
3981 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
3982 tcg_gen_shli_tl(t0
, t0
, 8);
3983 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
3984 tcg_gen_or_tl(t0
, t0
, t1
);
3986 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
3990 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
3993 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
3995 #if defined(TARGET_MIPS64)
3998 TCGv t1
= tcg_temp_new();
4000 tcg_gen_shri_tl(t1
, t0
, 8);
4001 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4002 tcg_gen_shli_tl(t0
, t0
, 8);
4003 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4004 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4010 TCGv t1
= tcg_temp_new();
4012 tcg_gen_shri_tl(t1
, t0
, 16);
4013 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4014 tcg_gen_shli_tl(t0
, t0
, 16);
4015 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4016 tcg_gen_or_tl(t0
, t0
, t1
);
4017 tcg_gen_shri_tl(t1
, t0
, 32);
4018 tcg_gen_shli_tl(t0
, t0
, 32);
4019 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4025 MIPS_INVAL("bsfhl");
4026 generate_exception(ctx
, EXCP_RI
);
4033 #ifndef CONFIG_USER_ONLY
4034 /* CP0 (MMU and control) */
4035 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4037 TCGv_i32 t0
= tcg_temp_new_i32();
4039 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4040 tcg_gen_ext_i32_tl(arg
, t0
);
4041 tcg_temp_free_i32(t0
);
4044 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4046 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4047 tcg_gen_ext32s_tl(arg
, arg
);
4050 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4052 TCGv_i32 t0
= tcg_temp_new_i32();
4054 tcg_gen_trunc_tl_i32(t0
, arg
);
4055 tcg_gen_st_i32(t0
, cpu_env
, off
);
4056 tcg_temp_free_i32(t0
);
4059 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4061 tcg_gen_ext32s_tl(arg
, arg
);
4062 tcg_gen_st_tl(arg
, cpu_env
, off
);
4065 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4067 const char *rn
= "invalid";
4070 check_insn(ctx
, ISA_MIPS32
);
4076 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4080 check_insn(ctx
, ASE_MT
);
4081 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4085 check_insn(ctx
, ASE_MT
);
4086 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4090 check_insn(ctx
, ASE_MT
);
4091 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4101 gen_helper_mfc0_random(arg
, cpu_env
);
4105 check_insn(ctx
, ASE_MT
);
4106 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4110 check_insn(ctx
, ASE_MT
);
4111 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4115 check_insn(ctx
, ASE_MT
);
4116 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4120 check_insn(ctx
, ASE_MT
);
4121 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4125 check_insn(ctx
, ASE_MT
);
4126 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4130 check_insn(ctx
, ASE_MT
);
4131 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4132 rn
= "VPEScheFBack";
4135 check_insn(ctx
, ASE_MT
);
4136 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4146 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4147 tcg_gen_ext32s_tl(arg
, arg
);
4151 check_insn(ctx
, ASE_MT
);
4152 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4156 check_insn(ctx
, ASE_MT
);
4157 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4161 check_insn(ctx
, ASE_MT
);
4162 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4166 check_insn(ctx
, ASE_MT
);
4167 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4171 check_insn(ctx
, ASE_MT
);
4172 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4176 check_insn(ctx
, ASE_MT
);
4177 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4181 check_insn(ctx
, ASE_MT
);
4182 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4192 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4193 tcg_gen_ext32s_tl(arg
, arg
);
4203 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4204 tcg_gen_ext32s_tl(arg
, arg
);
4208 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4209 rn
= "ContextConfig";
4218 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4222 check_insn(ctx
, ISA_MIPS32R2
);
4223 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4233 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4237 check_insn(ctx
, ISA_MIPS32R2
);
4238 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4242 check_insn(ctx
, ISA_MIPS32R2
);
4243 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4247 check_insn(ctx
, ISA_MIPS32R2
);
4248 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4252 check_insn(ctx
, ISA_MIPS32R2
);
4253 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4257 check_insn(ctx
, ISA_MIPS32R2
);
4258 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4268 check_insn(ctx
, ISA_MIPS32R2
);
4269 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4279 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4280 tcg_gen_ext32s_tl(arg
, arg
);
4290 /* Mark as an IO operation because we read the time. */
4293 gen_helper_mfc0_count(arg
, cpu_env
);
4297 /* Break the TB to be able to take timer interrupts immediately
4298 after reading count. */
4299 ctx
->bstate
= BS_STOP
;
4302 /* 6,7 are implementation dependent */
4310 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4311 tcg_gen_ext32s_tl(arg
, arg
);
4321 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4324 /* 6,7 are implementation dependent */
4332 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4336 check_insn(ctx
, ISA_MIPS32R2
);
4337 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4341 check_insn(ctx
, ISA_MIPS32R2
);
4342 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4346 check_insn(ctx
, ISA_MIPS32R2
);
4347 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4357 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4367 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4368 tcg_gen_ext32s_tl(arg
, arg
);
4378 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4382 check_insn(ctx
, ISA_MIPS32R2
);
4383 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4393 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4397 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4401 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4405 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4409 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
4413 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
4416 /* 6,7 are implementation dependent */
4418 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4422 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4432 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4442 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4452 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4462 #if defined(TARGET_MIPS64)
4463 check_insn(ctx
, ISA_MIPS3
);
4464 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4465 tcg_gen_ext32s_tl(arg
, arg
);
4474 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4477 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4485 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4486 rn
= "'Diagnostic"; /* implementation dependent */
4491 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4495 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4496 rn
= "TraceControl";
4499 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4500 rn
= "TraceControl2";
4503 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4504 rn
= "UserTraceData";
4507 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4518 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4519 tcg_gen_ext32s_tl(arg
, arg
);
4529 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4530 rn
= "Performance0";
4533 // gen_helper_mfc0_performance1(arg);
4534 rn
= "Performance1";
4537 // gen_helper_mfc0_performance2(arg);
4538 rn
= "Performance2";
4541 // gen_helper_mfc0_performance3(arg);
4542 rn
= "Performance3";
4545 // gen_helper_mfc0_performance4(arg);
4546 rn
= "Performance4";
4549 // gen_helper_mfc0_performance5(arg);
4550 rn
= "Performance5";
4553 // gen_helper_mfc0_performance6(arg);
4554 rn
= "Performance6";
4557 // gen_helper_mfc0_performance7(arg);
4558 rn
= "Performance7";
4565 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4571 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4584 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4591 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4604 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4611 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4621 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4622 tcg_gen_ext32s_tl(arg
, arg
);
4633 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4643 (void)rn
; /* avoid a compiler warning */
4644 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4648 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4649 generate_exception(ctx
, EXCP_RI
);
4652 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4654 const char *rn
= "invalid";
4657 check_insn(ctx
, ISA_MIPS32
);
4666 gen_helper_mtc0_index(cpu_env
, arg
);
4670 check_insn(ctx
, ASE_MT
);
4671 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4675 check_insn(ctx
, ASE_MT
);
4680 check_insn(ctx
, ASE_MT
);
4695 check_insn(ctx
, ASE_MT
);
4696 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4700 check_insn(ctx
, ASE_MT
);
4701 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4705 check_insn(ctx
, ASE_MT
);
4706 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4710 check_insn(ctx
, ASE_MT
);
4711 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4715 check_insn(ctx
, ASE_MT
);
4716 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4720 check_insn(ctx
, ASE_MT
);
4721 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4722 rn
= "VPEScheFBack";
4725 check_insn(ctx
, ASE_MT
);
4726 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4736 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4740 check_insn(ctx
, ASE_MT
);
4741 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4745 check_insn(ctx
, ASE_MT
);
4746 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4750 check_insn(ctx
, ASE_MT
);
4751 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4755 check_insn(ctx
, ASE_MT
);
4756 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4760 check_insn(ctx
, ASE_MT
);
4761 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4765 check_insn(ctx
, ASE_MT
);
4766 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4770 check_insn(ctx
, ASE_MT
);
4771 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4781 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4791 gen_helper_mtc0_context(cpu_env
, arg
);
4795 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4796 rn
= "ContextConfig";
4805 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4809 check_insn(ctx
, ISA_MIPS32R2
);
4810 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4820 gen_helper_mtc0_wired(cpu_env
, arg
);
4824 check_insn(ctx
, ISA_MIPS32R2
);
4825 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4829 check_insn(ctx
, ISA_MIPS32R2
);
4830 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4834 check_insn(ctx
, ISA_MIPS32R2
);
4835 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4839 check_insn(ctx
, ISA_MIPS32R2
);
4840 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4844 check_insn(ctx
, ISA_MIPS32R2
);
4845 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4855 check_insn(ctx
, ISA_MIPS32R2
);
4856 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4870 gen_helper_mtc0_count(cpu_env
, arg
);
4873 /* 6,7 are implementation dependent */
4881 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4891 gen_helper_mtc0_compare(cpu_env
, arg
);
4894 /* 6,7 are implementation dependent */
4902 save_cpu_state(ctx
, 1);
4903 gen_helper_mtc0_status(cpu_env
, arg
);
4904 /* BS_STOP isn't good enough here, hflags may have changed. */
4905 gen_save_pc(ctx
->pc
+ 4);
4906 ctx
->bstate
= BS_EXCP
;
4910 check_insn(ctx
, ISA_MIPS32R2
);
4911 gen_helper_mtc0_intctl(cpu_env
, arg
);
4912 /* Stop translation as we may have switched the execution mode */
4913 ctx
->bstate
= BS_STOP
;
4917 check_insn(ctx
, ISA_MIPS32R2
);
4918 gen_helper_mtc0_srsctl(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_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4926 /* Stop translation as we may have switched the execution mode */
4927 ctx
->bstate
= BS_STOP
;
4937 save_cpu_state(ctx
, 1);
4938 gen_helper_mtc0_cause(cpu_env
, arg
);
4948 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4962 check_insn(ctx
, ISA_MIPS32R2
);
4963 gen_helper_mtc0_ebase(cpu_env
, arg
);
4973 gen_helper_mtc0_config0(cpu_env
, arg
);
4975 /* Stop translation as we may have switched the execution mode */
4976 ctx
->bstate
= BS_STOP
;
4979 /* ignored, read only */
4983 gen_helper_mtc0_config2(cpu_env
, arg
);
4985 /* Stop translation as we may have switched the execution mode */
4986 ctx
->bstate
= BS_STOP
;
4989 /* ignored, read only */
4993 gen_helper_mtc0_config4(cpu_env
, arg
);
4995 ctx
->bstate
= BS_STOP
;
4998 gen_helper_mtc0_config5(cpu_env
, arg
);
5000 /* Stop translation as we may have switched the execution mode */
5001 ctx
->bstate
= BS_STOP
;
5003 /* 6,7 are implementation dependent */
5013 rn
= "Invalid config selector";
5020 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5030 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5040 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5050 #if defined(TARGET_MIPS64)
5051 check_insn(ctx
, ISA_MIPS3
);
5052 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5061 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5064 gen_helper_mtc0_framemask(cpu_env
, arg
);
5073 rn
= "Diagnostic"; /* implementation dependent */
5078 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5079 /* BS_STOP isn't good enough here, hflags may have changed. */
5080 gen_save_pc(ctx
->pc
+ 4);
5081 ctx
->bstate
= BS_EXCP
;
5085 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5086 rn
= "TraceControl";
5087 /* Stop translation as we may have switched the execution mode */
5088 ctx
->bstate
= BS_STOP
;
5091 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5092 rn
= "TraceControl2";
5093 /* Stop translation as we may have switched the execution mode */
5094 ctx
->bstate
= BS_STOP
;
5097 /* Stop translation as we may have switched the execution mode */
5098 ctx
->bstate
= BS_STOP
;
5099 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5100 rn
= "UserTraceData";
5101 /* Stop translation as we may have switched the execution mode */
5102 ctx
->bstate
= BS_STOP
;
5105 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5106 /* Stop translation as we may have switched the execution mode */
5107 ctx
->bstate
= BS_STOP
;
5118 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5128 gen_helper_mtc0_performance0(cpu_env
, arg
);
5129 rn
= "Performance0";
5132 // gen_helper_mtc0_performance1(arg);
5133 rn
= "Performance1";
5136 // gen_helper_mtc0_performance2(arg);
5137 rn
= "Performance2";
5140 // gen_helper_mtc0_performance3(arg);
5141 rn
= "Performance3";
5144 // gen_helper_mtc0_performance4(arg);
5145 rn
= "Performance4";
5148 // gen_helper_mtc0_performance5(arg);
5149 rn
= "Performance5";
5152 // gen_helper_mtc0_performance6(arg);
5153 rn
= "Performance6";
5156 // gen_helper_mtc0_performance7(arg);
5157 rn
= "Performance7";
5183 gen_helper_mtc0_taglo(cpu_env
, arg
);
5190 gen_helper_mtc0_datalo(cpu_env
, arg
);
5203 gen_helper_mtc0_taghi(cpu_env
, arg
);
5210 gen_helper_mtc0_datahi(cpu_env
, arg
);
5221 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5232 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5238 /* Stop translation as we may have switched the execution mode */
5239 ctx
->bstate
= BS_STOP
;
5244 (void)rn
; /* avoid a compiler warning */
5245 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5246 /* For simplicity assume that all writes can cause interrupts. */
5249 ctx
->bstate
= BS_STOP
;
5254 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5255 generate_exception(ctx
, EXCP_RI
);
5258 #if defined(TARGET_MIPS64)
5259 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5261 const char *rn
= "invalid";
5264 check_insn(ctx
, ISA_MIPS64
);
5270 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5274 check_insn(ctx
, ASE_MT
);
5275 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5279 check_insn(ctx
, ASE_MT
);
5280 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5284 check_insn(ctx
, ASE_MT
);
5285 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5295 gen_helper_mfc0_random(arg
, cpu_env
);
5299 check_insn(ctx
, ASE_MT
);
5300 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5304 check_insn(ctx
, ASE_MT
);
5305 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5309 check_insn(ctx
, ASE_MT
);
5310 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5314 check_insn(ctx
, ASE_MT
);
5315 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5319 check_insn(ctx
, ASE_MT
);
5320 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5324 check_insn(ctx
, ASE_MT
);
5325 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5326 rn
= "VPEScheFBack";
5329 check_insn(ctx
, ASE_MT
);
5330 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5340 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5344 check_insn(ctx
, ASE_MT
);
5345 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5349 check_insn(ctx
, ASE_MT
);
5350 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5354 check_insn(ctx
, ASE_MT
);
5355 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5359 check_insn(ctx
, ASE_MT
);
5360 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5364 check_insn(ctx
, ASE_MT
);
5365 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5369 check_insn(ctx
, ASE_MT
);
5370 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5374 check_insn(ctx
, ASE_MT
);
5375 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5385 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5395 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5399 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5400 rn
= "ContextConfig";
5409 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5413 check_insn(ctx
, ISA_MIPS32R2
);
5414 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5424 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5428 check_insn(ctx
, ISA_MIPS32R2
);
5429 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5433 check_insn(ctx
, ISA_MIPS32R2
);
5434 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5438 check_insn(ctx
, ISA_MIPS32R2
);
5439 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5443 check_insn(ctx
, ISA_MIPS32R2
);
5444 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5448 check_insn(ctx
, ISA_MIPS32R2
);
5449 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5459 check_insn(ctx
, ISA_MIPS32R2
);
5460 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5470 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5480 /* Mark as an IO operation because we read the time. */
5483 gen_helper_mfc0_count(arg
, cpu_env
);
5487 /* Break the TB to be able to take timer interrupts immediately
5488 after reading count. */
5489 ctx
->bstate
= BS_STOP
;
5492 /* 6,7 are implementation dependent */
5500 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5510 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5513 /* 6,7 are implementation dependent */
5521 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5525 check_insn(ctx
, ISA_MIPS32R2
);
5526 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5530 check_insn(ctx
, ISA_MIPS32R2
);
5531 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5535 check_insn(ctx
, ISA_MIPS32R2
);
5536 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5546 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5556 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5566 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5570 check_insn(ctx
, ISA_MIPS32R2
);
5571 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5581 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5585 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5589 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5593 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5596 /* 6,7 are implementation dependent */
5598 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5602 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5612 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5622 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5632 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5642 check_insn(ctx
, ISA_MIPS3
);
5643 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5651 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5654 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5662 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5663 rn
= "'Diagnostic"; /* implementation dependent */
5668 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5672 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5673 rn
= "TraceControl";
5676 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5677 rn
= "TraceControl2";
5680 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5681 rn
= "UserTraceData";
5684 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5695 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5705 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5706 rn
= "Performance0";
5709 // gen_helper_dmfc0_performance1(arg);
5710 rn
= "Performance1";
5713 // gen_helper_dmfc0_performance2(arg);
5714 rn
= "Performance2";
5717 // gen_helper_dmfc0_performance3(arg);
5718 rn
= "Performance3";
5721 // gen_helper_dmfc0_performance4(arg);
5722 rn
= "Performance4";
5725 // gen_helper_dmfc0_performance5(arg);
5726 rn
= "Performance5";
5729 // gen_helper_dmfc0_performance6(arg);
5730 rn
= "Performance6";
5733 // gen_helper_dmfc0_performance7(arg);
5734 rn
= "Performance7";
5741 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5748 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5761 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5768 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5781 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5788 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5798 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5809 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5819 (void)rn
; /* avoid a compiler warning */
5820 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5824 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5825 generate_exception(ctx
, EXCP_RI
);
5828 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5830 const char *rn
= "invalid";
5833 check_insn(ctx
, ISA_MIPS64
);
5842 gen_helper_mtc0_index(cpu_env
, arg
);
5846 check_insn(ctx
, ASE_MT
);
5847 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5851 check_insn(ctx
, ASE_MT
);
5856 check_insn(ctx
, ASE_MT
);
5871 check_insn(ctx
, ASE_MT
);
5872 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5876 check_insn(ctx
, ASE_MT
);
5877 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5881 check_insn(ctx
, ASE_MT
);
5882 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5886 check_insn(ctx
, ASE_MT
);
5887 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5891 check_insn(ctx
, ASE_MT
);
5892 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5896 check_insn(ctx
, ASE_MT
);
5897 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5898 rn
= "VPEScheFBack";
5901 check_insn(ctx
, ASE_MT
);
5902 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5912 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5916 check_insn(ctx
, ASE_MT
);
5917 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5921 check_insn(ctx
, ASE_MT
);
5922 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5926 check_insn(ctx
, ASE_MT
);
5927 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5931 check_insn(ctx
, ASE_MT
);
5932 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5936 check_insn(ctx
, ASE_MT
);
5937 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5941 check_insn(ctx
, ASE_MT
);
5942 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5946 check_insn(ctx
, ASE_MT
);
5947 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5957 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
5967 gen_helper_mtc0_context(cpu_env
, arg
);
5971 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5972 rn
= "ContextConfig";
5981 gen_helper_mtc0_pagemask(cpu_env
, arg
);
5985 check_insn(ctx
, ISA_MIPS32R2
);
5986 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
5996 gen_helper_mtc0_wired(cpu_env
, arg
);
6000 check_insn(ctx
, ISA_MIPS32R2
);
6001 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6005 check_insn(ctx
, ISA_MIPS32R2
);
6006 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6010 check_insn(ctx
, ISA_MIPS32R2
);
6011 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6015 check_insn(ctx
, ISA_MIPS32R2
);
6016 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6020 check_insn(ctx
, ISA_MIPS32R2
);
6021 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6031 check_insn(ctx
, ISA_MIPS32R2
);
6032 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6046 gen_helper_mtc0_count(cpu_env
, arg
);
6049 /* 6,7 are implementation dependent */
6053 /* Stop translation as we may have switched the execution mode */
6054 ctx
->bstate
= BS_STOP
;
6059 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6069 gen_helper_mtc0_compare(cpu_env
, arg
);
6072 /* 6,7 are implementation dependent */
6076 /* Stop translation as we may have switched the execution mode */
6077 ctx
->bstate
= BS_STOP
;
6082 save_cpu_state(ctx
, 1);
6083 gen_helper_mtc0_status(cpu_env
, arg
);
6084 /* BS_STOP isn't good enough here, hflags may have changed. */
6085 gen_save_pc(ctx
->pc
+ 4);
6086 ctx
->bstate
= BS_EXCP
;
6090 check_insn(ctx
, ISA_MIPS32R2
);
6091 gen_helper_mtc0_intctl(cpu_env
, arg
);
6092 /* Stop translation as we may have switched the execution mode */
6093 ctx
->bstate
= BS_STOP
;
6097 check_insn(ctx
, ISA_MIPS32R2
);
6098 gen_helper_mtc0_srsctl(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_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6106 /* Stop translation as we may have switched the execution mode */
6107 ctx
->bstate
= BS_STOP
;
6117 save_cpu_state(ctx
, 1);
6118 /* Mark as an IO operation because we may trigger a software
6123 gen_helper_mtc0_cause(cpu_env
, arg
);
6127 /* Stop translation as we may have triggered an intetrupt */
6128 ctx
->bstate
= BS_STOP
;
6138 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6152 check_insn(ctx
, ISA_MIPS32R2
);
6153 gen_helper_mtc0_ebase(cpu_env
, arg
);
6163 gen_helper_mtc0_config0(cpu_env
, arg
);
6165 /* Stop translation as we may have switched the execution mode */
6166 ctx
->bstate
= BS_STOP
;
6169 /* ignored, read only */
6173 gen_helper_mtc0_config2(cpu_env
, arg
);
6175 /* Stop translation as we may have switched the execution mode */
6176 ctx
->bstate
= BS_STOP
;
6182 /* 6,7 are implementation dependent */
6184 rn
= "Invalid config selector";
6191 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6201 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6211 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6221 check_insn(ctx
, ISA_MIPS3
);
6222 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6230 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6233 gen_helper_mtc0_framemask(cpu_env
, arg
);
6242 rn
= "Diagnostic"; /* implementation dependent */
6247 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6248 /* BS_STOP isn't good enough here, hflags may have changed. */
6249 gen_save_pc(ctx
->pc
+ 4);
6250 ctx
->bstate
= BS_EXCP
;
6254 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6255 /* Stop translation as we may have switched the execution mode */
6256 ctx
->bstate
= BS_STOP
;
6257 rn
= "TraceControl";
6260 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6261 /* Stop translation as we may have switched the execution mode */
6262 ctx
->bstate
= BS_STOP
;
6263 rn
= "TraceControl2";
6266 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6267 /* Stop translation as we may have switched the execution mode */
6268 ctx
->bstate
= BS_STOP
;
6269 rn
= "UserTraceData";
6272 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6273 /* Stop translation as we may have switched the execution mode */
6274 ctx
->bstate
= BS_STOP
;
6285 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6295 gen_helper_mtc0_performance0(cpu_env
, arg
);
6296 rn
= "Performance0";
6299 // gen_helper_mtc0_performance1(cpu_env, arg);
6300 rn
= "Performance1";
6303 // gen_helper_mtc0_performance2(cpu_env, arg);
6304 rn
= "Performance2";
6307 // gen_helper_mtc0_performance3(cpu_env, arg);
6308 rn
= "Performance3";
6311 // gen_helper_mtc0_performance4(cpu_env, arg);
6312 rn
= "Performance4";
6315 // gen_helper_mtc0_performance5(cpu_env, arg);
6316 rn
= "Performance5";
6319 // gen_helper_mtc0_performance6(cpu_env, arg);
6320 rn
= "Performance6";
6323 // gen_helper_mtc0_performance7(cpu_env, arg);
6324 rn
= "Performance7";
6350 gen_helper_mtc0_taglo(cpu_env
, arg
);
6357 gen_helper_mtc0_datalo(cpu_env
, arg
);
6370 gen_helper_mtc0_taghi(cpu_env
, arg
);
6377 gen_helper_mtc0_datahi(cpu_env
, arg
);
6388 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6399 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6405 /* Stop translation as we may have switched the execution mode */
6406 ctx
->bstate
= BS_STOP
;
6411 (void)rn
; /* avoid a compiler warning */
6412 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6413 /* For simplicity assume that all writes can cause interrupts. */
6416 ctx
->bstate
= BS_STOP
;
6421 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6422 generate_exception(ctx
, EXCP_RI
);
6424 #endif /* TARGET_MIPS64 */
6426 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6427 int u
, int sel
, int h
)
6429 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6430 TCGv t0
= tcg_temp_local_new();
6432 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6433 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6434 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6435 tcg_gen_movi_tl(t0
, -1);
6436 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6437 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6438 tcg_gen_movi_tl(t0
, -1);
6444 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6447 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6457 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6460 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6463 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6466 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6469 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6472 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6475 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6478 gen_mfc0(ctx
, t0
, rt
, sel
);
6485 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6488 gen_mfc0(ctx
, t0
, rt
, sel
);
6494 gen_helper_mftc0_status(t0
, cpu_env
);
6497 gen_mfc0(ctx
, t0
, rt
, sel
);
6503 gen_helper_mftc0_cause(t0
, cpu_env
);
6513 gen_helper_mftc0_epc(t0
, cpu_env
);
6523 gen_helper_mftc0_ebase(t0
, cpu_env
);
6533 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6543 gen_helper_mftc0_debug(t0
, cpu_env
);
6546 gen_mfc0(ctx
, t0
, rt
, sel
);
6551 gen_mfc0(ctx
, t0
, rt
, sel
);
6553 } else switch (sel
) {
6554 /* GPR registers. */
6556 gen_helper_1e0i(mftgpr
, t0
, rt
);
6558 /* Auxiliary CPU registers */
6562 gen_helper_1e0i(mftlo
, t0
, 0);
6565 gen_helper_1e0i(mfthi
, t0
, 0);
6568 gen_helper_1e0i(mftacx
, t0
, 0);
6571 gen_helper_1e0i(mftlo
, t0
, 1);
6574 gen_helper_1e0i(mfthi
, t0
, 1);
6577 gen_helper_1e0i(mftacx
, t0
, 1);
6580 gen_helper_1e0i(mftlo
, t0
, 2);
6583 gen_helper_1e0i(mfthi
, t0
, 2);
6586 gen_helper_1e0i(mftacx
, t0
, 2);
6589 gen_helper_1e0i(mftlo
, t0
, 3);
6592 gen_helper_1e0i(mfthi
, t0
, 3);
6595 gen_helper_1e0i(mftacx
, t0
, 3);
6598 gen_helper_mftdsp(t0
, cpu_env
);
6604 /* Floating point (COP1). */
6606 /* XXX: For now we support only a single FPU context. */
6608 TCGv_i32 fp0
= tcg_temp_new_i32();
6610 gen_load_fpr32(fp0
, rt
);
6611 tcg_gen_ext_i32_tl(t0
, fp0
);
6612 tcg_temp_free_i32(fp0
);
6614 TCGv_i32 fp0
= tcg_temp_new_i32();
6616 gen_load_fpr32h(fp0
, rt
);
6617 tcg_gen_ext_i32_tl(t0
, fp0
);
6618 tcg_temp_free_i32(fp0
);
6622 /* XXX: For now we support only a single FPU context. */
6623 gen_helper_1e0i(cfc1
, t0
, rt
);
6625 /* COP2: Not implemented. */
6632 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6633 gen_store_gpr(t0
, rd
);
6639 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6640 generate_exception(ctx
, EXCP_RI
);
6643 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6644 int u
, int sel
, int h
)
6646 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6647 TCGv t0
= tcg_temp_local_new();
6649 gen_load_gpr(t0
, rt
);
6650 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6651 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6652 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6654 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6655 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6662 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6665 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6675 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6678 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6681 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6684 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6687 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6690 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6693 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6696 gen_mtc0(ctx
, t0
, rd
, sel
);
6703 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6706 gen_mtc0(ctx
, t0
, rd
, sel
);
6712 gen_helper_mttc0_status(cpu_env
, t0
);
6715 gen_mtc0(ctx
, t0
, rd
, sel
);
6721 gen_helper_mttc0_cause(cpu_env
, t0
);
6731 gen_helper_mttc0_ebase(cpu_env
, t0
);
6741 gen_helper_mttc0_debug(cpu_env
, t0
);
6744 gen_mtc0(ctx
, t0
, rd
, sel
);
6749 gen_mtc0(ctx
, t0
, rd
, sel
);
6751 } else switch (sel
) {
6752 /* GPR registers. */
6754 gen_helper_0e1i(mttgpr
, t0
, rd
);
6756 /* Auxiliary CPU registers */
6760 gen_helper_0e1i(mttlo
, t0
, 0);
6763 gen_helper_0e1i(mtthi
, t0
, 0);
6766 gen_helper_0e1i(mttacx
, t0
, 0);
6769 gen_helper_0e1i(mttlo
, t0
, 1);
6772 gen_helper_0e1i(mtthi
, t0
, 1);
6775 gen_helper_0e1i(mttacx
, t0
, 1);
6778 gen_helper_0e1i(mttlo
, t0
, 2);
6781 gen_helper_0e1i(mtthi
, t0
, 2);
6784 gen_helper_0e1i(mttacx
, t0
, 2);
6787 gen_helper_0e1i(mttlo
, t0
, 3);
6790 gen_helper_0e1i(mtthi
, t0
, 3);
6793 gen_helper_0e1i(mttacx
, t0
, 3);
6796 gen_helper_mttdsp(cpu_env
, t0
);
6802 /* Floating point (COP1). */
6804 /* XXX: For now we support only a single FPU context. */
6806 TCGv_i32 fp0
= tcg_temp_new_i32();
6808 tcg_gen_trunc_tl_i32(fp0
, t0
);
6809 gen_store_fpr32(fp0
, rd
);
6810 tcg_temp_free_i32(fp0
);
6812 TCGv_i32 fp0
= tcg_temp_new_i32();
6814 tcg_gen_trunc_tl_i32(fp0
, t0
);
6815 gen_store_fpr32h(fp0
, rd
);
6816 tcg_temp_free_i32(fp0
);
6820 /* XXX: For now we support only a single FPU context. */
6822 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
6824 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
6825 tcg_temp_free_i32(fs_tmp
);
6828 /* COP2: Not implemented. */
6835 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6841 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6842 generate_exception(ctx
, EXCP_RI
);
6845 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6847 const char *opn
= "ldst";
6849 check_cp0_enabled(ctx
);
6856 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6861 TCGv t0
= tcg_temp_new();
6863 gen_load_gpr(t0
, rt
);
6864 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6869 #if defined(TARGET_MIPS64)
6871 check_insn(ctx
, ISA_MIPS3
);
6876 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6880 check_insn(ctx
, ISA_MIPS3
);
6882 TCGv t0
= tcg_temp_new();
6884 gen_load_gpr(t0
, rt
);
6885 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6892 check_insn(ctx
, ASE_MT
);
6897 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6898 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6902 check_insn(ctx
, ASE_MT
);
6903 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6904 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6909 if (!env
->tlb
->helper_tlbwi
)
6911 gen_helper_tlbwi(cpu_env
);
6915 if (!env
->tlb
->helper_tlbwr
)
6917 gen_helper_tlbwr(cpu_env
);
6921 if (!env
->tlb
->helper_tlbp
)
6923 gen_helper_tlbp(cpu_env
);
6927 if (!env
->tlb
->helper_tlbr
)
6929 gen_helper_tlbr(cpu_env
);
6933 check_insn(ctx
, ISA_MIPS2
);
6934 gen_helper_eret(cpu_env
);
6935 ctx
->bstate
= BS_EXCP
;
6939 check_insn(ctx
, ISA_MIPS32
);
6940 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6942 generate_exception(ctx
, EXCP_RI
);
6944 gen_helper_deret(cpu_env
);
6945 ctx
->bstate
= BS_EXCP
;
6950 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
6951 /* If we get an exception, we want to restart at next instruction */
6953 save_cpu_state(ctx
, 1);
6955 gen_helper_wait(cpu_env
);
6956 ctx
->bstate
= BS_EXCP
;
6961 generate_exception(ctx
, EXCP_RI
);
6964 (void)opn
; /* avoid a compiler warning */
6965 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
6967 #endif /* !CONFIG_USER_ONLY */
6969 /* CP1 Branches (before delay slot) */
6970 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
6971 int32_t cc
, int32_t offset
)
6973 target_ulong btarget
;
6974 const char *opn
= "cp1 cond branch";
6975 TCGv_i32 t0
= tcg_temp_new_i32();
6978 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
6980 btarget
= ctx
->pc
+ 4 + offset
;
6984 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
6985 tcg_gen_not_i32(t0
, t0
);
6986 tcg_gen_andi_i32(t0
, t0
, 1);
6987 tcg_gen_extu_i32_tl(bcond
, t0
);
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_andi_i32(t0
, t0
, 1);
7000 tcg_gen_extu_i32_tl(bcond
, t0
);
7004 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7005 tcg_gen_andi_i32(t0
, t0
, 1);
7006 tcg_gen_extu_i32_tl(bcond
, t0
);
7009 ctx
->hflags
|= MIPS_HFLAG_BL
;
7013 TCGv_i32 t1
= tcg_temp_new_i32();
7014 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7015 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7016 tcg_gen_nand_i32(t0
, t0
, t1
);
7017 tcg_temp_free_i32(t1
);
7018 tcg_gen_andi_i32(t0
, t0
, 1);
7019 tcg_gen_extu_i32_tl(bcond
, t0
);
7025 TCGv_i32 t1
= tcg_temp_new_i32();
7026 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7027 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7028 tcg_gen_or_i32(t0
, t0
, t1
);
7029 tcg_temp_free_i32(t1
);
7030 tcg_gen_andi_i32(t0
, t0
, 1);
7031 tcg_gen_extu_i32_tl(bcond
, t0
);
7037 TCGv_i32 t1
= tcg_temp_new_i32();
7038 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7039 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7040 tcg_gen_and_i32(t0
, t0
, t1
);
7041 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7042 tcg_gen_and_i32(t0
, t0
, t1
);
7043 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7044 tcg_gen_nand_i32(t0
, t0
, t1
);
7045 tcg_temp_free_i32(t1
);
7046 tcg_gen_andi_i32(t0
, t0
, 1);
7047 tcg_gen_extu_i32_tl(bcond
, t0
);
7053 TCGv_i32 t1
= tcg_temp_new_i32();
7054 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7055 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7056 tcg_gen_or_i32(t0
, t0
, t1
);
7057 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7058 tcg_gen_or_i32(t0
, t0
, t1
);
7059 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7060 tcg_gen_or_i32(t0
, t0
, t1
);
7061 tcg_temp_free_i32(t1
);
7062 tcg_gen_andi_i32(t0
, t0
, 1);
7063 tcg_gen_extu_i32_tl(bcond
, t0
);
7067 ctx
->hflags
|= MIPS_HFLAG_BC
;
7071 generate_exception (ctx
, EXCP_RI
);
7074 (void)opn
; /* avoid a compiler warning */
7075 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7076 ctx
->hflags
, btarget
);
7077 ctx
->btarget
= btarget
;
7080 tcg_temp_free_i32(t0
);
7083 /* Coprocessor 1 (FPU) */
7085 #define FOP(func, fmt) (((fmt) << 21) | (func))
7088 OPC_ADD_S
= FOP(0, FMT_S
),
7089 OPC_SUB_S
= FOP(1, FMT_S
),
7090 OPC_MUL_S
= FOP(2, FMT_S
),
7091 OPC_DIV_S
= FOP(3, FMT_S
),
7092 OPC_SQRT_S
= FOP(4, FMT_S
),
7093 OPC_ABS_S
= FOP(5, FMT_S
),
7094 OPC_MOV_S
= FOP(6, FMT_S
),
7095 OPC_NEG_S
= FOP(7, FMT_S
),
7096 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7097 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7098 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7099 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7100 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7101 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7102 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7103 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7104 OPC_MOVCF_S
= FOP(17, FMT_S
),
7105 OPC_MOVZ_S
= FOP(18, FMT_S
),
7106 OPC_MOVN_S
= FOP(19, FMT_S
),
7107 OPC_RECIP_S
= FOP(21, FMT_S
),
7108 OPC_RSQRT_S
= FOP(22, FMT_S
),
7109 OPC_RECIP2_S
= FOP(28, FMT_S
),
7110 OPC_RECIP1_S
= FOP(29, FMT_S
),
7111 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7112 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7113 OPC_CVT_D_S
= FOP(33, FMT_S
),
7114 OPC_CVT_W_S
= FOP(36, FMT_S
),
7115 OPC_CVT_L_S
= FOP(37, FMT_S
),
7116 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7117 OPC_CMP_F_S
= FOP (48, FMT_S
),
7118 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7119 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7120 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7121 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7122 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7123 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7124 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7125 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7126 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7127 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7128 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7129 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7130 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7131 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7132 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7134 OPC_ADD_D
= FOP(0, FMT_D
),
7135 OPC_SUB_D
= FOP(1, FMT_D
),
7136 OPC_MUL_D
= FOP(2, FMT_D
),
7137 OPC_DIV_D
= FOP(3, FMT_D
),
7138 OPC_SQRT_D
= FOP(4, FMT_D
),
7139 OPC_ABS_D
= FOP(5, FMT_D
),
7140 OPC_MOV_D
= FOP(6, FMT_D
),
7141 OPC_NEG_D
= FOP(7, FMT_D
),
7142 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7143 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7144 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7145 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7146 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7147 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7148 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7149 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7150 OPC_MOVCF_D
= FOP(17, FMT_D
),
7151 OPC_MOVZ_D
= FOP(18, FMT_D
),
7152 OPC_MOVN_D
= FOP(19, FMT_D
),
7153 OPC_RECIP_D
= FOP(21, FMT_D
),
7154 OPC_RSQRT_D
= FOP(22, FMT_D
),
7155 OPC_RECIP2_D
= FOP(28, FMT_D
),
7156 OPC_RECIP1_D
= FOP(29, FMT_D
),
7157 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7158 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7159 OPC_CVT_S_D
= FOP(32, FMT_D
),
7160 OPC_CVT_W_D
= FOP(36, FMT_D
),
7161 OPC_CVT_L_D
= FOP(37, FMT_D
),
7162 OPC_CMP_F_D
= FOP (48, FMT_D
),
7163 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7164 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7165 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7166 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7167 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7168 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7169 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7170 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7171 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7172 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7173 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7174 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7175 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7176 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7177 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7179 OPC_CVT_S_W
= FOP(32, FMT_W
),
7180 OPC_CVT_D_W
= FOP(33, FMT_W
),
7181 OPC_CVT_S_L
= FOP(32, FMT_L
),
7182 OPC_CVT_D_L
= FOP(33, FMT_L
),
7183 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7185 OPC_ADD_PS
= FOP(0, FMT_PS
),
7186 OPC_SUB_PS
= FOP(1, FMT_PS
),
7187 OPC_MUL_PS
= FOP(2, FMT_PS
),
7188 OPC_DIV_PS
= FOP(3, FMT_PS
),
7189 OPC_ABS_PS
= FOP(5, FMT_PS
),
7190 OPC_MOV_PS
= FOP(6, FMT_PS
),
7191 OPC_NEG_PS
= FOP(7, FMT_PS
),
7192 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7193 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7194 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7195 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7196 OPC_MULR_PS
= FOP(26, FMT_PS
),
7197 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7198 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7199 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7200 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7202 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7203 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7204 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7205 OPC_PLL_PS
= FOP(44, FMT_PS
),
7206 OPC_PLU_PS
= FOP(45, FMT_PS
),
7207 OPC_PUL_PS
= FOP(46, FMT_PS
),
7208 OPC_PUU_PS
= FOP(47, FMT_PS
),
7209 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7210 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7211 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7212 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7213 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7214 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7215 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7216 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7217 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7218 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7219 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7220 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7221 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7222 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7223 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7224 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7227 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7229 const char *opn
= "cp1 move";
7230 TCGv t0
= tcg_temp_new();
7235 TCGv_i32 fp0
= tcg_temp_new_i32();
7237 gen_load_fpr32(fp0
, fs
);
7238 tcg_gen_ext_i32_tl(t0
, fp0
);
7239 tcg_temp_free_i32(fp0
);
7241 gen_store_gpr(t0
, rt
);
7245 gen_load_gpr(t0
, rt
);
7247 TCGv_i32 fp0
= tcg_temp_new_i32();
7249 tcg_gen_trunc_tl_i32(fp0
, t0
);
7250 gen_store_fpr32(fp0
, fs
);
7251 tcg_temp_free_i32(fp0
);
7256 gen_helper_1e0i(cfc1
, t0
, fs
);
7257 gen_store_gpr(t0
, rt
);
7261 gen_load_gpr(t0
, rt
);
7263 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
7265 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7266 tcg_temp_free_i32(fs_tmp
);
7270 #if defined(TARGET_MIPS64)
7272 gen_load_fpr64(ctx
, t0
, fs
);
7273 gen_store_gpr(t0
, rt
);
7277 gen_load_gpr(t0
, rt
);
7278 gen_store_fpr64(ctx
, t0
, fs
);
7284 TCGv_i32 fp0
= tcg_temp_new_i32();
7286 gen_load_fpr32h(fp0
, fs
);
7287 tcg_gen_ext_i32_tl(t0
, fp0
);
7288 tcg_temp_free_i32(fp0
);
7290 gen_store_gpr(t0
, rt
);
7294 gen_load_gpr(t0
, rt
);
7296 TCGv_i32 fp0
= tcg_temp_new_i32();
7298 tcg_gen_trunc_tl_i32(fp0
, t0
);
7299 gen_store_fpr32h(fp0
, fs
);
7300 tcg_temp_free_i32(fp0
);
7306 generate_exception (ctx
, EXCP_RI
);
7309 (void)opn
; /* avoid a compiler warning */
7310 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7316 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7332 l1
= gen_new_label();
7333 t0
= tcg_temp_new_i32();
7334 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7335 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7336 tcg_temp_free_i32(t0
);
7338 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7340 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7345 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7348 TCGv_i32 t0
= tcg_temp_new_i32();
7349 int l1
= gen_new_label();
7356 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7357 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7358 gen_load_fpr32(t0
, fs
);
7359 gen_store_fpr32(t0
, fd
);
7361 tcg_temp_free_i32(t0
);
7364 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7367 TCGv_i32 t0
= tcg_temp_new_i32();
7369 int l1
= gen_new_label();
7376 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7377 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7378 tcg_temp_free_i32(t0
);
7379 fp0
= tcg_temp_new_i64();
7380 gen_load_fpr64(ctx
, fp0
, fs
);
7381 gen_store_fpr64(ctx
, fp0
, fd
);
7382 tcg_temp_free_i64(fp0
);
7386 static inline void gen_movcf_ps (int fs
, int fd
, int cc
, int tf
)
7389 TCGv_i32 t0
= tcg_temp_new_i32();
7390 int l1
= gen_new_label();
7391 int l2
= gen_new_label();
7398 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7399 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7400 gen_load_fpr32(t0
, fs
);
7401 gen_store_fpr32(t0
, fd
);
7404 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7405 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7406 gen_load_fpr32h(t0
, fs
);
7407 gen_store_fpr32h(t0
, fd
);
7408 tcg_temp_free_i32(t0
);
7413 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7414 int ft
, int fs
, int fd
, int cc
)
7416 const char *opn
= "farith";
7417 const char *condnames
[] = {
7435 const char *condnames_abs
[] = {
7453 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7454 uint32_t func
= ctx
->opcode
& 0x3f;
7459 TCGv_i32 fp0
= tcg_temp_new_i32();
7460 TCGv_i32 fp1
= tcg_temp_new_i32();
7462 gen_load_fpr32(fp0
, fs
);
7463 gen_load_fpr32(fp1
, ft
);
7464 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7465 tcg_temp_free_i32(fp1
);
7466 gen_store_fpr32(fp0
, fd
);
7467 tcg_temp_free_i32(fp0
);
7474 TCGv_i32 fp0
= tcg_temp_new_i32();
7475 TCGv_i32 fp1
= tcg_temp_new_i32();
7477 gen_load_fpr32(fp0
, fs
);
7478 gen_load_fpr32(fp1
, ft
);
7479 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7480 tcg_temp_free_i32(fp1
);
7481 gen_store_fpr32(fp0
, fd
);
7482 tcg_temp_free_i32(fp0
);
7489 TCGv_i32 fp0
= tcg_temp_new_i32();
7490 TCGv_i32 fp1
= tcg_temp_new_i32();
7492 gen_load_fpr32(fp0
, fs
);
7493 gen_load_fpr32(fp1
, ft
);
7494 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7495 tcg_temp_free_i32(fp1
);
7496 gen_store_fpr32(fp0
, fd
);
7497 tcg_temp_free_i32(fp0
);
7504 TCGv_i32 fp0
= tcg_temp_new_i32();
7505 TCGv_i32 fp1
= tcg_temp_new_i32();
7507 gen_load_fpr32(fp0
, fs
);
7508 gen_load_fpr32(fp1
, ft
);
7509 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7510 tcg_temp_free_i32(fp1
);
7511 gen_store_fpr32(fp0
, fd
);
7512 tcg_temp_free_i32(fp0
);
7519 TCGv_i32 fp0
= tcg_temp_new_i32();
7521 gen_load_fpr32(fp0
, fs
);
7522 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7523 gen_store_fpr32(fp0
, fd
);
7524 tcg_temp_free_i32(fp0
);
7530 TCGv_i32 fp0
= tcg_temp_new_i32();
7532 gen_load_fpr32(fp0
, fs
);
7533 gen_helper_float_abs_s(fp0
, fp0
);
7534 gen_store_fpr32(fp0
, fd
);
7535 tcg_temp_free_i32(fp0
);
7541 TCGv_i32 fp0
= tcg_temp_new_i32();
7543 gen_load_fpr32(fp0
, fs
);
7544 gen_store_fpr32(fp0
, fd
);
7545 tcg_temp_free_i32(fp0
);
7551 TCGv_i32 fp0
= tcg_temp_new_i32();
7553 gen_load_fpr32(fp0
, fs
);
7554 gen_helper_float_chs_s(fp0
, fp0
);
7555 gen_store_fpr32(fp0
, fd
);
7556 tcg_temp_free_i32(fp0
);
7561 check_cp1_64bitmode(ctx
);
7563 TCGv_i32 fp32
= tcg_temp_new_i32();
7564 TCGv_i64 fp64
= tcg_temp_new_i64();
7566 gen_load_fpr32(fp32
, fs
);
7567 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7568 tcg_temp_free_i32(fp32
);
7569 gen_store_fpr64(ctx
, fp64
, fd
);
7570 tcg_temp_free_i64(fp64
);
7575 check_cp1_64bitmode(ctx
);
7577 TCGv_i32 fp32
= tcg_temp_new_i32();
7578 TCGv_i64 fp64
= tcg_temp_new_i64();
7580 gen_load_fpr32(fp32
, fs
);
7581 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7582 tcg_temp_free_i32(fp32
);
7583 gen_store_fpr64(ctx
, fp64
, fd
);
7584 tcg_temp_free_i64(fp64
);
7589 check_cp1_64bitmode(ctx
);
7591 TCGv_i32 fp32
= tcg_temp_new_i32();
7592 TCGv_i64 fp64
= tcg_temp_new_i64();
7594 gen_load_fpr32(fp32
, fs
);
7595 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7596 tcg_temp_free_i32(fp32
);
7597 gen_store_fpr64(ctx
, fp64
, fd
);
7598 tcg_temp_free_i64(fp64
);
7603 check_cp1_64bitmode(ctx
);
7605 TCGv_i32 fp32
= tcg_temp_new_i32();
7606 TCGv_i64 fp64
= tcg_temp_new_i64();
7608 gen_load_fpr32(fp32
, fs
);
7609 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7610 tcg_temp_free_i32(fp32
);
7611 gen_store_fpr64(ctx
, fp64
, fd
);
7612 tcg_temp_free_i64(fp64
);
7618 TCGv_i32 fp0
= tcg_temp_new_i32();
7620 gen_load_fpr32(fp0
, fs
);
7621 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7622 gen_store_fpr32(fp0
, fd
);
7623 tcg_temp_free_i32(fp0
);
7629 TCGv_i32 fp0
= tcg_temp_new_i32();
7631 gen_load_fpr32(fp0
, fs
);
7632 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7633 gen_store_fpr32(fp0
, fd
);
7634 tcg_temp_free_i32(fp0
);
7640 TCGv_i32 fp0
= tcg_temp_new_i32();
7642 gen_load_fpr32(fp0
, fs
);
7643 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7644 gen_store_fpr32(fp0
, fd
);
7645 tcg_temp_free_i32(fp0
);
7651 TCGv_i32 fp0
= tcg_temp_new_i32();
7653 gen_load_fpr32(fp0
, fs
);
7654 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7655 gen_store_fpr32(fp0
, fd
);
7656 tcg_temp_free_i32(fp0
);
7661 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7666 int l1
= gen_new_label();
7670 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7672 fp0
= tcg_temp_new_i32();
7673 gen_load_fpr32(fp0
, fs
);
7674 gen_store_fpr32(fp0
, fd
);
7675 tcg_temp_free_i32(fp0
);
7682 int l1
= gen_new_label();
7686 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7687 fp0
= tcg_temp_new_i32();
7688 gen_load_fpr32(fp0
, fs
);
7689 gen_store_fpr32(fp0
, fd
);
7690 tcg_temp_free_i32(fp0
);
7699 TCGv_i32 fp0
= tcg_temp_new_i32();
7701 gen_load_fpr32(fp0
, fs
);
7702 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7703 gen_store_fpr32(fp0
, fd
);
7704 tcg_temp_free_i32(fp0
);
7711 TCGv_i32 fp0
= tcg_temp_new_i32();
7713 gen_load_fpr32(fp0
, fs
);
7714 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7715 gen_store_fpr32(fp0
, fd
);
7716 tcg_temp_free_i32(fp0
);
7721 check_cp1_64bitmode(ctx
);
7723 TCGv_i32 fp0
= tcg_temp_new_i32();
7724 TCGv_i32 fp1
= tcg_temp_new_i32();
7726 gen_load_fpr32(fp0
, fs
);
7727 gen_load_fpr32(fp1
, ft
);
7728 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7729 tcg_temp_free_i32(fp1
);
7730 gen_store_fpr32(fp0
, fd
);
7731 tcg_temp_free_i32(fp0
);
7736 check_cp1_64bitmode(ctx
);
7738 TCGv_i32 fp0
= tcg_temp_new_i32();
7740 gen_load_fpr32(fp0
, fs
);
7741 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7742 gen_store_fpr32(fp0
, fd
);
7743 tcg_temp_free_i32(fp0
);
7748 check_cp1_64bitmode(ctx
);
7750 TCGv_i32 fp0
= tcg_temp_new_i32();
7752 gen_load_fpr32(fp0
, fs
);
7753 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7754 gen_store_fpr32(fp0
, fd
);
7755 tcg_temp_free_i32(fp0
);
7760 check_cp1_64bitmode(ctx
);
7762 TCGv_i32 fp0
= tcg_temp_new_i32();
7763 TCGv_i32 fp1
= tcg_temp_new_i32();
7765 gen_load_fpr32(fp0
, fs
);
7766 gen_load_fpr32(fp1
, ft
);
7767 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7768 tcg_temp_free_i32(fp1
);
7769 gen_store_fpr32(fp0
, fd
);
7770 tcg_temp_free_i32(fp0
);
7775 check_cp1_registers(ctx
, fd
);
7777 TCGv_i32 fp32
= tcg_temp_new_i32();
7778 TCGv_i64 fp64
= tcg_temp_new_i64();
7780 gen_load_fpr32(fp32
, fs
);
7781 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7782 tcg_temp_free_i32(fp32
);
7783 gen_store_fpr64(ctx
, fp64
, fd
);
7784 tcg_temp_free_i64(fp64
);
7790 TCGv_i32 fp0
= tcg_temp_new_i32();
7792 gen_load_fpr32(fp0
, fs
);
7793 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7794 gen_store_fpr32(fp0
, fd
);
7795 tcg_temp_free_i32(fp0
);
7800 check_cp1_64bitmode(ctx
);
7802 TCGv_i32 fp32
= tcg_temp_new_i32();
7803 TCGv_i64 fp64
= tcg_temp_new_i64();
7805 gen_load_fpr32(fp32
, fs
);
7806 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7807 tcg_temp_free_i32(fp32
);
7808 gen_store_fpr64(ctx
, fp64
, fd
);
7809 tcg_temp_free_i64(fp64
);
7814 check_cp1_64bitmode(ctx
);
7816 TCGv_i64 fp64
= tcg_temp_new_i64();
7817 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7818 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7820 gen_load_fpr32(fp32_0
, fs
);
7821 gen_load_fpr32(fp32_1
, ft
);
7822 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7823 tcg_temp_free_i32(fp32_1
);
7824 tcg_temp_free_i32(fp32_0
);
7825 gen_store_fpr64(ctx
, fp64
, fd
);
7826 tcg_temp_free_i64(fp64
);
7839 case OPC_CMP_NGLE_S
:
7846 if (ctx
->opcode
& (1 << 6)) {
7847 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7848 opn
= condnames_abs
[func
-48];
7850 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7851 opn
= condnames
[func
-48];
7855 check_cp1_registers(ctx
, fs
| ft
| fd
);
7857 TCGv_i64 fp0
= tcg_temp_new_i64();
7858 TCGv_i64 fp1
= tcg_temp_new_i64();
7860 gen_load_fpr64(ctx
, fp0
, fs
);
7861 gen_load_fpr64(ctx
, fp1
, ft
);
7862 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7863 tcg_temp_free_i64(fp1
);
7864 gen_store_fpr64(ctx
, fp0
, fd
);
7865 tcg_temp_free_i64(fp0
);
7871 check_cp1_registers(ctx
, fs
| ft
| fd
);
7873 TCGv_i64 fp0
= tcg_temp_new_i64();
7874 TCGv_i64 fp1
= tcg_temp_new_i64();
7876 gen_load_fpr64(ctx
, fp0
, fs
);
7877 gen_load_fpr64(ctx
, fp1
, ft
);
7878 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7879 tcg_temp_free_i64(fp1
);
7880 gen_store_fpr64(ctx
, fp0
, fd
);
7881 tcg_temp_free_i64(fp0
);
7887 check_cp1_registers(ctx
, fs
| ft
| fd
);
7889 TCGv_i64 fp0
= tcg_temp_new_i64();
7890 TCGv_i64 fp1
= tcg_temp_new_i64();
7892 gen_load_fpr64(ctx
, fp0
, fs
);
7893 gen_load_fpr64(ctx
, fp1
, ft
);
7894 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7895 tcg_temp_free_i64(fp1
);
7896 gen_store_fpr64(ctx
, fp0
, fd
);
7897 tcg_temp_free_i64(fp0
);
7903 check_cp1_registers(ctx
, fs
| ft
| fd
);
7905 TCGv_i64 fp0
= tcg_temp_new_i64();
7906 TCGv_i64 fp1
= tcg_temp_new_i64();
7908 gen_load_fpr64(ctx
, fp0
, fs
);
7909 gen_load_fpr64(ctx
, fp1
, ft
);
7910 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7911 tcg_temp_free_i64(fp1
);
7912 gen_store_fpr64(ctx
, fp0
, fd
);
7913 tcg_temp_free_i64(fp0
);
7919 check_cp1_registers(ctx
, fs
| fd
);
7921 TCGv_i64 fp0
= tcg_temp_new_i64();
7923 gen_load_fpr64(ctx
, fp0
, fs
);
7924 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7925 gen_store_fpr64(ctx
, fp0
, fd
);
7926 tcg_temp_free_i64(fp0
);
7931 check_cp1_registers(ctx
, fs
| fd
);
7933 TCGv_i64 fp0
= tcg_temp_new_i64();
7935 gen_load_fpr64(ctx
, fp0
, fs
);
7936 gen_helper_float_abs_d(fp0
, fp0
);
7937 gen_store_fpr64(ctx
, fp0
, fd
);
7938 tcg_temp_free_i64(fp0
);
7943 check_cp1_registers(ctx
, fs
| fd
);
7945 TCGv_i64 fp0
= tcg_temp_new_i64();
7947 gen_load_fpr64(ctx
, fp0
, fs
);
7948 gen_store_fpr64(ctx
, fp0
, fd
);
7949 tcg_temp_free_i64(fp0
);
7954 check_cp1_registers(ctx
, fs
| fd
);
7956 TCGv_i64 fp0
= tcg_temp_new_i64();
7958 gen_load_fpr64(ctx
, fp0
, fs
);
7959 gen_helper_float_chs_d(fp0
, fp0
);
7960 gen_store_fpr64(ctx
, fp0
, fd
);
7961 tcg_temp_free_i64(fp0
);
7966 check_cp1_64bitmode(ctx
);
7968 TCGv_i64 fp0
= tcg_temp_new_i64();
7970 gen_load_fpr64(ctx
, fp0
, fs
);
7971 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
7972 gen_store_fpr64(ctx
, fp0
, fd
);
7973 tcg_temp_free_i64(fp0
);
7978 check_cp1_64bitmode(ctx
);
7980 TCGv_i64 fp0
= tcg_temp_new_i64();
7982 gen_load_fpr64(ctx
, fp0
, fs
);
7983 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
7984 gen_store_fpr64(ctx
, fp0
, fd
);
7985 tcg_temp_free_i64(fp0
);
7990 check_cp1_64bitmode(ctx
);
7992 TCGv_i64 fp0
= tcg_temp_new_i64();
7994 gen_load_fpr64(ctx
, fp0
, fs
);
7995 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
7996 gen_store_fpr64(ctx
, fp0
, fd
);
7997 tcg_temp_free_i64(fp0
);
8002 check_cp1_64bitmode(ctx
);
8004 TCGv_i64 fp0
= tcg_temp_new_i64();
8006 gen_load_fpr64(ctx
, fp0
, fs
);
8007 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8008 gen_store_fpr64(ctx
, fp0
, fd
);
8009 tcg_temp_free_i64(fp0
);
8014 check_cp1_registers(ctx
, fs
);
8016 TCGv_i32 fp32
= tcg_temp_new_i32();
8017 TCGv_i64 fp64
= tcg_temp_new_i64();
8019 gen_load_fpr64(ctx
, fp64
, fs
);
8020 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8021 tcg_temp_free_i64(fp64
);
8022 gen_store_fpr32(fp32
, fd
);
8023 tcg_temp_free_i32(fp32
);
8028 check_cp1_registers(ctx
, fs
);
8030 TCGv_i32 fp32
= tcg_temp_new_i32();
8031 TCGv_i64 fp64
= tcg_temp_new_i64();
8033 gen_load_fpr64(ctx
, fp64
, fs
);
8034 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8035 tcg_temp_free_i64(fp64
);
8036 gen_store_fpr32(fp32
, fd
);
8037 tcg_temp_free_i32(fp32
);
8042 check_cp1_registers(ctx
, fs
);
8044 TCGv_i32 fp32
= tcg_temp_new_i32();
8045 TCGv_i64 fp64
= tcg_temp_new_i64();
8047 gen_load_fpr64(ctx
, fp64
, fs
);
8048 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8049 tcg_temp_free_i64(fp64
);
8050 gen_store_fpr32(fp32
, fd
);
8051 tcg_temp_free_i32(fp32
);
8056 check_cp1_registers(ctx
, fs
);
8058 TCGv_i32 fp32
= tcg_temp_new_i32();
8059 TCGv_i64 fp64
= tcg_temp_new_i64();
8061 gen_load_fpr64(ctx
, fp64
, fs
);
8062 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8063 tcg_temp_free_i64(fp64
);
8064 gen_store_fpr32(fp32
, fd
);
8065 tcg_temp_free_i32(fp32
);
8070 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8075 int l1
= gen_new_label();
8079 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8081 fp0
= tcg_temp_new_i64();
8082 gen_load_fpr64(ctx
, fp0
, fs
);
8083 gen_store_fpr64(ctx
, fp0
, fd
);
8084 tcg_temp_free_i64(fp0
);
8091 int l1
= gen_new_label();
8095 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8096 fp0
= tcg_temp_new_i64();
8097 gen_load_fpr64(ctx
, fp0
, fs
);
8098 gen_store_fpr64(ctx
, fp0
, fd
);
8099 tcg_temp_free_i64(fp0
);
8106 check_cp1_64bitmode(ctx
);
8108 TCGv_i64 fp0
= tcg_temp_new_i64();
8110 gen_load_fpr64(ctx
, fp0
, fs
);
8111 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8112 gen_store_fpr64(ctx
, fp0
, fd
);
8113 tcg_temp_free_i64(fp0
);
8118 check_cp1_64bitmode(ctx
);
8120 TCGv_i64 fp0
= tcg_temp_new_i64();
8122 gen_load_fpr64(ctx
, fp0
, fs
);
8123 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8124 gen_store_fpr64(ctx
, fp0
, fd
);
8125 tcg_temp_free_i64(fp0
);
8130 check_cp1_64bitmode(ctx
);
8132 TCGv_i64 fp0
= tcg_temp_new_i64();
8133 TCGv_i64 fp1
= tcg_temp_new_i64();
8135 gen_load_fpr64(ctx
, fp0
, fs
);
8136 gen_load_fpr64(ctx
, fp1
, ft
);
8137 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8138 tcg_temp_free_i64(fp1
);
8139 gen_store_fpr64(ctx
, fp0
, fd
);
8140 tcg_temp_free_i64(fp0
);
8145 check_cp1_64bitmode(ctx
);
8147 TCGv_i64 fp0
= tcg_temp_new_i64();
8149 gen_load_fpr64(ctx
, fp0
, fs
);
8150 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8151 gen_store_fpr64(ctx
, fp0
, fd
);
8152 tcg_temp_free_i64(fp0
);
8157 check_cp1_64bitmode(ctx
);
8159 TCGv_i64 fp0
= tcg_temp_new_i64();
8161 gen_load_fpr64(ctx
, fp0
, fs
);
8162 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8163 gen_store_fpr64(ctx
, fp0
, fd
);
8164 tcg_temp_free_i64(fp0
);
8169 check_cp1_64bitmode(ctx
);
8171 TCGv_i64 fp0
= tcg_temp_new_i64();
8172 TCGv_i64 fp1
= tcg_temp_new_i64();
8174 gen_load_fpr64(ctx
, fp0
, fs
);
8175 gen_load_fpr64(ctx
, fp1
, ft
);
8176 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8177 tcg_temp_free_i64(fp1
);
8178 gen_store_fpr64(ctx
, fp0
, fd
);
8179 tcg_temp_free_i64(fp0
);
8192 case OPC_CMP_NGLE_D
:
8199 if (ctx
->opcode
& (1 << 6)) {
8200 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8201 opn
= condnames_abs
[func
-48];
8203 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8204 opn
= condnames
[func
-48];
8208 check_cp1_registers(ctx
, fs
);
8210 TCGv_i32 fp32
= tcg_temp_new_i32();
8211 TCGv_i64 fp64
= tcg_temp_new_i64();
8213 gen_load_fpr64(ctx
, fp64
, fs
);
8214 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8215 tcg_temp_free_i64(fp64
);
8216 gen_store_fpr32(fp32
, fd
);
8217 tcg_temp_free_i32(fp32
);
8222 check_cp1_registers(ctx
, fs
);
8224 TCGv_i32 fp32
= tcg_temp_new_i32();
8225 TCGv_i64 fp64
= tcg_temp_new_i64();
8227 gen_load_fpr64(ctx
, fp64
, fs
);
8228 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8229 tcg_temp_free_i64(fp64
);
8230 gen_store_fpr32(fp32
, fd
);
8231 tcg_temp_free_i32(fp32
);
8236 check_cp1_64bitmode(ctx
);
8238 TCGv_i64 fp0
= tcg_temp_new_i64();
8240 gen_load_fpr64(ctx
, fp0
, fs
);
8241 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8242 gen_store_fpr64(ctx
, fp0
, fd
);
8243 tcg_temp_free_i64(fp0
);
8249 TCGv_i32 fp0
= tcg_temp_new_i32();
8251 gen_load_fpr32(fp0
, fs
);
8252 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8253 gen_store_fpr32(fp0
, fd
);
8254 tcg_temp_free_i32(fp0
);
8259 check_cp1_registers(ctx
, fd
);
8261 TCGv_i32 fp32
= tcg_temp_new_i32();
8262 TCGv_i64 fp64
= tcg_temp_new_i64();
8264 gen_load_fpr32(fp32
, fs
);
8265 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8266 tcg_temp_free_i32(fp32
);
8267 gen_store_fpr64(ctx
, fp64
, fd
);
8268 tcg_temp_free_i64(fp64
);
8273 check_cp1_64bitmode(ctx
);
8275 TCGv_i32 fp32
= tcg_temp_new_i32();
8276 TCGv_i64 fp64
= tcg_temp_new_i64();
8278 gen_load_fpr64(ctx
, fp64
, fs
);
8279 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8280 tcg_temp_free_i64(fp64
);
8281 gen_store_fpr32(fp32
, fd
);
8282 tcg_temp_free_i32(fp32
);
8287 check_cp1_64bitmode(ctx
);
8289 TCGv_i64 fp0
= tcg_temp_new_i64();
8291 gen_load_fpr64(ctx
, fp0
, fs
);
8292 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8293 gen_store_fpr64(ctx
, fp0
, fd
);
8294 tcg_temp_free_i64(fp0
);
8299 check_cp1_64bitmode(ctx
);
8301 TCGv_i64 fp0
= tcg_temp_new_i64();
8303 gen_load_fpr64(ctx
, fp0
, fs
);
8304 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8305 gen_store_fpr64(ctx
, fp0
, fd
);
8306 tcg_temp_free_i64(fp0
);
8311 check_cp1_64bitmode(ctx
);
8313 TCGv_i64 fp0
= tcg_temp_new_i64();
8314 TCGv_i64 fp1
= tcg_temp_new_i64();
8316 gen_load_fpr64(ctx
, fp0
, fs
);
8317 gen_load_fpr64(ctx
, fp1
, ft
);
8318 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8319 tcg_temp_free_i64(fp1
);
8320 gen_store_fpr64(ctx
, fp0
, fd
);
8321 tcg_temp_free_i64(fp0
);
8326 check_cp1_64bitmode(ctx
);
8328 TCGv_i64 fp0
= tcg_temp_new_i64();
8329 TCGv_i64 fp1
= tcg_temp_new_i64();
8331 gen_load_fpr64(ctx
, fp0
, fs
);
8332 gen_load_fpr64(ctx
, fp1
, ft
);
8333 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8334 tcg_temp_free_i64(fp1
);
8335 gen_store_fpr64(ctx
, fp0
, fd
);
8336 tcg_temp_free_i64(fp0
);
8341 check_cp1_64bitmode(ctx
);
8343 TCGv_i64 fp0
= tcg_temp_new_i64();
8344 TCGv_i64 fp1
= tcg_temp_new_i64();
8346 gen_load_fpr64(ctx
, fp0
, fs
);
8347 gen_load_fpr64(ctx
, fp1
, ft
);
8348 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8349 tcg_temp_free_i64(fp1
);
8350 gen_store_fpr64(ctx
, fp0
, fd
);
8351 tcg_temp_free_i64(fp0
);
8356 check_cp1_64bitmode(ctx
);
8358 TCGv_i64 fp0
= tcg_temp_new_i64();
8360 gen_load_fpr64(ctx
, fp0
, fs
);
8361 gen_helper_float_abs_ps(fp0
, fp0
);
8362 gen_store_fpr64(ctx
, fp0
, fd
);
8363 tcg_temp_free_i64(fp0
);
8368 check_cp1_64bitmode(ctx
);
8370 TCGv_i64 fp0
= tcg_temp_new_i64();
8372 gen_load_fpr64(ctx
, fp0
, fs
);
8373 gen_store_fpr64(ctx
, fp0
, fd
);
8374 tcg_temp_free_i64(fp0
);
8379 check_cp1_64bitmode(ctx
);
8381 TCGv_i64 fp0
= tcg_temp_new_i64();
8383 gen_load_fpr64(ctx
, fp0
, fs
);
8384 gen_helper_float_chs_ps(fp0
, fp0
);
8385 gen_store_fpr64(ctx
, fp0
, fd
);
8386 tcg_temp_free_i64(fp0
);
8391 check_cp1_64bitmode(ctx
);
8392 gen_movcf_ps(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8396 check_cp1_64bitmode(ctx
);
8398 int l1
= gen_new_label();
8402 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8403 fp0
= tcg_temp_new_i64();
8404 gen_load_fpr64(ctx
, fp0
, fs
);
8405 gen_store_fpr64(ctx
, fp0
, fd
);
8406 tcg_temp_free_i64(fp0
);
8412 check_cp1_64bitmode(ctx
);
8414 int l1
= gen_new_label();
8418 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8419 fp0
= tcg_temp_new_i64();
8420 gen_load_fpr64(ctx
, fp0
, fs
);
8421 gen_store_fpr64(ctx
, fp0
, fd
);
8422 tcg_temp_free_i64(fp0
);
8429 check_cp1_64bitmode(ctx
);
8431 TCGv_i64 fp0
= tcg_temp_new_i64();
8432 TCGv_i64 fp1
= tcg_temp_new_i64();
8434 gen_load_fpr64(ctx
, fp0
, ft
);
8435 gen_load_fpr64(ctx
, fp1
, fs
);
8436 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8437 tcg_temp_free_i64(fp1
);
8438 gen_store_fpr64(ctx
, fp0
, fd
);
8439 tcg_temp_free_i64(fp0
);
8444 check_cp1_64bitmode(ctx
);
8446 TCGv_i64 fp0
= tcg_temp_new_i64();
8447 TCGv_i64 fp1
= tcg_temp_new_i64();
8449 gen_load_fpr64(ctx
, fp0
, ft
);
8450 gen_load_fpr64(ctx
, fp1
, fs
);
8451 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8452 tcg_temp_free_i64(fp1
);
8453 gen_store_fpr64(ctx
, fp0
, fd
);
8454 tcg_temp_free_i64(fp0
);
8459 check_cp1_64bitmode(ctx
);
8461 TCGv_i64 fp0
= tcg_temp_new_i64();
8462 TCGv_i64 fp1
= tcg_temp_new_i64();
8464 gen_load_fpr64(ctx
, fp0
, fs
);
8465 gen_load_fpr64(ctx
, fp1
, ft
);
8466 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8467 tcg_temp_free_i64(fp1
);
8468 gen_store_fpr64(ctx
, fp0
, fd
);
8469 tcg_temp_free_i64(fp0
);
8474 check_cp1_64bitmode(ctx
);
8476 TCGv_i64 fp0
= tcg_temp_new_i64();
8478 gen_load_fpr64(ctx
, fp0
, fs
);
8479 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
8480 gen_store_fpr64(ctx
, fp0
, fd
);
8481 tcg_temp_free_i64(fp0
);
8486 check_cp1_64bitmode(ctx
);
8488 TCGv_i64 fp0
= tcg_temp_new_i64();
8490 gen_load_fpr64(ctx
, fp0
, fs
);
8491 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8492 gen_store_fpr64(ctx
, fp0
, fd
);
8493 tcg_temp_free_i64(fp0
);
8498 check_cp1_64bitmode(ctx
);
8500 TCGv_i64 fp0
= tcg_temp_new_i64();
8501 TCGv_i64 fp1
= tcg_temp_new_i64();
8503 gen_load_fpr64(ctx
, fp0
, fs
);
8504 gen_load_fpr64(ctx
, fp1
, ft
);
8505 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8506 tcg_temp_free_i64(fp1
);
8507 gen_store_fpr64(ctx
, fp0
, fd
);
8508 tcg_temp_free_i64(fp0
);
8513 check_cp1_64bitmode(ctx
);
8515 TCGv_i32 fp0
= tcg_temp_new_i32();
8517 gen_load_fpr32h(fp0
, fs
);
8518 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8519 gen_store_fpr32(fp0
, fd
);
8520 tcg_temp_free_i32(fp0
);
8525 check_cp1_64bitmode(ctx
);
8527 TCGv_i64 fp0
= tcg_temp_new_i64();
8529 gen_load_fpr64(ctx
, fp0
, fs
);
8530 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8531 gen_store_fpr64(ctx
, fp0
, fd
);
8532 tcg_temp_free_i64(fp0
);
8537 check_cp1_64bitmode(ctx
);
8539 TCGv_i32 fp0
= tcg_temp_new_i32();
8541 gen_load_fpr32(fp0
, fs
);
8542 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8543 gen_store_fpr32(fp0
, fd
);
8544 tcg_temp_free_i32(fp0
);
8549 check_cp1_64bitmode(ctx
);
8551 TCGv_i32 fp0
= tcg_temp_new_i32();
8552 TCGv_i32 fp1
= tcg_temp_new_i32();
8554 gen_load_fpr32(fp0
, fs
);
8555 gen_load_fpr32(fp1
, ft
);
8556 gen_store_fpr32h(fp0
, fd
);
8557 gen_store_fpr32(fp1
, fd
);
8558 tcg_temp_free_i32(fp0
);
8559 tcg_temp_free_i32(fp1
);
8564 check_cp1_64bitmode(ctx
);
8566 TCGv_i32 fp0
= tcg_temp_new_i32();
8567 TCGv_i32 fp1
= tcg_temp_new_i32();
8569 gen_load_fpr32(fp0
, fs
);
8570 gen_load_fpr32h(fp1
, ft
);
8571 gen_store_fpr32(fp1
, fd
);
8572 gen_store_fpr32h(fp0
, fd
);
8573 tcg_temp_free_i32(fp0
);
8574 tcg_temp_free_i32(fp1
);
8579 check_cp1_64bitmode(ctx
);
8581 TCGv_i32 fp0
= tcg_temp_new_i32();
8582 TCGv_i32 fp1
= tcg_temp_new_i32();
8584 gen_load_fpr32h(fp0
, fs
);
8585 gen_load_fpr32(fp1
, ft
);
8586 gen_store_fpr32(fp1
, fd
);
8587 gen_store_fpr32h(fp0
, fd
);
8588 tcg_temp_free_i32(fp0
);
8589 tcg_temp_free_i32(fp1
);
8594 check_cp1_64bitmode(ctx
);
8596 TCGv_i32 fp0
= tcg_temp_new_i32();
8597 TCGv_i32 fp1
= tcg_temp_new_i32();
8599 gen_load_fpr32h(fp0
, fs
);
8600 gen_load_fpr32h(fp1
, ft
);
8601 gen_store_fpr32(fp1
, fd
);
8602 gen_store_fpr32h(fp0
, fd
);
8603 tcg_temp_free_i32(fp0
);
8604 tcg_temp_free_i32(fp1
);
8611 case OPC_CMP_UEQ_PS
:
8612 case OPC_CMP_OLT_PS
:
8613 case OPC_CMP_ULT_PS
:
8614 case OPC_CMP_OLE_PS
:
8615 case OPC_CMP_ULE_PS
:
8617 case OPC_CMP_NGLE_PS
:
8618 case OPC_CMP_SEQ_PS
:
8619 case OPC_CMP_NGL_PS
:
8621 case OPC_CMP_NGE_PS
:
8623 case OPC_CMP_NGT_PS
:
8624 if (ctx
->opcode
& (1 << 6)) {
8625 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8626 opn
= condnames_abs
[func
-48];
8628 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8629 opn
= condnames
[func
-48];
8634 generate_exception (ctx
, EXCP_RI
);
8637 (void)opn
; /* avoid a compiler warning */
8640 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8643 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8646 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8651 /* Coprocessor 3 (FPU) */
8652 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8653 int fd
, int fs
, int base
, int index
)
8655 const char *opn
= "extended float load/store";
8657 TCGv t0
= tcg_temp_new();
8660 gen_load_gpr(t0
, index
);
8661 } else if (index
== 0) {
8662 gen_load_gpr(t0
, base
);
8664 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8666 /* Don't do NOP if destination is zero: we must perform the actual
8672 TCGv_i32 fp0
= tcg_temp_new_i32();
8674 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
8675 tcg_gen_trunc_tl_i32(fp0
, t0
);
8676 gen_store_fpr32(fp0
, fd
);
8677 tcg_temp_free_i32(fp0
);
8683 check_cp1_registers(ctx
, fd
);
8685 TCGv_i64 fp0
= tcg_temp_new_i64();
8686 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8687 gen_store_fpr64(ctx
, fp0
, fd
);
8688 tcg_temp_free_i64(fp0
);
8693 check_cp1_64bitmode(ctx
);
8694 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8696 TCGv_i64 fp0
= tcg_temp_new_i64();
8698 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8699 gen_store_fpr64(ctx
, fp0
, fd
);
8700 tcg_temp_free_i64(fp0
);
8707 TCGv_i32 fp0
= tcg_temp_new_i32();
8708 gen_load_fpr32(fp0
, fs
);
8709 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
8710 tcg_temp_free_i32(fp0
);
8717 check_cp1_registers(ctx
, fs
);
8719 TCGv_i64 fp0
= tcg_temp_new_i64();
8720 gen_load_fpr64(ctx
, fp0
, fs
);
8721 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8722 tcg_temp_free_i64(fp0
);
8728 check_cp1_64bitmode(ctx
);
8729 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8731 TCGv_i64 fp0
= tcg_temp_new_i64();
8732 gen_load_fpr64(ctx
, fp0
, fs
);
8733 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8734 tcg_temp_free_i64(fp0
);
8741 (void)opn
; (void)store
; /* avoid compiler warnings */
8742 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8743 regnames
[index
], regnames
[base
]);
8746 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8747 int fd
, int fr
, int fs
, int ft
)
8749 const char *opn
= "flt3_arith";
8753 check_cp1_64bitmode(ctx
);
8755 TCGv t0
= tcg_temp_local_new();
8756 TCGv_i32 fp
= tcg_temp_new_i32();
8757 TCGv_i32 fph
= tcg_temp_new_i32();
8758 int l1
= gen_new_label();
8759 int l2
= gen_new_label();
8761 gen_load_gpr(t0
, fr
);
8762 tcg_gen_andi_tl(t0
, t0
, 0x7);
8764 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8765 gen_load_fpr32(fp
, fs
);
8766 gen_load_fpr32h(fph
, fs
);
8767 gen_store_fpr32(fp
, fd
);
8768 gen_store_fpr32h(fph
, fd
);
8771 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8773 #ifdef TARGET_WORDS_BIGENDIAN
8774 gen_load_fpr32(fp
, fs
);
8775 gen_load_fpr32h(fph
, ft
);
8776 gen_store_fpr32h(fp
, fd
);
8777 gen_store_fpr32(fph
, fd
);
8779 gen_load_fpr32h(fph
, fs
);
8780 gen_load_fpr32(fp
, ft
);
8781 gen_store_fpr32(fph
, fd
);
8782 gen_store_fpr32h(fp
, fd
);
8785 tcg_temp_free_i32(fp
);
8786 tcg_temp_free_i32(fph
);
8793 TCGv_i32 fp0
= tcg_temp_new_i32();
8794 TCGv_i32 fp1
= tcg_temp_new_i32();
8795 TCGv_i32 fp2
= tcg_temp_new_i32();
8797 gen_load_fpr32(fp0
, fs
);
8798 gen_load_fpr32(fp1
, ft
);
8799 gen_load_fpr32(fp2
, fr
);
8800 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8801 tcg_temp_free_i32(fp0
);
8802 tcg_temp_free_i32(fp1
);
8803 gen_store_fpr32(fp2
, fd
);
8804 tcg_temp_free_i32(fp2
);
8810 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8812 TCGv_i64 fp0
= tcg_temp_new_i64();
8813 TCGv_i64 fp1
= tcg_temp_new_i64();
8814 TCGv_i64 fp2
= tcg_temp_new_i64();
8816 gen_load_fpr64(ctx
, fp0
, fs
);
8817 gen_load_fpr64(ctx
, fp1
, ft
);
8818 gen_load_fpr64(ctx
, fp2
, fr
);
8819 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8820 tcg_temp_free_i64(fp0
);
8821 tcg_temp_free_i64(fp1
);
8822 gen_store_fpr64(ctx
, fp2
, fd
);
8823 tcg_temp_free_i64(fp2
);
8828 check_cp1_64bitmode(ctx
);
8830 TCGv_i64 fp0
= tcg_temp_new_i64();
8831 TCGv_i64 fp1
= tcg_temp_new_i64();
8832 TCGv_i64 fp2
= tcg_temp_new_i64();
8834 gen_load_fpr64(ctx
, fp0
, fs
);
8835 gen_load_fpr64(ctx
, fp1
, ft
);
8836 gen_load_fpr64(ctx
, fp2
, fr
);
8837 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8838 tcg_temp_free_i64(fp0
);
8839 tcg_temp_free_i64(fp1
);
8840 gen_store_fpr64(ctx
, fp2
, fd
);
8841 tcg_temp_free_i64(fp2
);
8848 TCGv_i32 fp0
= tcg_temp_new_i32();
8849 TCGv_i32 fp1
= tcg_temp_new_i32();
8850 TCGv_i32 fp2
= tcg_temp_new_i32();
8852 gen_load_fpr32(fp0
, fs
);
8853 gen_load_fpr32(fp1
, ft
);
8854 gen_load_fpr32(fp2
, fr
);
8855 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8856 tcg_temp_free_i32(fp0
);
8857 tcg_temp_free_i32(fp1
);
8858 gen_store_fpr32(fp2
, fd
);
8859 tcg_temp_free_i32(fp2
);
8865 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8867 TCGv_i64 fp0
= tcg_temp_new_i64();
8868 TCGv_i64 fp1
= tcg_temp_new_i64();
8869 TCGv_i64 fp2
= tcg_temp_new_i64();
8871 gen_load_fpr64(ctx
, fp0
, fs
);
8872 gen_load_fpr64(ctx
, fp1
, ft
);
8873 gen_load_fpr64(ctx
, fp2
, fr
);
8874 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8875 tcg_temp_free_i64(fp0
);
8876 tcg_temp_free_i64(fp1
);
8877 gen_store_fpr64(ctx
, fp2
, fd
);
8878 tcg_temp_free_i64(fp2
);
8883 check_cp1_64bitmode(ctx
);
8885 TCGv_i64 fp0
= tcg_temp_new_i64();
8886 TCGv_i64 fp1
= tcg_temp_new_i64();
8887 TCGv_i64 fp2
= tcg_temp_new_i64();
8889 gen_load_fpr64(ctx
, fp0
, fs
);
8890 gen_load_fpr64(ctx
, fp1
, ft
);
8891 gen_load_fpr64(ctx
, fp2
, fr
);
8892 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8893 tcg_temp_free_i64(fp0
);
8894 tcg_temp_free_i64(fp1
);
8895 gen_store_fpr64(ctx
, fp2
, fd
);
8896 tcg_temp_free_i64(fp2
);
8903 TCGv_i32 fp0
= tcg_temp_new_i32();
8904 TCGv_i32 fp1
= tcg_temp_new_i32();
8905 TCGv_i32 fp2
= tcg_temp_new_i32();
8907 gen_load_fpr32(fp0
, fs
);
8908 gen_load_fpr32(fp1
, ft
);
8909 gen_load_fpr32(fp2
, fr
);
8910 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8911 tcg_temp_free_i32(fp0
);
8912 tcg_temp_free_i32(fp1
);
8913 gen_store_fpr32(fp2
, fd
);
8914 tcg_temp_free_i32(fp2
);
8920 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8922 TCGv_i64 fp0
= tcg_temp_new_i64();
8923 TCGv_i64 fp1
= tcg_temp_new_i64();
8924 TCGv_i64 fp2
= tcg_temp_new_i64();
8926 gen_load_fpr64(ctx
, fp0
, fs
);
8927 gen_load_fpr64(ctx
, fp1
, ft
);
8928 gen_load_fpr64(ctx
, fp2
, fr
);
8929 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8930 tcg_temp_free_i64(fp0
);
8931 tcg_temp_free_i64(fp1
);
8932 gen_store_fpr64(ctx
, fp2
, fd
);
8933 tcg_temp_free_i64(fp2
);
8938 check_cp1_64bitmode(ctx
);
8940 TCGv_i64 fp0
= tcg_temp_new_i64();
8941 TCGv_i64 fp1
= tcg_temp_new_i64();
8942 TCGv_i64 fp2
= tcg_temp_new_i64();
8944 gen_load_fpr64(ctx
, fp0
, fs
);
8945 gen_load_fpr64(ctx
, fp1
, ft
);
8946 gen_load_fpr64(ctx
, fp2
, fr
);
8947 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8948 tcg_temp_free_i64(fp0
);
8949 tcg_temp_free_i64(fp1
);
8950 gen_store_fpr64(ctx
, fp2
, fd
);
8951 tcg_temp_free_i64(fp2
);
8958 TCGv_i32 fp0
= tcg_temp_new_i32();
8959 TCGv_i32 fp1
= tcg_temp_new_i32();
8960 TCGv_i32 fp2
= tcg_temp_new_i32();
8962 gen_load_fpr32(fp0
, fs
);
8963 gen_load_fpr32(fp1
, ft
);
8964 gen_load_fpr32(fp2
, fr
);
8965 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8966 tcg_temp_free_i32(fp0
);
8967 tcg_temp_free_i32(fp1
);
8968 gen_store_fpr32(fp2
, fd
);
8969 tcg_temp_free_i32(fp2
);
8975 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8977 TCGv_i64 fp0
= tcg_temp_new_i64();
8978 TCGv_i64 fp1
= tcg_temp_new_i64();
8979 TCGv_i64 fp2
= tcg_temp_new_i64();
8981 gen_load_fpr64(ctx
, fp0
, fs
);
8982 gen_load_fpr64(ctx
, fp1
, ft
);
8983 gen_load_fpr64(ctx
, fp2
, fr
);
8984 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8985 tcg_temp_free_i64(fp0
);
8986 tcg_temp_free_i64(fp1
);
8987 gen_store_fpr64(ctx
, fp2
, fd
);
8988 tcg_temp_free_i64(fp2
);
8993 check_cp1_64bitmode(ctx
);
8995 TCGv_i64 fp0
= tcg_temp_new_i64();
8996 TCGv_i64 fp1
= tcg_temp_new_i64();
8997 TCGv_i64 fp2
= tcg_temp_new_i64();
8999 gen_load_fpr64(ctx
, fp0
, fs
);
9000 gen_load_fpr64(ctx
, fp1
, ft
);
9001 gen_load_fpr64(ctx
, fp2
, fr
);
9002 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9003 tcg_temp_free_i64(fp0
);
9004 tcg_temp_free_i64(fp1
);
9005 gen_store_fpr64(ctx
, fp2
, fd
);
9006 tcg_temp_free_i64(fp2
);
9012 generate_exception (ctx
, EXCP_RI
);
9015 (void)opn
; /* avoid a compiler warning */
9016 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9017 fregnames
[fs
], fregnames
[ft
]);
9020 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
9024 #if !defined(CONFIG_USER_ONLY)
9025 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9026 Therefore only check the ISA in system mode. */
9027 check_insn(ctx
, ISA_MIPS32R2
);
9029 t0
= tcg_temp_new();
9033 save_cpu_state(ctx
, 1);
9034 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9035 gen_store_gpr(t0
, rt
);
9038 save_cpu_state(ctx
, 1);
9039 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9040 gen_store_gpr(t0
, rt
);
9043 save_cpu_state(ctx
, 1);
9044 gen_helper_rdhwr_cc(t0
, cpu_env
);
9045 gen_store_gpr(t0
, rt
);
9048 save_cpu_state(ctx
, 1);
9049 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9050 gen_store_gpr(t0
, rt
);
9053 #if defined(CONFIG_USER_ONLY)
9054 tcg_gen_ld_tl(t0
, cpu_env
, offsetof(CPUMIPSState
, tls_value
));
9055 gen_store_gpr(t0
, rt
);
9058 /* XXX: Some CPUs implement this in hardware.
9059 Not supported yet. */
9061 default: /* Invalid */
9062 MIPS_INVAL("rdhwr");
9063 generate_exception(ctx
, EXCP_RI
);
9069 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9071 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9072 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9073 /* Branches completion */
9074 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9075 ctx
->bstate
= BS_BRANCH
;
9076 save_cpu_state(ctx
, 0);
9077 /* FIXME: Need to clear can_do_io. */
9078 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9080 /* unconditional branch */
9081 MIPS_DEBUG("unconditional branch");
9082 if (proc_hflags
& MIPS_HFLAG_BX
) {
9083 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9085 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9088 /* blikely taken case */
9089 MIPS_DEBUG("blikely branch taken");
9090 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9093 /* Conditional branch */
9094 MIPS_DEBUG("conditional branch");
9096 int l1
= gen_new_label();
9098 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9099 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9101 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9105 /* unconditional branch to register */
9106 MIPS_DEBUG("branch to register");
9107 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9108 TCGv t0
= tcg_temp_new();
9109 TCGv_i32 t1
= tcg_temp_new_i32();
9111 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9112 tcg_gen_trunc_tl_i32(t1
, t0
);
9114 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9115 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9116 tcg_gen_or_i32(hflags
, hflags
, t1
);
9117 tcg_temp_free_i32(t1
);
9119 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9121 tcg_gen_mov_tl(cpu_PC
, btarget
);
9123 if (ctx
->singlestep_enabled
) {
9124 save_cpu_state(ctx
, 0);
9125 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9130 MIPS_DEBUG("unknown branch");
9136 /* ISA extensions (ASEs) */
9137 /* MIPS16 extension to MIPS32 */
9139 /* MIPS16 major opcodes */
9141 M16_OPC_ADDIUSP
= 0x00,
9142 M16_OPC_ADDIUPC
= 0x01,
9145 M16_OPC_BEQZ
= 0x04,
9146 M16_OPC_BNEQZ
= 0x05,
9147 M16_OPC_SHIFT
= 0x06,
9149 M16_OPC_RRIA
= 0x08,
9150 M16_OPC_ADDIU8
= 0x09,
9151 M16_OPC_SLTI
= 0x0a,
9152 M16_OPC_SLTIU
= 0x0b,
9155 M16_OPC_CMPI
= 0x0e,
9159 M16_OPC_LWSP
= 0x12,
9163 M16_OPC_LWPC
= 0x16,
9167 M16_OPC_SWSP
= 0x1a,
9171 M16_OPC_EXTEND
= 0x1e,
9175 /* I8 funct field */
9194 /* RR funct field */
9228 /* I64 funct field */
9240 /* RR ry field for CNVT */
9242 RR_RY_CNVT_ZEB
= 0x0,
9243 RR_RY_CNVT_ZEH
= 0x1,
9244 RR_RY_CNVT_ZEW
= 0x2,
9245 RR_RY_CNVT_SEB
= 0x4,
9246 RR_RY_CNVT_SEH
= 0x5,
9247 RR_RY_CNVT_SEW
= 0x6,
9250 static int xlat (int r
)
9252 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9257 static void gen_mips16_save (DisasContext
*ctx
,
9258 int xsregs
, int aregs
,
9259 int do_ra
, int do_s0
, int do_s1
,
9262 TCGv t0
= tcg_temp_new();
9263 TCGv t1
= tcg_temp_new();
9293 generate_exception(ctx
, EXCP_RI
);
9299 gen_base_offset_addr(ctx
, t0
, 29, 12);
9300 gen_load_gpr(t1
, 7);
9301 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9304 gen_base_offset_addr(ctx
, t0
, 29, 8);
9305 gen_load_gpr(t1
, 6);
9306 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9309 gen_base_offset_addr(ctx
, t0
, 29, 4);
9310 gen_load_gpr(t1
, 5);
9311 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9314 gen_base_offset_addr(ctx
, t0
, 29, 0);
9315 gen_load_gpr(t1
, 4);
9316 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9319 gen_load_gpr(t0
, 29);
9321 #define DECR_AND_STORE(reg) do { \
9322 tcg_gen_subi_tl(t0, t0, 4); \
9323 gen_load_gpr(t1, reg); \
9324 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9388 generate_exception(ctx
, EXCP_RI
);
9404 #undef DECR_AND_STORE
9406 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9411 static void gen_mips16_restore (DisasContext
*ctx
,
9412 int xsregs
, int aregs
,
9413 int do_ra
, int do_s0
, int do_s1
,
9417 TCGv t0
= tcg_temp_new();
9418 TCGv t1
= tcg_temp_new();
9420 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9422 #define DECR_AND_LOAD(reg) do { \
9423 tcg_gen_subi_tl(t0, t0, 4); \
9424 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9425 gen_store_gpr(t1, reg); \
9489 generate_exception(ctx
, EXCP_RI
);
9505 #undef DECR_AND_LOAD
9507 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9512 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9513 int is_64_bit
, int extended
)
9517 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9518 generate_exception(ctx
, EXCP_RI
);
9522 t0
= tcg_temp_new();
9524 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9525 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9527 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9533 #if defined(TARGET_MIPS64)
9534 static void decode_i64_mips16 (DisasContext
*ctx
,
9535 int ry
, int funct
, int16_t offset
,
9541 offset
= extended
? offset
: offset
<< 3;
9542 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9546 offset
= extended
? offset
: offset
<< 3;
9547 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9551 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9552 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9556 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9557 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9560 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9561 generate_exception(ctx
, EXCP_RI
);
9563 offset
= extended
? offset
: offset
<< 3;
9564 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9569 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9570 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9574 offset
= extended
? offset
: offset
<< 2;
9575 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9579 offset
= extended
? offset
: offset
<< 2;
9580 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9586 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9588 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9589 int op
, rx
, ry
, funct
, sa
;
9590 int16_t imm
, offset
;
9592 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9593 op
= (ctx
->opcode
>> 11) & 0x1f;
9594 sa
= (ctx
->opcode
>> 22) & 0x1f;
9595 funct
= (ctx
->opcode
>> 8) & 0x7;
9596 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9597 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9598 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9599 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9600 | (ctx
->opcode
& 0x1f));
9602 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9605 case M16_OPC_ADDIUSP
:
9606 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9608 case M16_OPC_ADDIUPC
:
9609 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9612 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9613 /* No delay slot, so just process as a normal instruction */
9616 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9617 /* No delay slot, so just process as a normal instruction */
9620 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9621 /* No delay slot, so just process as a normal instruction */
9624 switch (ctx
->opcode
& 0x3) {
9626 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9629 #if defined(TARGET_MIPS64)
9631 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9633 generate_exception(ctx
, EXCP_RI
);
9637 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9640 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9644 #if defined(TARGET_MIPS64)
9647 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9651 imm
= ctx
->opcode
& 0xf;
9652 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9653 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9654 imm
= (int16_t) (imm
<< 1) >> 1;
9655 if ((ctx
->opcode
>> 4) & 0x1) {
9656 #if defined(TARGET_MIPS64)
9658 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9660 generate_exception(ctx
, EXCP_RI
);
9663 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9666 case M16_OPC_ADDIU8
:
9667 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9670 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9673 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9678 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9681 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9684 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9687 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9691 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9692 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9693 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9694 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9695 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9696 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9697 | (ctx
->opcode
& 0xf)) << 3;
9699 if (ctx
->opcode
& (1 << 7)) {
9700 gen_mips16_save(ctx
, xsregs
, aregs
,
9701 do_ra
, do_s0
, do_s1
,
9704 gen_mips16_restore(ctx
, xsregs
, aregs
,
9705 do_ra
, do_s0
, do_s1
,
9711 generate_exception(ctx
, EXCP_RI
);
9716 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9719 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9721 #if defined(TARGET_MIPS64)
9723 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9727 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9730 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9733 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9736 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9739 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9742 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9745 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9747 #if defined(TARGET_MIPS64)
9749 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9753 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9756 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9759 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9762 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9764 #if defined(TARGET_MIPS64)
9766 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9770 generate_exception(ctx
, EXCP_RI
);
9777 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9781 int op
, cnvt_op
, op1
, offset
;
9785 op
= (ctx
->opcode
>> 11) & 0x1f;
9786 sa
= (ctx
->opcode
>> 2) & 0x7;
9787 sa
= sa
== 0 ? 8 : sa
;
9788 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9789 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9790 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9791 op1
= offset
= ctx
->opcode
& 0x1f;
9796 case M16_OPC_ADDIUSP
:
9798 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9800 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9803 case M16_OPC_ADDIUPC
:
9804 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9807 offset
= (ctx
->opcode
& 0x7ff) << 1;
9808 offset
= (int16_t)(offset
<< 4) >> 4;
9809 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9810 /* No delay slot, so just process as a normal instruction */
9813 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9814 offset
= (((ctx
->opcode
& 0x1f) << 21)
9815 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9817 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9818 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9822 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9823 /* No delay slot, so just process as a normal instruction */
9826 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9827 /* No delay slot, so just process as a normal instruction */
9830 switch (ctx
->opcode
& 0x3) {
9832 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9835 #if defined(TARGET_MIPS64)
9837 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9839 generate_exception(ctx
, EXCP_RI
);
9843 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9846 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9850 #if defined(TARGET_MIPS64)
9853 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9858 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9860 if ((ctx
->opcode
>> 4) & 1) {
9861 #if defined(TARGET_MIPS64)
9863 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9865 generate_exception(ctx
, EXCP_RI
);
9868 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9872 case M16_OPC_ADDIU8
:
9874 int16_t imm
= (int8_t) ctx
->opcode
;
9876 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9881 int16_t imm
= (uint8_t) ctx
->opcode
;
9882 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9887 int16_t imm
= (uint8_t) ctx
->opcode
;
9888 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9895 funct
= (ctx
->opcode
>> 8) & 0x7;
9898 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9899 ((int8_t)ctx
->opcode
) << 1);
9902 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9903 ((int8_t)ctx
->opcode
) << 1);
9906 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9909 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9910 ((int8_t)ctx
->opcode
) << 3);
9914 int do_ra
= ctx
->opcode
& (1 << 6);
9915 int do_s0
= ctx
->opcode
& (1 << 5);
9916 int do_s1
= ctx
->opcode
& (1 << 4);
9917 int framesize
= ctx
->opcode
& 0xf;
9919 if (framesize
== 0) {
9922 framesize
= framesize
<< 3;
9925 if (ctx
->opcode
& (1 << 7)) {
9926 gen_mips16_save(ctx
, 0, 0,
9927 do_ra
, do_s0
, do_s1
, framesize
);
9929 gen_mips16_restore(ctx
, 0, 0,
9930 do_ra
, do_s0
, do_s1
, framesize
);
9936 int rz
= xlat(ctx
->opcode
& 0x7);
9938 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9939 ((ctx
->opcode
>> 5) & 0x7);
9940 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
9944 reg32
= ctx
->opcode
& 0x1f;
9945 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
9948 generate_exception(ctx
, EXCP_RI
);
9955 int16_t imm
= (uint8_t) ctx
->opcode
;
9957 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
9962 int16_t imm
= (uint8_t) ctx
->opcode
;
9963 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
9966 #if defined(TARGET_MIPS64)
9969 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
9973 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9976 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
9979 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
9982 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
9985 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9988 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
9991 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
9993 #if defined (TARGET_MIPS64)
9996 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
10000 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10003 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
10006 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10009 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10013 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10016 switch (ctx
->opcode
& 0x3) {
10018 mips32_op
= OPC_ADDU
;
10021 mips32_op
= OPC_SUBU
;
10023 #if defined(TARGET_MIPS64)
10025 mips32_op
= OPC_DADDU
;
10026 check_mips_64(ctx
);
10029 mips32_op
= OPC_DSUBU
;
10030 check_mips_64(ctx
);
10034 generate_exception(ctx
, EXCP_RI
);
10038 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10047 int nd
= (ctx
->opcode
>> 7) & 0x1;
10048 int link
= (ctx
->opcode
>> 6) & 0x1;
10049 int ra
= (ctx
->opcode
>> 5) & 0x1;
10052 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10057 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10061 /* XXX: not clear which exception should be raised
10062 * when in debug mode...
10064 check_insn(ctx
, ISA_MIPS32
);
10065 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10066 generate_exception(ctx
, EXCP_DBp
);
10068 generate_exception(ctx
, EXCP_DBp
);
10072 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10075 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10078 generate_exception(ctx
, EXCP_BREAK
);
10081 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10084 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10087 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10089 #if defined (TARGET_MIPS64)
10091 check_mips_64(ctx
);
10092 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10096 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10099 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10102 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10105 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10108 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10111 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10114 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
10118 case RR_RY_CNVT_ZEB
:
10119 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10121 case RR_RY_CNVT_ZEH
:
10122 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10124 case RR_RY_CNVT_SEB
:
10125 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10127 case RR_RY_CNVT_SEH
:
10128 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10130 #if defined (TARGET_MIPS64)
10131 case RR_RY_CNVT_ZEW
:
10132 check_mips_64(ctx
);
10133 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10135 case RR_RY_CNVT_SEW
:
10136 check_mips_64(ctx
);
10137 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10141 generate_exception(ctx
, EXCP_RI
);
10146 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
10148 #if defined (TARGET_MIPS64)
10150 check_mips_64(ctx
);
10151 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10154 check_mips_64(ctx
);
10155 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10158 check_mips_64(ctx
);
10159 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10162 check_mips_64(ctx
);
10163 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10167 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
10170 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
10173 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
10176 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
10178 #if defined (TARGET_MIPS64)
10180 check_mips_64(ctx
);
10181 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
10184 check_mips_64(ctx
);
10185 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
10188 check_mips_64(ctx
);
10189 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
10192 check_mips_64(ctx
);
10193 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
10197 generate_exception(ctx
, EXCP_RI
);
10201 case M16_OPC_EXTEND
:
10202 decode_extended_mips16_opc(env
, ctx
);
10205 #if defined(TARGET_MIPS64)
10207 funct
= (ctx
->opcode
>> 8) & 0x7;
10208 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10212 generate_exception(ctx
, EXCP_RI
);
10219 /* microMIPS extension to MIPS32/MIPS64 */
10222 * microMIPS32/microMIPS64 major opcodes
10224 * 1. MIPS Architecture for Programmers Volume II-B:
10225 * The microMIPS32 Instruction Set (Revision 3.05)
10227 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10229 * 2. MIPS Architecture For Programmers Volume II-A:
10230 * The MIPS64 Instruction Set (Revision 3.51)
10258 POOL32S
= 0x16, /* MIPS64 */
10259 DADDIU32
= 0x17, /* MIPS64 */
10261 /* 0x1f is reserved */
10270 /* 0x20 is reserved */
10280 /* 0x28 and 0x29 are reserved */
10290 /* 0x30 and 0x31 are reserved */
10297 SD32
= 0x36, /* MIPS64 */
10298 LD32
= 0x37, /* MIPS64 */
10300 /* 0x38 and 0x39 are reserved */
10311 /* POOL32A encoding of minor opcode field */
10314 /* These opcodes are distinguished only by bits 9..6; those bits are
10315 * what are recorded below. */
10341 /* The following can be distinguished by their lower 6 bits. */
10347 /* POOL32AXF encoding of minor opcode field extension */
10350 * 1. MIPS Architecture for Programmers Volume II-B:
10351 * The microMIPS32 Instruction Set (Revision 3.05)
10353 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10355 * 2. MIPS Architecture for Programmers VolumeIV-e:
10356 * The MIPS DSP Application-Specific Extension
10357 * to the microMIPS32 Architecture (Revision 2.34)
10359 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10374 /* begin of microMIPS32 DSP */
10376 /* bits 13..12 for 0x01 */
10382 /* bits 13..12 for 0x2a */
10388 /* bits 13..12 for 0x32 */
10392 /* end of microMIPS32 DSP */
10394 /* bits 15..12 for 0x2c */
10410 /* bits 15..12 for 0x34 */
10418 /* bits 15..12 for 0x3c */
10420 JR
= 0x0, /* alias */
10425 /* bits 15..12 for 0x05 */
10429 /* bits 15..12 for 0x0d */
10439 /* bits 15..12 for 0x15 */
10445 /* bits 15..12 for 0x1d */
10449 /* bits 15..12 for 0x2d */
10454 /* bits 15..12 for 0x35 */
10461 /* POOL32B encoding of minor opcode field (bits 15..12) */
10477 /* POOL32C encoding of minor opcode field (bits 15..12) */
10485 /* 0xa is reserved */
10492 /* 0x6 is reserved */
10498 /* POOL32F encoding of minor opcode field (bits 5..0) */
10501 /* These are the bit 7..6 values */
10512 /* These are the bit 8..6 values */
10556 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10560 /* POOL32Fxf encoding of minor opcode extension field */
10598 /* POOL32I encoding of minor opcode field (bits 25..21) */
10623 /* These overlap and are distinguished by bit16 of the instruction */
10632 /* POOL16A encoding of minor opcode field */
10639 /* POOL16B encoding of minor opcode field */
10646 /* POOL16C encoding of minor opcode field */
10666 /* POOL16D encoding of minor opcode field */
10673 /* POOL16E encoding of minor opcode field */
10680 static int mmreg (int r
)
10682 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10687 /* Used for 16-bit store instructions. */
10688 static int mmreg2 (int r
)
10690 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10695 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10696 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10697 #define uMIPS_RS2(op) uMIPS_RS(op)
10698 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10699 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10700 #define uMIPS_RS5(op) (op & 0x1f)
10702 /* Signed immediate */
10703 #define SIMM(op, start, width) \
10704 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10707 /* Zero-extended immediate */
10708 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10710 static void gen_addiur1sp(DisasContext
*ctx
)
10712 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10714 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10717 static void gen_addiur2(DisasContext
*ctx
)
10719 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10720 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10721 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10723 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10726 static void gen_addiusp(DisasContext
*ctx
)
10728 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10731 if (encoded
<= 1) {
10732 decoded
= 256 + encoded
;
10733 } else if (encoded
<= 255) {
10735 } else if (encoded
<= 509) {
10736 decoded
= encoded
- 512;
10738 decoded
= encoded
- 768;
10741 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10744 static void gen_addius5(DisasContext
*ctx
)
10746 int imm
= SIMM(ctx
->opcode
, 1, 4);
10747 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10749 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10752 static void gen_andi16(DisasContext
*ctx
)
10754 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10755 31, 32, 63, 64, 255, 32768, 65535 };
10756 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10757 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10758 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10760 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10763 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10764 int base
, int16_t offset
)
10766 const char *opn
= "ldst_multiple";
10770 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10771 generate_exception(ctx
, EXCP_RI
);
10775 t0
= tcg_temp_new();
10777 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10779 t1
= tcg_const_tl(reglist
);
10780 t2
= tcg_const_i32(ctx
->mem_idx
);
10782 save_cpu_state(ctx
, 1);
10785 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10789 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10792 #ifdef TARGET_MIPS64
10794 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10798 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10804 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10807 tcg_temp_free_i32(t2
);
10811 static void gen_pool16c_insn(DisasContext
*ctx
)
10813 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10814 int rs
= mmreg(ctx
->opcode
& 0x7);
10817 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10822 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10828 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10834 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10840 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10847 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10848 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10850 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10859 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10860 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10862 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10869 int reg
= ctx
->opcode
& 0x1f;
10871 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10877 int reg
= ctx
->opcode
& 0x1f;
10879 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10880 /* Let normal delay slot handling in our caller take us
10881 to the branch target. */
10893 int reg
= ctx
->opcode
& 0x1f;
10895 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10900 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
10904 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
10907 generate_exception(ctx
, EXCP_BREAK
);
10910 /* XXX: not clear which exception should be raised
10911 * when in debug mode...
10913 check_insn(ctx
, ISA_MIPS32
);
10914 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10915 generate_exception(ctx
, EXCP_DBp
);
10917 generate_exception(ctx
, EXCP_DBp
);
10920 case JRADDIUSP
+ 0:
10921 case JRADDIUSP
+ 1:
10923 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10925 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10926 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10927 /* Let normal delay slot handling in our caller take us
10928 to the branch target. */
10932 generate_exception(ctx
, EXCP_RI
);
10937 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10939 TCGv t0
= tcg_temp_new();
10940 TCGv t1
= tcg_temp_new();
10942 gen_load_gpr(t0
, base
);
10945 gen_load_gpr(t1
, index
);
10946 tcg_gen_shli_tl(t1
, t1
, 2);
10947 gen_op_addr_add(ctx
, t0
, t1
, t0
);
10950 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
10951 gen_store_gpr(t1
, rd
);
10957 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
10958 int base
, int16_t offset
)
10960 const char *opn
= "ldst_pair";
10963 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
10964 generate_exception(ctx
, EXCP_RI
);
10968 t0
= tcg_temp_new();
10969 t1
= tcg_temp_new();
10971 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10976 generate_exception(ctx
, EXCP_RI
);
10979 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
10980 gen_store_gpr(t1
, rd
);
10981 tcg_gen_movi_tl(t1
, 4);
10982 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10983 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
10984 gen_store_gpr(t1
, rd
+1);
10988 gen_load_gpr(t1
, rd
);
10989 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10990 tcg_gen_movi_tl(t1
, 4);
10991 gen_op_addr_add(ctx
, t0
, t0
, t1
);
10992 gen_load_gpr(t1
, rd
+1);
10993 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
10996 #ifdef TARGET_MIPS64
10999 generate_exception(ctx
, EXCP_RI
);
11002 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11003 gen_store_gpr(t1
, rd
);
11004 tcg_gen_movi_tl(t1
, 8);
11005 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11006 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11007 gen_store_gpr(t1
, rd
+1);
11011 gen_load_gpr(t1
, rd
);
11012 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11013 tcg_gen_movi_tl(t1
, 8);
11014 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11015 gen_load_gpr(t1
, rd
+1);
11016 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11021 (void)opn
; /* avoid a compiler warning */
11022 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11027 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
11029 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11030 int minor
= (ctx
->opcode
>> 12) & 0xf;
11031 uint32_t mips32_op
;
11033 switch (extension
) {
11035 mips32_op
= OPC_TEQ
;
11038 mips32_op
= OPC_TGE
;
11041 mips32_op
= OPC_TGEU
;
11044 mips32_op
= OPC_TLT
;
11047 mips32_op
= OPC_TLTU
;
11050 mips32_op
= OPC_TNE
;
11052 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11054 #ifndef CONFIG_USER_ONLY
11057 check_cp0_enabled(ctx
);
11059 /* Treat as NOP. */
11062 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11066 check_cp0_enabled(ctx
);
11068 TCGv t0
= tcg_temp_new();
11070 gen_load_gpr(t0
, rt
);
11071 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11077 switch (minor
& 3) {
11079 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11082 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11085 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11088 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11091 goto pool32axf_invalid
;
11095 switch (minor
& 3) {
11097 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11100 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11103 goto pool32axf_invalid
;
11109 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11112 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11115 mips32_op
= OPC_CLO
;
11118 mips32_op
= OPC_CLZ
;
11120 check_insn(ctx
, ISA_MIPS32
);
11121 gen_cl(ctx
, mips32_op
, rt
, rs
);
11124 gen_rdhwr(ctx
, rt
, rs
);
11127 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11130 mips32_op
= OPC_MULT
;
11133 mips32_op
= OPC_MULTU
;
11136 mips32_op
= OPC_DIV
;
11139 mips32_op
= OPC_DIVU
;
11142 check_insn(ctx
, ISA_MIPS32
);
11143 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11146 mips32_op
= OPC_MADD
;
11149 mips32_op
= OPC_MADDU
;
11152 mips32_op
= OPC_MSUB
;
11155 mips32_op
= OPC_MSUBU
;
11157 check_insn(ctx
, ISA_MIPS32
);
11158 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11161 goto pool32axf_invalid
;
11172 generate_exception_err(ctx
, EXCP_CpU
, 2);
11175 goto pool32axf_invalid
;
11182 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11186 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11189 goto pool32axf_invalid
;
11195 check_cp0_enabled(ctx
);
11196 check_insn(ctx
, ISA_MIPS32R2
);
11197 gen_load_srsgpr(rt
, rs
);
11200 check_cp0_enabled(ctx
);
11201 check_insn(ctx
, ISA_MIPS32R2
);
11202 gen_store_srsgpr(rt
, rs
);
11205 goto pool32axf_invalid
;
11208 #ifndef CONFIG_USER_ONLY
11212 mips32_op
= OPC_TLBP
;
11215 mips32_op
= OPC_TLBR
;
11218 mips32_op
= OPC_TLBWI
;
11221 mips32_op
= OPC_TLBWR
;
11224 mips32_op
= OPC_WAIT
;
11227 mips32_op
= OPC_DERET
;
11230 mips32_op
= OPC_ERET
;
11232 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11235 goto pool32axf_invalid
;
11241 check_cp0_enabled(ctx
);
11243 TCGv t0
= tcg_temp_new();
11245 save_cpu_state(ctx
, 1);
11246 gen_helper_di(t0
, cpu_env
);
11247 gen_store_gpr(t0
, rs
);
11248 /* Stop translation as we may have switched the execution mode */
11249 ctx
->bstate
= BS_STOP
;
11254 check_cp0_enabled(ctx
);
11256 TCGv t0
= tcg_temp_new();
11258 save_cpu_state(ctx
, 1);
11259 gen_helper_ei(t0
, cpu_env
);
11260 gen_store_gpr(t0
, rs
);
11261 /* Stop translation as we may have switched the execution mode */
11262 ctx
->bstate
= BS_STOP
;
11267 goto pool32axf_invalid
;
11277 generate_exception(ctx
, EXCP_SYSCALL
);
11278 ctx
->bstate
= BS_STOP
;
11281 check_insn(ctx
, ISA_MIPS32
);
11282 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11283 generate_exception(ctx
, EXCP_DBp
);
11285 generate_exception(ctx
, EXCP_DBp
);
11289 goto pool32axf_invalid
;
11293 switch (minor
& 3) {
11295 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
11298 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
11301 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
11304 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
11307 goto pool32axf_invalid
;
11313 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
11316 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
11319 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
11322 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
11325 goto pool32axf_invalid
;
11330 MIPS_INVAL("pool32axf");
11331 generate_exception(ctx
, EXCP_RI
);
11336 /* Values for microMIPS fmt field. Variable-width, depending on which
11337 formats the instruction supports. */
11356 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11358 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11359 uint32_t mips32_op
;
11361 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11362 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11363 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11365 switch (extension
) {
11366 case FLOAT_1BIT_FMT(CFC1
, 0):
11367 mips32_op
= OPC_CFC1
;
11369 case FLOAT_1BIT_FMT(CTC1
, 0):
11370 mips32_op
= OPC_CTC1
;
11372 case FLOAT_1BIT_FMT(MFC1
, 0):
11373 mips32_op
= OPC_MFC1
;
11375 case FLOAT_1BIT_FMT(MTC1
, 0):
11376 mips32_op
= OPC_MTC1
;
11378 case FLOAT_1BIT_FMT(MFHC1
, 0):
11379 mips32_op
= OPC_MFHC1
;
11381 case FLOAT_1BIT_FMT(MTHC1
, 0):
11382 mips32_op
= OPC_MTHC1
;
11384 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11387 /* Reciprocal square root */
11388 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11389 mips32_op
= OPC_RSQRT_S
;
11391 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11392 mips32_op
= OPC_RSQRT_D
;
11396 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11397 mips32_op
= OPC_SQRT_S
;
11399 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11400 mips32_op
= OPC_SQRT_D
;
11404 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11405 mips32_op
= OPC_RECIP_S
;
11407 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11408 mips32_op
= OPC_RECIP_D
;
11412 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11413 mips32_op
= OPC_FLOOR_L_S
;
11415 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11416 mips32_op
= OPC_FLOOR_L_D
;
11418 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11419 mips32_op
= OPC_FLOOR_W_S
;
11421 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11422 mips32_op
= OPC_FLOOR_W_D
;
11426 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11427 mips32_op
= OPC_CEIL_L_S
;
11429 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11430 mips32_op
= OPC_CEIL_L_D
;
11432 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11433 mips32_op
= OPC_CEIL_W_S
;
11435 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11436 mips32_op
= OPC_CEIL_W_D
;
11440 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11441 mips32_op
= OPC_TRUNC_L_S
;
11443 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11444 mips32_op
= OPC_TRUNC_L_D
;
11446 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11447 mips32_op
= OPC_TRUNC_W_S
;
11449 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11450 mips32_op
= OPC_TRUNC_W_D
;
11454 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11455 mips32_op
= OPC_ROUND_L_S
;
11457 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11458 mips32_op
= OPC_ROUND_L_D
;
11460 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11461 mips32_op
= OPC_ROUND_W_S
;
11463 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11464 mips32_op
= OPC_ROUND_W_D
;
11467 /* Integer to floating-point conversion */
11468 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11469 mips32_op
= OPC_CVT_L_S
;
11471 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11472 mips32_op
= OPC_CVT_L_D
;
11474 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11475 mips32_op
= OPC_CVT_W_S
;
11477 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11478 mips32_op
= OPC_CVT_W_D
;
11481 /* Paired-foo conversions */
11482 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11483 mips32_op
= OPC_CVT_S_PL
;
11485 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11486 mips32_op
= OPC_CVT_S_PU
;
11488 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11489 mips32_op
= OPC_CVT_PW_PS
;
11491 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11492 mips32_op
= OPC_CVT_PS_PW
;
11495 /* Floating-point moves */
11496 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11497 mips32_op
= OPC_MOV_S
;
11499 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11500 mips32_op
= OPC_MOV_D
;
11502 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11503 mips32_op
= OPC_MOV_PS
;
11506 /* Absolute value */
11507 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11508 mips32_op
= OPC_ABS_S
;
11510 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11511 mips32_op
= OPC_ABS_D
;
11513 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11514 mips32_op
= OPC_ABS_PS
;
11518 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11519 mips32_op
= OPC_NEG_S
;
11521 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11522 mips32_op
= OPC_NEG_D
;
11524 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11525 mips32_op
= OPC_NEG_PS
;
11528 /* Reciprocal square root step */
11529 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11530 mips32_op
= OPC_RSQRT1_S
;
11532 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11533 mips32_op
= OPC_RSQRT1_D
;
11535 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11536 mips32_op
= OPC_RSQRT1_PS
;
11539 /* Reciprocal step */
11540 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11541 mips32_op
= OPC_RECIP1_S
;
11543 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11544 mips32_op
= OPC_RECIP1_S
;
11546 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11547 mips32_op
= OPC_RECIP1_PS
;
11550 /* Conversions from double */
11551 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11552 mips32_op
= OPC_CVT_D_S
;
11554 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11555 mips32_op
= OPC_CVT_D_W
;
11557 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11558 mips32_op
= OPC_CVT_D_L
;
11561 /* Conversions from single */
11562 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11563 mips32_op
= OPC_CVT_S_D
;
11565 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11566 mips32_op
= OPC_CVT_S_W
;
11568 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11569 mips32_op
= OPC_CVT_S_L
;
11571 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11574 /* Conditional moves on floating-point codes */
11575 case COND_FLOAT_MOV(MOVT
, 0):
11576 case COND_FLOAT_MOV(MOVT
, 1):
11577 case COND_FLOAT_MOV(MOVT
, 2):
11578 case COND_FLOAT_MOV(MOVT
, 3):
11579 case COND_FLOAT_MOV(MOVT
, 4):
11580 case COND_FLOAT_MOV(MOVT
, 5):
11581 case COND_FLOAT_MOV(MOVT
, 6):
11582 case COND_FLOAT_MOV(MOVT
, 7):
11583 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11585 case COND_FLOAT_MOV(MOVF
, 0):
11586 case COND_FLOAT_MOV(MOVF
, 1):
11587 case COND_FLOAT_MOV(MOVF
, 2):
11588 case COND_FLOAT_MOV(MOVF
, 3):
11589 case COND_FLOAT_MOV(MOVF
, 4):
11590 case COND_FLOAT_MOV(MOVF
, 5):
11591 case COND_FLOAT_MOV(MOVF
, 6):
11592 case COND_FLOAT_MOV(MOVF
, 7):
11593 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11596 MIPS_INVAL("pool32fxf");
11597 generate_exception(ctx
, EXCP_RI
);
11602 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11607 int rt
, rs
, rd
, rr
;
11609 uint32_t op
, minor
, mips32_op
;
11610 uint32_t cond
, fmt
, cc
;
11612 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11613 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11615 rt
= (ctx
->opcode
>> 21) & 0x1f;
11616 rs
= (ctx
->opcode
>> 16) & 0x1f;
11617 rd
= (ctx
->opcode
>> 11) & 0x1f;
11618 rr
= (ctx
->opcode
>> 6) & 0x1f;
11619 imm
= (int16_t) ctx
->opcode
;
11621 op
= (ctx
->opcode
>> 26) & 0x3f;
11624 minor
= ctx
->opcode
& 0x3f;
11627 minor
= (ctx
->opcode
>> 6) & 0xf;
11630 mips32_op
= OPC_SLL
;
11633 mips32_op
= OPC_SRA
;
11636 mips32_op
= OPC_SRL
;
11639 mips32_op
= OPC_ROTR
;
11641 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11644 goto pool32a_invalid
;
11648 minor
= (ctx
->opcode
>> 6) & 0xf;
11652 mips32_op
= OPC_ADD
;
11655 mips32_op
= OPC_ADDU
;
11658 mips32_op
= OPC_SUB
;
11661 mips32_op
= OPC_SUBU
;
11664 mips32_op
= OPC_MUL
;
11666 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11670 mips32_op
= OPC_SLLV
;
11673 mips32_op
= OPC_SRLV
;
11676 mips32_op
= OPC_SRAV
;
11679 mips32_op
= OPC_ROTRV
;
11681 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11683 /* Logical operations */
11685 mips32_op
= OPC_AND
;
11688 mips32_op
= OPC_OR
;
11691 mips32_op
= OPC_NOR
;
11694 mips32_op
= OPC_XOR
;
11696 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11698 /* Set less than */
11700 mips32_op
= OPC_SLT
;
11703 mips32_op
= OPC_SLTU
;
11705 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11708 goto pool32a_invalid
;
11712 minor
= (ctx
->opcode
>> 6) & 0xf;
11714 /* Conditional moves */
11716 mips32_op
= OPC_MOVN
;
11719 mips32_op
= OPC_MOVZ
;
11721 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11724 gen_ldxs(ctx
, rs
, rt
, rd
);
11727 goto pool32a_invalid
;
11731 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11734 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11737 gen_pool32axf(env
, ctx
, rt
, rs
);
11740 generate_exception(ctx
, EXCP_BREAK
);
11744 MIPS_INVAL("pool32a");
11745 generate_exception(ctx
, EXCP_RI
);
11750 minor
= (ctx
->opcode
>> 12) & 0xf;
11753 check_cp0_enabled(ctx
);
11754 /* Treat as no-op. */
11758 /* COP2: Not implemented. */
11759 generate_exception_err(ctx
, EXCP_CpU
, 2);
11763 #ifdef TARGET_MIPS64
11767 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11771 #ifdef TARGET_MIPS64
11775 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11778 MIPS_INVAL("pool32b");
11779 generate_exception(ctx
, EXCP_RI
);
11784 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
11785 minor
= ctx
->opcode
& 0x3f;
11786 check_cp1_enabled(ctx
);
11789 mips32_op
= OPC_ALNV_PS
;
11792 mips32_op
= OPC_MADD_S
;
11795 mips32_op
= OPC_MADD_D
;
11798 mips32_op
= OPC_MADD_PS
;
11801 mips32_op
= OPC_MSUB_S
;
11804 mips32_op
= OPC_MSUB_D
;
11807 mips32_op
= OPC_MSUB_PS
;
11810 mips32_op
= OPC_NMADD_S
;
11813 mips32_op
= OPC_NMADD_D
;
11816 mips32_op
= OPC_NMADD_PS
;
11819 mips32_op
= OPC_NMSUB_S
;
11822 mips32_op
= OPC_NMSUB_D
;
11825 mips32_op
= OPC_NMSUB_PS
;
11827 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11829 case CABS_COND_FMT
:
11830 cond
= (ctx
->opcode
>> 6) & 0xf;
11831 cc
= (ctx
->opcode
>> 13) & 0x7;
11832 fmt
= (ctx
->opcode
>> 10) & 0x3;
11835 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11838 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11841 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11844 goto pool32f_invalid
;
11848 cond
= (ctx
->opcode
>> 6) & 0xf;
11849 cc
= (ctx
->opcode
>> 13) & 0x7;
11850 fmt
= (ctx
->opcode
>> 10) & 0x3;
11853 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11856 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11859 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11862 goto pool32f_invalid
;
11866 gen_pool32fxf(ctx
, rt
, rs
);
11870 switch ((ctx
->opcode
>> 6) & 0x7) {
11872 mips32_op
= OPC_PLL_PS
;
11875 mips32_op
= OPC_PLU_PS
;
11878 mips32_op
= OPC_PUL_PS
;
11881 mips32_op
= OPC_PUU_PS
;
11884 mips32_op
= OPC_CVT_PS_S
;
11886 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11889 goto pool32f_invalid
;
11894 switch ((ctx
->opcode
>> 6) & 0x7) {
11896 mips32_op
= OPC_LWXC1
;
11899 mips32_op
= OPC_SWXC1
;
11902 mips32_op
= OPC_LDXC1
;
11905 mips32_op
= OPC_SDXC1
;
11908 mips32_op
= OPC_LUXC1
;
11911 mips32_op
= OPC_SUXC1
;
11913 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11916 goto pool32f_invalid
;
11921 fmt
= (ctx
->opcode
>> 9) & 0x3;
11922 switch ((ctx
->opcode
>> 6) & 0x7) {
11926 mips32_op
= OPC_RSQRT2_S
;
11929 mips32_op
= OPC_RSQRT2_D
;
11932 mips32_op
= OPC_RSQRT2_PS
;
11935 goto pool32f_invalid
;
11941 mips32_op
= OPC_RECIP2_S
;
11944 mips32_op
= OPC_RECIP2_D
;
11947 mips32_op
= OPC_RECIP2_PS
;
11950 goto pool32f_invalid
;
11954 mips32_op
= OPC_ADDR_PS
;
11957 mips32_op
= OPC_MULR_PS
;
11959 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11962 goto pool32f_invalid
;
11966 /* MOV[FT].fmt and PREFX */
11967 cc
= (ctx
->opcode
>> 13) & 0x7;
11968 fmt
= (ctx
->opcode
>> 9) & 0x3;
11969 switch ((ctx
->opcode
>> 6) & 0x7) {
11973 gen_movcf_s(rs
, rt
, cc
, 0);
11976 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
11979 gen_movcf_ps(rs
, rt
, cc
, 0);
11982 goto pool32f_invalid
;
11988 gen_movcf_s(rs
, rt
, cc
, 1);
11991 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
11994 gen_movcf_ps(rs
, rt
, cc
, 1);
11997 goto pool32f_invalid
;
12003 goto pool32f_invalid
;
12006 #define FINSN_3ARG_SDPS(prfx) \
12007 switch ((ctx->opcode >> 8) & 0x3) { \
12009 mips32_op = OPC_##prfx##_S; \
12012 mips32_op = OPC_##prfx##_D; \
12014 case FMT_SDPS_PS: \
12015 mips32_op = OPC_##prfx##_PS; \
12018 goto pool32f_invalid; \
12021 /* regular FP ops */
12022 switch ((ctx
->opcode
>> 6) & 0x3) {
12024 FINSN_3ARG_SDPS(ADD
);
12027 FINSN_3ARG_SDPS(SUB
);
12030 FINSN_3ARG_SDPS(MUL
);
12033 fmt
= (ctx
->opcode
>> 8) & 0x3;
12035 mips32_op
= OPC_DIV_D
;
12036 } else if (fmt
== 0) {
12037 mips32_op
= OPC_DIV_S
;
12039 goto pool32f_invalid
;
12043 goto pool32f_invalid
;
12048 switch ((ctx
->opcode
>> 6) & 0x3) {
12050 FINSN_3ARG_SDPS(MOVN
);
12053 FINSN_3ARG_SDPS(MOVZ
);
12056 goto pool32f_invalid
;
12060 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12064 MIPS_INVAL("pool32f");
12065 generate_exception(ctx
, EXCP_RI
);
12069 generate_exception_err(ctx
, EXCP_CpU
, 1);
12073 minor
= (ctx
->opcode
>> 21) & 0x1f;
12076 mips32_op
= OPC_BLTZ
;
12079 mips32_op
= OPC_BLTZAL
;
12082 mips32_op
= OPC_BLTZALS
;
12085 mips32_op
= OPC_BGEZ
;
12088 mips32_op
= OPC_BGEZAL
;
12091 mips32_op
= OPC_BGEZALS
;
12094 mips32_op
= OPC_BLEZ
;
12097 mips32_op
= OPC_BGTZ
;
12099 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12104 mips32_op
= OPC_TLTI
;
12107 mips32_op
= OPC_TGEI
;
12110 mips32_op
= OPC_TLTIU
;
12113 mips32_op
= OPC_TGEIU
;
12116 mips32_op
= OPC_TNEI
;
12119 mips32_op
= OPC_TEQI
;
12121 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12126 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12127 4, rs
, 0, imm
<< 1);
12128 /* Compact branches don't have a delay slot, so just let
12129 the normal delay slot handling take us to the branch
12133 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12139 /* COP2: Not implemented. */
12140 generate_exception_err(ctx
, EXCP_CpU
, 2);
12143 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12146 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12149 mips32_op
= OPC_BC1FANY4
;
12152 mips32_op
= OPC_BC1TANY4
;
12155 check_insn(ctx
, ASE_MIPS3D
);
12158 gen_compute_branch1(ctx
, mips32_op
,
12159 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12163 /* MIPS DSP: not implemented */
12166 MIPS_INVAL("pool32i");
12167 generate_exception(ctx
, EXCP_RI
);
12172 minor
= (ctx
->opcode
>> 12) & 0xf;
12175 mips32_op
= OPC_LWL
;
12178 mips32_op
= OPC_SWL
;
12181 mips32_op
= OPC_LWR
;
12184 mips32_op
= OPC_SWR
;
12186 #if defined(TARGET_MIPS64)
12188 mips32_op
= OPC_LDL
;
12191 mips32_op
= OPC_SDL
;
12194 mips32_op
= OPC_LDR
;
12197 mips32_op
= OPC_SDR
;
12200 mips32_op
= OPC_LWU
;
12203 mips32_op
= OPC_LLD
;
12207 mips32_op
= OPC_LL
;
12210 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12213 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12216 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12218 #if defined(TARGET_MIPS64)
12220 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12224 /* Treat as no-op */
12227 MIPS_INVAL("pool32c");
12228 generate_exception(ctx
, EXCP_RI
);
12233 mips32_op
= OPC_ADDI
;
12236 mips32_op
= OPC_ADDIU
;
12238 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12241 /* Logical operations */
12243 mips32_op
= OPC_ORI
;
12246 mips32_op
= OPC_XORI
;
12249 mips32_op
= OPC_ANDI
;
12251 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12254 /* Set less than immediate */
12256 mips32_op
= OPC_SLTI
;
12259 mips32_op
= OPC_SLTIU
;
12261 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12264 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12265 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12268 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12269 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12272 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12275 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12278 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12279 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12282 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12283 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12285 /* Floating point (COP1) */
12287 mips32_op
= OPC_LWC1
;
12290 mips32_op
= OPC_LDC1
;
12293 mips32_op
= OPC_SWC1
;
12296 mips32_op
= OPC_SDC1
;
12298 gen_cop1_ldst(env
, ctx
, mips32_op
, rt
, rs
, imm
);
12302 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12303 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12305 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12308 /* Loads and stores */
12310 mips32_op
= OPC_LB
;
12313 mips32_op
= OPC_LBU
;
12316 mips32_op
= OPC_LH
;
12319 mips32_op
= OPC_LHU
;
12322 mips32_op
= OPC_LW
;
12324 #ifdef TARGET_MIPS64
12326 mips32_op
= OPC_LD
;
12329 mips32_op
= OPC_SD
;
12333 mips32_op
= OPC_SB
;
12336 mips32_op
= OPC_SH
;
12339 mips32_op
= OPC_SW
;
12342 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12345 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12348 generate_exception(ctx
, EXCP_RI
);
12353 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
12357 /* make sure instructions are on a halfword boundary */
12358 if (ctx
->pc
& 0x1) {
12359 env
->CP0_BadVAddr
= ctx
->pc
;
12360 generate_exception(ctx
, EXCP_AdEL
);
12361 ctx
->bstate
= BS_STOP
;
12365 op
= (ctx
->opcode
>> 10) & 0x3f;
12366 /* Enforce properly-sized instructions in a delay slot */
12367 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12368 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12406 if (bits
& MIPS_HFLAG_BDS16
) {
12407 generate_exception(ctx
, EXCP_RI
);
12408 /* Just stop translation; the user is confused. */
12409 ctx
->bstate
= BS_STOP
;
12434 if (bits
& MIPS_HFLAG_BDS32
) {
12435 generate_exception(ctx
, EXCP_RI
);
12436 /* Just stop translation; the user is confused. */
12437 ctx
->bstate
= BS_STOP
;
12448 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12449 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12450 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12453 switch (ctx
->opcode
& 0x1) {
12462 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12467 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12468 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12469 int amount
= (ctx
->opcode
>> 1) & 0x7;
12471 amount
= amount
== 0 ? 8 : amount
;
12473 switch (ctx
->opcode
& 0x1) {
12482 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12486 gen_pool16c_insn(ctx
);
12490 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12491 int rb
= 28; /* GP */
12492 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12494 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12498 if (ctx
->opcode
& 1) {
12499 generate_exception(ctx
, EXCP_RI
);
12502 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12503 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12504 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12505 int rd
, rs
, re
, rt
;
12506 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12507 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12508 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12510 rd
= rd_enc
[enc_dest
];
12511 re
= re_enc
[enc_dest
];
12512 rs
= rs_rt_enc
[enc_rs
];
12513 rt
= rs_rt_enc
[enc_rt
];
12515 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12516 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12521 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12522 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12523 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12524 offset
= (offset
== 0xf ? -1 : offset
);
12526 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12531 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12532 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12533 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12535 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12540 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12541 int rb
= 29; /* SP */
12542 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12544 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12549 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12550 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12551 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12553 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12558 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12559 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12560 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12562 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12567 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12568 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12569 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12571 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12576 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12577 int rb
= 29; /* SP */
12578 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12580 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12585 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12586 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12587 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12589 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12594 int rd
= uMIPS_RD5(ctx
->opcode
);
12595 int rs
= uMIPS_RS5(ctx
->opcode
);
12597 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12604 switch (ctx
->opcode
& 0x1) {
12614 switch (ctx
->opcode
& 0x1) {
12619 gen_addiur1sp(ctx
);
12624 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12625 SIMM(ctx
->opcode
, 0, 10) << 1);
12629 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12630 mmreg(uMIPS_RD(ctx
->opcode
)),
12631 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12635 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12636 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12638 imm
= (imm
== 0x7f ? -1 : imm
);
12639 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12649 generate_exception(ctx
, EXCP_RI
);
12652 decode_micromips32_opc (env
, ctx
, op
);
12659 /* SmartMIPS extension to MIPS32 */
12661 #if defined(TARGET_MIPS64)
12663 /* MDMX extension to MIPS64 */
12667 /* MIPSDSP functions. */
12668 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12669 int rd
, int base
, int offset
)
12671 const char *opn
= "ldx";
12675 t0
= tcg_temp_new();
12678 gen_load_gpr(t0
, offset
);
12679 } else if (offset
== 0) {
12680 gen_load_gpr(t0
, base
);
12682 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12687 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
12688 gen_store_gpr(t0
, rd
);
12692 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
12693 gen_store_gpr(t0
, rd
);
12697 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12698 gen_store_gpr(t0
, rd
);
12701 #if defined(TARGET_MIPS64)
12703 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12704 gen_store_gpr(t0
, rd
);
12709 (void)opn
; /* avoid a compiler warning */
12710 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12711 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12715 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12716 int ret
, int v1
, int v2
)
12718 const char *opn
= "mipsdsp arith";
12723 /* Treat as NOP. */
12728 v1_t
= tcg_temp_new();
12729 v2_t
= tcg_temp_new();
12731 gen_load_gpr(v1_t
, v1
);
12732 gen_load_gpr(v2_t
, v2
);
12735 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12736 case OPC_MULT_G_2E
:
12740 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12742 case OPC_ADDUH_R_QB
:
12743 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12746 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12748 case OPC_ADDQH_R_PH
:
12749 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12752 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12754 case OPC_ADDQH_R_W
:
12755 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12758 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12760 case OPC_SUBUH_R_QB
:
12761 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12764 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12766 case OPC_SUBQH_R_PH
:
12767 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12770 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12772 case OPC_SUBQH_R_W
:
12773 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12777 case OPC_ABSQ_S_PH_DSP
:
12779 case OPC_ABSQ_S_QB
:
12781 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12783 case OPC_ABSQ_S_PH
:
12785 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12789 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12791 case OPC_PRECEQ_W_PHL
:
12793 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12794 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12796 case OPC_PRECEQ_W_PHR
:
12798 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12799 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12800 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12802 case OPC_PRECEQU_PH_QBL
:
12804 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12806 case OPC_PRECEQU_PH_QBR
:
12808 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12810 case OPC_PRECEQU_PH_QBLA
:
12812 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12814 case OPC_PRECEQU_PH_QBRA
:
12816 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12818 case OPC_PRECEU_PH_QBL
:
12820 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12822 case OPC_PRECEU_PH_QBR
:
12824 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12826 case OPC_PRECEU_PH_QBLA
:
12828 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12830 case OPC_PRECEU_PH_QBRA
:
12832 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12836 case OPC_ADDU_QB_DSP
:
12840 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12842 case OPC_ADDQ_S_PH
:
12844 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12848 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12852 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12854 case OPC_ADDU_S_QB
:
12856 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12860 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12862 case OPC_ADDU_S_PH
:
12864 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12868 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12870 case OPC_SUBQ_S_PH
:
12872 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12876 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12880 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12882 case OPC_SUBU_S_QB
:
12884 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12888 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12890 case OPC_SUBU_S_PH
:
12892 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12896 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12900 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12904 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12906 case OPC_RADDU_W_QB
:
12908 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12912 case OPC_CMPU_EQ_QB_DSP
:
12914 case OPC_PRECR_QB_PH
:
12916 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12918 case OPC_PRECRQ_QB_PH
:
12920 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12922 case OPC_PRECR_SRA_PH_W
:
12925 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12926 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12928 tcg_temp_free_i32(sa_t
);
12931 case OPC_PRECR_SRA_R_PH_W
:
12934 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12935 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12937 tcg_temp_free_i32(sa_t
);
12940 case OPC_PRECRQ_PH_W
:
12942 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12944 case OPC_PRECRQ_RS_PH_W
:
12946 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12948 case OPC_PRECRQU_S_QB_PH
:
12950 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12954 #ifdef TARGET_MIPS64
12955 case OPC_ABSQ_S_QH_DSP
:
12957 case OPC_PRECEQ_L_PWL
:
12959 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
12961 case OPC_PRECEQ_L_PWR
:
12963 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
12965 case OPC_PRECEQ_PW_QHL
:
12967 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
12969 case OPC_PRECEQ_PW_QHR
:
12971 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
12973 case OPC_PRECEQ_PW_QHLA
:
12975 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
12977 case OPC_PRECEQ_PW_QHRA
:
12979 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
12981 case OPC_PRECEQU_QH_OBL
:
12983 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
12985 case OPC_PRECEQU_QH_OBR
:
12987 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
12989 case OPC_PRECEQU_QH_OBLA
:
12991 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
12993 case OPC_PRECEQU_QH_OBRA
:
12995 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
12997 case OPC_PRECEU_QH_OBL
:
12999 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
13001 case OPC_PRECEU_QH_OBR
:
13003 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
13005 case OPC_PRECEU_QH_OBLA
:
13007 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
13009 case OPC_PRECEU_QH_OBRA
:
13011 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
13013 case OPC_ABSQ_S_OB
:
13015 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
13017 case OPC_ABSQ_S_PW
:
13019 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
13021 case OPC_ABSQ_S_QH
:
13023 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
13027 case OPC_ADDU_OB_DSP
:
13029 case OPC_RADDU_L_OB
:
13031 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
13035 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13037 case OPC_SUBQ_S_PW
:
13039 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13043 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13045 case OPC_SUBQ_S_QH
:
13047 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13051 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13053 case OPC_SUBU_S_OB
:
13055 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13059 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13061 case OPC_SUBU_S_QH
:
13063 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13067 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13069 case OPC_SUBUH_R_OB
:
13071 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13075 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13077 case OPC_ADDQ_S_PW
:
13079 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13083 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13085 case OPC_ADDQ_S_QH
:
13087 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13091 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13093 case OPC_ADDU_S_OB
:
13095 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13099 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13101 case OPC_ADDU_S_QH
:
13103 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13107 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13109 case OPC_ADDUH_R_OB
:
13111 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13115 case OPC_CMPU_EQ_OB_DSP
:
13117 case OPC_PRECR_OB_QH
:
13119 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13121 case OPC_PRECR_SRA_QH_PW
:
13124 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13125 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13126 tcg_temp_free_i32(ret_t
);
13129 case OPC_PRECR_SRA_R_QH_PW
:
13132 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13133 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13134 tcg_temp_free_i32(sa_v
);
13137 case OPC_PRECRQ_OB_QH
:
13139 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13141 case OPC_PRECRQ_PW_L
:
13143 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13145 case OPC_PRECRQ_QH_PW
:
13147 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13149 case OPC_PRECRQ_RS_QH_PW
:
13151 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13153 case OPC_PRECRQU_S_OB_QH
:
13155 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13162 tcg_temp_free(v1_t
);
13163 tcg_temp_free(v2_t
);
13165 (void)opn
; /* avoid a compiler warning */
13166 MIPS_DEBUG("%s", opn
);
13169 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13170 int ret
, int v1
, int v2
)
13173 const char *opn
= "mipsdsp shift";
13179 /* Treat as NOP. */
13184 t0
= tcg_temp_new();
13185 v1_t
= tcg_temp_new();
13186 v2_t
= tcg_temp_new();
13188 tcg_gen_movi_tl(t0
, v1
);
13189 gen_load_gpr(v1_t
, v1
);
13190 gen_load_gpr(v2_t
, v2
);
13193 case OPC_SHLL_QB_DSP
:
13195 op2
= MASK_SHLL_QB(ctx
->opcode
);
13199 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13203 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13207 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13211 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13213 case OPC_SHLL_S_PH
:
13215 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13217 case OPC_SHLLV_S_PH
:
13219 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13223 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13225 case OPC_SHLLV_S_W
:
13227 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13231 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13235 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13239 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13243 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13247 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13249 case OPC_SHRA_R_QB
:
13251 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13255 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13257 case OPC_SHRAV_R_QB
:
13259 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13263 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13265 case OPC_SHRA_R_PH
:
13267 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13271 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13273 case OPC_SHRAV_R_PH
:
13275 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13279 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13281 case OPC_SHRAV_R_W
:
13283 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13285 default: /* Invalid */
13286 MIPS_INVAL("MASK SHLL.QB");
13287 generate_exception(ctx
, EXCP_RI
);
13292 #ifdef TARGET_MIPS64
13293 case OPC_SHLL_OB_DSP
:
13294 op2
= MASK_SHLL_OB(ctx
->opcode
);
13298 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13302 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13304 case OPC_SHLL_S_PW
:
13306 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13308 case OPC_SHLLV_S_PW
:
13310 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13314 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13318 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13322 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13326 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13328 case OPC_SHLL_S_QH
:
13330 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13332 case OPC_SHLLV_S_QH
:
13334 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13338 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13342 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13344 case OPC_SHRA_R_OB
:
13346 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13348 case OPC_SHRAV_R_OB
:
13350 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13354 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13358 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13360 case OPC_SHRA_R_PW
:
13362 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13364 case OPC_SHRAV_R_PW
:
13366 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13370 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13374 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13376 case OPC_SHRA_R_QH
:
13378 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13380 case OPC_SHRAV_R_QH
:
13382 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13386 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13390 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13394 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13398 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13400 default: /* Invalid */
13401 MIPS_INVAL("MASK SHLL.OB");
13402 generate_exception(ctx
, EXCP_RI
);
13410 tcg_temp_free(v1_t
);
13411 tcg_temp_free(v2_t
);
13412 (void)opn
; /* avoid a compiler warning */
13413 MIPS_DEBUG("%s", opn
);
13416 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13417 int ret
, int v1
, int v2
, int check_ret
)
13419 const char *opn
= "mipsdsp multiply";
13424 if ((ret
== 0) && (check_ret
== 1)) {
13425 /* Treat as NOP. */
13430 t0
= tcg_temp_new_i32();
13431 v1_t
= tcg_temp_new();
13432 v2_t
= tcg_temp_new();
13434 tcg_gen_movi_i32(t0
, ret
);
13435 gen_load_gpr(v1_t
, v1
);
13436 gen_load_gpr(v2_t
, v2
);
13439 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13440 * the same mask and op1. */
13441 case OPC_MULT_G_2E
:
13445 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13448 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13451 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13453 case OPC_MULQ_RS_W
:
13454 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13458 case OPC_DPA_W_PH_DSP
:
13460 case OPC_DPAU_H_QBL
:
13462 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13464 case OPC_DPAU_H_QBR
:
13466 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13468 case OPC_DPSU_H_QBL
:
13470 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13472 case OPC_DPSU_H_QBR
:
13474 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13478 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13480 case OPC_DPAX_W_PH
:
13482 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13484 case OPC_DPAQ_S_W_PH
:
13486 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13488 case OPC_DPAQX_S_W_PH
:
13490 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13492 case OPC_DPAQX_SA_W_PH
:
13494 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13498 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13500 case OPC_DPSX_W_PH
:
13502 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13504 case OPC_DPSQ_S_W_PH
:
13506 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13508 case OPC_DPSQX_S_W_PH
:
13510 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13512 case OPC_DPSQX_SA_W_PH
:
13514 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13516 case OPC_MULSAQ_S_W_PH
:
13518 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13520 case OPC_DPAQ_SA_L_W
:
13522 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13524 case OPC_DPSQ_SA_L_W
:
13526 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13528 case OPC_MAQ_S_W_PHL
:
13530 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13532 case OPC_MAQ_S_W_PHR
:
13534 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13536 case OPC_MAQ_SA_W_PHL
:
13538 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13540 case OPC_MAQ_SA_W_PHR
:
13542 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13544 case OPC_MULSA_W_PH
:
13546 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13550 #ifdef TARGET_MIPS64
13551 case OPC_DPAQ_W_QH_DSP
:
13553 int ac
= ret
& 0x03;
13554 tcg_gen_movi_i32(t0
, ac
);
13559 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13563 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13567 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13571 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13575 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13577 case OPC_DPAQ_S_W_QH
:
13579 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13581 case OPC_DPAQ_SA_L_PW
:
13583 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13585 case OPC_DPAU_H_OBL
:
13587 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13589 case OPC_DPAU_H_OBR
:
13591 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13595 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13597 case OPC_DPSQ_S_W_QH
:
13599 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13601 case OPC_DPSQ_SA_L_PW
:
13603 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13605 case OPC_DPSU_H_OBL
:
13607 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13609 case OPC_DPSU_H_OBR
:
13611 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13613 case OPC_MAQ_S_L_PWL
:
13615 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13617 case OPC_MAQ_S_L_PWR
:
13619 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13621 case OPC_MAQ_S_W_QHLL
:
13623 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13625 case OPC_MAQ_SA_W_QHLL
:
13627 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13629 case OPC_MAQ_S_W_QHLR
:
13631 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13633 case OPC_MAQ_SA_W_QHLR
:
13635 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13637 case OPC_MAQ_S_W_QHRL
:
13639 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13641 case OPC_MAQ_SA_W_QHRL
:
13643 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13645 case OPC_MAQ_S_W_QHRR
:
13647 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13649 case OPC_MAQ_SA_W_QHRR
:
13651 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13653 case OPC_MULSAQ_S_L_PW
:
13655 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13657 case OPC_MULSAQ_S_W_QH
:
13659 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13665 case OPC_ADDU_QB_DSP
:
13667 case OPC_MULEU_S_PH_QBL
:
13669 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13671 case OPC_MULEU_S_PH_QBR
:
13673 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13675 case OPC_MULQ_RS_PH
:
13677 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13679 case OPC_MULEQ_S_W_PHL
:
13681 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13683 case OPC_MULEQ_S_W_PHR
:
13685 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13687 case OPC_MULQ_S_PH
:
13689 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13693 #ifdef TARGET_MIPS64
13694 case OPC_ADDU_OB_DSP
:
13696 case OPC_MULEQ_S_PW_QHL
:
13698 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13700 case OPC_MULEQ_S_PW_QHR
:
13702 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13704 case OPC_MULEU_S_QH_OBL
:
13706 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13708 case OPC_MULEU_S_QH_OBR
:
13710 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13712 case OPC_MULQ_RS_QH
:
13714 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13721 tcg_temp_free_i32(t0
);
13722 tcg_temp_free(v1_t
);
13723 tcg_temp_free(v2_t
);
13725 (void)opn
; /* avoid a compiler warning */
13726 MIPS_DEBUG("%s", opn
);
13730 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13733 const char *opn
= "mipsdsp Bit/ Manipulation";
13739 /* Treat as NOP. */
13744 t0
= tcg_temp_new();
13745 val_t
= tcg_temp_new();
13746 gen_load_gpr(val_t
, val
);
13749 case OPC_ABSQ_S_PH_DSP
:
13753 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13758 target_long result
;
13759 imm
= (ctx
->opcode
>> 16) & 0xFF;
13760 result
= (uint32_t)imm
<< 24 |
13761 (uint32_t)imm
<< 16 |
13762 (uint32_t)imm
<< 8 |
13764 result
= (int32_t)result
;
13765 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13770 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13771 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13772 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13773 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13774 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13775 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13780 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13781 imm
= (int16_t)(imm
<< 6) >> 6;
13782 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13783 (target_long
)((int32_t)imm
<< 16 | \
13789 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13790 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13791 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13792 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13796 #ifdef TARGET_MIPS64
13797 case OPC_ABSQ_S_QH_DSP
:
13804 imm
= (ctx
->opcode
>> 16) & 0xFF;
13805 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13806 temp
= (temp
<< 16) | temp
;
13807 temp
= (temp
<< 32) | temp
;
13808 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13816 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13817 imm
= (int16_t)(imm
<< 6) >> 6;
13818 temp
= ((target_long
)imm
<< 32) \
13819 | ((target_long
)imm
& 0xFFFFFFFF);
13820 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13828 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13829 imm
= (int16_t)(imm
<< 6) >> 6;
13831 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13832 ((uint64_t)(uint16_t)imm
<< 32) |
13833 ((uint64_t)(uint16_t)imm
<< 16) |
13834 (uint64_t)(uint16_t)imm
;
13835 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13840 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13841 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13842 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13843 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13844 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13845 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13846 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13850 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13851 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13852 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13856 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13857 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13858 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13859 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13860 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13867 tcg_temp_free(val_t
);
13869 (void)opn
; /* avoid a compiler warning */
13870 MIPS_DEBUG("%s", opn
);
13873 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13874 uint32_t op1
, uint32_t op2
,
13875 int ret
, int v1
, int v2
, int check_ret
)
13877 const char *opn
= "mipsdsp add compare pick";
13882 if ((ret
== 0) && (check_ret
== 1)) {
13883 /* Treat as NOP. */
13888 t1
= tcg_temp_new();
13889 v1_t
= tcg_temp_new();
13890 v2_t
= tcg_temp_new();
13892 gen_load_gpr(v1_t
, v1
);
13893 gen_load_gpr(v2_t
, v2
);
13896 case OPC_CMPU_EQ_QB_DSP
:
13898 case OPC_CMPU_EQ_QB
:
13900 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13902 case OPC_CMPU_LT_QB
:
13904 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13906 case OPC_CMPU_LE_QB
:
13908 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13910 case OPC_CMPGU_EQ_QB
:
13912 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13914 case OPC_CMPGU_LT_QB
:
13916 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13918 case OPC_CMPGU_LE_QB
:
13920 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13922 case OPC_CMPGDU_EQ_QB
:
13924 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13925 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13926 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13927 tcg_gen_shli_tl(t1
, t1
, 24);
13928 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13930 case OPC_CMPGDU_LT_QB
:
13932 gen_helper_cmpgu_lt_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_LE_QB
:
13940 gen_helper_cmpgu_le_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_CMP_EQ_PH
:
13948 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
13950 case OPC_CMP_LT_PH
:
13952 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
13954 case OPC_CMP_LE_PH
:
13956 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
13960 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13964 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13966 case OPC_PACKRL_PH
:
13968 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13972 #ifdef TARGET_MIPS64
13973 case OPC_CMPU_EQ_OB_DSP
:
13975 case OPC_CMP_EQ_PW
:
13977 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
13979 case OPC_CMP_LT_PW
:
13981 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
13983 case OPC_CMP_LE_PW
:
13985 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
13987 case OPC_CMP_EQ_QH
:
13989 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
13991 case OPC_CMP_LT_QH
:
13993 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
13995 case OPC_CMP_LE_QH
:
13997 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
13999 case OPC_CMPGDU_EQ_OB
:
14001 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14003 case OPC_CMPGDU_LT_OB
:
14005 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14007 case OPC_CMPGDU_LE_OB
:
14009 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14011 case OPC_CMPGU_EQ_OB
:
14013 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14015 case OPC_CMPGU_LT_OB
:
14017 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14019 case OPC_CMPGU_LE_OB
:
14021 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14023 case OPC_CMPU_EQ_OB
:
14025 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
14027 case OPC_CMPU_LT_OB
:
14029 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
14031 case OPC_CMPU_LE_OB
:
14033 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
14035 case OPC_PACKRL_PW
:
14037 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14041 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14045 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14049 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14057 tcg_temp_free(v1_t
);
14058 tcg_temp_free(v2_t
);
14060 (void)opn
; /* avoid a compiler warning */
14061 MIPS_DEBUG("%s", opn
);
14064 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14065 uint32_t op1
, int rt
, int rs
, int sa
)
14067 const char *opn
= "mipsdsp append/dappend";
14073 /* Treat as NOP. */
14078 t0
= tcg_temp_new();
14079 gen_load_gpr(t0
, rs
);
14082 case OPC_APPEND_DSP
:
14083 switch (MASK_APPEND(ctx
->opcode
)) {
14086 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14088 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14092 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14093 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14094 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14095 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14097 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14101 if (sa
!= 0 && sa
!= 2) {
14102 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14103 tcg_gen_ext32u_tl(t0
, t0
);
14104 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14105 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14107 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14109 default: /* Invalid */
14110 MIPS_INVAL("MASK APPEND");
14111 generate_exception(ctx
, EXCP_RI
);
14115 #ifdef TARGET_MIPS64
14116 case OPC_DAPPEND_DSP
:
14117 switch (MASK_DAPPEND(ctx
->opcode
)) {
14120 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14124 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14125 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14126 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14130 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14131 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14132 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14137 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14138 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14139 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14140 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14143 default: /* Invalid */
14144 MIPS_INVAL("MASK DAPPEND");
14145 generate_exception(ctx
, EXCP_RI
);
14152 (void)opn
; /* avoid a compiler warning */
14153 MIPS_DEBUG("%s", opn
);
14156 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14157 int ret
, int v1
, int v2
, int check_ret
)
14160 const char *opn
= "mipsdsp accumulator";
14167 if ((ret
== 0) && (check_ret
== 1)) {
14168 /* Treat as NOP. */
14173 t0
= tcg_temp_new();
14174 t1
= tcg_temp_new();
14175 v1_t
= tcg_temp_new();
14176 v2_t
= tcg_temp_new();
14178 gen_load_gpr(v1_t
, v1
);
14179 gen_load_gpr(v2_t
, v2
);
14182 case OPC_EXTR_W_DSP
:
14186 tcg_gen_movi_tl(t0
, v2
);
14187 tcg_gen_movi_tl(t1
, v1
);
14188 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14191 tcg_gen_movi_tl(t0
, v2
);
14192 tcg_gen_movi_tl(t1
, v1
);
14193 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14195 case OPC_EXTR_RS_W
:
14196 tcg_gen_movi_tl(t0
, v2
);
14197 tcg_gen_movi_tl(t1
, v1
);
14198 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14201 tcg_gen_movi_tl(t0
, v2
);
14202 tcg_gen_movi_tl(t1
, v1
);
14203 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14205 case OPC_EXTRV_S_H
:
14206 tcg_gen_movi_tl(t0
, v2
);
14207 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14210 tcg_gen_movi_tl(t0
, v2
);
14211 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14213 case OPC_EXTRV_R_W
:
14214 tcg_gen_movi_tl(t0
, v2
);
14215 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14217 case OPC_EXTRV_RS_W
:
14218 tcg_gen_movi_tl(t0
, v2
);
14219 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14222 tcg_gen_movi_tl(t0
, v2
);
14223 tcg_gen_movi_tl(t1
, v1
);
14224 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14227 tcg_gen_movi_tl(t0
, v2
);
14228 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14231 tcg_gen_movi_tl(t0
, v2
);
14232 tcg_gen_movi_tl(t1
, v1
);
14233 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14236 tcg_gen_movi_tl(t0
, v2
);
14237 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14240 imm
= (ctx
->opcode
>> 20) & 0x3F;
14241 tcg_gen_movi_tl(t0
, ret
);
14242 tcg_gen_movi_tl(t1
, imm
);
14243 gen_helper_shilo(t0
, t1
, cpu_env
);
14246 tcg_gen_movi_tl(t0
, ret
);
14247 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14250 tcg_gen_movi_tl(t0
, ret
);
14251 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14254 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14255 tcg_gen_movi_tl(t0
, imm
);
14256 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14259 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14260 tcg_gen_movi_tl(t0
, imm
);
14261 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14265 #ifdef TARGET_MIPS64
14266 case OPC_DEXTR_W_DSP
:
14270 tcg_gen_movi_tl(t0
, ret
);
14271 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14275 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14276 int ac
= (ctx
->opcode
>> 11) & 0x03;
14277 tcg_gen_movi_tl(t0
, shift
);
14278 tcg_gen_movi_tl(t1
, ac
);
14279 gen_helper_dshilo(t0
, t1
, cpu_env
);
14284 int ac
= (ctx
->opcode
>> 11) & 0x03;
14285 tcg_gen_movi_tl(t0
, ac
);
14286 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14290 tcg_gen_movi_tl(t0
, v2
);
14291 tcg_gen_movi_tl(t1
, v1
);
14293 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14296 tcg_gen_movi_tl(t0
, v2
);
14297 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14300 tcg_gen_movi_tl(t0
, v2
);
14301 tcg_gen_movi_tl(t1
, v1
);
14302 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14305 tcg_gen_movi_tl(t0
, v2
);
14306 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14309 tcg_gen_movi_tl(t0
, v2
);
14310 tcg_gen_movi_tl(t1
, v1
);
14311 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14313 case OPC_DEXTR_R_L
:
14314 tcg_gen_movi_tl(t0
, v2
);
14315 tcg_gen_movi_tl(t1
, v1
);
14316 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14318 case OPC_DEXTR_RS_L
:
14319 tcg_gen_movi_tl(t0
, v2
);
14320 tcg_gen_movi_tl(t1
, v1
);
14321 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14324 tcg_gen_movi_tl(t0
, v2
);
14325 tcg_gen_movi_tl(t1
, v1
);
14326 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14328 case OPC_DEXTR_R_W
:
14329 tcg_gen_movi_tl(t0
, v2
);
14330 tcg_gen_movi_tl(t1
, v1
);
14331 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14333 case OPC_DEXTR_RS_W
:
14334 tcg_gen_movi_tl(t0
, v2
);
14335 tcg_gen_movi_tl(t1
, v1
);
14336 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14338 case OPC_DEXTR_S_H
:
14339 tcg_gen_movi_tl(t0
, v2
);
14340 tcg_gen_movi_tl(t1
, v1
);
14341 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14343 case OPC_DEXTRV_S_H
:
14344 tcg_gen_movi_tl(t0
, v2
);
14345 tcg_gen_movi_tl(t1
, v1
);
14346 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14349 tcg_gen_movi_tl(t0
, v2
);
14350 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14352 case OPC_DEXTRV_R_L
:
14353 tcg_gen_movi_tl(t0
, v2
);
14354 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14356 case OPC_DEXTRV_RS_L
:
14357 tcg_gen_movi_tl(t0
, v2
);
14358 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14361 tcg_gen_movi_tl(t0
, v2
);
14362 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14364 case OPC_DEXTRV_R_W
:
14365 tcg_gen_movi_tl(t0
, v2
);
14366 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14368 case OPC_DEXTRV_RS_W
:
14369 tcg_gen_movi_tl(t0
, v2
);
14370 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14379 tcg_temp_free(v1_t
);
14380 tcg_temp_free(v2_t
);
14382 (void)opn
; /* avoid a compiler warning */
14383 MIPS_DEBUG("%s", opn
);
14386 /* End MIPSDSP functions. */
14388 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
14391 int rs
, rt
, rd
, sa
;
14392 uint32_t op
, op1
, op2
;
14395 /* make sure instructions are on a word boundary */
14396 if (ctx
->pc
& 0x3) {
14397 env
->CP0_BadVAddr
= ctx
->pc
;
14398 generate_exception(ctx
, EXCP_AdEL
);
14402 /* Handle blikely not taken case */
14403 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14404 int l1
= gen_new_label();
14406 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14407 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14408 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14409 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14413 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14414 tcg_gen_debug_insn_start(ctx
->pc
);
14417 op
= MASK_OP_MAJOR(ctx
->opcode
);
14418 rs
= (ctx
->opcode
>> 21) & 0x1f;
14419 rt
= (ctx
->opcode
>> 16) & 0x1f;
14420 rd
= (ctx
->opcode
>> 11) & 0x1f;
14421 sa
= (ctx
->opcode
>> 6) & 0x1f;
14422 imm
= (int16_t)ctx
->opcode
;
14425 op1
= MASK_SPECIAL(ctx
->opcode
);
14427 case OPC_SLL
: /* Shift with immediate */
14429 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14432 switch ((ctx
->opcode
>> 21) & 0x1f) {
14434 /* rotr is decoded as srl on non-R2 CPUs */
14435 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14440 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14443 generate_exception(ctx
, EXCP_RI
);
14447 case OPC_MOVN
: /* Conditional move */
14449 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14450 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14451 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14453 case OPC_ADD
... OPC_SUBU
:
14454 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14456 case OPC_SLLV
: /* Shifts */
14458 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14461 switch ((ctx
->opcode
>> 6) & 0x1f) {
14463 /* rotrv is decoded as srlv on non-R2 CPUs */
14464 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14469 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14472 generate_exception(ctx
, EXCP_RI
);
14476 case OPC_SLT
: /* Set on less than */
14478 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14480 case OPC_AND
: /* Logic*/
14484 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14489 check_insn(ctx
, INSN_VR54XX
);
14490 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14491 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14493 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14498 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14500 case OPC_JR
... OPC_JALR
:
14501 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14503 case OPC_TGE
... OPC_TEQ
: /* Traps */
14505 gen_trap(ctx
, op1
, rs
, rt
, -1);
14507 case OPC_MFHI
: /* Move from HI/LO */
14509 gen_HILO(ctx
, op1
, rs
& 3, rd
);
14512 case OPC_MTLO
: /* Move to HI/LO */
14513 gen_HILO(ctx
, op1
, rd
& 3, rs
);
14515 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14516 #ifdef MIPS_STRICT_STANDARD
14517 MIPS_INVAL("PMON / selsl");
14518 generate_exception(ctx
, EXCP_RI
);
14520 gen_helper_0e0i(pmon
, sa
);
14524 generate_exception(ctx
, EXCP_SYSCALL
);
14525 ctx
->bstate
= BS_STOP
;
14528 generate_exception(ctx
, EXCP_BREAK
);
14531 #ifdef MIPS_STRICT_STANDARD
14532 MIPS_INVAL("SPIM");
14533 generate_exception(ctx
, EXCP_RI
);
14535 /* Implemented as RI exception for now. */
14536 MIPS_INVAL("spim (unofficial)");
14537 generate_exception(ctx
, EXCP_RI
);
14541 /* Treat as NOP. */
14545 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14546 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
14547 check_cp1_enabled(ctx
);
14548 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14549 (ctx
->opcode
>> 16) & 1);
14551 generate_exception_err(ctx
, EXCP_CpU
, 1);
14555 #if defined(TARGET_MIPS64)
14556 /* MIPS64 specific opcodes */
14561 check_insn(ctx
, ISA_MIPS3
);
14562 check_mips_64(ctx
);
14563 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14566 switch ((ctx
->opcode
>> 21) & 0x1f) {
14568 /* drotr is decoded as dsrl on non-R2 CPUs */
14569 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14574 check_insn(ctx
, ISA_MIPS3
);
14575 check_mips_64(ctx
);
14576 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14579 generate_exception(ctx
, EXCP_RI
);
14584 switch ((ctx
->opcode
>> 21) & 0x1f) {
14586 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14587 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14592 check_insn(ctx
, ISA_MIPS3
);
14593 check_mips_64(ctx
);
14594 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14597 generate_exception(ctx
, EXCP_RI
);
14601 case OPC_DADD
... OPC_DSUBU
:
14602 check_insn(ctx
, ISA_MIPS3
);
14603 check_mips_64(ctx
);
14604 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14608 check_insn(ctx
, ISA_MIPS3
);
14609 check_mips_64(ctx
);
14610 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14613 switch ((ctx
->opcode
>> 6) & 0x1f) {
14615 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14616 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14621 check_insn(ctx
, ISA_MIPS3
);
14622 check_mips_64(ctx
);
14623 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14626 generate_exception(ctx
, EXCP_RI
);
14630 case OPC_DMULT
... OPC_DDIVU
:
14631 check_insn(ctx
, ISA_MIPS3
);
14632 check_mips_64(ctx
);
14633 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14636 default: /* Invalid */
14637 MIPS_INVAL("special");
14638 generate_exception(ctx
, EXCP_RI
);
14643 op1
= MASK_SPECIAL2(ctx
->opcode
);
14645 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14646 case OPC_MSUB
... OPC_MSUBU
:
14647 check_insn(ctx
, ISA_MIPS32
);
14648 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14651 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14655 check_insn(ctx
, ISA_MIPS32
);
14656 gen_cl(ctx
, op1
, rd
, rs
);
14659 /* XXX: not clear which exception should be raised
14660 * when in debug mode...
14662 check_insn(ctx
, ISA_MIPS32
);
14663 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14664 generate_exception(ctx
, EXCP_DBp
);
14666 generate_exception(ctx
, EXCP_DBp
);
14668 /* Treat as NOP. */
14671 case OPC_DIVU_G_2F
:
14672 case OPC_MULT_G_2F
:
14673 case OPC_MULTU_G_2F
:
14675 case OPC_MODU_G_2F
:
14676 check_insn(ctx
, INSN_LOONGSON2F
);
14677 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14679 #if defined(TARGET_MIPS64)
14682 check_insn(ctx
, ISA_MIPS64
);
14683 check_mips_64(ctx
);
14684 gen_cl(ctx
, op1
, rd
, rs
);
14686 case OPC_DMULT_G_2F
:
14687 case OPC_DMULTU_G_2F
:
14688 case OPC_DDIV_G_2F
:
14689 case OPC_DDIVU_G_2F
:
14690 case OPC_DMOD_G_2F
:
14691 case OPC_DMODU_G_2F
:
14692 check_insn(ctx
, INSN_LOONGSON2F
);
14693 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14696 default: /* Invalid */
14697 MIPS_INVAL("special2");
14698 generate_exception(ctx
, EXCP_RI
);
14703 op1
= MASK_SPECIAL3(ctx
->opcode
);
14707 check_insn(ctx
, ISA_MIPS32R2
);
14708 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14711 check_insn(ctx
, ISA_MIPS32R2
);
14712 op2
= MASK_BSHFL(ctx
->opcode
);
14713 gen_bshfl(ctx
, op2
, rt
, rd
);
14716 gen_rdhwr(ctx
, rt
, rd
);
14719 check_insn(ctx
, ASE_MT
);
14721 TCGv t0
= tcg_temp_new();
14722 TCGv t1
= tcg_temp_new();
14724 gen_load_gpr(t0
, rt
);
14725 gen_load_gpr(t1
, rs
);
14726 gen_helper_fork(t0
, t1
);
14732 check_insn(ctx
, ASE_MT
);
14734 TCGv t0
= tcg_temp_new();
14736 save_cpu_state(ctx
, 1);
14737 gen_load_gpr(t0
, rs
);
14738 gen_helper_yield(t0
, cpu_env
, t0
);
14739 gen_store_gpr(t0
, rd
);
14743 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14744 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14745 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14746 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14747 * the same mask and op1. */
14748 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14749 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14752 case OPC_ADDUH_R_QB
:
14754 case OPC_ADDQH_R_PH
:
14756 case OPC_ADDQH_R_W
:
14758 case OPC_SUBUH_R_QB
:
14760 case OPC_SUBQH_R_PH
:
14762 case OPC_SUBQH_R_W
:
14763 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14768 case OPC_MULQ_RS_W
:
14769 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14772 MIPS_INVAL("MASK ADDUH.QB");
14773 generate_exception(ctx
, EXCP_RI
);
14776 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14777 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14779 generate_exception(ctx
, EXCP_RI
);
14783 op2
= MASK_LX(ctx
->opcode
);
14785 #if defined(TARGET_MIPS64)
14791 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14793 default: /* Invalid */
14794 MIPS_INVAL("MASK LX");
14795 generate_exception(ctx
, EXCP_RI
);
14799 case OPC_ABSQ_S_PH_DSP
:
14800 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14802 case OPC_ABSQ_S_QB
:
14803 case OPC_ABSQ_S_PH
:
14805 case OPC_PRECEQ_W_PHL
:
14806 case OPC_PRECEQ_W_PHR
:
14807 case OPC_PRECEQU_PH_QBL
:
14808 case OPC_PRECEQU_PH_QBR
:
14809 case OPC_PRECEQU_PH_QBLA
:
14810 case OPC_PRECEQU_PH_QBRA
:
14811 case OPC_PRECEU_PH_QBL
:
14812 case OPC_PRECEU_PH_QBR
:
14813 case OPC_PRECEU_PH_QBLA
:
14814 case OPC_PRECEU_PH_QBRA
:
14815 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14822 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14825 MIPS_INVAL("MASK ABSQ_S.PH");
14826 generate_exception(ctx
, EXCP_RI
);
14830 case OPC_ADDU_QB_DSP
:
14831 op2
= MASK_ADDU_QB(ctx
->opcode
);
14834 case OPC_ADDQ_S_PH
:
14837 case OPC_ADDU_S_QB
:
14839 case OPC_ADDU_S_PH
:
14841 case OPC_SUBQ_S_PH
:
14844 case OPC_SUBU_S_QB
:
14846 case OPC_SUBU_S_PH
:
14850 case OPC_RADDU_W_QB
:
14851 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14853 case OPC_MULEU_S_PH_QBL
:
14854 case OPC_MULEU_S_PH_QBR
:
14855 case OPC_MULQ_RS_PH
:
14856 case OPC_MULEQ_S_W_PHL
:
14857 case OPC_MULEQ_S_W_PHR
:
14858 case OPC_MULQ_S_PH
:
14859 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14861 default: /* Invalid */
14862 MIPS_INVAL("MASK ADDU.QB");
14863 generate_exception(ctx
, EXCP_RI
);
14868 case OPC_CMPU_EQ_QB_DSP
:
14869 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14871 case OPC_PRECR_SRA_PH_W
:
14872 case OPC_PRECR_SRA_R_PH_W
:
14873 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14875 case OPC_PRECR_QB_PH
:
14876 case OPC_PRECRQ_QB_PH
:
14877 case OPC_PRECRQ_PH_W
:
14878 case OPC_PRECRQ_RS_PH_W
:
14879 case OPC_PRECRQU_S_QB_PH
:
14880 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14882 case OPC_CMPU_EQ_QB
:
14883 case OPC_CMPU_LT_QB
:
14884 case OPC_CMPU_LE_QB
:
14885 case OPC_CMP_EQ_PH
:
14886 case OPC_CMP_LT_PH
:
14887 case OPC_CMP_LE_PH
:
14888 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14890 case OPC_CMPGU_EQ_QB
:
14891 case OPC_CMPGU_LT_QB
:
14892 case OPC_CMPGU_LE_QB
:
14893 case OPC_CMPGDU_EQ_QB
:
14894 case OPC_CMPGDU_LT_QB
:
14895 case OPC_CMPGDU_LE_QB
:
14898 case OPC_PACKRL_PH
:
14899 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14901 default: /* Invalid */
14902 MIPS_INVAL("MASK CMPU.EQ.QB");
14903 generate_exception(ctx
, EXCP_RI
);
14907 case OPC_SHLL_QB_DSP
:
14908 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14910 case OPC_DPA_W_PH_DSP
:
14911 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14913 case OPC_DPAU_H_QBL
:
14914 case OPC_DPAU_H_QBR
:
14915 case OPC_DPSU_H_QBL
:
14916 case OPC_DPSU_H_QBR
:
14918 case OPC_DPAX_W_PH
:
14919 case OPC_DPAQ_S_W_PH
:
14920 case OPC_DPAQX_S_W_PH
:
14921 case OPC_DPAQX_SA_W_PH
:
14923 case OPC_DPSX_W_PH
:
14924 case OPC_DPSQ_S_W_PH
:
14925 case OPC_DPSQX_S_W_PH
:
14926 case OPC_DPSQX_SA_W_PH
:
14927 case OPC_MULSAQ_S_W_PH
:
14928 case OPC_DPAQ_SA_L_W
:
14929 case OPC_DPSQ_SA_L_W
:
14930 case OPC_MAQ_S_W_PHL
:
14931 case OPC_MAQ_S_W_PHR
:
14932 case OPC_MAQ_SA_W_PHL
:
14933 case OPC_MAQ_SA_W_PHR
:
14934 case OPC_MULSA_W_PH
:
14935 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14937 default: /* Invalid */
14938 MIPS_INVAL("MASK DPAW.PH");
14939 generate_exception(ctx
, EXCP_RI
);
14944 op2
= MASK_INSV(ctx
->opcode
);
14956 t0
= tcg_temp_new();
14957 t1
= tcg_temp_new();
14959 gen_load_gpr(t0
, rt
);
14960 gen_load_gpr(t1
, rs
);
14962 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
14968 default: /* Invalid */
14969 MIPS_INVAL("MASK INSV");
14970 generate_exception(ctx
, EXCP_RI
);
14974 case OPC_APPEND_DSP
:
14975 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
14977 case OPC_EXTR_W_DSP
:
14978 op2
= MASK_EXTR_W(ctx
->opcode
);
14982 case OPC_EXTR_RS_W
:
14984 case OPC_EXTRV_S_H
:
14986 case OPC_EXTRV_R_W
:
14987 case OPC_EXTRV_RS_W
:
14992 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
14995 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15001 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15003 default: /* Invalid */
15004 MIPS_INVAL("MASK EXTR.W");
15005 generate_exception(ctx
, EXCP_RI
);
15009 #if defined(TARGET_MIPS64)
15010 case OPC_DEXTM
... OPC_DEXT
:
15011 case OPC_DINSM
... OPC_DINS
:
15012 check_insn(ctx
, ISA_MIPS64R2
);
15013 check_mips_64(ctx
);
15014 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
15017 check_insn(ctx
, ISA_MIPS64R2
);
15018 check_mips_64(ctx
);
15019 op2
= MASK_DBSHFL(ctx
->opcode
);
15020 gen_bshfl(ctx
, op2
, rt
, rd
);
15022 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
15023 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
15024 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
15025 check_insn(ctx
, INSN_LOONGSON2E
);
15026 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
15028 case OPC_ABSQ_S_QH_DSP
:
15029 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
15031 case OPC_PRECEQ_L_PWL
:
15032 case OPC_PRECEQ_L_PWR
:
15033 case OPC_PRECEQ_PW_QHL
:
15034 case OPC_PRECEQ_PW_QHR
:
15035 case OPC_PRECEQ_PW_QHLA
:
15036 case OPC_PRECEQ_PW_QHRA
:
15037 case OPC_PRECEQU_QH_OBL
:
15038 case OPC_PRECEQU_QH_OBR
:
15039 case OPC_PRECEQU_QH_OBLA
:
15040 case OPC_PRECEQU_QH_OBRA
:
15041 case OPC_PRECEU_QH_OBL
:
15042 case OPC_PRECEU_QH_OBR
:
15043 case OPC_PRECEU_QH_OBLA
:
15044 case OPC_PRECEU_QH_OBRA
:
15045 case OPC_ABSQ_S_OB
:
15046 case OPC_ABSQ_S_PW
:
15047 case OPC_ABSQ_S_QH
:
15048 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15056 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
15058 default: /* Invalid */
15059 MIPS_INVAL("MASK ABSQ_S.QH");
15060 generate_exception(ctx
, EXCP_RI
);
15064 case OPC_ADDU_OB_DSP
:
15065 op2
= MASK_ADDU_OB(ctx
->opcode
);
15067 case OPC_RADDU_L_OB
:
15069 case OPC_SUBQ_S_PW
:
15071 case OPC_SUBQ_S_QH
:
15073 case OPC_SUBU_S_OB
:
15075 case OPC_SUBU_S_QH
:
15077 case OPC_SUBUH_R_OB
:
15079 case OPC_ADDQ_S_PW
:
15081 case OPC_ADDQ_S_QH
:
15083 case OPC_ADDU_S_OB
:
15085 case OPC_ADDU_S_QH
:
15087 case OPC_ADDUH_R_OB
:
15088 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15090 case OPC_MULEQ_S_PW_QHL
:
15091 case OPC_MULEQ_S_PW_QHR
:
15092 case OPC_MULEU_S_QH_OBL
:
15093 case OPC_MULEU_S_QH_OBR
:
15094 case OPC_MULQ_RS_QH
:
15095 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15097 default: /* Invalid */
15098 MIPS_INVAL("MASK ADDU.OB");
15099 generate_exception(ctx
, EXCP_RI
);
15103 case OPC_CMPU_EQ_OB_DSP
:
15104 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15106 case OPC_PRECR_SRA_QH_PW
:
15107 case OPC_PRECR_SRA_R_QH_PW
:
15108 /* Return value is rt. */
15109 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15111 case OPC_PRECR_OB_QH
:
15112 case OPC_PRECRQ_OB_QH
:
15113 case OPC_PRECRQ_PW_L
:
15114 case OPC_PRECRQ_QH_PW
:
15115 case OPC_PRECRQ_RS_QH_PW
:
15116 case OPC_PRECRQU_S_OB_QH
:
15117 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15119 case OPC_CMPU_EQ_OB
:
15120 case OPC_CMPU_LT_OB
:
15121 case OPC_CMPU_LE_OB
:
15122 case OPC_CMP_EQ_QH
:
15123 case OPC_CMP_LT_QH
:
15124 case OPC_CMP_LE_QH
:
15125 case OPC_CMP_EQ_PW
:
15126 case OPC_CMP_LT_PW
:
15127 case OPC_CMP_LE_PW
:
15128 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15130 case OPC_CMPGDU_EQ_OB
:
15131 case OPC_CMPGDU_LT_OB
:
15132 case OPC_CMPGDU_LE_OB
:
15133 case OPC_CMPGU_EQ_OB
:
15134 case OPC_CMPGU_LT_OB
:
15135 case OPC_CMPGU_LE_OB
:
15136 case OPC_PACKRL_PW
:
15140 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15142 default: /* Invalid */
15143 MIPS_INVAL("MASK CMPU_EQ.OB");
15144 generate_exception(ctx
, EXCP_RI
);
15148 case OPC_DAPPEND_DSP
:
15149 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15151 case OPC_DEXTR_W_DSP
:
15152 op2
= MASK_DEXTR_W(ctx
->opcode
);
15159 case OPC_DEXTR_R_L
:
15160 case OPC_DEXTR_RS_L
:
15162 case OPC_DEXTR_R_W
:
15163 case OPC_DEXTR_RS_W
:
15164 case OPC_DEXTR_S_H
:
15166 case OPC_DEXTRV_R_L
:
15167 case OPC_DEXTRV_RS_L
:
15168 case OPC_DEXTRV_S_H
:
15170 case OPC_DEXTRV_R_W
:
15171 case OPC_DEXTRV_RS_W
:
15172 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15177 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15179 default: /* Invalid */
15180 MIPS_INVAL("MASK EXTR.W");
15181 generate_exception(ctx
, EXCP_RI
);
15185 case OPC_DPAQ_W_QH_DSP
:
15186 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15188 case OPC_DPAU_H_OBL
:
15189 case OPC_DPAU_H_OBR
:
15190 case OPC_DPSU_H_OBL
:
15191 case OPC_DPSU_H_OBR
:
15193 case OPC_DPAQ_S_W_QH
:
15195 case OPC_DPSQ_S_W_QH
:
15196 case OPC_MULSAQ_S_W_QH
:
15197 case OPC_DPAQ_SA_L_PW
:
15198 case OPC_DPSQ_SA_L_PW
:
15199 case OPC_MULSAQ_S_L_PW
:
15200 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15202 case OPC_MAQ_S_W_QHLL
:
15203 case OPC_MAQ_S_W_QHLR
:
15204 case OPC_MAQ_S_W_QHRL
:
15205 case OPC_MAQ_S_W_QHRR
:
15206 case OPC_MAQ_SA_W_QHLL
:
15207 case OPC_MAQ_SA_W_QHLR
:
15208 case OPC_MAQ_SA_W_QHRL
:
15209 case OPC_MAQ_SA_W_QHRR
:
15210 case OPC_MAQ_S_L_PWL
:
15211 case OPC_MAQ_S_L_PWR
:
15216 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15218 default: /* Invalid */
15219 MIPS_INVAL("MASK DPAQ.W.QH");
15220 generate_exception(ctx
, EXCP_RI
);
15224 case OPC_DINSV_DSP
:
15225 op2
= MASK_INSV(ctx
->opcode
);
15237 t0
= tcg_temp_new();
15238 t1
= tcg_temp_new();
15240 gen_load_gpr(t0
, rt
);
15241 gen_load_gpr(t1
, rs
);
15243 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15246 default: /* Invalid */
15247 MIPS_INVAL("MASK DINSV");
15248 generate_exception(ctx
, EXCP_RI
);
15252 case OPC_SHLL_OB_DSP
:
15253 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15256 default: /* Invalid */
15257 MIPS_INVAL("special3");
15258 generate_exception(ctx
, EXCP_RI
);
15263 op1
= MASK_REGIMM(ctx
->opcode
);
15265 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15266 case OPC_BLTZAL
... OPC_BGEZALL
:
15267 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15269 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15271 gen_trap(ctx
, op1
, rs
, -1, imm
);
15274 check_insn(ctx
, ISA_MIPS32R2
);
15275 /* Treat as NOP. */
15277 case OPC_BPOSGE32
: /* MIPS DSP branch */
15278 #if defined(TARGET_MIPS64)
15282 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15284 default: /* Invalid */
15285 MIPS_INVAL("regimm");
15286 generate_exception(ctx
, EXCP_RI
);
15291 check_cp0_enabled(ctx
);
15292 op1
= MASK_CP0(ctx
->opcode
);
15298 #if defined(TARGET_MIPS64)
15302 #ifndef CONFIG_USER_ONLY
15303 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15304 #endif /* !CONFIG_USER_ONLY */
15306 case OPC_C0_FIRST
... OPC_C0_LAST
:
15307 #ifndef CONFIG_USER_ONLY
15308 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15309 #endif /* !CONFIG_USER_ONLY */
15312 #ifndef CONFIG_USER_ONLY
15314 TCGv t0
= tcg_temp_new();
15316 op2
= MASK_MFMC0(ctx
->opcode
);
15319 check_insn(ctx
, ASE_MT
);
15320 gen_helper_dmt(t0
);
15321 gen_store_gpr(t0
, rt
);
15324 check_insn(ctx
, ASE_MT
);
15325 gen_helper_emt(t0
);
15326 gen_store_gpr(t0
, rt
);
15329 check_insn(ctx
, ASE_MT
);
15330 gen_helper_dvpe(t0
, cpu_env
);
15331 gen_store_gpr(t0
, rt
);
15334 check_insn(ctx
, ASE_MT
);
15335 gen_helper_evpe(t0
, cpu_env
);
15336 gen_store_gpr(t0
, rt
);
15339 check_insn(ctx
, ISA_MIPS32R2
);
15340 save_cpu_state(ctx
, 1);
15341 gen_helper_di(t0
, cpu_env
);
15342 gen_store_gpr(t0
, rt
);
15343 /* Stop translation as we may have switched the execution mode */
15344 ctx
->bstate
= BS_STOP
;
15347 check_insn(ctx
, ISA_MIPS32R2
);
15348 save_cpu_state(ctx
, 1);
15349 gen_helper_ei(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
;
15354 default: /* Invalid */
15355 MIPS_INVAL("mfmc0");
15356 generate_exception(ctx
, EXCP_RI
);
15361 #endif /* !CONFIG_USER_ONLY */
15364 check_insn(ctx
, ISA_MIPS32R2
);
15365 gen_load_srsgpr(rt
, rd
);
15368 check_insn(ctx
, ISA_MIPS32R2
);
15369 gen_store_srsgpr(rt
, rd
);
15373 generate_exception(ctx
, EXCP_RI
);
15377 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15379 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15381 case OPC_SLTI
: /* Set on less than with immediate opcode */
15383 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15385 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15389 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15391 case OPC_J
... OPC_JAL
: /* Jump */
15392 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15393 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15395 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15396 case OPC_BEQL
... OPC_BGTZL
:
15397 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15399 case OPC_LB
... OPC_LWR
: /* Load and stores */
15401 gen_ld(ctx
, op
, rt
, rs
, imm
);
15403 case OPC_SB
... OPC_SW
:
15405 gen_st(ctx
, op
, rt
, rs
, imm
);
15408 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15411 check_cp0_enabled(ctx
);
15412 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15413 /* Treat as NOP. */
15416 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15417 /* Treat as NOP. */
15420 /* Floating point (COP1). */
15425 gen_cop1_ldst(env
, ctx
, op
, rt
, rs
, imm
);
15429 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15430 check_cp1_enabled(ctx
);
15431 op1
= MASK_CP1(ctx
->opcode
);
15435 check_insn(ctx
, ISA_MIPS32R2
);
15440 gen_cp1(ctx
, op1
, rt
, rd
);
15442 #if defined(TARGET_MIPS64)
15445 check_insn(ctx
, ISA_MIPS3
);
15446 gen_cp1(ctx
, op1
, rt
, rd
);
15452 check_insn(ctx
, ASE_MIPS3D
);
15455 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15456 (rt
>> 2) & 0x7, imm
<< 2);
15463 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15468 generate_exception (ctx
, EXCP_RI
);
15472 generate_exception_err(ctx
, EXCP_CpU
, 1);
15481 /* COP2: Not implemented. */
15482 generate_exception_err(ctx
, EXCP_CpU
, 2);
15485 check_insn(ctx
, INSN_LOONGSON2F
);
15486 /* Note that these instructions use different fields. */
15487 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15491 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15492 check_cp1_enabled(ctx
);
15493 op1
= MASK_CP3(ctx
->opcode
);
15501 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15504 /* Treat as NOP. */
15519 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15523 generate_exception (ctx
, EXCP_RI
);
15527 generate_exception_err(ctx
, EXCP_CpU
, 1);
15531 #if defined(TARGET_MIPS64)
15532 /* MIPS64 opcodes */
15534 case OPC_LDL
... OPC_LDR
:
15537 check_insn(ctx
, ISA_MIPS3
);
15538 check_mips_64(ctx
);
15539 gen_ld(ctx
, op
, rt
, rs
, imm
);
15541 case OPC_SDL
... OPC_SDR
:
15543 check_insn(ctx
, ISA_MIPS3
);
15544 check_mips_64(ctx
);
15545 gen_st(ctx
, op
, rt
, rs
, imm
);
15548 check_insn(ctx
, ISA_MIPS3
);
15549 check_mips_64(ctx
);
15550 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15554 check_insn(ctx
, ISA_MIPS3
);
15555 check_mips_64(ctx
);
15556 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15560 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15561 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15562 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15565 check_insn(ctx
, ASE_MDMX
);
15566 /* MDMX: Not implemented. */
15567 default: /* Invalid */
15568 MIPS_INVAL("major opcode");
15569 generate_exception(ctx
, EXCP_RI
);
15575 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
15578 CPUState
*cs
= CPU(cpu
);
15579 CPUMIPSState
*env
= &cpu
->env
;
15581 target_ulong pc_start
;
15582 uint16_t *gen_opc_end
;
15591 qemu_log("search pc %d\n", search_pc
);
15594 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15597 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
15598 ctx
.insn_flags
= env
->insn_flags
;
15600 ctx
.bstate
= BS_NONE
;
15601 /* Restore delay slot state from the tb context. */
15602 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15603 restore_cpu_state(env
, &ctx
);
15604 #ifdef CONFIG_USER_ONLY
15605 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15607 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15610 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15611 if (max_insns
== 0)
15612 max_insns
= CF_COUNT_MASK
;
15613 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15615 while (ctx
.bstate
== BS_NONE
) {
15616 if (unlikely(!QTAILQ_EMPTY(&env
->breakpoints
))) {
15617 QTAILQ_FOREACH(bp
, &env
->breakpoints
, entry
) {
15618 if (bp
->pc
== ctx
.pc
) {
15619 save_cpu_state(&ctx
, 1);
15620 ctx
.bstate
= BS_BRANCH
;
15621 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15622 /* Include the breakpoint location or the tb won't
15623 * be flushed when it must be. */
15625 goto done_generating
;
15631 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15635 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15637 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15638 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15639 gen_opc_btarget
[lj
] = ctx
.btarget
;
15640 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15641 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15643 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15646 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
15647 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15648 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15650 decode_opc(env
, &ctx
);
15651 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15652 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15653 insn_bytes
= decode_micromips_opc(env
, &ctx
);
15654 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15655 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15656 insn_bytes
= decode_mips16_opc(env
, &ctx
);
15658 generate_exception(&ctx
, EXCP_RI
);
15659 ctx
.bstate
= BS_STOP
;
15663 handle_delay_slot(&ctx
, insn_bytes
);
15665 ctx
.pc
+= insn_bytes
;
15669 /* Execute a branch and its delay slot as a single instruction.
15670 This is what GDB expects and is consistent with what the
15671 hardware does (e.g. if a delay slot instruction faults, the
15672 reported PC is the PC of the branch). */
15673 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
15677 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15680 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15684 if (num_insns
>= max_insns
)
15690 if (tb
->cflags
& CF_LAST_IO
) {
15693 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15694 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15695 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15697 switch (ctx
.bstate
) {
15699 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15702 save_cpu_state(&ctx
, 0);
15703 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15706 tcg_gen_exit_tb(0);
15714 gen_tb_end(tb
, num_insns
);
15715 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15717 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15720 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15722 tb
->size
= ctx
.pc
- pc_start
;
15723 tb
->icount
= num_insns
;
15727 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15728 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15729 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15735 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15737 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
15740 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15742 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
15745 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15749 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15751 #define printfpr(fp) \
15754 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15755 " fd:%13g fs:%13g psu: %13g\n", \
15756 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15757 (double)(fp)->fd, \
15758 (double)(fp)->fs[FP_ENDIAN_IDX], \
15759 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15762 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15763 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15764 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15765 " fd:%13g fs:%13g psu:%13g\n", \
15766 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15768 (double)tmp.fs[FP_ENDIAN_IDX], \
15769 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15774 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15775 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15776 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15777 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15778 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15779 printfpr(&env
->active_fpu
.fpr
[i
]);
15785 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15786 /* Debug help: The architecture requires 32bit code to maintain proper
15787 sign-extended values on 64bit machines. */
15789 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15792 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15793 fprintf_function cpu_fprintf
,
15798 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15799 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15800 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15801 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15802 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15803 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15804 if (!SIGN_EXT_P(env
->btarget
))
15805 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15807 for (i
= 0; i
< 32; i
++) {
15808 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15809 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15812 if (!SIGN_EXT_P(env
->CP0_EPC
))
15813 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15814 if (!SIGN_EXT_P(env
->lladdr
))
15815 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15819 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
15822 MIPSCPU
*cpu
= MIPS_CPU(cs
);
15823 CPUMIPSState
*env
= &cpu
->env
;
15826 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15827 " LO=0x" TARGET_FMT_lx
" ds %04x "
15828 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15829 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15830 env
->hflags
, env
->btarget
, env
->bcond
);
15831 for (i
= 0; i
< 32; i
++) {
15833 cpu_fprintf(f
, "GPR%02d:", i
);
15834 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15836 cpu_fprintf(f
, "\n");
15839 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15840 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15841 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15842 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15843 if (env
->hflags
& MIPS_HFLAG_FPU
)
15844 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15845 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15846 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15850 void mips_tcg_init(void)
15855 /* Initialize various static tables. */
15859 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15860 TCGV_UNUSED(cpu_gpr
[0]);
15861 for (i
= 1; i
< 32; i
++)
15862 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15863 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15866 for (i
= 0; i
< 32; i
++) {
15867 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15868 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15871 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15872 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15873 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15874 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15875 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15877 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15878 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15880 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15881 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15884 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15885 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15887 bcond
= tcg_global_mem_new(TCG_AREG0
,
15888 offsetof(CPUMIPSState
, bcond
), "bcond");
15889 btarget
= tcg_global_mem_new(TCG_AREG0
,
15890 offsetof(CPUMIPSState
, btarget
), "btarget");
15891 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15892 offsetof(CPUMIPSState
, hflags
), "hflags");
15894 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15895 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15897 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15898 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15904 #include "translate_init.c"
15906 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15910 const mips_def_t
*def
;
15912 def
= cpu_mips_find_by_name(cpu_model
);
15915 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15917 env
->cpu_model
= def
;
15919 #ifndef CONFIG_USER_ONLY
15920 mmu_init(env
, def
);
15922 fpu_init(env
, def
);
15923 mvp_init(env
, def
);
15925 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15930 void cpu_state_reset(CPUMIPSState
*env
)
15932 #ifndef CONFIG_USER_ONLY
15933 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
15934 CPUState
*cs
= CPU(cpu
);
15937 /* Reset registers to their default values */
15938 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15939 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15940 #ifdef TARGET_WORDS_BIGENDIAN
15941 env
->CP0_Config0
|= (1 << CP0C0_BE
);
15943 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
15944 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
15945 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
15946 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
15947 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
15948 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
15949 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
15950 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
15951 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
15952 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
15953 << env
->cpu_model
->CP0_LLAddr_shift
;
15954 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
15955 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
15956 env
->CCRes
= env
->cpu_model
->CCRes
;
15957 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
15958 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
15959 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
15960 env
->current_tc
= 0;
15961 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
15962 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
15963 #if defined(TARGET_MIPS64)
15964 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
15965 env
->SEGMask
|= 3ULL << 62;
15968 env
->PABITS
= env
->cpu_model
->PABITS
;
15969 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
15970 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
15971 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
15972 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
15973 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
15974 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
15975 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
15976 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
15977 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
15978 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
15979 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
15980 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
15981 env
->insn_flags
= env
->cpu_model
->insn_flags
;
15983 #if defined(CONFIG_USER_ONLY)
15984 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
15985 # ifdef TARGET_MIPS64
15986 /* Enable 64-bit register mode. */
15987 env
->CP0_Status
|= (1 << CP0St_PX
);
15989 # ifdef TARGET_ABI_MIPSN64
15990 /* Enable 64-bit address mode. */
15991 env
->CP0_Status
|= (1 << CP0St_UX
);
15993 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15994 hardware registers. */
15995 env
->CP0_HWREna
|= 0x0000000F;
15996 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
15997 env
->CP0_Status
|= (1 << CP0St_CU1
);
15999 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
16000 env
->CP0_Status
|= (1 << CP0St_MX
);
16002 # if defined(TARGET_MIPS64)
16003 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16004 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
16005 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
16006 env
->CP0_Status
|= (1 << CP0St_FR
);
16010 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
16011 /* If the exception was raised from a delay slot,
16012 come back to the jump. */
16013 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
16015 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
16017 env
->active_tc
.PC
= (int32_t)0xBFC00000;
16018 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
16019 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
16020 env
->CP0_Wired
= 0;
16021 env
->CP0_EBase
= 0x80000000 | (cs
->cpu_index
& 0x3FF);
16022 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
16023 /* vectored interrupts not implemented, timer on int 7,
16024 no performance counters. */
16025 env
->CP0_IntCtl
= 0xe0000000;
16029 for (i
= 0; i
< 7; i
++) {
16030 env
->CP0_WatchLo
[i
] = 0;
16031 env
->CP0_WatchHi
[i
] = 0x80000000;
16033 env
->CP0_WatchLo
[7] = 0;
16034 env
->CP0_WatchHi
[7] = 0;
16036 /* Count register increments in debug mode, EJTAG version 1 */
16037 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
16039 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
16042 /* Only TC0 on VPE 0 starts as active. */
16043 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
16044 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
16045 env
->tcs
[i
].CP0_TCHalt
= 1;
16047 env
->active_tc
.CP0_TCHalt
= 1;
16050 if (cs
->cpu_index
== 0) {
16051 /* VPE0 starts up enabled. */
16052 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
16053 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
16055 /* TC0 starts up unhalted. */
16057 env
->active_tc
.CP0_TCHalt
= 0;
16058 env
->tcs
[0].CP0_TCHalt
= 0;
16059 /* With thread 0 active. */
16060 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
16061 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16065 compute_hflags(env
);
16066 env
->exception_index
= EXCP_NONE
;
16069 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16071 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16072 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16073 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16074 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16075 case MIPS_HFLAG_BR
:
16077 case MIPS_HFLAG_BC
:
16078 case MIPS_HFLAG_BL
:
16080 env
->btarget
= gen_opc_btarget
[pc_pos
];