2 * MIPS32 emulation for qemu: main translation routines.
4 * Copyright (c) 2004-2005 Jocelyn Mayer
5 * Copyright (c) 2006 Marius Groeger (FPU operations)
6 * Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7 * Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8 * Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
25 #include "disas/disas.h"
27 #include "exec/cpu_ldst.h"
29 #include "exec/helper-proto.h"
30 #include "exec/helper-gen.h"
31 #include "sysemu/kvm.h"
33 #define MIPS_DEBUG_DISAS 0
34 //#define MIPS_DEBUG_SIGN_EXTENSIONS
36 /* MIPS major opcodes */
37 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
40 /* indirect opcode tables */
41 OPC_SPECIAL
= (0x00 << 26),
42 OPC_REGIMM
= (0x01 << 26),
43 OPC_CP0
= (0x10 << 26),
44 OPC_CP1
= (0x11 << 26),
45 OPC_CP2
= (0x12 << 26),
46 OPC_CP3
= (0x13 << 26),
47 OPC_SPECIAL2
= (0x1C << 26),
48 OPC_SPECIAL3
= (0x1F << 26),
49 /* arithmetic with immediate */
50 OPC_ADDI
= (0x08 << 26),
51 OPC_ADDIU
= (0x09 << 26),
52 OPC_SLTI
= (0x0A << 26),
53 OPC_SLTIU
= (0x0B << 26),
54 /* logic with immediate */
55 OPC_ANDI
= (0x0C << 26),
56 OPC_ORI
= (0x0D << 26),
57 OPC_XORI
= (0x0E << 26),
58 OPC_LUI
= (0x0F << 26),
59 /* arithmetic with immediate */
60 OPC_DADDI
= (0x18 << 26),
61 OPC_DADDIU
= (0x19 << 26),
62 /* Jump and branches */
64 OPC_JAL
= (0x03 << 26),
65 OPC_JALS
= OPC_JAL
| 0x5,
66 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
67 OPC_BEQL
= (0x14 << 26),
68 OPC_BNE
= (0x05 << 26),
69 OPC_BNEL
= (0x15 << 26),
70 OPC_BLEZ
= (0x06 << 26),
71 OPC_BLEZL
= (0x16 << 26),
72 OPC_BGTZ
= (0x07 << 26),
73 OPC_BGTZL
= (0x17 << 26),
74 OPC_JALX
= (0x1D << 26), /* MIPS 16 only */
75 OPC_JALXS
= OPC_JALX
| 0x5,
77 OPC_LDL
= (0x1A << 26),
78 OPC_LDR
= (0x1B << 26),
79 OPC_LB
= (0x20 << 26),
80 OPC_LH
= (0x21 << 26),
81 OPC_LWL
= (0x22 << 26),
82 OPC_LW
= (0x23 << 26),
83 OPC_LWPC
= OPC_LW
| 0x5,
84 OPC_LBU
= (0x24 << 26),
85 OPC_LHU
= (0x25 << 26),
86 OPC_LWR
= (0x26 << 26),
87 OPC_LWU
= (0x27 << 26),
88 OPC_SB
= (0x28 << 26),
89 OPC_SH
= (0x29 << 26),
90 OPC_SWL
= (0x2A << 26),
91 OPC_SW
= (0x2B << 26),
92 OPC_SDL
= (0x2C << 26),
93 OPC_SDR
= (0x2D << 26),
94 OPC_SWR
= (0x2E << 26),
95 OPC_LL
= (0x30 << 26),
96 OPC_LLD
= (0x34 << 26),
97 OPC_LD
= (0x37 << 26),
98 OPC_LDPC
= OPC_LD
| 0x5,
99 OPC_SC
= (0x38 << 26),
100 OPC_SCD
= (0x3C << 26),
101 OPC_SD
= (0x3F << 26),
102 /* Floating point load/store */
103 OPC_LWC1
= (0x31 << 26),
104 OPC_LWC2
= (0x32 << 26),
105 OPC_LDC1
= (0x35 << 26),
106 OPC_LDC2
= (0x36 << 26),
107 OPC_SWC1
= (0x39 << 26),
108 OPC_SWC2
= (0x3A << 26),
109 OPC_SDC1
= (0x3D << 26),
110 OPC_SDC2
= (0x3E << 26),
111 /* MDMX ASE specific */
112 OPC_MDMX
= (0x1E << 26),
113 /* Cache and prefetch */
114 OPC_CACHE
= (0x2F << 26),
115 OPC_PREF
= (0x33 << 26),
116 /* Reserved major opcode */
117 OPC_MAJOR3B_RESERVED
= (0x3B << 26),
120 /* MIPS special opcodes */
121 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
125 OPC_SLL
= 0x00 | OPC_SPECIAL
,
126 /* NOP is SLL r0, r0, 0 */
127 /* SSNOP is SLL r0, r0, 1 */
128 /* EHB is SLL r0, r0, 3 */
129 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
130 OPC_ROTR
= OPC_SRL
| (1 << 21),
131 OPC_SRA
= 0x03 | OPC_SPECIAL
,
132 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
133 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
134 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
135 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
136 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
137 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
138 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
139 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
140 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
141 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
142 OPC_DROTR
= OPC_DSRL
| (1 << 21),
143 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
144 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
145 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
146 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
147 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
148 /* Multiplication / division */
149 OPC_MULT
= 0x18 | OPC_SPECIAL
,
150 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
151 OPC_DIV
= 0x1A | OPC_SPECIAL
,
152 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
153 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
154 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
155 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
156 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
157 /* 2 registers arithmetic / logic */
158 OPC_ADD
= 0x20 | OPC_SPECIAL
,
159 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
160 OPC_SUB
= 0x22 | OPC_SPECIAL
,
161 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
162 OPC_AND
= 0x24 | OPC_SPECIAL
,
163 OPC_OR
= 0x25 | OPC_SPECIAL
,
164 OPC_XOR
= 0x26 | OPC_SPECIAL
,
165 OPC_NOR
= 0x27 | OPC_SPECIAL
,
166 OPC_SLT
= 0x2A | OPC_SPECIAL
,
167 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
168 OPC_DADD
= 0x2C | OPC_SPECIAL
,
169 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
170 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
171 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
173 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
174 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
175 OPC_JALRC
= OPC_JALR
| (0x5 << 6),
176 OPC_JALRS
= 0x10 | OPC_SPECIAL
| (0x5 << 6),
178 OPC_TGE
= 0x30 | OPC_SPECIAL
,
179 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
180 OPC_TLT
= 0x32 | OPC_SPECIAL
,
181 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
182 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
183 OPC_TNE
= 0x36 | OPC_SPECIAL
,
184 /* HI / LO registers load & stores */
185 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
186 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
187 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
188 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
189 /* Conditional moves */
190 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
191 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
193 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
196 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
197 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
198 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
199 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
200 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
202 OPC_SPECIAL15_RESERVED
= 0x15 | OPC_SPECIAL
,
203 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
204 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
205 OPC_SPECIAL35_RESERVED
= 0x35 | OPC_SPECIAL
,
206 OPC_SPECIAL37_RESERVED
= 0x37 | OPC_SPECIAL
,
207 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
208 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
211 /* Multiplication variants of the vr54xx. */
212 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
215 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
216 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
217 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
218 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
219 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
220 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
221 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
222 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
223 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
224 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
225 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
226 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
227 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
228 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
231 /* REGIMM (rt field) opcodes */
232 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
235 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
236 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
237 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
238 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
239 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
240 OPC_BLTZALS
= OPC_BLTZAL
| 0x5, /* microMIPS */
241 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
242 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
243 OPC_BGEZALS
= OPC_BGEZAL
| 0x5, /* microMIPS */
244 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
245 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
246 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
247 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
248 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
249 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
250 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
251 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
254 /* Special2 opcodes */
255 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
258 /* Multiply & xxx operations */
259 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
260 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
261 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
262 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
263 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
265 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
266 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
267 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
268 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
269 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
270 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
271 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
272 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
273 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
274 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
275 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
276 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
278 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
279 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
280 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
281 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
283 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
286 /* Special3 opcodes */
287 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
290 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
291 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
292 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
293 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
294 OPC_INS
= 0x04 | OPC_SPECIAL3
,
295 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
296 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
297 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
298 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
299 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
300 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
301 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
302 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
305 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
306 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
307 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
308 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
309 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
310 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
311 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
312 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
313 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
314 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
315 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
316 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
319 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
320 /* MIPS DSP Arithmetic */
321 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
322 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
323 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
324 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
325 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
326 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
327 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
328 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
329 /* MIPS DSP GPR-Based Shift Sub-class */
330 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
331 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
332 /* MIPS DSP Multiply Sub-class insns */
333 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
334 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
335 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
336 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
337 /* DSP Bit/Manipulation Sub-class */
338 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
339 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
340 /* MIPS DSP Append Sub-class */
341 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
342 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
343 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
344 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
345 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
349 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
352 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
353 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
354 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
358 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
361 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
362 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
365 /* MIPS DSP REGIMM opcodes */
367 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
368 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
371 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
374 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
375 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
376 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
377 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
380 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
382 /* MIPS DSP Arithmetic Sub-class */
383 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
384 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
385 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
386 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
387 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
388 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
389 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
390 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
391 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
392 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
393 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
394 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
395 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
396 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
397 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
398 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
399 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
400 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
401 /* MIPS DSP Multiply Sub-class insns */
402 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
403 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
404 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
405 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
406 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
407 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
410 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
411 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
413 /* MIPS DSP Arithmetic Sub-class */
414 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
415 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
416 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
417 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
418 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
419 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
420 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
421 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
422 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
423 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
424 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
425 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
426 /* MIPS DSP Multiply Sub-class insns */
427 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
428 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
429 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
430 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
433 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
435 /* MIPS DSP Arithmetic Sub-class */
436 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
437 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
438 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
439 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
440 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
441 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
442 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
443 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
444 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
445 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
446 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
447 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
448 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
449 /* DSP Bit/Manipulation Sub-class */
450 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
451 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
452 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
453 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
454 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
457 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
459 /* MIPS DSP Arithmetic Sub-class */
460 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
461 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
462 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
463 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
464 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
465 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
466 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
467 /* DSP Compare-Pick Sub-class */
468 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
469 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
470 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
471 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
472 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
473 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
474 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
475 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
476 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
477 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
478 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
479 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
480 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
481 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
482 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
485 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
487 /* MIPS DSP GPR-Based Shift Sub-class */
488 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
489 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
490 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
491 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
492 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
493 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
494 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
495 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
496 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
497 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
498 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
499 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
500 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
501 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
502 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
503 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
504 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
505 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
506 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
507 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
508 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
509 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
512 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
514 /* MIPS DSP Multiply Sub-class insns */
515 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
516 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
517 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
518 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
519 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
520 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
521 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
522 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
523 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
524 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
525 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
526 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
527 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
528 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
529 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
530 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
531 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
532 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
533 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
534 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
535 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
536 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
539 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
541 /* DSP Bit/Manipulation Sub-class */
542 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
545 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
547 /* MIPS DSP Append Sub-class */
548 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
549 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
550 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
553 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
555 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
556 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
557 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
558 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
559 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
560 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
561 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
562 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
563 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
564 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
565 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
566 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
567 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
568 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
569 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
570 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
571 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
572 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
575 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
577 /* MIPS DSP Arithmetic Sub-class */
578 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
579 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
580 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
581 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
582 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
583 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
584 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
585 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
586 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
587 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
588 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
589 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
590 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
591 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
592 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
593 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
594 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
595 /* DSP Bit/Manipulation Sub-class */
596 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
597 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
598 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
599 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
600 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
601 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
604 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
606 /* MIPS DSP Multiply Sub-class insns */
607 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
608 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
609 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
610 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
611 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
612 /* MIPS DSP Arithmetic Sub-class */
613 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
614 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
615 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
616 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
617 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
618 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
619 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
620 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
621 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
622 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
623 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
624 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
625 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
626 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
627 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
628 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
629 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
630 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
631 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
632 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
633 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
636 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
638 /* DSP Compare-Pick Sub-class */
639 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
640 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
641 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
642 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
643 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
644 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
645 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
646 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
647 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
648 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
649 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
650 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
651 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
652 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
653 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
654 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
655 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
656 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
657 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
658 /* MIPS DSP Arithmetic Sub-class */
659 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
660 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
661 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
662 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
663 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
664 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
665 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
666 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
669 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671 /* DSP Append Sub-class */
672 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
673 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
674 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
675 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
678 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
680 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
681 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
682 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
683 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
684 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
685 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
686 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
687 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
688 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
689 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
690 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
691 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
692 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
693 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
694 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
695 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
696 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
697 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
698 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
699 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
700 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
701 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
704 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
706 /* DSP Bit/Manipulation Sub-class */
707 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
710 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
712 /* MIPS DSP Multiply Sub-class insns */
713 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
714 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
715 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
716 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
717 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
718 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
719 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
720 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
721 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
722 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
723 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
724 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
725 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
726 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
727 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
728 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
729 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
730 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
731 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
732 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
733 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
734 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
735 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
736 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
737 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
738 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
741 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
743 /* MIPS DSP GPR-Based Shift Sub-class */
744 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
745 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
746 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
747 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
748 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
749 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
750 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
751 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
752 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
753 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
754 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
755 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
756 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
757 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
758 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
759 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
760 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
761 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
762 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
763 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
764 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
765 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
766 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
767 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
768 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
769 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
772 /* Coprocessor 0 (rs field) */
773 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
776 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
777 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
778 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
779 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
780 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
781 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
782 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
783 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
784 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
785 OPC_C0
= (0x10 << 21) | OPC_CP0
,
786 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
787 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
791 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
794 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
795 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
796 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
797 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
798 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
799 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
802 /* Coprocessor 0 (with rs == C0) */
803 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
806 OPC_TLBR
= 0x01 | OPC_C0
,
807 OPC_TLBWI
= 0x02 | OPC_C0
,
808 OPC_TLBWR
= 0x06 | OPC_C0
,
809 OPC_TLBP
= 0x08 | OPC_C0
,
810 OPC_RFE
= 0x10 | OPC_C0
,
811 OPC_ERET
= 0x18 | OPC_C0
,
812 OPC_DERET
= 0x1F | OPC_C0
,
813 OPC_WAIT
= 0x20 | OPC_C0
,
816 /* Coprocessor 1 (rs field) */
817 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
819 /* Values for the fmt field in FP instructions */
821 /* 0 - 15 are reserved */
822 FMT_S
= 16, /* single fp */
823 FMT_D
= 17, /* double fp */
824 FMT_E
= 18, /* extended fp */
825 FMT_Q
= 19, /* quad fp */
826 FMT_W
= 20, /* 32-bit fixed */
827 FMT_L
= 21, /* 64-bit fixed */
828 FMT_PS
= 22, /* paired single fp */
829 /* 23 - 31 are reserved */
833 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
834 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
835 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
836 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
837 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
838 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
839 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
840 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
841 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
842 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
843 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
844 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
845 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
846 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
847 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
848 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
849 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
850 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
853 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
854 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
857 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
858 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
859 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
860 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
864 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
865 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
869 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
870 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
873 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
876 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
877 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
878 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
879 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
880 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
881 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
882 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
883 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
884 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
887 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
890 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
891 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
892 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
893 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
894 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
895 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
896 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
897 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
899 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
900 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
901 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
902 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
903 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
904 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
905 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
906 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
908 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
909 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
910 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
911 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
912 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
913 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
914 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
915 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
917 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
918 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
919 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
920 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
921 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
922 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
923 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
924 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
926 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
927 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
928 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
929 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
930 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
931 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
933 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
934 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
935 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
936 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
937 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
938 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
940 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
941 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
942 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
943 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
944 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
945 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
947 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
948 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
949 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
950 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
951 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
952 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
954 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
955 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
956 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
957 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
958 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
959 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
961 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
962 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
963 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
964 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
965 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
966 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
968 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
969 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
970 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
971 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
972 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
973 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
975 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
976 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
977 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
978 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
979 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
980 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
984 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
987 OPC_LWXC1
= 0x00 | OPC_CP3
,
988 OPC_LDXC1
= 0x01 | OPC_CP3
,
989 OPC_LUXC1
= 0x05 | OPC_CP3
,
990 OPC_SWXC1
= 0x08 | OPC_CP3
,
991 OPC_SDXC1
= 0x09 | OPC_CP3
,
992 OPC_SUXC1
= 0x0D | OPC_CP3
,
993 OPC_PREFX
= 0x0F | OPC_CP3
,
994 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
995 OPC_MADD_S
= 0x20 | OPC_CP3
,
996 OPC_MADD_D
= 0x21 | OPC_CP3
,
997 OPC_MADD_PS
= 0x26 | OPC_CP3
,
998 OPC_MSUB_S
= 0x28 | OPC_CP3
,
999 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1000 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1001 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1002 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1003 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1004 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1005 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1006 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1009 /* global register indices */
1010 static TCGv_ptr cpu_env
;
1011 static TCGv cpu_gpr
[32], cpu_PC
;
1012 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
], cpu_ACX
[MIPS_DSP_ACC
];
1013 static TCGv cpu_dspctrl
, btarget
, bcond
;
1014 static TCGv_i32 hflags
;
1015 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1016 static TCGv_i64 fpu_f64
[32];
1018 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1019 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1021 #include "exec/gen-icount.h"
1023 #define gen_helper_0e0i(name, arg) do { \
1024 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1025 gen_helper_##name(cpu_env, helper_tmp); \
1026 tcg_temp_free_i32(helper_tmp); \
1029 #define gen_helper_0e1i(name, arg1, arg2) do { \
1030 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1031 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1032 tcg_temp_free_i32(helper_tmp); \
1035 #define gen_helper_1e0i(name, ret, arg1) do { \
1036 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1037 gen_helper_##name(ret, cpu_env, helper_tmp); \
1038 tcg_temp_free_i32(helper_tmp); \
1041 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1042 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1043 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1044 tcg_temp_free_i32(helper_tmp); \
1047 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1048 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1049 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1050 tcg_temp_free_i32(helper_tmp); \
1053 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1054 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1055 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1056 tcg_temp_free_i32(helper_tmp); \
1059 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1060 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1061 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1062 tcg_temp_free_i32(helper_tmp); \
1065 typedef struct DisasContext
{
1066 struct TranslationBlock
*tb
;
1067 target_ulong pc
, saved_pc
;
1069 int singlestep_enabled
;
1071 int32_t CP0_Config1
;
1072 /* Routine used to access memory */
1074 uint32_t hflags
, saved_hflags
;
1076 target_ulong btarget
;
1081 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1082 * exception condition */
1083 BS_STOP
= 1, /* We want to stop translation for any reason */
1084 BS_BRANCH
= 2, /* We reached a branch condition */
1085 BS_EXCP
= 3, /* We reached an exception condition */
1088 static const char * const regnames
[] = {
1089 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1090 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1091 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1092 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1095 static const char * const regnames_HI
[] = {
1096 "HI0", "HI1", "HI2", "HI3",
1099 static const char * const regnames_LO
[] = {
1100 "LO0", "LO1", "LO2", "LO3",
1103 static const char * const regnames_ACX
[] = {
1104 "ACX0", "ACX1", "ACX2", "ACX3",
1107 static const char * const fregnames
[] = {
1108 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1109 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1110 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1111 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1114 #define MIPS_DEBUG(fmt, ...) \
1116 if (MIPS_DEBUG_DISAS) { \
1117 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1118 TARGET_FMT_lx ": %08x " fmt "\n", \
1119 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1123 #define LOG_DISAS(...) \
1125 if (MIPS_DEBUG_DISAS) { \
1126 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1130 #define MIPS_INVAL(op) \
1131 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1132 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1134 /* General purpose registers moves. */
1135 static inline void gen_load_gpr (TCGv t
, int reg
)
1138 tcg_gen_movi_tl(t
, 0);
1140 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1143 static inline void gen_store_gpr (TCGv t
, int reg
)
1146 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1149 /* Moves to/from ACX register. */
1150 static inline void gen_load_ACX (TCGv t
, int reg
)
1152 tcg_gen_mov_tl(t
, cpu_ACX
[reg
]);
1155 static inline void gen_store_ACX (TCGv t
, int reg
)
1157 tcg_gen_mov_tl(cpu_ACX
[reg
], t
);
1160 /* Moves to/from shadow registers. */
1161 static inline void gen_load_srsgpr (int from
, int to
)
1163 TCGv t0
= tcg_temp_new();
1166 tcg_gen_movi_tl(t0
, 0);
1168 TCGv_i32 t2
= tcg_temp_new_i32();
1169 TCGv_ptr addr
= tcg_temp_new_ptr();
1171 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1172 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1173 tcg_gen_andi_i32(t2
, t2
, 0xf);
1174 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1175 tcg_gen_ext_i32_ptr(addr
, t2
);
1176 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1178 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1179 tcg_temp_free_ptr(addr
);
1180 tcg_temp_free_i32(t2
);
1182 gen_store_gpr(t0
, to
);
1186 static inline void gen_store_srsgpr (int from
, int to
)
1189 TCGv t0
= tcg_temp_new();
1190 TCGv_i32 t2
= tcg_temp_new_i32();
1191 TCGv_ptr addr
= tcg_temp_new_ptr();
1193 gen_load_gpr(t0
, from
);
1194 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1195 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1196 tcg_gen_andi_i32(t2
, t2
, 0xf);
1197 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1198 tcg_gen_ext_i32_ptr(addr
, t2
);
1199 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1201 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1202 tcg_temp_free_ptr(addr
);
1203 tcg_temp_free_i32(t2
);
1208 /* Floating point register moves. */
1209 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1211 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1214 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1216 TCGv_i64 t64
= tcg_temp_new_i64();
1217 tcg_gen_extu_i32_i64(t64
, t
);
1218 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1219 tcg_temp_free_i64(t64
);
1222 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1224 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1225 TCGv_i64 t64
= tcg_temp_new_i64();
1226 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1227 tcg_gen_trunc_i64_i32(t
, t64
);
1228 tcg_temp_free_i64(t64
);
1230 gen_load_fpr32(t
, reg
| 1);
1234 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1236 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1237 TCGv_i64 t64
= tcg_temp_new_i64();
1238 tcg_gen_extu_i32_i64(t64
, t
);
1239 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1240 tcg_temp_free_i64(t64
);
1242 gen_store_fpr32(t
, reg
| 1);
1246 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1248 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1249 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1251 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1255 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1257 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1258 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1261 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1262 t0
= tcg_temp_new_i64();
1263 tcg_gen_shri_i64(t0
, t
, 32);
1264 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1265 tcg_temp_free_i64(t0
);
1269 static inline int get_fp_bit (int cc
)
1278 static inline void gen_save_pc(target_ulong pc
)
1280 tcg_gen_movi_tl(cpu_PC
, pc
);
1283 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1285 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1286 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1287 gen_save_pc(ctx
->pc
);
1288 ctx
->saved_pc
= ctx
->pc
;
1290 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1291 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1292 ctx
->saved_hflags
= ctx
->hflags
;
1293 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1299 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1305 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1307 ctx
->saved_hflags
= ctx
->hflags
;
1308 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1314 ctx
->btarget
= env
->btarget
;
1320 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1322 TCGv_i32 texcp
= tcg_const_i32(excp
);
1323 TCGv_i32 terr
= tcg_const_i32(err
);
1324 save_cpu_state(ctx
, 1);
1325 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1326 tcg_temp_free_i32(terr
);
1327 tcg_temp_free_i32(texcp
);
1331 generate_exception (DisasContext
*ctx
, int excp
)
1333 save_cpu_state(ctx
, 1);
1334 gen_helper_0e0i(raise_exception
, excp
);
1337 /* Addresses computation */
1338 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1340 tcg_gen_add_tl(ret
, arg0
, arg1
);
1342 #if defined(TARGET_MIPS64)
1343 /* For compatibility with 32-bit code, data reference in user mode
1344 with Status_UX = 0 should be casted to 32-bit and sign extended.
1345 See the MIPS64 PRA manual, section 4.10. */
1346 if (((ctx
->hflags
& MIPS_HFLAG_KSU
) == MIPS_HFLAG_UM
) &&
1347 !(ctx
->hflags
& MIPS_HFLAG_UX
)) {
1348 tcg_gen_ext32s_i64(ret
, ret
);
1353 static inline void check_cp0_enabled(DisasContext
*ctx
)
1355 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1356 generate_exception_err(ctx
, EXCP_CpU
, 0);
1359 static inline void check_cp1_enabled(DisasContext
*ctx
)
1361 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1362 generate_exception_err(ctx
, EXCP_CpU
, 1);
1365 /* Verify that the processor is running with COP1X instructions enabled.
1366 This is associated with the nabla symbol in the MIPS32 and MIPS64
1369 static inline void check_cop1x(DisasContext
*ctx
)
1371 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1372 generate_exception(ctx
, EXCP_RI
);
1375 /* Verify that the processor is running with 64-bit floating-point
1376 operations enabled. */
1378 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1380 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1381 generate_exception(ctx
, EXCP_RI
);
1385 * Verify if floating point register is valid; an operation is not defined
1386 * if bit 0 of any register specification is set and the FR bit in the
1387 * Status register equals zero, since the register numbers specify an
1388 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1389 * in the Status register equals one, both even and odd register numbers
1390 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1392 * Multiple 64 bit wide registers can be checked by calling
1393 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1395 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1397 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1398 generate_exception(ctx
, EXCP_RI
);
1401 /* Verify that the processor is running with DSP instructions enabled.
1402 This is enabled by CP0 Status register MX(24) bit.
1405 static inline void check_dsp(DisasContext
*ctx
)
1407 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1408 if (ctx
->insn_flags
& ASE_DSP
) {
1409 generate_exception(ctx
, EXCP_DSPDIS
);
1411 generate_exception(ctx
, EXCP_RI
);
1416 static inline void check_dspr2(DisasContext
*ctx
)
1418 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1419 if (ctx
->insn_flags
& ASE_DSP
) {
1420 generate_exception(ctx
, EXCP_DSPDIS
);
1422 generate_exception(ctx
, EXCP_RI
);
1427 /* This code generates a "reserved instruction" exception if the
1428 CPU does not support the instruction set corresponding to flags. */
1429 static inline void check_insn(DisasContext
*ctx
, int flags
)
1431 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1432 generate_exception(ctx
, EXCP_RI
);
1436 /* This code generates a "reserved instruction" exception if 64-bit
1437 instructions are not enabled. */
1438 static inline void check_mips_64(DisasContext
*ctx
)
1440 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1441 generate_exception(ctx
, EXCP_RI
);
1444 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1445 calling interface for 32 and 64-bit FPRs. No sense in changing
1446 all callers for gen_load_fpr32 when we need the CTX parameter for
1448 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1449 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1450 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1451 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1452 int ft, int fs, int cc) \
1454 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1455 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1458 check_cp1_64bitmode(ctx); \
1464 check_cp1_registers(ctx, fs | ft); \
1472 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1473 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1475 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1476 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1477 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1478 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1479 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1480 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1481 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1482 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1483 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1484 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1485 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1486 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1487 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1488 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1489 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1490 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1493 tcg_temp_free_i##bits (fp0); \
1494 tcg_temp_free_i##bits (fp1); \
1497 FOP_CONDS(, 0, d
, FMT_D
, 64)
1498 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1499 FOP_CONDS(, 0, s
, FMT_S
, 32)
1500 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1501 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1502 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1504 #undef gen_ldcmp_fpr32
1505 #undef gen_ldcmp_fpr64
1507 /* load/store instructions. */
1508 #ifdef CONFIG_USER_ONLY
1509 #define OP_LD_ATOMIC(insn,fname) \
1510 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1512 TCGv t0 = tcg_temp_new(); \
1513 tcg_gen_mov_tl(t0, arg1); \
1514 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1515 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1516 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1517 tcg_temp_free(t0); \
1520 #define OP_LD_ATOMIC(insn,fname) \
1521 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1523 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1526 OP_LD_ATOMIC(ll
,ld32s
);
1527 #if defined(TARGET_MIPS64)
1528 OP_LD_ATOMIC(lld
,ld64
);
1532 #ifdef CONFIG_USER_ONLY
1533 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1534 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1536 TCGv t0 = tcg_temp_new(); \
1537 int l1 = gen_new_label(); \
1538 int l2 = gen_new_label(); \
1540 tcg_gen_andi_tl(t0, arg2, almask); \
1541 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1542 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1543 generate_exception(ctx, EXCP_AdES); \
1544 gen_set_label(l1); \
1545 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1546 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1547 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1548 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1549 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1550 gen_helper_0e0i(raise_exception, EXCP_SC); \
1551 gen_set_label(l2); \
1552 tcg_gen_movi_tl(t0, 0); \
1553 gen_store_gpr(t0, rt); \
1554 tcg_temp_free(t0); \
1557 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1558 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1560 TCGv t0 = tcg_temp_new(); \
1561 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1562 gen_store_gpr(t0, rt); \
1563 tcg_temp_free(t0); \
1566 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1567 #if defined(TARGET_MIPS64)
1568 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1572 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1573 int base
, int16_t offset
)
1576 tcg_gen_movi_tl(addr
, offset
);
1577 } else if (offset
== 0) {
1578 gen_load_gpr(addr
, base
);
1580 tcg_gen_movi_tl(addr
, offset
);
1581 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1585 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1587 target_ulong pc
= ctx
->pc
;
1589 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1590 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1595 pc
&= ~(target_ulong
)3;
1600 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1601 int rt
, int base
, int16_t offset
)
1603 const char *opn
= "ld";
1606 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1607 /* Loongson CPU uses a load to zero register for prefetch.
1608 We emulate it as a NOP. On other CPU we must perform the
1609 actual memory access. */
1614 t0
= tcg_temp_new();
1615 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1618 #if defined(TARGET_MIPS64)
1620 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1621 gen_store_gpr(t0
, rt
);
1625 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1626 gen_store_gpr(t0
, rt
);
1630 save_cpu_state(ctx
, 1);
1631 op_ld_lld(t0
, t0
, ctx
);
1632 gen_store_gpr(t0
, rt
);
1636 t1
= tcg_temp_new();
1637 tcg_gen_andi_tl(t1
, t0
, 7);
1638 #ifndef TARGET_WORDS_BIGENDIAN
1639 tcg_gen_xori_tl(t1
, t1
, 7);
1641 tcg_gen_shli_tl(t1
, t1
, 3);
1642 tcg_gen_andi_tl(t0
, t0
, ~7);
1643 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1644 tcg_gen_shl_tl(t0
, t0
, t1
);
1645 tcg_gen_xori_tl(t1
, t1
, 63);
1646 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1647 tcg_gen_shr_tl(t2
, t2
, t1
);
1648 gen_load_gpr(t1
, rt
);
1649 tcg_gen_and_tl(t1
, t1
, t2
);
1651 tcg_gen_or_tl(t0
, t0
, t1
);
1653 gen_store_gpr(t0
, rt
);
1657 t1
= tcg_temp_new();
1658 tcg_gen_andi_tl(t1
, t0
, 7);
1659 #ifdef TARGET_WORDS_BIGENDIAN
1660 tcg_gen_xori_tl(t1
, t1
, 7);
1662 tcg_gen_shli_tl(t1
, t1
, 3);
1663 tcg_gen_andi_tl(t0
, t0
, ~7);
1664 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1665 tcg_gen_shr_tl(t0
, t0
, t1
);
1666 tcg_gen_xori_tl(t1
, t1
, 63);
1667 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1668 tcg_gen_shl_tl(t2
, t2
, t1
);
1669 gen_load_gpr(t1
, rt
);
1670 tcg_gen_and_tl(t1
, t1
, t2
);
1672 tcg_gen_or_tl(t0
, t0
, t1
);
1674 gen_store_gpr(t0
, rt
);
1678 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1679 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1681 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1682 gen_store_gpr(t0
, rt
);
1687 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1688 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1690 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1691 gen_store_gpr(t0
, rt
);
1695 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1696 gen_store_gpr(t0
, rt
);
1700 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
1701 gen_store_gpr(t0
, rt
);
1705 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
1706 gen_store_gpr(t0
, rt
);
1710 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
1711 gen_store_gpr(t0
, rt
);
1715 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
1716 gen_store_gpr(t0
, rt
);
1720 t1
= tcg_temp_new();
1721 tcg_gen_andi_tl(t1
, t0
, 3);
1722 #ifndef TARGET_WORDS_BIGENDIAN
1723 tcg_gen_xori_tl(t1
, t1
, 3);
1725 tcg_gen_shli_tl(t1
, t1
, 3);
1726 tcg_gen_andi_tl(t0
, t0
, ~3);
1727 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1728 tcg_gen_shl_tl(t0
, t0
, t1
);
1729 tcg_gen_xori_tl(t1
, t1
, 31);
1730 t2
= tcg_const_tl(0x7fffffffull
);
1731 tcg_gen_shr_tl(t2
, t2
, t1
);
1732 gen_load_gpr(t1
, rt
);
1733 tcg_gen_and_tl(t1
, t1
, t2
);
1735 tcg_gen_or_tl(t0
, t0
, t1
);
1737 tcg_gen_ext32s_tl(t0
, t0
);
1738 gen_store_gpr(t0
, rt
);
1742 t1
= tcg_temp_new();
1743 tcg_gen_andi_tl(t1
, t0
, 3);
1744 #ifdef TARGET_WORDS_BIGENDIAN
1745 tcg_gen_xori_tl(t1
, t1
, 3);
1747 tcg_gen_shli_tl(t1
, t1
, 3);
1748 tcg_gen_andi_tl(t0
, t0
, ~3);
1749 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1750 tcg_gen_shr_tl(t0
, t0
, t1
);
1751 tcg_gen_xori_tl(t1
, t1
, 31);
1752 t2
= tcg_const_tl(0xfffffffeull
);
1753 tcg_gen_shl_tl(t2
, t2
, t1
);
1754 gen_load_gpr(t1
, rt
);
1755 tcg_gen_and_tl(t1
, t1
, t2
);
1757 tcg_gen_or_tl(t0
, t0
, t1
);
1759 tcg_gen_ext32s_tl(t0
, t0
);
1760 gen_store_gpr(t0
, rt
);
1764 save_cpu_state(ctx
, 1);
1765 op_ld_ll(t0
, t0
, ctx
);
1766 gen_store_gpr(t0
, rt
);
1770 (void)opn
; /* avoid a compiler warning */
1771 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1776 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1777 int base
, int16_t offset
)
1779 const char *opn
= "st";
1780 TCGv t0
= tcg_temp_new();
1781 TCGv t1
= tcg_temp_new();
1783 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1784 gen_load_gpr(t1
, rt
);
1786 #if defined(TARGET_MIPS64)
1788 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
1792 save_cpu_state(ctx
, 1);
1793 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1797 save_cpu_state(ctx
, 1);
1798 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
1803 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
1807 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
1811 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
1815 save_cpu_state(ctx
, 1);
1816 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
1820 save_cpu_state(ctx
, 1);
1821 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
1825 (void)opn
; /* avoid a compiler warning */
1826 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1832 /* Store conditional */
1833 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
1834 int base
, int16_t offset
)
1836 const char *opn
= "st_cond";
1839 #ifdef CONFIG_USER_ONLY
1840 t0
= tcg_temp_local_new();
1841 t1
= tcg_temp_local_new();
1843 t0
= tcg_temp_new();
1844 t1
= tcg_temp_new();
1846 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1847 gen_load_gpr(t1
, rt
);
1849 #if defined(TARGET_MIPS64)
1851 save_cpu_state(ctx
, 1);
1852 op_st_scd(t1
, t0
, rt
, ctx
);
1857 save_cpu_state(ctx
, 1);
1858 op_st_sc(t1
, t0
, rt
, ctx
);
1862 (void)opn
; /* avoid a compiler warning */
1863 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1868 /* Load and store */
1869 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
1870 int base
, int16_t offset
)
1872 const char *opn
= "flt_ldst";
1873 TCGv t0
= tcg_temp_new();
1875 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1876 /* Don't do NOP if destination is zero: we must perform the actual
1881 TCGv_i32 fp0
= tcg_temp_new_i32();
1882 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
1883 gen_store_fpr32(fp0
, ft
);
1884 tcg_temp_free_i32(fp0
);
1890 TCGv_i32 fp0
= tcg_temp_new_i32();
1891 gen_load_fpr32(fp0
, ft
);
1892 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1893 tcg_temp_free_i32(fp0
);
1899 TCGv_i64 fp0
= tcg_temp_new_i64();
1900 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1901 gen_store_fpr64(ctx
, fp0
, ft
);
1902 tcg_temp_free_i64(fp0
);
1908 TCGv_i64 fp0
= tcg_temp_new_i64();
1909 gen_load_fpr64(ctx
, fp0
, ft
);
1910 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1911 tcg_temp_free_i64(fp0
);
1917 generate_exception(ctx
, EXCP_RI
);
1920 (void)opn
; /* avoid a compiler warning */
1921 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
1926 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
1927 int rs
, int16_t imm
)
1929 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
1930 check_cp1_enabled(ctx
);
1931 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
1933 generate_exception_err(ctx
, EXCP_CpU
, 1);
1937 /* Arithmetic with immediate operand */
1938 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
1939 int rt
, int rs
, int16_t imm
)
1941 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
1942 const char *opn
= "imm arith";
1944 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
1945 /* If no destination, treat it as a NOP.
1946 For addi, we must generate the overflow exception when needed. */
1953 TCGv t0
= tcg_temp_local_new();
1954 TCGv t1
= tcg_temp_new();
1955 TCGv t2
= tcg_temp_new();
1956 int l1
= gen_new_label();
1958 gen_load_gpr(t1
, rs
);
1959 tcg_gen_addi_tl(t0
, t1
, uimm
);
1960 tcg_gen_ext32s_tl(t0
, t0
);
1962 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1963 tcg_gen_xori_tl(t2
, t0
, uimm
);
1964 tcg_gen_and_tl(t1
, t1
, t2
);
1966 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1968 /* operands of same sign, result different sign */
1969 generate_exception(ctx
, EXCP_OVERFLOW
);
1971 tcg_gen_ext32s_tl(t0
, t0
);
1972 gen_store_gpr(t0
, rt
);
1979 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1980 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
1982 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1986 #if defined(TARGET_MIPS64)
1989 TCGv t0
= tcg_temp_local_new();
1990 TCGv t1
= tcg_temp_new();
1991 TCGv t2
= tcg_temp_new();
1992 int l1
= gen_new_label();
1994 gen_load_gpr(t1
, rs
);
1995 tcg_gen_addi_tl(t0
, t1
, uimm
);
1997 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1998 tcg_gen_xori_tl(t2
, t0
, uimm
);
1999 tcg_gen_and_tl(t1
, t1
, t2
);
2001 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2003 /* operands of same sign, result different sign */
2004 generate_exception(ctx
, EXCP_OVERFLOW
);
2006 gen_store_gpr(t0
, rt
);
2013 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2015 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2021 (void)opn
; /* avoid a compiler warning */
2022 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2025 /* Logic with immediate operand */
2026 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2027 int rt
, int rs
, int16_t imm
)
2032 /* If no destination, treat it as a NOP. */
2036 uimm
= (uint16_t)imm
;
2039 if (likely(rs
!= 0))
2040 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2042 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2043 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2044 regnames
[rs
], uimm
);
2048 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2050 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2051 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2052 regnames
[rs
], uimm
);
2055 if (likely(rs
!= 0))
2056 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2058 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2059 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2060 regnames
[rs
], uimm
);
2063 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2064 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2068 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2073 /* Set on less than with immediate operand */
2074 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2075 int rt
, int rs
, int16_t imm
)
2077 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2078 const char *opn
= "imm arith";
2082 /* If no destination, treat it as a NOP. */
2086 t0
= tcg_temp_new();
2087 gen_load_gpr(t0
, rs
);
2090 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2094 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2098 (void)opn
; /* avoid a compiler warning */
2099 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2103 /* Shifts with immediate operand */
2104 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2105 int rt
, int rs
, int16_t imm
)
2107 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2108 const char *opn
= "imm shift";
2112 /* If no destination, treat it as a NOP. */
2117 t0
= tcg_temp_new();
2118 gen_load_gpr(t0
, rs
);
2121 tcg_gen_shli_tl(t0
, t0
, uimm
);
2122 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2126 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2131 tcg_gen_ext32u_tl(t0
, t0
);
2132 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2134 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2140 TCGv_i32 t1
= tcg_temp_new_i32();
2142 tcg_gen_trunc_tl_i32(t1
, t0
);
2143 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2144 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2145 tcg_temp_free_i32(t1
);
2147 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2151 #if defined(TARGET_MIPS64)
2153 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2157 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2161 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2166 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2168 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2173 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2177 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2181 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2185 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2190 (void)opn
; /* avoid a compiler warning */
2191 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2196 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2197 int rd
, int rs
, int rt
)
2199 const char *opn
= "arith";
2201 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2202 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2203 /* If no destination, treat it as a NOP.
2204 For add & sub, we must generate the overflow exception when needed. */
2212 TCGv t0
= tcg_temp_local_new();
2213 TCGv t1
= tcg_temp_new();
2214 TCGv t2
= tcg_temp_new();
2215 int l1
= gen_new_label();
2217 gen_load_gpr(t1
, rs
);
2218 gen_load_gpr(t2
, rt
);
2219 tcg_gen_add_tl(t0
, t1
, t2
);
2220 tcg_gen_ext32s_tl(t0
, t0
);
2221 tcg_gen_xor_tl(t1
, t1
, t2
);
2222 tcg_gen_xor_tl(t2
, t0
, t2
);
2223 tcg_gen_andc_tl(t1
, t2
, t1
);
2225 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2227 /* operands of same sign, result different sign */
2228 generate_exception(ctx
, EXCP_OVERFLOW
);
2230 gen_store_gpr(t0
, rd
);
2236 if (rs
!= 0 && rt
!= 0) {
2237 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2238 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2239 } else if (rs
== 0 && rt
!= 0) {
2240 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2241 } else if (rs
!= 0 && rt
== 0) {
2242 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2244 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2250 TCGv t0
= tcg_temp_local_new();
2251 TCGv t1
= tcg_temp_new();
2252 TCGv t2
= tcg_temp_new();
2253 int l1
= gen_new_label();
2255 gen_load_gpr(t1
, rs
);
2256 gen_load_gpr(t2
, rt
);
2257 tcg_gen_sub_tl(t0
, t1
, t2
);
2258 tcg_gen_ext32s_tl(t0
, t0
);
2259 tcg_gen_xor_tl(t2
, t1
, t2
);
2260 tcg_gen_xor_tl(t1
, t0
, t1
);
2261 tcg_gen_and_tl(t1
, t1
, t2
);
2263 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2265 /* operands of different sign, first operand and result different sign */
2266 generate_exception(ctx
, EXCP_OVERFLOW
);
2268 gen_store_gpr(t0
, rd
);
2274 if (rs
!= 0 && rt
!= 0) {
2275 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2276 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2277 } else if (rs
== 0 && rt
!= 0) {
2278 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2279 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2280 } else if (rs
!= 0 && rt
== 0) {
2281 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2283 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2287 #if defined(TARGET_MIPS64)
2290 TCGv t0
= tcg_temp_local_new();
2291 TCGv t1
= tcg_temp_new();
2292 TCGv t2
= tcg_temp_new();
2293 int l1
= gen_new_label();
2295 gen_load_gpr(t1
, rs
);
2296 gen_load_gpr(t2
, rt
);
2297 tcg_gen_add_tl(t0
, t1
, t2
);
2298 tcg_gen_xor_tl(t1
, t1
, t2
);
2299 tcg_gen_xor_tl(t2
, t0
, t2
);
2300 tcg_gen_andc_tl(t1
, t2
, t1
);
2302 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2304 /* operands of same sign, result different sign */
2305 generate_exception(ctx
, EXCP_OVERFLOW
);
2307 gen_store_gpr(t0
, rd
);
2313 if (rs
!= 0 && rt
!= 0) {
2314 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2315 } else if (rs
== 0 && rt
!= 0) {
2316 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2317 } else if (rs
!= 0 && rt
== 0) {
2318 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2320 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2326 TCGv t0
= tcg_temp_local_new();
2327 TCGv t1
= tcg_temp_new();
2328 TCGv t2
= tcg_temp_new();
2329 int l1
= gen_new_label();
2331 gen_load_gpr(t1
, rs
);
2332 gen_load_gpr(t2
, rt
);
2333 tcg_gen_sub_tl(t0
, t1
, t2
);
2334 tcg_gen_xor_tl(t2
, t1
, t2
);
2335 tcg_gen_xor_tl(t1
, t0
, t1
);
2336 tcg_gen_and_tl(t1
, t1
, t2
);
2338 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2340 /* operands of different sign, first operand and result different sign */
2341 generate_exception(ctx
, EXCP_OVERFLOW
);
2343 gen_store_gpr(t0
, rd
);
2349 if (rs
!= 0 && rt
!= 0) {
2350 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2351 } else if (rs
== 0 && rt
!= 0) {
2352 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2353 } else if (rs
!= 0 && rt
== 0) {
2354 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2356 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2362 if (likely(rs
!= 0 && rt
!= 0)) {
2363 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2364 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2366 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2371 (void)opn
; /* avoid a compiler warning */
2372 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2375 /* Conditional move */
2376 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2377 int rd
, int rs
, int rt
)
2379 const char *opn
= "cond move";
2383 /* If no destination, treat it as a NOP. */
2388 t0
= tcg_temp_new();
2389 gen_load_gpr(t0
, rt
);
2390 t1
= tcg_const_tl(0);
2391 t2
= tcg_temp_new();
2392 gen_load_gpr(t2
, rs
);
2395 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2399 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2407 (void)opn
; /* avoid a compiler warning */
2408 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2412 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2413 int rd
, int rs
, int rt
)
2415 const char *opn
= "logic";
2418 /* If no destination, treat it as a NOP. */
2425 if (likely(rs
!= 0 && rt
!= 0)) {
2426 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2428 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2433 if (rs
!= 0 && rt
!= 0) {
2434 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2435 } else if (rs
== 0 && rt
!= 0) {
2436 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2437 } else if (rs
!= 0 && rt
== 0) {
2438 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2440 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2445 if (likely(rs
!= 0 && rt
!= 0)) {
2446 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2447 } else if (rs
== 0 && rt
!= 0) {
2448 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2449 } else if (rs
!= 0 && rt
== 0) {
2450 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2452 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2457 if (likely(rs
!= 0 && rt
!= 0)) {
2458 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2459 } else if (rs
== 0 && rt
!= 0) {
2460 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2461 } else if (rs
!= 0 && rt
== 0) {
2462 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2464 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2469 (void)opn
; /* avoid a compiler warning */
2470 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2473 /* Set on lower than */
2474 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2475 int rd
, int rs
, int rt
)
2477 const char *opn
= "slt";
2481 /* If no destination, treat it as a NOP. */
2486 t0
= tcg_temp_new();
2487 t1
= tcg_temp_new();
2488 gen_load_gpr(t0
, rs
);
2489 gen_load_gpr(t1
, rt
);
2492 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2496 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2500 (void)opn
; /* avoid a compiler warning */
2501 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2507 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2508 int rd
, int rs
, int rt
)
2510 const char *opn
= "shifts";
2514 /* If no destination, treat it as a NOP.
2515 For add & sub, we must generate the overflow exception when needed. */
2520 t0
= tcg_temp_new();
2521 t1
= tcg_temp_new();
2522 gen_load_gpr(t0
, rs
);
2523 gen_load_gpr(t1
, rt
);
2526 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2527 tcg_gen_shl_tl(t0
, t1
, t0
);
2528 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2532 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2533 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2537 tcg_gen_ext32u_tl(t1
, t1
);
2538 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2539 tcg_gen_shr_tl(t0
, t1
, t0
);
2540 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2545 TCGv_i32 t2
= tcg_temp_new_i32();
2546 TCGv_i32 t3
= tcg_temp_new_i32();
2548 tcg_gen_trunc_tl_i32(t2
, t0
);
2549 tcg_gen_trunc_tl_i32(t3
, t1
);
2550 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2551 tcg_gen_rotr_i32(t2
, t3
, t2
);
2552 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2553 tcg_temp_free_i32(t2
);
2554 tcg_temp_free_i32(t3
);
2558 #if defined(TARGET_MIPS64)
2560 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2561 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2565 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2566 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2570 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2571 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2575 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2576 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2581 (void)opn
; /* avoid a compiler warning */
2582 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2587 /* Arithmetic on HI/LO registers */
2588 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2590 const char *opn
= "hilo";
2592 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2604 #if defined(TARGET_MIPS64)
2606 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2610 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2615 #if defined(TARGET_MIPS64)
2617 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2621 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2627 #if defined(TARGET_MIPS64)
2629 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2633 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2636 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2642 #if defined(TARGET_MIPS64)
2644 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2648 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2651 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2656 (void)opn
; /* avoid a compiler warning */
2657 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2660 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
2661 int acc
, int rs
, int rt
)
2663 const char *opn
= "mul/div";
2666 t0
= tcg_temp_new();
2667 t1
= tcg_temp_new();
2669 gen_load_gpr(t0
, rs
);
2670 gen_load_gpr(t1
, rt
);
2679 TCGv t2
= tcg_temp_new();
2680 TCGv t3
= tcg_temp_new();
2681 tcg_gen_ext32s_tl(t0
, t0
);
2682 tcg_gen_ext32s_tl(t1
, t1
);
2683 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2684 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2685 tcg_gen_and_tl(t2
, t2
, t3
);
2686 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2687 tcg_gen_or_tl(t2
, t2
, t3
);
2688 tcg_gen_movi_tl(t3
, 0);
2689 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2690 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2691 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2692 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2693 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2701 TCGv t2
= tcg_const_tl(0);
2702 TCGv t3
= tcg_const_tl(1);
2703 tcg_gen_ext32u_tl(t0
, t0
);
2704 tcg_gen_ext32u_tl(t1
, t1
);
2705 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2706 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
2707 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
2708 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2709 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2717 TCGv_i32 t2
= tcg_temp_new_i32();
2718 TCGv_i32 t3
= tcg_temp_new_i32();
2719 tcg_gen_trunc_tl_i32(t2
, t0
);
2720 tcg_gen_trunc_tl_i32(t3
, t1
);
2721 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
2722 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2723 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2724 tcg_temp_free_i32(t2
);
2725 tcg_temp_free_i32(t3
);
2731 TCGv_i32 t2
= tcg_temp_new_i32();
2732 TCGv_i32 t3
= tcg_temp_new_i32();
2733 tcg_gen_trunc_tl_i32(t2
, t0
);
2734 tcg_gen_trunc_tl_i32(t3
, t1
);
2735 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
2736 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2737 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2738 tcg_temp_free_i32(t2
);
2739 tcg_temp_free_i32(t3
);
2743 #if defined(TARGET_MIPS64)
2746 TCGv t2
= tcg_temp_new();
2747 TCGv t3
= tcg_temp_new();
2748 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2749 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2750 tcg_gen_and_tl(t2
, t2
, t3
);
2751 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2752 tcg_gen_or_tl(t2
, t2
, t3
);
2753 tcg_gen_movi_tl(t3
, 0);
2754 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2755 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2756 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2764 TCGv t2
= tcg_const_tl(0);
2765 TCGv t3
= tcg_const_tl(1);
2766 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2767 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
2768 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
2775 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2779 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2785 TCGv_i64 t2
= tcg_temp_new_i64();
2786 TCGv_i64 t3
= tcg_temp_new_i64();
2788 tcg_gen_ext_tl_i64(t2
, t0
);
2789 tcg_gen_ext_tl_i64(t3
, t1
);
2790 tcg_gen_mul_i64(t2
, t2
, t3
);
2791 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2792 tcg_gen_add_i64(t2
, t2
, t3
);
2793 tcg_temp_free_i64(t3
);
2794 tcg_gen_trunc_i64_tl(t0
, t2
);
2795 tcg_gen_shri_i64(t2
, t2
, 32);
2796 tcg_gen_trunc_i64_tl(t1
, t2
);
2797 tcg_temp_free_i64(t2
);
2798 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2799 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2805 TCGv_i64 t2
= tcg_temp_new_i64();
2806 TCGv_i64 t3
= tcg_temp_new_i64();
2808 tcg_gen_ext32u_tl(t0
, t0
);
2809 tcg_gen_ext32u_tl(t1
, t1
);
2810 tcg_gen_extu_tl_i64(t2
, t0
);
2811 tcg_gen_extu_tl_i64(t3
, t1
);
2812 tcg_gen_mul_i64(t2
, t2
, t3
);
2813 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2814 tcg_gen_add_i64(t2
, t2
, t3
);
2815 tcg_temp_free_i64(t3
);
2816 tcg_gen_trunc_i64_tl(t0
, t2
);
2817 tcg_gen_shri_i64(t2
, t2
, 32);
2818 tcg_gen_trunc_i64_tl(t1
, t2
);
2819 tcg_temp_free_i64(t2
);
2820 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2821 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2827 TCGv_i64 t2
= tcg_temp_new_i64();
2828 TCGv_i64 t3
= tcg_temp_new_i64();
2830 tcg_gen_ext_tl_i64(t2
, t0
);
2831 tcg_gen_ext_tl_i64(t3
, t1
);
2832 tcg_gen_mul_i64(t2
, t2
, t3
);
2833 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2834 tcg_gen_sub_i64(t2
, t3
, t2
);
2835 tcg_temp_free_i64(t3
);
2836 tcg_gen_trunc_i64_tl(t0
, t2
);
2837 tcg_gen_shri_i64(t2
, t2
, 32);
2838 tcg_gen_trunc_i64_tl(t1
, t2
);
2839 tcg_temp_free_i64(t2
);
2840 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2841 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2847 TCGv_i64 t2
= tcg_temp_new_i64();
2848 TCGv_i64 t3
= tcg_temp_new_i64();
2850 tcg_gen_ext32u_tl(t0
, t0
);
2851 tcg_gen_ext32u_tl(t1
, t1
);
2852 tcg_gen_extu_tl_i64(t2
, t0
);
2853 tcg_gen_extu_tl_i64(t3
, t1
);
2854 tcg_gen_mul_i64(t2
, t2
, t3
);
2855 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2856 tcg_gen_sub_i64(t2
, t3
, t2
);
2857 tcg_temp_free_i64(t3
);
2858 tcg_gen_trunc_i64_tl(t0
, t2
);
2859 tcg_gen_shri_i64(t2
, t2
, 32);
2860 tcg_gen_trunc_i64_tl(t1
, t2
);
2861 tcg_temp_free_i64(t2
);
2862 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2863 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2869 generate_exception(ctx
, EXCP_RI
);
2872 (void)opn
; /* avoid a compiler warning */
2873 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2879 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2880 int rd
, int rs
, int rt
)
2882 const char *opn
= "mul vr54xx";
2883 TCGv t0
= tcg_temp_new();
2884 TCGv t1
= tcg_temp_new();
2886 gen_load_gpr(t0
, rs
);
2887 gen_load_gpr(t1
, rt
);
2890 case OPC_VR54XX_MULS
:
2891 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2894 case OPC_VR54XX_MULSU
:
2895 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2898 case OPC_VR54XX_MACC
:
2899 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2902 case OPC_VR54XX_MACCU
:
2903 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2906 case OPC_VR54XX_MSAC
:
2907 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2910 case OPC_VR54XX_MSACU
:
2911 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2914 case OPC_VR54XX_MULHI
:
2915 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2918 case OPC_VR54XX_MULHIU
:
2919 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2922 case OPC_VR54XX_MULSHI
:
2923 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2926 case OPC_VR54XX_MULSHIU
:
2927 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2930 case OPC_VR54XX_MACCHI
:
2931 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2934 case OPC_VR54XX_MACCHIU
:
2935 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2938 case OPC_VR54XX_MSACHI
:
2939 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2942 case OPC_VR54XX_MSACHIU
:
2943 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2947 MIPS_INVAL("mul vr54xx");
2948 generate_exception(ctx
, EXCP_RI
);
2951 gen_store_gpr(t0
, rd
);
2952 (void)opn
; /* avoid a compiler warning */
2953 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2960 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2963 const char *opn
= "CLx";
2971 t0
= tcg_temp_new();
2972 gen_load_gpr(t0
, rs
);
2975 gen_helper_clo(cpu_gpr
[rd
], t0
);
2979 gen_helper_clz(cpu_gpr
[rd
], t0
);
2982 #if defined(TARGET_MIPS64)
2984 gen_helper_dclo(cpu_gpr
[rd
], t0
);
2988 gen_helper_dclz(cpu_gpr
[rd
], t0
);
2993 (void)opn
; /* avoid a compiler warning */
2994 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
2998 /* Godson integer instructions */
2999 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3000 int rd
, int rs
, int rt
)
3002 const char *opn
= "loongson";
3014 case OPC_MULTU_G_2E
:
3015 case OPC_MULTU_G_2F
:
3016 #if defined(TARGET_MIPS64)
3017 case OPC_DMULT_G_2E
:
3018 case OPC_DMULT_G_2F
:
3019 case OPC_DMULTU_G_2E
:
3020 case OPC_DMULTU_G_2F
:
3022 t0
= tcg_temp_new();
3023 t1
= tcg_temp_new();
3026 t0
= tcg_temp_local_new();
3027 t1
= tcg_temp_local_new();
3031 gen_load_gpr(t0
, rs
);
3032 gen_load_gpr(t1
, rt
);
3037 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3038 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3041 case OPC_MULTU_G_2E
:
3042 case OPC_MULTU_G_2F
:
3043 tcg_gen_ext32u_tl(t0
, t0
);
3044 tcg_gen_ext32u_tl(t1
, t1
);
3045 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3046 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3052 int l1
= gen_new_label();
3053 int l2
= gen_new_label();
3054 int l3
= gen_new_label();
3055 tcg_gen_ext32s_tl(t0
, t0
);
3056 tcg_gen_ext32s_tl(t1
, t1
);
3057 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3058 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3061 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3062 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3063 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3066 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3067 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3075 int l1
= gen_new_label();
3076 int l2
= gen_new_label();
3077 tcg_gen_ext32u_tl(t0
, t0
);
3078 tcg_gen_ext32u_tl(t1
, t1
);
3079 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3080 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3083 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3084 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3092 int l1
= gen_new_label();
3093 int l2
= gen_new_label();
3094 int l3
= gen_new_label();
3095 tcg_gen_ext32u_tl(t0
, t0
);
3096 tcg_gen_ext32u_tl(t1
, t1
);
3097 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3098 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3099 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3101 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3104 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3105 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3113 int l1
= gen_new_label();
3114 int l2
= gen_new_label();
3115 tcg_gen_ext32u_tl(t0
, t0
);
3116 tcg_gen_ext32u_tl(t1
, t1
);
3117 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3118 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3121 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3122 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3127 #if defined(TARGET_MIPS64)
3128 case OPC_DMULT_G_2E
:
3129 case OPC_DMULT_G_2F
:
3130 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3133 case OPC_DMULTU_G_2E
:
3134 case OPC_DMULTU_G_2F
:
3135 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3141 int l1
= gen_new_label();
3142 int l2
= gen_new_label();
3143 int l3
= gen_new_label();
3144 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3145 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3148 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3149 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3150 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3153 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3158 case OPC_DDIVU_G_2E
:
3159 case OPC_DDIVU_G_2F
:
3161 int l1
= gen_new_label();
3162 int l2
= gen_new_label();
3163 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3164 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3167 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3175 int l1
= gen_new_label();
3176 int l2
= gen_new_label();
3177 int l3
= gen_new_label();
3178 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3179 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3180 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3182 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3185 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3190 case OPC_DMODU_G_2E
:
3191 case OPC_DMODU_G_2F
:
3193 int l1
= gen_new_label();
3194 int l2
= gen_new_label();
3195 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3196 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3199 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3207 (void)opn
; /* avoid a compiler warning */
3208 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3213 /* Loongson multimedia instructions */
3214 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3216 const char *opn
= "loongson_cp2";
3217 uint32_t opc
, shift_max
;
3220 opc
= MASK_LMI(ctx
->opcode
);
3226 t0
= tcg_temp_local_new_i64();
3227 t1
= tcg_temp_local_new_i64();
3230 t0
= tcg_temp_new_i64();
3231 t1
= tcg_temp_new_i64();
3235 gen_load_fpr64(ctx
, t0
, rs
);
3236 gen_load_fpr64(ctx
, t1
, rt
);
3238 #define LMI_HELPER(UP, LO) \
3239 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3240 #define LMI_HELPER_1(UP, LO) \
3241 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3242 #define LMI_DIRECT(UP, LO, OP) \
3243 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3246 LMI_HELPER(PADDSH
, paddsh
);
3247 LMI_HELPER(PADDUSH
, paddush
);
3248 LMI_HELPER(PADDH
, paddh
);
3249 LMI_HELPER(PADDW
, paddw
);
3250 LMI_HELPER(PADDSB
, paddsb
);
3251 LMI_HELPER(PADDUSB
, paddusb
);
3252 LMI_HELPER(PADDB
, paddb
);
3254 LMI_HELPER(PSUBSH
, psubsh
);
3255 LMI_HELPER(PSUBUSH
, psubush
);
3256 LMI_HELPER(PSUBH
, psubh
);
3257 LMI_HELPER(PSUBW
, psubw
);
3258 LMI_HELPER(PSUBSB
, psubsb
);
3259 LMI_HELPER(PSUBUSB
, psubusb
);
3260 LMI_HELPER(PSUBB
, psubb
);
3262 LMI_HELPER(PSHUFH
, pshufh
);
3263 LMI_HELPER(PACKSSWH
, packsswh
);
3264 LMI_HELPER(PACKSSHB
, packsshb
);
3265 LMI_HELPER(PACKUSHB
, packushb
);
3267 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3268 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3269 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3270 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3271 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3272 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3274 LMI_HELPER(PAVGH
, pavgh
);
3275 LMI_HELPER(PAVGB
, pavgb
);
3276 LMI_HELPER(PMAXSH
, pmaxsh
);
3277 LMI_HELPER(PMINSH
, pminsh
);
3278 LMI_HELPER(PMAXUB
, pmaxub
);
3279 LMI_HELPER(PMINUB
, pminub
);
3281 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3282 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3283 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3284 LMI_HELPER(PCMPGTH
, pcmpgth
);
3285 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3286 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3288 LMI_HELPER(PSLLW
, psllw
);
3289 LMI_HELPER(PSLLH
, psllh
);
3290 LMI_HELPER(PSRLW
, psrlw
);
3291 LMI_HELPER(PSRLH
, psrlh
);
3292 LMI_HELPER(PSRAW
, psraw
);
3293 LMI_HELPER(PSRAH
, psrah
);
3295 LMI_HELPER(PMULLH
, pmullh
);
3296 LMI_HELPER(PMULHH
, pmulhh
);
3297 LMI_HELPER(PMULHUH
, pmulhuh
);
3298 LMI_HELPER(PMADDHW
, pmaddhw
);
3300 LMI_HELPER(PASUBUB
, pasubub
);
3301 LMI_HELPER_1(BIADD
, biadd
);
3302 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3304 LMI_DIRECT(PADDD
, paddd
, add
);
3305 LMI_DIRECT(PSUBD
, psubd
, sub
);
3306 LMI_DIRECT(XOR_CP2
, xor, xor);
3307 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3308 LMI_DIRECT(AND_CP2
, and, and);
3309 LMI_DIRECT(PANDN
, pandn
, andc
);
3310 LMI_DIRECT(OR
, or, or);
3313 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3317 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3321 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3325 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3330 tcg_gen_andi_i64(t1
, t1
, 3);
3331 tcg_gen_shli_i64(t1
, t1
, 4);
3332 tcg_gen_shr_i64(t0
, t0
, t1
);
3333 tcg_gen_ext16u_i64(t0
, t0
);
3338 tcg_gen_add_i64(t0
, t0
, t1
);
3339 tcg_gen_ext32s_i64(t0
, t0
);
3343 tcg_gen_sub_i64(t0
, t0
, t1
);
3344 tcg_gen_ext32s_i64(t0
, t0
);
3373 /* Make sure shift count isn't TCG undefined behaviour. */
3374 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3379 tcg_gen_shl_i64(t0
, t0
, t1
);
3383 /* Since SRA is UndefinedResult without sign-extended inputs,
3384 we can treat SRA and DSRA the same. */
3385 tcg_gen_sar_i64(t0
, t0
, t1
);
3388 /* We want to shift in zeros for SRL; zero-extend first. */
3389 tcg_gen_ext32u_i64(t0
, t0
);
3392 tcg_gen_shr_i64(t0
, t0
, t1
);
3396 if (shift_max
== 32) {
3397 tcg_gen_ext32s_i64(t0
, t0
);
3400 /* Shifts larger than MAX produce zero. */
3401 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3402 tcg_gen_neg_i64(t1
, t1
);
3403 tcg_gen_and_i64(t0
, t0
, t1
);
3409 TCGv_i64 t2
= tcg_temp_new_i64();
3410 int lab
= gen_new_label();
3412 tcg_gen_mov_i64(t2
, t0
);
3413 tcg_gen_add_i64(t0
, t1
, t2
);
3414 if (opc
== OPC_ADD_CP2
) {
3415 tcg_gen_ext32s_i64(t0
, t0
);
3417 tcg_gen_xor_i64(t1
, t1
, t2
);
3418 tcg_gen_xor_i64(t2
, t2
, t0
);
3419 tcg_gen_andc_i64(t1
, t2
, t1
);
3420 tcg_temp_free_i64(t2
);
3421 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3422 generate_exception(ctx
, EXCP_OVERFLOW
);
3425 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3432 TCGv_i64 t2
= tcg_temp_new_i64();
3433 int lab
= gen_new_label();
3435 tcg_gen_mov_i64(t2
, t0
);
3436 tcg_gen_sub_i64(t0
, t1
, t2
);
3437 if (opc
== OPC_SUB_CP2
) {
3438 tcg_gen_ext32s_i64(t0
, t0
);
3440 tcg_gen_xor_i64(t1
, t1
, t2
);
3441 tcg_gen_xor_i64(t2
, t2
, t0
);
3442 tcg_gen_and_i64(t1
, t1
, t2
);
3443 tcg_temp_free_i64(t2
);
3444 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3445 generate_exception(ctx
, EXCP_OVERFLOW
);
3448 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3453 tcg_gen_ext32u_i64(t0
, t0
);
3454 tcg_gen_ext32u_i64(t1
, t1
);
3455 tcg_gen_mul_i64(t0
, t0
, t1
);
3465 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3466 FD field is the CC field? */
3469 generate_exception(ctx
, EXCP_RI
);
3476 gen_store_fpr64(ctx
, t0
, rd
);
3478 (void)opn
; /* avoid a compiler warning */
3479 MIPS_DEBUG("%s %s, %s, %s", opn
,
3480 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3481 tcg_temp_free_i64(t0
);
3482 tcg_temp_free_i64(t1
);
3486 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3487 int rs
, int rt
, int16_t imm
)
3490 TCGv t0
= tcg_temp_new();
3491 TCGv t1
= tcg_temp_new();
3494 /* Load needed operands */
3502 /* Compare two registers */
3504 gen_load_gpr(t0
, rs
);
3505 gen_load_gpr(t1
, rt
);
3515 /* Compare register to immediate */
3516 if (rs
!= 0 || imm
!= 0) {
3517 gen_load_gpr(t0
, rs
);
3518 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3525 case OPC_TEQ
: /* rs == rs */
3526 case OPC_TEQI
: /* r0 == 0 */
3527 case OPC_TGE
: /* rs >= rs */
3528 case OPC_TGEI
: /* r0 >= 0 */
3529 case OPC_TGEU
: /* rs >= rs unsigned */
3530 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3532 generate_exception(ctx
, EXCP_TRAP
);
3534 case OPC_TLT
: /* rs < rs */
3535 case OPC_TLTI
: /* r0 < 0 */
3536 case OPC_TLTU
: /* rs < rs unsigned */
3537 case OPC_TLTIU
: /* r0 < 0 unsigned */
3538 case OPC_TNE
: /* rs != rs */
3539 case OPC_TNEI
: /* r0 != 0 */
3540 /* Never trap: treat as NOP. */
3544 int l1
= gen_new_label();
3549 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3553 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3557 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3561 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3565 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3569 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3572 generate_exception(ctx
, EXCP_TRAP
);
3579 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3581 TranslationBlock
*tb
;
3583 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3584 likely(!ctx
->singlestep_enabled
)) {
3587 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3590 if (ctx
->singlestep_enabled
) {
3591 save_cpu_state(ctx
, 0);
3592 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3598 /* Branches (before delay slot) */
3599 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3601 int rs
, int rt
, int32_t offset
)
3603 target_ulong btgt
= -1;
3605 int bcond_compute
= 0;
3606 TCGv t0
= tcg_temp_new();
3607 TCGv t1
= tcg_temp_new();
3609 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3610 #ifdef MIPS_DEBUG_DISAS
3611 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3613 generate_exception(ctx
, EXCP_RI
);
3617 /* Load needed operands */
3623 /* Compare two registers */
3625 gen_load_gpr(t0
, rs
);
3626 gen_load_gpr(t1
, rt
);
3629 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3645 /* Compare to zero */
3647 gen_load_gpr(t0
, rs
);
3650 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3653 #if defined(TARGET_MIPS64)
3655 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3657 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3660 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3667 /* Jump to immediate */
3668 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3674 /* Jump to register */
3675 if (offset
!= 0 && offset
!= 16) {
3676 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3677 others are reserved. */
3678 MIPS_INVAL("jump hint");
3679 generate_exception(ctx
, EXCP_RI
);
3682 gen_load_gpr(btarget
, rs
);
3685 MIPS_INVAL("branch/jump");
3686 generate_exception(ctx
, EXCP_RI
);
3689 if (bcond_compute
== 0) {
3690 /* No condition to be computed */
3692 case OPC_BEQ
: /* rx == rx */
3693 case OPC_BEQL
: /* rx == rx likely */
3694 case OPC_BGEZ
: /* 0 >= 0 */
3695 case OPC_BGEZL
: /* 0 >= 0 likely */
3696 case OPC_BLEZ
: /* 0 <= 0 */
3697 case OPC_BLEZL
: /* 0 <= 0 likely */
3699 ctx
->hflags
|= MIPS_HFLAG_B
;
3700 MIPS_DEBUG("balways");
3703 case OPC_BGEZAL
: /* 0 >= 0 */
3704 case OPC_BGEZALL
: /* 0 >= 0 likely */
3705 ctx
->hflags
|= (opc
== OPC_BGEZALS
3707 : MIPS_HFLAG_BDS32
);
3708 /* Always take and link */
3710 ctx
->hflags
|= MIPS_HFLAG_B
;
3711 MIPS_DEBUG("balways and link");
3713 case OPC_BNE
: /* rx != rx */
3714 case OPC_BGTZ
: /* 0 > 0 */
3715 case OPC_BLTZ
: /* 0 < 0 */
3717 MIPS_DEBUG("bnever (NOP)");
3720 case OPC_BLTZAL
: /* 0 < 0 */
3721 ctx
->hflags
|= (opc
== OPC_BLTZALS
3723 : MIPS_HFLAG_BDS32
);
3724 /* Handle as an unconditional branch to get correct delay
3727 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3728 ctx
->hflags
|= MIPS_HFLAG_B
;
3729 MIPS_DEBUG("bnever and link");
3731 case OPC_BLTZALL
: /* 0 < 0 likely */
3732 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3733 /* Skip the instruction in the delay slot */
3734 MIPS_DEBUG("bnever, link and skip");
3737 case OPC_BNEL
: /* rx != rx likely */
3738 case OPC_BGTZL
: /* 0 > 0 likely */
3739 case OPC_BLTZL
: /* 0 < 0 likely */
3740 /* Skip the instruction in the delay slot */
3741 MIPS_DEBUG("bnever and skip");
3745 ctx
->hflags
|= MIPS_HFLAG_B
;
3746 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3750 ctx
->hflags
|= MIPS_HFLAG_BX
;
3755 ctx
->hflags
|= MIPS_HFLAG_B
;
3756 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3758 : MIPS_HFLAG_BDS32
);
3759 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3762 ctx
->hflags
|= MIPS_HFLAG_BR
;
3763 if (insn_bytes
== 4)
3764 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3765 MIPS_DEBUG("jr %s", regnames
[rs
]);
3771 ctx
->hflags
|= MIPS_HFLAG_BR
;
3772 ctx
->hflags
|= (opc
== OPC_JALRS
3774 : MIPS_HFLAG_BDS32
);
3775 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3778 MIPS_INVAL("branch/jump");
3779 generate_exception(ctx
, EXCP_RI
);
3785 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3786 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3787 regnames
[rs
], regnames
[rt
], btgt
);
3790 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3791 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3792 regnames
[rs
], regnames
[rt
], btgt
);
3795 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3796 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3797 regnames
[rs
], regnames
[rt
], btgt
);
3800 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3801 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3802 regnames
[rs
], regnames
[rt
], btgt
);
3805 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3806 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3809 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3810 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3814 ctx
->hflags
|= (opc
== OPC_BGEZALS
3816 : MIPS_HFLAG_BDS32
);
3817 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3818 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3822 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3824 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3827 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3828 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3831 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3832 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3835 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3836 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3839 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3840 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3843 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3844 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3847 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3848 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3851 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3852 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3854 #if defined(TARGET_MIPS64)
3856 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3857 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3862 ctx
->hflags
|= (opc
== OPC_BLTZALS
3864 : MIPS_HFLAG_BDS32
);
3865 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3867 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3869 ctx
->hflags
|= MIPS_HFLAG_BC
;
3872 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3874 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3876 ctx
->hflags
|= MIPS_HFLAG_BL
;
3879 MIPS_INVAL("conditional branch/jump");
3880 generate_exception(ctx
, EXCP_RI
);
3884 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3885 blink
, ctx
->hflags
, btgt
);
3887 ctx
->btarget
= btgt
;
3889 int post_delay
= insn_bytes
;
3890 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3892 if (opc
!= OPC_JALRC
)
3893 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3895 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3899 if (insn_bytes
== 2)
3900 ctx
->hflags
|= MIPS_HFLAG_B16
;
3905 /* special3 bitfield operations */
3906 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3907 int rs
, int lsb
, int msb
)
3909 TCGv t0
= tcg_temp_new();
3910 TCGv t1
= tcg_temp_new();
3912 gen_load_gpr(t1
, rs
);
3917 tcg_gen_shri_tl(t0
, t1
, lsb
);
3919 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3921 tcg_gen_ext32s_tl(t0
, t0
);
3924 #if defined(TARGET_MIPS64)
3926 tcg_gen_shri_tl(t0
, t1
, lsb
);
3928 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3932 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3933 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3936 tcg_gen_shri_tl(t0
, t1
, lsb
);
3937 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3943 gen_load_gpr(t0
, rt
);
3944 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3945 tcg_gen_ext32s_tl(t0
, t0
);
3947 #if defined(TARGET_MIPS64)
3949 gen_load_gpr(t0
, rt
);
3950 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3953 gen_load_gpr(t0
, rt
);
3954 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3957 gen_load_gpr(t0
, rt
);
3958 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3963 MIPS_INVAL("bitops");
3964 generate_exception(ctx
, EXCP_RI
);
3969 gen_store_gpr(t0
, rt
);
3974 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
3979 /* If no destination, treat it as a NOP. */
3984 t0
= tcg_temp_new();
3985 gen_load_gpr(t0
, rt
);
3989 TCGv t1
= tcg_temp_new();
3991 tcg_gen_shri_tl(t1
, t0
, 8);
3992 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
3993 tcg_gen_shli_tl(t0
, t0
, 8);
3994 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
3995 tcg_gen_or_tl(t0
, t0
, t1
);
3997 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4001 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4004 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4006 #if defined(TARGET_MIPS64)
4009 TCGv t1
= tcg_temp_new();
4011 tcg_gen_shri_tl(t1
, t0
, 8);
4012 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4013 tcg_gen_shli_tl(t0
, t0
, 8);
4014 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4015 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4021 TCGv t1
= tcg_temp_new();
4023 tcg_gen_shri_tl(t1
, t0
, 16);
4024 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4025 tcg_gen_shli_tl(t0
, t0
, 16);
4026 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4027 tcg_gen_or_tl(t0
, t0
, t1
);
4028 tcg_gen_shri_tl(t1
, t0
, 32);
4029 tcg_gen_shli_tl(t0
, t0
, 32);
4030 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4036 MIPS_INVAL("bsfhl");
4037 generate_exception(ctx
, EXCP_RI
);
4044 #ifndef CONFIG_USER_ONLY
4045 /* CP0 (MMU and control) */
4046 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4048 TCGv_i32 t0
= tcg_temp_new_i32();
4050 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4051 tcg_gen_ext_i32_tl(arg
, t0
);
4052 tcg_temp_free_i32(t0
);
4055 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4057 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4058 tcg_gen_ext32s_tl(arg
, arg
);
4061 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4063 TCGv_i32 t0
= tcg_temp_new_i32();
4065 tcg_gen_trunc_tl_i32(t0
, arg
);
4066 tcg_gen_st_i32(t0
, cpu_env
, off
);
4067 tcg_temp_free_i32(t0
);
4070 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4072 tcg_gen_ext32s_tl(arg
, arg
);
4073 tcg_gen_st_tl(arg
, cpu_env
, off
);
4076 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4078 const char *rn
= "invalid";
4081 check_insn(ctx
, ISA_MIPS32
);
4087 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4091 check_insn(ctx
, ASE_MT
);
4092 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4096 check_insn(ctx
, ASE_MT
);
4097 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4101 check_insn(ctx
, ASE_MT
);
4102 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4112 gen_helper_mfc0_random(arg
, cpu_env
);
4116 check_insn(ctx
, ASE_MT
);
4117 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4121 check_insn(ctx
, ASE_MT
);
4122 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4126 check_insn(ctx
, ASE_MT
);
4127 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4131 check_insn(ctx
, ASE_MT
);
4132 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4136 check_insn(ctx
, ASE_MT
);
4137 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4141 check_insn(ctx
, ASE_MT
);
4142 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4143 rn
= "VPEScheFBack";
4146 check_insn(ctx
, ASE_MT
);
4147 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4157 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4158 tcg_gen_ext32s_tl(arg
, arg
);
4162 check_insn(ctx
, ASE_MT
);
4163 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4167 check_insn(ctx
, ASE_MT
);
4168 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4172 check_insn(ctx
, ASE_MT
);
4173 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4177 check_insn(ctx
, ASE_MT
);
4178 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4182 check_insn(ctx
, ASE_MT
);
4183 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4187 check_insn(ctx
, ASE_MT
);
4188 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4192 check_insn(ctx
, ASE_MT
);
4193 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4203 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4204 tcg_gen_ext32s_tl(arg
, arg
);
4214 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4215 tcg_gen_ext32s_tl(arg
, arg
);
4219 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4220 rn
= "ContextConfig";
4225 tcg_gen_ld32s_tl(arg
, cpu_env
,
4226 offsetof(CPUMIPSState
,
4227 active_tc
.CP0_UserLocal
));
4230 tcg_gen_movi_tl(arg
, 0);
4240 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4244 check_insn(ctx
, ISA_MIPS32R2
);
4245 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4255 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4259 check_insn(ctx
, ISA_MIPS32R2
);
4260 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4264 check_insn(ctx
, ISA_MIPS32R2
);
4265 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4269 check_insn(ctx
, ISA_MIPS32R2
);
4270 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4274 check_insn(ctx
, ISA_MIPS32R2
);
4275 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4279 check_insn(ctx
, ISA_MIPS32R2
);
4280 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4290 check_insn(ctx
, ISA_MIPS32R2
);
4291 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4301 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4302 tcg_gen_ext32s_tl(arg
, arg
);
4312 /* Mark as an IO operation because we read the time. */
4315 gen_helper_mfc0_count(arg
, cpu_env
);
4319 /* Break the TB to be able to take timer interrupts immediately
4320 after reading count. */
4321 ctx
->bstate
= BS_STOP
;
4324 /* 6,7 are implementation dependent */
4332 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4333 tcg_gen_ext32s_tl(arg
, arg
);
4343 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4346 /* 6,7 are implementation dependent */
4354 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4358 check_insn(ctx
, ISA_MIPS32R2
);
4359 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4363 check_insn(ctx
, ISA_MIPS32R2
);
4364 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4368 check_insn(ctx
, ISA_MIPS32R2
);
4369 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4379 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4389 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4390 tcg_gen_ext32s_tl(arg
, arg
);
4400 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4404 check_insn(ctx
, ISA_MIPS32R2
);
4405 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4415 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4419 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4423 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4427 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4431 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
4435 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
4438 /* 6,7 are implementation dependent */
4440 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4444 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4454 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4464 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4474 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4484 #if defined(TARGET_MIPS64)
4485 check_insn(ctx
, ISA_MIPS3
);
4486 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4487 tcg_gen_ext32s_tl(arg
, arg
);
4496 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4499 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4507 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4508 rn
= "'Diagnostic"; /* implementation dependent */
4513 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4517 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4518 rn
= "TraceControl";
4521 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4522 rn
= "TraceControl2";
4525 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4526 rn
= "UserTraceData";
4529 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4540 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4541 tcg_gen_ext32s_tl(arg
, arg
);
4551 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4552 rn
= "Performance0";
4555 // gen_helper_mfc0_performance1(arg);
4556 rn
= "Performance1";
4559 // gen_helper_mfc0_performance2(arg);
4560 rn
= "Performance2";
4563 // gen_helper_mfc0_performance3(arg);
4564 rn
= "Performance3";
4567 // gen_helper_mfc0_performance4(arg);
4568 rn
= "Performance4";
4571 // gen_helper_mfc0_performance5(arg);
4572 rn
= "Performance5";
4575 // gen_helper_mfc0_performance6(arg);
4576 rn
= "Performance6";
4579 // gen_helper_mfc0_performance7(arg);
4580 rn
= "Performance7";
4587 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4593 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4606 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4613 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4626 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4633 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4643 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4644 tcg_gen_ext32s_tl(arg
, arg
);
4655 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4665 (void)rn
; /* avoid a compiler warning */
4666 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4670 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4671 generate_exception(ctx
, EXCP_RI
);
4674 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4676 const char *rn
= "invalid";
4679 check_insn(ctx
, ISA_MIPS32
);
4688 gen_helper_mtc0_index(cpu_env
, arg
);
4692 check_insn(ctx
, ASE_MT
);
4693 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4697 check_insn(ctx
, ASE_MT
);
4702 check_insn(ctx
, ASE_MT
);
4717 check_insn(ctx
, ASE_MT
);
4718 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4722 check_insn(ctx
, ASE_MT
);
4723 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4727 check_insn(ctx
, ASE_MT
);
4728 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4732 check_insn(ctx
, ASE_MT
);
4733 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4737 check_insn(ctx
, ASE_MT
);
4738 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4742 check_insn(ctx
, ASE_MT
);
4743 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4744 rn
= "VPEScheFBack";
4747 check_insn(ctx
, ASE_MT
);
4748 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4758 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4762 check_insn(ctx
, ASE_MT
);
4763 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4767 check_insn(ctx
, ASE_MT
);
4768 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4772 check_insn(ctx
, ASE_MT
);
4773 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4777 check_insn(ctx
, ASE_MT
);
4778 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4782 check_insn(ctx
, ASE_MT
);
4783 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4787 check_insn(ctx
, ASE_MT
);
4788 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4792 check_insn(ctx
, ASE_MT
);
4793 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4803 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4813 gen_helper_mtc0_context(cpu_env
, arg
);
4817 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4818 rn
= "ContextConfig";
4823 tcg_gen_st_tl(arg
, cpu_env
,
4824 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
4835 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4839 check_insn(ctx
, ISA_MIPS32R2
);
4840 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4850 gen_helper_mtc0_wired(cpu_env
, arg
);
4854 check_insn(ctx
, ISA_MIPS32R2
);
4855 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4859 check_insn(ctx
, ISA_MIPS32R2
);
4860 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4864 check_insn(ctx
, ISA_MIPS32R2
);
4865 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4869 check_insn(ctx
, ISA_MIPS32R2
);
4870 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4874 check_insn(ctx
, ISA_MIPS32R2
);
4875 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4885 check_insn(ctx
, ISA_MIPS32R2
);
4886 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4887 ctx
->bstate
= BS_STOP
;
4901 gen_helper_mtc0_count(cpu_env
, arg
);
4904 /* 6,7 are implementation dependent */
4912 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4922 gen_helper_mtc0_compare(cpu_env
, arg
);
4925 /* 6,7 are implementation dependent */
4933 save_cpu_state(ctx
, 1);
4934 gen_helper_mtc0_status(cpu_env
, arg
);
4935 /* BS_STOP isn't good enough here, hflags may have changed. */
4936 gen_save_pc(ctx
->pc
+ 4);
4937 ctx
->bstate
= BS_EXCP
;
4941 check_insn(ctx
, ISA_MIPS32R2
);
4942 gen_helper_mtc0_intctl(cpu_env
, arg
);
4943 /* Stop translation as we may have switched the execution mode */
4944 ctx
->bstate
= BS_STOP
;
4948 check_insn(ctx
, ISA_MIPS32R2
);
4949 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4950 /* Stop translation as we may have switched the execution mode */
4951 ctx
->bstate
= BS_STOP
;
4955 check_insn(ctx
, ISA_MIPS32R2
);
4956 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4957 /* Stop translation as we may have switched the execution mode */
4958 ctx
->bstate
= BS_STOP
;
4968 save_cpu_state(ctx
, 1);
4969 gen_helper_mtc0_cause(cpu_env
, arg
);
4979 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4993 check_insn(ctx
, ISA_MIPS32R2
);
4994 gen_helper_mtc0_ebase(cpu_env
, arg
);
5004 gen_helper_mtc0_config0(cpu_env
, arg
);
5006 /* Stop translation as we may have switched the execution mode */
5007 ctx
->bstate
= BS_STOP
;
5010 /* ignored, read only */
5014 gen_helper_mtc0_config2(cpu_env
, arg
);
5016 /* Stop translation as we may have switched the execution mode */
5017 ctx
->bstate
= BS_STOP
;
5020 /* ignored, read only */
5024 gen_helper_mtc0_config4(cpu_env
, arg
);
5026 ctx
->bstate
= BS_STOP
;
5029 gen_helper_mtc0_config5(cpu_env
, arg
);
5031 /* Stop translation as we may have switched the execution mode */
5032 ctx
->bstate
= BS_STOP
;
5034 /* 6,7 are implementation dependent */
5044 rn
= "Invalid config selector";
5051 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5061 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5071 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5081 #if defined(TARGET_MIPS64)
5082 check_insn(ctx
, ISA_MIPS3
);
5083 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5092 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5095 gen_helper_mtc0_framemask(cpu_env
, arg
);
5104 rn
= "Diagnostic"; /* implementation dependent */
5109 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5110 /* BS_STOP isn't good enough here, hflags may have changed. */
5111 gen_save_pc(ctx
->pc
+ 4);
5112 ctx
->bstate
= BS_EXCP
;
5116 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5117 rn
= "TraceControl";
5118 /* Stop translation as we may have switched the execution mode */
5119 ctx
->bstate
= BS_STOP
;
5122 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5123 rn
= "TraceControl2";
5124 /* Stop translation as we may have switched the execution mode */
5125 ctx
->bstate
= BS_STOP
;
5128 /* Stop translation as we may have switched the execution mode */
5129 ctx
->bstate
= BS_STOP
;
5130 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5131 rn
= "UserTraceData";
5132 /* Stop translation as we may have switched the execution mode */
5133 ctx
->bstate
= BS_STOP
;
5136 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5137 /* Stop translation as we may have switched the execution mode */
5138 ctx
->bstate
= BS_STOP
;
5149 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5159 gen_helper_mtc0_performance0(cpu_env
, arg
);
5160 rn
= "Performance0";
5163 // gen_helper_mtc0_performance1(arg);
5164 rn
= "Performance1";
5167 // gen_helper_mtc0_performance2(arg);
5168 rn
= "Performance2";
5171 // gen_helper_mtc0_performance3(arg);
5172 rn
= "Performance3";
5175 // gen_helper_mtc0_performance4(arg);
5176 rn
= "Performance4";
5179 // gen_helper_mtc0_performance5(arg);
5180 rn
= "Performance5";
5183 // gen_helper_mtc0_performance6(arg);
5184 rn
= "Performance6";
5187 // gen_helper_mtc0_performance7(arg);
5188 rn
= "Performance7";
5214 gen_helper_mtc0_taglo(cpu_env
, arg
);
5221 gen_helper_mtc0_datalo(cpu_env
, arg
);
5234 gen_helper_mtc0_taghi(cpu_env
, arg
);
5241 gen_helper_mtc0_datahi(cpu_env
, arg
);
5252 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5263 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5269 /* Stop translation as we may have switched the execution mode */
5270 ctx
->bstate
= BS_STOP
;
5275 (void)rn
; /* avoid a compiler warning */
5276 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5277 /* For simplicity assume that all writes can cause interrupts. */
5280 ctx
->bstate
= BS_STOP
;
5285 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5286 generate_exception(ctx
, EXCP_RI
);
5289 #if defined(TARGET_MIPS64)
5290 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5292 const char *rn
= "invalid";
5295 check_insn(ctx
, ISA_MIPS64
);
5301 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5305 check_insn(ctx
, ASE_MT
);
5306 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5310 check_insn(ctx
, ASE_MT
);
5311 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5315 check_insn(ctx
, ASE_MT
);
5316 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5326 gen_helper_mfc0_random(arg
, cpu_env
);
5330 check_insn(ctx
, ASE_MT
);
5331 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5335 check_insn(ctx
, ASE_MT
);
5336 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5340 check_insn(ctx
, ASE_MT
);
5341 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5345 check_insn(ctx
, ASE_MT
);
5346 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5350 check_insn(ctx
, ASE_MT
);
5351 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5355 check_insn(ctx
, ASE_MT
);
5356 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5357 rn
= "VPEScheFBack";
5360 check_insn(ctx
, ASE_MT
);
5361 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5371 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5375 check_insn(ctx
, ASE_MT
);
5376 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5380 check_insn(ctx
, ASE_MT
);
5381 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5385 check_insn(ctx
, ASE_MT
);
5386 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5390 check_insn(ctx
, ASE_MT
);
5391 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5395 check_insn(ctx
, ASE_MT
);
5396 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5400 check_insn(ctx
, ASE_MT
);
5401 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5405 check_insn(ctx
, ASE_MT
);
5406 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5416 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5426 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5430 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5431 rn
= "ContextConfig";
5436 tcg_gen_ld_tl(arg
, cpu_env
,
5437 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5440 tcg_gen_movi_tl(arg
, 0);
5450 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5454 check_insn(ctx
, ISA_MIPS32R2
);
5455 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5465 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5469 check_insn(ctx
, ISA_MIPS32R2
);
5470 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5474 check_insn(ctx
, ISA_MIPS32R2
);
5475 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5479 check_insn(ctx
, ISA_MIPS32R2
);
5480 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5484 check_insn(ctx
, ISA_MIPS32R2
);
5485 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5489 check_insn(ctx
, ISA_MIPS32R2
);
5490 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5500 check_insn(ctx
, ISA_MIPS32R2
);
5501 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5511 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5521 /* Mark as an IO operation because we read the time. */
5524 gen_helper_mfc0_count(arg
, cpu_env
);
5528 /* Break the TB to be able to take timer interrupts immediately
5529 after reading count. */
5530 ctx
->bstate
= BS_STOP
;
5533 /* 6,7 are implementation dependent */
5541 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5551 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5554 /* 6,7 are implementation dependent */
5562 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5566 check_insn(ctx
, ISA_MIPS32R2
);
5567 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5571 check_insn(ctx
, ISA_MIPS32R2
);
5572 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5576 check_insn(ctx
, ISA_MIPS32R2
);
5577 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5587 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5597 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5607 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5611 check_insn(ctx
, ISA_MIPS32R2
);
5612 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5622 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5626 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5630 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5634 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5637 /* 6,7 are implementation dependent */
5639 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5643 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5653 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5663 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5673 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5683 check_insn(ctx
, ISA_MIPS3
);
5684 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5692 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5695 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5703 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5704 rn
= "'Diagnostic"; /* implementation dependent */
5709 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5713 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5714 rn
= "TraceControl";
5717 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5718 rn
= "TraceControl2";
5721 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5722 rn
= "UserTraceData";
5725 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5736 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5746 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5747 rn
= "Performance0";
5750 // gen_helper_dmfc0_performance1(arg);
5751 rn
= "Performance1";
5754 // gen_helper_dmfc0_performance2(arg);
5755 rn
= "Performance2";
5758 // gen_helper_dmfc0_performance3(arg);
5759 rn
= "Performance3";
5762 // gen_helper_dmfc0_performance4(arg);
5763 rn
= "Performance4";
5766 // gen_helper_dmfc0_performance5(arg);
5767 rn
= "Performance5";
5770 // gen_helper_dmfc0_performance6(arg);
5771 rn
= "Performance6";
5774 // gen_helper_dmfc0_performance7(arg);
5775 rn
= "Performance7";
5782 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5789 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5802 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5809 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5822 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5829 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5839 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5850 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5860 (void)rn
; /* avoid a compiler warning */
5861 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5865 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5866 generate_exception(ctx
, EXCP_RI
);
5869 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5871 const char *rn
= "invalid";
5874 check_insn(ctx
, ISA_MIPS64
);
5883 gen_helper_mtc0_index(cpu_env
, arg
);
5887 check_insn(ctx
, ASE_MT
);
5888 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5892 check_insn(ctx
, ASE_MT
);
5897 check_insn(ctx
, ASE_MT
);
5912 check_insn(ctx
, ASE_MT
);
5913 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5917 check_insn(ctx
, ASE_MT
);
5918 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5922 check_insn(ctx
, ASE_MT
);
5923 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5927 check_insn(ctx
, ASE_MT
);
5928 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5932 check_insn(ctx
, ASE_MT
);
5933 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5937 check_insn(ctx
, ASE_MT
);
5938 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5939 rn
= "VPEScheFBack";
5942 check_insn(ctx
, ASE_MT
);
5943 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5953 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5957 check_insn(ctx
, ASE_MT
);
5958 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5962 check_insn(ctx
, ASE_MT
);
5963 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5967 check_insn(ctx
, ASE_MT
);
5968 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5972 check_insn(ctx
, ASE_MT
);
5973 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5977 check_insn(ctx
, ASE_MT
);
5978 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5982 check_insn(ctx
, ASE_MT
);
5983 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5987 check_insn(ctx
, ASE_MT
);
5988 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
5998 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
6008 gen_helper_mtc0_context(cpu_env
, arg
);
6012 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6013 rn
= "ContextConfig";
6018 tcg_gen_st_tl(arg
, cpu_env
,
6019 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6030 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6034 check_insn(ctx
, ISA_MIPS32R2
);
6035 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6045 gen_helper_mtc0_wired(cpu_env
, arg
);
6049 check_insn(ctx
, ISA_MIPS32R2
);
6050 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6054 check_insn(ctx
, ISA_MIPS32R2
);
6055 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6059 check_insn(ctx
, ISA_MIPS32R2
);
6060 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6064 check_insn(ctx
, ISA_MIPS32R2
);
6065 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6069 check_insn(ctx
, ISA_MIPS32R2
);
6070 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6080 check_insn(ctx
, ISA_MIPS32R2
);
6081 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6082 ctx
->bstate
= BS_STOP
;
6096 gen_helper_mtc0_count(cpu_env
, arg
);
6099 /* 6,7 are implementation dependent */
6103 /* Stop translation as we may have switched the execution mode */
6104 ctx
->bstate
= BS_STOP
;
6109 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6119 gen_helper_mtc0_compare(cpu_env
, arg
);
6122 /* 6,7 are implementation dependent */
6126 /* Stop translation as we may have switched the execution mode */
6127 ctx
->bstate
= BS_STOP
;
6132 save_cpu_state(ctx
, 1);
6133 gen_helper_mtc0_status(cpu_env
, arg
);
6134 /* BS_STOP isn't good enough here, hflags may have changed. */
6135 gen_save_pc(ctx
->pc
+ 4);
6136 ctx
->bstate
= BS_EXCP
;
6140 check_insn(ctx
, ISA_MIPS32R2
);
6141 gen_helper_mtc0_intctl(cpu_env
, arg
);
6142 /* Stop translation as we may have switched the execution mode */
6143 ctx
->bstate
= BS_STOP
;
6147 check_insn(ctx
, ISA_MIPS32R2
);
6148 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6149 /* Stop translation as we may have switched the execution mode */
6150 ctx
->bstate
= BS_STOP
;
6154 check_insn(ctx
, ISA_MIPS32R2
);
6155 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6156 /* Stop translation as we may have switched the execution mode */
6157 ctx
->bstate
= BS_STOP
;
6167 save_cpu_state(ctx
, 1);
6168 /* Mark as an IO operation because we may trigger a software
6173 gen_helper_mtc0_cause(cpu_env
, arg
);
6177 /* Stop translation as we may have triggered an intetrupt */
6178 ctx
->bstate
= BS_STOP
;
6188 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6202 check_insn(ctx
, ISA_MIPS32R2
);
6203 gen_helper_mtc0_ebase(cpu_env
, arg
);
6213 gen_helper_mtc0_config0(cpu_env
, arg
);
6215 /* Stop translation as we may have switched the execution mode */
6216 ctx
->bstate
= BS_STOP
;
6219 /* ignored, read only */
6223 gen_helper_mtc0_config2(cpu_env
, arg
);
6225 /* Stop translation as we may have switched the execution mode */
6226 ctx
->bstate
= BS_STOP
;
6232 /* 6,7 are implementation dependent */
6234 rn
= "Invalid config selector";
6241 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6251 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6261 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6271 check_insn(ctx
, ISA_MIPS3
);
6272 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6280 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6283 gen_helper_mtc0_framemask(cpu_env
, arg
);
6292 rn
= "Diagnostic"; /* implementation dependent */
6297 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6298 /* BS_STOP isn't good enough here, hflags may have changed. */
6299 gen_save_pc(ctx
->pc
+ 4);
6300 ctx
->bstate
= BS_EXCP
;
6304 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6305 /* Stop translation as we may have switched the execution mode */
6306 ctx
->bstate
= BS_STOP
;
6307 rn
= "TraceControl";
6310 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6311 /* Stop translation as we may have switched the execution mode */
6312 ctx
->bstate
= BS_STOP
;
6313 rn
= "TraceControl2";
6316 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6317 /* Stop translation as we may have switched the execution mode */
6318 ctx
->bstate
= BS_STOP
;
6319 rn
= "UserTraceData";
6322 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6323 /* Stop translation as we may have switched the execution mode */
6324 ctx
->bstate
= BS_STOP
;
6335 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6345 gen_helper_mtc0_performance0(cpu_env
, arg
);
6346 rn
= "Performance0";
6349 // gen_helper_mtc0_performance1(cpu_env, arg);
6350 rn
= "Performance1";
6353 // gen_helper_mtc0_performance2(cpu_env, arg);
6354 rn
= "Performance2";
6357 // gen_helper_mtc0_performance3(cpu_env, arg);
6358 rn
= "Performance3";
6361 // gen_helper_mtc0_performance4(cpu_env, arg);
6362 rn
= "Performance4";
6365 // gen_helper_mtc0_performance5(cpu_env, arg);
6366 rn
= "Performance5";
6369 // gen_helper_mtc0_performance6(cpu_env, arg);
6370 rn
= "Performance6";
6373 // gen_helper_mtc0_performance7(cpu_env, arg);
6374 rn
= "Performance7";
6400 gen_helper_mtc0_taglo(cpu_env
, arg
);
6407 gen_helper_mtc0_datalo(cpu_env
, arg
);
6420 gen_helper_mtc0_taghi(cpu_env
, arg
);
6427 gen_helper_mtc0_datahi(cpu_env
, arg
);
6438 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6449 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6455 /* Stop translation as we may have switched the execution mode */
6456 ctx
->bstate
= BS_STOP
;
6461 (void)rn
; /* avoid a compiler warning */
6462 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6463 /* For simplicity assume that all writes can cause interrupts. */
6466 ctx
->bstate
= BS_STOP
;
6471 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6472 generate_exception(ctx
, EXCP_RI
);
6474 #endif /* TARGET_MIPS64 */
6476 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6477 int u
, int sel
, int h
)
6479 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6480 TCGv t0
= tcg_temp_local_new();
6482 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6483 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6484 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6485 tcg_gen_movi_tl(t0
, -1);
6486 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6487 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6488 tcg_gen_movi_tl(t0
, -1);
6494 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6497 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6507 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6510 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6513 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6516 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6519 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6522 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6525 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6528 gen_mfc0(ctx
, t0
, rt
, sel
);
6535 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6538 gen_mfc0(ctx
, t0
, rt
, sel
);
6544 gen_helper_mftc0_status(t0
, cpu_env
);
6547 gen_mfc0(ctx
, t0
, rt
, sel
);
6553 gen_helper_mftc0_cause(t0
, cpu_env
);
6563 gen_helper_mftc0_epc(t0
, cpu_env
);
6573 gen_helper_mftc0_ebase(t0
, cpu_env
);
6583 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6593 gen_helper_mftc0_debug(t0
, cpu_env
);
6596 gen_mfc0(ctx
, t0
, rt
, sel
);
6601 gen_mfc0(ctx
, t0
, rt
, sel
);
6603 } else switch (sel
) {
6604 /* GPR registers. */
6606 gen_helper_1e0i(mftgpr
, t0
, rt
);
6608 /* Auxiliary CPU registers */
6612 gen_helper_1e0i(mftlo
, t0
, 0);
6615 gen_helper_1e0i(mfthi
, t0
, 0);
6618 gen_helper_1e0i(mftacx
, t0
, 0);
6621 gen_helper_1e0i(mftlo
, t0
, 1);
6624 gen_helper_1e0i(mfthi
, t0
, 1);
6627 gen_helper_1e0i(mftacx
, t0
, 1);
6630 gen_helper_1e0i(mftlo
, t0
, 2);
6633 gen_helper_1e0i(mfthi
, t0
, 2);
6636 gen_helper_1e0i(mftacx
, t0
, 2);
6639 gen_helper_1e0i(mftlo
, t0
, 3);
6642 gen_helper_1e0i(mfthi
, t0
, 3);
6645 gen_helper_1e0i(mftacx
, t0
, 3);
6648 gen_helper_mftdsp(t0
, cpu_env
);
6654 /* Floating point (COP1). */
6656 /* XXX: For now we support only a single FPU context. */
6658 TCGv_i32 fp0
= tcg_temp_new_i32();
6660 gen_load_fpr32(fp0
, rt
);
6661 tcg_gen_ext_i32_tl(t0
, fp0
);
6662 tcg_temp_free_i32(fp0
);
6664 TCGv_i32 fp0
= tcg_temp_new_i32();
6666 gen_load_fpr32h(ctx
, fp0
, rt
);
6667 tcg_gen_ext_i32_tl(t0
, fp0
);
6668 tcg_temp_free_i32(fp0
);
6672 /* XXX: For now we support only a single FPU context. */
6673 gen_helper_1e0i(cfc1
, t0
, rt
);
6675 /* COP2: Not implemented. */
6682 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6683 gen_store_gpr(t0
, rd
);
6689 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6690 generate_exception(ctx
, EXCP_RI
);
6693 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6694 int u
, int sel
, int h
)
6696 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6697 TCGv t0
= tcg_temp_local_new();
6699 gen_load_gpr(t0
, rt
);
6700 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6701 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6702 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6704 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6705 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6712 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6715 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6725 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6728 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6731 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6734 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6737 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6740 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6743 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6746 gen_mtc0(ctx
, t0
, rd
, sel
);
6753 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6756 gen_mtc0(ctx
, t0
, rd
, sel
);
6762 gen_helper_mttc0_status(cpu_env
, t0
);
6765 gen_mtc0(ctx
, t0
, rd
, sel
);
6771 gen_helper_mttc0_cause(cpu_env
, t0
);
6781 gen_helper_mttc0_ebase(cpu_env
, t0
);
6791 gen_helper_mttc0_debug(cpu_env
, t0
);
6794 gen_mtc0(ctx
, t0
, rd
, sel
);
6799 gen_mtc0(ctx
, t0
, rd
, sel
);
6801 } else switch (sel
) {
6802 /* GPR registers. */
6804 gen_helper_0e1i(mttgpr
, t0
, rd
);
6806 /* Auxiliary CPU registers */
6810 gen_helper_0e1i(mttlo
, t0
, 0);
6813 gen_helper_0e1i(mtthi
, t0
, 0);
6816 gen_helper_0e1i(mttacx
, t0
, 0);
6819 gen_helper_0e1i(mttlo
, t0
, 1);
6822 gen_helper_0e1i(mtthi
, t0
, 1);
6825 gen_helper_0e1i(mttacx
, t0
, 1);
6828 gen_helper_0e1i(mttlo
, t0
, 2);
6831 gen_helper_0e1i(mtthi
, t0
, 2);
6834 gen_helper_0e1i(mttacx
, t0
, 2);
6837 gen_helper_0e1i(mttlo
, t0
, 3);
6840 gen_helper_0e1i(mtthi
, t0
, 3);
6843 gen_helper_0e1i(mttacx
, t0
, 3);
6846 gen_helper_mttdsp(cpu_env
, t0
);
6852 /* Floating point (COP1). */
6854 /* XXX: For now we support only a single FPU context. */
6856 TCGv_i32 fp0
= tcg_temp_new_i32();
6858 tcg_gen_trunc_tl_i32(fp0
, t0
);
6859 gen_store_fpr32(fp0
, rd
);
6860 tcg_temp_free_i32(fp0
);
6862 TCGv_i32 fp0
= tcg_temp_new_i32();
6864 tcg_gen_trunc_tl_i32(fp0
, t0
);
6865 gen_store_fpr32h(ctx
, fp0
, rd
);
6866 tcg_temp_free_i32(fp0
);
6870 /* XXX: For now we support only a single FPU context. */
6872 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
6874 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
6875 tcg_temp_free_i32(fs_tmp
);
6878 /* COP2: Not implemented. */
6885 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6891 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6892 generate_exception(ctx
, EXCP_RI
);
6895 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6897 const char *opn
= "ldst";
6899 check_cp0_enabled(ctx
);
6906 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6911 TCGv t0
= tcg_temp_new();
6913 gen_load_gpr(t0
, rt
);
6914 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6919 #if defined(TARGET_MIPS64)
6921 check_insn(ctx
, ISA_MIPS3
);
6926 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6930 check_insn(ctx
, ISA_MIPS3
);
6932 TCGv t0
= tcg_temp_new();
6934 gen_load_gpr(t0
, rt
);
6935 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6942 check_insn(ctx
, ASE_MT
);
6947 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6948 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6952 check_insn(ctx
, ASE_MT
);
6953 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6954 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6959 if (!env
->tlb
->helper_tlbwi
)
6961 gen_helper_tlbwi(cpu_env
);
6965 if (!env
->tlb
->helper_tlbwr
)
6967 gen_helper_tlbwr(cpu_env
);
6971 if (!env
->tlb
->helper_tlbp
)
6973 gen_helper_tlbp(cpu_env
);
6977 if (!env
->tlb
->helper_tlbr
)
6979 gen_helper_tlbr(cpu_env
);
6983 check_insn(ctx
, ISA_MIPS2
);
6984 gen_helper_eret(cpu_env
);
6985 ctx
->bstate
= BS_EXCP
;
6989 check_insn(ctx
, ISA_MIPS32
);
6990 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6992 generate_exception(ctx
, EXCP_RI
);
6994 gen_helper_deret(cpu_env
);
6995 ctx
->bstate
= BS_EXCP
;
7000 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
7001 /* If we get an exception, we want to restart at next instruction */
7003 save_cpu_state(ctx
, 1);
7005 gen_helper_wait(cpu_env
);
7006 ctx
->bstate
= BS_EXCP
;
7011 generate_exception(ctx
, EXCP_RI
);
7014 (void)opn
; /* avoid a compiler warning */
7015 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
7017 #endif /* !CONFIG_USER_ONLY */
7019 /* CP1 Branches (before delay slot) */
7020 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
7021 int32_t cc
, int32_t offset
)
7023 target_ulong btarget
;
7024 const char *opn
= "cp1 cond branch";
7025 TCGv_i32 t0
= tcg_temp_new_i32();
7028 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
7030 btarget
= ctx
->pc
+ 4 + offset
;
7034 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7035 tcg_gen_not_i32(t0
, t0
);
7036 tcg_gen_andi_i32(t0
, t0
, 1);
7037 tcg_gen_extu_i32_tl(bcond
, t0
);
7041 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7042 tcg_gen_not_i32(t0
, t0
);
7043 tcg_gen_andi_i32(t0
, t0
, 1);
7044 tcg_gen_extu_i32_tl(bcond
, t0
);
7048 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7049 tcg_gen_andi_i32(t0
, t0
, 1);
7050 tcg_gen_extu_i32_tl(bcond
, t0
);
7054 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7055 tcg_gen_andi_i32(t0
, t0
, 1);
7056 tcg_gen_extu_i32_tl(bcond
, t0
);
7059 ctx
->hflags
|= MIPS_HFLAG_BL
;
7063 TCGv_i32 t1
= tcg_temp_new_i32();
7064 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7065 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7066 tcg_gen_nand_i32(t0
, t0
, t1
);
7067 tcg_temp_free_i32(t1
);
7068 tcg_gen_andi_i32(t0
, t0
, 1);
7069 tcg_gen_extu_i32_tl(bcond
, t0
);
7075 TCGv_i32 t1
= tcg_temp_new_i32();
7076 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7077 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7078 tcg_gen_or_i32(t0
, t0
, t1
);
7079 tcg_temp_free_i32(t1
);
7080 tcg_gen_andi_i32(t0
, t0
, 1);
7081 tcg_gen_extu_i32_tl(bcond
, t0
);
7087 TCGv_i32 t1
= tcg_temp_new_i32();
7088 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7089 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7090 tcg_gen_and_i32(t0
, t0
, t1
);
7091 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7092 tcg_gen_and_i32(t0
, t0
, t1
);
7093 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7094 tcg_gen_nand_i32(t0
, t0
, t1
);
7095 tcg_temp_free_i32(t1
);
7096 tcg_gen_andi_i32(t0
, t0
, 1);
7097 tcg_gen_extu_i32_tl(bcond
, t0
);
7103 TCGv_i32 t1
= tcg_temp_new_i32();
7104 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7105 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7106 tcg_gen_or_i32(t0
, t0
, t1
);
7107 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7108 tcg_gen_or_i32(t0
, t0
, t1
);
7109 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7110 tcg_gen_or_i32(t0
, t0
, t1
);
7111 tcg_temp_free_i32(t1
);
7112 tcg_gen_andi_i32(t0
, t0
, 1);
7113 tcg_gen_extu_i32_tl(bcond
, t0
);
7117 ctx
->hflags
|= MIPS_HFLAG_BC
;
7121 generate_exception (ctx
, EXCP_RI
);
7124 (void)opn
; /* avoid a compiler warning */
7125 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7126 ctx
->hflags
, btarget
);
7127 ctx
->btarget
= btarget
;
7130 tcg_temp_free_i32(t0
);
7133 /* Coprocessor 1 (FPU) */
7135 #define FOP(func, fmt) (((fmt) << 21) | (func))
7138 OPC_ADD_S
= FOP(0, FMT_S
),
7139 OPC_SUB_S
= FOP(1, FMT_S
),
7140 OPC_MUL_S
= FOP(2, FMT_S
),
7141 OPC_DIV_S
= FOP(3, FMT_S
),
7142 OPC_SQRT_S
= FOP(4, FMT_S
),
7143 OPC_ABS_S
= FOP(5, FMT_S
),
7144 OPC_MOV_S
= FOP(6, FMT_S
),
7145 OPC_NEG_S
= FOP(7, FMT_S
),
7146 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7147 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7148 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7149 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7150 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7151 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7152 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7153 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7154 OPC_MOVCF_S
= FOP(17, FMT_S
),
7155 OPC_MOVZ_S
= FOP(18, FMT_S
),
7156 OPC_MOVN_S
= FOP(19, FMT_S
),
7157 OPC_RECIP_S
= FOP(21, FMT_S
),
7158 OPC_RSQRT_S
= FOP(22, FMT_S
),
7159 OPC_RECIP2_S
= FOP(28, FMT_S
),
7160 OPC_RECIP1_S
= FOP(29, FMT_S
),
7161 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7162 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7163 OPC_CVT_D_S
= FOP(33, FMT_S
),
7164 OPC_CVT_W_S
= FOP(36, FMT_S
),
7165 OPC_CVT_L_S
= FOP(37, FMT_S
),
7166 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7167 OPC_CMP_F_S
= FOP (48, FMT_S
),
7168 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7169 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7170 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7171 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7172 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7173 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7174 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7175 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7176 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7177 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7178 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7179 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7180 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7181 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7182 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7184 OPC_ADD_D
= FOP(0, FMT_D
),
7185 OPC_SUB_D
= FOP(1, FMT_D
),
7186 OPC_MUL_D
= FOP(2, FMT_D
),
7187 OPC_DIV_D
= FOP(3, FMT_D
),
7188 OPC_SQRT_D
= FOP(4, FMT_D
),
7189 OPC_ABS_D
= FOP(5, FMT_D
),
7190 OPC_MOV_D
= FOP(6, FMT_D
),
7191 OPC_NEG_D
= FOP(7, FMT_D
),
7192 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7193 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7194 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7195 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7196 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7197 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7198 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7199 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7200 OPC_MOVCF_D
= FOP(17, FMT_D
),
7201 OPC_MOVZ_D
= FOP(18, FMT_D
),
7202 OPC_MOVN_D
= FOP(19, FMT_D
),
7203 OPC_RECIP_D
= FOP(21, FMT_D
),
7204 OPC_RSQRT_D
= FOP(22, FMT_D
),
7205 OPC_RECIP2_D
= FOP(28, FMT_D
),
7206 OPC_RECIP1_D
= FOP(29, FMT_D
),
7207 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7208 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7209 OPC_CVT_S_D
= FOP(32, FMT_D
),
7210 OPC_CVT_W_D
= FOP(36, FMT_D
),
7211 OPC_CVT_L_D
= FOP(37, FMT_D
),
7212 OPC_CMP_F_D
= FOP (48, FMT_D
),
7213 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7214 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7215 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7216 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7217 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7218 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7219 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7220 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7221 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7222 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7223 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7224 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7225 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7226 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7227 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7229 OPC_CVT_S_W
= FOP(32, FMT_W
),
7230 OPC_CVT_D_W
= FOP(33, FMT_W
),
7231 OPC_CVT_S_L
= FOP(32, FMT_L
),
7232 OPC_CVT_D_L
= FOP(33, FMT_L
),
7233 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7235 OPC_ADD_PS
= FOP(0, FMT_PS
),
7236 OPC_SUB_PS
= FOP(1, FMT_PS
),
7237 OPC_MUL_PS
= FOP(2, FMT_PS
),
7238 OPC_DIV_PS
= FOP(3, FMT_PS
),
7239 OPC_ABS_PS
= FOP(5, FMT_PS
),
7240 OPC_MOV_PS
= FOP(6, FMT_PS
),
7241 OPC_NEG_PS
= FOP(7, FMT_PS
),
7242 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7243 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7244 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7245 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7246 OPC_MULR_PS
= FOP(26, FMT_PS
),
7247 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7248 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7249 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7250 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7252 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7253 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7254 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7255 OPC_PLL_PS
= FOP(44, FMT_PS
),
7256 OPC_PLU_PS
= FOP(45, FMT_PS
),
7257 OPC_PUL_PS
= FOP(46, FMT_PS
),
7258 OPC_PUU_PS
= FOP(47, FMT_PS
),
7259 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7260 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7261 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7262 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7263 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7264 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7265 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7266 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7267 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7268 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7269 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7270 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7271 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7272 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7273 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7274 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7277 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7279 const char *opn
= "cp1 move";
7280 TCGv t0
= tcg_temp_new();
7285 TCGv_i32 fp0
= tcg_temp_new_i32();
7287 gen_load_fpr32(fp0
, fs
);
7288 tcg_gen_ext_i32_tl(t0
, fp0
);
7289 tcg_temp_free_i32(fp0
);
7291 gen_store_gpr(t0
, rt
);
7295 gen_load_gpr(t0
, rt
);
7297 TCGv_i32 fp0
= tcg_temp_new_i32();
7299 tcg_gen_trunc_tl_i32(fp0
, t0
);
7300 gen_store_fpr32(fp0
, fs
);
7301 tcg_temp_free_i32(fp0
);
7306 gen_helper_1e0i(cfc1
, t0
, fs
);
7307 gen_store_gpr(t0
, rt
);
7311 gen_load_gpr(t0
, rt
);
7313 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
7315 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7316 tcg_temp_free_i32(fs_tmp
);
7320 #if defined(TARGET_MIPS64)
7322 gen_load_fpr64(ctx
, t0
, fs
);
7323 gen_store_gpr(t0
, rt
);
7327 gen_load_gpr(t0
, rt
);
7328 gen_store_fpr64(ctx
, t0
, fs
);
7334 TCGv_i32 fp0
= tcg_temp_new_i32();
7336 gen_load_fpr32h(ctx
, fp0
, fs
);
7337 tcg_gen_ext_i32_tl(t0
, fp0
);
7338 tcg_temp_free_i32(fp0
);
7340 gen_store_gpr(t0
, rt
);
7344 gen_load_gpr(t0
, rt
);
7346 TCGv_i32 fp0
= tcg_temp_new_i32();
7348 tcg_gen_trunc_tl_i32(fp0
, t0
);
7349 gen_store_fpr32h(ctx
, fp0
, fs
);
7350 tcg_temp_free_i32(fp0
);
7356 generate_exception (ctx
, EXCP_RI
);
7359 (void)opn
; /* avoid a compiler warning */
7360 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7366 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7382 l1
= gen_new_label();
7383 t0
= tcg_temp_new_i32();
7384 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7385 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7386 tcg_temp_free_i32(t0
);
7388 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7390 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7395 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7398 TCGv_i32 t0
= tcg_temp_new_i32();
7399 int l1
= gen_new_label();
7406 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7407 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7408 gen_load_fpr32(t0
, fs
);
7409 gen_store_fpr32(t0
, fd
);
7411 tcg_temp_free_i32(t0
);
7414 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7417 TCGv_i32 t0
= tcg_temp_new_i32();
7419 int l1
= gen_new_label();
7426 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7427 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7428 tcg_temp_free_i32(t0
);
7429 fp0
= tcg_temp_new_i64();
7430 gen_load_fpr64(ctx
, fp0
, fs
);
7431 gen_store_fpr64(ctx
, fp0
, fd
);
7432 tcg_temp_free_i64(fp0
);
7436 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
7440 TCGv_i32 t0
= tcg_temp_new_i32();
7441 int l1
= gen_new_label();
7442 int l2
= gen_new_label();
7449 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7450 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7451 gen_load_fpr32(t0
, fs
);
7452 gen_store_fpr32(t0
, fd
);
7455 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7456 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7457 gen_load_fpr32h(ctx
, t0
, fs
);
7458 gen_store_fpr32h(ctx
, t0
, fd
);
7459 tcg_temp_free_i32(t0
);
7464 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7465 int ft
, int fs
, int fd
, int cc
)
7467 const char *opn
= "farith";
7468 const char *condnames
[] = {
7486 const char *condnames_abs
[] = {
7504 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7505 uint32_t func
= ctx
->opcode
& 0x3f;
7510 TCGv_i32 fp0
= tcg_temp_new_i32();
7511 TCGv_i32 fp1
= tcg_temp_new_i32();
7513 gen_load_fpr32(fp0
, fs
);
7514 gen_load_fpr32(fp1
, ft
);
7515 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7516 tcg_temp_free_i32(fp1
);
7517 gen_store_fpr32(fp0
, fd
);
7518 tcg_temp_free_i32(fp0
);
7525 TCGv_i32 fp0
= tcg_temp_new_i32();
7526 TCGv_i32 fp1
= tcg_temp_new_i32();
7528 gen_load_fpr32(fp0
, fs
);
7529 gen_load_fpr32(fp1
, ft
);
7530 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7531 tcg_temp_free_i32(fp1
);
7532 gen_store_fpr32(fp0
, fd
);
7533 tcg_temp_free_i32(fp0
);
7540 TCGv_i32 fp0
= tcg_temp_new_i32();
7541 TCGv_i32 fp1
= tcg_temp_new_i32();
7543 gen_load_fpr32(fp0
, fs
);
7544 gen_load_fpr32(fp1
, ft
);
7545 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7546 tcg_temp_free_i32(fp1
);
7547 gen_store_fpr32(fp0
, fd
);
7548 tcg_temp_free_i32(fp0
);
7555 TCGv_i32 fp0
= tcg_temp_new_i32();
7556 TCGv_i32 fp1
= tcg_temp_new_i32();
7558 gen_load_fpr32(fp0
, fs
);
7559 gen_load_fpr32(fp1
, ft
);
7560 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7561 tcg_temp_free_i32(fp1
);
7562 gen_store_fpr32(fp0
, fd
);
7563 tcg_temp_free_i32(fp0
);
7570 TCGv_i32 fp0
= tcg_temp_new_i32();
7572 gen_load_fpr32(fp0
, fs
);
7573 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7574 gen_store_fpr32(fp0
, fd
);
7575 tcg_temp_free_i32(fp0
);
7581 TCGv_i32 fp0
= tcg_temp_new_i32();
7583 gen_load_fpr32(fp0
, fs
);
7584 gen_helper_float_abs_s(fp0
, fp0
);
7585 gen_store_fpr32(fp0
, fd
);
7586 tcg_temp_free_i32(fp0
);
7592 TCGv_i32 fp0
= tcg_temp_new_i32();
7594 gen_load_fpr32(fp0
, fs
);
7595 gen_store_fpr32(fp0
, fd
);
7596 tcg_temp_free_i32(fp0
);
7602 TCGv_i32 fp0
= tcg_temp_new_i32();
7604 gen_load_fpr32(fp0
, fs
);
7605 gen_helper_float_chs_s(fp0
, fp0
);
7606 gen_store_fpr32(fp0
, fd
);
7607 tcg_temp_free_i32(fp0
);
7612 check_cp1_64bitmode(ctx
);
7614 TCGv_i32 fp32
= tcg_temp_new_i32();
7615 TCGv_i64 fp64
= tcg_temp_new_i64();
7617 gen_load_fpr32(fp32
, fs
);
7618 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7619 tcg_temp_free_i32(fp32
);
7620 gen_store_fpr64(ctx
, fp64
, fd
);
7621 tcg_temp_free_i64(fp64
);
7626 check_cp1_64bitmode(ctx
);
7628 TCGv_i32 fp32
= tcg_temp_new_i32();
7629 TCGv_i64 fp64
= tcg_temp_new_i64();
7631 gen_load_fpr32(fp32
, fs
);
7632 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7633 tcg_temp_free_i32(fp32
);
7634 gen_store_fpr64(ctx
, fp64
, fd
);
7635 tcg_temp_free_i64(fp64
);
7640 check_cp1_64bitmode(ctx
);
7642 TCGv_i32 fp32
= tcg_temp_new_i32();
7643 TCGv_i64 fp64
= tcg_temp_new_i64();
7645 gen_load_fpr32(fp32
, fs
);
7646 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7647 tcg_temp_free_i32(fp32
);
7648 gen_store_fpr64(ctx
, fp64
, fd
);
7649 tcg_temp_free_i64(fp64
);
7654 check_cp1_64bitmode(ctx
);
7656 TCGv_i32 fp32
= tcg_temp_new_i32();
7657 TCGv_i64 fp64
= tcg_temp_new_i64();
7659 gen_load_fpr32(fp32
, fs
);
7660 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7661 tcg_temp_free_i32(fp32
);
7662 gen_store_fpr64(ctx
, fp64
, fd
);
7663 tcg_temp_free_i64(fp64
);
7669 TCGv_i32 fp0
= tcg_temp_new_i32();
7671 gen_load_fpr32(fp0
, fs
);
7672 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7673 gen_store_fpr32(fp0
, fd
);
7674 tcg_temp_free_i32(fp0
);
7680 TCGv_i32 fp0
= tcg_temp_new_i32();
7682 gen_load_fpr32(fp0
, fs
);
7683 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7684 gen_store_fpr32(fp0
, fd
);
7685 tcg_temp_free_i32(fp0
);
7691 TCGv_i32 fp0
= tcg_temp_new_i32();
7693 gen_load_fpr32(fp0
, fs
);
7694 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7695 gen_store_fpr32(fp0
, fd
);
7696 tcg_temp_free_i32(fp0
);
7702 TCGv_i32 fp0
= tcg_temp_new_i32();
7704 gen_load_fpr32(fp0
, fs
);
7705 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7706 gen_store_fpr32(fp0
, fd
);
7707 tcg_temp_free_i32(fp0
);
7712 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7717 int l1
= gen_new_label();
7721 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7723 fp0
= tcg_temp_new_i32();
7724 gen_load_fpr32(fp0
, fs
);
7725 gen_store_fpr32(fp0
, fd
);
7726 tcg_temp_free_i32(fp0
);
7733 int l1
= gen_new_label();
7737 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7738 fp0
= tcg_temp_new_i32();
7739 gen_load_fpr32(fp0
, fs
);
7740 gen_store_fpr32(fp0
, fd
);
7741 tcg_temp_free_i32(fp0
);
7750 TCGv_i32 fp0
= tcg_temp_new_i32();
7752 gen_load_fpr32(fp0
, fs
);
7753 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7754 gen_store_fpr32(fp0
, fd
);
7755 tcg_temp_free_i32(fp0
);
7762 TCGv_i32 fp0
= tcg_temp_new_i32();
7764 gen_load_fpr32(fp0
, fs
);
7765 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7766 gen_store_fpr32(fp0
, fd
);
7767 tcg_temp_free_i32(fp0
);
7772 check_cp1_64bitmode(ctx
);
7774 TCGv_i32 fp0
= tcg_temp_new_i32();
7775 TCGv_i32 fp1
= tcg_temp_new_i32();
7777 gen_load_fpr32(fp0
, fs
);
7778 gen_load_fpr32(fp1
, ft
);
7779 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7780 tcg_temp_free_i32(fp1
);
7781 gen_store_fpr32(fp0
, fd
);
7782 tcg_temp_free_i32(fp0
);
7787 check_cp1_64bitmode(ctx
);
7789 TCGv_i32 fp0
= tcg_temp_new_i32();
7791 gen_load_fpr32(fp0
, fs
);
7792 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7793 gen_store_fpr32(fp0
, fd
);
7794 tcg_temp_free_i32(fp0
);
7799 check_cp1_64bitmode(ctx
);
7801 TCGv_i32 fp0
= tcg_temp_new_i32();
7803 gen_load_fpr32(fp0
, fs
);
7804 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7805 gen_store_fpr32(fp0
, fd
);
7806 tcg_temp_free_i32(fp0
);
7811 check_cp1_64bitmode(ctx
);
7813 TCGv_i32 fp0
= tcg_temp_new_i32();
7814 TCGv_i32 fp1
= tcg_temp_new_i32();
7816 gen_load_fpr32(fp0
, fs
);
7817 gen_load_fpr32(fp1
, ft
);
7818 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7819 tcg_temp_free_i32(fp1
);
7820 gen_store_fpr32(fp0
, fd
);
7821 tcg_temp_free_i32(fp0
);
7826 check_cp1_registers(ctx
, fd
);
7828 TCGv_i32 fp32
= tcg_temp_new_i32();
7829 TCGv_i64 fp64
= tcg_temp_new_i64();
7831 gen_load_fpr32(fp32
, fs
);
7832 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7833 tcg_temp_free_i32(fp32
);
7834 gen_store_fpr64(ctx
, fp64
, fd
);
7835 tcg_temp_free_i64(fp64
);
7841 TCGv_i32 fp0
= tcg_temp_new_i32();
7843 gen_load_fpr32(fp0
, fs
);
7844 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7845 gen_store_fpr32(fp0
, fd
);
7846 tcg_temp_free_i32(fp0
);
7851 check_cp1_64bitmode(ctx
);
7853 TCGv_i32 fp32
= tcg_temp_new_i32();
7854 TCGv_i64 fp64
= tcg_temp_new_i64();
7856 gen_load_fpr32(fp32
, fs
);
7857 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7858 tcg_temp_free_i32(fp32
);
7859 gen_store_fpr64(ctx
, fp64
, fd
);
7860 tcg_temp_free_i64(fp64
);
7865 check_cp1_64bitmode(ctx
);
7867 TCGv_i64 fp64
= tcg_temp_new_i64();
7868 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7869 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7871 gen_load_fpr32(fp32_0
, fs
);
7872 gen_load_fpr32(fp32_1
, ft
);
7873 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7874 tcg_temp_free_i32(fp32_1
);
7875 tcg_temp_free_i32(fp32_0
);
7876 gen_store_fpr64(ctx
, fp64
, fd
);
7877 tcg_temp_free_i64(fp64
);
7890 case OPC_CMP_NGLE_S
:
7897 if (ctx
->opcode
& (1 << 6)) {
7898 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7899 opn
= condnames_abs
[func
-48];
7901 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7902 opn
= condnames
[func
-48];
7906 check_cp1_registers(ctx
, fs
| ft
| fd
);
7908 TCGv_i64 fp0
= tcg_temp_new_i64();
7909 TCGv_i64 fp1
= tcg_temp_new_i64();
7911 gen_load_fpr64(ctx
, fp0
, fs
);
7912 gen_load_fpr64(ctx
, fp1
, ft
);
7913 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7914 tcg_temp_free_i64(fp1
);
7915 gen_store_fpr64(ctx
, fp0
, fd
);
7916 tcg_temp_free_i64(fp0
);
7922 check_cp1_registers(ctx
, fs
| ft
| fd
);
7924 TCGv_i64 fp0
= tcg_temp_new_i64();
7925 TCGv_i64 fp1
= tcg_temp_new_i64();
7927 gen_load_fpr64(ctx
, fp0
, fs
);
7928 gen_load_fpr64(ctx
, fp1
, ft
);
7929 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7930 tcg_temp_free_i64(fp1
);
7931 gen_store_fpr64(ctx
, fp0
, fd
);
7932 tcg_temp_free_i64(fp0
);
7938 check_cp1_registers(ctx
, fs
| ft
| fd
);
7940 TCGv_i64 fp0
= tcg_temp_new_i64();
7941 TCGv_i64 fp1
= tcg_temp_new_i64();
7943 gen_load_fpr64(ctx
, fp0
, fs
);
7944 gen_load_fpr64(ctx
, fp1
, ft
);
7945 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7946 tcg_temp_free_i64(fp1
);
7947 gen_store_fpr64(ctx
, fp0
, fd
);
7948 tcg_temp_free_i64(fp0
);
7954 check_cp1_registers(ctx
, fs
| ft
| fd
);
7956 TCGv_i64 fp0
= tcg_temp_new_i64();
7957 TCGv_i64 fp1
= tcg_temp_new_i64();
7959 gen_load_fpr64(ctx
, fp0
, fs
);
7960 gen_load_fpr64(ctx
, fp1
, ft
);
7961 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7962 tcg_temp_free_i64(fp1
);
7963 gen_store_fpr64(ctx
, fp0
, fd
);
7964 tcg_temp_free_i64(fp0
);
7970 check_cp1_registers(ctx
, fs
| fd
);
7972 TCGv_i64 fp0
= tcg_temp_new_i64();
7974 gen_load_fpr64(ctx
, fp0
, fs
);
7975 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7976 gen_store_fpr64(ctx
, fp0
, fd
);
7977 tcg_temp_free_i64(fp0
);
7982 check_cp1_registers(ctx
, fs
| fd
);
7984 TCGv_i64 fp0
= tcg_temp_new_i64();
7986 gen_load_fpr64(ctx
, fp0
, fs
);
7987 gen_helper_float_abs_d(fp0
, fp0
);
7988 gen_store_fpr64(ctx
, fp0
, fd
);
7989 tcg_temp_free_i64(fp0
);
7994 check_cp1_registers(ctx
, fs
| fd
);
7996 TCGv_i64 fp0
= tcg_temp_new_i64();
7998 gen_load_fpr64(ctx
, fp0
, fs
);
7999 gen_store_fpr64(ctx
, fp0
, fd
);
8000 tcg_temp_free_i64(fp0
);
8005 check_cp1_registers(ctx
, fs
| fd
);
8007 TCGv_i64 fp0
= tcg_temp_new_i64();
8009 gen_load_fpr64(ctx
, fp0
, fs
);
8010 gen_helper_float_chs_d(fp0
, fp0
);
8011 gen_store_fpr64(ctx
, fp0
, fd
);
8012 tcg_temp_free_i64(fp0
);
8017 check_cp1_64bitmode(ctx
);
8019 TCGv_i64 fp0
= tcg_temp_new_i64();
8021 gen_load_fpr64(ctx
, fp0
, fs
);
8022 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
8023 gen_store_fpr64(ctx
, fp0
, fd
);
8024 tcg_temp_free_i64(fp0
);
8029 check_cp1_64bitmode(ctx
);
8031 TCGv_i64 fp0
= tcg_temp_new_i64();
8033 gen_load_fpr64(ctx
, fp0
, fs
);
8034 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
8035 gen_store_fpr64(ctx
, fp0
, fd
);
8036 tcg_temp_free_i64(fp0
);
8041 check_cp1_64bitmode(ctx
);
8043 TCGv_i64 fp0
= tcg_temp_new_i64();
8045 gen_load_fpr64(ctx
, fp0
, fs
);
8046 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
8047 gen_store_fpr64(ctx
, fp0
, fd
);
8048 tcg_temp_free_i64(fp0
);
8053 check_cp1_64bitmode(ctx
);
8055 TCGv_i64 fp0
= tcg_temp_new_i64();
8057 gen_load_fpr64(ctx
, fp0
, fs
);
8058 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8059 gen_store_fpr64(ctx
, fp0
, fd
);
8060 tcg_temp_free_i64(fp0
);
8065 check_cp1_registers(ctx
, fs
);
8067 TCGv_i32 fp32
= tcg_temp_new_i32();
8068 TCGv_i64 fp64
= tcg_temp_new_i64();
8070 gen_load_fpr64(ctx
, fp64
, fs
);
8071 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8072 tcg_temp_free_i64(fp64
);
8073 gen_store_fpr32(fp32
, fd
);
8074 tcg_temp_free_i32(fp32
);
8079 check_cp1_registers(ctx
, fs
);
8081 TCGv_i32 fp32
= tcg_temp_new_i32();
8082 TCGv_i64 fp64
= tcg_temp_new_i64();
8084 gen_load_fpr64(ctx
, fp64
, fs
);
8085 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8086 tcg_temp_free_i64(fp64
);
8087 gen_store_fpr32(fp32
, fd
);
8088 tcg_temp_free_i32(fp32
);
8093 check_cp1_registers(ctx
, fs
);
8095 TCGv_i32 fp32
= tcg_temp_new_i32();
8096 TCGv_i64 fp64
= tcg_temp_new_i64();
8098 gen_load_fpr64(ctx
, fp64
, fs
);
8099 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8100 tcg_temp_free_i64(fp64
);
8101 gen_store_fpr32(fp32
, fd
);
8102 tcg_temp_free_i32(fp32
);
8107 check_cp1_registers(ctx
, fs
);
8109 TCGv_i32 fp32
= tcg_temp_new_i32();
8110 TCGv_i64 fp64
= tcg_temp_new_i64();
8112 gen_load_fpr64(ctx
, fp64
, fs
);
8113 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8114 tcg_temp_free_i64(fp64
);
8115 gen_store_fpr32(fp32
, fd
);
8116 tcg_temp_free_i32(fp32
);
8121 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8126 int l1
= gen_new_label();
8130 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8132 fp0
= tcg_temp_new_i64();
8133 gen_load_fpr64(ctx
, fp0
, fs
);
8134 gen_store_fpr64(ctx
, fp0
, fd
);
8135 tcg_temp_free_i64(fp0
);
8142 int l1
= gen_new_label();
8146 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8147 fp0
= tcg_temp_new_i64();
8148 gen_load_fpr64(ctx
, fp0
, fs
);
8149 gen_store_fpr64(ctx
, fp0
, fd
);
8150 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_recip_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();
8173 gen_load_fpr64(ctx
, fp0
, fs
);
8174 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8175 gen_store_fpr64(ctx
, fp0
, fd
);
8176 tcg_temp_free_i64(fp0
);
8181 check_cp1_64bitmode(ctx
);
8183 TCGv_i64 fp0
= tcg_temp_new_i64();
8184 TCGv_i64 fp1
= tcg_temp_new_i64();
8186 gen_load_fpr64(ctx
, fp0
, fs
);
8187 gen_load_fpr64(ctx
, fp1
, ft
);
8188 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8189 tcg_temp_free_i64(fp1
);
8190 gen_store_fpr64(ctx
, fp0
, fd
);
8191 tcg_temp_free_i64(fp0
);
8196 check_cp1_64bitmode(ctx
);
8198 TCGv_i64 fp0
= tcg_temp_new_i64();
8200 gen_load_fpr64(ctx
, fp0
, fs
);
8201 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8202 gen_store_fpr64(ctx
, fp0
, fd
);
8203 tcg_temp_free_i64(fp0
);
8208 check_cp1_64bitmode(ctx
);
8210 TCGv_i64 fp0
= tcg_temp_new_i64();
8212 gen_load_fpr64(ctx
, fp0
, fs
);
8213 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8214 gen_store_fpr64(ctx
, fp0
, fd
);
8215 tcg_temp_free_i64(fp0
);
8220 check_cp1_64bitmode(ctx
);
8222 TCGv_i64 fp0
= tcg_temp_new_i64();
8223 TCGv_i64 fp1
= tcg_temp_new_i64();
8225 gen_load_fpr64(ctx
, fp0
, fs
);
8226 gen_load_fpr64(ctx
, fp1
, ft
);
8227 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8228 tcg_temp_free_i64(fp1
);
8229 gen_store_fpr64(ctx
, fp0
, fd
);
8230 tcg_temp_free_i64(fp0
);
8243 case OPC_CMP_NGLE_D
:
8250 if (ctx
->opcode
& (1 << 6)) {
8251 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8252 opn
= condnames_abs
[func
-48];
8254 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8255 opn
= condnames
[func
-48];
8259 check_cp1_registers(ctx
, fs
);
8261 TCGv_i32 fp32
= tcg_temp_new_i32();
8262 TCGv_i64 fp64
= tcg_temp_new_i64();
8264 gen_load_fpr64(ctx
, fp64
, fs
);
8265 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8266 tcg_temp_free_i64(fp64
);
8267 gen_store_fpr32(fp32
, fd
);
8268 tcg_temp_free_i32(fp32
);
8273 check_cp1_registers(ctx
, fs
);
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_cvtw_d(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_cvtl_d(fp0
, cpu_env
, fp0
);
8293 gen_store_fpr64(ctx
, fp0
, fd
);
8294 tcg_temp_free_i64(fp0
);
8300 TCGv_i32 fp0
= tcg_temp_new_i32();
8302 gen_load_fpr32(fp0
, fs
);
8303 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8304 gen_store_fpr32(fp0
, fd
);
8305 tcg_temp_free_i32(fp0
);
8310 check_cp1_registers(ctx
, fd
);
8312 TCGv_i32 fp32
= tcg_temp_new_i32();
8313 TCGv_i64 fp64
= tcg_temp_new_i64();
8315 gen_load_fpr32(fp32
, fs
);
8316 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8317 tcg_temp_free_i32(fp32
);
8318 gen_store_fpr64(ctx
, fp64
, fd
);
8319 tcg_temp_free_i64(fp64
);
8324 check_cp1_64bitmode(ctx
);
8326 TCGv_i32 fp32
= tcg_temp_new_i32();
8327 TCGv_i64 fp64
= tcg_temp_new_i64();
8329 gen_load_fpr64(ctx
, fp64
, fs
);
8330 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8331 tcg_temp_free_i64(fp64
);
8332 gen_store_fpr32(fp32
, fd
);
8333 tcg_temp_free_i32(fp32
);
8338 check_cp1_64bitmode(ctx
);
8340 TCGv_i64 fp0
= tcg_temp_new_i64();
8342 gen_load_fpr64(ctx
, fp0
, fs
);
8343 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8344 gen_store_fpr64(ctx
, fp0
, fd
);
8345 tcg_temp_free_i64(fp0
);
8350 check_cp1_64bitmode(ctx
);
8352 TCGv_i64 fp0
= tcg_temp_new_i64();
8354 gen_load_fpr64(ctx
, fp0
, fs
);
8355 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8356 gen_store_fpr64(ctx
, fp0
, fd
);
8357 tcg_temp_free_i64(fp0
);
8362 check_cp1_64bitmode(ctx
);
8364 TCGv_i64 fp0
= tcg_temp_new_i64();
8365 TCGv_i64 fp1
= tcg_temp_new_i64();
8367 gen_load_fpr64(ctx
, fp0
, fs
);
8368 gen_load_fpr64(ctx
, fp1
, ft
);
8369 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8370 tcg_temp_free_i64(fp1
);
8371 gen_store_fpr64(ctx
, fp0
, fd
);
8372 tcg_temp_free_i64(fp0
);
8377 check_cp1_64bitmode(ctx
);
8379 TCGv_i64 fp0
= tcg_temp_new_i64();
8380 TCGv_i64 fp1
= tcg_temp_new_i64();
8382 gen_load_fpr64(ctx
, fp0
, fs
);
8383 gen_load_fpr64(ctx
, fp1
, ft
);
8384 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8385 tcg_temp_free_i64(fp1
);
8386 gen_store_fpr64(ctx
, fp0
, fd
);
8387 tcg_temp_free_i64(fp0
);
8392 check_cp1_64bitmode(ctx
);
8394 TCGv_i64 fp0
= tcg_temp_new_i64();
8395 TCGv_i64 fp1
= tcg_temp_new_i64();
8397 gen_load_fpr64(ctx
, fp0
, fs
);
8398 gen_load_fpr64(ctx
, fp1
, ft
);
8399 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8400 tcg_temp_free_i64(fp1
);
8401 gen_store_fpr64(ctx
, fp0
, fd
);
8402 tcg_temp_free_i64(fp0
);
8407 check_cp1_64bitmode(ctx
);
8409 TCGv_i64 fp0
= tcg_temp_new_i64();
8411 gen_load_fpr64(ctx
, fp0
, fs
);
8412 gen_helper_float_abs_ps(fp0
, fp0
);
8413 gen_store_fpr64(ctx
, fp0
, fd
);
8414 tcg_temp_free_i64(fp0
);
8419 check_cp1_64bitmode(ctx
);
8421 TCGv_i64 fp0
= tcg_temp_new_i64();
8423 gen_load_fpr64(ctx
, fp0
, fs
);
8424 gen_store_fpr64(ctx
, fp0
, fd
);
8425 tcg_temp_free_i64(fp0
);
8430 check_cp1_64bitmode(ctx
);
8432 TCGv_i64 fp0
= tcg_temp_new_i64();
8434 gen_load_fpr64(ctx
, fp0
, fs
);
8435 gen_helper_float_chs_ps(fp0
, fp0
);
8436 gen_store_fpr64(ctx
, fp0
, fd
);
8437 tcg_temp_free_i64(fp0
);
8442 check_cp1_64bitmode(ctx
);
8443 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8447 check_cp1_64bitmode(ctx
);
8449 int l1
= gen_new_label();
8453 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8454 fp0
= tcg_temp_new_i64();
8455 gen_load_fpr64(ctx
, fp0
, fs
);
8456 gen_store_fpr64(ctx
, fp0
, fd
);
8457 tcg_temp_free_i64(fp0
);
8463 check_cp1_64bitmode(ctx
);
8465 int l1
= gen_new_label();
8469 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8470 fp0
= tcg_temp_new_i64();
8471 gen_load_fpr64(ctx
, fp0
, fs
);
8472 gen_store_fpr64(ctx
, fp0
, fd
);
8473 tcg_temp_free_i64(fp0
);
8480 check_cp1_64bitmode(ctx
);
8482 TCGv_i64 fp0
= tcg_temp_new_i64();
8483 TCGv_i64 fp1
= tcg_temp_new_i64();
8485 gen_load_fpr64(ctx
, fp0
, ft
);
8486 gen_load_fpr64(ctx
, fp1
, fs
);
8487 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8488 tcg_temp_free_i64(fp1
);
8489 gen_store_fpr64(ctx
, fp0
, fd
);
8490 tcg_temp_free_i64(fp0
);
8495 check_cp1_64bitmode(ctx
);
8497 TCGv_i64 fp0
= tcg_temp_new_i64();
8498 TCGv_i64 fp1
= tcg_temp_new_i64();
8500 gen_load_fpr64(ctx
, fp0
, ft
);
8501 gen_load_fpr64(ctx
, fp1
, fs
);
8502 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8503 tcg_temp_free_i64(fp1
);
8504 gen_store_fpr64(ctx
, fp0
, fd
);
8505 tcg_temp_free_i64(fp0
);
8510 check_cp1_64bitmode(ctx
);
8512 TCGv_i64 fp0
= tcg_temp_new_i64();
8513 TCGv_i64 fp1
= tcg_temp_new_i64();
8515 gen_load_fpr64(ctx
, fp0
, fs
);
8516 gen_load_fpr64(ctx
, fp1
, ft
);
8517 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8518 tcg_temp_free_i64(fp1
);
8519 gen_store_fpr64(ctx
, fp0
, fd
);
8520 tcg_temp_free_i64(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_recip1_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_i64 fp0
= tcg_temp_new_i64();
8541 gen_load_fpr64(ctx
, fp0
, fs
);
8542 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8543 gen_store_fpr64(ctx
, fp0
, fd
);
8544 tcg_temp_free_i64(fp0
);
8549 check_cp1_64bitmode(ctx
);
8551 TCGv_i64 fp0
= tcg_temp_new_i64();
8552 TCGv_i64 fp1
= tcg_temp_new_i64();
8554 gen_load_fpr64(ctx
, fp0
, fs
);
8555 gen_load_fpr64(ctx
, fp1
, ft
);
8556 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8557 tcg_temp_free_i64(fp1
);
8558 gen_store_fpr64(ctx
, fp0
, fd
);
8559 tcg_temp_free_i64(fp0
);
8564 check_cp1_64bitmode(ctx
);
8566 TCGv_i32 fp0
= tcg_temp_new_i32();
8568 gen_load_fpr32h(ctx
, fp0
, fs
);
8569 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8570 gen_store_fpr32(fp0
, fd
);
8571 tcg_temp_free_i32(fp0
);
8576 check_cp1_64bitmode(ctx
);
8578 TCGv_i64 fp0
= tcg_temp_new_i64();
8580 gen_load_fpr64(ctx
, fp0
, fs
);
8581 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8582 gen_store_fpr64(ctx
, fp0
, fd
);
8583 tcg_temp_free_i64(fp0
);
8588 check_cp1_64bitmode(ctx
);
8590 TCGv_i32 fp0
= tcg_temp_new_i32();
8592 gen_load_fpr32(fp0
, fs
);
8593 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8594 gen_store_fpr32(fp0
, fd
);
8595 tcg_temp_free_i32(fp0
);
8600 check_cp1_64bitmode(ctx
);
8602 TCGv_i32 fp0
= tcg_temp_new_i32();
8603 TCGv_i32 fp1
= tcg_temp_new_i32();
8605 gen_load_fpr32(fp0
, fs
);
8606 gen_load_fpr32(fp1
, ft
);
8607 gen_store_fpr32h(ctx
, fp0
, fd
);
8608 gen_store_fpr32(fp1
, fd
);
8609 tcg_temp_free_i32(fp0
);
8610 tcg_temp_free_i32(fp1
);
8615 check_cp1_64bitmode(ctx
);
8617 TCGv_i32 fp0
= tcg_temp_new_i32();
8618 TCGv_i32 fp1
= tcg_temp_new_i32();
8620 gen_load_fpr32(fp0
, fs
);
8621 gen_load_fpr32h(ctx
, fp1
, ft
);
8622 gen_store_fpr32(fp1
, fd
);
8623 gen_store_fpr32h(ctx
, fp0
, fd
);
8624 tcg_temp_free_i32(fp0
);
8625 tcg_temp_free_i32(fp1
);
8630 check_cp1_64bitmode(ctx
);
8632 TCGv_i32 fp0
= tcg_temp_new_i32();
8633 TCGv_i32 fp1
= tcg_temp_new_i32();
8635 gen_load_fpr32h(ctx
, fp0
, fs
);
8636 gen_load_fpr32(fp1
, ft
);
8637 gen_store_fpr32(fp1
, fd
);
8638 gen_store_fpr32h(ctx
, fp0
, fd
);
8639 tcg_temp_free_i32(fp0
);
8640 tcg_temp_free_i32(fp1
);
8645 check_cp1_64bitmode(ctx
);
8647 TCGv_i32 fp0
= tcg_temp_new_i32();
8648 TCGv_i32 fp1
= tcg_temp_new_i32();
8650 gen_load_fpr32h(ctx
, fp0
, fs
);
8651 gen_load_fpr32h(ctx
, fp1
, ft
);
8652 gen_store_fpr32(fp1
, fd
);
8653 gen_store_fpr32h(ctx
, fp0
, fd
);
8654 tcg_temp_free_i32(fp0
);
8655 tcg_temp_free_i32(fp1
);
8662 case OPC_CMP_UEQ_PS
:
8663 case OPC_CMP_OLT_PS
:
8664 case OPC_CMP_ULT_PS
:
8665 case OPC_CMP_OLE_PS
:
8666 case OPC_CMP_ULE_PS
:
8668 case OPC_CMP_NGLE_PS
:
8669 case OPC_CMP_SEQ_PS
:
8670 case OPC_CMP_NGL_PS
:
8672 case OPC_CMP_NGE_PS
:
8674 case OPC_CMP_NGT_PS
:
8675 if (ctx
->opcode
& (1 << 6)) {
8676 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8677 opn
= condnames_abs
[func
-48];
8679 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8680 opn
= condnames
[func
-48];
8685 generate_exception (ctx
, EXCP_RI
);
8688 (void)opn
; /* avoid a compiler warning */
8691 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8694 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8697 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8702 /* Coprocessor 3 (FPU) */
8703 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8704 int fd
, int fs
, int base
, int index
)
8706 const char *opn
= "extended float load/store";
8708 TCGv t0
= tcg_temp_new();
8711 gen_load_gpr(t0
, index
);
8712 } else if (index
== 0) {
8713 gen_load_gpr(t0
, base
);
8715 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8717 /* Don't do NOP if destination is zero: we must perform the actual
8723 TCGv_i32 fp0
= tcg_temp_new_i32();
8725 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
8726 tcg_gen_trunc_tl_i32(fp0
, t0
);
8727 gen_store_fpr32(fp0
, fd
);
8728 tcg_temp_free_i32(fp0
);
8734 check_cp1_registers(ctx
, fd
);
8736 TCGv_i64 fp0
= tcg_temp_new_i64();
8737 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8738 gen_store_fpr64(ctx
, fp0
, fd
);
8739 tcg_temp_free_i64(fp0
);
8744 check_cp1_64bitmode(ctx
);
8745 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8747 TCGv_i64 fp0
= tcg_temp_new_i64();
8749 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8750 gen_store_fpr64(ctx
, fp0
, fd
);
8751 tcg_temp_free_i64(fp0
);
8758 TCGv_i32 fp0
= tcg_temp_new_i32();
8759 gen_load_fpr32(fp0
, fs
);
8760 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
8761 tcg_temp_free_i32(fp0
);
8768 check_cp1_registers(ctx
, fs
);
8770 TCGv_i64 fp0
= tcg_temp_new_i64();
8771 gen_load_fpr64(ctx
, fp0
, fs
);
8772 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8773 tcg_temp_free_i64(fp0
);
8779 check_cp1_64bitmode(ctx
);
8780 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8782 TCGv_i64 fp0
= tcg_temp_new_i64();
8783 gen_load_fpr64(ctx
, fp0
, fs
);
8784 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8785 tcg_temp_free_i64(fp0
);
8792 (void)opn
; (void)store
; /* avoid compiler warnings */
8793 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8794 regnames
[index
], regnames
[base
]);
8797 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8798 int fd
, int fr
, int fs
, int ft
)
8800 const char *opn
= "flt3_arith";
8804 check_cp1_64bitmode(ctx
);
8806 TCGv t0
= tcg_temp_local_new();
8807 TCGv_i32 fp
= tcg_temp_new_i32();
8808 TCGv_i32 fph
= tcg_temp_new_i32();
8809 int l1
= gen_new_label();
8810 int l2
= gen_new_label();
8812 gen_load_gpr(t0
, fr
);
8813 tcg_gen_andi_tl(t0
, t0
, 0x7);
8815 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8816 gen_load_fpr32(fp
, fs
);
8817 gen_load_fpr32h(ctx
, fph
, fs
);
8818 gen_store_fpr32(fp
, fd
);
8819 gen_store_fpr32h(ctx
, fph
, fd
);
8822 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8824 #ifdef TARGET_WORDS_BIGENDIAN
8825 gen_load_fpr32(fp
, fs
);
8826 gen_load_fpr32h(ctx
, fph
, ft
);
8827 gen_store_fpr32h(ctx
, fp
, fd
);
8828 gen_store_fpr32(fph
, fd
);
8830 gen_load_fpr32h(ctx
, fph
, fs
);
8831 gen_load_fpr32(fp
, ft
);
8832 gen_store_fpr32(fph
, fd
);
8833 gen_store_fpr32h(ctx
, fp
, fd
);
8836 tcg_temp_free_i32(fp
);
8837 tcg_temp_free_i32(fph
);
8844 TCGv_i32 fp0
= tcg_temp_new_i32();
8845 TCGv_i32 fp1
= tcg_temp_new_i32();
8846 TCGv_i32 fp2
= tcg_temp_new_i32();
8848 gen_load_fpr32(fp0
, fs
);
8849 gen_load_fpr32(fp1
, ft
);
8850 gen_load_fpr32(fp2
, fr
);
8851 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8852 tcg_temp_free_i32(fp0
);
8853 tcg_temp_free_i32(fp1
);
8854 gen_store_fpr32(fp2
, fd
);
8855 tcg_temp_free_i32(fp2
);
8861 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8863 TCGv_i64 fp0
= tcg_temp_new_i64();
8864 TCGv_i64 fp1
= tcg_temp_new_i64();
8865 TCGv_i64 fp2
= tcg_temp_new_i64();
8867 gen_load_fpr64(ctx
, fp0
, fs
);
8868 gen_load_fpr64(ctx
, fp1
, ft
);
8869 gen_load_fpr64(ctx
, fp2
, fr
);
8870 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8871 tcg_temp_free_i64(fp0
);
8872 tcg_temp_free_i64(fp1
);
8873 gen_store_fpr64(ctx
, fp2
, fd
);
8874 tcg_temp_free_i64(fp2
);
8879 check_cp1_64bitmode(ctx
);
8881 TCGv_i64 fp0
= tcg_temp_new_i64();
8882 TCGv_i64 fp1
= tcg_temp_new_i64();
8883 TCGv_i64 fp2
= tcg_temp_new_i64();
8885 gen_load_fpr64(ctx
, fp0
, fs
);
8886 gen_load_fpr64(ctx
, fp1
, ft
);
8887 gen_load_fpr64(ctx
, fp2
, fr
);
8888 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8889 tcg_temp_free_i64(fp0
);
8890 tcg_temp_free_i64(fp1
);
8891 gen_store_fpr64(ctx
, fp2
, fd
);
8892 tcg_temp_free_i64(fp2
);
8899 TCGv_i32 fp0
= tcg_temp_new_i32();
8900 TCGv_i32 fp1
= tcg_temp_new_i32();
8901 TCGv_i32 fp2
= tcg_temp_new_i32();
8903 gen_load_fpr32(fp0
, fs
);
8904 gen_load_fpr32(fp1
, ft
);
8905 gen_load_fpr32(fp2
, fr
);
8906 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8907 tcg_temp_free_i32(fp0
);
8908 tcg_temp_free_i32(fp1
);
8909 gen_store_fpr32(fp2
, fd
);
8910 tcg_temp_free_i32(fp2
);
8916 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8918 TCGv_i64 fp0
= tcg_temp_new_i64();
8919 TCGv_i64 fp1
= tcg_temp_new_i64();
8920 TCGv_i64 fp2
= tcg_temp_new_i64();
8922 gen_load_fpr64(ctx
, fp0
, fs
);
8923 gen_load_fpr64(ctx
, fp1
, ft
);
8924 gen_load_fpr64(ctx
, fp2
, fr
);
8925 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8926 tcg_temp_free_i64(fp0
);
8927 tcg_temp_free_i64(fp1
);
8928 gen_store_fpr64(ctx
, fp2
, fd
);
8929 tcg_temp_free_i64(fp2
);
8934 check_cp1_64bitmode(ctx
);
8936 TCGv_i64 fp0
= tcg_temp_new_i64();
8937 TCGv_i64 fp1
= tcg_temp_new_i64();
8938 TCGv_i64 fp2
= tcg_temp_new_i64();
8940 gen_load_fpr64(ctx
, fp0
, fs
);
8941 gen_load_fpr64(ctx
, fp1
, ft
);
8942 gen_load_fpr64(ctx
, fp2
, fr
);
8943 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8944 tcg_temp_free_i64(fp0
);
8945 tcg_temp_free_i64(fp1
);
8946 gen_store_fpr64(ctx
, fp2
, fd
);
8947 tcg_temp_free_i64(fp2
);
8954 TCGv_i32 fp0
= tcg_temp_new_i32();
8955 TCGv_i32 fp1
= tcg_temp_new_i32();
8956 TCGv_i32 fp2
= tcg_temp_new_i32();
8958 gen_load_fpr32(fp0
, fs
);
8959 gen_load_fpr32(fp1
, ft
);
8960 gen_load_fpr32(fp2
, fr
);
8961 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8962 tcg_temp_free_i32(fp0
);
8963 tcg_temp_free_i32(fp1
);
8964 gen_store_fpr32(fp2
, fd
);
8965 tcg_temp_free_i32(fp2
);
8971 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8973 TCGv_i64 fp0
= tcg_temp_new_i64();
8974 TCGv_i64 fp1
= tcg_temp_new_i64();
8975 TCGv_i64 fp2
= tcg_temp_new_i64();
8977 gen_load_fpr64(ctx
, fp0
, fs
);
8978 gen_load_fpr64(ctx
, fp1
, ft
);
8979 gen_load_fpr64(ctx
, fp2
, fr
);
8980 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8981 tcg_temp_free_i64(fp0
);
8982 tcg_temp_free_i64(fp1
);
8983 gen_store_fpr64(ctx
, fp2
, fd
);
8984 tcg_temp_free_i64(fp2
);
8989 check_cp1_64bitmode(ctx
);
8991 TCGv_i64 fp0
= tcg_temp_new_i64();
8992 TCGv_i64 fp1
= tcg_temp_new_i64();
8993 TCGv_i64 fp2
= tcg_temp_new_i64();
8995 gen_load_fpr64(ctx
, fp0
, fs
);
8996 gen_load_fpr64(ctx
, fp1
, ft
);
8997 gen_load_fpr64(ctx
, fp2
, fr
);
8998 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8999 tcg_temp_free_i64(fp0
);
9000 tcg_temp_free_i64(fp1
);
9001 gen_store_fpr64(ctx
, fp2
, fd
);
9002 tcg_temp_free_i64(fp2
);
9009 TCGv_i32 fp0
= tcg_temp_new_i32();
9010 TCGv_i32 fp1
= tcg_temp_new_i32();
9011 TCGv_i32 fp2
= tcg_temp_new_i32();
9013 gen_load_fpr32(fp0
, fs
);
9014 gen_load_fpr32(fp1
, ft
);
9015 gen_load_fpr32(fp2
, fr
);
9016 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9017 tcg_temp_free_i32(fp0
);
9018 tcg_temp_free_i32(fp1
);
9019 gen_store_fpr32(fp2
, fd
);
9020 tcg_temp_free_i32(fp2
);
9026 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9028 TCGv_i64 fp0
= tcg_temp_new_i64();
9029 TCGv_i64 fp1
= tcg_temp_new_i64();
9030 TCGv_i64 fp2
= tcg_temp_new_i64();
9032 gen_load_fpr64(ctx
, fp0
, fs
);
9033 gen_load_fpr64(ctx
, fp1
, ft
);
9034 gen_load_fpr64(ctx
, fp2
, fr
);
9035 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9036 tcg_temp_free_i64(fp0
);
9037 tcg_temp_free_i64(fp1
);
9038 gen_store_fpr64(ctx
, fp2
, fd
);
9039 tcg_temp_free_i64(fp2
);
9044 check_cp1_64bitmode(ctx
);
9046 TCGv_i64 fp0
= tcg_temp_new_i64();
9047 TCGv_i64 fp1
= tcg_temp_new_i64();
9048 TCGv_i64 fp2
= tcg_temp_new_i64();
9050 gen_load_fpr64(ctx
, fp0
, fs
);
9051 gen_load_fpr64(ctx
, fp1
, ft
);
9052 gen_load_fpr64(ctx
, fp2
, fr
);
9053 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9054 tcg_temp_free_i64(fp0
);
9055 tcg_temp_free_i64(fp1
);
9056 gen_store_fpr64(ctx
, fp2
, fd
);
9057 tcg_temp_free_i64(fp2
);
9063 generate_exception (ctx
, EXCP_RI
);
9066 (void)opn
; /* avoid a compiler warning */
9067 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9068 fregnames
[fs
], fregnames
[ft
]);
9071 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
9075 #if !defined(CONFIG_USER_ONLY)
9076 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9077 Therefore only check the ISA in system mode. */
9078 check_insn(ctx
, ISA_MIPS32R2
);
9080 t0
= tcg_temp_new();
9084 save_cpu_state(ctx
, 1);
9085 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9086 gen_store_gpr(t0
, rt
);
9089 save_cpu_state(ctx
, 1);
9090 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9091 gen_store_gpr(t0
, rt
);
9094 save_cpu_state(ctx
, 1);
9095 gen_helper_rdhwr_cc(t0
, cpu_env
);
9096 gen_store_gpr(t0
, rt
);
9099 save_cpu_state(ctx
, 1);
9100 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9101 gen_store_gpr(t0
, rt
);
9104 #if defined(CONFIG_USER_ONLY)
9105 tcg_gen_ld_tl(t0
, cpu_env
,
9106 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9107 gen_store_gpr(t0
, rt
);
9110 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
9111 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
9112 tcg_gen_ld_tl(t0
, cpu_env
,
9113 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9114 gen_store_gpr(t0
, rt
);
9116 generate_exception(ctx
, EXCP_RI
);
9120 default: /* Invalid */
9121 MIPS_INVAL("rdhwr");
9122 generate_exception(ctx
, EXCP_RI
);
9128 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9130 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9131 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9132 /* Branches completion */
9133 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9134 ctx
->bstate
= BS_BRANCH
;
9135 save_cpu_state(ctx
, 0);
9136 /* FIXME: Need to clear can_do_io. */
9137 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9139 /* unconditional branch */
9140 MIPS_DEBUG("unconditional branch");
9141 if (proc_hflags
& MIPS_HFLAG_BX
) {
9142 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9144 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9147 /* blikely taken case */
9148 MIPS_DEBUG("blikely branch taken");
9149 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9152 /* Conditional branch */
9153 MIPS_DEBUG("conditional branch");
9155 int l1
= gen_new_label();
9157 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9158 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9160 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9164 /* unconditional branch to register */
9165 MIPS_DEBUG("branch to register");
9166 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9167 TCGv t0
= tcg_temp_new();
9168 TCGv_i32 t1
= tcg_temp_new_i32();
9170 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9171 tcg_gen_trunc_tl_i32(t1
, t0
);
9173 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9174 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9175 tcg_gen_or_i32(hflags
, hflags
, t1
);
9176 tcg_temp_free_i32(t1
);
9178 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9180 tcg_gen_mov_tl(cpu_PC
, btarget
);
9182 if (ctx
->singlestep_enabled
) {
9183 save_cpu_state(ctx
, 0);
9184 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9189 MIPS_DEBUG("unknown branch");
9195 /* ISA extensions (ASEs) */
9196 /* MIPS16 extension to MIPS32 */
9198 /* MIPS16 major opcodes */
9200 M16_OPC_ADDIUSP
= 0x00,
9201 M16_OPC_ADDIUPC
= 0x01,
9204 M16_OPC_BEQZ
= 0x04,
9205 M16_OPC_BNEQZ
= 0x05,
9206 M16_OPC_SHIFT
= 0x06,
9208 M16_OPC_RRIA
= 0x08,
9209 M16_OPC_ADDIU8
= 0x09,
9210 M16_OPC_SLTI
= 0x0a,
9211 M16_OPC_SLTIU
= 0x0b,
9214 M16_OPC_CMPI
= 0x0e,
9218 M16_OPC_LWSP
= 0x12,
9222 M16_OPC_LWPC
= 0x16,
9226 M16_OPC_SWSP
= 0x1a,
9230 M16_OPC_EXTEND
= 0x1e,
9234 /* I8 funct field */
9253 /* RR funct field */
9287 /* I64 funct field */
9299 /* RR ry field for CNVT */
9301 RR_RY_CNVT_ZEB
= 0x0,
9302 RR_RY_CNVT_ZEH
= 0x1,
9303 RR_RY_CNVT_ZEW
= 0x2,
9304 RR_RY_CNVT_SEB
= 0x4,
9305 RR_RY_CNVT_SEH
= 0x5,
9306 RR_RY_CNVT_SEW
= 0x6,
9309 static int xlat (int r
)
9311 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9316 static void gen_mips16_save (DisasContext
*ctx
,
9317 int xsregs
, int aregs
,
9318 int do_ra
, int do_s0
, int do_s1
,
9321 TCGv t0
= tcg_temp_new();
9322 TCGv t1
= tcg_temp_new();
9352 generate_exception(ctx
, EXCP_RI
);
9358 gen_base_offset_addr(ctx
, t0
, 29, 12);
9359 gen_load_gpr(t1
, 7);
9360 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9363 gen_base_offset_addr(ctx
, t0
, 29, 8);
9364 gen_load_gpr(t1
, 6);
9365 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9368 gen_base_offset_addr(ctx
, t0
, 29, 4);
9369 gen_load_gpr(t1
, 5);
9370 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9373 gen_base_offset_addr(ctx
, t0
, 29, 0);
9374 gen_load_gpr(t1
, 4);
9375 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9378 gen_load_gpr(t0
, 29);
9380 #define DECR_AND_STORE(reg) do { \
9381 tcg_gen_subi_tl(t0, t0, 4); \
9382 gen_load_gpr(t1, reg); \
9383 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9447 generate_exception(ctx
, EXCP_RI
);
9463 #undef DECR_AND_STORE
9465 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9470 static void gen_mips16_restore (DisasContext
*ctx
,
9471 int xsregs
, int aregs
,
9472 int do_ra
, int do_s0
, int do_s1
,
9476 TCGv t0
= tcg_temp_new();
9477 TCGv t1
= tcg_temp_new();
9479 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9481 #define DECR_AND_LOAD(reg) do { \
9482 tcg_gen_subi_tl(t0, t0, 4); \
9483 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9484 gen_store_gpr(t1, reg); \
9548 generate_exception(ctx
, EXCP_RI
);
9564 #undef DECR_AND_LOAD
9566 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9571 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9572 int is_64_bit
, int extended
)
9576 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9577 generate_exception(ctx
, EXCP_RI
);
9581 t0
= tcg_temp_new();
9583 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9584 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9586 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9592 #if defined(TARGET_MIPS64)
9593 static void decode_i64_mips16 (DisasContext
*ctx
,
9594 int ry
, int funct
, int16_t offset
,
9600 offset
= extended
? offset
: offset
<< 3;
9601 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9605 offset
= extended
? offset
: offset
<< 3;
9606 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9610 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9611 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9615 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9616 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9619 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9620 generate_exception(ctx
, EXCP_RI
);
9622 offset
= extended
? offset
: offset
<< 3;
9623 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9628 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9629 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9633 offset
= extended
? offset
: offset
<< 2;
9634 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9638 offset
= extended
? offset
: offset
<< 2;
9639 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9645 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9647 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9648 int op
, rx
, ry
, funct
, sa
;
9649 int16_t imm
, offset
;
9651 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9652 op
= (ctx
->opcode
>> 11) & 0x1f;
9653 sa
= (ctx
->opcode
>> 22) & 0x1f;
9654 funct
= (ctx
->opcode
>> 8) & 0x7;
9655 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9656 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9657 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9658 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9659 | (ctx
->opcode
& 0x1f));
9661 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9664 case M16_OPC_ADDIUSP
:
9665 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9667 case M16_OPC_ADDIUPC
:
9668 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9671 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9672 /* No delay slot, so just process as a normal instruction */
9675 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9676 /* No delay slot, so just process as a normal instruction */
9679 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9680 /* No delay slot, so just process as a normal instruction */
9683 switch (ctx
->opcode
& 0x3) {
9685 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9688 #if defined(TARGET_MIPS64)
9690 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9692 generate_exception(ctx
, EXCP_RI
);
9696 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9699 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9703 #if defined(TARGET_MIPS64)
9706 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9710 imm
= ctx
->opcode
& 0xf;
9711 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9712 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9713 imm
= (int16_t) (imm
<< 1) >> 1;
9714 if ((ctx
->opcode
>> 4) & 0x1) {
9715 #if defined(TARGET_MIPS64)
9717 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9719 generate_exception(ctx
, EXCP_RI
);
9722 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9725 case M16_OPC_ADDIU8
:
9726 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9729 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9732 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9737 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9740 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9743 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9746 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9750 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9751 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9752 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9753 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9754 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9755 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9756 | (ctx
->opcode
& 0xf)) << 3;
9758 if (ctx
->opcode
& (1 << 7)) {
9759 gen_mips16_save(ctx
, xsregs
, aregs
,
9760 do_ra
, do_s0
, do_s1
,
9763 gen_mips16_restore(ctx
, xsregs
, aregs
,
9764 do_ra
, do_s0
, do_s1
,
9770 generate_exception(ctx
, EXCP_RI
);
9775 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9778 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9780 #if defined(TARGET_MIPS64)
9782 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9786 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9789 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9792 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9795 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9798 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9801 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9804 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9806 #if defined(TARGET_MIPS64)
9808 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9812 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9815 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9818 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9821 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9823 #if defined(TARGET_MIPS64)
9825 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9829 generate_exception(ctx
, EXCP_RI
);
9836 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9840 int op
, cnvt_op
, op1
, offset
;
9844 op
= (ctx
->opcode
>> 11) & 0x1f;
9845 sa
= (ctx
->opcode
>> 2) & 0x7;
9846 sa
= sa
== 0 ? 8 : sa
;
9847 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9848 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9849 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9850 op1
= offset
= ctx
->opcode
& 0x1f;
9855 case M16_OPC_ADDIUSP
:
9857 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9859 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9862 case M16_OPC_ADDIUPC
:
9863 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9866 offset
= (ctx
->opcode
& 0x7ff) << 1;
9867 offset
= (int16_t)(offset
<< 4) >> 4;
9868 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9869 /* No delay slot, so just process as a normal instruction */
9872 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9873 offset
= (((ctx
->opcode
& 0x1f) << 21)
9874 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9876 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9877 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9881 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9882 /* No delay slot, so just process as a normal instruction */
9885 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9886 /* No delay slot, so just process as a normal instruction */
9889 switch (ctx
->opcode
& 0x3) {
9891 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9894 #if defined(TARGET_MIPS64)
9896 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9898 generate_exception(ctx
, EXCP_RI
);
9902 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9905 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9909 #if defined(TARGET_MIPS64)
9912 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9917 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9919 if ((ctx
->opcode
>> 4) & 1) {
9920 #if defined(TARGET_MIPS64)
9922 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9924 generate_exception(ctx
, EXCP_RI
);
9927 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9931 case M16_OPC_ADDIU8
:
9933 int16_t imm
= (int8_t) ctx
->opcode
;
9935 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9940 int16_t imm
= (uint8_t) ctx
->opcode
;
9941 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9946 int16_t imm
= (uint8_t) ctx
->opcode
;
9947 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9954 funct
= (ctx
->opcode
>> 8) & 0x7;
9957 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9958 ((int8_t)ctx
->opcode
) << 1);
9961 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9962 ((int8_t)ctx
->opcode
) << 1);
9965 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9968 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9969 ((int8_t)ctx
->opcode
) << 3);
9973 int do_ra
= ctx
->opcode
& (1 << 6);
9974 int do_s0
= ctx
->opcode
& (1 << 5);
9975 int do_s1
= ctx
->opcode
& (1 << 4);
9976 int framesize
= ctx
->opcode
& 0xf;
9978 if (framesize
== 0) {
9981 framesize
= framesize
<< 3;
9984 if (ctx
->opcode
& (1 << 7)) {
9985 gen_mips16_save(ctx
, 0, 0,
9986 do_ra
, do_s0
, do_s1
, framesize
);
9988 gen_mips16_restore(ctx
, 0, 0,
9989 do_ra
, do_s0
, do_s1
, framesize
);
9995 int rz
= xlat(ctx
->opcode
& 0x7);
9997 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
9998 ((ctx
->opcode
>> 5) & 0x7);
9999 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
10003 reg32
= ctx
->opcode
& 0x1f;
10004 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
10007 generate_exception(ctx
, EXCP_RI
);
10014 int16_t imm
= (uint8_t) ctx
->opcode
;
10016 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
10021 int16_t imm
= (uint8_t) ctx
->opcode
;
10022 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
10025 #if defined(TARGET_MIPS64)
10027 check_mips_64(ctx
);
10028 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
10032 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
10035 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
10038 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10041 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
10044 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
10047 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
10050 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
10052 #if defined (TARGET_MIPS64)
10054 check_mips_64(ctx
);
10055 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
10059 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10062 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
10065 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10068 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10072 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10075 switch (ctx
->opcode
& 0x3) {
10077 mips32_op
= OPC_ADDU
;
10080 mips32_op
= OPC_SUBU
;
10082 #if defined(TARGET_MIPS64)
10084 mips32_op
= OPC_DADDU
;
10085 check_mips_64(ctx
);
10088 mips32_op
= OPC_DSUBU
;
10089 check_mips_64(ctx
);
10093 generate_exception(ctx
, EXCP_RI
);
10097 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10106 int nd
= (ctx
->opcode
>> 7) & 0x1;
10107 int link
= (ctx
->opcode
>> 6) & 0x1;
10108 int ra
= (ctx
->opcode
>> 5) & 0x1;
10111 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10116 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10120 /* XXX: not clear which exception should be raised
10121 * when in debug mode...
10123 check_insn(ctx
, ISA_MIPS32
);
10124 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10125 generate_exception(ctx
, EXCP_DBp
);
10127 generate_exception(ctx
, EXCP_DBp
);
10131 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10134 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10137 generate_exception(ctx
, EXCP_BREAK
);
10140 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10143 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10146 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10148 #if defined (TARGET_MIPS64)
10150 check_mips_64(ctx
);
10151 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10155 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10158 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10161 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10164 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10167 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10170 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10173 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
10177 case RR_RY_CNVT_ZEB
:
10178 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10180 case RR_RY_CNVT_ZEH
:
10181 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10183 case RR_RY_CNVT_SEB
:
10184 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10186 case RR_RY_CNVT_SEH
:
10187 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10189 #if defined (TARGET_MIPS64)
10190 case RR_RY_CNVT_ZEW
:
10191 check_mips_64(ctx
);
10192 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10194 case RR_RY_CNVT_SEW
:
10195 check_mips_64(ctx
);
10196 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10200 generate_exception(ctx
, EXCP_RI
);
10205 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
10207 #if defined (TARGET_MIPS64)
10209 check_mips_64(ctx
);
10210 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10213 check_mips_64(ctx
);
10214 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10217 check_mips_64(ctx
);
10218 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10221 check_mips_64(ctx
);
10222 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10226 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
10229 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
10232 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
10235 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
10237 #if defined (TARGET_MIPS64)
10239 check_mips_64(ctx
);
10240 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
10243 check_mips_64(ctx
);
10244 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
10247 check_mips_64(ctx
);
10248 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
10251 check_mips_64(ctx
);
10252 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
10256 generate_exception(ctx
, EXCP_RI
);
10260 case M16_OPC_EXTEND
:
10261 decode_extended_mips16_opc(env
, ctx
);
10264 #if defined(TARGET_MIPS64)
10266 funct
= (ctx
->opcode
>> 8) & 0x7;
10267 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10271 generate_exception(ctx
, EXCP_RI
);
10278 /* microMIPS extension to MIPS32/MIPS64 */
10281 * microMIPS32/microMIPS64 major opcodes
10283 * 1. MIPS Architecture for Programmers Volume II-B:
10284 * The microMIPS32 Instruction Set (Revision 3.05)
10286 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10288 * 2. MIPS Architecture For Programmers Volume II-A:
10289 * The MIPS64 Instruction Set (Revision 3.51)
10317 POOL32S
= 0x16, /* MIPS64 */
10318 DADDIU32
= 0x17, /* MIPS64 */
10320 /* 0x1f is reserved */
10329 /* 0x20 is reserved */
10339 /* 0x28 and 0x29 are reserved */
10349 /* 0x30 and 0x31 are reserved */
10356 SD32
= 0x36, /* MIPS64 */
10357 LD32
= 0x37, /* MIPS64 */
10359 /* 0x38 and 0x39 are reserved */
10370 /* POOL32A encoding of minor opcode field */
10373 /* These opcodes are distinguished only by bits 9..6; those bits are
10374 * what are recorded below. */
10400 /* The following can be distinguished by their lower 6 bits. */
10406 /* POOL32AXF encoding of minor opcode field extension */
10409 * 1. MIPS Architecture for Programmers Volume II-B:
10410 * The microMIPS32 Instruction Set (Revision 3.05)
10412 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10414 * 2. MIPS Architecture for Programmers VolumeIV-e:
10415 * The MIPS DSP Application-Specific Extension
10416 * to the microMIPS32 Architecture (Revision 2.34)
10418 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10433 /* begin of microMIPS32 DSP */
10435 /* bits 13..12 for 0x01 */
10441 /* bits 13..12 for 0x2a */
10447 /* bits 13..12 for 0x32 */
10451 /* end of microMIPS32 DSP */
10453 /* bits 15..12 for 0x2c */
10469 /* bits 15..12 for 0x34 */
10477 /* bits 15..12 for 0x3c */
10479 JR
= 0x0, /* alias */
10484 /* bits 15..12 for 0x05 */
10488 /* bits 15..12 for 0x0d */
10498 /* bits 15..12 for 0x15 */
10504 /* bits 15..12 for 0x1d */
10508 /* bits 15..12 for 0x2d */
10513 /* bits 15..12 for 0x35 */
10520 /* POOL32B encoding of minor opcode field (bits 15..12) */
10536 /* POOL32C encoding of minor opcode field (bits 15..12) */
10544 /* 0xa is reserved */
10551 /* 0x6 is reserved */
10557 /* POOL32F encoding of minor opcode field (bits 5..0) */
10560 /* These are the bit 7..6 values */
10571 /* These are the bit 8..6 values */
10615 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10619 /* POOL32Fxf encoding of minor opcode extension field */
10657 /* POOL32I encoding of minor opcode field (bits 25..21) */
10682 /* These overlap and are distinguished by bit16 of the instruction */
10691 /* POOL16A encoding of minor opcode field */
10698 /* POOL16B encoding of minor opcode field */
10705 /* POOL16C encoding of minor opcode field */
10725 /* POOL16D encoding of minor opcode field */
10732 /* POOL16E encoding of minor opcode field */
10739 static int mmreg (int r
)
10741 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10746 /* Used for 16-bit store instructions. */
10747 static int mmreg2 (int r
)
10749 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10754 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10755 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10756 #define uMIPS_RS2(op) uMIPS_RS(op)
10757 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10758 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10759 #define uMIPS_RS5(op) (op & 0x1f)
10761 /* Signed immediate */
10762 #define SIMM(op, start, width) \
10763 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10766 /* Zero-extended immediate */
10767 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10769 static void gen_addiur1sp(DisasContext
*ctx
)
10771 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10773 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10776 static void gen_addiur2(DisasContext
*ctx
)
10778 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10779 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10780 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10782 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10785 static void gen_addiusp(DisasContext
*ctx
)
10787 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10790 if (encoded
<= 1) {
10791 decoded
= 256 + encoded
;
10792 } else if (encoded
<= 255) {
10794 } else if (encoded
<= 509) {
10795 decoded
= encoded
- 512;
10797 decoded
= encoded
- 768;
10800 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10803 static void gen_addius5(DisasContext
*ctx
)
10805 int imm
= SIMM(ctx
->opcode
, 1, 4);
10806 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10808 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10811 static void gen_andi16(DisasContext
*ctx
)
10813 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10814 31, 32, 63, 64, 255, 32768, 65535 };
10815 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10816 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10817 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10819 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10822 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10823 int base
, int16_t offset
)
10825 const char *opn
= "ldst_multiple";
10829 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10830 generate_exception(ctx
, EXCP_RI
);
10834 t0
= tcg_temp_new();
10836 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10838 t1
= tcg_const_tl(reglist
);
10839 t2
= tcg_const_i32(ctx
->mem_idx
);
10841 save_cpu_state(ctx
, 1);
10844 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10848 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10851 #ifdef TARGET_MIPS64
10853 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10857 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10863 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10866 tcg_temp_free_i32(t2
);
10870 static void gen_pool16c_insn(DisasContext
*ctx
)
10872 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10873 int rs
= mmreg(ctx
->opcode
& 0x7);
10876 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10881 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10887 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10893 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10899 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10906 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10907 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10909 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10918 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10919 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10921 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10928 int reg
= ctx
->opcode
& 0x1f;
10930 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10936 int reg
= ctx
->opcode
& 0x1f;
10938 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10939 /* Let normal delay slot handling in our caller take us
10940 to the branch target. */
10952 int reg
= ctx
->opcode
& 0x1f;
10954 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10959 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
10963 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
10966 generate_exception(ctx
, EXCP_BREAK
);
10969 /* XXX: not clear which exception should be raised
10970 * when in debug mode...
10972 check_insn(ctx
, ISA_MIPS32
);
10973 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10974 generate_exception(ctx
, EXCP_DBp
);
10976 generate_exception(ctx
, EXCP_DBp
);
10979 case JRADDIUSP
+ 0:
10980 case JRADDIUSP
+ 1:
10982 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10984 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10985 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10986 /* Let normal delay slot handling in our caller take us
10987 to the branch target. */
10991 generate_exception(ctx
, EXCP_RI
);
10996 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
10998 TCGv t0
= tcg_temp_new();
10999 TCGv t1
= tcg_temp_new();
11001 gen_load_gpr(t0
, base
);
11004 gen_load_gpr(t1
, index
);
11005 tcg_gen_shli_tl(t1
, t1
, 2);
11006 gen_op_addr_add(ctx
, t0
, t1
, t0
);
11009 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11010 gen_store_gpr(t1
, rd
);
11016 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
11017 int base
, int16_t offset
)
11019 const char *opn
= "ldst_pair";
11022 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
11023 generate_exception(ctx
, EXCP_RI
);
11027 t0
= tcg_temp_new();
11028 t1
= tcg_temp_new();
11030 gen_base_offset_addr(ctx
, t0
, base
, offset
);
11035 generate_exception(ctx
, EXCP_RI
);
11038 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11039 gen_store_gpr(t1
, rd
);
11040 tcg_gen_movi_tl(t1
, 4);
11041 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11042 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11043 gen_store_gpr(t1
, rd
+1);
11047 gen_load_gpr(t1
, rd
);
11048 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11049 tcg_gen_movi_tl(t1
, 4);
11050 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11051 gen_load_gpr(t1
, rd
+1);
11052 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11055 #ifdef TARGET_MIPS64
11058 generate_exception(ctx
, EXCP_RI
);
11061 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11062 gen_store_gpr(t1
, rd
);
11063 tcg_gen_movi_tl(t1
, 8);
11064 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11065 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11066 gen_store_gpr(t1
, rd
+1);
11070 gen_load_gpr(t1
, rd
);
11071 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11072 tcg_gen_movi_tl(t1
, 8);
11073 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11074 gen_load_gpr(t1
, rd
+1);
11075 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11080 (void)opn
; /* avoid a compiler warning */
11081 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11086 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
11088 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11089 int minor
= (ctx
->opcode
>> 12) & 0xf;
11090 uint32_t mips32_op
;
11092 switch (extension
) {
11094 mips32_op
= OPC_TEQ
;
11097 mips32_op
= OPC_TGE
;
11100 mips32_op
= OPC_TGEU
;
11103 mips32_op
= OPC_TLT
;
11106 mips32_op
= OPC_TLTU
;
11109 mips32_op
= OPC_TNE
;
11111 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11113 #ifndef CONFIG_USER_ONLY
11116 check_cp0_enabled(ctx
);
11118 /* Treat as NOP. */
11121 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11125 check_cp0_enabled(ctx
);
11127 TCGv t0
= tcg_temp_new();
11129 gen_load_gpr(t0
, rt
);
11130 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11136 switch (minor
& 3) {
11138 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11141 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11144 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11147 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11150 goto pool32axf_invalid
;
11154 switch (minor
& 3) {
11156 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11159 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11162 goto pool32axf_invalid
;
11168 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11171 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11174 mips32_op
= OPC_CLO
;
11177 mips32_op
= OPC_CLZ
;
11179 check_insn(ctx
, ISA_MIPS32
);
11180 gen_cl(ctx
, mips32_op
, rt
, rs
);
11183 gen_rdhwr(ctx
, rt
, rs
);
11186 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11189 mips32_op
= OPC_MULT
;
11192 mips32_op
= OPC_MULTU
;
11195 mips32_op
= OPC_DIV
;
11198 mips32_op
= OPC_DIVU
;
11201 check_insn(ctx
, ISA_MIPS32
);
11202 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11205 mips32_op
= OPC_MADD
;
11208 mips32_op
= OPC_MADDU
;
11211 mips32_op
= OPC_MSUB
;
11214 mips32_op
= OPC_MSUBU
;
11216 check_insn(ctx
, ISA_MIPS32
);
11217 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11220 goto pool32axf_invalid
;
11231 generate_exception_err(ctx
, EXCP_CpU
, 2);
11234 goto pool32axf_invalid
;
11241 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11245 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11248 goto pool32axf_invalid
;
11254 check_cp0_enabled(ctx
);
11255 check_insn(ctx
, ISA_MIPS32R2
);
11256 gen_load_srsgpr(rt
, rs
);
11259 check_cp0_enabled(ctx
);
11260 check_insn(ctx
, ISA_MIPS32R2
);
11261 gen_store_srsgpr(rt
, rs
);
11264 goto pool32axf_invalid
;
11267 #ifndef CONFIG_USER_ONLY
11271 mips32_op
= OPC_TLBP
;
11274 mips32_op
= OPC_TLBR
;
11277 mips32_op
= OPC_TLBWI
;
11280 mips32_op
= OPC_TLBWR
;
11283 mips32_op
= OPC_WAIT
;
11286 mips32_op
= OPC_DERET
;
11289 mips32_op
= OPC_ERET
;
11291 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11294 goto pool32axf_invalid
;
11300 check_cp0_enabled(ctx
);
11302 TCGv t0
= tcg_temp_new();
11304 save_cpu_state(ctx
, 1);
11305 gen_helper_di(t0
, cpu_env
);
11306 gen_store_gpr(t0
, rs
);
11307 /* Stop translation as we may have switched the execution mode */
11308 ctx
->bstate
= BS_STOP
;
11313 check_cp0_enabled(ctx
);
11315 TCGv t0
= tcg_temp_new();
11317 save_cpu_state(ctx
, 1);
11318 gen_helper_ei(t0
, cpu_env
);
11319 gen_store_gpr(t0
, rs
);
11320 /* Stop translation as we may have switched the execution mode */
11321 ctx
->bstate
= BS_STOP
;
11326 goto pool32axf_invalid
;
11336 generate_exception(ctx
, EXCP_SYSCALL
);
11337 ctx
->bstate
= BS_STOP
;
11340 check_insn(ctx
, ISA_MIPS32
);
11341 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11342 generate_exception(ctx
, EXCP_DBp
);
11344 generate_exception(ctx
, EXCP_DBp
);
11348 goto pool32axf_invalid
;
11352 switch (minor
& 3) {
11354 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
11357 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
11360 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
11363 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
11366 goto pool32axf_invalid
;
11372 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
11375 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
11378 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
11381 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
11384 goto pool32axf_invalid
;
11389 MIPS_INVAL("pool32axf");
11390 generate_exception(ctx
, EXCP_RI
);
11395 /* Values for microMIPS fmt field. Variable-width, depending on which
11396 formats the instruction supports. */
11415 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11417 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11418 uint32_t mips32_op
;
11420 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11421 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11422 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11424 switch (extension
) {
11425 case FLOAT_1BIT_FMT(CFC1
, 0):
11426 mips32_op
= OPC_CFC1
;
11428 case FLOAT_1BIT_FMT(CTC1
, 0):
11429 mips32_op
= OPC_CTC1
;
11431 case FLOAT_1BIT_FMT(MFC1
, 0):
11432 mips32_op
= OPC_MFC1
;
11434 case FLOAT_1BIT_FMT(MTC1
, 0):
11435 mips32_op
= OPC_MTC1
;
11437 case FLOAT_1BIT_FMT(MFHC1
, 0):
11438 mips32_op
= OPC_MFHC1
;
11440 case FLOAT_1BIT_FMT(MTHC1
, 0):
11441 mips32_op
= OPC_MTHC1
;
11443 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11446 /* Reciprocal square root */
11447 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11448 mips32_op
= OPC_RSQRT_S
;
11450 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11451 mips32_op
= OPC_RSQRT_D
;
11455 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11456 mips32_op
= OPC_SQRT_S
;
11458 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11459 mips32_op
= OPC_SQRT_D
;
11463 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11464 mips32_op
= OPC_RECIP_S
;
11466 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11467 mips32_op
= OPC_RECIP_D
;
11471 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11472 mips32_op
= OPC_FLOOR_L_S
;
11474 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11475 mips32_op
= OPC_FLOOR_L_D
;
11477 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11478 mips32_op
= OPC_FLOOR_W_S
;
11480 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11481 mips32_op
= OPC_FLOOR_W_D
;
11485 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11486 mips32_op
= OPC_CEIL_L_S
;
11488 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11489 mips32_op
= OPC_CEIL_L_D
;
11491 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11492 mips32_op
= OPC_CEIL_W_S
;
11494 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11495 mips32_op
= OPC_CEIL_W_D
;
11499 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11500 mips32_op
= OPC_TRUNC_L_S
;
11502 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11503 mips32_op
= OPC_TRUNC_L_D
;
11505 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11506 mips32_op
= OPC_TRUNC_W_S
;
11508 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11509 mips32_op
= OPC_TRUNC_W_D
;
11513 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11514 mips32_op
= OPC_ROUND_L_S
;
11516 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11517 mips32_op
= OPC_ROUND_L_D
;
11519 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11520 mips32_op
= OPC_ROUND_W_S
;
11522 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11523 mips32_op
= OPC_ROUND_W_D
;
11526 /* Integer to floating-point conversion */
11527 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11528 mips32_op
= OPC_CVT_L_S
;
11530 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11531 mips32_op
= OPC_CVT_L_D
;
11533 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11534 mips32_op
= OPC_CVT_W_S
;
11536 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11537 mips32_op
= OPC_CVT_W_D
;
11540 /* Paired-foo conversions */
11541 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11542 mips32_op
= OPC_CVT_S_PL
;
11544 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11545 mips32_op
= OPC_CVT_S_PU
;
11547 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11548 mips32_op
= OPC_CVT_PW_PS
;
11550 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11551 mips32_op
= OPC_CVT_PS_PW
;
11554 /* Floating-point moves */
11555 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11556 mips32_op
= OPC_MOV_S
;
11558 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11559 mips32_op
= OPC_MOV_D
;
11561 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11562 mips32_op
= OPC_MOV_PS
;
11565 /* Absolute value */
11566 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11567 mips32_op
= OPC_ABS_S
;
11569 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11570 mips32_op
= OPC_ABS_D
;
11572 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11573 mips32_op
= OPC_ABS_PS
;
11577 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11578 mips32_op
= OPC_NEG_S
;
11580 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11581 mips32_op
= OPC_NEG_D
;
11583 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11584 mips32_op
= OPC_NEG_PS
;
11587 /* Reciprocal square root step */
11588 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11589 mips32_op
= OPC_RSQRT1_S
;
11591 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11592 mips32_op
= OPC_RSQRT1_D
;
11594 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11595 mips32_op
= OPC_RSQRT1_PS
;
11598 /* Reciprocal step */
11599 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11600 mips32_op
= OPC_RECIP1_S
;
11602 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11603 mips32_op
= OPC_RECIP1_S
;
11605 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11606 mips32_op
= OPC_RECIP1_PS
;
11609 /* Conversions from double */
11610 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11611 mips32_op
= OPC_CVT_D_S
;
11613 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11614 mips32_op
= OPC_CVT_D_W
;
11616 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11617 mips32_op
= OPC_CVT_D_L
;
11620 /* Conversions from single */
11621 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11622 mips32_op
= OPC_CVT_S_D
;
11624 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11625 mips32_op
= OPC_CVT_S_W
;
11627 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11628 mips32_op
= OPC_CVT_S_L
;
11630 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11633 /* Conditional moves on floating-point codes */
11634 case COND_FLOAT_MOV(MOVT
, 0):
11635 case COND_FLOAT_MOV(MOVT
, 1):
11636 case COND_FLOAT_MOV(MOVT
, 2):
11637 case COND_FLOAT_MOV(MOVT
, 3):
11638 case COND_FLOAT_MOV(MOVT
, 4):
11639 case COND_FLOAT_MOV(MOVT
, 5):
11640 case COND_FLOAT_MOV(MOVT
, 6):
11641 case COND_FLOAT_MOV(MOVT
, 7):
11642 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11644 case COND_FLOAT_MOV(MOVF
, 0):
11645 case COND_FLOAT_MOV(MOVF
, 1):
11646 case COND_FLOAT_MOV(MOVF
, 2):
11647 case COND_FLOAT_MOV(MOVF
, 3):
11648 case COND_FLOAT_MOV(MOVF
, 4):
11649 case COND_FLOAT_MOV(MOVF
, 5):
11650 case COND_FLOAT_MOV(MOVF
, 6):
11651 case COND_FLOAT_MOV(MOVF
, 7):
11652 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11655 MIPS_INVAL("pool32fxf");
11656 generate_exception(ctx
, EXCP_RI
);
11661 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11666 int rt
, rs
, rd
, rr
;
11668 uint32_t op
, minor
, mips32_op
;
11669 uint32_t cond
, fmt
, cc
;
11671 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11672 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11674 rt
= (ctx
->opcode
>> 21) & 0x1f;
11675 rs
= (ctx
->opcode
>> 16) & 0x1f;
11676 rd
= (ctx
->opcode
>> 11) & 0x1f;
11677 rr
= (ctx
->opcode
>> 6) & 0x1f;
11678 imm
= (int16_t) ctx
->opcode
;
11680 op
= (ctx
->opcode
>> 26) & 0x3f;
11683 minor
= ctx
->opcode
& 0x3f;
11686 minor
= (ctx
->opcode
>> 6) & 0xf;
11689 mips32_op
= OPC_SLL
;
11692 mips32_op
= OPC_SRA
;
11695 mips32_op
= OPC_SRL
;
11698 mips32_op
= OPC_ROTR
;
11700 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11703 goto pool32a_invalid
;
11707 minor
= (ctx
->opcode
>> 6) & 0xf;
11711 mips32_op
= OPC_ADD
;
11714 mips32_op
= OPC_ADDU
;
11717 mips32_op
= OPC_SUB
;
11720 mips32_op
= OPC_SUBU
;
11723 mips32_op
= OPC_MUL
;
11725 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11729 mips32_op
= OPC_SLLV
;
11732 mips32_op
= OPC_SRLV
;
11735 mips32_op
= OPC_SRAV
;
11738 mips32_op
= OPC_ROTRV
;
11740 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11742 /* Logical operations */
11744 mips32_op
= OPC_AND
;
11747 mips32_op
= OPC_OR
;
11750 mips32_op
= OPC_NOR
;
11753 mips32_op
= OPC_XOR
;
11755 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11757 /* Set less than */
11759 mips32_op
= OPC_SLT
;
11762 mips32_op
= OPC_SLTU
;
11764 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11767 goto pool32a_invalid
;
11771 minor
= (ctx
->opcode
>> 6) & 0xf;
11773 /* Conditional moves */
11775 mips32_op
= OPC_MOVN
;
11778 mips32_op
= OPC_MOVZ
;
11780 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11783 gen_ldxs(ctx
, rs
, rt
, rd
);
11786 goto pool32a_invalid
;
11790 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11793 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11796 gen_pool32axf(env
, ctx
, rt
, rs
);
11799 generate_exception(ctx
, EXCP_BREAK
);
11803 MIPS_INVAL("pool32a");
11804 generate_exception(ctx
, EXCP_RI
);
11809 minor
= (ctx
->opcode
>> 12) & 0xf;
11812 check_cp0_enabled(ctx
);
11813 /* Treat as no-op. */
11817 /* COP2: Not implemented. */
11818 generate_exception_err(ctx
, EXCP_CpU
, 2);
11822 #ifdef TARGET_MIPS64
11826 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11830 #ifdef TARGET_MIPS64
11834 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11837 MIPS_INVAL("pool32b");
11838 generate_exception(ctx
, EXCP_RI
);
11843 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
11844 minor
= ctx
->opcode
& 0x3f;
11845 check_cp1_enabled(ctx
);
11848 mips32_op
= OPC_ALNV_PS
;
11851 mips32_op
= OPC_MADD_S
;
11854 mips32_op
= OPC_MADD_D
;
11857 mips32_op
= OPC_MADD_PS
;
11860 mips32_op
= OPC_MSUB_S
;
11863 mips32_op
= OPC_MSUB_D
;
11866 mips32_op
= OPC_MSUB_PS
;
11869 mips32_op
= OPC_NMADD_S
;
11872 mips32_op
= OPC_NMADD_D
;
11875 mips32_op
= OPC_NMADD_PS
;
11878 mips32_op
= OPC_NMSUB_S
;
11881 mips32_op
= OPC_NMSUB_D
;
11884 mips32_op
= OPC_NMSUB_PS
;
11886 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11888 case CABS_COND_FMT
:
11889 cond
= (ctx
->opcode
>> 6) & 0xf;
11890 cc
= (ctx
->opcode
>> 13) & 0x7;
11891 fmt
= (ctx
->opcode
>> 10) & 0x3;
11894 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11897 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11900 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11903 goto pool32f_invalid
;
11907 cond
= (ctx
->opcode
>> 6) & 0xf;
11908 cc
= (ctx
->opcode
>> 13) & 0x7;
11909 fmt
= (ctx
->opcode
>> 10) & 0x3;
11912 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11915 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11918 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11921 goto pool32f_invalid
;
11925 gen_pool32fxf(ctx
, rt
, rs
);
11929 switch ((ctx
->opcode
>> 6) & 0x7) {
11931 mips32_op
= OPC_PLL_PS
;
11934 mips32_op
= OPC_PLU_PS
;
11937 mips32_op
= OPC_PUL_PS
;
11940 mips32_op
= OPC_PUU_PS
;
11943 mips32_op
= OPC_CVT_PS_S
;
11945 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11948 goto pool32f_invalid
;
11953 switch ((ctx
->opcode
>> 6) & 0x7) {
11955 mips32_op
= OPC_LWXC1
;
11958 mips32_op
= OPC_SWXC1
;
11961 mips32_op
= OPC_LDXC1
;
11964 mips32_op
= OPC_SDXC1
;
11967 mips32_op
= OPC_LUXC1
;
11970 mips32_op
= OPC_SUXC1
;
11972 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11975 goto pool32f_invalid
;
11980 fmt
= (ctx
->opcode
>> 9) & 0x3;
11981 switch ((ctx
->opcode
>> 6) & 0x7) {
11985 mips32_op
= OPC_RSQRT2_S
;
11988 mips32_op
= OPC_RSQRT2_D
;
11991 mips32_op
= OPC_RSQRT2_PS
;
11994 goto pool32f_invalid
;
12000 mips32_op
= OPC_RECIP2_S
;
12003 mips32_op
= OPC_RECIP2_D
;
12006 mips32_op
= OPC_RECIP2_PS
;
12009 goto pool32f_invalid
;
12013 mips32_op
= OPC_ADDR_PS
;
12016 mips32_op
= OPC_MULR_PS
;
12018 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12021 goto pool32f_invalid
;
12025 /* MOV[FT].fmt and PREFX */
12026 cc
= (ctx
->opcode
>> 13) & 0x7;
12027 fmt
= (ctx
->opcode
>> 9) & 0x3;
12028 switch ((ctx
->opcode
>> 6) & 0x7) {
12032 gen_movcf_s(rs
, rt
, cc
, 0);
12035 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
12038 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
12041 goto pool32f_invalid
;
12047 gen_movcf_s(rs
, rt
, cc
, 1);
12050 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
12053 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
12056 goto pool32f_invalid
;
12062 goto pool32f_invalid
;
12065 #define FINSN_3ARG_SDPS(prfx) \
12066 switch ((ctx->opcode >> 8) & 0x3) { \
12068 mips32_op = OPC_##prfx##_S; \
12071 mips32_op = OPC_##prfx##_D; \
12073 case FMT_SDPS_PS: \
12074 mips32_op = OPC_##prfx##_PS; \
12077 goto pool32f_invalid; \
12080 /* regular FP ops */
12081 switch ((ctx
->opcode
>> 6) & 0x3) {
12083 FINSN_3ARG_SDPS(ADD
);
12086 FINSN_3ARG_SDPS(SUB
);
12089 FINSN_3ARG_SDPS(MUL
);
12092 fmt
= (ctx
->opcode
>> 8) & 0x3;
12094 mips32_op
= OPC_DIV_D
;
12095 } else if (fmt
== 0) {
12096 mips32_op
= OPC_DIV_S
;
12098 goto pool32f_invalid
;
12102 goto pool32f_invalid
;
12107 switch ((ctx
->opcode
>> 6) & 0x3) {
12109 FINSN_3ARG_SDPS(MOVN
);
12112 FINSN_3ARG_SDPS(MOVZ
);
12115 goto pool32f_invalid
;
12119 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12123 MIPS_INVAL("pool32f");
12124 generate_exception(ctx
, EXCP_RI
);
12128 generate_exception_err(ctx
, EXCP_CpU
, 1);
12132 minor
= (ctx
->opcode
>> 21) & 0x1f;
12135 mips32_op
= OPC_BLTZ
;
12138 mips32_op
= OPC_BLTZAL
;
12141 mips32_op
= OPC_BLTZALS
;
12144 mips32_op
= OPC_BGEZ
;
12147 mips32_op
= OPC_BGEZAL
;
12150 mips32_op
= OPC_BGEZALS
;
12153 mips32_op
= OPC_BLEZ
;
12156 mips32_op
= OPC_BGTZ
;
12158 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12163 mips32_op
= OPC_TLTI
;
12166 mips32_op
= OPC_TGEI
;
12169 mips32_op
= OPC_TLTIU
;
12172 mips32_op
= OPC_TGEIU
;
12175 mips32_op
= OPC_TNEI
;
12178 mips32_op
= OPC_TEQI
;
12180 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12185 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12186 4, rs
, 0, imm
<< 1);
12187 /* Compact branches don't have a delay slot, so just let
12188 the normal delay slot handling take us to the branch
12192 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12198 /* COP2: Not implemented. */
12199 generate_exception_err(ctx
, EXCP_CpU
, 2);
12202 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12205 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12208 mips32_op
= OPC_BC1FANY4
;
12211 mips32_op
= OPC_BC1TANY4
;
12214 check_insn(ctx
, ASE_MIPS3D
);
12217 gen_compute_branch1(ctx
, mips32_op
,
12218 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12222 /* MIPS DSP: not implemented */
12225 MIPS_INVAL("pool32i");
12226 generate_exception(ctx
, EXCP_RI
);
12231 minor
= (ctx
->opcode
>> 12) & 0xf;
12234 mips32_op
= OPC_LWL
;
12237 mips32_op
= OPC_SWL
;
12240 mips32_op
= OPC_LWR
;
12243 mips32_op
= OPC_SWR
;
12245 #if defined(TARGET_MIPS64)
12247 mips32_op
= OPC_LDL
;
12250 mips32_op
= OPC_SDL
;
12253 mips32_op
= OPC_LDR
;
12256 mips32_op
= OPC_SDR
;
12259 mips32_op
= OPC_LWU
;
12262 mips32_op
= OPC_LLD
;
12266 mips32_op
= OPC_LL
;
12269 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12272 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12275 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12277 #if defined(TARGET_MIPS64)
12279 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12283 /* Treat as no-op */
12286 MIPS_INVAL("pool32c");
12287 generate_exception(ctx
, EXCP_RI
);
12292 mips32_op
= OPC_ADDI
;
12295 mips32_op
= OPC_ADDIU
;
12297 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12300 /* Logical operations */
12302 mips32_op
= OPC_ORI
;
12305 mips32_op
= OPC_XORI
;
12308 mips32_op
= OPC_ANDI
;
12310 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12313 /* Set less than immediate */
12315 mips32_op
= OPC_SLTI
;
12318 mips32_op
= OPC_SLTIU
;
12320 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12323 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12324 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12327 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12328 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12331 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12334 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12337 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12338 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12341 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12342 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12344 /* Floating point (COP1) */
12346 mips32_op
= OPC_LWC1
;
12349 mips32_op
= OPC_LDC1
;
12352 mips32_op
= OPC_SWC1
;
12355 mips32_op
= OPC_SDC1
;
12357 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
12361 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12362 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12364 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12367 /* Loads and stores */
12369 mips32_op
= OPC_LB
;
12372 mips32_op
= OPC_LBU
;
12375 mips32_op
= OPC_LH
;
12378 mips32_op
= OPC_LHU
;
12381 mips32_op
= OPC_LW
;
12383 #ifdef TARGET_MIPS64
12385 mips32_op
= OPC_LD
;
12388 mips32_op
= OPC_SD
;
12392 mips32_op
= OPC_SB
;
12395 mips32_op
= OPC_SH
;
12398 mips32_op
= OPC_SW
;
12401 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12404 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12407 generate_exception(ctx
, EXCP_RI
);
12412 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
12416 /* make sure instructions are on a halfword boundary */
12417 if (ctx
->pc
& 0x1) {
12418 env
->CP0_BadVAddr
= ctx
->pc
;
12419 generate_exception(ctx
, EXCP_AdEL
);
12420 ctx
->bstate
= BS_STOP
;
12424 op
= (ctx
->opcode
>> 10) & 0x3f;
12425 /* Enforce properly-sized instructions in a delay slot */
12426 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12427 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12465 if (bits
& MIPS_HFLAG_BDS16
) {
12466 generate_exception(ctx
, EXCP_RI
);
12467 /* Just stop translation; the user is confused. */
12468 ctx
->bstate
= BS_STOP
;
12493 if (bits
& MIPS_HFLAG_BDS32
) {
12494 generate_exception(ctx
, EXCP_RI
);
12495 /* Just stop translation; the user is confused. */
12496 ctx
->bstate
= BS_STOP
;
12507 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12508 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12509 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12512 switch (ctx
->opcode
& 0x1) {
12521 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12526 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12527 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12528 int amount
= (ctx
->opcode
>> 1) & 0x7;
12530 amount
= amount
== 0 ? 8 : amount
;
12532 switch (ctx
->opcode
& 0x1) {
12541 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12545 gen_pool16c_insn(ctx
);
12549 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12550 int rb
= 28; /* GP */
12551 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12553 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12557 if (ctx
->opcode
& 1) {
12558 generate_exception(ctx
, EXCP_RI
);
12561 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12562 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12563 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12564 int rd
, rs
, re
, rt
;
12565 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12566 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12567 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12569 rd
= rd_enc
[enc_dest
];
12570 re
= re_enc
[enc_dest
];
12571 rs
= rs_rt_enc
[enc_rs
];
12572 rt
= rs_rt_enc
[enc_rt
];
12574 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12575 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12580 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12581 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12582 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12583 offset
= (offset
== 0xf ? -1 : offset
);
12585 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12590 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12591 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12592 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12594 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12599 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12600 int rb
= 29; /* SP */
12601 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12603 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12608 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12609 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12610 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12612 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12617 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12618 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12619 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12621 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12626 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12627 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12628 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12630 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12635 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12636 int rb
= 29; /* SP */
12637 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12639 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12644 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12645 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12646 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12648 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12653 int rd
= uMIPS_RD5(ctx
->opcode
);
12654 int rs
= uMIPS_RS5(ctx
->opcode
);
12656 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12663 switch (ctx
->opcode
& 0x1) {
12673 switch (ctx
->opcode
& 0x1) {
12678 gen_addiur1sp(ctx
);
12683 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12684 SIMM(ctx
->opcode
, 0, 10) << 1);
12688 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12689 mmreg(uMIPS_RD(ctx
->opcode
)),
12690 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12694 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12695 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12697 imm
= (imm
== 0x7f ? -1 : imm
);
12698 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12708 generate_exception(ctx
, EXCP_RI
);
12711 decode_micromips32_opc (env
, ctx
, op
);
12718 /* SmartMIPS extension to MIPS32 */
12720 #if defined(TARGET_MIPS64)
12722 /* MDMX extension to MIPS64 */
12726 /* MIPSDSP functions. */
12727 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12728 int rd
, int base
, int offset
)
12730 const char *opn
= "ldx";
12734 t0
= tcg_temp_new();
12737 gen_load_gpr(t0
, offset
);
12738 } else if (offset
== 0) {
12739 gen_load_gpr(t0
, base
);
12741 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12746 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
12747 gen_store_gpr(t0
, rd
);
12751 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
12752 gen_store_gpr(t0
, rd
);
12756 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12757 gen_store_gpr(t0
, rd
);
12760 #if defined(TARGET_MIPS64)
12762 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12763 gen_store_gpr(t0
, rd
);
12768 (void)opn
; /* avoid a compiler warning */
12769 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12770 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12774 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12775 int ret
, int v1
, int v2
)
12777 const char *opn
= "mipsdsp arith";
12782 /* Treat as NOP. */
12787 v1_t
= tcg_temp_new();
12788 v2_t
= tcg_temp_new();
12790 gen_load_gpr(v1_t
, v1
);
12791 gen_load_gpr(v2_t
, v2
);
12794 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12795 case OPC_MULT_G_2E
:
12799 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12801 case OPC_ADDUH_R_QB
:
12802 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12805 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12807 case OPC_ADDQH_R_PH
:
12808 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12811 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12813 case OPC_ADDQH_R_W
:
12814 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12817 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12819 case OPC_SUBUH_R_QB
:
12820 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12823 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12825 case OPC_SUBQH_R_PH
:
12826 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12829 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12831 case OPC_SUBQH_R_W
:
12832 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12836 case OPC_ABSQ_S_PH_DSP
:
12838 case OPC_ABSQ_S_QB
:
12840 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12842 case OPC_ABSQ_S_PH
:
12844 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12848 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12850 case OPC_PRECEQ_W_PHL
:
12852 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12853 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12855 case OPC_PRECEQ_W_PHR
:
12857 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12858 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12859 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12861 case OPC_PRECEQU_PH_QBL
:
12863 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12865 case OPC_PRECEQU_PH_QBR
:
12867 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12869 case OPC_PRECEQU_PH_QBLA
:
12871 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12873 case OPC_PRECEQU_PH_QBRA
:
12875 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12877 case OPC_PRECEU_PH_QBL
:
12879 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12881 case OPC_PRECEU_PH_QBR
:
12883 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12885 case OPC_PRECEU_PH_QBLA
:
12887 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12889 case OPC_PRECEU_PH_QBRA
:
12891 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12895 case OPC_ADDU_QB_DSP
:
12899 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12901 case OPC_ADDQ_S_PH
:
12903 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12907 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12911 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12913 case OPC_ADDU_S_QB
:
12915 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12919 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12921 case OPC_ADDU_S_PH
:
12923 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12927 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12929 case OPC_SUBQ_S_PH
:
12931 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12935 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12939 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12941 case OPC_SUBU_S_QB
:
12943 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12947 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12949 case OPC_SUBU_S_PH
:
12951 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12955 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12959 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12963 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12965 case OPC_RADDU_W_QB
:
12967 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12971 case OPC_CMPU_EQ_QB_DSP
:
12973 case OPC_PRECR_QB_PH
:
12975 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12977 case OPC_PRECRQ_QB_PH
:
12979 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12981 case OPC_PRECR_SRA_PH_W
:
12984 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12985 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12987 tcg_temp_free_i32(sa_t
);
12990 case OPC_PRECR_SRA_R_PH_W
:
12993 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12994 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12996 tcg_temp_free_i32(sa_t
);
12999 case OPC_PRECRQ_PH_W
:
13001 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13003 case OPC_PRECRQ_RS_PH_W
:
13005 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13007 case OPC_PRECRQU_S_QB_PH
:
13009 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13013 #ifdef TARGET_MIPS64
13014 case OPC_ABSQ_S_QH_DSP
:
13016 case OPC_PRECEQ_L_PWL
:
13018 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
13020 case OPC_PRECEQ_L_PWR
:
13022 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
13024 case OPC_PRECEQ_PW_QHL
:
13026 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
13028 case OPC_PRECEQ_PW_QHR
:
13030 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
13032 case OPC_PRECEQ_PW_QHLA
:
13034 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
13036 case OPC_PRECEQ_PW_QHRA
:
13038 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
13040 case OPC_PRECEQU_QH_OBL
:
13042 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
13044 case OPC_PRECEQU_QH_OBR
:
13046 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
13048 case OPC_PRECEQU_QH_OBLA
:
13050 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
13052 case OPC_PRECEQU_QH_OBRA
:
13054 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
13056 case OPC_PRECEU_QH_OBL
:
13058 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
13060 case OPC_PRECEU_QH_OBR
:
13062 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
13064 case OPC_PRECEU_QH_OBLA
:
13066 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
13068 case OPC_PRECEU_QH_OBRA
:
13070 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
13072 case OPC_ABSQ_S_OB
:
13074 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
13076 case OPC_ABSQ_S_PW
:
13078 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
13080 case OPC_ABSQ_S_QH
:
13082 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
13086 case OPC_ADDU_OB_DSP
:
13088 case OPC_RADDU_L_OB
:
13090 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
13094 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13096 case OPC_SUBQ_S_PW
:
13098 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13102 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13104 case OPC_SUBQ_S_QH
:
13106 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13110 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13112 case OPC_SUBU_S_OB
:
13114 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13118 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13120 case OPC_SUBU_S_QH
:
13122 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13126 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13128 case OPC_SUBUH_R_OB
:
13130 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13134 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13136 case OPC_ADDQ_S_PW
:
13138 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13142 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13144 case OPC_ADDQ_S_QH
:
13146 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13150 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13152 case OPC_ADDU_S_OB
:
13154 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13158 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13160 case OPC_ADDU_S_QH
:
13162 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13166 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13168 case OPC_ADDUH_R_OB
:
13170 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13174 case OPC_CMPU_EQ_OB_DSP
:
13176 case OPC_PRECR_OB_QH
:
13178 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13180 case OPC_PRECR_SRA_QH_PW
:
13183 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13184 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13185 tcg_temp_free_i32(ret_t
);
13188 case OPC_PRECR_SRA_R_QH_PW
:
13191 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13192 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13193 tcg_temp_free_i32(sa_v
);
13196 case OPC_PRECRQ_OB_QH
:
13198 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13200 case OPC_PRECRQ_PW_L
:
13202 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13204 case OPC_PRECRQ_QH_PW
:
13206 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13208 case OPC_PRECRQ_RS_QH_PW
:
13210 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13212 case OPC_PRECRQU_S_OB_QH
:
13214 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13221 tcg_temp_free(v1_t
);
13222 tcg_temp_free(v2_t
);
13224 (void)opn
; /* avoid a compiler warning */
13225 MIPS_DEBUG("%s", opn
);
13228 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13229 int ret
, int v1
, int v2
)
13232 const char *opn
= "mipsdsp shift";
13238 /* Treat as NOP. */
13243 t0
= tcg_temp_new();
13244 v1_t
= tcg_temp_new();
13245 v2_t
= tcg_temp_new();
13247 tcg_gen_movi_tl(t0
, v1
);
13248 gen_load_gpr(v1_t
, v1
);
13249 gen_load_gpr(v2_t
, v2
);
13252 case OPC_SHLL_QB_DSP
:
13254 op2
= MASK_SHLL_QB(ctx
->opcode
);
13258 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13262 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13266 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13270 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13272 case OPC_SHLL_S_PH
:
13274 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13276 case OPC_SHLLV_S_PH
:
13278 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13282 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13284 case OPC_SHLLV_S_W
:
13286 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13290 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13294 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13298 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13302 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13306 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13308 case OPC_SHRA_R_QB
:
13310 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13314 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13316 case OPC_SHRAV_R_QB
:
13318 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13322 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13324 case OPC_SHRA_R_PH
:
13326 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13330 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13332 case OPC_SHRAV_R_PH
:
13334 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13338 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13340 case OPC_SHRAV_R_W
:
13342 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13344 default: /* Invalid */
13345 MIPS_INVAL("MASK SHLL.QB");
13346 generate_exception(ctx
, EXCP_RI
);
13351 #ifdef TARGET_MIPS64
13352 case OPC_SHLL_OB_DSP
:
13353 op2
= MASK_SHLL_OB(ctx
->opcode
);
13357 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13361 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13363 case OPC_SHLL_S_PW
:
13365 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13367 case OPC_SHLLV_S_PW
:
13369 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13373 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13377 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13381 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13385 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13387 case OPC_SHLL_S_QH
:
13389 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13391 case OPC_SHLLV_S_QH
:
13393 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13397 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13401 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13403 case OPC_SHRA_R_OB
:
13405 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13407 case OPC_SHRAV_R_OB
:
13409 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13413 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13417 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13419 case OPC_SHRA_R_PW
:
13421 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13423 case OPC_SHRAV_R_PW
:
13425 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13429 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13433 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13435 case OPC_SHRA_R_QH
:
13437 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13439 case OPC_SHRAV_R_QH
:
13441 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13445 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13449 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13453 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13457 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13459 default: /* Invalid */
13460 MIPS_INVAL("MASK SHLL.OB");
13461 generate_exception(ctx
, EXCP_RI
);
13469 tcg_temp_free(v1_t
);
13470 tcg_temp_free(v2_t
);
13471 (void)opn
; /* avoid a compiler warning */
13472 MIPS_DEBUG("%s", opn
);
13475 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13476 int ret
, int v1
, int v2
, int check_ret
)
13478 const char *opn
= "mipsdsp multiply";
13483 if ((ret
== 0) && (check_ret
== 1)) {
13484 /* Treat as NOP. */
13489 t0
= tcg_temp_new_i32();
13490 v1_t
= tcg_temp_new();
13491 v2_t
= tcg_temp_new();
13493 tcg_gen_movi_i32(t0
, ret
);
13494 gen_load_gpr(v1_t
, v1
);
13495 gen_load_gpr(v2_t
, v2
);
13498 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13499 * the same mask and op1. */
13500 case OPC_MULT_G_2E
:
13504 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13507 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13510 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13512 case OPC_MULQ_RS_W
:
13513 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13517 case OPC_DPA_W_PH_DSP
:
13519 case OPC_DPAU_H_QBL
:
13521 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13523 case OPC_DPAU_H_QBR
:
13525 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13527 case OPC_DPSU_H_QBL
:
13529 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13531 case OPC_DPSU_H_QBR
:
13533 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13537 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13539 case OPC_DPAX_W_PH
:
13541 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13543 case OPC_DPAQ_S_W_PH
:
13545 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13547 case OPC_DPAQX_S_W_PH
:
13549 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13551 case OPC_DPAQX_SA_W_PH
:
13553 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13557 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13559 case OPC_DPSX_W_PH
:
13561 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13563 case OPC_DPSQ_S_W_PH
:
13565 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13567 case OPC_DPSQX_S_W_PH
:
13569 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13571 case OPC_DPSQX_SA_W_PH
:
13573 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13575 case OPC_MULSAQ_S_W_PH
:
13577 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13579 case OPC_DPAQ_SA_L_W
:
13581 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13583 case OPC_DPSQ_SA_L_W
:
13585 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13587 case OPC_MAQ_S_W_PHL
:
13589 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13591 case OPC_MAQ_S_W_PHR
:
13593 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13595 case OPC_MAQ_SA_W_PHL
:
13597 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13599 case OPC_MAQ_SA_W_PHR
:
13601 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13603 case OPC_MULSA_W_PH
:
13605 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13609 #ifdef TARGET_MIPS64
13610 case OPC_DPAQ_W_QH_DSP
:
13612 int ac
= ret
& 0x03;
13613 tcg_gen_movi_i32(t0
, ac
);
13618 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13622 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13626 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13630 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13634 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13636 case OPC_DPAQ_S_W_QH
:
13638 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13640 case OPC_DPAQ_SA_L_PW
:
13642 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13644 case OPC_DPAU_H_OBL
:
13646 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13648 case OPC_DPAU_H_OBR
:
13650 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13654 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13656 case OPC_DPSQ_S_W_QH
:
13658 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13660 case OPC_DPSQ_SA_L_PW
:
13662 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13664 case OPC_DPSU_H_OBL
:
13666 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13668 case OPC_DPSU_H_OBR
:
13670 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13672 case OPC_MAQ_S_L_PWL
:
13674 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13676 case OPC_MAQ_S_L_PWR
:
13678 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13680 case OPC_MAQ_S_W_QHLL
:
13682 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13684 case OPC_MAQ_SA_W_QHLL
:
13686 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13688 case OPC_MAQ_S_W_QHLR
:
13690 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13692 case OPC_MAQ_SA_W_QHLR
:
13694 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13696 case OPC_MAQ_S_W_QHRL
:
13698 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13700 case OPC_MAQ_SA_W_QHRL
:
13702 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13704 case OPC_MAQ_S_W_QHRR
:
13706 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13708 case OPC_MAQ_SA_W_QHRR
:
13710 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13712 case OPC_MULSAQ_S_L_PW
:
13714 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13716 case OPC_MULSAQ_S_W_QH
:
13718 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13724 case OPC_ADDU_QB_DSP
:
13726 case OPC_MULEU_S_PH_QBL
:
13728 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13730 case OPC_MULEU_S_PH_QBR
:
13732 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13734 case OPC_MULQ_RS_PH
:
13736 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13738 case OPC_MULEQ_S_W_PHL
:
13740 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13742 case OPC_MULEQ_S_W_PHR
:
13744 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13746 case OPC_MULQ_S_PH
:
13748 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13752 #ifdef TARGET_MIPS64
13753 case OPC_ADDU_OB_DSP
:
13755 case OPC_MULEQ_S_PW_QHL
:
13757 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13759 case OPC_MULEQ_S_PW_QHR
:
13761 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13763 case OPC_MULEU_S_QH_OBL
:
13765 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13767 case OPC_MULEU_S_QH_OBR
:
13769 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13771 case OPC_MULQ_RS_QH
:
13773 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13780 tcg_temp_free_i32(t0
);
13781 tcg_temp_free(v1_t
);
13782 tcg_temp_free(v2_t
);
13784 (void)opn
; /* avoid a compiler warning */
13785 MIPS_DEBUG("%s", opn
);
13789 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13792 const char *opn
= "mipsdsp Bit/ Manipulation";
13798 /* Treat as NOP. */
13803 t0
= tcg_temp_new();
13804 val_t
= tcg_temp_new();
13805 gen_load_gpr(val_t
, val
);
13808 case OPC_ABSQ_S_PH_DSP
:
13812 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13817 target_long result
;
13818 imm
= (ctx
->opcode
>> 16) & 0xFF;
13819 result
= (uint32_t)imm
<< 24 |
13820 (uint32_t)imm
<< 16 |
13821 (uint32_t)imm
<< 8 |
13823 result
= (int32_t)result
;
13824 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13829 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13830 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13831 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13832 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13833 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13834 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13839 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13840 imm
= (int16_t)(imm
<< 6) >> 6;
13841 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13842 (target_long
)((int32_t)imm
<< 16 | \
13848 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13849 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13850 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13851 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13855 #ifdef TARGET_MIPS64
13856 case OPC_ABSQ_S_QH_DSP
:
13863 imm
= (ctx
->opcode
>> 16) & 0xFF;
13864 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13865 temp
= (temp
<< 16) | temp
;
13866 temp
= (temp
<< 32) | temp
;
13867 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13875 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13876 imm
= (int16_t)(imm
<< 6) >> 6;
13877 temp
= ((target_long
)imm
<< 32) \
13878 | ((target_long
)imm
& 0xFFFFFFFF);
13879 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13887 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13888 imm
= (int16_t)(imm
<< 6) >> 6;
13890 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13891 ((uint64_t)(uint16_t)imm
<< 32) |
13892 ((uint64_t)(uint16_t)imm
<< 16) |
13893 (uint64_t)(uint16_t)imm
;
13894 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13899 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13900 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13901 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13902 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13903 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13904 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13905 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13909 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13910 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13911 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13915 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13916 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13917 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13918 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13919 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13926 tcg_temp_free(val_t
);
13928 (void)opn
; /* avoid a compiler warning */
13929 MIPS_DEBUG("%s", opn
);
13932 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13933 uint32_t op1
, uint32_t op2
,
13934 int ret
, int v1
, int v2
, int check_ret
)
13936 const char *opn
= "mipsdsp add compare pick";
13941 if ((ret
== 0) && (check_ret
== 1)) {
13942 /* Treat as NOP. */
13947 t1
= tcg_temp_new();
13948 v1_t
= tcg_temp_new();
13949 v2_t
= tcg_temp_new();
13951 gen_load_gpr(v1_t
, v1
);
13952 gen_load_gpr(v2_t
, v2
);
13955 case OPC_CMPU_EQ_QB_DSP
:
13957 case OPC_CMPU_EQ_QB
:
13959 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13961 case OPC_CMPU_LT_QB
:
13963 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13965 case OPC_CMPU_LE_QB
:
13967 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13969 case OPC_CMPGU_EQ_QB
:
13971 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13973 case OPC_CMPGU_LT_QB
:
13975 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13977 case OPC_CMPGU_LE_QB
:
13979 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13981 case OPC_CMPGDU_EQ_QB
:
13983 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13984 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13985 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13986 tcg_gen_shli_tl(t1
, t1
, 24);
13987 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13989 case OPC_CMPGDU_LT_QB
:
13991 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
13992 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13993 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13994 tcg_gen_shli_tl(t1
, t1
, 24);
13995 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13997 case OPC_CMPGDU_LE_QB
:
13999 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
14000 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14001 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
14002 tcg_gen_shli_tl(t1
, t1
, 24);
14003 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14005 case OPC_CMP_EQ_PH
:
14007 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
14009 case OPC_CMP_LT_PH
:
14011 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
14013 case OPC_CMP_LE_PH
:
14015 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
14019 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14023 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14025 case OPC_PACKRL_PH
:
14027 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14031 #ifdef TARGET_MIPS64
14032 case OPC_CMPU_EQ_OB_DSP
:
14034 case OPC_CMP_EQ_PW
:
14036 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
14038 case OPC_CMP_LT_PW
:
14040 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
14042 case OPC_CMP_LE_PW
:
14044 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
14046 case OPC_CMP_EQ_QH
:
14048 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
14050 case OPC_CMP_LT_QH
:
14052 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
14054 case OPC_CMP_LE_QH
:
14056 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
14058 case OPC_CMPGDU_EQ_OB
:
14060 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14062 case OPC_CMPGDU_LT_OB
:
14064 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14066 case OPC_CMPGDU_LE_OB
:
14068 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14070 case OPC_CMPGU_EQ_OB
:
14072 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14074 case OPC_CMPGU_LT_OB
:
14076 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14078 case OPC_CMPGU_LE_OB
:
14080 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14082 case OPC_CMPU_EQ_OB
:
14084 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
14086 case OPC_CMPU_LT_OB
:
14088 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
14090 case OPC_CMPU_LE_OB
:
14092 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
14094 case OPC_PACKRL_PW
:
14096 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14100 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14104 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14108 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14116 tcg_temp_free(v1_t
);
14117 tcg_temp_free(v2_t
);
14119 (void)opn
; /* avoid a compiler warning */
14120 MIPS_DEBUG("%s", opn
);
14123 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14124 uint32_t op1
, int rt
, int rs
, int sa
)
14126 const char *opn
= "mipsdsp append/dappend";
14132 /* Treat as NOP. */
14137 t0
= tcg_temp_new();
14138 gen_load_gpr(t0
, rs
);
14141 case OPC_APPEND_DSP
:
14142 switch (MASK_APPEND(ctx
->opcode
)) {
14145 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14147 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14151 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14152 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14153 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14154 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14156 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14160 if (sa
!= 0 && sa
!= 2) {
14161 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14162 tcg_gen_ext32u_tl(t0
, t0
);
14163 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14164 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14166 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14168 default: /* Invalid */
14169 MIPS_INVAL("MASK APPEND");
14170 generate_exception(ctx
, EXCP_RI
);
14174 #ifdef TARGET_MIPS64
14175 case OPC_DAPPEND_DSP
:
14176 switch (MASK_DAPPEND(ctx
->opcode
)) {
14179 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14183 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14184 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14185 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14189 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14190 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14191 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14196 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14197 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14198 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14199 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14202 default: /* Invalid */
14203 MIPS_INVAL("MASK DAPPEND");
14204 generate_exception(ctx
, EXCP_RI
);
14211 (void)opn
; /* avoid a compiler warning */
14212 MIPS_DEBUG("%s", opn
);
14215 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14216 int ret
, int v1
, int v2
, int check_ret
)
14219 const char *opn
= "mipsdsp accumulator";
14226 if ((ret
== 0) && (check_ret
== 1)) {
14227 /* Treat as NOP. */
14232 t0
= tcg_temp_new();
14233 t1
= tcg_temp_new();
14234 v1_t
= tcg_temp_new();
14235 v2_t
= tcg_temp_new();
14237 gen_load_gpr(v1_t
, v1
);
14238 gen_load_gpr(v2_t
, v2
);
14241 case OPC_EXTR_W_DSP
:
14245 tcg_gen_movi_tl(t0
, v2
);
14246 tcg_gen_movi_tl(t1
, v1
);
14247 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14250 tcg_gen_movi_tl(t0
, v2
);
14251 tcg_gen_movi_tl(t1
, v1
);
14252 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14254 case OPC_EXTR_RS_W
:
14255 tcg_gen_movi_tl(t0
, v2
);
14256 tcg_gen_movi_tl(t1
, v1
);
14257 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14260 tcg_gen_movi_tl(t0
, v2
);
14261 tcg_gen_movi_tl(t1
, v1
);
14262 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14264 case OPC_EXTRV_S_H
:
14265 tcg_gen_movi_tl(t0
, v2
);
14266 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14269 tcg_gen_movi_tl(t0
, v2
);
14270 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14272 case OPC_EXTRV_R_W
:
14273 tcg_gen_movi_tl(t0
, v2
);
14274 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14276 case OPC_EXTRV_RS_W
:
14277 tcg_gen_movi_tl(t0
, v2
);
14278 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14281 tcg_gen_movi_tl(t0
, v2
);
14282 tcg_gen_movi_tl(t1
, v1
);
14283 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14286 tcg_gen_movi_tl(t0
, v2
);
14287 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14290 tcg_gen_movi_tl(t0
, v2
);
14291 tcg_gen_movi_tl(t1
, v1
);
14292 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14295 tcg_gen_movi_tl(t0
, v2
);
14296 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14299 imm
= (ctx
->opcode
>> 20) & 0x3F;
14300 tcg_gen_movi_tl(t0
, ret
);
14301 tcg_gen_movi_tl(t1
, imm
);
14302 gen_helper_shilo(t0
, t1
, cpu_env
);
14305 tcg_gen_movi_tl(t0
, ret
);
14306 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14309 tcg_gen_movi_tl(t0
, ret
);
14310 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14313 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14314 tcg_gen_movi_tl(t0
, imm
);
14315 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14318 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14319 tcg_gen_movi_tl(t0
, imm
);
14320 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14324 #ifdef TARGET_MIPS64
14325 case OPC_DEXTR_W_DSP
:
14329 tcg_gen_movi_tl(t0
, ret
);
14330 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14334 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14335 int ac
= (ctx
->opcode
>> 11) & 0x03;
14336 tcg_gen_movi_tl(t0
, shift
);
14337 tcg_gen_movi_tl(t1
, ac
);
14338 gen_helper_dshilo(t0
, t1
, cpu_env
);
14343 int ac
= (ctx
->opcode
>> 11) & 0x03;
14344 tcg_gen_movi_tl(t0
, ac
);
14345 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14349 tcg_gen_movi_tl(t0
, v2
);
14350 tcg_gen_movi_tl(t1
, v1
);
14352 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14355 tcg_gen_movi_tl(t0
, v2
);
14356 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14359 tcg_gen_movi_tl(t0
, v2
);
14360 tcg_gen_movi_tl(t1
, v1
);
14361 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14364 tcg_gen_movi_tl(t0
, v2
);
14365 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14368 tcg_gen_movi_tl(t0
, v2
);
14369 tcg_gen_movi_tl(t1
, v1
);
14370 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14372 case OPC_DEXTR_R_L
:
14373 tcg_gen_movi_tl(t0
, v2
);
14374 tcg_gen_movi_tl(t1
, v1
);
14375 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14377 case OPC_DEXTR_RS_L
:
14378 tcg_gen_movi_tl(t0
, v2
);
14379 tcg_gen_movi_tl(t1
, v1
);
14380 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14383 tcg_gen_movi_tl(t0
, v2
);
14384 tcg_gen_movi_tl(t1
, v1
);
14385 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14387 case OPC_DEXTR_R_W
:
14388 tcg_gen_movi_tl(t0
, v2
);
14389 tcg_gen_movi_tl(t1
, v1
);
14390 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14392 case OPC_DEXTR_RS_W
:
14393 tcg_gen_movi_tl(t0
, v2
);
14394 tcg_gen_movi_tl(t1
, v1
);
14395 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14397 case OPC_DEXTR_S_H
:
14398 tcg_gen_movi_tl(t0
, v2
);
14399 tcg_gen_movi_tl(t1
, v1
);
14400 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14402 case OPC_DEXTRV_S_H
:
14403 tcg_gen_movi_tl(t0
, v2
);
14404 tcg_gen_movi_tl(t1
, v1
);
14405 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14408 tcg_gen_movi_tl(t0
, v2
);
14409 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14411 case OPC_DEXTRV_R_L
:
14412 tcg_gen_movi_tl(t0
, v2
);
14413 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14415 case OPC_DEXTRV_RS_L
:
14416 tcg_gen_movi_tl(t0
, v2
);
14417 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14420 tcg_gen_movi_tl(t0
, v2
);
14421 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14423 case OPC_DEXTRV_R_W
:
14424 tcg_gen_movi_tl(t0
, v2
);
14425 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14427 case OPC_DEXTRV_RS_W
:
14428 tcg_gen_movi_tl(t0
, v2
);
14429 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14438 tcg_temp_free(v1_t
);
14439 tcg_temp_free(v2_t
);
14441 (void)opn
; /* avoid a compiler warning */
14442 MIPS_DEBUG("%s", opn
);
14445 /* End MIPSDSP functions. */
14447 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
14450 int rs
, rt
, rd
, sa
;
14451 uint32_t op
, op1
, op2
;
14454 /* make sure instructions are on a word boundary */
14455 if (ctx
->pc
& 0x3) {
14456 env
->CP0_BadVAddr
= ctx
->pc
;
14457 generate_exception(ctx
, EXCP_AdEL
);
14461 /* Handle blikely not taken case */
14462 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14463 int l1
= gen_new_label();
14465 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14466 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14467 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14468 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14472 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14473 tcg_gen_debug_insn_start(ctx
->pc
);
14476 op
= MASK_OP_MAJOR(ctx
->opcode
);
14477 rs
= (ctx
->opcode
>> 21) & 0x1f;
14478 rt
= (ctx
->opcode
>> 16) & 0x1f;
14479 rd
= (ctx
->opcode
>> 11) & 0x1f;
14480 sa
= (ctx
->opcode
>> 6) & 0x1f;
14481 imm
= (int16_t)ctx
->opcode
;
14484 op1
= MASK_SPECIAL(ctx
->opcode
);
14486 case OPC_SLL
: /* Shift with immediate */
14488 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14491 switch ((ctx
->opcode
>> 21) & 0x1f) {
14493 /* rotr is decoded as srl on non-R2 CPUs */
14494 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14499 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14502 generate_exception(ctx
, EXCP_RI
);
14506 case OPC_MOVN
: /* Conditional move */
14508 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14509 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14510 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14512 case OPC_ADD
... OPC_SUBU
:
14513 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14515 case OPC_SLLV
: /* Shifts */
14517 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14520 switch ((ctx
->opcode
>> 6) & 0x1f) {
14522 /* rotrv is decoded as srlv on non-R2 CPUs */
14523 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14528 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14531 generate_exception(ctx
, EXCP_RI
);
14535 case OPC_SLT
: /* Set on less than */
14537 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14539 case OPC_AND
: /* Logic*/
14543 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14548 check_insn(ctx
, INSN_VR54XX
);
14549 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14550 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14552 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14557 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14559 case OPC_JR
... OPC_JALR
:
14560 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14562 case OPC_TGE
... OPC_TEQ
: /* Traps */
14564 gen_trap(ctx
, op1
, rs
, rt
, -1);
14566 case OPC_MFHI
: /* Move from HI/LO */
14568 gen_HILO(ctx
, op1
, rs
& 3, rd
);
14571 case OPC_MTLO
: /* Move to HI/LO */
14572 gen_HILO(ctx
, op1
, rd
& 3, rs
);
14574 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14575 #ifdef MIPS_STRICT_STANDARD
14576 MIPS_INVAL("PMON / selsl");
14577 generate_exception(ctx
, EXCP_RI
);
14579 gen_helper_0e0i(pmon
, sa
);
14583 generate_exception(ctx
, EXCP_SYSCALL
);
14584 ctx
->bstate
= BS_STOP
;
14587 generate_exception(ctx
, EXCP_BREAK
);
14590 #ifdef MIPS_STRICT_STANDARD
14591 MIPS_INVAL("SPIM");
14592 generate_exception(ctx
, EXCP_RI
);
14594 /* Implemented as RI exception for now. */
14595 MIPS_INVAL("spim (unofficial)");
14596 generate_exception(ctx
, EXCP_RI
);
14600 /* Treat as NOP. */
14604 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14605 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
14606 check_cp1_enabled(ctx
);
14607 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14608 (ctx
->opcode
>> 16) & 1);
14610 generate_exception_err(ctx
, EXCP_CpU
, 1);
14614 #if defined(TARGET_MIPS64)
14615 /* MIPS64 specific opcodes */
14620 check_insn(ctx
, ISA_MIPS3
);
14621 check_mips_64(ctx
);
14622 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14625 switch ((ctx
->opcode
>> 21) & 0x1f) {
14627 /* drotr is decoded as dsrl on non-R2 CPUs */
14628 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14633 check_insn(ctx
, ISA_MIPS3
);
14634 check_mips_64(ctx
);
14635 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14638 generate_exception(ctx
, EXCP_RI
);
14643 switch ((ctx
->opcode
>> 21) & 0x1f) {
14645 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14646 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14651 check_insn(ctx
, ISA_MIPS3
);
14652 check_mips_64(ctx
);
14653 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14656 generate_exception(ctx
, EXCP_RI
);
14660 case OPC_DADD
... OPC_DSUBU
:
14661 check_insn(ctx
, ISA_MIPS3
);
14662 check_mips_64(ctx
);
14663 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14667 check_insn(ctx
, ISA_MIPS3
);
14668 check_mips_64(ctx
);
14669 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14672 switch ((ctx
->opcode
>> 6) & 0x1f) {
14674 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14675 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14680 check_insn(ctx
, ISA_MIPS3
);
14681 check_mips_64(ctx
);
14682 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14685 generate_exception(ctx
, EXCP_RI
);
14689 case OPC_DMULT
... OPC_DDIVU
:
14690 check_insn(ctx
, ISA_MIPS3
);
14691 check_mips_64(ctx
);
14692 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14695 default: /* Invalid */
14696 MIPS_INVAL("special");
14697 generate_exception(ctx
, EXCP_RI
);
14702 op1
= MASK_SPECIAL2(ctx
->opcode
);
14704 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14705 case OPC_MSUB
... OPC_MSUBU
:
14706 check_insn(ctx
, ISA_MIPS32
);
14707 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14710 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14714 check_insn(ctx
, ISA_MIPS32
);
14715 gen_cl(ctx
, op1
, rd
, rs
);
14718 /* XXX: not clear which exception should be raised
14719 * when in debug mode...
14721 check_insn(ctx
, ISA_MIPS32
);
14722 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14723 generate_exception(ctx
, EXCP_DBp
);
14725 generate_exception(ctx
, EXCP_DBp
);
14727 /* Treat as NOP. */
14730 case OPC_DIVU_G_2F
:
14731 case OPC_MULT_G_2F
:
14732 case OPC_MULTU_G_2F
:
14734 case OPC_MODU_G_2F
:
14735 check_insn(ctx
, INSN_LOONGSON2F
);
14736 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14738 #if defined(TARGET_MIPS64)
14741 check_insn(ctx
, ISA_MIPS64
);
14742 check_mips_64(ctx
);
14743 gen_cl(ctx
, op1
, rd
, rs
);
14745 case OPC_DMULT_G_2F
:
14746 case OPC_DMULTU_G_2F
:
14747 case OPC_DDIV_G_2F
:
14748 case OPC_DDIVU_G_2F
:
14749 case OPC_DMOD_G_2F
:
14750 case OPC_DMODU_G_2F
:
14751 check_insn(ctx
, INSN_LOONGSON2F
);
14752 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14755 default: /* Invalid */
14756 MIPS_INVAL("special2");
14757 generate_exception(ctx
, EXCP_RI
);
14762 op1
= MASK_SPECIAL3(ctx
->opcode
);
14766 check_insn(ctx
, ISA_MIPS32R2
);
14767 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14770 check_insn(ctx
, ISA_MIPS32R2
);
14771 op2
= MASK_BSHFL(ctx
->opcode
);
14772 gen_bshfl(ctx
, op2
, rt
, rd
);
14775 gen_rdhwr(ctx
, rt
, rd
);
14778 check_insn(ctx
, ASE_MT
);
14780 TCGv t0
= tcg_temp_new();
14781 TCGv t1
= tcg_temp_new();
14783 gen_load_gpr(t0
, rt
);
14784 gen_load_gpr(t1
, rs
);
14785 gen_helper_fork(t0
, t1
);
14791 check_insn(ctx
, ASE_MT
);
14793 TCGv t0
= tcg_temp_new();
14795 save_cpu_state(ctx
, 1);
14796 gen_load_gpr(t0
, rs
);
14797 gen_helper_yield(t0
, cpu_env
, t0
);
14798 gen_store_gpr(t0
, rd
);
14802 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14803 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14804 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14805 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14806 * the same mask and op1. */
14807 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14808 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14811 case OPC_ADDUH_R_QB
:
14813 case OPC_ADDQH_R_PH
:
14815 case OPC_ADDQH_R_W
:
14817 case OPC_SUBUH_R_QB
:
14819 case OPC_SUBQH_R_PH
:
14821 case OPC_SUBQH_R_W
:
14822 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14827 case OPC_MULQ_RS_W
:
14828 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14831 MIPS_INVAL("MASK ADDUH.QB");
14832 generate_exception(ctx
, EXCP_RI
);
14835 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14836 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14838 generate_exception(ctx
, EXCP_RI
);
14842 op2
= MASK_LX(ctx
->opcode
);
14844 #if defined(TARGET_MIPS64)
14850 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14852 default: /* Invalid */
14853 MIPS_INVAL("MASK LX");
14854 generate_exception(ctx
, EXCP_RI
);
14858 case OPC_ABSQ_S_PH_DSP
:
14859 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14861 case OPC_ABSQ_S_QB
:
14862 case OPC_ABSQ_S_PH
:
14864 case OPC_PRECEQ_W_PHL
:
14865 case OPC_PRECEQ_W_PHR
:
14866 case OPC_PRECEQU_PH_QBL
:
14867 case OPC_PRECEQU_PH_QBR
:
14868 case OPC_PRECEQU_PH_QBLA
:
14869 case OPC_PRECEQU_PH_QBRA
:
14870 case OPC_PRECEU_PH_QBL
:
14871 case OPC_PRECEU_PH_QBR
:
14872 case OPC_PRECEU_PH_QBLA
:
14873 case OPC_PRECEU_PH_QBRA
:
14874 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14881 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14884 MIPS_INVAL("MASK ABSQ_S.PH");
14885 generate_exception(ctx
, EXCP_RI
);
14889 case OPC_ADDU_QB_DSP
:
14890 op2
= MASK_ADDU_QB(ctx
->opcode
);
14893 case OPC_ADDQ_S_PH
:
14896 case OPC_ADDU_S_QB
:
14898 case OPC_ADDU_S_PH
:
14900 case OPC_SUBQ_S_PH
:
14903 case OPC_SUBU_S_QB
:
14905 case OPC_SUBU_S_PH
:
14909 case OPC_RADDU_W_QB
:
14910 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14912 case OPC_MULEU_S_PH_QBL
:
14913 case OPC_MULEU_S_PH_QBR
:
14914 case OPC_MULQ_RS_PH
:
14915 case OPC_MULEQ_S_W_PHL
:
14916 case OPC_MULEQ_S_W_PHR
:
14917 case OPC_MULQ_S_PH
:
14918 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14920 default: /* Invalid */
14921 MIPS_INVAL("MASK ADDU.QB");
14922 generate_exception(ctx
, EXCP_RI
);
14927 case OPC_CMPU_EQ_QB_DSP
:
14928 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14930 case OPC_PRECR_SRA_PH_W
:
14931 case OPC_PRECR_SRA_R_PH_W
:
14932 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14934 case OPC_PRECR_QB_PH
:
14935 case OPC_PRECRQ_QB_PH
:
14936 case OPC_PRECRQ_PH_W
:
14937 case OPC_PRECRQ_RS_PH_W
:
14938 case OPC_PRECRQU_S_QB_PH
:
14939 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14941 case OPC_CMPU_EQ_QB
:
14942 case OPC_CMPU_LT_QB
:
14943 case OPC_CMPU_LE_QB
:
14944 case OPC_CMP_EQ_PH
:
14945 case OPC_CMP_LT_PH
:
14946 case OPC_CMP_LE_PH
:
14947 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14949 case OPC_CMPGU_EQ_QB
:
14950 case OPC_CMPGU_LT_QB
:
14951 case OPC_CMPGU_LE_QB
:
14952 case OPC_CMPGDU_EQ_QB
:
14953 case OPC_CMPGDU_LT_QB
:
14954 case OPC_CMPGDU_LE_QB
:
14957 case OPC_PACKRL_PH
:
14958 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14960 default: /* Invalid */
14961 MIPS_INVAL("MASK CMPU.EQ.QB");
14962 generate_exception(ctx
, EXCP_RI
);
14966 case OPC_SHLL_QB_DSP
:
14967 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14969 case OPC_DPA_W_PH_DSP
:
14970 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14972 case OPC_DPAU_H_QBL
:
14973 case OPC_DPAU_H_QBR
:
14974 case OPC_DPSU_H_QBL
:
14975 case OPC_DPSU_H_QBR
:
14977 case OPC_DPAX_W_PH
:
14978 case OPC_DPAQ_S_W_PH
:
14979 case OPC_DPAQX_S_W_PH
:
14980 case OPC_DPAQX_SA_W_PH
:
14982 case OPC_DPSX_W_PH
:
14983 case OPC_DPSQ_S_W_PH
:
14984 case OPC_DPSQX_S_W_PH
:
14985 case OPC_DPSQX_SA_W_PH
:
14986 case OPC_MULSAQ_S_W_PH
:
14987 case OPC_DPAQ_SA_L_W
:
14988 case OPC_DPSQ_SA_L_W
:
14989 case OPC_MAQ_S_W_PHL
:
14990 case OPC_MAQ_S_W_PHR
:
14991 case OPC_MAQ_SA_W_PHL
:
14992 case OPC_MAQ_SA_W_PHR
:
14993 case OPC_MULSA_W_PH
:
14994 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14996 default: /* Invalid */
14997 MIPS_INVAL("MASK DPAW.PH");
14998 generate_exception(ctx
, EXCP_RI
);
15003 op2
= MASK_INSV(ctx
->opcode
);
15015 t0
= tcg_temp_new();
15016 t1
= tcg_temp_new();
15018 gen_load_gpr(t0
, rt
);
15019 gen_load_gpr(t1
, rs
);
15021 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15027 default: /* Invalid */
15028 MIPS_INVAL("MASK INSV");
15029 generate_exception(ctx
, EXCP_RI
);
15033 case OPC_APPEND_DSP
:
15034 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15036 case OPC_EXTR_W_DSP
:
15037 op2
= MASK_EXTR_W(ctx
->opcode
);
15041 case OPC_EXTR_RS_W
:
15043 case OPC_EXTRV_S_H
:
15045 case OPC_EXTRV_R_W
:
15046 case OPC_EXTRV_RS_W
:
15051 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15054 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15060 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15062 default: /* Invalid */
15063 MIPS_INVAL("MASK EXTR.W");
15064 generate_exception(ctx
, EXCP_RI
);
15068 #if defined(TARGET_MIPS64)
15069 case OPC_DEXTM
... OPC_DEXT
:
15070 case OPC_DINSM
... OPC_DINS
:
15071 check_insn(ctx
, ISA_MIPS64R2
);
15072 check_mips_64(ctx
);
15073 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
15076 check_insn(ctx
, ISA_MIPS64R2
);
15077 check_mips_64(ctx
);
15078 op2
= MASK_DBSHFL(ctx
->opcode
);
15079 gen_bshfl(ctx
, op2
, rt
, rd
);
15081 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
15082 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
15083 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
15084 check_insn(ctx
, INSN_LOONGSON2E
);
15085 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
15087 case OPC_ABSQ_S_QH_DSP
:
15088 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
15090 case OPC_PRECEQ_L_PWL
:
15091 case OPC_PRECEQ_L_PWR
:
15092 case OPC_PRECEQ_PW_QHL
:
15093 case OPC_PRECEQ_PW_QHR
:
15094 case OPC_PRECEQ_PW_QHLA
:
15095 case OPC_PRECEQ_PW_QHRA
:
15096 case OPC_PRECEQU_QH_OBL
:
15097 case OPC_PRECEQU_QH_OBR
:
15098 case OPC_PRECEQU_QH_OBLA
:
15099 case OPC_PRECEQU_QH_OBRA
:
15100 case OPC_PRECEU_QH_OBL
:
15101 case OPC_PRECEU_QH_OBR
:
15102 case OPC_PRECEU_QH_OBLA
:
15103 case OPC_PRECEU_QH_OBRA
:
15104 case OPC_ABSQ_S_OB
:
15105 case OPC_ABSQ_S_PW
:
15106 case OPC_ABSQ_S_QH
:
15107 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15115 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
15117 default: /* Invalid */
15118 MIPS_INVAL("MASK ABSQ_S.QH");
15119 generate_exception(ctx
, EXCP_RI
);
15123 case OPC_ADDU_OB_DSP
:
15124 op2
= MASK_ADDU_OB(ctx
->opcode
);
15126 case OPC_RADDU_L_OB
:
15128 case OPC_SUBQ_S_PW
:
15130 case OPC_SUBQ_S_QH
:
15132 case OPC_SUBU_S_OB
:
15134 case OPC_SUBU_S_QH
:
15136 case OPC_SUBUH_R_OB
:
15138 case OPC_ADDQ_S_PW
:
15140 case OPC_ADDQ_S_QH
:
15142 case OPC_ADDU_S_OB
:
15144 case OPC_ADDU_S_QH
:
15146 case OPC_ADDUH_R_OB
:
15147 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15149 case OPC_MULEQ_S_PW_QHL
:
15150 case OPC_MULEQ_S_PW_QHR
:
15151 case OPC_MULEU_S_QH_OBL
:
15152 case OPC_MULEU_S_QH_OBR
:
15153 case OPC_MULQ_RS_QH
:
15154 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15156 default: /* Invalid */
15157 MIPS_INVAL("MASK ADDU.OB");
15158 generate_exception(ctx
, EXCP_RI
);
15162 case OPC_CMPU_EQ_OB_DSP
:
15163 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15165 case OPC_PRECR_SRA_QH_PW
:
15166 case OPC_PRECR_SRA_R_QH_PW
:
15167 /* Return value is rt. */
15168 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15170 case OPC_PRECR_OB_QH
:
15171 case OPC_PRECRQ_OB_QH
:
15172 case OPC_PRECRQ_PW_L
:
15173 case OPC_PRECRQ_QH_PW
:
15174 case OPC_PRECRQ_RS_QH_PW
:
15175 case OPC_PRECRQU_S_OB_QH
:
15176 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15178 case OPC_CMPU_EQ_OB
:
15179 case OPC_CMPU_LT_OB
:
15180 case OPC_CMPU_LE_OB
:
15181 case OPC_CMP_EQ_QH
:
15182 case OPC_CMP_LT_QH
:
15183 case OPC_CMP_LE_QH
:
15184 case OPC_CMP_EQ_PW
:
15185 case OPC_CMP_LT_PW
:
15186 case OPC_CMP_LE_PW
:
15187 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15189 case OPC_CMPGDU_EQ_OB
:
15190 case OPC_CMPGDU_LT_OB
:
15191 case OPC_CMPGDU_LE_OB
:
15192 case OPC_CMPGU_EQ_OB
:
15193 case OPC_CMPGU_LT_OB
:
15194 case OPC_CMPGU_LE_OB
:
15195 case OPC_PACKRL_PW
:
15199 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15201 default: /* Invalid */
15202 MIPS_INVAL("MASK CMPU_EQ.OB");
15203 generate_exception(ctx
, EXCP_RI
);
15207 case OPC_DAPPEND_DSP
:
15208 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15210 case OPC_DEXTR_W_DSP
:
15211 op2
= MASK_DEXTR_W(ctx
->opcode
);
15218 case OPC_DEXTR_R_L
:
15219 case OPC_DEXTR_RS_L
:
15221 case OPC_DEXTR_R_W
:
15222 case OPC_DEXTR_RS_W
:
15223 case OPC_DEXTR_S_H
:
15225 case OPC_DEXTRV_R_L
:
15226 case OPC_DEXTRV_RS_L
:
15227 case OPC_DEXTRV_S_H
:
15229 case OPC_DEXTRV_R_W
:
15230 case OPC_DEXTRV_RS_W
:
15231 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15236 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15238 default: /* Invalid */
15239 MIPS_INVAL("MASK EXTR.W");
15240 generate_exception(ctx
, EXCP_RI
);
15244 case OPC_DPAQ_W_QH_DSP
:
15245 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15247 case OPC_DPAU_H_OBL
:
15248 case OPC_DPAU_H_OBR
:
15249 case OPC_DPSU_H_OBL
:
15250 case OPC_DPSU_H_OBR
:
15252 case OPC_DPAQ_S_W_QH
:
15254 case OPC_DPSQ_S_W_QH
:
15255 case OPC_MULSAQ_S_W_QH
:
15256 case OPC_DPAQ_SA_L_PW
:
15257 case OPC_DPSQ_SA_L_PW
:
15258 case OPC_MULSAQ_S_L_PW
:
15259 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15261 case OPC_MAQ_S_W_QHLL
:
15262 case OPC_MAQ_S_W_QHLR
:
15263 case OPC_MAQ_S_W_QHRL
:
15264 case OPC_MAQ_S_W_QHRR
:
15265 case OPC_MAQ_SA_W_QHLL
:
15266 case OPC_MAQ_SA_W_QHLR
:
15267 case OPC_MAQ_SA_W_QHRL
:
15268 case OPC_MAQ_SA_W_QHRR
:
15269 case OPC_MAQ_S_L_PWL
:
15270 case OPC_MAQ_S_L_PWR
:
15275 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15277 default: /* Invalid */
15278 MIPS_INVAL("MASK DPAQ.W.QH");
15279 generate_exception(ctx
, EXCP_RI
);
15283 case OPC_DINSV_DSP
:
15284 op2
= MASK_INSV(ctx
->opcode
);
15296 t0
= tcg_temp_new();
15297 t1
= tcg_temp_new();
15299 gen_load_gpr(t0
, rt
);
15300 gen_load_gpr(t1
, rs
);
15302 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15305 default: /* Invalid */
15306 MIPS_INVAL("MASK DINSV");
15307 generate_exception(ctx
, EXCP_RI
);
15311 case OPC_SHLL_OB_DSP
:
15312 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15315 default: /* Invalid */
15316 MIPS_INVAL("special3");
15317 generate_exception(ctx
, EXCP_RI
);
15322 op1
= MASK_REGIMM(ctx
->opcode
);
15324 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15325 case OPC_BLTZAL
... OPC_BGEZALL
:
15326 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15328 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15330 gen_trap(ctx
, op1
, rs
, -1, imm
);
15333 check_insn(ctx
, ISA_MIPS32R2
);
15334 /* Treat as NOP. */
15336 case OPC_BPOSGE32
: /* MIPS DSP branch */
15337 #if defined(TARGET_MIPS64)
15341 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15343 default: /* Invalid */
15344 MIPS_INVAL("regimm");
15345 generate_exception(ctx
, EXCP_RI
);
15350 check_cp0_enabled(ctx
);
15351 op1
= MASK_CP0(ctx
->opcode
);
15357 #if defined(TARGET_MIPS64)
15361 #ifndef CONFIG_USER_ONLY
15362 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15363 #endif /* !CONFIG_USER_ONLY */
15365 case OPC_C0_FIRST
... OPC_C0_LAST
:
15366 #ifndef CONFIG_USER_ONLY
15367 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15368 #endif /* !CONFIG_USER_ONLY */
15371 #ifndef CONFIG_USER_ONLY
15373 TCGv t0
= tcg_temp_new();
15375 op2
= MASK_MFMC0(ctx
->opcode
);
15378 check_insn(ctx
, ASE_MT
);
15379 gen_helper_dmt(t0
);
15380 gen_store_gpr(t0
, rt
);
15383 check_insn(ctx
, ASE_MT
);
15384 gen_helper_emt(t0
);
15385 gen_store_gpr(t0
, rt
);
15388 check_insn(ctx
, ASE_MT
);
15389 gen_helper_dvpe(t0
, cpu_env
);
15390 gen_store_gpr(t0
, rt
);
15393 check_insn(ctx
, ASE_MT
);
15394 gen_helper_evpe(t0
, cpu_env
);
15395 gen_store_gpr(t0
, rt
);
15398 check_insn(ctx
, ISA_MIPS32R2
);
15399 save_cpu_state(ctx
, 1);
15400 gen_helper_di(t0
, cpu_env
);
15401 gen_store_gpr(t0
, rt
);
15402 /* Stop translation as we may have switched the execution mode */
15403 ctx
->bstate
= BS_STOP
;
15406 check_insn(ctx
, ISA_MIPS32R2
);
15407 save_cpu_state(ctx
, 1);
15408 gen_helper_ei(t0
, cpu_env
);
15409 gen_store_gpr(t0
, rt
);
15410 /* Stop translation as we may have switched the execution mode */
15411 ctx
->bstate
= BS_STOP
;
15413 default: /* Invalid */
15414 MIPS_INVAL("mfmc0");
15415 generate_exception(ctx
, EXCP_RI
);
15420 #endif /* !CONFIG_USER_ONLY */
15423 check_insn(ctx
, ISA_MIPS32R2
);
15424 gen_load_srsgpr(rt
, rd
);
15427 check_insn(ctx
, ISA_MIPS32R2
);
15428 gen_store_srsgpr(rt
, rd
);
15432 generate_exception(ctx
, EXCP_RI
);
15436 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15438 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15440 case OPC_SLTI
: /* Set on less than with immediate opcode */
15442 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15444 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15448 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15450 case OPC_J
... OPC_JAL
: /* Jump */
15451 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15452 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15454 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15455 case OPC_BEQL
... OPC_BGTZL
:
15456 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15458 case OPC_LB
... OPC_LWR
: /* Load and stores */
15460 gen_ld(ctx
, op
, rt
, rs
, imm
);
15462 case OPC_SB
... OPC_SW
:
15464 gen_st(ctx
, op
, rt
, rs
, imm
);
15467 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15470 check_cp0_enabled(ctx
);
15471 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15472 /* Treat as NOP. */
15475 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15476 /* Treat as NOP. */
15479 /* Floating point (COP1). */
15484 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
15488 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15489 check_cp1_enabled(ctx
);
15490 op1
= MASK_CP1(ctx
->opcode
);
15494 check_insn(ctx
, ISA_MIPS32R2
);
15499 gen_cp1(ctx
, op1
, rt
, rd
);
15501 #if defined(TARGET_MIPS64)
15504 check_insn(ctx
, ISA_MIPS3
);
15505 gen_cp1(ctx
, op1
, rt
, rd
);
15511 check_insn(ctx
, ASE_MIPS3D
);
15514 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15515 (rt
>> 2) & 0x7, imm
<< 2);
15522 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15527 generate_exception (ctx
, EXCP_RI
);
15531 generate_exception_err(ctx
, EXCP_CpU
, 1);
15540 /* COP2: Not implemented. */
15541 generate_exception_err(ctx
, EXCP_CpU
, 2);
15544 check_insn(ctx
, INSN_LOONGSON2F
);
15545 /* Note that these instructions use different fields. */
15546 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15550 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15551 check_cp1_enabled(ctx
);
15552 op1
= MASK_CP3(ctx
->opcode
);
15560 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15563 /* Treat as NOP. */
15578 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15582 generate_exception (ctx
, EXCP_RI
);
15586 generate_exception_err(ctx
, EXCP_CpU
, 1);
15590 #if defined(TARGET_MIPS64)
15591 /* MIPS64 opcodes */
15593 case OPC_LDL
... OPC_LDR
:
15596 check_insn(ctx
, ISA_MIPS3
);
15597 check_mips_64(ctx
);
15598 gen_ld(ctx
, op
, rt
, rs
, imm
);
15600 case OPC_SDL
... OPC_SDR
:
15602 check_insn(ctx
, ISA_MIPS3
);
15603 check_mips_64(ctx
);
15604 gen_st(ctx
, op
, rt
, rs
, imm
);
15607 check_insn(ctx
, ISA_MIPS3
);
15608 check_mips_64(ctx
);
15609 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15613 check_insn(ctx
, ISA_MIPS3
);
15614 check_mips_64(ctx
);
15615 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15619 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15620 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15621 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15624 check_insn(ctx
, ASE_MDMX
);
15625 /* MDMX: Not implemented. */
15626 default: /* Invalid */
15627 MIPS_INVAL("major opcode");
15628 generate_exception(ctx
, EXCP_RI
);
15634 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
15637 CPUState
*cs
= CPU(cpu
);
15638 CPUMIPSState
*env
= &cpu
->env
;
15640 target_ulong pc_start
;
15641 uint16_t *gen_opc_end
;
15650 qemu_log("search pc %d\n", search_pc
);
15653 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15656 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
15657 ctx
.insn_flags
= env
->insn_flags
;
15658 ctx
.CP0_Config1
= env
->CP0_Config1
;
15660 ctx
.bstate
= BS_NONE
;
15661 /* Restore delay slot state from the tb context. */
15662 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15663 ctx
.ulri
= env
->CP0_Config3
& (1 << CP0C3_ULRI
);
15664 restore_cpu_state(env
, &ctx
);
15665 #ifdef CONFIG_USER_ONLY
15666 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15668 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15671 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15672 if (max_insns
== 0)
15673 max_insns
= CF_COUNT_MASK
;
15674 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15676 while (ctx
.bstate
== BS_NONE
) {
15677 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
15678 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
15679 if (bp
->pc
== ctx
.pc
) {
15680 save_cpu_state(&ctx
, 1);
15681 ctx
.bstate
= BS_BRANCH
;
15682 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15683 /* Include the breakpoint location or the tb won't
15684 * be flushed when it must be. */
15686 goto done_generating
;
15692 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15696 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15698 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15699 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15700 gen_opc_btarget
[lj
] = ctx
.btarget
;
15701 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15702 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15704 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15707 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
15708 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15709 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15711 decode_opc(env
, &ctx
);
15712 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15713 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15714 insn_bytes
= decode_micromips_opc(env
, &ctx
);
15715 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15716 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15717 insn_bytes
= decode_mips16_opc(env
, &ctx
);
15719 generate_exception(&ctx
, EXCP_RI
);
15720 ctx
.bstate
= BS_STOP
;
15724 handle_delay_slot(&ctx
, insn_bytes
);
15726 ctx
.pc
+= insn_bytes
;
15730 /* Execute a branch and its delay slot as a single instruction.
15731 This is what GDB expects and is consistent with what the
15732 hardware does (e.g. if a delay slot instruction faults, the
15733 reported PC is the PC of the branch). */
15734 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
15738 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15741 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15745 if (num_insns
>= max_insns
)
15751 if (tb
->cflags
& CF_LAST_IO
) {
15754 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15755 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15756 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15758 switch (ctx
.bstate
) {
15760 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15763 save_cpu_state(&ctx
, 0);
15764 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15767 tcg_gen_exit_tb(0);
15775 gen_tb_end(tb
, num_insns
);
15776 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15778 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15781 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15783 tb
->size
= ctx
.pc
- pc_start
;
15784 tb
->icount
= num_insns
;
15788 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15789 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15790 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15796 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15798 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
15801 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15803 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
15806 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15810 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15812 #define printfpr(fp) \
15815 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15816 " fd:%13g fs:%13g psu: %13g\n", \
15817 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15818 (double)(fp)->fd, \
15819 (double)(fp)->fs[FP_ENDIAN_IDX], \
15820 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15823 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15824 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15825 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15826 " fd:%13g fs:%13g psu:%13g\n", \
15827 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15829 (double)tmp.fs[FP_ENDIAN_IDX], \
15830 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15835 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15836 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15837 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15838 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15839 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15840 printfpr(&env
->active_fpu
.fpr
[i
]);
15846 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15847 /* Debug help: The architecture requires 32bit code to maintain proper
15848 sign-extended values on 64bit machines. */
15850 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15853 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15854 fprintf_function cpu_fprintf
,
15859 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15860 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15861 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15862 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15863 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15864 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15865 if (!SIGN_EXT_P(env
->btarget
))
15866 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15868 for (i
= 0; i
< 32; i
++) {
15869 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15870 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15873 if (!SIGN_EXT_P(env
->CP0_EPC
))
15874 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15875 if (!SIGN_EXT_P(env
->lladdr
))
15876 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15880 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
15883 MIPSCPU
*cpu
= MIPS_CPU(cs
);
15884 CPUMIPSState
*env
= &cpu
->env
;
15887 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15888 " LO=0x" TARGET_FMT_lx
" ds %04x "
15889 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15890 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15891 env
->hflags
, env
->btarget
, env
->bcond
);
15892 for (i
= 0; i
< 32; i
++) {
15894 cpu_fprintf(f
, "GPR%02d:", i
);
15895 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15897 cpu_fprintf(f
, "\n");
15900 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15901 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15902 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15903 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15904 if (env
->hflags
& MIPS_HFLAG_FPU
)
15905 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15906 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15907 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15911 void mips_tcg_init(void)
15916 /* Initialize various static tables. */
15920 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15921 TCGV_UNUSED(cpu_gpr
[0]);
15922 for (i
= 1; i
< 32; i
++)
15923 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15924 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15927 for (i
= 0; i
< 32; i
++) {
15928 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15929 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15932 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15933 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15934 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15935 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15936 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15938 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15939 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15941 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15942 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15945 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15946 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15948 bcond
= tcg_global_mem_new(TCG_AREG0
,
15949 offsetof(CPUMIPSState
, bcond
), "bcond");
15950 btarget
= tcg_global_mem_new(TCG_AREG0
,
15951 offsetof(CPUMIPSState
, btarget
), "btarget");
15952 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15953 offsetof(CPUMIPSState
, hflags
), "hflags");
15955 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15956 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15958 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15959 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15965 #include "translate_init.c"
15967 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15971 const mips_def_t
*def
;
15973 def
= cpu_mips_find_by_name(cpu_model
);
15976 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15978 env
->cpu_model
= def
;
15980 #ifndef CONFIG_USER_ONLY
15981 mmu_init(env
, def
);
15983 fpu_init(env
, def
);
15984 mvp_init(env
, def
);
15986 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15991 void cpu_state_reset(CPUMIPSState
*env
)
15993 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
15994 CPUState
*cs
= CPU(cpu
);
15996 /* Reset registers to their default values */
15997 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
15998 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
15999 #ifdef TARGET_WORDS_BIGENDIAN
16000 env
->CP0_Config0
|= (1 << CP0C0_BE
);
16002 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
16003 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
16004 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
16005 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
16006 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
16007 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
16008 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
16009 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
16010 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
16011 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
16012 << env
->cpu_model
->CP0_LLAddr_shift
;
16013 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
16014 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
16015 env
->CCRes
= env
->cpu_model
->CCRes
;
16016 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
16017 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
16018 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
16019 env
->current_tc
= 0;
16020 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
16021 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
16022 #if defined(TARGET_MIPS64)
16023 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
16024 env
->SEGMask
|= 3ULL << 62;
16027 env
->PABITS
= env
->cpu_model
->PABITS
;
16028 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
16029 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
16030 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
16031 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
16032 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
16033 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
16034 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
16035 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
16036 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
16037 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
16038 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
16039 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
16040 env
->insn_flags
= env
->cpu_model
->insn_flags
;
16042 #if defined(CONFIG_USER_ONLY)
16043 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
16044 # ifdef TARGET_MIPS64
16045 /* Enable 64-bit register mode. */
16046 env
->CP0_Status
|= (1 << CP0St_PX
);
16048 # ifdef TARGET_ABI_MIPSN64
16049 /* Enable 64-bit address mode. */
16050 env
->CP0_Status
|= (1 << CP0St_UX
);
16052 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16053 hardware registers. */
16054 env
->CP0_HWREna
|= 0x0000000F;
16055 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16056 env
->CP0_Status
|= (1 << CP0St_CU1
);
16058 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
16059 env
->CP0_Status
|= (1 << CP0St_MX
);
16061 # if defined(TARGET_MIPS64)
16062 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16063 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
16064 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
16065 env
->CP0_Status
|= (1 << CP0St_FR
);
16069 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
16070 /* If the exception was raised from a delay slot,
16071 come back to the jump. */
16072 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
16074 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
16076 env
->active_tc
.PC
= (int32_t)0xBFC00000;
16077 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
16078 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
16079 env
->CP0_Wired
= 0;
16080 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
16081 if (kvm_enabled()) {
16082 env
->CP0_EBase
|= 0x40000000;
16084 env
->CP0_EBase
|= 0x80000000;
16086 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
16087 /* vectored interrupts not implemented, timer on int 7,
16088 no performance counters. */
16089 env
->CP0_IntCtl
= 0xe0000000;
16093 for (i
= 0; i
< 7; i
++) {
16094 env
->CP0_WatchLo
[i
] = 0;
16095 env
->CP0_WatchHi
[i
] = 0x80000000;
16097 env
->CP0_WatchLo
[7] = 0;
16098 env
->CP0_WatchHi
[7] = 0;
16100 /* Count register increments in debug mode, EJTAG version 1 */
16101 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
16103 cpu_mips_store_count(env
, 1);
16105 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
16108 /* Only TC0 on VPE 0 starts as active. */
16109 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
16110 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
16111 env
->tcs
[i
].CP0_TCHalt
= 1;
16113 env
->active_tc
.CP0_TCHalt
= 1;
16116 if (cs
->cpu_index
== 0) {
16117 /* VPE0 starts up enabled. */
16118 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
16119 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
16121 /* TC0 starts up unhalted. */
16123 env
->active_tc
.CP0_TCHalt
= 0;
16124 env
->tcs
[0].CP0_TCHalt
= 0;
16125 /* With thread 0 active. */
16126 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
16127 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16131 compute_hflags(env
);
16132 cs
->exception_index
= EXCP_NONE
;
16135 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16137 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16138 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16139 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16140 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16141 case MIPS_HFLAG_BR
:
16143 case MIPS_HFLAG_BC
:
16144 case MIPS_HFLAG_BL
:
16146 env
->btarget
= gen_opc_btarget
[pc_pos
];