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 #include "trace-tcg.h"
36 #define MIPS_DEBUG_DISAS 0
37 //#define MIPS_DEBUG_SIGN_EXTENSIONS
39 /* MIPS major opcodes */
40 #define MASK_OP_MAJOR(op) (op & (0x3F << 26))
43 /* indirect opcode tables */
44 OPC_SPECIAL
= (0x00 << 26),
45 OPC_REGIMM
= (0x01 << 26),
46 OPC_CP0
= (0x10 << 26),
47 OPC_CP1
= (0x11 << 26),
48 OPC_CP2
= (0x12 << 26),
49 OPC_CP3
= (0x13 << 26),
50 OPC_SPECIAL2
= (0x1C << 26),
51 OPC_SPECIAL3
= (0x1F << 26),
52 /* arithmetic with immediate */
53 OPC_ADDI
= (0x08 << 26),
54 OPC_ADDIU
= (0x09 << 26),
55 OPC_SLTI
= (0x0A << 26),
56 OPC_SLTIU
= (0x0B << 26),
57 /* logic with immediate */
58 OPC_ANDI
= (0x0C << 26),
59 OPC_ORI
= (0x0D << 26),
60 OPC_XORI
= (0x0E << 26),
61 OPC_LUI
= (0x0F << 26),
62 /* arithmetic with immediate */
63 OPC_DADDI
= (0x18 << 26),
64 OPC_DADDIU
= (0x19 << 26),
65 /* Jump and branches */
67 OPC_JAL
= (0x03 << 26),
68 OPC_JALS
= OPC_JAL
| 0x5,
69 OPC_BEQ
= (0x04 << 26), /* Unconditional if rs = rt = 0 (B) */
70 OPC_BEQL
= (0x14 << 26),
71 OPC_BNE
= (0x05 << 26),
72 OPC_BNEL
= (0x15 << 26),
73 OPC_BLEZ
= (0x06 << 26),
74 OPC_BLEZL
= (0x16 << 26),
75 OPC_BGTZ
= (0x07 << 26),
76 OPC_BGTZL
= (0x17 << 26),
77 OPC_JALX
= (0x1D << 26), /* MIPS 16 only */
78 OPC_JALXS
= OPC_JALX
| 0x5,
80 OPC_LDL
= (0x1A << 26),
81 OPC_LDR
= (0x1B << 26),
82 OPC_LB
= (0x20 << 26),
83 OPC_LH
= (0x21 << 26),
84 OPC_LWL
= (0x22 << 26),
85 OPC_LW
= (0x23 << 26),
86 OPC_LWPC
= OPC_LW
| 0x5,
87 OPC_LBU
= (0x24 << 26),
88 OPC_LHU
= (0x25 << 26),
89 OPC_LWR
= (0x26 << 26),
90 OPC_LWU
= (0x27 << 26),
91 OPC_SB
= (0x28 << 26),
92 OPC_SH
= (0x29 << 26),
93 OPC_SWL
= (0x2A << 26),
94 OPC_SW
= (0x2B << 26),
95 OPC_SDL
= (0x2C << 26),
96 OPC_SDR
= (0x2D << 26),
97 OPC_SWR
= (0x2E << 26),
98 OPC_LL
= (0x30 << 26),
99 OPC_LLD
= (0x34 << 26),
100 OPC_LD
= (0x37 << 26),
101 OPC_LDPC
= OPC_LD
| 0x5,
102 OPC_SC
= (0x38 << 26),
103 OPC_SCD
= (0x3C << 26),
104 OPC_SD
= (0x3F << 26),
105 /* Floating point load/store */
106 OPC_LWC1
= (0x31 << 26),
107 OPC_LWC2
= (0x32 << 26),
108 OPC_LDC1
= (0x35 << 26),
109 OPC_LDC2
= (0x36 << 26),
110 OPC_SWC1
= (0x39 << 26),
111 OPC_SWC2
= (0x3A << 26),
112 OPC_SDC1
= (0x3D << 26),
113 OPC_SDC2
= (0x3E << 26),
114 /* MDMX ASE specific */
115 OPC_MDMX
= (0x1E << 26),
116 /* Cache and prefetch */
117 OPC_CACHE
= (0x2F << 26),
118 OPC_PREF
= (0x33 << 26),
119 /* Reserved major opcode */
120 OPC_MAJOR3B_RESERVED
= (0x3B << 26),
123 /* MIPS special opcodes */
124 #define MASK_SPECIAL(op) MASK_OP_MAJOR(op) | (op & 0x3F)
128 OPC_SLL
= 0x00 | OPC_SPECIAL
,
129 /* NOP is SLL r0, r0, 0 */
130 /* SSNOP is SLL r0, r0, 1 */
131 /* EHB is SLL r0, r0, 3 */
132 OPC_SRL
= 0x02 | OPC_SPECIAL
, /* also ROTR */
133 OPC_ROTR
= OPC_SRL
| (1 << 21),
134 OPC_SRA
= 0x03 | OPC_SPECIAL
,
135 OPC_SLLV
= 0x04 | OPC_SPECIAL
,
136 OPC_SRLV
= 0x06 | OPC_SPECIAL
, /* also ROTRV */
137 OPC_ROTRV
= OPC_SRLV
| (1 << 6),
138 OPC_SRAV
= 0x07 | OPC_SPECIAL
,
139 OPC_DSLLV
= 0x14 | OPC_SPECIAL
,
140 OPC_DSRLV
= 0x16 | OPC_SPECIAL
, /* also DROTRV */
141 OPC_DROTRV
= OPC_DSRLV
| (1 << 6),
142 OPC_DSRAV
= 0x17 | OPC_SPECIAL
,
143 OPC_DSLL
= 0x38 | OPC_SPECIAL
,
144 OPC_DSRL
= 0x3A | OPC_SPECIAL
, /* also DROTR */
145 OPC_DROTR
= OPC_DSRL
| (1 << 21),
146 OPC_DSRA
= 0x3B | OPC_SPECIAL
,
147 OPC_DSLL32
= 0x3C | OPC_SPECIAL
,
148 OPC_DSRL32
= 0x3E | OPC_SPECIAL
, /* also DROTR32 */
149 OPC_DROTR32
= OPC_DSRL32
| (1 << 21),
150 OPC_DSRA32
= 0x3F | OPC_SPECIAL
,
151 /* Multiplication / division */
152 OPC_MULT
= 0x18 | OPC_SPECIAL
,
153 OPC_MULTU
= 0x19 | OPC_SPECIAL
,
154 OPC_DIV
= 0x1A | OPC_SPECIAL
,
155 OPC_DIVU
= 0x1B | OPC_SPECIAL
,
156 OPC_DMULT
= 0x1C | OPC_SPECIAL
,
157 OPC_DMULTU
= 0x1D | OPC_SPECIAL
,
158 OPC_DDIV
= 0x1E | OPC_SPECIAL
,
159 OPC_DDIVU
= 0x1F | OPC_SPECIAL
,
160 /* 2 registers arithmetic / logic */
161 OPC_ADD
= 0x20 | OPC_SPECIAL
,
162 OPC_ADDU
= 0x21 | OPC_SPECIAL
,
163 OPC_SUB
= 0x22 | OPC_SPECIAL
,
164 OPC_SUBU
= 0x23 | OPC_SPECIAL
,
165 OPC_AND
= 0x24 | OPC_SPECIAL
,
166 OPC_OR
= 0x25 | OPC_SPECIAL
,
167 OPC_XOR
= 0x26 | OPC_SPECIAL
,
168 OPC_NOR
= 0x27 | OPC_SPECIAL
,
169 OPC_SLT
= 0x2A | OPC_SPECIAL
,
170 OPC_SLTU
= 0x2B | OPC_SPECIAL
,
171 OPC_DADD
= 0x2C | OPC_SPECIAL
,
172 OPC_DADDU
= 0x2D | OPC_SPECIAL
,
173 OPC_DSUB
= 0x2E | OPC_SPECIAL
,
174 OPC_DSUBU
= 0x2F | OPC_SPECIAL
,
176 OPC_JR
= 0x08 | OPC_SPECIAL
, /* Also JR.HB */
177 OPC_JALR
= 0x09 | OPC_SPECIAL
, /* Also JALR.HB */
178 OPC_JALRC
= OPC_JALR
| (0x5 << 6),
179 OPC_JALRS
= 0x10 | OPC_SPECIAL
| (0x5 << 6),
181 OPC_TGE
= 0x30 | OPC_SPECIAL
,
182 OPC_TGEU
= 0x31 | OPC_SPECIAL
,
183 OPC_TLT
= 0x32 | OPC_SPECIAL
,
184 OPC_TLTU
= 0x33 | OPC_SPECIAL
,
185 OPC_TEQ
= 0x34 | OPC_SPECIAL
,
186 OPC_TNE
= 0x36 | OPC_SPECIAL
,
187 /* HI / LO registers load & stores */
188 OPC_MFHI
= 0x10 | OPC_SPECIAL
,
189 OPC_MTHI
= 0x11 | OPC_SPECIAL
,
190 OPC_MFLO
= 0x12 | OPC_SPECIAL
,
191 OPC_MTLO
= 0x13 | OPC_SPECIAL
,
192 /* Conditional moves */
193 OPC_MOVZ
= 0x0A | OPC_SPECIAL
,
194 OPC_MOVN
= 0x0B | OPC_SPECIAL
,
196 OPC_MOVCI
= 0x01 | OPC_SPECIAL
,
199 OPC_PMON
= 0x05 | OPC_SPECIAL
, /* unofficial */
200 OPC_SYSCALL
= 0x0C | OPC_SPECIAL
,
201 OPC_BREAK
= 0x0D | OPC_SPECIAL
,
202 OPC_SPIM
= 0x0E | OPC_SPECIAL
, /* unofficial */
203 OPC_SYNC
= 0x0F | OPC_SPECIAL
,
205 OPC_SPECIAL15_RESERVED
= 0x15 | OPC_SPECIAL
,
206 OPC_SPECIAL28_RESERVED
= 0x28 | OPC_SPECIAL
,
207 OPC_SPECIAL29_RESERVED
= 0x29 | OPC_SPECIAL
,
208 OPC_SPECIAL35_RESERVED
= 0x35 | OPC_SPECIAL
,
209 OPC_SPECIAL37_RESERVED
= 0x37 | OPC_SPECIAL
,
210 OPC_SPECIAL39_RESERVED
= 0x39 | OPC_SPECIAL
,
211 OPC_SPECIAL3D_RESERVED
= 0x3D | OPC_SPECIAL
,
214 /* Multiplication variants of the vr54xx. */
215 #define MASK_MUL_VR54XX(op) MASK_SPECIAL(op) | (op & (0x1F << 6))
218 OPC_VR54XX_MULS
= (0x03 << 6) | OPC_MULT
,
219 OPC_VR54XX_MULSU
= (0x03 << 6) | OPC_MULTU
,
220 OPC_VR54XX_MACC
= (0x05 << 6) | OPC_MULT
,
221 OPC_VR54XX_MACCU
= (0x05 << 6) | OPC_MULTU
,
222 OPC_VR54XX_MSAC
= (0x07 << 6) | OPC_MULT
,
223 OPC_VR54XX_MSACU
= (0x07 << 6) | OPC_MULTU
,
224 OPC_VR54XX_MULHI
= (0x09 << 6) | OPC_MULT
,
225 OPC_VR54XX_MULHIU
= (0x09 << 6) | OPC_MULTU
,
226 OPC_VR54XX_MULSHI
= (0x0B << 6) | OPC_MULT
,
227 OPC_VR54XX_MULSHIU
= (0x0B << 6) | OPC_MULTU
,
228 OPC_VR54XX_MACCHI
= (0x0D << 6) | OPC_MULT
,
229 OPC_VR54XX_MACCHIU
= (0x0D << 6) | OPC_MULTU
,
230 OPC_VR54XX_MSACHI
= (0x0F << 6) | OPC_MULT
,
231 OPC_VR54XX_MSACHIU
= (0x0F << 6) | OPC_MULTU
,
234 /* REGIMM (rt field) opcodes */
235 #define MASK_REGIMM(op) MASK_OP_MAJOR(op) | (op & (0x1F << 16))
238 OPC_BLTZ
= (0x00 << 16) | OPC_REGIMM
,
239 OPC_BLTZL
= (0x02 << 16) | OPC_REGIMM
,
240 OPC_BGEZ
= (0x01 << 16) | OPC_REGIMM
,
241 OPC_BGEZL
= (0x03 << 16) | OPC_REGIMM
,
242 OPC_BLTZAL
= (0x10 << 16) | OPC_REGIMM
,
243 OPC_BLTZALS
= OPC_BLTZAL
| 0x5, /* microMIPS */
244 OPC_BLTZALL
= (0x12 << 16) | OPC_REGIMM
,
245 OPC_BGEZAL
= (0x11 << 16) | OPC_REGIMM
,
246 OPC_BGEZALS
= OPC_BGEZAL
| 0x5, /* microMIPS */
247 OPC_BGEZALL
= (0x13 << 16) | OPC_REGIMM
,
248 OPC_TGEI
= (0x08 << 16) | OPC_REGIMM
,
249 OPC_TGEIU
= (0x09 << 16) | OPC_REGIMM
,
250 OPC_TLTI
= (0x0A << 16) | OPC_REGIMM
,
251 OPC_TLTIU
= (0x0B << 16) | OPC_REGIMM
,
252 OPC_TEQI
= (0x0C << 16) | OPC_REGIMM
,
253 OPC_TNEI
= (0x0E << 16) | OPC_REGIMM
,
254 OPC_SYNCI
= (0x1F << 16) | OPC_REGIMM
,
257 /* Special2 opcodes */
258 #define MASK_SPECIAL2(op) MASK_OP_MAJOR(op) | (op & 0x3F)
261 /* Multiply & xxx operations */
262 OPC_MADD
= 0x00 | OPC_SPECIAL2
,
263 OPC_MADDU
= 0x01 | OPC_SPECIAL2
,
264 OPC_MUL
= 0x02 | OPC_SPECIAL2
,
265 OPC_MSUB
= 0x04 | OPC_SPECIAL2
,
266 OPC_MSUBU
= 0x05 | OPC_SPECIAL2
,
268 OPC_MULT_G_2F
= 0x10 | OPC_SPECIAL2
,
269 OPC_DMULT_G_2F
= 0x11 | OPC_SPECIAL2
,
270 OPC_MULTU_G_2F
= 0x12 | OPC_SPECIAL2
,
271 OPC_DMULTU_G_2F
= 0x13 | OPC_SPECIAL2
,
272 OPC_DIV_G_2F
= 0x14 | OPC_SPECIAL2
,
273 OPC_DDIV_G_2F
= 0x15 | OPC_SPECIAL2
,
274 OPC_DIVU_G_2F
= 0x16 | OPC_SPECIAL2
,
275 OPC_DDIVU_G_2F
= 0x17 | OPC_SPECIAL2
,
276 OPC_MOD_G_2F
= 0x1c | OPC_SPECIAL2
,
277 OPC_DMOD_G_2F
= 0x1d | OPC_SPECIAL2
,
278 OPC_MODU_G_2F
= 0x1e | OPC_SPECIAL2
,
279 OPC_DMODU_G_2F
= 0x1f | OPC_SPECIAL2
,
281 OPC_CLZ
= 0x20 | OPC_SPECIAL2
,
282 OPC_CLO
= 0x21 | OPC_SPECIAL2
,
283 OPC_DCLZ
= 0x24 | OPC_SPECIAL2
,
284 OPC_DCLO
= 0x25 | OPC_SPECIAL2
,
286 OPC_SDBBP
= 0x3F | OPC_SPECIAL2
,
289 /* Special3 opcodes */
290 #define MASK_SPECIAL3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
293 OPC_EXT
= 0x00 | OPC_SPECIAL3
,
294 OPC_DEXTM
= 0x01 | OPC_SPECIAL3
,
295 OPC_DEXTU
= 0x02 | OPC_SPECIAL3
,
296 OPC_DEXT
= 0x03 | OPC_SPECIAL3
,
297 OPC_INS
= 0x04 | OPC_SPECIAL3
,
298 OPC_DINSM
= 0x05 | OPC_SPECIAL3
,
299 OPC_DINSU
= 0x06 | OPC_SPECIAL3
,
300 OPC_DINS
= 0x07 | OPC_SPECIAL3
,
301 OPC_FORK
= 0x08 | OPC_SPECIAL3
,
302 OPC_YIELD
= 0x09 | OPC_SPECIAL3
,
303 OPC_BSHFL
= 0x20 | OPC_SPECIAL3
,
304 OPC_DBSHFL
= 0x24 | OPC_SPECIAL3
,
305 OPC_RDHWR
= 0x3B | OPC_SPECIAL3
,
308 OPC_MULT_G_2E
= 0x18 | OPC_SPECIAL3
,
309 OPC_MULTU_G_2E
= 0x19 | OPC_SPECIAL3
,
310 OPC_DIV_G_2E
= 0x1A | OPC_SPECIAL3
,
311 OPC_DIVU_G_2E
= 0x1B | OPC_SPECIAL3
,
312 OPC_DMULT_G_2E
= 0x1C | OPC_SPECIAL3
,
313 OPC_DMULTU_G_2E
= 0x1D | OPC_SPECIAL3
,
314 OPC_DDIV_G_2E
= 0x1E | OPC_SPECIAL3
,
315 OPC_DDIVU_G_2E
= 0x1F | OPC_SPECIAL3
,
316 OPC_MOD_G_2E
= 0x22 | OPC_SPECIAL3
,
317 OPC_MODU_G_2E
= 0x23 | OPC_SPECIAL3
,
318 OPC_DMOD_G_2E
= 0x26 | OPC_SPECIAL3
,
319 OPC_DMODU_G_2E
= 0x27 | OPC_SPECIAL3
,
322 OPC_LX_DSP
= 0x0A | OPC_SPECIAL3
,
323 /* MIPS DSP Arithmetic */
324 OPC_ADDU_QB_DSP
= 0x10 | OPC_SPECIAL3
,
325 OPC_ADDU_OB_DSP
= 0x14 | OPC_SPECIAL3
,
326 OPC_ABSQ_S_PH_DSP
= 0x12 | OPC_SPECIAL3
,
327 OPC_ABSQ_S_QH_DSP
= 0x16 | OPC_SPECIAL3
,
328 /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E. */
329 /* OPC_ADDUH_QB_DSP = 0x18 | OPC_SPECIAL3, */
330 OPC_CMPU_EQ_QB_DSP
= 0x11 | OPC_SPECIAL3
,
331 OPC_CMPU_EQ_OB_DSP
= 0x15 | OPC_SPECIAL3
,
332 /* MIPS DSP GPR-Based Shift Sub-class */
333 OPC_SHLL_QB_DSP
= 0x13 | OPC_SPECIAL3
,
334 OPC_SHLL_OB_DSP
= 0x17 | OPC_SPECIAL3
,
335 /* MIPS DSP Multiply Sub-class insns */
336 /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP. */
337 /* OPC_MUL_PH_DSP = 0x18 | OPC_SPECIAL3, */
338 OPC_DPA_W_PH_DSP
= 0x30 | OPC_SPECIAL3
,
339 OPC_DPAQ_W_QH_DSP
= 0x34 | OPC_SPECIAL3
,
340 /* DSP Bit/Manipulation Sub-class */
341 OPC_INSV_DSP
= 0x0C | OPC_SPECIAL3
,
342 OPC_DINSV_DSP
= 0x0D | OPC_SPECIAL3
,
343 /* MIPS DSP Append Sub-class */
344 OPC_APPEND_DSP
= 0x31 | OPC_SPECIAL3
,
345 OPC_DAPPEND_DSP
= 0x35 | OPC_SPECIAL3
,
346 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
347 OPC_EXTR_W_DSP
= 0x38 | OPC_SPECIAL3
,
348 OPC_DEXTR_W_DSP
= 0x3C | OPC_SPECIAL3
,
352 #define MASK_BSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
355 OPC_WSBH
= (0x02 << 6) | OPC_BSHFL
,
356 OPC_SEB
= (0x10 << 6) | OPC_BSHFL
,
357 OPC_SEH
= (0x18 << 6) | OPC_BSHFL
,
361 #define MASK_DBSHFL(op) MASK_SPECIAL3(op) | (op & (0x1F << 6))
364 OPC_DSBH
= (0x02 << 6) | OPC_DBSHFL
,
365 OPC_DSHD
= (0x05 << 6) | OPC_DBSHFL
,
368 /* MIPS DSP REGIMM opcodes */
370 OPC_BPOSGE32
= (0x1C << 16) | OPC_REGIMM
,
371 OPC_BPOSGE64
= (0x1D << 16) | OPC_REGIMM
,
374 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
377 OPC_LBUX
= (0x06 << 6) | OPC_LX_DSP
,
378 OPC_LHX
= (0x04 << 6) | OPC_LX_DSP
,
379 OPC_LWX
= (0x00 << 6) | OPC_LX_DSP
,
380 OPC_LDX
= (0x08 << 6) | OPC_LX_DSP
,
383 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
385 /* MIPS DSP Arithmetic Sub-class */
386 OPC_ADDQ_PH
= (0x0A << 6) | OPC_ADDU_QB_DSP
,
387 OPC_ADDQ_S_PH
= (0x0E << 6) | OPC_ADDU_QB_DSP
,
388 OPC_ADDQ_S_W
= (0x16 << 6) | OPC_ADDU_QB_DSP
,
389 OPC_ADDU_QB
= (0x00 << 6) | OPC_ADDU_QB_DSP
,
390 OPC_ADDU_S_QB
= (0x04 << 6) | OPC_ADDU_QB_DSP
,
391 OPC_ADDU_PH
= (0x08 << 6) | OPC_ADDU_QB_DSP
,
392 OPC_ADDU_S_PH
= (0x0C << 6) | OPC_ADDU_QB_DSP
,
393 OPC_SUBQ_PH
= (0x0B << 6) | OPC_ADDU_QB_DSP
,
394 OPC_SUBQ_S_PH
= (0x0F << 6) | OPC_ADDU_QB_DSP
,
395 OPC_SUBQ_S_W
= (0x17 << 6) | OPC_ADDU_QB_DSP
,
396 OPC_SUBU_QB
= (0x01 << 6) | OPC_ADDU_QB_DSP
,
397 OPC_SUBU_S_QB
= (0x05 << 6) | OPC_ADDU_QB_DSP
,
398 OPC_SUBU_PH
= (0x09 << 6) | OPC_ADDU_QB_DSP
,
399 OPC_SUBU_S_PH
= (0x0D << 6) | OPC_ADDU_QB_DSP
,
400 OPC_ADDSC
= (0x10 << 6) | OPC_ADDU_QB_DSP
,
401 OPC_ADDWC
= (0x11 << 6) | OPC_ADDU_QB_DSP
,
402 OPC_MODSUB
= (0x12 << 6) | OPC_ADDU_QB_DSP
,
403 OPC_RADDU_W_QB
= (0x14 << 6) | OPC_ADDU_QB_DSP
,
404 /* MIPS DSP Multiply Sub-class insns */
405 OPC_MULEU_S_PH_QBL
= (0x06 << 6) | OPC_ADDU_QB_DSP
,
406 OPC_MULEU_S_PH_QBR
= (0x07 << 6) | OPC_ADDU_QB_DSP
,
407 OPC_MULQ_RS_PH
= (0x1F << 6) | OPC_ADDU_QB_DSP
,
408 OPC_MULEQ_S_W_PHL
= (0x1C << 6) | OPC_ADDU_QB_DSP
,
409 OPC_MULEQ_S_W_PHR
= (0x1D << 6) | OPC_ADDU_QB_DSP
,
410 OPC_MULQ_S_PH
= (0x1E << 6) | OPC_ADDU_QB_DSP
,
413 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
414 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
416 /* MIPS DSP Arithmetic Sub-class */
417 OPC_ADDUH_QB
= (0x00 << 6) | OPC_ADDUH_QB_DSP
,
418 OPC_ADDUH_R_QB
= (0x02 << 6) | OPC_ADDUH_QB_DSP
,
419 OPC_ADDQH_PH
= (0x08 << 6) | OPC_ADDUH_QB_DSP
,
420 OPC_ADDQH_R_PH
= (0x0A << 6) | OPC_ADDUH_QB_DSP
,
421 OPC_ADDQH_W
= (0x10 << 6) | OPC_ADDUH_QB_DSP
,
422 OPC_ADDQH_R_W
= (0x12 << 6) | OPC_ADDUH_QB_DSP
,
423 OPC_SUBUH_QB
= (0x01 << 6) | OPC_ADDUH_QB_DSP
,
424 OPC_SUBUH_R_QB
= (0x03 << 6) | OPC_ADDUH_QB_DSP
,
425 OPC_SUBQH_PH
= (0x09 << 6) | OPC_ADDUH_QB_DSP
,
426 OPC_SUBQH_R_PH
= (0x0B << 6) | OPC_ADDUH_QB_DSP
,
427 OPC_SUBQH_W
= (0x11 << 6) | OPC_ADDUH_QB_DSP
,
428 OPC_SUBQH_R_W
= (0x13 << 6) | OPC_ADDUH_QB_DSP
,
429 /* MIPS DSP Multiply Sub-class insns */
430 OPC_MUL_PH
= (0x0C << 6) | OPC_ADDUH_QB_DSP
,
431 OPC_MUL_S_PH
= (0x0E << 6) | OPC_ADDUH_QB_DSP
,
432 OPC_MULQ_S_W
= (0x16 << 6) | OPC_ADDUH_QB_DSP
,
433 OPC_MULQ_RS_W
= (0x17 << 6) | OPC_ADDUH_QB_DSP
,
436 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
438 /* MIPS DSP Arithmetic Sub-class */
439 OPC_ABSQ_S_QB
= (0x01 << 6) | OPC_ABSQ_S_PH_DSP
,
440 OPC_ABSQ_S_PH
= (0x09 << 6) | OPC_ABSQ_S_PH_DSP
,
441 OPC_ABSQ_S_W
= (0x11 << 6) | OPC_ABSQ_S_PH_DSP
,
442 OPC_PRECEQ_W_PHL
= (0x0C << 6) | OPC_ABSQ_S_PH_DSP
,
443 OPC_PRECEQ_W_PHR
= (0x0D << 6) | OPC_ABSQ_S_PH_DSP
,
444 OPC_PRECEQU_PH_QBL
= (0x04 << 6) | OPC_ABSQ_S_PH_DSP
,
445 OPC_PRECEQU_PH_QBR
= (0x05 << 6) | OPC_ABSQ_S_PH_DSP
,
446 OPC_PRECEQU_PH_QBLA
= (0x06 << 6) | OPC_ABSQ_S_PH_DSP
,
447 OPC_PRECEQU_PH_QBRA
= (0x07 << 6) | OPC_ABSQ_S_PH_DSP
,
448 OPC_PRECEU_PH_QBL
= (0x1C << 6) | OPC_ABSQ_S_PH_DSP
,
449 OPC_PRECEU_PH_QBR
= (0x1D << 6) | OPC_ABSQ_S_PH_DSP
,
450 OPC_PRECEU_PH_QBLA
= (0x1E << 6) | OPC_ABSQ_S_PH_DSP
,
451 OPC_PRECEU_PH_QBRA
= (0x1F << 6) | OPC_ABSQ_S_PH_DSP
,
452 /* DSP Bit/Manipulation Sub-class */
453 OPC_BITREV
= (0x1B << 6) | OPC_ABSQ_S_PH_DSP
,
454 OPC_REPL_QB
= (0x02 << 6) | OPC_ABSQ_S_PH_DSP
,
455 OPC_REPLV_QB
= (0x03 << 6) | OPC_ABSQ_S_PH_DSP
,
456 OPC_REPL_PH
= (0x0A << 6) | OPC_ABSQ_S_PH_DSP
,
457 OPC_REPLV_PH
= (0x0B << 6) | OPC_ABSQ_S_PH_DSP
,
460 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
462 /* MIPS DSP Arithmetic Sub-class */
463 OPC_PRECR_QB_PH
= (0x0D << 6) | OPC_CMPU_EQ_QB_DSP
,
464 OPC_PRECRQ_QB_PH
= (0x0C << 6) | OPC_CMPU_EQ_QB_DSP
,
465 OPC_PRECR_SRA_PH_W
= (0x1E << 6) | OPC_CMPU_EQ_QB_DSP
,
466 OPC_PRECR_SRA_R_PH_W
= (0x1F << 6) | OPC_CMPU_EQ_QB_DSP
,
467 OPC_PRECRQ_PH_W
= (0x14 << 6) | OPC_CMPU_EQ_QB_DSP
,
468 OPC_PRECRQ_RS_PH_W
= (0x15 << 6) | OPC_CMPU_EQ_QB_DSP
,
469 OPC_PRECRQU_S_QB_PH
= (0x0F << 6) | OPC_CMPU_EQ_QB_DSP
,
470 /* DSP Compare-Pick Sub-class */
471 OPC_CMPU_EQ_QB
= (0x00 << 6) | OPC_CMPU_EQ_QB_DSP
,
472 OPC_CMPU_LT_QB
= (0x01 << 6) | OPC_CMPU_EQ_QB_DSP
,
473 OPC_CMPU_LE_QB
= (0x02 << 6) | OPC_CMPU_EQ_QB_DSP
,
474 OPC_CMPGU_EQ_QB
= (0x04 << 6) | OPC_CMPU_EQ_QB_DSP
,
475 OPC_CMPGU_LT_QB
= (0x05 << 6) | OPC_CMPU_EQ_QB_DSP
,
476 OPC_CMPGU_LE_QB
= (0x06 << 6) | OPC_CMPU_EQ_QB_DSP
,
477 OPC_CMPGDU_EQ_QB
= (0x18 << 6) | OPC_CMPU_EQ_QB_DSP
,
478 OPC_CMPGDU_LT_QB
= (0x19 << 6) | OPC_CMPU_EQ_QB_DSP
,
479 OPC_CMPGDU_LE_QB
= (0x1A << 6) | OPC_CMPU_EQ_QB_DSP
,
480 OPC_CMP_EQ_PH
= (0x08 << 6) | OPC_CMPU_EQ_QB_DSP
,
481 OPC_CMP_LT_PH
= (0x09 << 6) | OPC_CMPU_EQ_QB_DSP
,
482 OPC_CMP_LE_PH
= (0x0A << 6) | OPC_CMPU_EQ_QB_DSP
,
483 OPC_PICK_QB
= (0x03 << 6) | OPC_CMPU_EQ_QB_DSP
,
484 OPC_PICK_PH
= (0x0B << 6) | OPC_CMPU_EQ_QB_DSP
,
485 OPC_PACKRL_PH
= (0x0E << 6) | OPC_CMPU_EQ_QB_DSP
,
488 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
490 /* MIPS DSP GPR-Based Shift Sub-class */
491 OPC_SHLL_QB
= (0x00 << 6) | OPC_SHLL_QB_DSP
,
492 OPC_SHLLV_QB
= (0x02 << 6) | OPC_SHLL_QB_DSP
,
493 OPC_SHLL_PH
= (0x08 << 6) | OPC_SHLL_QB_DSP
,
494 OPC_SHLLV_PH
= (0x0A << 6) | OPC_SHLL_QB_DSP
,
495 OPC_SHLL_S_PH
= (0x0C << 6) | OPC_SHLL_QB_DSP
,
496 OPC_SHLLV_S_PH
= (0x0E << 6) | OPC_SHLL_QB_DSP
,
497 OPC_SHLL_S_W
= (0x14 << 6) | OPC_SHLL_QB_DSP
,
498 OPC_SHLLV_S_W
= (0x16 << 6) | OPC_SHLL_QB_DSP
,
499 OPC_SHRL_QB
= (0x01 << 6) | OPC_SHLL_QB_DSP
,
500 OPC_SHRLV_QB
= (0x03 << 6) | OPC_SHLL_QB_DSP
,
501 OPC_SHRL_PH
= (0x19 << 6) | OPC_SHLL_QB_DSP
,
502 OPC_SHRLV_PH
= (0x1B << 6) | OPC_SHLL_QB_DSP
,
503 OPC_SHRA_QB
= (0x04 << 6) | OPC_SHLL_QB_DSP
,
504 OPC_SHRA_R_QB
= (0x05 << 6) | OPC_SHLL_QB_DSP
,
505 OPC_SHRAV_QB
= (0x06 << 6) | OPC_SHLL_QB_DSP
,
506 OPC_SHRAV_R_QB
= (0x07 << 6) | OPC_SHLL_QB_DSP
,
507 OPC_SHRA_PH
= (0x09 << 6) | OPC_SHLL_QB_DSP
,
508 OPC_SHRAV_PH
= (0x0B << 6) | OPC_SHLL_QB_DSP
,
509 OPC_SHRA_R_PH
= (0x0D << 6) | OPC_SHLL_QB_DSP
,
510 OPC_SHRAV_R_PH
= (0x0F << 6) | OPC_SHLL_QB_DSP
,
511 OPC_SHRA_R_W
= (0x15 << 6) | OPC_SHLL_QB_DSP
,
512 OPC_SHRAV_R_W
= (0x17 << 6) | OPC_SHLL_QB_DSP
,
515 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
517 /* MIPS DSP Multiply Sub-class insns */
518 OPC_DPAU_H_QBL
= (0x03 << 6) | OPC_DPA_W_PH_DSP
,
519 OPC_DPAU_H_QBR
= (0x07 << 6) | OPC_DPA_W_PH_DSP
,
520 OPC_DPSU_H_QBL
= (0x0B << 6) | OPC_DPA_W_PH_DSP
,
521 OPC_DPSU_H_QBR
= (0x0F << 6) | OPC_DPA_W_PH_DSP
,
522 OPC_DPA_W_PH
= (0x00 << 6) | OPC_DPA_W_PH_DSP
,
523 OPC_DPAX_W_PH
= (0x08 << 6) | OPC_DPA_W_PH_DSP
,
524 OPC_DPAQ_S_W_PH
= (0x04 << 6) | OPC_DPA_W_PH_DSP
,
525 OPC_DPAQX_S_W_PH
= (0x18 << 6) | OPC_DPA_W_PH_DSP
,
526 OPC_DPAQX_SA_W_PH
= (0x1A << 6) | OPC_DPA_W_PH_DSP
,
527 OPC_DPS_W_PH
= (0x01 << 6) | OPC_DPA_W_PH_DSP
,
528 OPC_DPSX_W_PH
= (0x09 << 6) | OPC_DPA_W_PH_DSP
,
529 OPC_DPSQ_S_W_PH
= (0x05 << 6) | OPC_DPA_W_PH_DSP
,
530 OPC_DPSQX_S_W_PH
= (0x19 << 6) | OPC_DPA_W_PH_DSP
,
531 OPC_DPSQX_SA_W_PH
= (0x1B << 6) | OPC_DPA_W_PH_DSP
,
532 OPC_MULSAQ_S_W_PH
= (0x06 << 6) | OPC_DPA_W_PH_DSP
,
533 OPC_DPAQ_SA_L_W
= (0x0C << 6) | OPC_DPA_W_PH_DSP
,
534 OPC_DPSQ_SA_L_W
= (0x0D << 6) | OPC_DPA_W_PH_DSP
,
535 OPC_MAQ_S_W_PHL
= (0x14 << 6) | OPC_DPA_W_PH_DSP
,
536 OPC_MAQ_S_W_PHR
= (0x16 << 6) | OPC_DPA_W_PH_DSP
,
537 OPC_MAQ_SA_W_PHL
= (0x10 << 6) | OPC_DPA_W_PH_DSP
,
538 OPC_MAQ_SA_W_PHR
= (0x12 << 6) | OPC_DPA_W_PH_DSP
,
539 OPC_MULSA_W_PH
= (0x02 << 6) | OPC_DPA_W_PH_DSP
,
542 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
544 /* DSP Bit/Manipulation Sub-class */
545 OPC_INSV
= (0x00 << 6) | OPC_INSV_DSP
,
548 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
550 /* MIPS DSP Append Sub-class */
551 OPC_APPEND
= (0x00 << 6) | OPC_APPEND_DSP
,
552 OPC_PREPEND
= (0x01 << 6) | OPC_APPEND_DSP
,
553 OPC_BALIGN
= (0x10 << 6) | OPC_APPEND_DSP
,
556 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
558 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
559 OPC_EXTR_W
= (0x00 << 6) | OPC_EXTR_W_DSP
,
560 OPC_EXTR_R_W
= (0x04 << 6) | OPC_EXTR_W_DSP
,
561 OPC_EXTR_RS_W
= (0x06 << 6) | OPC_EXTR_W_DSP
,
562 OPC_EXTR_S_H
= (0x0E << 6) | OPC_EXTR_W_DSP
,
563 OPC_EXTRV_S_H
= (0x0F << 6) | OPC_EXTR_W_DSP
,
564 OPC_EXTRV_W
= (0x01 << 6) | OPC_EXTR_W_DSP
,
565 OPC_EXTRV_R_W
= (0x05 << 6) | OPC_EXTR_W_DSP
,
566 OPC_EXTRV_RS_W
= (0x07 << 6) | OPC_EXTR_W_DSP
,
567 OPC_EXTP
= (0x02 << 6) | OPC_EXTR_W_DSP
,
568 OPC_EXTPV
= (0x03 << 6) | OPC_EXTR_W_DSP
,
569 OPC_EXTPDP
= (0x0A << 6) | OPC_EXTR_W_DSP
,
570 OPC_EXTPDPV
= (0x0B << 6) | OPC_EXTR_W_DSP
,
571 OPC_SHILO
= (0x1A << 6) | OPC_EXTR_W_DSP
,
572 OPC_SHILOV
= (0x1B << 6) | OPC_EXTR_W_DSP
,
573 OPC_MTHLIP
= (0x1F << 6) | OPC_EXTR_W_DSP
,
574 OPC_WRDSP
= (0x13 << 6) | OPC_EXTR_W_DSP
,
575 OPC_RDDSP
= (0x12 << 6) | OPC_EXTR_W_DSP
,
578 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
580 /* MIPS DSP Arithmetic Sub-class */
581 OPC_PRECEQ_L_PWL
= (0x14 << 6) | OPC_ABSQ_S_QH_DSP
,
582 OPC_PRECEQ_L_PWR
= (0x15 << 6) | OPC_ABSQ_S_QH_DSP
,
583 OPC_PRECEQ_PW_QHL
= (0x0C << 6) | OPC_ABSQ_S_QH_DSP
,
584 OPC_PRECEQ_PW_QHR
= (0x0D << 6) | OPC_ABSQ_S_QH_DSP
,
585 OPC_PRECEQ_PW_QHLA
= (0x0E << 6) | OPC_ABSQ_S_QH_DSP
,
586 OPC_PRECEQ_PW_QHRA
= (0x0F << 6) | OPC_ABSQ_S_QH_DSP
,
587 OPC_PRECEQU_QH_OBL
= (0x04 << 6) | OPC_ABSQ_S_QH_DSP
,
588 OPC_PRECEQU_QH_OBR
= (0x05 << 6) | OPC_ABSQ_S_QH_DSP
,
589 OPC_PRECEQU_QH_OBLA
= (0x06 << 6) | OPC_ABSQ_S_QH_DSP
,
590 OPC_PRECEQU_QH_OBRA
= (0x07 << 6) | OPC_ABSQ_S_QH_DSP
,
591 OPC_PRECEU_QH_OBL
= (0x1C << 6) | OPC_ABSQ_S_QH_DSP
,
592 OPC_PRECEU_QH_OBR
= (0x1D << 6) | OPC_ABSQ_S_QH_DSP
,
593 OPC_PRECEU_QH_OBLA
= (0x1E << 6) | OPC_ABSQ_S_QH_DSP
,
594 OPC_PRECEU_QH_OBRA
= (0x1F << 6) | OPC_ABSQ_S_QH_DSP
,
595 OPC_ABSQ_S_OB
= (0x01 << 6) | OPC_ABSQ_S_QH_DSP
,
596 OPC_ABSQ_S_PW
= (0x11 << 6) | OPC_ABSQ_S_QH_DSP
,
597 OPC_ABSQ_S_QH
= (0x09 << 6) | OPC_ABSQ_S_QH_DSP
,
598 /* DSP Bit/Manipulation Sub-class */
599 OPC_REPL_OB
= (0x02 << 6) | OPC_ABSQ_S_QH_DSP
,
600 OPC_REPL_PW
= (0x12 << 6) | OPC_ABSQ_S_QH_DSP
,
601 OPC_REPL_QH
= (0x0A << 6) | OPC_ABSQ_S_QH_DSP
,
602 OPC_REPLV_OB
= (0x03 << 6) | OPC_ABSQ_S_QH_DSP
,
603 OPC_REPLV_PW
= (0x13 << 6) | OPC_ABSQ_S_QH_DSP
,
604 OPC_REPLV_QH
= (0x0B << 6) | OPC_ABSQ_S_QH_DSP
,
607 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
609 /* MIPS DSP Multiply Sub-class insns */
610 OPC_MULEQ_S_PW_QHL
= (0x1C << 6) | OPC_ADDU_OB_DSP
,
611 OPC_MULEQ_S_PW_QHR
= (0x1D << 6) | OPC_ADDU_OB_DSP
,
612 OPC_MULEU_S_QH_OBL
= (0x06 << 6) | OPC_ADDU_OB_DSP
,
613 OPC_MULEU_S_QH_OBR
= (0x07 << 6) | OPC_ADDU_OB_DSP
,
614 OPC_MULQ_RS_QH
= (0x1F << 6) | OPC_ADDU_OB_DSP
,
615 /* MIPS DSP Arithmetic Sub-class */
616 OPC_RADDU_L_OB
= (0x14 << 6) | OPC_ADDU_OB_DSP
,
617 OPC_SUBQ_PW
= (0x13 << 6) | OPC_ADDU_OB_DSP
,
618 OPC_SUBQ_S_PW
= (0x17 << 6) | OPC_ADDU_OB_DSP
,
619 OPC_SUBQ_QH
= (0x0B << 6) | OPC_ADDU_OB_DSP
,
620 OPC_SUBQ_S_QH
= (0x0F << 6) | OPC_ADDU_OB_DSP
,
621 OPC_SUBU_OB
= (0x01 << 6) | OPC_ADDU_OB_DSP
,
622 OPC_SUBU_S_OB
= (0x05 << 6) | OPC_ADDU_OB_DSP
,
623 OPC_SUBU_QH
= (0x09 << 6) | OPC_ADDU_OB_DSP
,
624 OPC_SUBU_S_QH
= (0x0D << 6) | OPC_ADDU_OB_DSP
,
625 OPC_SUBUH_OB
= (0x19 << 6) | OPC_ADDU_OB_DSP
,
626 OPC_SUBUH_R_OB
= (0x1B << 6) | OPC_ADDU_OB_DSP
,
627 OPC_ADDQ_PW
= (0x12 << 6) | OPC_ADDU_OB_DSP
,
628 OPC_ADDQ_S_PW
= (0x16 << 6) | OPC_ADDU_OB_DSP
,
629 OPC_ADDQ_QH
= (0x0A << 6) | OPC_ADDU_OB_DSP
,
630 OPC_ADDQ_S_QH
= (0x0E << 6) | OPC_ADDU_OB_DSP
,
631 OPC_ADDU_OB
= (0x00 << 6) | OPC_ADDU_OB_DSP
,
632 OPC_ADDU_S_OB
= (0x04 << 6) | OPC_ADDU_OB_DSP
,
633 OPC_ADDU_QH
= (0x08 << 6) | OPC_ADDU_OB_DSP
,
634 OPC_ADDU_S_QH
= (0x0C << 6) | OPC_ADDU_OB_DSP
,
635 OPC_ADDUH_OB
= (0x18 << 6) | OPC_ADDU_OB_DSP
,
636 OPC_ADDUH_R_OB
= (0x1A << 6) | OPC_ADDU_OB_DSP
,
639 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
641 /* DSP Compare-Pick Sub-class */
642 OPC_CMP_EQ_PW
= (0x10 << 6) | OPC_CMPU_EQ_OB_DSP
,
643 OPC_CMP_LT_PW
= (0x11 << 6) | OPC_CMPU_EQ_OB_DSP
,
644 OPC_CMP_LE_PW
= (0x12 << 6) | OPC_CMPU_EQ_OB_DSP
,
645 OPC_CMP_EQ_QH
= (0x08 << 6) | OPC_CMPU_EQ_OB_DSP
,
646 OPC_CMP_LT_QH
= (0x09 << 6) | OPC_CMPU_EQ_OB_DSP
,
647 OPC_CMP_LE_QH
= (0x0A << 6) | OPC_CMPU_EQ_OB_DSP
,
648 OPC_CMPGDU_EQ_OB
= (0x18 << 6) | OPC_CMPU_EQ_OB_DSP
,
649 OPC_CMPGDU_LT_OB
= (0x19 << 6) | OPC_CMPU_EQ_OB_DSP
,
650 OPC_CMPGDU_LE_OB
= (0x1A << 6) | OPC_CMPU_EQ_OB_DSP
,
651 OPC_CMPGU_EQ_OB
= (0x04 << 6) | OPC_CMPU_EQ_OB_DSP
,
652 OPC_CMPGU_LT_OB
= (0x05 << 6) | OPC_CMPU_EQ_OB_DSP
,
653 OPC_CMPGU_LE_OB
= (0x06 << 6) | OPC_CMPU_EQ_OB_DSP
,
654 OPC_CMPU_EQ_OB
= (0x00 << 6) | OPC_CMPU_EQ_OB_DSP
,
655 OPC_CMPU_LT_OB
= (0x01 << 6) | OPC_CMPU_EQ_OB_DSP
,
656 OPC_CMPU_LE_OB
= (0x02 << 6) | OPC_CMPU_EQ_OB_DSP
,
657 OPC_PACKRL_PW
= (0x0E << 6) | OPC_CMPU_EQ_OB_DSP
,
658 OPC_PICK_OB
= (0x03 << 6) | OPC_CMPU_EQ_OB_DSP
,
659 OPC_PICK_PW
= (0x13 << 6) | OPC_CMPU_EQ_OB_DSP
,
660 OPC_PICK_QH
= (0x0B << 6) | OPC_CMPU_EQ_OB_DSP
,
661 /* MIPS DSP Arithmetic Sub-class */
662 OPC_PRECR_OB_QH
= (0x0D << 6) | OPC_CMPU_EQ_OB_DSP
,
663 OPC_PRECR_SRA_QH_PW
= (0x1E << 6) | OPC_CMPU_EQ_OB_DSP
,
664 OPC_PRECR_SRA_R_QH_PW
= (0x1F << 6) | OPC_CMPU_EQ_OB_DSP
,
665 OPC_PRECRQ_OB_QH
= (0x0C << 6) | OPC_CMPU_EQ_OB_DSP
,
666 OPC_PRECRQ_PW_L
= (0x1C << 6) | OPC_CMPU_EQ_OB_DSP
,
667 OPC_PRECRQ_QH_PW
= (0x14 << 6) | OPC_CMPU_EQ_OB_DSP
,
668 OPC_PRECRQ_RS_QH_PW
= (0x15 << 6) | OPC_CMPU_EQ_OB_DSP
,
669 OPC_PRECRQU_S_OB_QH
= (0x0F << 6) | OPC_CMPU_EQ_OB_DSP
,
672 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
674 /* DSP Append Sub-class */
675 OPC_DAPPEND
= (0x00 << 6) | OPC_DAPPEND_DSP
,
676 OPC_PREPENDD
= (0x03 << 6) | OPC_DAPPEND_DSP
,
677 OPC_PREPENDW
= (0x01 << 6) | OPC_DAPPEND_DSP
,
678 OPC_DBALIGN
= (0x10 << 6) | OPC_DAPPEND_DSP
,
681 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
683 /* MIPS DSP Accumulator and DSPControl Access Sub-class */
684 OPC_DMTHLIP
= (0x1F << 6) | OPC_DEXTR_W_DSP
,
685 OPC_DSHILO
= (0x1A << 6) | OPC_DEXTR_W_DSP
,
686 OPC_DEXTP
= (0x02 << 6) | OPC_DEXTR_W_DSP
,
687 OPC_DEXTPDP
= (0x0A << 6) | OPC_DEXTR_W_DSP
,
688 OPC_DEXTPDPV
= (0x0B << 6) | OPC_DEXTR_W_DSP
,
689 OPC_DEXTPV
= (0x03 << 6) | OPC_DEXTR_W_DSP
,
690 OPC_DEXTR_L
= (0x10 << 6) | OPC_DEXTR_W_DSP
,
691 OPC_DEXTR_R_L
= (0x14 << 6) | OPC_DEXTR_W_DSP
,
692 OPC_DEXTR_RS_L
= (0x16 << 6) | OPC_DEXTR_W_DSP
,
693 OPC_DEXTR_W
= (0x00 << 6) | OPC_DEXTR_W_DSP
,
694 OPC_DEXTR_R_W
= (0x04 << 6) | OPC_DEXTR_W_DSP
,
695 OPC_DEXTR_RS_W
= (0x06 << 6) | OPC_DEXTR_W_DSP
,
696 OPC_DEXTR_S_H
= (0x0E << 6) | OPC_DEXTR_W_DSP
,
697 OPC_DEXTRV_L
= (0x11 << 6) | OPC_DEXTR_W_DSP
,
698 OPC_DEXTRV_R_L
= (0x15 << 6) | OPC_DEXTR_W_DSP
,
699 OPC_DEXTRV_RS_L
= (0x17 << 6) | OPC_DEXTR_W_DSP
,
700 OPC_DEXTRV_S_H
= (0x0F << 6) | OPC_DEXTR_W_DSP
,
701 OPC_DEXTRV_W
= (0x01 << 6) | OPC_DEXTR_W_DSP
,
702 OPC_DEXTRV_R_W
= (0x05 << 6) | OPC_DEXTR_W_DSP
,
703 OPC_DEXTRV_RS_W
= (0x07 << 6) | OPC_DEXTR_W_DSP
,
704 OPC_DSHILOV
= (0x1B << 6) | OPC_DEXTR_W_DSP
,
707 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
709 /* DSP Bit/Manipulation Sub-class */
710 OPC_DINSV
= (0x00 << 6) | OPC_DINSV_DSP
,
713 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
715 /* MIPS DSP Multiply Sub-class insns */
716 OPC_DMADD
= (0x19 << 6) | OPC_DPAQ_W_QH_DSP
,
717 OPC_DMADDU
= (0x1D << 6) | OPC_DPAQ_W_QH_DSP
,
718 OPC_DMSUB
= (0x1B << 6) | OPC_DPAQ_W_QH_DSP
,
719 OPC_DMSUBU
= (0x1F << 6) | OPC_DPAQ_W_QH_DSP
,
720 OPC_DPA_W_QH
= (0x00 << 6) | OPC_DPAQ_W_QH_DSP
,
721 OPC_DPAQ_S_W_QH
= (0x04 << 6) | OPC_DPAQ_W_QH_DSP
,
722 OPC_DPAQ_SA_L_PW
= (0x0C << 6) | OPC_DPAQ_W_QH_DSP
,
723 OPC_DPAU_H_OBL
= (0x03 << 6) | OPC_DPAQ_W_QH_DSP
,
724 OPC_DPAU_H_OBR
= (0x07 << 6) | OPC_DPAQ_W_QH_DSP
,
725 OPC_DPS_W_QH
= (0x01 << 6) | OPC_DPAQ_W_QH_DSP
,
726 OPC_DPSQ_S_W_QH
= (0x05 << 6) | OPC_DPAQ_W_QH_DSP
,
727 OPC_DPSQ_SA_L_PW
= (0x0D << 6) | OPC_DPAQ_W_QH_DSP
,
728 OPC_DPSU_H_OBL
= (0x0B << 6) | OPC_DPAQ_W_QH_DSP
,
729 OPC_DPSU_H_OBR
= (0x0F << 6) | OPC_DPAQ_W_QH_DSP
,
730 OPC_MAQ_S_L_PWL
= (0x1C << 6) | OPC_DPAQ_W_QH_DSP
,
731 OPC_MAQ_S_L_PWR
= (0x1E << 6) | OPC_DPAQ_W_QH_DSP
,
732 OPC_MAQ_S_W_QHLL
= (0x14 << 6) | OPC_DPAQ_W_QH_DSP
,
733 OPC_MAQ_SA_W_QHLL
= (0x10 << 6) | OPC_DPAQ_W_QH_DSP
,
734 OPC_MAQ_S_W_QHLR
= (0x15 << 6) | OPC_DPAQ_W_QH_DSP
,
735 OPC_MAQ_SA_W_QHLR
= (0x11 << 6) | OPC_DPAQ_W_QH_DSP
,
736 OPC_MAQ_S_W_QHRL
= (0x16 << 6) | OPC_DPAQ_W_QH_DSP
,
737 OPC_MAQ_SA_W_QHRL
= (0x12 << 6) | OPC_DPAQ_W_QH_DSP
,
738 OPC_MAQ_S_W_QHRR
= (0x17 << 6) | OPC_DPAQ_W_QH_DSP
,
739 OPC_MAQ_SA_W_QHRR
= (0x13 << 6) | OPC_DPAQ_W_QH_DSP
,
740 OPC_MULSAQ_S_L_PW
= (0x0E << 6) | OPC_DPAQ_W_QH_DSP
,
741 OPC_MULSAQ_S_W_QH
= (0x06 << 6) | OPC_DPAQ_W_QH_DSP
,
744 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
746 /* MIPS DSP GPR-Based Shift Sub-class */
747 OPC_SHLL_PW
= (0x10 << 6) | OPC_SHLL_OB_DSP
,
748 OPC_SHLL_S_PW
= (0x14 << 6) | OPC_SHLL_OB_DSP
,
749 OPC_SHLLV_OB
= (0x02 << 6) | OPC_SHLL_OB_DSP
,
750 OPC_SHLLV_PW
= (0x12 << 6) | OPC_SHLL_OB_DSP
,
751 OPC_SHLLV_S_PW
= (0x16 << 6) | OPC_SHLL_OB_DSP
,
752 OPC_SHLLV_QH
= (0x0A << 6) | OPC_SHLL_OB_DSP
,
753 OPC_SHLLV_S_QH
= (0x0E << 6) | OPC_SHLL_OB_DSP
,
754 OPC_SHRA_PW
= (0x11 << 6) | OPC_SHLL_OB_DSP
,
755 OPC_SHRA_R_PW
= (0x15 << 6) | OPC_SHLL_OB_DSP
,
756 OPC_SHRAV_OB
= (0x06 << 6) | OPC_SHLL_OB_DSP
,
757 OPC_SHRAV_R_OB
= (0x07 << 6) | OPC_SHLL_OB_DSP
,
758 OPC_SHRAV_PW
= (0x13 << 6) | OPC_SHLL_OB_DSP
,
759 OPC_SHRAV_R_PW
= (0x17 << 6) | OPC_SHLL_OB_DSP
,
760 OPC_SHRAV_QH
= (0x0B << 6) | OPC_SHLL_OB_DSP
,
761 OPC_SHRAV_R_QH
= (0x0F << 6) | OPC_SHLL_OB_DSP
,
762 OPC_SHRLV_OB
= (0x03 << 6) | OPC_SHLL_OB_DSP
,
763 OPC_SHRLV_QH
= (0x1B << 6) | OPC_SHLL_OB_DSP
,
764 OPC_SHLL_OB
= (0x00 << 6) | OPC_SHLL_OB_DSP
,
765 OPC_SHLL_QH
= (0x08 << 6) | OPC_SHLL_OB_DSP
,
766 OPC_SHLL_S_QH
= (0x0C << 6) | OPC_SHLL_OB_DSP
,
767 OPC_SHRA_OB
= (0x04 << 6) | OPC_SHLL_OB_DSP
,
768 OPC_SHRA_R_OB
= (0x05 << 6) | OPC_SHLL_OB_DSP
,
769 OPC_SHRA_QH
= (0x09 << 6) | OPC_SHLL_OB_DSP
,
770 OPC_SHRA_R_QH
= (0x0D << 6) | OPC_SHLL_OB_DSP
,
771 OPC_SHRL_OB
= (0x01 << 6) | OPC_SHLL_OB_DSP
,
772 OPC_SHRL_QH
= (0x19 << 6) | OPC_SHLL_OB_DSP
,
775 /* Coprocessor 0 (rs field) */
776 #define MASK_CP0(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
779 OPC_MFC0
= (0x00 << 21) | OPC_CP0
,
780 OPC_DMFC0
= (0x01 << 21) | OPC_CP0
,
781 OPC_MTC0
= (0x04 << 21) | OPC_CP0
,
782 OPC_DMTC0
= (0x05 << 21) | OPC_CP0
,
783 OPC_MFTR
= (0x08 << 21) | OPC_CP0
,
784 OPC_RDPGPR
= (0x0A << 21) | OPC_CP0
,
785 OPC_MFMC0
= (0x0B << 21) | OPC_CP0
,
786 OPC_MTTR
= (0x0C << 21) | OPC_CP0
,
787 OPC_WRPGPR
= (0x0E << 21) | OPC_CP0
,
788 OPC_C0
= (0x10 << 21) | OPC_CP0
,
789 OPC_C0_FIRST
= (0x10 << 21) | OPC_CP0
,
790 OPC_C0_LAST
= (0x1F << 21) | OPC_CP0
,
794 #define MASK_MFMC0(op) MASK_CP0(op) | (op & 0xFFFF)
797 OPC_DMT
= 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
798 OPC_EMT
= 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0
,
799 OPC_DVPE
= 0x01 | (0 << 5) | OPC_MFMC0
,
800 OPC_EVPE
= 0x01 | (1 << 5) | OPC_MFMC0
,
801 OPC_DI
= (0 << 5) | (0x0C << 11) | OPC_MFMC0
,
802 OPC_EI
= (1 << 5) | (0x0C << 11) | OPC_MFMC0
,
805 /* Coprocessor 0 (with rs == C0) */
806 #define MASK_C0(op) MASK_CP0(op) | (op & 0x3F)
809 OPC_TLBR
= 0x01 | OPC_C0
,
810 OPC_TLBWI
= 0x02 | OPC_C0
,
811 OPC_TLBWR
= 0x06 | OPC_C0
,
812 OPC_TLBP
= 0x08 | OPC_C0
,
813 OPC_RFE
= 0x10 | OPC_C0
,
814 OPC_ERET
= 0x18 | OPC_C0
,
815 OPC_DERET
= 0x1F | OPC_C0
,
816 OPC_WAIT
= 0x20 | OPC_C0
,
819 /* Coprocessor 1 (rs field) */
820 #define MASK_CP1(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
822 /* Values for the fmt field in FP instructions */
824 /* 0 - 15 are reserved */
825 FMT_S
= 16, /* single fp */
826 FMT_D
= 17, /* double fp */
827 FMT_E
= 18, /* extended fp */
828 FMT_Q
= 19, /* quad fp */
829 FMT_W
= 20, /* 32-bit fixed */
830 FMT_L
= 21, /* 64-bit fixed */
831 FMT_PS
= 22, /* paired single fp */
832 /* 23 - 31 are reserved */
836 OPC_MFC1
= (0x00 << 21) | OPC_CP1
,
837 OPC_DMFC1
= (0x01 << 21) | OPC_CP1
,
838 OPC_CFC1
= (0x02 << 21) | OPC_CP1
,
839 OPC_MFHC1
= (0x03 << 21) | OPC_CP1
,
840 OPC_MTC1
= (0x04 << 21) | OPC_CP1
,
841 OPC_DMTC1
= (0x05 << 21) | OPC_CP1
,
842 OPC_CTC1
= (0x06 << 21) | OPC_CP1
,
843 OPC_MTHC1
= (0x07 << 21) | OPC_CP1
,
844 OPC_BC1
= (0x08 << 21) | OPC_CP1
, /* bc */
845 OPC_BC1ANY2
= (0x09 << 21) | OPC_CP1
,
846 OPC_BC1ANY4
= (0x0A << 21) | OPC_CP1
,
847 OPC_S_FMT
= (FMT_S
<< 21) | OPC_CP1
,
848 OPC_D_FMT
= (FMT_D
<< 21) | OPC_CP1
,
849 OPC_E_FMT
= (FMT_E
<< 21) | OPC_CP1
,
850 OPC_Q_FMT
= (FMT_Q
<< 21) | OPC_CP1
,
851 OPC_W_FMT
= (FMT_W
<< 21) | OPC_CP1
,
852 OPC_L_FMT
= (FMT_L
<< 21) | OPC_CP1
,
853 OPC_PS_FMT
= (FMT_PS
<< 21) | OPC_CP1
,
856 #define MASK_CP1_FUNC(op) MASK_CP1(op) | (op & 0x3F)
857 #define MASK_BC1(op) MASK_CP1(op) | (op & (0x3 << 16))
860 OPC_BC1F
= (0x00 << 16) | OPC_BC1
,
861 OPC_BC1T
= (0x01 << 16) | OPC_BC1
,
862 OPC_BC1FL
= (0x02 << 16) | OPC_BC1
,
863 OPC_BC1TL
= (0x03 << 16) | OPC_BC1
,
867 OPC_BC1FANY2
= (0x00 << 16) | OPC_BC1ANY2
,
868 OPC_BC1TANY2
= (0x01 << 16) | OPC_BC1ANY2
,
872 OPC_BC1FANY4
= (0x00 << 16) | OPC_BC1ANY4
,
873 OPC_BC1TANY4
= (0x01 << 16) | OPC_BC1ANY4
,
876 #define MASK_CP2(op) MASK_OP_MAJOR(op) | (op & (0x1F << 21))
879 OPC_MFC2
= (0x00 << 21) | OPC_CP2
,
880 OPC_DMFC2
= (0x01 << 21) | OPC_CP2
,
881 OPC_CFC2
= (0x02 << 21) | OPC_CP2
,
882 OPC_MFHC2
= (0x03 << 21) | OPC_CP2
,
883 OPC_MTC2
= (0x04 << 21) | OPC_CP2
,
884 OPC_DMTC2
= (0x05 << 21) | OPC_CP2
,
885 OPC_CTC2
= (0x06 << 21) | OPC_CP2
,
886 OPC_MTHC2
= (0x07 << 21) | OPC_CP2
,
887 OPC_BC2
= (0x08 << 21) | OPC_CP2
,
890 #define MASK_LMI(op) (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
893 OPC_PADDSH
= (24 << 21) | (0x00) | OPC_CP2
,
894 OPC_PADDUSH
= (25 << 21) | (0x00) | OPC_CP2
,
895 OPC_PADDH
= (26 << 21) | (0x00) | OPC_CP2
,
896 OPC_PADDW
= (27 << 21) | (0x00) | OPC_CP2
,
897 OPC_PADDSB
= (28 << 21) | (0x00) | OPC_CP2
,
898 OPC_PADDUSB
= (29 << 21) | (0x00) | OPC_CP2
,
899 OPC_PADDB
= (30 << 21) | (0x00) | OPC_CP2
,
900 OPC_PADDD
= (31 << 21) | (0x00) | OPC_CP2
,
902 OPC_PSUBSH
= (24 << 21) | (0x01) | OPC_CP2
,
903 OPC_PSUBUSH
= (25 << 21) | (0x01) | OPC_CP2
,
904 OPC_PSUBH
= (26 << 21) | (0x01) | OPC_CP2
,
905 OPC_PSUBW
= (27 << 21) | (0x01) | OPC_CP2
,
906 OPC_PSUBSB
= (28 << 21) | (0x01) | OPC_CP2
,
907 OPC_PSUBUSB
= (29 << 21) | (0x01) | OPC_CP2
,
908 OPC_PSUBB
= (30 << 21) | (0x01) | OPC_CP2
,
909 OPC_PSUBD
= (31 << 21) | (0x01) | OPC_CP2
,
911 OPC_PSHUFH
= (24 << 21) | (0x02) | OPC_CP2
,
912 OPC_PACKSSWH
= (25 << 21) | (0x02) | OPC_CP2
,
913 OPC_PACKSSHB
= (26 << 21) | (0x02) | OPC_CP2
,
914 OPC_PACKUSHB
= (27 << 21) | (0x02) | OPC_CP2
,
915 OPC_XOR_CP2
= (28 << 21) | (0x02) | OPC_CP2
,
916 OPC_NOR_CP2
= (29 << 21) | (0x02) | OPC_CP2
,
917 OPC_AND_CP2
= (30 << 21) | (0x02) | OPC_CP2
,
918 OPC_PANDN
= (31 << 21) | (0x02) | OPC_CP2
,
920 OPC_PUNPCKLHW
= (24 << 21) | (0x03) | OPC_CP2
,
921 OPC_PUNPCKHHW
= (25 << 21) | (0x03) | OPC_CP2
,
922 OPC_PUNPCKLBH
= (26 << 21) | (0x03) | OPC_CP2
,
923 OPC_PUNPCKHBH
= (27 << 21) | (0x03) | OPC_CP2
,
924 OPC_PINSRH_0
= (28 << 21) | (0x03) | OPC_CP2
,
925 OPC_PINSRH_1
= (29 << 21) | (0x03) | OPC_CP2
,
926 OPC_PINSRH_2
= (30 << 21) | (0x03) | OPC_CP2
,
927 OPC_PINSRH_3
= (31 << 21) | (0x03) | OPC_CP2
,
929 OPC_PAVGH
= (24 << 21) | (0x08) | OPC_CP2
,
930 OPC_PAVGB
= (25 << 21) | (0x08) | OPC_CP2
,
931 OPC_PMAXSH
= (26 << 21) | (0x08) | OPC_CP2
,
932 OPC_PMINSH
= (27 << 21) | (0x08) | OPC_CP2
,
933 OPC_PMAXUB
= (28 << 21) | (0x08) | OPC_CP2
,
934 OPC_PMINUB
= (29 << 21) | (0x08) | OPC_CP2
,
936 OPC_PCMPEQW
= (24 << 21) | (0x09) | OPC_CP2
,
937 OPC_PCMPGTW
= (25 << 21) | (0x09) | OPC_CP2
,
938 OPC_PCMPEQH
= (26 << 21) | (0x09) | OPC_CP2
,
939 OPC_PCMPGTH
= (27 << 21) | (0x09) | OPC_CP2
,
940 OPC_PCMPEQB
= (28 << 21) | (0x09) | OPC_CP2
,
941 OPC_PCMPGTB
= (29 << 21) | (0x09) | OPC_CP2
,
943 OPC_PSLLW
= (24 << 21) | (0x0A) | OPC_CP2
,
944 OPC_PSLLH
= (25 << 21) | (0x0A) | OPC_CP2
,
945 OPC_PMULLH
= (26 << 21) | (0x0A) | OPC_CP2
,
946 OPC_PMULHH
= (27 << 21) | (0x0A) | OPC_CP2
,
947 OPC_PMULUW
= (28 << 21) | (0x0A) | OPC_CP2
,
948 OPC_PMULHUH
= (29 << 21) | (0x0A) | OPC_CP2
,
950 OPC_PSRLW
= (24 << 21) | (0x0B) | OPC_CP2
,
951 OPC_PSRLH
= (25 << 21) | (0x0B) | OPC_CP2
,
952 OPC_PSRAW
= (26 << 21) | (0x0B) | OPC_CP2
,
953 OPC_PSRAH
= (27 << 21) | (0x0B) | OPC_CP2
,
954 OPC_PUNPCKLWD
= (28 << 21) | (0x0B) | OPC_CP2
,
955 OPC_PUNPCKHWD
= (29 << 21) | (0x0B) | OPC_CP2
,
957 OPC_ADDU_CP2
= (24 << 21) | (0x0C) | OPC_CP2
,
958 OPC_OR_CP2
= (25 << 21) | (0x0C) | OPC_CP2
,
959 OPC_ADD_CP2
= (26 << 21) | (0x0C) | OPC_CP2
,
960 OPC_DADD_CP2
= (27 << 21) | (0x0C) | OPC_CP2
,
961 OPC_SEQU_CP2
= (28 << 21) | (0x0C) | OPC_CP2
,
962 OPC_SEQ_CP2
= (29 << 21) | (0x0C) | OPC_CP2
,
964 OPC_SUBU_CP2
= (24 << 21) | (0x0D) | OPC_CP2
,
965 OPC_PASUBUB
= (25 << 21) | (0x0D) | OPC_CP2
,
966 OPC_SUB_CP2
= (26 << 21) | (0x0D) | OPC_CP2
,
967 OPC_DSUB_CP2
= (27 << 21) | (0x0D) | OPC_CP2
,
968 OPC_SLTU_CP2
= (28 << 21) | (0x0D) | OPC_CP2
,
969 OPC_SLT_CP2
= (29 << 21) | (0x0D) | OPC_CP2
,
971 OPC_SLL_CP2
= (24 << 21) | (0x0E) | OPC_CP2
,
972 OPC_DSLL_CP2
= (25 << 21) | (0x0E) | OPC_CP2
,
973 OPC_PEXTRH
= (26 << 21) | (0x0E) | OPC_CP2
,
974 OPC_PMADDHW
= (27 << 21) | (0x0E) | OPC_CP2
,
975 OPC_SLEU_CP2
= (28 << 21) | (0x0E) | OPC_CP2
,
976 OPC_SLE_CP2
= (29 << 21) | (0x0E) | OPC_CP2
,
978 OPC_SRL_CP2
= (24 << 21) | (0x0F) | OPC_CP2
,
979 OPC_DSRL_CP2
= (25 << 21) | (0x0F) | OPC_CP2
,
980 OPC_SRA_CP2
= (26 << 21) | (0x0F) | OPC_CP2
,
981 OPC_DSRA_CP2
= (27 << 21) | (0x0F) | OPC_CP2
,
982 OPC_BIADD
= (28 << 21) | (0x0F) | OPC_CP2
,
983 OPC_PMOVMSKB
= (29 << 21) | (0x0F) | OPC_CP2
,
987 #define MASK_CP3(op) MASK_OP_MAJOR(op) | (op & 0x3F)
990 OPC_LWXC1
= 0x00 | OPC_CP3
,
991 OPC_LDXC1
= 0x01 | OPC_CP3
,
992 OPC_LUXC1
= 0x05 | OPC_CP3
,
993 OPC_SWXC1
= 0x08 | OPC_CP3
,
994 OPC_SDXC1
= 0x09 | OPC_CP3
,
995 OPC_SUXC1
= 0x0D | OPC_CP3
,
996 OPC_PREFX
= 0x0F | OPC_CP3
,
997 OPC_ALNV_PS
= 0x1E | OPC_CP3
,
998 OPC_MADD_S
= 0x20 | OPC_CP3
,
999 OPC_MADD_D
= 0x21 | OPC_CP3
,
1000 OPC_MADD_PS
= 0x26 | OPC_CP3
,
1001 OPC_MSUB_S
= 0x28 | OPC_CP3
,
1002 OPC_MSUB_D
= 0x29 | OPC_CP3
,
1003 OPC_MSUB_PS
= 0x2E | OPC_CP3
,
1004 OPC_NMADD_S
= 0x30 | OPC_CP3
,
1005 OPC_NMADD_D
= 0x31 | OPC_CP3
,
1006 OPC_NMADD_PS
= 0x36 | OPC_CP3
,
1007 OPC_NMSUB_S
= 0x38 | OPC_CP3
,
1008 OPC_NMSUB_D
= 0x39 | OPC_CP3
,
1009 OPC_NMSUB_PS
= 0x3E | OPC_CP3
,
1012 /* global register indices */
1013 static TCGv_ptr cpu_env
;
1014 static TCGv cpu_gpr
[32], cpu_PC
;
1015 static TCGv cpu_HI
[MIPS_DSP_ACC
], cpu_LO
[MIPS_DSP_ACC
], cpu_ACX
[MIPS_DSP_ACC
];
1016 static TCGv cpu_dspctrl
, btarget
, bcond
;
1017 static TCGv_i32 hflags
;
1018 static TCGv_i32 fpu_fcr0
, fpu_fcr31
;
1019 static TCGv_i64 fpu_f64
[32];
1021 static uint32_t gen_opc_hflags
[OPC_BUF_SIZE
];
1022 static target_ulong gen_opc_btarget
[OPC_BUF_SIZE
];
1024 #include "exec/gen-icount.h"
1026 #define gen_helper_0e0i(name, arg) do { \
1027 TCGv_i32 helper_tmp = tcg_const_i32(arg); \
1028 gen_helper_##name(cpu_env, helper_tmp); \
1029 tcg_temp_free_i32(helper_tmp); \
1032 #define gen_helper_0e1i(name, arg1, arg2) do { \
1033 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1034 gen_helper_##name(cpu_env, arg1, helper_tmp); \
1035 tcg_temp_free_i32(helper_tmp); \
1038 #define gen_helper_1e0i(name, ret, arg1) do { \
1039 TCGv_i32 helper_tmp = tcg_const_i32(arg1); \
1040 gen_helper_##name(ret, cpu_env, helper_tmp); \
1041 tcg_temp_free_i32(helper_tmp); \
1044 #define gen_helper_1e1i(name, ret, arg1, arg2) do { \
1045 TCGv_i32 helper_tmp = tcg_const_i32(arg2); \
1046 gen_helper_##name(ret, cpu_env, arg1, helper_tmp); \
1047 tcg_temp_free_i32(helper_tmp); \
1050 #define gen_helper_0e2i(name, arg1, arg2, arg3) do { \
1051 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1052 gen_helper_##name(cpu_env, arg1, arg2, helper_tmp); \
1053 tcg_temp_free_i32(helper_tmp); \
1056 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do { \
1057 TCGv_i32 helper_tmp = tcg_const_i32(arg3); \
1058 gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp); \
1059 tcg_temp_free_i32(helper_tmp); \
1062 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do { \
1063 TCGv_i32 helper_tmp = tcg_const_i32(arg4); \
1064 gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp); \
1065 tcg_temp_free_i32(helper_tmp); \
1068 typedef struct DisasContext
{
1069 struct TranslationBlock
*tb
;
1070 target_ulong pc
, saved_pc
;
1072 int singlestep_enabled
;
1074 int32_t CP0_Config1
;
1075 /* Routine used to access memory */
1077 uint32_t hflags
, saved_hflags
;
1079 target_ulong btarget
;
1084 BS_NONE
= 0, /* We go out of the TB without reaching a branch or an
1085 * exception condition */
1086 BS_STOP
= 1, /* We want to stop translation for any reason */
1087 BS_BRANCH
= 2, /* We reached a branch condition */
1088 BS_EXCP
= 3, /* We reached an exception condition */
1091 static const char * const regnames
[] = {
1092 "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1093 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1094 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1095 "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1098 static const char * const regnames_HI
[] = {
1099 "HI0", "HI1", "HI2", "HI3",
1102 static const char * const regnames_LO
[] = {
1103 "LO0", "LO1", "LO2", "LO3",
1106 static const char * const regnames_ACX
[] = {
1107 "ACX0", "ACX1", "ACX2", "ACX3",
1110 static const char * const fregnames
[] = {
1111 "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
1112 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
1113 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1114 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1117 #define MIPS_DEBUG(fmt, ...) \
1119 if (MIPS_DEBUG_DISAS) { \
1120 qemu_log_mask(CPU_LOG_TB_IN_ASM, \
1121 TARGET_FMT_lx ": %08x " fmt "\n", \
1122 ctx->pc, ctx->opcode , ## __VA_ARGS__); \
1126 #define LOG_DISAS(...) \
1128 if (MIPS_DEBUG_DISAS) { \
1129 qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__); \
1133 #define MIPS_INVAL(op) \
1134 MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26, \
1135 ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1137 /* General purpose registers moves. */
1138 static inline void gen_load_gpr (TCGv t
, int reg
)
1141 tcg_gen_movi_tl(t
, 0);
1143 tcg_gen_mov_tl(t
, cpu_gpr
[reg
]);
1146 static inline void gen_store_gpr (TCGv t
, int reg
)
1149 tcg_gen_mov_tl(cpu_gpr
[reg
], t
);
1152 /* Moves to/from ACX register. */
1153 static inline void gen_load_ACX (TCGv t
, int reg
)
1155 tcg_gen_mov_tl(t
, cpu_ACX
[reg
]);
1158 static inline void gen_store_ACX (TCGv t
, int reg
)
1160 tcg_gen_mov_tl(cpu_ACX
[reg
], t
);
1163 /* Moves to/from shadow registers. */
1164 static inline void gen_load_srsgpr (int from
, int to
)
1166 TCGv t0
= tcg_temp_new();
1169 tcg_gen_movi_tl(t0
, 0);
1171 TCGv_i32 t2
= tcg_temp_new_i32();
1172 TCGv_ptr addr
= tcg_temp_new_ptr();
1174 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1175 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1176 tcg_gen_andi_i32(t2
, t2
, 0xf);
1177 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1178 tcg_gen_ext_i32_ptr(addr
, t2
);
1179 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1181 tcg_gen_ld_tl(t0
, addr
, sizeof(target_ulong
) * from
);
1182 tcg_temp_free_ptr(addr
);
1183 tcg_temp_free_i32(t2
);
1185 gen_store_gpr(t0
, to
);
1189 static inline void gen_store_srsgpr (int from
, int to
)
1192 TCGv t0
= tcg_temp_new();
1193 TCGv_i32 t2
= tcg_temp_new_i32();
1194 TCGv_ptr addr
= tcg_temp_new_ptr();
1196 gen_load_gpr(t0
, from
);
1197 tcg_gen_ld_i32(t2
, cpu_env
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
1198 tcg_gen_shri_i32(t2
, t2
, CP0SRSCtl_PSS
);
1199 tcg_gen_andi_i32(t2
, t2
, 0xf);
1200 tcg_gen_muli_i32(t2
, t2
, sizeof(target_ulong
) * 32);
1201 tcg_gen_ext_i32_ptr(addr
, t2
);
1202 tcg_gen_add_ptr(addr
, cpu_env
, addr
);
1204 tcg_gen_st_tl(t0
, addr
, sizeof(target_ulong
) * to
);
1205 tcg_temp_free_ptr(addr
);
1206 tcg_temp_free_i32(t2
);
1211 /* Floating point register moves. */
1212 static void gen_load_fpr32(TCGv_i32 t
, int reg
)
1214 tcg_gen_trunc_i64_i32(t
, fpu_f64
[reg
]);
1217 static void gen_store_fpr32(TCGv_i32 t
, int reg
)
1219 TCGv_i64 t64
= tcg_temp_new_i64();
1220 tcg_gen_extu_i32_i64(t64
, t
);
1221 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 0, 32);
1222 tcg_temp_free_i64(t64
);
1225 static void gen_load_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1227 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1228 TCGv_i64 t64
= tcg_temp_new_i64();
1229 tcg_gen_shri_i64(t64
, fpu_f64
[reg
], 32);
1230 tcg_gen_trunc_i64_i32(t
, t64
);
1231 tcg_temp_free_i64(t64
);
1233 gen_load_fpr32(t
, reg
| 1);
1237 static void gen_store_fpr32h(DisasContext
*ctx
, TCGv_i32 t
, int reg
)
1239 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1240 TCGv_i64 t64
= tcg_temp_new_i64();
1241 tcg_gen_extu_i32_i64(t64
, t
);
1242 tcg_gen_deposit_i64(fpu_f64
[reg
], fpu_f64
[reg
], t64
, 32, 32);
1243 tcg_temp_free_i64(t64
);
1245 gen_store_fpr32(t
, reg
| 1);
1249 static void gen_load_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1251 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1252 tcg_gen_mov_i64(t
, fpu_f64
[reg
]);
1254 tcg_gen_concat32_i64(t
, fpu_f64
[reg
& ~1], fpu_f64
[reg
| 1]);
1258 static void gen_store_fpr64(DisasContext
*ctx
, TCGv_i64 t
, int reg
)
1260 if (ctx
->hflags
& MIPS_HFLAG_F64
) {
1261 tcg_gen_mov_i64(fpu_f64
[reg
], t
);
1264 tcg_gen_deposit_i64(fpu_f64
[reg
& ~1], fpu_f64
[reg
& ~1], t
, 0, 32);
1265 t0
= tcg_temp_new_i64();
1266 tcg_gen_shri_i64(t0
, t
, 32);
1267 tcg_gen_deposit_i64(fpu_f64
[reg
| 1], fpu_f64
[reg
| 1], t0
, 0, 32);
1268 tcg_temp_free_i64(t0
);
1272 static inline int get_fp_bit (int cc
)
1281 static inline void gen_save_pc(target_ulong pc
)
1283 tcg_gen_movi_tl(cpu_PC
, pc
);
1286 static inline void save_cpu_state (DisasContext
*ctx
, int do_save_pc
)
1288 LOG_DISAS("hflags %08x saved %08x\n", ctx
->hflags
, ctx
->saved_hflags
);
1289 if (do_save_pc
&& ctx
->pc
!= ctx
->saved_pc
) {
1290 gen_save_pc(ctx
->pc
);
1291 ctx
->saved_pc
= ctx
->pc
;
1293 if (ctx
->hflags
!= ctx
->saved_hflags
) {
1294 tcg_gen_movi_i32(hflags
, ctx
->hflags
);
1295 ctx
->saved_hflags
= ctx
->hflags
;
1296 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1302 tcg_gen_movi_tl(btarget
, ctx
->btarget
);
1308 static inline void restore_cpu_state (CPUMIPSState
*env
, DisasContext
*ctx
)
1310 ctx
->saved_hflags
= ctx
->hflags
;
1311 switch (ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
1317 ctx
->btarget
= env
->btarget
;
1323 generate_exception_err (DisasContext
*ctx
, int excp
, int err
)
1325 TCGv_i32 texcp
= tcg_const_i32(excp
);
1326 TCGv_i32 terr
= tcg_const_i32(err
);
1327 save_cpu_state(ctx
, 1);
1328 gen_helper_raise_exception_err(cpu_env
, texcp
, terr
);
1329 tcg_temp_free_i32(terr
);
1330 tcg_temp_free_i32(texcp
);
1334 generate_exception (DisasContext
*ctx
, int excp
)
1336 save_cpu_state(ctx
, 1);
1337 gen_helper_0e0i(raise_exception
, excp
);
1340 /* Addresses computation */
1341 static inline void gen_op_addr_add (DisasContext
*ctx
, TCGv ret
, TCGv arg0
, TCGv arg1
)
1343 tcg_gen_add_tl(ret
, arg0
, arg1
);
1345 #if defined(TARGET_MIPS64)
1346 /* For compatibility with 32-bit code, data reference in user mode
1347 with Status_UX = 0 should be casted to 32-bit and sign extended.
1348 See the MIPS64 PRA manual, section 4.10. */
1349 if (((ctx
->hflags
& MIPS_HFLAG_KSU
) == MIPS_HFLAG_UM
) &&
1350 !(ctx
->hflags
& MIPS_HFLAG_UX
)) {
1351 tcg_gen_ext32s_i64(ret
, ret
);
1356 static inline void check_cp0_enabled(DisasContext
*ctx
)
1358 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_CP0
)))
1359 generate_exception_err(ctx
, EXCP_CpU
, 0);
1362 static inline void check_cp1_enabled(DisasContext
*ctx
)
1364 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_FPU
)))
1365 generate_exception_err(ctx
, EXCP_CpU
, 1);
1368 /* Verify that the processor is running with COP1X instructions enabled.
1369 This is associated with the nabla symbol in the MIPS32 and MIPS64
1372 static inline void check_cop1x(DisasContext
*ctx
)
1374 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_COP1X
)))
1375 generate_exception(ctx
, EXCP_RI
);
1378 /* Verify that the processor is running with 64-bit floating-point
1379 operations enabled. */
1381 static inline void check_cp1_64bitmode(DisasContext
*ctx
)
1383 if (unlikely(~ctx
->hflags
& (MIPS_HFLAG_F64
| MIPS_HFLAG_COP1X
)))
1384 generate_exception(ctx
, EXCP_RI
);
1388 * Verify if floating point register is valid; an operation is not defined
1389 * if bit 0 of any register specification is set and the FR bit in the
1390 * Status register equals zero, since the register numbers specify an
1391 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1392 * in the Status register equals one, both even and odd register numbers
1393 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1395 * Multiple 64 bit wide registers can be checked by calling
1396 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1398 static inline void check_cp1_registers(DisasContext
*ctx
, int regs
)
1400 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_F64
) && (regs
& 1)))
1401 generate_exception(ctx
, EXCP_RI
);
1404 /* Verify that the processor is running with DSP instructions enabled.
1405 This is enabled by CP0 Status register MX(24) bit.
1408 static inline void check_dsp(DisasContext
*ctx
)
1410 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSP
))) {
1411 if (ctx
->insn_flags
& ASE_DSP
) {
1412 generate_exception(ctx
, EXCP_DSPDIS
);
1414 generate_exception(ctx
, EXCP_RI
);
1419 static inline void check_dspr2(DisasContext
*ctx
)
1421 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_DSPR2
))) {
1422 if (ctx
->insn_flags
& ASE_DSP
) {
1423 generate_exception(ctx
, EXCP_DSPDIS
);
1425 generate_exception(ctx
, EXCP_RI
);
1430 /* This code generates a "reserved instruction" exception if the
1431 CPU does not support the instruction set corresponding to flags. */
1432 static inline void check_insn(DisasContext
*ctx
, int flags
)
1434 if (unlikely(!(ctx
->insn_flags
& flags
))) {
1435 generate_exception(ctx
, EXCP_RI
);
1439 /* This code generates a "reserved instruction" exception if 64-bit
1440 instructions are not enabled. */
1441 static inline void check_mips_64(DisasContext
*ctx
)
1443 if (unlikely(!(ctx
->hflags
& MIPS_HFLAG_64
)))
1444 generate_exception(ctx
, EXCP_RI
);
1447 /* Define small wrappers for gen_load_fpr* so that we have a uniform
1448 calling interface for 32 and 64-bit FPRs. No sense in changing
1449 all callers for gen_load_fpr32 when we need the CTX parameter for
1451 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1452 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1453 #define FOP_CONDS(type, abs, fmt, ifmt, bits) \
1454 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n, \
1455 int ft, int fs, int cc) \
1457 TCGv_i##bits fp0 = tcg_temp_new_i##bits (); \
1458 TCGv_i##bits fp1 = tcg_temp_new_i##bits (); \
1461 check_cp1_64bitmode(ctx); \
1467 check_cp1_registers(ctx, fs | ft); \
1475 gen_ldcmp_fpr##bits (ctx, fp0, fs); \
1476 gen_ldcmp_fpr##bits (ctx, fp1, ft); \
1478 case 0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc); break;\
1479 case 1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc); break;\
1480 case 2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc); break;\
1481 case 3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc); break;\
1482 case 4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc); break;\
1483 case 5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc); break;\
1484 case 6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc); break;\
1485 case 7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc); break;\
1486 case 8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc); break;\
1487 case 9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1488 case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc); break;\
1489 case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc); break;\
1490 case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc); break;\
1491 case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc); break;\
1492 case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc); break;\
1493 case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc); break;\
1496 tcg_temp_free_i##bits (fp0); \
1497 tcg_temp_free_i##bits (fp1); \
1500 FOP_CONDS(, 0, d
, FMT_D
, 64)
1501 FOP_CONDS(abs
, 1, d
, FMT_D
, 64)
1502 FOP_CONDS(, 0, s
, FMT_S
, 32)
1503 FOP_CONDS(abs
, 1, s
, FMT_S
, 32)
1504 FOP_CONDS(, 0, ps
, FMT_PS
, 64)
1505 FOP_CONDS(abs
, 1, ps
, FMT_PS
, 64)
1507 #undef gen_ldcmp_fpr32
1508 #undef gen_ldcmp_fpr64
1510 /* load/store instructions. */
1511 #ifdef CONFIG_USER_ONLY
1512 #define OP_LD_ATOMIC(insn,fname) \
1513 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1515 TCGv t0 = tcg_temp_new(); \
1516 tcg_gen_mov_tl(t0, arg1); \
1517 tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx); \
1518 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1519 tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval)); \
1520 tcg_temp_free(t0); \
1523 #define OP_LD_ATOMIC(insn,fname) \
1524 static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
1526 gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
1529 OP_LD_ATOMIC(ll
,ld32s
);
1530 #if defined(TARGET_MIPS64)
1531 OP_LD_ATOMIC(lld
,ld64
);
1535 #ifdef CONFIG_USER_ONLY
1536 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1537 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1539 TCGv t0 = tcg_temp_new(); \
1540 int l1 = gen_new_label(); \
1541 int l2 = gen_new_label(); \
1543 tcg_gen_andi_tl(t0, arg2, almask); \
1544 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1); \
1545 tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr)); \
1546 generate_exception(ctx, EXCP_AdES); \
1547 gen_set_label(l1); \
1548 tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr)); \
1549 tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2); \
1550 tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20)); \
1551 tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg)); \
1552 tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval)); \
1553 gen_helper_0e0i(raise_exception, EXCP_SC); \
1554 gen_set_label(l2); \
1555 tcg_gen_movi_tl(t0, 0); \
1556 gen_store_gpr(t0, rt); \
1557 tcg_temp_free(t0); \
1560 #define OP_ST_ATOMIC(insn,fname,ldname,almask) \
1561 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1563 TCGv t0 = tcg_temp_new(); \
1564 gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
1565 gen_store_gpr(t0, rt); \
1566 tcg_temp_free(t0); \
1569 OP_ST_ATOMIC(sc
,st32
,ld32s
,0x3);
1570 #if defined(TARGET_MIPS64)
1571 OP_ST_ATOMIC(scd
,st64
,ld64
,0x7);
1575 static void gen_base_offset_addr (DisasContext
*ctx
, TCGv addr
,
1576 int base
, int16_t offset
)
1579 tcg_gen_movi_tl(addr
, offset
);
1580 } else if (offset
== 0) {
1581 gen_load_gpr(addr
, base
);
1583 tcg_gen_movi_tl(addr
, offset
);
1584 gen_op_addr_add(ctx
, addr
, cpu_gpr
[base
], addr
);
1588 static target_ulong
pc_relative_pc (DisasContext
*ctx
)
1590 target_ulong pc
= ctx
->pc
;
1592 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
1593 int branch_bytes
= ctx
->hflags
& MIPS_HFLAG_BDS16
? 2 : 4;
1598 pc
&= ~(target_ulong
)3;
1603 static void gen_ld(DisasContext
*ctx
, uint32_t opc
,
1604 int rt
, int base
, int16_t offset
)
1606 const char *opn
= "ld";
1609 if (rt
== 0 && ctx
->insn_flags
& (INSN_LOONGSON2E
| INSN_LOONGSON2F
)) {
1610 /* Loongson CPU uses a load to zero register for prefetch.
1611 We emulate it as a NOP. On other CPU we must perform the
1612 actual memory access. */
1617 t0
= tcg_temp_new();
1618 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1621 #if defined(TARGET_MIPS64)
1623 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1624 gen_store_gpr(t0
, rt
);
1628 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1629 gen_store_gpr(t0
, rt
);
1633 save_cpu_state(ctx
, 1);
1634 op_ld_lld(t0
, t0
, ctx
);
1635 gen_store_gpr(t0
, rt
);
1639 t1
= tcg_temp_new();
1640 tcg_gen_andi_tl(t1
, t0
, 7);
1641 #ifndef TARGET_WORDS_BIGENDIAN
1642 tcg_gen_xori_tl(t1
, t1
, 7);
1644 tcg_gen_shli_tl(t1
, t1
, 3);
1645 tcg_gen_andi_tl(t0
, t0
, ~7);
1646 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1647 tcg_gen_shl_tl(t0
, t0
, t1
);
1648 tcg_gen_xori_tl(t1
, t1
, 63);
1649 t2
= tcg_const_tl(0x7fffffffffffffffull
);
1650 tcg_gen_shr_tl(t2
, t2
, t1
);
1651 gen_load_gpr(t1
, rt
);
1652 tcg_gen_and_tl(t1
, t1
, t2
);
1654 tcg_gen_or_tl(t0
, t0
, t1
);
1656 gen_store_gpr(t0
, rt
);
1660 t1
= tcg_temp_new();
1661 tcg_gen_andi_tl(t1
, t0
, 7);
1662 #ifdef TARGET_WORDS_BIGENDIAN
1663 tcg_gen_xori_tl(t1
, t1
, 7);
1665 tcg_gen_shli_tl(t1
, t1
, 3);
1666 tcg_gen_andi_tl(t0
, t0
, ~7);
1667 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1668 tcg_gen_shr_tl(t0
, t0
, t1
);
1669 tcg_gen_xori_tl(t1
, t1
, 63);
1670 t2
= tcg_const_tl(0xfffffffffffffffeull
);
1671 tcg_gen_shl_tl(t2
, t2
, t1
);
1672 gen_load_gpr(t1
, rt
);
1673 tcg_gen_and_tl(t1
, t1
, t2
);
1675 tcg_gen_or_tl(t0
, t0
, t1
);
1677 gen_store_gpr(t0
, rt
);
1681 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1682 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1684 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1685 gen_store_gpr(t0
, rt
);
1690 t1
= tcg_const_tl(pc_relative_pc(ctx
));
1691 gen_op_addr_add(ctx
, t0
, t0
, t1
);
1693 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1694 gen_store_gpr(t0
, rt
);
1698 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
1699 gen_store_gpr(t0
, rt
);
1703 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
1704 gen_store_gpr(t0
, rt
);
1708 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUW
);
1709 gen_store_gpr(t0
, rt
);
1713 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_SB
);
1714 gen_store_gpr(t0
, rt
);
1718 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
1719 gen_store_gpr(t0
, rt
);
1723 t1
= tcg_temp_new();
1724 tcg_gen_andi_tl(t1
, t0
, 3);
1725 #ifndef TARGET_WORDS_BIGENDIAN
1726 tcg_gen_xori_tl(t1
, t1
, 3);
1728 tcg_gen_shli_tl(t1
, t1
, 3);
1729 tcg_gen_andi_tl(t0
, t0
, ~3);
1730 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1731 tcg_gen_shl_tl(t0
, t0
, t1
);
1732 tcg_gen_xori_tl(t1
, t1
, 31);
1733 t2
= tcg_const_tl(0x7fffffffull
);
1734 tcg_gen_shr_tl(t2
, t2
, t1
);
1735 gen_load_gpr(t1
, rt
);
1736 tcg_gen_and_tl(t1
, t1
, t2
);
1738 tcg_gen_or_tl(t0
, t0
, t1
);
1740 tcg_gen_ext32s_tl(t0
, t0
);
1741 gen_store_gpr(t0
, rt
);
1745 t1
= tcg_temp_new();
1746 tcg_gen_andi_tl(t1
, t0
, 3);
1747 #ifdef TARGET_WORDS_BIGENDIAN
1748 tcg_gen_xori_tl(t1
, t1
, 3);
1750 tcg_gen_shli_tl(t1
, t1
, 3);
1751 tcg_gen_andi_tl(t0
, t0
, ~3);
1752 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1753 tcg_gen_shr_tl(t0
, t0
, t1
);
1754 tcg_gen_xori_tl(t1
, t1
, 31);
1755 t2
= tcg_const_tl(0xfffffffeull
);
1756 tcg_gen_shl_tl(t2
, t2
, t1
);
1757 gen_load_gpr(t1
, rt
);
1758 tcg_gen_and_tl(t1
, t1
, t2
);
1760 tcg_gen_or_tl(t0
, t0
, t1
);
1762 tcg_gen_ext32s_tl(t0
, t0
);
1763 gen_store_gpr(t0
, rt
);
1767 save_cpu_state(ctx
, 1);
1768 op_ld_ll(t0
, t0
, ctx
);
1769 gen_store_gpr(t0
, rt
);
1773 (void)opn
; /* avoid a compiler warning */
1774 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1779 static void gen_st (DisasContext
*ctx
, uint32_t opc
, int rt
,
1780 int base
, int16_t offset
)
1782 const char *opn
= "st";
1783 TCGv t0
= tcg_temp_new();
1784 TCGv t1
= tcg_temp_new();
1786 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1787 gen_load_gpr(t1
, rt
);
1789 #if defined(TARGET_MIPS64)
1791 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
1795 save_cpu_state(ctx
, 1);
1796 gen_helper_0e2i(sdl
, t1
, t0
, ctx
->mem_idx
);
1800 save_cpu_state(ctx
, 1);
1801 gen_helper_0e2i(sdr
, t1
, t0
, ctx
->mem_idx
);
1806 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
1810 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUW
);
1814 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_8
);
1818 save_cpu_state(ctx
, 1);
1819 gen_helper_0e2i(swl
, t1
, t0
, ctx
->mem_idx
);
1823 save_cpu_state(ctx
, 1);
1824 gen_helper_0e2i(swr
, t1
, t0
, ctx
->mem_idx
);
1828 (void)opn
; /* avoid a compiler warning */
1829 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1835 /* Store conditional */
1836 static void gen_st_cond (DisasContext
*ctx
, uint32_t opc
, int rt
,
1837 int base
, int16_t offset
)
1839 const char *opn
= "st_cond";
1842 #ifdef CONFIG_USER_ONLY
1843 t0
= tcg_temp_local_new();
1844 t1
= tcg_temp_local_new();
1846 t0
= tcg_temp_new();
1847 t1
= tcg_temp_new();
1849 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1850 gen_load_gpr(t1
, rt
);
1852 #if defined(TARGET_MIPS64)
1854 save_cpu_state(ctx
, 1);
1855 op_st_scd(t1
, t0
, rt
, ctx
);
1860 save_cpu_state(ctx
, 1);
1861 op_st_sc(t1
, t0
, rt
, ctx
);
1865 (void)opn
; /* avoid a compiler warning */
1866 MIPS_DEBUG("%s %s, %d(%s)", opn
, regnames
[rt
], offset
, regnames
[base
]);
1871 /* Load and store */
1872 static void gen_flt_ldst (DisasContext
*ctx
, uint32_t opc
, int ft
,
1873 int base
, int16_t offset
)
1875 const char *opn
= "flt_ldst";
1876 TCGv t0
= tcg_temp_new();
1878 gen_base_offset_addr(ctx
, t0
, base
, offset
);
1879 /* Don't do NOP if destination is zero: we must perform the actual
1884 TCGv_i32 fp0
= tcg_temp_new_i32();
1885 tcg_gen_qemu_ld_i32(fp0
, t0
, ctx
->mem_idx
, MO_TESL
);
1886 gen_store_fpr32(fp0
, ft
);
1887 tcg_temp_free_i32(fp0
);
1893 TCGv_i32 fp0
= tcg_temp_new_i32();
1894 gen_load_fpr32(fp0
, ft
);
1895 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
1896 tcg_temp_free_i32(fp0
);
1902 TCGv_i64 fp0
= tcg_temp_new_i64();
1903 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1904 gen_store_fpr64(ctx
, fp0
, ft
);
1905 tcg_temp_free_i64(fp0
);
1911 TCGv_i64 fp0
= tcg_temp_new_i64();
1912 gen_load_fpr64(ctx
, fp0
, ft
);
1913 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
1914 tcg_temp_free_i64(fp0
);
1920 generate_exception(ctx
, EXCP_RI
);
1923 (void)opn
; /* avoid a compiler warning */
1924 MIPS_DEBUG("%s %s, %d(%s)", opn
, fregnames
[ft
], offset
, regnames
[base
]);
1929 static void gen_cop1_ldst(DisasContext
*ctx
, uint32_t op
, int rt
,
1930 int rs
, int16_t imm
)
1932 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
1933 check_cp1_enabled(ctx
);
1934 gen_flt_ldst(ctx
, op
, rt
, rs
, imm
);
1936 generate_exception_err(ctx
, EXCP_CpU
, 1);
1940 /* Arithmetic with immediate operand */
1941 static void gen_arith_imm(DisasContext
*ctx
, uint32_t opc
,
1942 int rt
, int rs
, int16_t imm
)
1944 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
1945 const char *opn
= "imm arith";
1947 if (rt
== 0 && opc
!= OPC_ADDI
&& opc
!= OPC_DADDI
) {
1948 /* If no destination, treat it as a NOP.
1949 For addi, we must generate the overflow exception when needed. */
1956 TCGv t0
= tcg_temp_local_new();
1957 TCGv t1
= tcg_temp_new();
1958 TCGv t2
= tcg_temp_new();
1959 int l1
= gen_new_label();
1961 gen_load_gpr(t1
, rs
);
1962 tcg_gen_addi_tl(t0
, t1
, uimm
);
1963 tcg_gen_ext32s_tl(t0
, t0
);
1965 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
1966 tcg_gen_xori_tl(t2
, t0
, uimm
);
1967 tcg_gen_and_tl(t1
, t1
, t2
);
1969 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
1971 /* operands of same sign, result different sign */
1972 generate_exception(ctx
, EXCP_OVERFLOW
);
1974 tcg_gen_ext32s_tl(t0
, t0
);
1975 gen_store_gpr(t0
, rt
);
1982 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
1983 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
1985 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
1989 #if defined(TARGET_MIPS64)
1992 TCGv t0
= tcg_temp_local_new();
1993 TCGv t1
= tcg_temp_new();
1994 TCGv t2
= tcg_temp_new();
1995 int l1
= gen_new_label();
1997 gen_load_gpr(t1
, rs
);
1998 tcg_gen_addi_tl(t0
, t1
, uimm
);
2000 tcg_gen_xori_tl(t1
, t1
, ~uimm
);
2001 tcg_gen_xori_tl(t2
, t0
, uimm
);
2002 tcg_gen_and_tl(t1
, t1
, t2
);
2004 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2006 /* operands of same sign, result different sign */
2007 generate_exception(ctx
, EXCP_OVERFLOW
);
2009 gen_store_gpr(t0
, rt
);
2016 tcg_gen_addi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2018 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2024 (void)opn
; /* avoid a compiler warning */
2025 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2028 /* Logic with immediate operand */
2029 static void gen_logic_imm(DisasContext
*ctx
, uint32_t opc
,
2030 int rt
, int rs
, int16_t imm
)
2035 /* If no destination, treat it as a NOP. */
2039 uimm
= (uint16_t)imm
;
2042 if (likely(rs
!= 0))
2043 tcg_gen_andi_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2045 tcg_gen_movi_tl(cpu_gpr
[rt
], 0);
2046 MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2047 regnames
[rs
], uimm
);
2051 tcg_gen_ori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2053 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2054 MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2055 regnames
[rs
], uimm
);
2058 if (likely(rs
!= 0))
2059 tcg_gen_xori_tl(cpu_gpr
[rt
], cpu_gpr
[rs
], uimm
);
2061 tcg_gen_movi_tl(cpu_gpr
[rt
], uimm
);
2062 MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx
, regnames
[rt
],
2063 regnames
[rs
], uimm
);
2066 tcg_gen_movi_tl(cpu_gpr
[rt
], imm
<< 16);
2067 MIPS_DEBUG("lui %s, " TARGET_FMT_lx
, regnames
[rt
], uimm
);
2071 MIPS_DEBUG("Unknown logical immediate opcode %08x", opc
);
2076 /* Set on less than with immediate operand */
2077 static void gen_slt_imm(DisasContext
*ctx
, uint32_t opc
,
2078 int rt
, int rs
, int16_t imm
)
2080 target_ulong uimm
= (target_long
)imm
; /* Sign extend to 32/64 bits */
2081 const char *opn
= "imm arith";
2085 /* If no destination, treat it as a NOP. */
2089 t0
= tcg_temp_new();
2090 gen_load_gpr(t0
, rs
);
2093 tcg_gen_setcondi_tl(TCG_COND_LT
, cpu_gpr
[rt
], t0
, uimm
);
2097 tcg_gen_setcondi_tl(TCG_COND_LTU
, cpu_gpr
[rt
], t0
, uimm
);
2101 (void)opn
; /* avoid a compiler warning */
2102 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2106 /* Shifts with immediate operand */
2107 static void gen_shift_imm(DisasContext
*ctx
, uint32_t opc
,
2108 int rt
, int rs
, int16_t imm
)
2110 target_ulong uimm
= ((uint16_t)imm
) & 0x1f;
2111 const char *opn
= "imm shift";
2115 /* If no destination, treat it as a NOP. */
2120 t0
= tcg_temp_new();
2121 gen_load_gpr(t0
, rs
);
2124 tcg_gen_shli_tl(t0
, t0
, uimm
);
2125 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2129 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2134 tcg_gen_ext32u_tl(t0
, t0
);
2135 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2137 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2143 TCGv_i32 t1
= tcg_temp_new_i32();
2145 tcg_gen_trunc_tl_i32(t1
, t0
);
2146 tcg_gen_rotri_i32(t1
, t1
, uimm
);
2147 tcg_gen_ext_i32_tl(cpu_gpr
[rt
], t1
);
2148 tcg_temp_free_i32(t1
);
2150 tcg_gen_ext32s_tl(cpu_gpr
[rt
], t0
);
2154 #if defined(TARGET_MIPS64)
2156 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
);
2160 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
);
2164 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
);
2169 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
);
2171 tcg_gen_mov_tl(cpu_gpr
[rt
], t0
);
2176 tcg_gen_shli_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2180 tcg_gen_sari_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2184 tcg_gen_shri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2188 tcg_gen_rotri_tl(cpu_gpr
[rt
], t0
, uimm
+ 32);
2193 (void)opn
; /* avoid a compiler warning */
2194 MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx
, opn
, regnames
[rt
], regnames
[rs
], uimm
);
2199 static void gen_arith(DisasContext
*ctx
, uint32_t opc
,
2200 int rd
, int rs
, int rt
)
2202 const char *opn
= "arith";
2204 if (rd
== 0 && opc
!= OPC_ADD
&& opc
!= OPC_SUB
2205 && opc
!= OPC_DADD
&& opc
!= OPC_DSUB
) {
2206 /* If no destination, treat it as a NOP.
2207 For add & sub, we must generate the overflow exception when needed. */
2215 TCGv t0
= tcg_temp_local_new();
2216 TCGv t1
= tcg_temp_new();
2217 TCGv t2
= tcg_temp_new();
2218 int l1
= gen_new_label();
2220 gen_load_gpr(t1
, rs
);
2221 gen_load_gpr(t2
, rt
);
2222 tcg_gen_add_tl(t0
, t1
, t2
);
2223 tcg_gen_ext32s_tl(t0
, t0
);
2224 tcg_gen_xor_tl(t1
, t1
, t2
);
2225 tcg_gen_xor_tl(t2
, t0
, t2
);
2226 tcg_gen_andc_tl(t1
, t2
, t1
);
2228 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2230 /* operands of same sign, result different sign */
2231 generate_exception(ctx
, EXCP_OVERFLOW
);
2233 gen_store_gpr(t0
, rd
);
2239 if (rs
!= 0 && rt
!= 0) {
2240 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2241 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2242 } else if (rs
== 0 && rt
!= 0) {
2243 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2244 } else if (rs
!= 0 && rt
== 0) {
2245 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2247 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2253 TCGv t0
= tcg_temp_local_new();
2254 TCGv t1
= tcg_temp_new();
2255 TCGv t2
= tcg_temp_new();
2256 int l1
= gen_new_label();
2258 gen_load_gpr(t1
, rs
);
2259 gen_load_gpr(t2
, rt
);
2260 tcg_gen_sub_tl(t0
, t1
, t2
);
2261 tcg_gen_ext32s_tl(t0
, t0
);
2262 tcg_gen_xor_tl(t2
, t1
, t2
);
2263 tcg_gen_xor_tl(t1
, t0
, t1
);
2264 tcg_gen_and_tl(t1
, t1
, t2
);
2266 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2268 /* operands of different sign, first operand and result different sign */
2269 generate_exception(ctx
, EXCP_OVERFLOW
);
2271 gen_store_gpr(t0
, rd
);
2277 if (rs
!= 0 && rt
!= 0) {
2278 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2279 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2280 } else if (rs
== 0 && rt
!= 0) {
2281 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2282 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2283 } else if (rs
!= 0 && rt
== 0) {
2284 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2286 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2290 #if defined(TARGET_MIPS64)
2293 TCGv t0
= tcg_temp_local_new();
2294 TCGv t1
= tcg_temp_new();
2295 TCGv t2
= tcg_temp_new();
2296 int l1
= gen_new_label();
2298 gen_load_gpr(t1
, rs
);
2299 gen_load_gpr(t2
, rt
);
2300 tcg_gen_add_tl(t0
, t1
, t2
);
2301 tcg_gen_xor_tl(t1
, t1
, t2
);
2302 tcg_gen_xor_tl(t2
, t0
, t2
);
2303 tcg_gen_andc_tl(t1
, t2
, t1
);
2305 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2307 /* operands of same sign, result different sign */
2308 generate_exception(ctx
, EXCP_OVERFLOW
);
2310 gen_store_gpr(t0
, rd
);
2316 if (rs
!= 0 && rt
!= 0) {
2317 tcg_gen_add_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2318 } else if (rs
== 0 && rt
!= 0) {
2319 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2320 } else if (rs
!= 0 && rt
== 0) {
2321 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2323 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2329 TCGv t0
= tcg_temp_local_new();
2330 TCGv t1
= tcg_temp_new();
2331 TCGv t2
= tcg_temp_new();
2332 int l1
= gen_new_label();
2334 gen_load_gpr(t1
, rs
);
2335 gen_load_gpr(t2
, rt
);
2336 tcg_gen_sub_tl(t0
, t1
, t2
);
2337 tcg_gen_xor_tl(t2
, t1
, t2
);
2338 tcg_gen_xor_tl(t1
, t0
, t1
);
2339 tcg_gen_and_tl(t1
, t1
, t2
);
2341 tcg_gen_brcondi_tl(TCG_COND_GE
, t1
, 0, l1
);
2343 /* operands of different sign, first operand and result different sign */
2344 generate_exception(ctx
, EXCP_OVERFLOW
);
2346 gen_store_gpr(t0
, rd
);
2352 if (rs
!= 0 && rt
!= 0) {
2353 tcg_gen_sub_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2354 } else if (rs
== 0 && rt
!= 0) {
2355 tcg_gen_neg_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2356 } else if (rs
!= 0 && rt
== 0) {
2357 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2359 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2365 if (likely(rs
!= 0 && rt
!= 0)) {
2366 tcg_gen_mul_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2367 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
2369 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2374 (void)opn
; /* avoid a compiler warning */
2375 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2378 /* Conditional move */
2379 static void gen_cond_move(DisasContext
*ctx
, uint32_t opc
,
2380 int rd
, int rs
, int rt
)
2382 const char *opn
= "cond move";
2386 /* If no destination, treat it as a NOP. */
2391 t0
= tcg_temp_new();
2392 gen_load_gpr(t0
, rt
);
2393 t1
= tcg_const_tl(0);
2394 t2
= tcg_temp_new();
2395 gen_load_gpr(t2
, rs
);
2398 tcg_gen_movcond_tl(TCG_COND_NE
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2402 tcg_gen_movcond_tl(TCG_COND_EQ
, cpu_gpr
[rd
], t0
, t1
, t2
, cpu_gpr
[rd
]);
2410 (void)opn
; /* avoid a compiler warning */
2411 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2415 static void gen_logic(DisasContext
*ctx
, uint32_t opc
,
2416 int rd
, int rs
, int rt
)
2418 const char *opn
= "logic";
2421 /* If no destination, treat it as a NOP. */
2428 if (likely(rs
!= 0 && rt
!= 0)) {
2429 tcg_gen_and_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2431 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2436 if (rs
!= 0 && rt
!= 0) {
2437 tcg_gen_nor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2438 } else if (rs
== 0 && rt
!= 0) {
2439 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2440 } else if (rs
!= 0 && rt
== 0) {
2441 tcg_gen_not_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2443 tcg_gen_movi_tl(cpu_gpr
[rd
], ~((target_ulong
)0));
2448 if (likely(rs
!= 0 && rt
!= 0)) {
2449 tcg_gen_or_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2450 } else if (rs
== 0 && rt
!= 0) {
2451 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2452 } else if (rs
!= 0 && rt
== 0) {
2453 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2455 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2460 if (likely(rs
!= 0 && rt
!= 0)) {
2461 tcg_gen_xor_tl(cpu_gpr
[rd
], cpu_gpr
[rs
], cpu_gpr
[rt
]);
2462 } else if (rs
== 0 && rt
!= 0) {
2463 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rt
]);
2464 } else if (rs
!= 0 && rt
== 0) {
2465 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
2467 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
2472 (void)opn
; /* avoid a compiler warning */
2473 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2476 /* Set on lower than */
2477 static void gen_slt(DisasContext
*ctx
, uint32_t opc
,
2478 int rd
, int rs
, int rt
)
2480 const char *opn
= "slt";
2484 /* If no destination, treat it as a NOP. */
2489 t0
= tcg_temp_new();
2490 t1
= tcg_temp_new();
2491 gen_load_gpr(t0
, rs
);
2492 gen_load_gpr(t1
, rt
);
2495 tcg_gen_setcond_tl(TCG_COND_LT
, cpu_gpr
[rd
], t0
, t1
);
2499 tcg_gen_setcond_tl(TCG_COND_LTU
, cpu_gpr
[rd
], t0
, t1
);
2503 (void)opn
; /* avoid a compiler warning */
2504 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2510 static void gen_shift(DisasContext
*ctx
, uint32_t opc
,
2511 int rd
, int rs
, int rt
)
2513 const char *opn
= "shifts";
2517 /* If no destination, treat it as a NOP.
2518 For add & sub, we must generate the overflow exception when needed. */
2523 t0
= tcg_temp_new();
2524 t1
= tcg_temp_new();
2525 gen_load_gpr(t0
, rs
);
2526 gen_load_gpr(t1
, rt
);
2529 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2530 tcg_gen_shl_tl(t0
, t1
, t0
);
2531 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2535 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2536 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2540 tcg_gen_ext32u_tl(t1
, t1
);
2541 tcg_gen_andi_tl(t0
, t0
, 0x1f);
2542 tcg_gen_shr_tl(t0
, t1
, t0
);
2543 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
2548 TCGv_i32 t2
= tcg_temp_new_i32();
2549 TCGv_i32 t3
= tcg_temp_new_i32();
2551 tcg_gen_trunc_tl_i32(t2
, t0
);
2552 tcg_gen_trunc_tl_i32(t3
, t1
);
2553 tcg_gen_andi_i32(t2
, t2
, 0x1f);
2554 tcg_gen_rotr_i32(t2
, t3
, t2
);
2555 tcg_gen_ext_i32_tl(cpu_gpr
[rd
], t2
);
2556 tcg_temp_free_i32(t2
);
2557 tcg_temp_free_i32(t3
);
2561 #if defined(TARGET_MIPS64)
2563 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2564 tcg_gen_shl_tl(cpu_gpr
[rd
], t1
, t0
);
2568 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2569 tcg_gen_sar_tl(cpu_gpr
[rd
], t1
, t0
);
2573 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2574 tcg_gen_shr_tl(cpu_gpr
[rd
], t1
, t0
);
2578 tcg_gen_andi_tl(t0
, t0
, 0x3f);
2579 tcg_gen_rotr_tl(cpu_gpr
[rd
], t1
, t0
);
2584 (void)opn
; /* avoid a compiler warning */
2585 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2590 /* Arithmetic on HI/LO registers */
2591 static void gen_HILO(DisasContext
*ctx
, uint32_t opc
, int acc
, int reg
)
2593 const char *opn
= "hilo";
2595 if (reg
== 0 && (opc
== OPC_MFHI
|| opc
== OPC_MFLO
)) {
2607 #if defined(TARGET_MIPS64)
2609 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2613 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_HI
[acc
]);
2618 #if defined(TARGET_MIPS64)
2620 tcg_gen_ext32s_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2624 tcg_gen_mov_tl(cpu_gpr
[reg
], cpu_LO
[acc
]);
2630 #if defined(TARGET_MIPS64)
2632 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2636 tcg_gen_mov_tl(cpu_HI
[acc
], cpu_gpr
[reg
]);
2639 tcg_gen_movi_tl(cpu_HI
[acc
], 0);
2645 #if defined(TARGET_MIPS64)
2647 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2651 tcg_gen_mov_tl(cpu_LO
[acc
], cpu_gpr
[reg
]);
2654 tcg_gen_movi_tl(cpu_LO
[acc
], 0);
2659 (void)opn
; /* avoid a compiler warning */
2660 MIPS_DEBUG("%s %s", opn
, regnames
[reg
]);
2663 static void gen_muldiv(DisasContext
*ctx
, uint32_t opc
,
2664 int acc
, int rs
, int rt
)
2666 const char *opn
= "mul/div";
2669 t0
= tcg_temp_new();
2670 t1
= tcg_temp_new();
2672 gen_load_gpr(t0
, rs
);
2673 gen_load_gpr(t1
, rt
);
2682 TCGv t2
= tcg_temp_new();
2683 TCGv t3
= tcg_temp_new();
2684 tcg_gen_ext32s_tl(t0
, t0
);
2685 tcg_gen_ext32s_tl(t1
, t1
);
2686 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, INT_MIN
);
2687 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1);
2688 tcg_gen_and_tl(t2
, t2
, t3
);
2689 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2690 tcg_gen_or_tl(t2
, t2
, t3
);
2691 tcg_gen_movi_tl(t3
, 0);
2692 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2693 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2694 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2695 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2696 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2704 TCGv t2
= tcg_const_tl(0);
2705 TCGv t3
= tcg_const_tl(1);
2706 tcg_gen_ext32u_tl(t0
, t0
);
2707 tcg_gen_ext32u_tl(t1
, t1
);
2708 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2709 tcg_gen_divu_tl(cpu_LO
[acc
], t0
, t1
);
2710 tcg_gen_remu_tl(cpu_HI
[acc
], t0
, t1
);
2711 tcg_gen_ext32s_tl(cpu_LO
[acc
], cpu_LO
[acc
]);
2712 tcg_gen_ext32s_tl(cpu_HI
[acc
], cpu_HI
[acc
]);
2720 TCGv_i32 t2
= tcg_temp_new_i32();
2721 TCGv_i32 t3
= tcg_temp_new_i32();
2722 tcg_gen_trunc_tl_i32(t2
, t0
);
2723 tcg_gen_trunc_tl_i32(t3
, t1
);
2724 tcg_gen_muls2_i32(t2
, t3
, t2
, t3
);
2725 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2726 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2727 tcg_temp_free_i32(t2
);
2728 tcg_temp_free_i32(t3
);
2734 TCGv_i32 t2
= tcg_temp_new_i32();
2735 TCGv_i32 t3
= tcg_temp_new_i32();
2736 tcg_gen_trunc_tl_i32(t2
, t0
);
2737 tcg_gen_trunc_tl_i32(t3
, t1
);
2738 tcg_gen_mulu2_i32(t2
, t3
, t2
, t3
);
2739 tcg_gen_ext_i32_tl(cpu_LO
[acc
], t2
);
2740 tcg_gen_ext_i32_tl(cpu_HI
[acc
], t3
);
2741 tcg_temp_free_i32(t2
);
2742 tcg_temp_free_i32(t3
);
2746 #if defined(TARGET_MIPS64)
2749 TCGv t2
= tcg_temp_new();
2750 TCGv t3
= tcg_temp_new();
2751 tcg_gen_setcondi_tl(TCG_COND_EQ
, t2
, t0
, -1LL << 63);
2752 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, -1LL);
2753 tcg_gen_and_tl(t2
, t2
, t3
);
2754 tcg_gen_setcondi_tl(TCG_COND_EQ
, t3
, t1
, 0);
2755 tcg_gen_or_tl(t2
, t2
, t3
);
2756 tcg_gen_movi_tl(t3
, 0);
2757 tcg_gen_movcond_tl(TCG_COND_NE
, t1
, t2
, t3
, t2
, t1
);
2758 tcg_gen_div_tl(cpu_LO
[acc
], t0
, t1
);
2759 tcg_gen_rem_tl(cpu_HI
[acc
], t0
, t1
);
2767 TCGv t2
= tcg_const_tl(0);
2768 TCGv t3
= tcg_const_tl(1);
2769 tcg_gen_movcond_tl(TCG_COND_EQ
, t1
, t1
, t2
, t3
, t1
);
2770 tcg_gen_divu_i64(cpu_LO
[acc
], t0
, t1
);
2771 tcg_gen_remu_i64(cpu_HI
[acc
], t0
, t1
);
2778 tcg_gen_muls2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2782 tcg_gen_mulu2_i64(cpu_LO
[acc
], cpu_HI
[acc
], t0
, t1
);
2788 TCGv_i64 t2
= tcg_temp_new_i64();
2789 TCGv_i64 t3
= tcg_temp_new_i64();
2791 tcg_gen_ext_tl_i64(t2
, t0
);
2792 tcg_gen_ext_tl_i64(t3
, t1
);
2793 tcg_gen_mul_i64(t2
, t2
, t3
);
2794 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2795 tcg_gen_add_i64(t2
, t2
, t3
);
2796 tcg_temp_free_i64(t3
);
2797 tcg_gen_trunc_i64_tl(t0
, t2
);
2798 tcg_gen_shri_i64(t2
, t2
, 32);
2799 tcg_gen_trunc_i64_tl(t1
, t2
);
2800 tcg_temp_free_i64(t2
);
2801 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2802 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2808 TCGv_i64 t2
= tcg_temp_new_i64();
2809 TCGv_i64 t3
= tcg_temp_new_i64();
2811 tcg_gen_ext32u_tl(t0
, t0
);
2812 tcg_gen_ext32u_tl(t1
, t1
);
2813 tcg_gen_extu_tl_i64(t2
, t0
);
2814 tcg_gen_extu_tl_i64(t3
, t1
);
2815 tcg_gen_mul_i64(t2
, t2
, t3
);
2816 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2817 tcg_gen_add_i64(t2
, t2
, t3
);
2818 tcg_temp_free_i64(t3
);
2819 tcg_gen_trunc_i64_tl(t0
, t2
);
2820 tcg_gen_shri_i64(t2
, t2
, 32);
2821 tcg_gen_trunc_i64_tl(t1
, t2
);
2822 tcg_temp_free_i64(t2
);
2823 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2824 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2830 TCGv_i64 t2
= tcg_temp_new_i64();
2831 TCGv_i64 t3
= tcg_temp_new_i64();
2833 tcg_gen_ext_tl_i64(t2
, t0
);
2834 tcg_gen_ext_tl_i64(t3
, t1
);
2835 tcg_gen_mul_i64(t2
, t2
, t3
);
2836 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2837 tcg_gen_sub_i64(t2
, t3
, t2
);
2838 tcg_temp_free_i64(t3
);
2839 tcg_gen_trunc_i64_tl(t0
, t2
);
2840 tcg_gen_shri_i64(t2
, t2
, 32);
2841 tcg_gen_trunc_i64_tl(t1
, t2
);
2842 tcg_temp_free_i64(t2
);
2843 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2844 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2850 TCGv_i64 t2
= tcg_temp_new_i64();
2851 TCGv_i64 t3
= tcg_temp_new_i64();
2853 tcg_gen_ext32u_tl(t0
, t0
);
2854 tcg_gen_ext32u_tl(t1
, t1
);
2855 tcg_gen_extu_tl_i64(t2
, t0
);
2856 tcg_gen_extu_tl_i64(t3
, t1
);
2857 tcg_gen_mul_i64(t2
, t2
, t3
);
2858 tcg_gen_concat_tl_i64(t3
, cpu_LO
[acc
], cpu_HI
[acc
]);
2859 tcg_gen_sub_i64(t2
, t3
, t2
);
2860 tcg_temp_free_i64(t3
);
2861 tcg_gen_trunc_i64_tl(t0
, t2
);
2862 tcg_gen_shri_i64(t2
, t2
, 32);
2863 tcg_gen_trunc_i64_tl(t1
, t2
);
2864 tcg_temp_free_i64(t2
);
2865 tcg_gen_ext32s_tl(cpu_LO
[acc
], t0
);
2866 tcg_gen_ext32s_tl(cpu_HI
[acc
], t1
);
2872 generate_exception(ctx
, EXCP_RI
);
2875 (void)opn
; /* avoid a compiler warning */
2876 MIPS_DEBUG("%s %s %s", opn
, regnames
[rs
], regnames
[rt
]);
2882 static void gen_mul_vr54xx (DisasContext
*ctx
, uint32_t opc
,
2883 int rd
, int rs
, int rt
)
2885 const char *opn
= "mul vr54xx";
2886 TCGv t0
= tcg_temp_new();
2887 TCGv t1
= tcg_temp_new();
2889 gen_load_gpr(t0
, rs
);
2890 gen_load_gpr(t1
, rt
);
2893 case OPC_VR54XX_MULS
:
2894 gen_helper_muls(t0
, cpu_env
, t0
, t1
);
2897 case OPC_VR54XX_MULSU
:
2898 gen_helper_mulsu(t0
, cpu_env
, t0
, t1
);
2901 case OPC_VR54XX_MACC
:
2902 gen_helper_macc(t0
, cpu_env
, t0
, t1
);
2905 case OPC_VR54XX_MACCU
:
2906 gen_helper_maccu(t0
, cpu_env
, t0
, t1
);
2909 case OPC_VR54XX_MSAC
:
2910 gen_helper_msac(t0
, cpu_env
, t0
, t1
);
2913 case OPC_VR54XX_MSACU
:
2914 gen_helper_msacu(t0
, cpu_env
, t0
, t1
);
2917 case OPC_VR54XX_MULHI
:
2918 gen_helper_mulhi(t0
, cpu_env
, t0
, t1
);
2921 case OPC_VR54XX_MULHIU
:
2922 gen_helper_mulhiu(t0
, cpu_env
, t0
, t1
);
2925 case OPC_VR54XX_MULSHI
:
2926 gen_helper_mulshi(t0
, cpu_env
, t0
, t1
);
2929 case OPC_VR54XX_MULSHIU
:
2930 gen_helper_mulshiu(t0
, cpu_env
, t0
, t1
);
2933 case OPC_VR54XX_MACCHI
:
2934 gen_helper_macchi(t0
, cpu_env
, t0
, t1
);
2937 case OPC_VR54XX_MACCHIU
:
2938 gen_helper_macchiu(t0
, cpu_env
, t0
, t1
);
2941 case OPC_VR54XX_MSACHI
:
2942 gen_helper_msachi(t0
, cpu_env
, t0
, t1
);
2945 case OPC_VR54XX_MSACHIU
:
2946 gen_helper_msachiu(t0
, cpu_env
, t0
, t1
);
2950 MIPS_INVAL("mul vr54xx");
2951 generate_exception(ctx
, EXCP_RI
);
2954 gen_store_gpr(t0
, rd
);
2955 (void)opn
; /* avoid a compiler warning */
2956 MIPS_DEBUG("%s %s, %s, %s", opn
, regnames
[rd
], regnames
[rs
], regnames
[rt
]);
2963 static void gen_cl (DisasContext
*ctx
, uint32_t opc
,
2966 const char *opn
= "CLx";
2974 t0
= tcg_temp_new();
2975 gen_load_gpr(t0
, rs
);
2978 gen_helper_clo(cpu_gpr
[rd
], t0
);
2982 gen_helper_clz(cpu_gpr
[rd
], t0
);
2985 #if defined(TARGET_MIPS64)
2987 gen_helper_dclo(cpu_gpr
[rd
], t0
);
2991 gen_helper_dclz(cpu_gpr
[rd
], t0
);
2996 (void)opn
; /* avoid a compiler warning */
2997 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3001 /* Godson integer instructions */
3002 static void gen_loongson_integer(DisasContext
*ctx
, uint32_t opc
,
3003 int rd
, int rs
, int rt
)
3005 const char *opn
= "loongson";
3017 case OPC_MULTU_G_2E
:
3018 case OPC_MULTU_G_2F
:
3019 #if defined(TARGET_MIPS64)
3020 case OPC_DMULT_G_2E
:
3021 case OPC_DMULT_G_2F
:
3022 case OPC_DMULTU_G_2E
:
3023 case OPC_DMULTU_G_2F
:
3025 t0
= tcg_temp_new();
3026 t1
= tcg_temp_new();
3029 t0
= tcg_temp_local_new();
3030 t1
= tcg_temp_local_new();
3034 gen_load_gpr(t0
, rs
);
3035 gen_load_gpr(t1
, rt
);
3040 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3041 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3044 case OPC_MULTU_G_2E
:
3045 case OPC_MULTU_G_2F
:
3046 tcg_gen_ext32u_tl(t0
, t0
);
3047 tcg_gen_ext32u_tl(t1
, t1
);
3048 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3049 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3055 int l1
= gen_new_label();
3056 int l2
= gen_new_label();
3057 int l3
= gen_new_label();
3058 tcg_gen_ext32s_tl(t0
, t0
);
3059 tcg_gen_ext32s_tl(t1
, t1
);
3060 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3061 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3064 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3065 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3066 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3069 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3070 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3078 int l1
= gen_new_label();
3079 int l2
= gen_new_label();
3080 tcg_gen_ext32u_tl(t0
, t0
);
3081 tcg_gen_ext32u_tl(t1
, t1
);
3082 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3083 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3086 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3087 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3095 int l1
= gen_new_label();
3096 int l2
= gen_new_label();
3097 int l3
= gen_new_label();
3098 tcg_gen_ext32u_tl(t0
, t0
);
3099 tcg_gen_ext32u_tl(t1
, t1
);
3100 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3101 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, INT_MIN
, l2
);
3102 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1, l2
);
3104 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3107 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3108 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3116 int l1
= gen_new_label();
3117 int l2
= gen_new_label();
3118 tcg_gen_ext32u_tl(t0
, t0
);
3119 tcg_gen_ext32u_tl(t1
, t1
);
3120 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3121 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3124 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3125 tcg_gen_ext32s_tl(cpu_gpr
[rd
], cpu_gpr
[rd
]);
3130 #if defined(TARGET_MIPS64)
3131 case OPC_DMULT_G_2E
:
3132 case OPC_DMULT_G_2F
:
3133 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3136 case OPC_DMULTU_G_2E
:
3137 case OPC_DMULTU_G_2F
:
3138 tcg_gen_mul_tl(cpu_gpr
[rd
], t0
, t1
);
3144 int l1
= gen_new_label();
3145 int l2
= gen_new_label();
3146 int l3
= gen_new_label();
3147 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3148 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3151 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3152 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3153 tcg_gen_mov_tl(cpu_gpr
[rd
], t0
);
3156 tcg_gen_div_tl(cpu_gpr
[rd
], t0
, t1
);
3161 case OPC_DDIVU_G_2E
:
3162 case OPC_DDIVU_G_2F
:
3164 int l1
= gen_new_label();
3165 int l2
= gen_new_label();
3166 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3167 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3170 tcg_gen_divu_tl(cpu_gpr
[rd
], t0
, t1
);
3178 int l1
= gen_new_label();
3179 int l2
= gen_new_label();
3180 int l3
= gen_new_label();
3181 tcg_gen_brcondi_tl(TCG_COND_EQ
, t1
, 0, l1
);
3182 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, -1LL << 63, l2
);
3183 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, -1LL, l2
);
3185 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3188 tcg_gen_rem_tl(cpu_gpr
[rd
], t0
, t1
);
3193 case OPC_DMODU_G_2E
:
3194 case OPC_DMODU_G_2F
:
3196 int l1
= gen_new_label();
3197 int l2
= gen_new_label();
3198 tcg_gen_brcondi_tl(TCG_COND_NE
, t1
, 0, l1
);
3199 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
3202 tcg_gen_remu_tl(cpu_gpr
[rd
], t0
, t1
);
3210 (void)opn
; /* avoid a compiler warning */
3211 MIPS_DEBUG("%s %s, %s", opn
, regnames
[rd
], regnames
[rs
]);
3216 /* Loongson multimedia instructions */
3217 static void gen_loongson_multimedia(DisasContext
*ctx
, int rd
, int rs
, int rt
)
3219 const char *opn
= "loongson_cp2";
3220 uint32_t opc
, shift_max
;
3223 opc
= MASK_LMI(ctx
->opcode
);
3229 t0
= tcg_temp_local_new_i64();
3230 t1
= tcg_temp_local_new_i64();
3233 t0
= tcg_temp_new_i64();
3234 t1
= tcg_temp_new_i64();
3238 gen_load_fpr64(ctx
, t0
, rs
);
3239 gen_load_fpr64(ctx
, t1
, rt
);
3241 #define LMI_HELPER(UP, LO) \
3242 case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3243 #define LMI_HELPER_1(UP, LO) \
3244 case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3245 #define LMI_DIRECT(UP, LO, OP) \
3246 case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3249 LMI_HELPER(PADDSH
, paddsh
);
3250 LMI_HELPER(PADDUSH
, paddush
);
3251 LMI_HELPER(PADDH
, paddh
);
3252 LMI_HELPER(PADDW
, paddw
);
3253 LMI_HELPER(PADDSB
, paddsb
);
3254 LMI_HELPER(PADDUSB
, paddusb
);
3255 LMI_HELPER(PADDB
, paddb
);
3257 LMI_HELPER(PSUBSH
, psubsh
);
3258 LMI_HELPER(PSUBUSH
, psubush
);
3259 LMI_HELPER(PSUBH
, psubh
);
3260 LMI_HELPER(PSUBW
, psubw
);
3261 LMI_HELPER(PSUBSB
, psubsb
);
3262 LMI_HELPER(PSUBUSB
, psubusb
);
3263 LMI_HELPER(PSUBB
, psubb
);
3265 LMI_HELPER(PSHUFH
, pshufh
);
3266 LMI_HELPER(PACKSSWH
, packsswh
);
3267 LMI_HELPER(PACKSSHB
, packsshb
);
3268 LMI_HELPER(PACKUSHB
, packushb
);
3270 LMI_HELPER(PUNPCKLHW
, punpcklhw
);
3271 LMI_HELPER(PUNPCKHHW
, punpckhhw
);
3272 LMI_HELPER(PUNPCKLBH
, punpcklbh
);
3273 LMI_HELPER(PUNPCKHBH
, punpckhbh
);
3274 LMI_HELPER(PUNPCKLWD
, punpcklwd
);
3275 LMI_HELPER(PUNPCKHWD
, punpckhwd
);
3277 LMI_HELPER(PAVGH
, pavgh
);
3278 LMI_HELPER(PAVGB
, pavgb
);
3279 LMI_HELPER(PMAXSH
, pmaxsh
);
3280 LMI_HELPER(PMINSH
, pminsh
);
3281 LMI_HELPER(PMAXUB
, pmaxub
);
3282 LMI_HELPER(PMINUB
, pminub
);
3284 LMI_HELPER(PCMPEQW
, pcmpeqw
);
3285 LMI_HELPER(PCMPGTW
, pcmpgtw
);
3286 LMI_HELPER(PCMPEQH
, pcmpeqh
);
3287 LMI_HELPER(PCMPGTH
, pcmpgth
);
3288 LMI_HELPER(PCMPEQB
, pcmpeqb
);
3289 LMI_HELPER(PCMPGTB
, pcmpgtb
);
3291 LMI_HELPER(PSLLW
, psllw
);
3292 LMI_HELPER(PSLLH
, psllh
);
3293 LMI_HELPER(PSRLW
, psrlw
);
3294 LMI_HELPER(PSRLH
, psrlh
);
3295 LMI_HELPER(PSRAW
, psraw
);
3296 LMI_HELPER(PSRAH
, psrah
);
3298 LMI_HELPER(PMULLH
, pmullh
);
3299 LMI_HELPER(PMULHH
, pmulhh
);
3300 LMI_HELPER(PMULHUH
, pmulhuh
);
3301 LMI_HELPER(PMADDHW
, pmaddhw
);
3303 LMI_HELPER(PASUBUB
, pasubub
);
3304 LMI_HELPER_1(BIADD
, biadd
);
3305 LMI_HELPER_1(PMOVMSKB
, pmovmskb
);
3307 LMI_DIRECT(PADDD
, paddd
, add
);
3308 LMI_DIRECT(PSUBD
, psubd
, sub
);
3309 LMI_DIRECT(XOR_CP2
, xor, xor);
3310 LMI_DIRECT(NOR_CP2
, nor
, nor
);
3311 LMI_DIRECT(AND_CP2
, and, and);
3312 LMI_DIRECT(PANDN
, pandn
, andc
);
3313 LMI_DIRECT(OR
, or, or);
3316 tcg_gen_deposit_i64(t0
, t0
, t1
, 0, 16);
3320 tcg_gen_deposit_i64(t0
, t0
, t1
, 16, 16);
3324 tcg_gen_deposit_i64(t0
, t0
, t1
, 32, 16);
3328 tcg_gen_deposit_i64(t0
, t0
, t1
, 48, 16);
3333 tcg_gen_andi_i64(t1
, t1
, 3);
3334 tcg_gen_shli_i64(t1
, t1
, 4);
3335 tcg_gen_shr_i64(t0
, t0
, t1
);
3336 tcg_gen_ext16u_i64(t0
, t0
);
3341 tcg_gen_add_i64(t0
, t0
, t1
);
3342 tcg_gen_ext32s_i64(t0
, t0
);
3346 tcg_gen_sub_i64(t0
, t0
, t1
);
3347 tcg_gen_ext32s_i64(t0
, t0
);
3376 /* Make sure shift count isn't TCG undefined behaviour. */
3377 tcg_gen_andi_i64(t1
, t1
, shift_max
- 1);
3382 tcg_gen_shl_i64(t0
, t0
, t1
);
3386 /* Since SRA is UndefinedResult without sign-extended inputs,
3387 we can treat SRA and DSRA the same. */
3388 tcg_gen_sar_i64(t0
, t0
, t1
);
3391 /* We want to shift in zeros for SRL; zero-extend first. */
3392 tcg_gen_ext32u_i64(t0
, t0
);
3395 tcg_gen_shr_i64(t0
, t0
, t1
);
3399 if (shift_max
== 32) {
3400 tcg_gen_ext32s_i64(t0
, t0
);
3403 /* Shifts larger than MAX produce zero. */
3404 tcg_gen_setcondi_i64(TCG_COND_LTU
, t1
, t1
, shift_max
);
3405 tcg_gen_neg_i64(t1
, t1
);
3406 tcg_gen_and_i64(t0
, t0
, t1
);
3412 TCGv_i64 t2
= tcg_temp_new_i64();
3413 int lab
= gen_new_label();
3415 tcg_gen_mov_i64(t2
, t0
);
3416 tcg_gen_add_i64(t0
, t1
, t2
);
3417 if (opc
== OPC_ADD_CP2
) {
3418 tcg_gen_ext32s_i64(t0
, t0
);
3420 tcg_gen_xor_i64(t1
, t1
, t2
);
3421 tcg_gen_xor_i64(t2
, t2
, t0
);
3422 tcg_gen_andc_i64(t1
, t2
, t1
);
3423 tcg_temp_free_i64(t2
);
3424 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3425 generate_exception(ctx
, EXCP_OVERFLOW
);
3428 opn
= (opc
== OPC_ADD_CP2
? "add" : "dadd");
3435 TCGv_i64 t2
= tcg_temp_new_i64();
3436 int lab
= gen_new_label();
3438 tcg_gen_mov_i64(t2
, t0
);
3439 tcg_gen_sub_i64(t0
, t1
, t2
);
3440 if (opc
== OPC_SUB_CP2
) {
3441 tcg_gen_ext32s_i64(t0
, t0
);
3443 tcg_gen_xor_i64(t1
, t1
, t2
);
3444 tcg_gen_xor_i64(t2
, t2
, t0
);
3445 tcg_gen_and_i64(t1
, t1
, t2
);
3446 tcg_temp_free_i64(t2
);
3447 tcg_gen_brcondi_i64(TCG_COND_GE
, t1
, 0, lab
);
3448 generate_exception(ctx
, EXCP_OVERFLOW
);
3451 opn
= (opc
== OPC_SUB_CP2
? "sub" : "dsub");
3456 tcg_gen_ext32u_i64(t0
, t0
);
3457 tcg_gen_ext32u_i64(t1
, t1
);
3458 tcg_gen_mul_i64(t0
, t0
, t1
);
3468 /* ??? Document is unclear: Set FCC[CC]. Does that mean the
3469 FD field is the CC field? */
3472 generate_exception(ctx
, EXCP_RI
);
3479 gen_store_fpr64(ctx
, t0
, rd
);
3481 (void)opn
; /* avoid a compiler warning */
3482 MIPS_DEBUG("%s %s, %s, %s", opn
,
3483 fregnames
[rd
], fregnames
[rs
], fregnames
[rt
]);
3484 tcg_temp_free_i64(t0
);
3485 tcg_temp_free_i64(t1
);
3489 static void gen_trap (DisasContext
*ctx
, uint32_t opc
,
3490 int rs
, int rt
, int16_t imm
)
3493 TCGv t0
= tcg_temp_new();
3494 TCGv t1
= tcg_temp_new();
3497 /* Load needed operands */
3505 /* Compare two registers */
3507 gen_load_gpr(t0
, rs
);
3508 gen_load_gpr(t1
, rt
);
3518 /* Compare register to immediate */
3519 if (rs
!= 0 || imm
!= 0) {
3520 gen_load_gpr(t0
, rs
);
3521 tcg_gen_movi_tl(t1
, (int32_t)imm
);
3528 case OPC_TEQ
: /* rs == rs */
3529 case OPC_TEQI
: /* r0 == 0 */
3530 case OPC_TGE
: /* rs >= rs */
3531 case OPC_TGEI
: /* r0 >= 0 */
3532 case OPC_TGEU
: /* rs >= rs unsigned */
3533 case OPC_TGEIU
: /* r0 >= 0 unsigned */
3535 generate_exception(ctx
, EXCP_TRAP
);
3537 case OPC_TLT
: /* rs < rs */
3538 case OPC_TLTI
: /* r0 < 0 */
3539 case OPC_TLTU
: /* rs < rs unsigned */
3540 case OPC_TLTIU
: /* r0 < 0 unsigned */
3541 case OPC_TNE
: /* rs != rs */
3542 case OPC_TNEI
: /* r0 != 0 */
3543 /* Never trap: treat as NOP. */
3547 int l1
= gen_new_label();
3552 tcg_gen_brcond_tl(TCG_COND_NE
, t0
, t1
, l1
);
3556 tcg_gen_brcond_tl(TCG_COND_LT
, t0
, t1
, l1
);
3560 tcg_gen_brcond_tl(TCG_COND_LTU
, t0
, t1
, l1
);
3564 tcg_gen_brcond_tl(TCG_COND_GE
, t0
, t1
, l1
);
3568 tcg_gen_brcond_tl(TCG_COND_GEU
, t0
, t1
, l1
);
3572 tcg_gen_brcond_tl(TCG_COND_EQ
, t0
, t1
, l1
);
3575 generate_exception(ctx
, EXCP_TRAP
);
3582 static inline void gen_goto_tb(DisasContext
*ctx
, int n
, target_ulong dest
)
3584 TranslationBlock
*tb
;
3586 if ((tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) &&
3587 likely(!ctx
->singlestep_enabled
)) {
3590 tcg_gen_exit_tb((uintptr_t)tb
+ n
);
3593 if (ctx
->singlestep_enabled
) {
3594 save_cpu_state(ctx
, 0);
3595 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
3601 /* Branches (before delay slot) */
3602 static void gen_compute_branch (DisasContext
*ctx
, uint32_t opc
,
3604 int rs
, int rt
, int32_t offset
)
3606 target_ulong btgt
= -1;
3608 int bcond_compute
= 0;
3609 TCGv t0
= tcg_temp_new();
3610 TCGv t1
= tcg_temp_new();
3612 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
3613 #ifdef MIPS_DEBUG_DISAS
3614 LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx
"\n", ctx
->pc
);
3616 generate_exception(ctx
, EXCP_RI
);
3620 /* Load needed operands */
3626 /* Compare two registers */
3628 gen_load_gpr(t0
, rs
);
3629 gen_load_gpr(t1
, rt
);
3632 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3648 /* Compare to zero */
3650 gen_load_gpr(t0
, rs
);
3653 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3656 #if defined(TARGET_MIPS64)
3658 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x7F);
3660 tcg_gen_andi_tl(t0
, cpu_dspctrl
, 0x3F);
3663 btgt
= ctx
->pc
+ insn_bytes
+ offset
;
3670 /* Jump to immediate */
3671 btgt
= ((ctx
->pc
+ insn_bytes
) & (int32_t)0xF0000000) | (uint32_t)offset
;
3677 /* Jump to register */
3678 if (offset
!= 0 && offset
!= 16) {
3679 /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3680 others are reserved. */
3681 MIPS_INVAL("jump hint");
3682 generate_exception(ctx
, EXCP_RI
);
3685 gen_load_gpr(btarget
, rs
);
3688 MIPS_INVAL("branch/jump");
3689 generate_exception(ctx
, EXCP_RI
);
3692 if (bcond_compute
== 0) {
3693 /* No condition to be computed */
3695 case OPC_BEQ
: /* rx == rx */
3696 case OPC_BEQL
: /* rx == rx likely */
3697 case OPC_BGEZ
: /* 0 >= 0 */
3698 case OPC_BGEZL
: /* 0 >= 0 likely */
3699 case OPC_BLEZ
: /* 0 <= 0 */
3700 case OPC_BLEZL
: /* 0 <= 0 likely */
3702 ctx
->hflags
|= MIPS_HFLAG_B
;
3703 MIPS_DEBUG("balways");
3706 case OPC_BGEZAL
: /* 0 >= 0 */
3707 case OPC_BGEZALL
: /* 0 >= 0 likely */
3708 ctx
->hflags
|= (opc
== OPC_BGEZALS
3710 : MIPS_HFLAG_BDS32
);
3711 /* Always take and link */
3713 ctx
->hflags
|= MIPS_HFLAG_B
;
3714 MIPS_DEBUG("balways and link");
3716 case OPC_BNE
: /* rx != rx */
3717 case OPC_BGTZ
: /* 0 > 0 */
3718 case OPC_BLTZ
: /* 0 < 0 */
3720 MIPS_DEBUG("bnever (NOP)");
3723 case OPC_BLTZAL
: /* 0 < 0 */
3724 ctx
->hflags
|= (opc
== OPC_BLTZALS
3726 : MIPS_HFLAG_BDS32
);
3727 /* Handle as an unconditional branch to get correct delay
3730 btgt
= ctx
->pc
+ (opc
== OPC_BLTZALS
? 6 : 8);
3731 ctx
->hflags
|= MIPS_HFLAG_B
;
3732 MIPS_DEBUG("bnever and link");
3734 case OPC_BLTZALL
: /* 0 < 0 likely */
3735 tcg_gen_movi_tl(cpu_gpr
[31], ctx
->pc
+ 8);
3736 /* Skip the instruction in the delay slot */
3737 MIPS_DEBUG("bnever, link and skip");
3740 case OPC_BNEL
: /* rx != rx likely */
3741 case OPC_BGTZL
: /* 0 > 0 likely */
3742 case OPC_BLTZL
: /* 0 < 0 likely */
3743 /* Skip the instruction in the delay slot */
3744 MIPS_DEBUG("bnever and skip");
3748 ctx
->hflags
|= MIPS_HFLAG_B
;
3749 MIPS_DEBUG("j " TARGET_FMT_lx
, btgt
);
3753 ctx
->hflags
|= MIPS_HFLAG_BX
;
3758 ctx
->hflags
|= MIPS_HFLAG_B
;
3759 ctx
->hflags
|= ((opc
== OPC_JALS
|| opc
== OPC_JALXS
)
3761 : MIPS_HFLAG_BDS32
);
3762 MIPS_DEBUG("jal " TARGET_FMT_lx
, btgt
);
3765 ctx
->hflags
|= MIPS_HFLAG_BR
;
3766 if (insn_bytes
== 4)
3767 ctx
->hflags
|= MIPS_HFLAG_BDS32
;
3768 MIPS_DEBUG("jr %s", regnames
[rs
]);
3774 ctx
->hflags
|= MIPS_HFLAG_BR
;
3775 ctx
->hflags
|= (opc
== OPC_JALRS
3777 : MIPS_HFLAG_BDS32
);
3778 MIPS_DEBUG("jalr %s, %s", regnames
[rt
], regnames
[rs
]);
3781 MIPS_INVAL("branch/jump");
3782 generate_exception(ctx
, EXCP_RI
);
3788 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3789 MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx
,
3790 regnames
[rs
], regnames
[rt
], btgt
);
3793 tcg_gen_setcond_tl(TCG_COND_EQ
, bcond
, t0
, t1
);
3794 MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx
,
3795 regnames
[rs
], regnames
[rt
], btgt
);
3798 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3799 MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx
,
3800 regnames
[rs
], regnames
[rt
], btgt
);
3803 tcg_gen_setcond_tl(TCG_COND_NE
, bcond
, t0
, t1
);
3804 MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx
,
3805 regnames
[rs
], regnames
[rt
], btgt
);
3808 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3809 MIPS_DEBUG("bgez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3812 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3813 MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3817 ctx
->hflags
|= (opc
== OPC_BGEZALS
3819 : MIPS_HFLAG_BDS32
);
3820 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3821 MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3825 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 0);
3827 MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3830 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3831 MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3834 tcg_gen_setcondi_tl(TCG_COND_GT
, bcond
, t0
, 0);
3835 MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3838 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3839 MIPS_DEBUG("blez %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3842 tcg_gen_setcondi_tl(TCG_COND_LE
, bcond
, t0
, 0);
3843 MIPS_DEBUG("blezl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3846 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3847 MIPS_DEBUG("bltz %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3850 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3851 MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3854 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 32);
3855 MIPS_DEBUG("bposge32 " TARGET_FMT_lx
, btgt
);
3857 #if defined(TARGET_MIPS64)
3859 tcg_gen_setcondi_tl(TCG_COND_GE
, bcond
, t0
, 64);
3860 MIPS_DEBUG("bposge64 " TARGET_FMT_lx
, btgt
);
3865 ctx
->hflags
|= (opc
== OPC_BLTZALS
3867 : MIPS_HFLAG_BDS32
);
3868 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3870 MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3872 ctx
->hflags
|= MIPS_HFLAG_BC
;
3875 tcg_gen_setcondi_tl(TCG_COND_LT
, bcond
, t0
, 0);
3877 MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx
, regnames
[rs
], btgt
);
3879 ctx
->hflags
|= MIPS_HFLAG_BL
;
3882 MIPS_INVAL("conditional branch/jump");
3883 generate_exception(ctx
, EXCP_RI
);
3887 MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx
,
3888 blink
, ctx
->hflags
, btgt
);
3890 ctx
->btarget
= btgt
;
3892 int post_delay
= insn_bytes
;
3893 int lowbit
= !!(ctx
->hflags
& MIPS_HFLAG_M16
);
3895 if (opc
!= OPC_JALRC
)
3896 post_delay
+= ((ctx
->hflags
& MIPS_HFLAG_BDS16
) ? 2 : 4);
3898 tcg_gen_movi_tl(cpu_gpr
[blink
], ctx
->pc
+ post_delay
+ lowbit
);
3902 if (insn_bytes
== 2)
3903 ctx
->hflags
|= MIPS_HFLAG_B16
;
3908 /* special3 bitfield operations */
3909 static void gen_bitops (DisasContext
*ctx
, uint32_t opc
, int rt
,
3910 int rs
, int lsb
, int msb
)
3912 TCGv t0
= tcg_temp_new();
3913 TCGv t1
= tcg_temp_new();
3915 gen_load_gpr(t1
, rs
);
3920 tcg_gen_shri_tl(t0
, t1
, lsb
);
3922 tcg_gen_andi_tl(t0
, t0
, (1 << (msb
+ 1)) - 1);
3924 tcg_gen_ext32s_tl(t0
, t0
);
3927 #if defined(TARGET_MIPS64)
3929 tcg_gen_shri_tl(t0
, t1
, lsb
);
3931 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1 + 32)) - 1);
3935 tcg_gen_shri_tl(t0
, t1
, lsb
+ 32);
3936 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3939 tcg_gen_shri_tl(t0
, t1
, lsb
);
3940 tcg_gen_andi_tl(t0
, t0
, (1ULL << (msb
+ 1)) - 1);
3946 gen_load_gpr(t0
, rt
);
3947 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3948 tcg_gen_ext32s_tl(t0
, t0
);
3950 #if defined(TARGET_MIPS64)
3952 gen_load_gpr(t0
, rt
);
3953 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
+ 32 - lsb
+ 1);
3956 gen_load_gpr(t0
, rt
);
3957 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
+ 32, msb
- lsb
+ 1);
3960 gen_load_gpr(t0
, rt
);
3961 tcg_gen_deposit_tl(t0
, t0
, t1
, lsb
, msb
- lsb
+ 1);
3966 MIPS_INVAL("bitops");
3967 generate_exception(ctx
, EXCP_RI
);
3972 gen_store_gpr(t0
, rt
);
3977 static void gen_bshfl (DisasContext
*ctx
, uint32_t op2
, int rt
, int rd
)
3982 /* If no destination, treat it as a NOP. */
3987 t0
= tcg_temp_new();
3988 gen_load_gpr(t0
, rt
);
3992 TCGv t1
= tcg_temp_new();
3994 tcg_gen_shri_tl(t1
, t0
, 8);
3995 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF);
3996 tcg_gen_shli_tl(t0
, t0
, 8);
3997 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF);
3998 tcg_gen_or_tl(t0
, t0
, t1
);
4000 tcg_gen_ext32s_tl(cpu_gpr
[rd
], t0
);
4004 tcg_gen_ext8s_tl(cpu_gpr
[rd
], t0
);
4007 tcg_gen_ext16s_tl(cpu_gpr
[rd
], t0
);
4009 #if defined(TARGET_MIPS64)
4012 TCGv t1
= tcg_temp_new();
4014 tcg_gen_shri_tl(t1
, t0
, 8);
4015 tcg_gen_andi_tl(t1
, t1
, 0x00FF00FF00FF00FFULL
);
4016 tcg_gen_shli_tl(t0
, t0
, 8);
4017 tcg_gen_andi_tl(t0
, t0
, ~0x00FF00FF00FF00FFULL
);
4018 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4024 TCGv t1
= tcg_temp_new();
4026 tcg_gen_shri_tl(t1
, t0
, 16);
4027 tcg_gen_andi_tl(t1
, t1
, 0x0000FFFF0000FFFFULL
);
4028 tcg_gen_shli_tl(t0
, t0
, 16);
4029 tcg_gen_andi_tl(t0
, t0
, ~0x0000FFFF0000FFFFULL
);
4030 tcg_gen_or_tl(t0
, t0
, t1
);
4031 tcg_gen_shri_tl(t1
, t0
, 32);
4032 tcg_gen_shli_tl(t0
, t0
, 32);
4033 tcg_gen_or_tl(cpu_gpr
[rd
], t0
, t1
);
4039 MIPS_INVAL("bsfhl");
4040 generate_exception(ctx
, EXCP_RI
);
4047 #ifndef CONFIG_USER_ONLY
4048 /* CP0 (MMU and control) */
4049 static inline void gen_mfc0_load32 (TCGv arg
, target_ulong off
)
4051 TCGv_i32 t0
= tcg_temp_new_i32();
4053 tcg_gen_ld_i32(t0
, cpu_env
, off
);
4054 tcg_gen_ext_i32_tl(arg
, t0
);
4055 tcg_temp_free_i32(t0
);
4058 static inline void gen_mfc0_load64 (TCGv arg
, target_ulong off
)
4060 tcg_gen_ld_tl(arg
, cpu_env
, off
);
4061 tcg_gen_ext32s_tl(arg
, arg
);
4064 static inline void gen_mtc0_store32 (TCGv arg
, target_ulong off
)
4066 TCGv_i32 t0
= tcg_temp_new_i32();
4068 tcg_gen_trunc_tl_i32(t0
, arg
);
4069 tcg_gen_st_i32(t0
, cpu_env
, off
);
4070 tcg_temp_free_i32(t0
);
4073 static inline void gen_mtc0_store64 (TCGv arg
, target_ulong off
)
4075 tcg_gen_ext32s_tl(arg
, arg
);
4076 tcg_gen_st_tl(arg
, cpu_env
, off
);
4079 static void gen_mfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4081 const char *rn
= "invalid";
4084 check_insn(ctx
, ISA_MIPS32
);
4090 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
4094 check_insn(ctx
, ASE_MT
);
4095 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
4099 check_insn(ctx
, ASE_MT
);
4100 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
4104 check_insn(ctx
, ASE_MT
);
4105 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
4115 gen_helper_mfc0_random(arg
, cpu_env
);
4119 check_insn(ctx
, ASE_MT
);
4120 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
4124 check_insn(ctx
, ASE_MT
);
4125 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
4129 check_insn(ctx
, ASE_MT
);
4130 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
4134 check_insn(ctx
, ASE_MT
);
4135 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_YQMask
));
4139 check_insn(ctx
, ASE_MT
);
4140 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4144 check_insn(ctx
, ASE_MT
);
4145 gen_mfc0_load64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4146 rn
= "VPEScheFBack";
4149 check_insn(ctx
, ASE_MT
);
4150 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
4160 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
4161 tcg_gen_ext32s_tl(arg
, arg
);
4165 check_insn(ctx
, ASE_MT
);
4166 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
4170 check_insn(ctx
, ASE_MT
);
4171 gen_helper_mfc0_tcbind(arg
, cpu_env
);
4175 check_insn(ctx
, ASE_MT
);
4176 gen_helper_mfc0_tcrestart(arg
, cpu_env
);
4180 check_insn(ctx
, ASE_MT
);
4181 gen_helper_mfc0_tchalt(arg
, cpu_env
);
4185 check_insn(ctx
, ASE_MT
);
4186 gen_helper_mfc0_tccontext(arg
, cpu_env
);
4190 check_insn(ctx
, ASE_MT
);
4191 gen_helper_mfc0_tcschedule(arg
, cpu_env
);
4195 check_insn(ctx
, ASE_MT
);
4196 gen_helper_mfc0_tcschefback(arg
, cpu_env
);
4206 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
4207 tcg_gen_ext32s_tl(arg
, arg
);
4217 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
4218 tcg_gen_ext32s_tl(arg
, arg
);
4222 // gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4223 rn
= "ContextConfig";
4228 tcg_gen_ld32s_tl(arg
, cpu_env
,
4229 offsetof(CPUMIPSState
,
4230 active_tc
.CP0_UserLocal
));
4233 tcg_gen_movi_tl(arg
, 0);
4243 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
4247 check_insn(ctx
, ISA_MIPS32R2
);
4248 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
4258 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
4262 check_insn(ctx
, ISA_MIPS32R2
);
4263 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
4267 check_insn(ctx
, ISA_MIPS32R2
);
4268 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
4272 check_insn(ctx
, ISA_MIPS32R2
);
4273 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
4277 check_insn(ctx
, ISA_MIPS32R2
);
4278 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
4282 check_insn(ctx
, ISA_MIPS32R2
);
4283 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
4293 check_insn(ctx
, ISA_MIPS32R2
);
4294 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
4304 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
4305 tcg_gen_ext32s_tl(arg
, arg
);
4315 /* Mark as an IO operation because we read the time. */
4318 gen_helper_mfc0_count(arg
, cpu_env
);
4322 /* Break the TB to be able to take timer interrupts immediately
4323 after reading count. */
4324 ctx
->bstate
= BS_STOP
;
4327 /* 6,7 are implementation dependent */
4335 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
4336 tcg_gen_ext32s_tl(arg
, arg
);
4346 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
4349 /* 6,7 are implementation dependent */
4357 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
4361 check_insn(ctx
, ISA_MIPS32R2
);
4362 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
4366 check_insn(ctx
, ISA_MIPS32R2
);
4367 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
4371 check_insn(ctx
, ISA_MIPS32R2
);
4372 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4382 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
4392 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
4393 tcg_gen_ext32s_tl(arg
, arg
);
4403 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
4407 check_insn(ctx
, ISA_MIPS32R2
);
4408 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
4418 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
4422 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
4426 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
4430 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
4434 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config4
));
4438 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config5
));
4441 /* 6,7 are implementation dependent */
4443 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
4447 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
4457 gen_helper_mfc0_lladdr(arg
, cpu_env
);
4467 gen_helper_1e0i(mfc0_watchlo
, arg
, sel
);
4477 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
4487 #if defined(TARGET_MIPS64)
4488 check_insn(ctx
, ISA_MIPS3
);
4489 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
4490 tcg_gen_ext32s_tl(arg
, arg
);
4499 /* Officially reserved, but sel 0 is used for R1x000 framemask */
4502 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
4510 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4511 rn
= "'Diagnostic"; /* implementation dependent */
4516 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
4520 // gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4521 rn
= "TraceControl";
4524 // gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4525 rn
= "TraceControl2";
4528 // gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4529 rn
= "UserTraceData";
4532 // gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4543 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
4544 tcg_gen_ext32s_tl(arg
, arg
);
4554 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
4555 rn
= "Performance0";
4558 // gen_helper_mfc0_performance1(arg);
4559 rn
= "Performance1";
4562 // gen_helper_mfc0_performance2(arg);
4563 rn
= "Performance2";
4566 // gen_helper_mfc0_performance3(arg);
4567 rn
= "Performance3";
4570 // gen_helper_mfc0_performance4(arg);
4571 rn
= "Performance4";
4574 // gen_helper_mfc0_performance5(arg);
4575 rn
= "Performance5";
4578 // gen_helper_mfc0_performance6(arg);
4579 rn
= "Performance6";
4582 // gen_helper_mfc0_performance7(arg);
4583 rn
= "Performance7";
4590 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4596 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
4609 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
4616 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
4629 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
4636 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
4646 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
4647 tcg_gen_ext32s_tl(arg
, arg
);
4658 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
4668 (void)rn
; /* avoid a compiler warning */
4669 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4673 LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
4674 generate_exception(ctx
, EXCP_RI
);
4677 static void gen_mtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
4679 const char *rn
= "invalid";
4682 check_insn(ctx
, ISA_MIPS32
);
4691 gen_helper_mtc0_index(cpu_env
, arg
);
4695 check_insn(ctx
, ASE_MT
);
4696 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
4700 check_insn(ctx
, ASE_MT
);
4705 check_insn(ctx
, ASE_MT
);
4720 check_insn(ctx
, ASE_MT
);
4721 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
4725 check_insn(ctx
, ASE_MT
);
4726 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
4730 check_insn(ctx
, ASE_MT
);
4731 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
4735 check_insn(ctx
, ASE_MT
);
4736 gen_helper_mtc0_yqmask(cpu_env
, arg
);
4740 check_insn(ctx
, ASE_MT
);
4741 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
4745 check_insn(ctx
, ASE_MT
);
4746 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
4747 rn
= "VPEScheFBack";
4750 check_insn(ctx
, ASE_MT
);
4751 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
4761 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
4765 check_insn(ctx
, ASE_MT
);
4766 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
4770 check_insn(ctx
, ASE_MT
);
4771 gen_helper_mtc0_tcbind(cpu_env
, arg
);
4775 check_insn(ctx
, ASE_MT
);
4776 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
4780 check_insn(ctx
, ASE_MT
);
4781 gen_helper_mtc0_tchalt(cpu_env
, arg
);
4785 check_insn(ctx
, ASE_MT
);
4786 gen_helper_mtc0_tccontext(cpu_env
, arg
);
4790 check_insn(ctx
, ASE_MT
);
4791 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
4795 check_insn(ctx
, ASE_MT
);
4796 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
4806 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
4816 gen_helper_mtc0_context(cpu_env
, arg
);
4820 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4821 rn
= "ContextConfig";
4826 tcg_gen_st_tl(arg
, cpu_env
,
4827 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
4838 gen_helper_mtc0_pagemask(cpu_env
, arg
);
4842 check_insn(ctx
, ISA_MIPS32R2
);
4843 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
4853 gen_helper_mtc0_wired(cpu_env
, arg
);
4857 check_insn(ctx
, ISA_MIPS32R2
);
4858 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
4862 check_insn(ctx
, ISA_MIPS32R2
);
4863 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
4867 check_insn(ctx
, ISA_MIPS32R2
);
4868 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
4872 check_insn(ctx
, ISA_MIPS32R2
);
4873 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
4877 check_insn(ctx
, ISA_MIPS32R2
);
4878 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
4888 check_insn(ctx
, ISA_MIPS32R2
);
4889 gen_helper_mtc0_hwrena(cpu_env
, arg
);
4890 ctx
->bstate
= BS_STOP
;
4904 gen_helper_mtc0_count(cpu_env
, arg
);
4907 /* 6,7 are implementation dependent */
4915 gen_helper_mtc0_entryhi(cpu_env
, arg
);
4925 gen_helper_mtc0_compare(cpu_env
, arg
);
4928 /* 6,7 are implementation dependent */
4936 save_cpu_state(ctx
, 1);
4937 gen_helper_mtc0_status(cpu_env
, arg
);
4938 /* BS_STOP isn't good enough here, hflags may have changed. */
4939 gen_save_pc(ctx
->pc
+ 4);
4940 ctx
->bstate
= BS_EXCP
;
4944 check_insn(ctx
, ISA_MIPS32R2
);
4945 gen_helper_mtc0_intctl(cpu_env
, arg
);
4946 /* Stop translation as we may have switched the execution mode */
4947 ctx
->bstate
= BS_STOP
;
4951 check_insn(ctx
, ISA_MIPS32R2
);
4952 gen_helper_mtc0_srsctl(cpu_env
, arg
);
4953 /* Stop translation as we may have switched the execution mode */
4954 ctx
->bstate
= BS_STOP
;
4958 check_insn(ctx
, ISA_MIPS32R2
);
4959 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
4960 /* Stop translation as we may have switched the execution mode */
4961 ctx
->bstate
= BS_STOP
;
4971 save_cpu_state(ctx
, 1);
4972 gen_helper_mtc0_cause(cpu_env
, arg
);
4982 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_EPC
));
4996 check_insn(ctx
, ISA_MIPS32R2
);
4997 gen_helper_mtc0_ebase(cpu_env
, arg
);
5007 gen_helper_mtc0_config0(cpu_env
, arg
);
5009 /* Stop translation as we may have switched the execution mode */
5010 ctx
->bstate
= BS_STOP
;
5013 /* ignored, read only */
5017 gen_helper_mtc0_config2(cpu_env
, arg
);
5019 /* Stop translation as we may have switched the execution mode */
5020 ctx
->bstate
= BS_STOP
;
5023 /* ignored, read only */
5027 gen_helper_mtc0_config4(cpu_env
, arg
);
5029 ctx
->bstate
= BS_STOP
;
5032 gen_helper_mtc0_config5(cpu_env
, arg
);
5034 /* Stop translation as we may have switched the execution mode */
5035 ctx
->bstate
= BS_STOP
;
5037 /* 6,7 are implementation dependent */
5047 rn
= "Invalid config selector";
5054 gen_helper_mtc0_lladdr(cpu_env
, arg
);
5064 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
5074 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
5084 #if defined(TARGET_MIPS64)
5085 check_insn(ctx
, ISA_MIPS3
);
5086 gen_helper_mtc0_xcontext(cpu_env
, arg
);
5095 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5098 gen_helper_mtc0_framemask(cpu_env
, arg
);
5107 rn
= "Diagnostic"; /* implementation dependent */
5112 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
5113 /* BS_STOP isn't good enough here, hflags may have changed. */
5114 gen_save_pc(ctx
->pc
+ 4);
5115 ctx
->bstate
= BS_EXCP
;
5119 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5120 rn
= "TraceControl";
5121 /* Stop translation as we may have switched the execution mode */
5122 ctx
->bstate
= BS_STOP
;
5125 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5126 rn
= "TraceControl2";
5127 /* Stop translation as we may have switched the execution mode */
5128 ctx
->bstate
= BS_STOP
;
5131 /* Stop translation as we may have switched the execution mode */
5132 ctx
->bstate
= BS_STOP
;
5133 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5134 rn
= "UserTraceData";
5135 /* Stop translation as we may have switched the execution mode */
5136 ctx
->bstate
= BS_STOP
;
5139 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5140 /* Stop translation as we may have switched the execution mode */
5141 ctx
->bstate
= BS_STOP
;
5152 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_DEPC
));
5162 gen_helper_mtc0_performance0(cpu_env
, arg
);
5163 rn
= "Performance0";
5166 // gen_helper_mtc0_performance1(arg);
5167 rn
= "Performance1";
5170 // gen_helper_mtc0_performance2(arg);
5171 rn
= "Performance2";
5174 // gen_helper_mtc0_performance3(arg);
5175 rn
= "Performance3";
5178 // gen_helper_mtc0_performance4(arg);
5179 rn
= "Performance4";
5182 // gen_helper_mtc0_performance5(arg);
5183 rn
= "Performance5";
5186 // gen_helper_mtc0_performance6(arg);
5187 rn
= "Performance6";
5190 // gen_helper_mtc0_performance7(arg);
5191 rn
= "Performance7";
5217 gen_helper_mtc0_taglo(cpu_env
, arg
);
5224 gen_helper_mtc0_datalo(cpu_env
, arg
);
5237 gen_helper_mtc0_taghi(cpu_env
, arg
);
5244 gen_helper_mtc0_datahi(cpu_env
, arg
);
5255 gen_mtc0_store64(arg
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5266 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5272 /* Stop translation as we may have switched the execution mode */
5273 ctx
->bstate
= BS_STOP
;
5278 (void)rn
; /* avoid a compiler warning */
5279 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5280 /* For simplicity assume that all writes can cause interrupts. */
5283 ctx
->bstate
= BS_STOP
;
5288 LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5289 generate_exception(ctx
, EXCP_RI
);
5292 #if defined(TARGET_MIPS64)
5293 static void gen_dmfc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5295 const char *rn
= "invalid";
5298 check_insn(ctx
, ISA_MIPS64
);
5304 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Index
));
5308 check_insn(ctx
, ASE_MT
);
5309 gen_helper_mfc0_mvpcontrol(arg
, cpu_env
);
5313 check_insn(ctx
, ASE_MT
);
5314 gen_helper_mfc0_mvpconf0(arg
, cpu_env
);
5318 check_insn(ctx
, ASE_MT
);
5319 gen_helper_mfc0_mvpconf1(arg
, cpu_env
);
5329 gen_helper_mfc0_random(arg
, cpu_env
);
5333 check_insn(ctx
, ASE_MT
);
5334 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEControl
));
5338 check_insn(ctx
, ASE_MT
);
5339 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf0
));
5343 check_insn(ctx
, ASE_MT
);
5344 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEConf1
));
5348 check_insn(ctx
, ASE_MT
);
5349 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_YQMask
));
5353 check_insn(ctx
, ASE_MT
);
5354 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5358 check_insn(ctx
, ASE_MT
);
5359 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5360 rn
= "VPEScheFBack";
5363 check_insn(ctx
, ASE_MT
);
5364 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_VPEOpt
));
5374 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo0
));
5378 check_insn(ctx
, ASE_MT
);
5379 gen_helper_mfc0_tcstatus(arg
, cpu_env
);
5383 check_insn(ctx
, ASE_MT
);
5384 gen_helper_mfc0_tcbind(arg
, cpu_env
);
5388 check_insn(ctx
, ASE_MT
);
5389 gen_helper_dmfc0_tcrestart(arg
, cpu_env
);
5393 check_insn(ctx
, ASE_MT
);
5394 gen_helper_dmfc0_tchalt(arg
, cpu_env
);
5398 check_insn(ctx
, ASE_MT
);
5399 gen_helper_dmfc0_tccontext(arg
, cpu_env
);
5403 check_insn(ctx
, ASE_MT
);
5404 gen_helper_dmfc0_tcschedule(arg
, cpu_env
);
5408 check_insn(ctx
, ASE_MT
);
5409 gen_helper_dmfc0_tcschefback(arg
, cpu_env
);
5419 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryLo1
));
5429 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_Context
));
5433 // gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5434 rn
= "ContextConfig";
5439 tcg_gen_ld_tl(arg
, cpu_env
,
5440 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
5443 tcg_gen_movi_tl(arg
, 0);
5453 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageMask
));
5457 check_insn(ctx
, ISA_MIPS32R2
);
5458 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PageGrain
));
5468 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Wired
));
5472 check_insn(ctx
, ISA_MIPS32R2
);
5473 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf0
));
5477 check_insn(ctx
, ISA_MIPS32R2
);
5478 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf1
));
5482 check_insn(ctx
, ISA_MIPS32R2
);
5483 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf2
));
5487 check_insn(ctx
, ISA_MIPS32R2
);
5488 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf3
));
5492 check_insn(ctx
, ISA_MIPS32R2
);
5493 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSConf4
));
5503 check_insn(ctx
, ISA_MIPS32R2
);
5504 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_HWREna
));
5514 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_BadVAddr
));
5524 /* Mark as an IO operation because we read the time. */
5527 gen_helper_mfc0_count(arg
, cpu_env
);
5531 /* Break the TB to be able to take timer interrupts immediately
5532 after reading count. */
5533 ctx
->bstate
= BS_STOP
;
5536 /* 6,7 are implementation dependent */
5544 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EntryHi
));
5554 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Compare
));
5557 /* 6,7 are implementation dependent */
5565 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Status
));
5569 check_insn(ctx
, ISA_MIPS32R2
);
5570 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_IntCtl
));
5574 check_insn(ctx
, ISA_MIPS32R2
);
5575 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSCtl
));
5579 check_insn(ctx
, ISA_MIPS32R2
);
5580 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
5590 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Cause
));
5600 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
5610 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_PRid
));
5614 check_insn(ctx
, ISA_MIPS32R2
);
5615 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_EBase
));
5625 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config0
));
5629 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config1
));
5633 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config2
));
5637 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config3
));
5640 /* 6,7 are implementation dependent */
5642 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config6
));
5646 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Config7
));
5656 gen_helper_dmfc0_lladdr(arg
, cpu_env
);
5666 gen_helper_1e0i(dmfc0_watchlo
, arg
, sel
);
5676 gen_helper_1e0i(mfc0_watchhi
, arg
, sel
);
5686 check_insn(ctx
, ISA_MIPS3
);
5687 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_XContext
));
5695 /* Officially reserved, but sel 0 is used for R1x000 framemask */
5698 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Framemask
));
5706 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5707 rn
= "'Diagnostic"; /* implementation dependent */
5712 gen_helper_mfc0_debug(arg
, cpu_env
); /* EJTAG support */
5716 // gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5717 rn
= "TraceControl";
5720 // gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5721 rn
= "TraceControl2";
5724 // gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5725 rn
= "UserTraceData";
5728 // gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5739 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
5749 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_Performance0
));
5750 rn
= "Performance0";
5753 // gen_helper_dmfc0_performance1(arg);
5754 rn
= "Performance1";
5757 // gen_helper_dmfc0_performance2(arg);
5758 rn
= "Performance2";
5761 // gen_helper_dmfc0_performance3(arg);
5762 rn
= "Performance3";
5765 // gen_helper_dmfc0_performance4(arg);
5766 rn
= "Performance4";
5769 // gen_helper_dmfc0_performance5(arg);
5770 rn
= "Performance5";
5773 // gen_helper_dmfc0_performance6(arg);
5774 rn
= "Performance6";
5777 // gen_helper_dmfc0_performance7(arg);
5778 rn
= "Performance7";
5785 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5792 tcg_gen_movi_tl(arg
, 0); /* unimplemented */
5805 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagLo
));
5812 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataLo
));
5825 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_TagHi
));
5832 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DataHi
));
5842 tcg_gen_ld_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
5853 gen_mfc0_load32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
5863 (void)rn
; /* avoid a compiler warning */
5864 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5868 LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
5869 generate_exception(ctx
, EXCP_RI
);
5872 static void gen_dmtc0(DisasContext
*ctx
, TCGv arg
, int reg
, int sel
)
5874 const char *rn
= "invalid";
5877 check_insn(ctx
, ISA_MIPS64
);
5886 gen_helper_mtc0_index(cpu_env
, arg
);
5890 check_insn(ctx
, ASE_MT
);
5891 gen_helper_mtc0_mvpcontrol(cpu_env
, arg
);
5895 check_insn(ctx
, ASE_MT
);
5900 check_insn(ctx
, ASE_MT
);
5915 check_insn(ctx
, ASE_MT
);
5916 gen_helper_mtc0_vpecontrol(cpu_env
, arg
);
5920 check_insn(ctx
, ASE_MT
);
5921 gen_helper_mtc0_vpeconf0(cpu_env
, arg
);
5925 check_insn(ctx
, ASE_MT
);
5926 gen_helper_mtc0_vpeconf1(cpu_env
, arg
);
5930 check_insn(ctx
, ASE_MT
);
5931 gen_helper_mtc0_yqmask(cpu_env
, arg
);
5935 check_insn(ctx
, ASE_MT
);
5936 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPESchedule
));
5940 check_insn(ctx
, ASE_MT
);
5941 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_VPEScheFBack
));
5942 rn
= "VPEScheFBack";
5945 check_insn(ctx
, ASE_MT
);
5946 gen_helper_mtc0_vpeopt(cpu_env
, arg
);
5956 gen_helper_mtc0_entrylo0(cpu_env
, arg
);
5960 check_insn(ctx
, ASE_MT
);
5961 gen_helper_mtc0_tcstatus(cpu_env
, arg
);
5965 check_insn(ctx
, ASE_MT
);
5966 gen_helper_mtc0_tcbind(cpu_env
, arg
);
5970 check_insn(ctx
, ASE_MT
);
5971 gen_helper_mtc0_tcrestart(cpu_env
, arg
);
5975 check_insn(ctx
, ASE_MT
);
5976 gen_helper_mtc0_tchalt(cpu_env
, arg
);
5980 check_insn(ctx
, ASE_MT
);
5981 gen_helper_mtc0_tccontext(cpu_env
, arg
);
5985 check_insn(ctx
, ASE_MT
);
5986 gen_helper_mtc0_tcschedule(cpu_env
, arg
);
5990 check_insn(ctx
, ASE_MT
);
5991 gen_helper_mtc0_tcschefback(cpu_env
, arg
);
6001 gen_helper_mtc0_entrylo1(cpu_env
, arg
);
6011 gen_helper_mtc0_context(cpu_env
, arg
);
6015 // gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6016 rn
= "ContextConfig";
6021 tcg_gen_st_tl(arg
, cpu_env
,
6022 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
6033 gen_helper_mtc0_pagemask(cpu_env
, arg
);
6037 check_insn(ctx
, ISA_MIPS32R2
);
6038 gen_helper_mtc0_pagegrain(cpu_env
, arg
);
6048 gen_helper_mtc0_wired(cpu_env
, arg
);
6052 check_insn(ctx
, ISA_MIPS32R2
);
6053 gen_helper_mtc0_srsconf0(cpu_env
, arg
);
6057 check_insn(ctx
, ISA_MIPS32R2
);
6058 gen_helper_mtc0_srsconf1(cpu_env
, arg
);
6062 check_insn(ctx
, ISA_MIPS32R2
);
6063 gen_helper_mtc0_srsconf2(cpu_env
, arg
);
6067 check_insn(ctx
, ISA_MIPS32R2
);
6068 gen_helper_mtc0_srsconf3(cpu_env
, arg
);
6072 check_insn(ctx
, ISA_MIPS32R2
);
6073 gen_helper_mtc0_srsconf4(cpu_env
, arg
);
6083 check_insn(ctx
, ISA_MIPS32R2
);
6084 gen_helper_mtc0_hwrena(cpu_env
, arg
);
6085 ctx
->bstate
= BS_STOP
;
6099 gen_helper_mtc0_count(cpu_env
, arg
);
6102 /* 6,7 are implementation dependent */
6106 /* Stop translation as we may have switched the execution mode */
6107 ctx
->bstate
= BS_STOP
;
6112 gen_helper_mtc0_entryhi(cpu_env
, arg
);
6122 gen_helper_mtc0_compare(cpu_env
, arg
);
6125 /* 6,7 are implementation dependent */
6129 /* Stop translation as we may have switched the execution mode */
6130 ctx
->bstate
= BS_STOP
;
6135 save_cpu_state(ctx
, 1);
6136 gen_helper_mtc0_status(cpu_env
, arg
);
6137 /* BS_STOP isn't good enough here, hflags may have changed. */
6138 gen_save_pc(ctx
->pc
+ 4);
6139 ctx
->bstate
= BS_EXCP
;
6143 check_insn(ctx
, ISA_MIPS32R2
);
6144 gen_helper_mtc0_intctl(cpu_env
, arg
);
6145 /* Stop translation as we may have switched the execution mode */
6146 ctx
->bstate
= BS_STOP
;
6150 check_insn(ctx
, ISA_MIPS32R2
);
6151 gen_helper_mtc0_srsctl(cpu_env
, arg
);
6152 /* Stop translation as we may have switched the execution mode */
6153 ctx
->bstate
= BS_STOP
;
6157 check_insn(ctx
, ISA_MIPS32R2
);
6158 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_SRSMap
));
6159 /* Stop translation as we may have switched the execution mode */
6160 ctx
->bstate
= BS_STOP
;
6170 save_cpu_state(ctx
, 1);
6171 /* Mark as an IO operation because we may trigger a software
6176 gen_helper_mtc0_cause(cpu_env
, arg
);
6180 /* Stop translation as we may have triggered an intetrupt */
6181 ctx
->bstate
= BS_STOP
;
6191 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_EPC
));
6205 check_insn(ctx
, ISA_MIPS32R2
);
6206 gen_helper_mtc0_ebase(cpu_env
, arg
);
6216 gen_helper_mtc0_config0(cpu_env
, arg
);
6218 /* Stop translation as we may have switched the execution mode */
6219 ctx
->bstate
= BS_STOP
;
6222 /* ignored, read only */
6226 gen_helper_mtc0_config2(cpu_env
, arg
);
6228 /* Stop translation as we may have switched the execution mode */
6229 ctx
->bstate
= BS_STOP
;
6235 /* 6,7 are implementation dependent */
6237 rn
= "Invalid config selector";
6244 gen_helper_mtc0_lladdr(cpu_env
, arg
);
6254 gen_helper_0e1i(mtc0_watchlo
, arg
, sel
);
6264 gen_helper_0e1i(mtc0_watchhi
, arg
, sel
);
6274 check_insn(ctx
, ISA_MIPS3
);
6275 gen_helper_mtc0_xcontext(cpu_env
, arg
);
6283 /* Officially reserved, but sel 0 is used for R1x000 framemask */
6286 gen_helper_mtc0_framemask(cpu_env
, arg
);
6295 rn
= "Diagnostic"; /* implementation dependent */
6300 gen_helper_mtc0_debug(cpu_env
, arg
); /* EJTAG support */
6301 /* BS_STOP isn't good enough here, hflags may have changed. */
6302 gen_save_pc(ctx
->pc
+ 4);
6303 ctx
->bstate
= BS_EXCP
;
6307 // gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6308 /* Stop translation as we may have switched the execution mode */
6309 ctx
->bstate
= BS_STOP
;
6310 rn
= "TraceControl";
6313 // gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6314 /* Stop translation as we may have switched the execution mode */
6315 ctx
->bstate
= BS_STOP
;
6316 rn
= "TraceControl2";
6319 // gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6320 /* Stop translation as we may have switched the execution mode */
6321 ctx
->bstate
= BS_STOP
;
6322 rn
= "UserTraceData";
6325 // gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6326 /* Stop translation as we may have switched the execution mode */
6327 ctx
->bstate
= BS_STOP
;
6338 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_DEPC
));
6348 gen_helper_mtc0_performance0(cpu_env
, arg
);
6349 rn
= "Performance0";
6352 // gen_helper_mtc0_performance1(cpu_env, arg);
6353 rn
= "Performance1";
6356 // gen_helper_mtc0_performance2(cpu_env, arg);
6357 rn
= "Performance2";
6360 // gen_helper_mtc0_performance3(cpu_env, arg);
6361 rn
= "Performance3";
6364 // gen_helper_mtc0_performance4(cpu_env, arg);
6365 rn
= "Performance4";
6368 // gen_helper_mtc0_performance5(cpu_env, arg);
6369 rn
= "Performance5";
6372 // gen_helper_mtc0_performance6(cpu_env, arg);
6373 rn
= "Performance6";
6376 // gen_helper_mtc0_performance7(cpu_env, arg);
6377 rn
= "Performance7";
6403 gen_helper_mtc0_taglo(cpu_env
, arg
);
6410 gen_helper_mtc0_datalo(cpu_env
, arg
);
6423 gen_helper_mtc0_taghi(cpu_env
, arg
);
6430 gen_helper_mtc0_datahi(cpu_env
, arg
);
6441 tcg_gen_st_tl(arg
, cpu_env
, offsetof(CPUMIPSState
, CP0_ErrorEPC
));
6452 gen_mtc0_store32(arg
, offsetof(CPUMIPSState
, CP0_DESAVE
));
6458 /* Stop translation as we may have switched the execution mode */
6459 ctx
->bstate
= BS_STOP
;
6464 (void)rn
; /* avoid a compiler warning */
6465 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6466 /* For simplicity assume that all writes can cause interrupts. */
6469 ctx
->bstate
= BS_STOP
;
6474 LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn
, reg
, sel
);
6475 generate_exception(ctx
, EXCP_RI
);
6477 #endif /* TARGET_MIPS64 */
6479 static void gen_mftr(CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rd
,
6480 int u
, int sel
, int h
)
6482 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6483 TCGv t0
= tcg_temp_local_new();
6485 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6486 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6487 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6488 tcg_gen_movi_tl(t0
, -1);
6489 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6490 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6491 tcg_gen_movi_tl(t0
, -1);
6497 gen_helper_mftc0_vpecontrol(t0
, cpu_env
);
6500 gen_helper_mftc0_vpeconf0(t0
, cpu_env
);
6510 gen_helper_mftc0_tcstatus(t0
, cpu_env
);
6513 gen_helper_mftc0_tcbind(t0
, cpu_env
);
6516 gen_helper_mftc0_tcrestart(t0
, cpu_env
);
6519 gen_helper_mftc0_tchalt(t0
, cpu_env
);
6522 gen_helper_mftc0_tccontext(t0
, cpu_env
);
6525 gen_helper_mftc0_tcschedule(t0
, cpu_env
);
6528 gen_helper_mftc0_tcschefback(t0
, cpu_env
);
6531 gen_mfc0(ctx
, t0
, rt
, sel
);
6538 gen_helper_mftc0_entryhi(t0
, cpu_env
);
6541 gen_mfc0(ctx
, t0
, rt
, sel
);
6547 gen_helper_mftc0_status(t0
, cpu_env
);
6550 gen_mfc0(ctx
, t0
, rt
, sel
);
6556 gen_helper_mftc0_cause(t0
, cpu_env
);
6566 gen_helper_mftc0_epc(t0
, cpu_env
);
6576 gen_helper_mftc0_ebase(t0
, cpu_env
);
6586 gen_helper_mftc0_configx(t0
, cpu_env
, tcg_const_tl(sel
));
6596 gen_helper_mftc0_debug(t0
, cpu_env
);
6599 gen_mfc0(ctx
, t0
, rt
, sel
);
6604 gen_mfc0(ctx
, t0
, rt
, sel
);
6606 } else switch (sel
) {
6607 /* GPR registers. */
6609 gen_helper_1e0i(mftgpr
, t0
, rt
);
6611 /* Auxiliary CPU registers */
6615 gen_helper_1e0i(mftlo
, t0
, 0);
6618 gen_helper_1e0i(mfthi
, t0
, 0);
6621 gen_helper_1e0i(mftacx
, t0
, 0);
6624 gen_helper_1e0i(mftlo
, t0
, 1);
6627 gen_helper_1e0i(mfthi
, t0
, 1);
6630 gen_helper_1e0i(mftacx
, t0
, 1);
6633 gen_helper_1e0i(mftlo
, t0
, 2);
6636 gen_helper_1e0i(mfthi
, t0
, 2);
6639 gen_helper_1e0i(mftacx
, t0
, 2);
6642 gen_helper_1e0i(mftlo
, t0
, 3);
6645 gen_helper_1e0i(mfthi
, t0
, 3);
6648 gen_helper_1e0i(mftacx
, t0
, 3);
6651 gen_helper_mftdsp(t0
, cpu_env
);
6657 /* Floating point (COP1). */
6659 /* XXX: For now we support only a single FPU context. */
6661 TCGv_i32 fp0
= tcg_temp_new_i32();
6663 gen_load_fpr32(fp0
, rt
);
6664 tcg_gen_ext_i32_tl(t0
, fp0
);
6665 tcg_temp_free_i32(fp0
);
6667 TCGv_i32 fp0
= tcg_temp_new_i32();
6669 gen_load_fpr32h(ctx
, fp0
, rt
);
6670 tcg_gen_ext_i32_tl(t0
, fp0
);
6671 tcg_temp_free_i32(fp0
);
6675 /* XXX: For now we support only a single FPU context. */
6676 gen_helper_1e0i(cfc1
, t0
, rt
);
6678 /* COP2: Not implemented. */
6685 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6686 gen_store_gpr(t0
, rd
);
6692 LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt
, u
, sel
, h
);
6693 generate_exception(ctx
, EXCP_RI
);
6696 static void gen_mttr(CPUMIPSState
*env
, DisasContext
*ctx
, int rd
, int rt
,
6697 int u
, int sel
, int h
)
6699 int other_tc
= env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
);
6700 TCGv t0
= tcg_temp_local_new();
6702 gen_load_gpr(t0
, rt
);
6703 if ((env
->CP0_VPEConf0
& (1 << CP0VPEC0_MVP
)) == 0 &&
6704 ((env
->tcs
[other_tc
].CP0_TCBind
& (0xf << CP0TCBd_CurVPE
)) !=
6705 (env
->active_tc
.CP0_TCBind
& (0xf << CP0TCBd_CurVPE
))))
6707 else if ((env
->CP0_VPEControl
& (0xff << CP0VPECo_TargTC
)) >
6708 (env
->mvp
->CP0_MVPConf0
& (0xff << CP0MVPC0_PTC
)))
6715 gen_helper_mttc0_vpecontrol(cpu_env
, t0
);
6718 gen_helper_mttc0_vpeconf0(cpu_env
, t0
);
6728 gen_helper_mttc0_tcstatus(cpu_env
, t0
);
6731 gen_helper_mttc0_tcbind(cpu_env
, t0
);
6734 gen_helper_mttc0_tcrestart(cpu_env
, t0
);
6737 gen_helper_mttc0_tchalt(cpu_env
, t0
);
6740 gen_helper_mttc0_tccontext(cpu_env
, t0
);
6743 gen_helper_mttc0_tcschedule(cpu_env
, t0
);
6746 gen_helper_mttc0_tcschefback(cpu_env
, t0
);
6749 gen_mtc0(ctx
, t0
, rd
, sel
);
6756 gen_helper_mttc0_entryhi(cpu_env
, t0
);
6759 gen_mtc0(ctx
, t0
, rd
, sel
);
6765 gen_helper_mttc0_status(cpu_env
, t0
);
6768 gen_mtc0(ctx
, t0
, rd
, sel
);
6774 gen_helper_mttc0_cause(cpu_env
, t0
);
6784 gen_helper_mttc0_ebase(cpu_env
, t0
);
6794 gen_helper_mttc0_debug(cpu_env
, t0
);
6797 gen_mtc0(ctx
, t0
, rd
, sel
);
6802 gen_mtc0(ctx
, t0
, rd
, sel
);
6804 } else switch (sel
) {
6805 /* GPR registers. */
6807 gen_helper_0e1i(mttgpr
, t0
, rd
);
6809 /* Auxiliary CPU registers */
6813 gen_helper_0e1i(mttlo
, t0
, 0);
6816 gen_helper_0e1i(mtthi
, t0
, 0);
6819 gen_helper_0e1i(mttacx
, t0
, 0);
6822 gen_helper_0e1i(mttlo
, t0
, 1);
6825 gen_helper_0e1i(mtthi
, t0
, 1);
6828 gen_helper_0e1i(mttacx
, t0
, 1);
6831 gen_helper_0e1i(mttlo
, t0
, 2);
6834 gen_helper_0e1i(mtthi
, t0
, 2);
6837 gen_helper_0e1i(mttacx
, t0
, 2);
6840 gen_helper_0e1i(mttlo
, t0
, 3);
6843 gen_helper_0e1i(mtthi
, t0
, 3);
6846 gen_helper_0e1i(mttacx
, t0
, 3);
6849 gen_helper_mttdsp(cpu_env
, t0
);
6855 /* Floating point (COP1). */
6857 /* XXX: For now we support only a single FPU context. */
6859 TCGv_i32 fp0
= tcg_temp_new_i32();
6861 tcg_gen_trunc_tl_i32(fp0
, t0
);
6862 gen_store_fpr32(fp0
, rd
);
6863 tcg_temp_free_i32(fp0
);
6865 TCGv_i32 fp0
= tcg_temp_new_i32();
6867 tcg_gen_trunc_tl_i32(fp0
, t0
);
6868 gen_store_fpr32h(ctx
, fp0
, rd
);
6869 tcg_temp_free_i32(fp0
);
6873 /* XXX: For now we support only a single FPU context. */
6875 TCGv_i32 fs_tmp
= tcg_const_i32(rd
);
6877 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
6878 tcg_temp_free_i32(fs_tmp
);
6881 /* COP2: Not implemented. */
6888 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6894 LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd
, u
, sel
, h
);
6895 generate_exception(ctx
, EXCP_RI
);
6898 static void gen_cp0 (CPUMIPSState
*env
, DisasContext
*ctx
, uint32_t opc
, int rt
, int rd
)
6900 const char *opn
= "ldst";
6902 check_cp0_enabled(ctx
);
6909 gen_mfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6914 TCGv t0
= tcg_temp_new();
6916 gen_load_gpr(t0
, rt
);
6917 gen_mtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6922 #if defined(TARGET_MIPS64)
6924 check_insn(ctx
, ISA_MIPS3
);
6929 gen_dmfc0(ctx
, cpu_gpr
[rt
], rd
, ctx
->opcode
& 0x7);
6933 check_insn(ctx
, ISA_MIPS3
);
6935 TCGv t0
= tcg_temp_new();
6937 gen_load_gpr(t0
, rt
);
6938 gen_dmtc0(ctx
, t0
, rd
, ctx
->opcode
& 0x7);
6945 check_insn(ctx
, ASE_MT
);
6950 gen_mftr(env
, ctx
, rt
, rd
, (ctx
->opcode
>> 5) & 1,
6951 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6955 check_insn(ctx
, ASE_MT
);
6956 gen_mttr(env
, ctx
, rd
, rt
, (ctx
->opcode
>> 5) & 1,
6957 ctx
->opcode
& 0x7, (ctx
->opcode
>> 4) & 1);
6962 if (!env
->tlb
->helper_tlbwi
)
6964 gen_helper_tlbwi(cpu_env
);
6968 if (!env
->tlb
->helper_tlbwr
)
6970 gen_helper_tlbwr(cpu_env
);
6974 if (!env
->tlb
->helper_tlbp
)
6976 gen_helper_tlbp(cpu_env
);
6980 if (!env
->tlb
->helper_tlbr
)
6982 gen_helper_tlbr(cpu_env
);
6986 check_insn(ctx
, ISA_MIPS2
);
6987 gen_helper_eret(cpu_env
);
6988 ctx
->bstate
= BS_EXCP
;
6992 check_insn(ctx
, ISA_MIPS32
);
6993 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
6995 generate_exception(ctx
, EXCP_RI
);
6997 gen_helper_deret(cpu_env
);
6998 ctx
->bstate
= BS_EXCP
;
7003 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
7004 /* If we get an exception, we want to restart at next instruction */
7006 save_cpu_state(ctx
, 1);
7008 gen_helper_wait(cpu_env
);
7009 ctx
->bstate
= BS_EXCP
;
7014 generate_exception(ctx
, EXCP_RI
);
7017 (void)opn
; /* avoid a compiler warning */
7018 MIPS_DEBUG("%s %s %d", opn
, regnames
[rt
], rd
);
7020 #endif /* !CONFIG_USER_ONLY */
7022 /* CP1 Branches (before delay slot) */
7023 static void gen_compute_branch1(DisasContext
*ctx
, uint32_t op
,
7024 int32_t cc
, int32_t offset
)
7026 target_ulong btarget
;
7027 const char *opn
= "cp1 cond branch";
7028 TCGv_i32 t0
= tcg_temp_new_i32();
7031 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
7033 btarget
= ctx
->pc
+ 4 + offset
;
7037 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7038 tcg_gen_not_i32(t0
, t0
);
7039 tcg_gen_andi_i32(t0
, t0
, 1);
7040 tcg_gen_extu_i32_tl(bcond
, t0
);
7044 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7045 tcg_gen_not_i32(t0
, t0
);
7046 tcg_gen_andi_i32(t0
, t0
, 1);
7047 tcg_gen_extu_i32_tl(bcond
, t0
);
7051 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7052 tcg_gen_andi_i32(t0
, t0
, 1);
7053 tcg_gen_extu_i32_tl(bcond
, t0
);
7057 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7058 tcg_gen_andi_i32(t0
, t0
, 1);
7059 tcg_gen_extu_i32_tl(bcond
, t0
);
7062 ctx
->hflags
|= MIPS_HFLAG_BL
;
7066 TCGv_i32 t1
= tcg_temp_new_i32();
7067 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7068 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7069 tcg_gen_nand_i32(t0
, t0
, t1
);
7070 tcg_temp_free_i32(t1
);
7071 tcg_gen_andi_i32(t0
, t0
, 1);
7072 tcg_gen_extu_i32_tl(bcond
, t0
);
7078 TCGv_i32 t1
= tcg_temp_new_i32();
7079 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7080 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7081 tcg_gen_or_i32(t0
, t0
, t1
);
7082 tcg_temp_free_i32(t1
);
7083 tcg_gen_andi_i32(t0
, t0
, 1);
7084 tcg_gen_extu_i32_tl(bcond
, t0
);
7090 TCGv_i32 t1
= tcg_temp_new_i32();
7091 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7092 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7093 tcg_gen_and_i32(t0
, t0
, t1
);
7094 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7095 tcg_gen_and_i32(t0
, t0
, t1
);
7096 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7097 tcg_gen_nand_i32(t0
, t0
, t1
);
7098 tcg_temp_free_i32(t1
);
7099 tcg_gen_andi_i32(t0
, t0
, 1);
7100 tcg_gen_extu_i32_tl(bcond
, t0
);
7106 TCGv_i32 t1
= tcg_temp_new_i32();
7107 tcg_gen_shri_i32(t0
, fpu_fcr31
, get_fp_bit(cc
));
7108 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+1));
7109 tcg_gen_or_i32(t0
, t0
, t1
);
7110 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+2));
7111 tcg_gen_or_i32(t0
, t0
, t1
);
7112 tcg_gen_shri_i32(t1
, fpu_fcr31
, get_fp_bit(cc
+3));
7113 tcg_gen_or_i32(t0
, t0
, t1
);
7114 tcg_temp_free_i32(t1
);
7115 tcg_gen_andi_i32(t0
, t0
, 1);
7116 tcg_gen_extu_i32_tl(bcond
, t0
);
7120 ctx
->hflags
|= MIPS_HFLAG_BC
;
7124 generate_exception (ctx
, EXCP_RI
);
7127 (void)opn
; /* avoid a compiler warning */
7128 MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx
, opn
,
7129 ctx
->hflags
, btarget
);
7130 ctx
->btarget
= btarget
;
7133 tcg_temp_free_i32(t0
);
7136 /* Coprocessor 1 (FPU) */
7138 #define FOP(func, fmt) (((fmt) << 21) | (func))
7141 OPC_ADD_S
= FOP(0, FMT_S
),
7142 OPC_SUB_S
= FOP(1, FMT_S
),
7143 OPC_MUL_S
= FOP(2, FMT_S
),
7144 OPC_DIV_S
= FOP(3, FMT_S
),
7145 OPC_SQRT_S
= FOP(4, FMT_S
),
7146 OPC_ABS_S
= FOP(5, FMT_S
),
7147 OPC_MOV_S
= FOP(6, FMT_S
),
7148 OPC_NEG_S
= FOP(7, FMT_S
),
7149 OPC_ROUND_L_S
= FOP(8, FMT_S
),
7150 OPC_TRUNC_L_S
= FOP(9, FMT_S
),
7151 OPC_CEIL_L_S
= FOP(10, FMT_S
),
7152 OPC_FLOOR_L_S
= FOP(11, FMT_S
),
7153 OPC_ROUND_W_S
= FOP(12, FMT_S
),
7154 OPC_TRUNC_W_S
= FOP(13, FMT_S
),
7155 OPC_CEIL_W_S
= FOP(14, FMT_S
),
7156 OPC_FLOOR_W_S
= FOP(15, FMT_S
),
7157 OPC_MOVCF_S
= FOP(17, FMT_S
),
7158 OPC_MOVZ_S
= FOP(18, FMT_S
),
7159 OPC_MOVN_S
= FOP(19, FMT_S
),
7160 OPC_RECIP_S
= FOP(21, FMT_S
),
7161 OPC_RSQRT_S
= FOP(22, FMT_S
),
7162 OPC_RECIP2_S
= FOP(28, FMT_S
),
7163 OPC_RECIP1_S
= FOP(29, FMT_S
),
7164 OPC_RSQRT1_S
= FOP(30, FMT_S
),
7165 OPC_RSQRT2_S
= FOP(31, FMT_S
),
7166 OPC_CVT_D_S
= FOP(33, FMT_S
),
7167 OPC_CVT_W_S
= FOP(36, FMT_S
),
7168 OPC_CVT_L_S
= FOP(37, FMT_S
),
7169 OPC_CVT_PS_S
= FOP(38, FMT_S
),
7170 OPC_CMP_F_S
= FOP (48, FMT_S
),
7171 OPC_CMP_UN_S
= FOP (49, FMT_S
),
7172 OPC_CMP_EQ_S
= FOP (50, FMT_S
),
7173 OPC_CMP_UEQ_S
= FOP (51, FMT_S
),
7174 OPC_CMP_OLT_S
= FOP (52, FMT_S
),
7175 OPC_CMP_ULT_S
= FOP (53, FMT_S
),
7176 OPC_CMP_OLE_S
= FOP (54, FMT_S
),
7177 OPC_CMP_ULE_S
= FOP (55, FMT_S
),
7178 OPC_CMP_SF_S
= FOP (56, FMT_S
),
7179 OPC_CMP_NGLE_S
= FOP (57, FMT_S
),
7180 OPC_CMP_SEQ_S
= FOP (58, FMT_S
),
7181 OPC_CMP_NGL_S
= FOP (59, FMT_S
),
7182 OPC_CMP_LT_S
= FOP (60, FMT_S
),
7183 OPC_CMP_NGE_S
= FOP (61, FMT_S
),
7184 OPC_CMP_LE_S
= FOP (62, FMT_S
),
7185 OPC_CMP_NGT_S
= FOP (63, FMT_S
),
7187 OPC_ADD_D
= FOP(0, FMT_D
),
7188 OPC_SUB_D
= FOP(1, FMT_D
),
7189 OPC_MUL_D
= FOP(2, FMT_D
),
7190 OPC_DIV_D
= FOP(3, FMT_D
),
7191 OPC_SQRT_D
= FOP(4, FMT_D
),
7192 OPC_ABS_D
= FOP(5, FMT_D
),
7193 OPC_MOV_D
= FOP(6, FMT_D
),
7194 OPC_NEG_D
= FOP(7, FMT_D
),
7195 OPC_ROUND_L_D
= FOP(8, FMT_D
),
7196 OPC_TRUNC_L_D
= FOP(9, FMT_D
),
7197 OPC_CEIL_L_D
= FOP(10, FMT_D
),
7198 OPC_FLOOR_L_D
= FOP(11, FMT_D
),
7199 OPC_ROUND_W_D
= FOP(12, FMT_D
),
7200 OPC_TRUNC_W_D
= FOP(13, FMT_D
),
7201 OPC_CEIL_W_D
= FOP(14, FMT_D
),
7202 OPC_FLOOR_W_D
= FOP(15, FMT_D
),
7203 OPC_MOVCF_D
= FOP(17, FMT_D
),
7204 OPC_MOVZ_D
= FOP(18, FMT_D
),
7205 OPC_MOVN_D
= FOP(19, FMT_D
),
7206 OPC_RECIP_D
= FOP(21, FMT_D
),
7207 OPC_RSQRT_D
= FOP(22, FMT_D
),
7208 OPC_RECIP2_D
= FOP(28, FMT_D
),
7209 OPC_RECIP1_D
= FOP(29, FMT_D
),
7210 OPC_RSQRT1_D
= FOP(30, FMT_D
),
7211 OPC_RSQRT2_D
= FOP(31, FMT_D
),
7212 OPC_CVT_S_D
= FOP(32, FMT_D
),
7213 OPC_CVT_W_D
= FOP(36, FMT_D
),
7214 OPC_CVT_L_D
= FOP(37, FMT_D
),
7215 OPC_CMP_F_D
= FOP (48, FMT_D
),
7216 OPC_CMP_UN_D
= FOP (49, FMT_D
),
7217 OPC_CMP_EQ_D
= FOP (50, FMT_D
),
7218 OPC_CMP_UEQ_D
= FOP (51, FMT_D
),
7219 OPC_CMP_OLT_D
= FOP (52, FMT_D
),
7220 OPC_CMP_ULT_D
= FOP (53, FMT_D
),
7221 OPC_CMP_OLE_D
= FOP (54, FMT_D
),
7222 OPC_CMP_ULE_D
= FOP (55, FMT_D
),
7223 OPC_CMP_SF_D
= FOP (56, FMT_D
),
7224 OPC_CMP_NGLE_D
= FOP (57, FMT_D
),
7225 OPC_CMP_SEQ_D
= FOP (58, FMT_D
),
7226 OPC_CMP_NGL_D
= FOP (59, FMT_D
),
7227 OPC_CMP_LT_D
= FOP (60, FMT_D
),
7228 OPC_CMP_NGE_D
= FOP (61, FMT_D
),
7229 OPC_CMP_LE_D
= FOP (62, FMT_D
),
7230 OPC_CMP_NGT_D
= FOP (63, FMT_D
),
7232 OPC_CVT_S_W
= FOP(32, FMT_W
),
7233 OPC_CVT_D_W
= FOP(33, FMT_W
),
7234 OPC_CVT_S_L
= FOP(32, FMT_L
),
7235 OPC_CVT_D_L
= FOP(33, FMT_L
),
7236 OPC_CVT_PS_PW
= FOP(38, FMT_W
),
7238 OPC_ADD_PS
= FOP(0, FMT_PS
),
7239 OPC_SUB_PS
= FOP(1, FMT_PS
),
7240 OPC_MUL_PS
= FOP(2, FMT_PS
),
7241 OPC_DIV_PS
= FOP(3, FMT_PS
),
7242 OPC_ABS_PS
= FOP(5, FMT_PS
),
7243 OPC_MOV_PS
= FOP(6, FMT_PS
),
7244 OPC_NEG_PS
= FOP(7, FMT_PS
),
7245 OPC_MOVCF_PS
= FOP(17, FMT_PS
),
7246 OPC_MOVZ_PS
= FOP(18, FMT_PS
),
7247 OPC_MOVN_PS
= FOP(19, FMT_PS
),
7248 OPC_ADDR_PS
= FOP(24, FMT_PS
),
7249 OPC_MULR_PS
= FOP(26, FMT_PS
),
7250 OPC_RECIP2_PS
= FOP(28, FMT_PS
),
7251 OPC_RECIP1_PS
= FOP(29, FMT_PS
),
7252 OPC_RSQRT1_PS
= FOP(30, FMT_PS
),
7253 OPC_RSQRT2_PS
= FOP(31, FMT_PS
),
7255 OPC_CVT_S_PU
= FOP(32, FMT_PS
),
7256 OPC_CVT_PW_PS
= FOP(36, FMT_PS
),
7257 OPC_CVT_S_PL
= FOP(40, FMT_PS
),
7258 OPC_PLL_PS
= FOP(44, FMT_PS
),
7259 OPC_PLU_PS
= FOP(45, FMT_PS
),
7260 OPC_PUL_PS
= FOP(46, FMT_PS
),
7261 OPC_PUU_PS
= FOP(47, FMT_PS
),
7262 OPC_CMP_F_PS
= FOP (48, FMT_PS
),
7263 OPC_CMP_UN_PS
= FOP (49, FMT_PS
),
7264 OPC_CMP_EQ_PS
= FOP (50, FMT_PS
),
7265 OPC_CMP_UEQ_PS
= FOP (51, FMT_PS
),
7266 OPC_CMP_OLT_PS
= FOP (52, FMT_PS
),
7267 OPC_CMP_ULT_PS
= FOP (53, FMT_PS
),
7268 OPC_CMP_OLE_PS
= FOP (54, FMT_PS
),
7269 OPC_CMP_ULE_PS
= FOP (55, FMT_PS
),
7270 OPC_CMP_SF_PS
= FOP (56, FMT_PS
),
7271 OPC_CMP_NGLE_PS
= FOP (57, FMT_PS
),
7272 OPC_CMP_SEQ_PS
= FOP (58, FMT_PS
),
7273 OPC_CMP_NGL_PS
= FOP (59, FMT_PS
),
7274 OPC_CMP_LT_PS
= FOP (60, FMT_PS
),
7275 OPC_CMP_NGE_PS
= FOP (61, FMT_PS
),
7276 OPC_CMP_LE_PS
= FOP (62, FMT_PS
),
7277 OPC_CMP_NGT_PS
= FOP (63, FMT_PS
),
7280 static void gen_cp1 (DisasContext
*ctx
, uint32_t opc
, int rt
, int fs
)
7282 const char *opn
= "cp1 move";
7283 TCGv t0
= tcg_temp_new();
7288 TCGv_i32 fp0
= tcg_temp_new_i32();
7290 gen_load_fpr32(fp0
, fs
);
7291 tcg_gen_ext_i32_tl(t0
, fp0
);
7292 tcg_temp_free_i32(fp0
);
7294 gen_store_gpr(t0
, rt
);
7298 gen_load_gpr(t0
, rt
);
7300 TCGv_i32 fp0
= tcg_temp_new_i32();
7302 tcg_gen_trunc_tl_i32(fp0
, t0
);
7303 gen_store_fpr32(fp0
, fs
);
7304 tcg_temp_free_i32(fp0
);
7309 gen_helper_1e0i(cfc1
, t0
, fs
);
7310 gen_store_gpr(t0
, rt
);
7314 gen_load_gpr(t0
, rt
);
7316 TCGv_i32 fs_tmp
= tcg_const_i32(fs
);
7318 gen_helper_0e2i(ctc1
, t0
, fs_tmp
, rt
);
7319 tcg_temp_free_i32(fs_tmp
);
7323 #if defined(TARGET_MIPS64)
7325 gen_load_fpr64(ctx
, t0
, fs
);
7326 gen_store_gpr(t0
, rt
);
7330 gen_load_gpr(t0
, rt
);
7331 gen_store_fpr64(ctx
, t0
, fs
);
7337 TCGv_i32 fp0
= tcg_temp_new_i32();
7339 gen_load_fpr32h(ctx
, fp0
, fs
);
7340 tcg_gen_ext_i32_tl(t0
, fp0
);
7341 tcg_temp_free_i32(fp0
);
7343 gen_store_gpr(t0
, rt
);
7347 gen_load_gpr(t0
, rt
);
7349 TCGv_i32 fp0
= tcg_temp_new_i32();
7351 tcg_gen_trunc_tl_i32(fp0
, t0
);
7352 gen_store_fpr32h(ctx
, fp0
, fs
);
7353 tcg_temp_free_i32(fp0
);
7359 generate_exception (ctx
, EXCP_RI
);
7362 (void)opn
; /* avoid a compiler warning */
7363 MIPS_DEBUG("%s %s %s", opn
, regnames
[rt
], fregnames
[fs
]);
7369 static void gen_movci (DisasContext
*ctx
, int rd
, int rs
, int cc
, int tf
)
7385 l1
= gen_new_label();
7386 t0
= tcg_temp_new_i32();
7387 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7388 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7389 tcg_temp_free_i32(t0
);
7391 tcg_gen_movi_tl(cpu_gpr
[rd
], 0);
7393 tcg_gen_mov_tl(cpu_gpr
[rd
], cpu_gpr
[rs
]);
7398 static inline void gen_movcf_s (int fs
, int fd
, int cc
, int tf
)
7401 TCGv_i32 t0
= tcg_temp_new_i32();
7402 int l1
= gen_new_label();
7409 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7410 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7411 gen_load_fpr32(t0
, fs
);
7412 gen_store_fpr32(t0
, fd
);
7414 tcg_temp_free_i32(t0
);
7417 static inline void gen_movcf_d (DisasContext
*ctx
, int fs
, int fd
, int cc
, int tf
)
7420 TCGv_i32 t0
= tcg_temp_new_i32();
7422 int l1
= gen_new_label();
7429 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7430 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7431 tcg_temp_free_i32(t0
);
7432 fp0
= tcg_temp_new_i64();
7433 gen_load_fpr64(ctx
, fp0
, fs
);
7434 gen_store_fpr64(ctx
, fp0
, fd
);
7435 tcg_temp_free_i64(fp0
);
7439 static inline void gen_movcf_ps(DisasContext
*ctx
, int fs
, int fd
,
7443 TCGv_i32 t0
= tcg_temp_new_i32();
7444 int l1
= gen_new_label();
7445 int l2
= gen_new_label();
7452 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
));
7453 tcg_gen_brcondi_i32(cond
, t0
, 0, l1
);
7454 gen_load_fpr32(t0
, fs
);
7455 gen_store_fpr32(t0
, fd
);
7458 tcg_gen_andi_i32(t0
, fpu_fcr31
, 1 << get_fp_bit(cc
+1));
7459 tcg_gen_brcondi_i32(cond
, t0
, 0, l2
);
7460 gen_load_fpr32h(ctx
, t0
, fs
);
7461 gen_store_fpr32h(ctx
, t0
, fd
);
7462 tcg_temp_free_i32(t0
);
7467 static void gen_farith (DisasContext
*ctx
, enum fopcode op1
,
7468 int ft
, int fs
, int fd
, int cc
)
7470 const char *opn
= "farith";
7471 const char *condnames
[] = {
7489 const char *condnames_abs
[] = {
7507 enum { BINOP
, CMPOP
, OTHEROP
} optype
= OTHEROP
;
7508 uint32_t func
= ctx
->opcode
& 0x3f;
7513 TCGv_i32 fp0
= tcg_temp_new_i32();
7514 TCGv_i32 fp1
= tcg_temp_new_i32();
7516 gen_load_fpr32(fp0
, fs
);
7517 gen_load_fpr32(fp1
, ft
);
7518 gen_helper_float_add_s(fp0
, cpu_env
, fp0
, fp1
);
7519 tcg_temp_free_i32(fp1
);
7520 gen_store_fpr32(fp0
, fd
);
7521 tcg_temp_free_i32(fp0
);
7528 TCGv_i32 fp0
= tcg_temp_new_i32();
7529 TCGv_i32 fp1
= tcg_temp_new_i32();
7531 gen_load_fpr32(fp0
, fs
);
7532 gen_load_fpr32(fp1
, ft
);
7533 gen_helper_float_sub_s(fp0
, cpu_env
, fp0
, fp1
);
7534 tcg_temp_free_i32(fp1
);
7535 gen_store_fpr32(fp0
, fd
);
7536 tcg_temp_free_i32(fp0
);
7543 TCGv_i32 fp0
= tcg_temp_new_i32();
7544 TCGv_i32 fp1
= tcg_temp_new_i32();
7546 gen_load_fpr32(fp0
, fs
);
7547 gen_load_fpr32(fp1
, ft
);
7548 gen_helper_float_mul_s(fp0
, cpu_env
, fp0
, fp1
);
7549 tcg_temp_free_i32(fp1
);
7550 gen_store_fpr32(fp0
, fd
);
7551 tcg_temp_free_i32(fp0
);
7558 TCGv_i32 fp0
= tcg_temp_new_i32();
7559 TCGv_i32 fp1
= tcg_temp_new_i32();
7561 gen_load_fpr32(fp0
, fs
);
7562 gen_load_fpr32(fp1
, ft
);
7563 gen_helper_float_div_s(fp0
, cpu_env
, fp0
, fp1
);
7564 tcg_temp_free_i32(fp1
);
7565 gen_store_fpr32(fp0
, fd
);
7566 tcg_temp_free_i32(fp0
);
7573 TCGv_i32 fp0
= tcg_temp_new_i32();
7575 gen_load_fpr32(fp0
, fs
);
7576 gen_helper_float_sqrt_s(fp0
, cpu_env
, fp0
);
7577 gen_store_fpr32(fp0
, fd
);
7578 tcg_temp_free_i32(fp0
);
7584 TCGv_i32 fp0
= tcg_temp_new_i32();
7586 gen_load_fpr32(fp0
, fs
);
7587 gen_helper_float_abs_s(fp0
, fp0
);
7588 gen_store_fpr32(fp0
, fd
);
7589 tcg_temp_free_i32(fp0
);
7595 TCGv_i32 fp0
= tcg_temp_new_i32();
7597 gen_load_fpr32(fp0
, fs
);
7598 gen_store_fpr32(fp0
, fd
);
7599 tcg_temp_free_i32(fp0
);
7605 TCGv_i32 fp0
= tcg_temp_new_i32();
7607 gen_load_fpr32(fp0
, fs
);
7608 gen_helper_float_chs_s(fp0
, fp0
);
7609 gen_store_fpr32(fp0
, fd
);
7610 tcg_temp_free_i32(fp0
);
7615 check_cp1_64bitmode(ctx
);
7617 TCGv_i32 fp32
= tcg_temp_new_i32();
7618 TCGv_i64 fp64
= tcg_temp_new_i64();
7620 gen_load_fpr32(fp32
, fs
);
7621 gen_helper_float_roundl_s(fp64
, cpu_env
, fp32
);
7622 tcg_temp_free_i32(fp32
);
7623 gen_store_fpr64(ctx
, fp64
, fd
);
7624 tcg_temp_free_i64(fp64
);
7629 check_cp1_64bitmode(ctx
);
7631 TCGv_i32 fp32
= tcg_temp_new_i32();
7632 TCGv_i64 fp64
= tcg_temp_new_i64();
7634 gen_load_fpr32(fp32
, fs
);
7635 gen_helper_float_truncl_s(fp64
, cpu_env
, fp32
);
7636 tcg_temp_free_i32(fp32
);
7637 gen_store_fpr64(ctx
, fp64
, fd
);
7638 tcg_temp_free_i64(fp64
);
7643 check_cp1_64bitmode(ctx
);
7645 TCGv_i32 fp32
= tcg_temp_new_i32();
7646 TCGv_i64 fp64
= tcg_temp_new_i64();
7648 gen_load_fpr32(fp32
, fs
);
7649 gen_helper_float_ceill_s(fp64
, cpu_env
, fp32
);
7650 tcg_temp_free_i32(fp32
);
7651 gen_store_fpr64(ctx
, fp64
, fd
);
7652 tcg_temp_free_i64(fp64
);
7657 check_cp1_64bitmode(ctx
);
7659 TCGv_i32 fp32
= tcg_temp_new_i32();
7660 TCGv_i64 fp64
= tcg_temp_new_i64();
7662 gen_load_fpr32(fp32
, fs
);
7663 gen_helper_float_floorl_s(fp64
, cpu_env
, fp32
);
7664 tcg_temp_free_i32(fp32
);
7665 gen_store_fpr64(ctx
, fp64
, fd
);
7666 tcg_temp_free_i64(fp64
);
7672 TCGv_i32 fp0
= tcg_temp_new_i32();
7674 gen_load_fpr32(fp0
, fs
);
7675 gen_helper_float_roundw_s(fp0
, cpu_env
, fp0
);
7676 gen_store_fpr32(fp0
, fd
);
7677 tcg_temp_free_i32(fp0
);
7683 TCGv_i32 fp0
= tcg_temp_new_i32();
7685 gen_load_fpr32(fp0
, fs
);
7686 gen_helper_float_truncw_s(fp0
, cpu_env
, fp0
);
7687 gen_store_fpr32(fp0
, fd
);
7688 tcg_temp_free_i32(fp0
);
7694 TCGv_i32 fp0
= tcg_temp_new_i32();
7696 gen_load_fpr32(fp0
, fs
);
7697 gen_helper_float_ceilw_s(fp0
, cpu_env
, fp0
);
7698 gen_store_fpr32(fp0
, fd
);
7699 tcg_temp_free_i32(fp0
);
7705 TCGv_i32 fp0
= tcg_temp_new_i32();
7707 gen_load_fpr32(fp0
, fs
);
7708 gen_helper_float_floorw_s(fp0
, cpu_env
, fp0
);
7709 gen_store_fpr32(fp0
, fd
);
7710 tcg_temp_free_i32(fp0
);
7715 gen_movcf_s(fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
7720 int l1
= gen_new_label();
7724 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
7726 fp0
= tcg_temp_new_i32();
7727 gen_load_fpr32(fp0
, fs
);
7728 gen_store_fpr32(fp0
, fd
);
7729 tcg_temp_free_i32(fp0
);
7736 int l1
= gen_new_label();
7740 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
7741 fp0
= tcg_temp_new_i32();
7742 gen_load_fpr32(fp0
, fs
);
7743 gen_store_fpr32(fp0
, fd
);
7744 tcg_temp_free_i32(fp0
);
7753 TCGv_i32 fp0
= tcg_temp_new_i32();
7755 gen_load_fpr32(fp0
, fs
);
7756 gen_helper_float_recip_s(fp0
, cpu_env
, fp0
);
7757 gen_store_fpr32(fp0
, fd
);
7758 tcg_temp_free_i32(fp0
);
7765 TCGv_i32 fp0
= tcg_temp_new_i32();
7767 gen_load_fpr32(fp0
, fs
);
7768 gen_helper_float_rsqrt_s(fp0
, cpu_env
, fp0
);
7769 gen_store_fpr32(fp0
, fd
);
7770 tcg_temp_free_i32(fp0
);
7775 check_cp1_64bitmode(ctx
);
7777 TCGv_i32 fp0
= tcg_temp_new_i32();
7778 TCGv_i32 fp1
= tcg_temp_new_i32();
7780 gen_load_fpr32(fp0
, fs
);
7781 gen_load_fpr32(fp1
, ft
);
7782 gen_helper_float_recip2_s(fp0
, cpu_env
, fp0
, fp1
);
7783 tcg_temp_free_i32(fp1
);
7784 gen_store_fpr32(fp0
, fd
);
7785 tcg_temp_free_i32(fp0
);
7790 check_cp1_64bitmode(ctx
);
7792 TCGv_i32 fp0
= tcg_temp_new_i32();
7794 gen_load_fpr32(fp0
, fs
);
7795 gen_helper_float_recip1_s(fp0
, cpu_env
, fp0
);
7796 gen_store_fpr32(fp0
, fd
);
7797 tcg_temp_free_i32(fp0
);
7802 check_cp1_64bitmode(ctx
);
7804 TCGv_i32 fp0
= tcg_temp_new_i32();
7806 gen_load_fpr32(fp0
, fs
);
7807 gen_helper_float_rsqrt1_s(fp0
, cpu_env
, fp0
);
7808 gen_store_fpr32(fp0
, fd
);
7809 tcg_temp_free_i32(fp0
);
7814 check_cp1_64bitmode(ctx
);
7816 TCGv_i32 fp0
= tcg_temp_new_i32();
7817 TCGv_i32 fp1
= tcg_temp_new_i32();
7819 gen_load_fpr32(fp0
, fs
);
7820 gen_load_fpr32(fp1
, ft
);
7821 gen_helper_float_rsqrt2_s(fp0
, cpu_env
, fp0
, fp1
);
7822 tcg_temp_free_i32(fp1
);
7823 gen_store_fpr32(fp0
, fd
);
7824 tcg_temp_free_i32(fp0
);
7829 check_cp1_registers(ctx
, fd
);
7831 TCGv_i32 fp32
= tcg_temp_new_i32();
7832 TCGv_i64 fp64
= tcg_temp_new_i64();
7834 gen_load_fpr32(fp32
, fs
);
7835 gen_helper_float_cvtd_s(fp64
, cpu_env
, fp32
);
7836 tcg_temp_free_i32(fp32
);
7837 gen_store_fpr64(ctx
, fp64
, fd
);
7838 tcg_temp_free_i64(fp64
);
7844 TCGv_i32 fp0
= tcg_temp_new_i32();
7846 gen_load_fpr32(fp0
, fs
);
7847 gen_helper_float_cvtw_s(fp0
, cpu_env
, fp0
);
7848 gen_store_fpr32(fp0
, fd
);
7849 tcg_temp_free_i32(fp0
);
7854 check_cp1_64bitmode(ctx
);
7856 TCGv_i32 fp32
= tcg_temp_new_i32();
7857 TCGv_i64 fp64
= tcg_temp_new_i64();
7859 gen_load_fpr32(fp32
, fs
);
7860 gen_helper_float_cvtl_s(fp64
, cpu_env
, fp32
);
7861 tcg_temp_free_i32(fp32
);
7862 gen_store_fpr64(ctx
, fp64
, fd
);
7863 tcg_temp_free_i64(fp64
);
7868 check_cp1_64bitmode(ctx
);
7870 TCGv_i64 fp64
= tcg_temp_new_i64();
7871 TCGv_i32 fp32_0
= tcg_temp_new_i32();
7872 TCGv_i32 fp32_1
= tcg_temp_new_i32();
7874 gen_load_fpr32(fp32_0
, fs
);
7875 gen_load_fpr32(fp32_1
, ft
);
7876 tcg_gen_concat_i32_i64(fp64
, fp32_1
, fp32_0
);
7877 tcg_temp_free_i32(fp32_1
);
7878 tcg_temp_free_i32(fp32_0
);
7879 gen_store_fpr64(ctx
, fp64
, fd
);
7880 tcg_temp_free_i64(fp64
);
7893 case OPC_CMP_NGLE_S
:
7900 if (ctx
->opcode
& (1 << 6)) {
7901 gen_cmpabs_s(ctx
, func
-48, ft
, fs
, cc
);
7902 opn
= condnames_abs
[func
-48];
7904 gen_cmp_s(ctx
, func
-48, ft
, fs
, cc
);
7905 opn
= condnames
[func
-48];
7909 check_cp1_registers(ctx
, fs
| ft
| fd
);
7911 TCGv_i64 fp0
= tcg_temp_new_i64();
7912 TCGv_i64 fp1
= tcg_temp_new_i64();
7914 gen_load_fpr64(ctx
, fp0
, fs
);
7915 gen_load_fpr64(ctx
, fp1
, ft
);
7916 gen_helper_float_add_d(fp0
, cpu_env
, fp0
, fp1
);
7917 tcg_temp_free_i64(fp1
);
7918 gen_store_fpr64(ctx
, fp0
, fd
);
7919 tcg_temp_free_i64(fp0
);
7925 check_cp1_registers(ctx
, fs
| ft
| fd
);
7927 TCGv_i64 fp0
= tcg_temp_new_i64();
7928 TCGv_i64 fp1
= tcg_temp_new_i64();
7930 gen_load_fpr64(ctx
, fp0
, fs
);
7931 gen_load_fpr64(ctx
, fp1
, ft
);
7932 gen_helper_float_sub_d(fp0
, cpu_env
, fp0
, fp1
);
7933 tcg_temp_free_i64(fp1
);
7934 gen_store_fpr64(ctx
, fp0
, fd
);
7935 tcg_temp_free_i64(fp0
);
7941 check_cp1_registers(ctx
, fs
| ft
| fd
);
7943 TCGv_i64 fp0
= tcg_temp_new_i64();
7944 TCGv_i64 fp1
= tcg_temp_new_i64();
7946 gen_load_fpr64(ctx
, fp0
, fs
);
7947 gen_load_fpr64(ctx
, fp1
, ft
);
7948 gen_helper_float_mul_d(fp0
, cpu_env
, fp0
, fp1
);
7949 tcg_temp_free_i64(fp1
);
7950 gen_store_fpr64(ctx
, fp0
, fd
);
7951 tcg_temp_free_i64(fp0
);
7957 check_cp1_registers(ctx
, fs
| ft
| fd
);
7959 TCGv_i64 fp0
= tcg_temp_new_i64();
7960 TCGv_i64 fp1
= tcg_temp_new_i64();
7962 gen_load_fpr64(ctx
, fp0
, fs
);
7963 gen_load_fpr64(ctx
, fp1
, ft
);
7964 gen_helper_float_div_d(fp0
, cpu_env
, fp0
, fp1
);
7965 tcg_temp_free_i64(fp1
);
7966 gen_store_fpr64(ctx
, fp0
, fd
);
7967 tcg_temp_free_i64(fp0
);
7973 check_cp1_registers(ctx
, fs
| fd
);
7975 TCGv_i64 fp0
= tcg_temp_new_i64();
7977 gen_load_fpr64(ctx
, fp0
, fs
);
7978 gen_helper_float_sqrt_d(fp0
, cpu_env
, fp0
);
7979 gen_store_fpr64(ctx
, fp0
, fd
);
7980 tcg_temp_free_i64(fp0
);
7985 check_cp1_registers(ctx
, fs
| fd
);
7987 TCGv_i64 fp0
= tcg_temp_new_i64();
7989 gen_load_fpr64(ctx
, fp0
, fs
);
7990 gen_helper_float_abs_d(fp0
, fp0
);
7991 gen_store_fpr64(ctx
, fp0
, fd
);
7992 tcg_temp_free_i64(fp0
);
7997 check_cp1_registers(ctx
, fs
| fd
);
7999 TCGv_i64 fp0
= tcg_temp_new_i64();
8001 gen_load_fpr64(ctx
, fp0
, fs
);
8002 gen_store_fpr64(ctx
, fp0
, fd
);
8003 tcg_temp_free_i64(fp0
);
8008 check_cp1_registers(ctx
, fs
| fd
);
8010 TCGv_i64 fp0
= tcg_temp_new_i64();
8012 gen_load_fpr64(ctx
, fp0
, fs
);
8013 gen_helper_float_chs_d(fp0
, fp0
);
8014 gen_store_fpr64(ctx
, fp0
, fd
);
8015 tcg_temp_free_i64(fp0
);
8020 check_cp1_64bitmode(ctx
);
8022 TCGv_i64 fp0
= tcg_temp_new_i64();
8024 gen_load_fpr64(ctx
, fp0
, fs
);
8025 gen_helper_float_roundl_d(fp0
, cpu_env
, fp0
);
8026 gen_store_fpr64(ctx
, fp0
, fd
);
8027 tcg_temp_free_i64(fp0
);
8032 check_cp1_64bitmode(ctx
);
8034 TCGv_i64 fp0
= tcg_temp_new_i64();
8036 gen_load_fpr64(ctx
, fp0
, fs
);
8037 gen_helper_float_truncl_d(fp0
, cpu_env
, fp0
);
8038 gen_store_fpr64(ctx
, fp0
, fd
);
8039 tcg_temp_free_i64(fp0
);
8044 check_cp1_64bitmode(ctx
);
8046 TCGv_i64 fp0
= tcg_temp_new_i64();
8048 gen_load_fpr64(ctx
, fp0
, fs
);
8049 gen_helper_float_ceill_d(fp0
, cpu_env
, fp0
);
8050 gen_store_fpr64(ctx
, fp0
, fd
);
8051 tcg_temp_free_i64(fp0
);
8056 check_cp1_64bitmode(ctx
);
8058 TCGv_i64 fp0
= tcg_temp_new_i64();
8060 gen_load_fpr64(ctx
, fp0
, fs
);
8061 gen_helper_float_floorl_d(fp0
, cpu_env
, fp0
);
8062 gen_store_fpr64(ctx
, fp0
, fd
);
8063 tcg_temp_free_i64(fp0
);
8068 check_cp1_registers(ctx
, fs
);
8070 TCGv_i32 fp32
= tcg_temp_new_i32();
8071 TCGv_i64 fp64
= tcg_temp_new_i64();
8073 gen_load_fpr64(ctx
, fp64
, fs
);
8074 gen_helper_float_roundw_d(fp32
, cpu_env
, fp64
);
8075 tcg_temp_free_i64(fp64
);
8076 gen_store_fpr32(fp32
, fd
);
8077 tcg_temp_free_i32(fp32
);
8082 check_cp1_registers(ctx
, fs
);
8084 TCGv_i32 fp32
= tcg_temp_new_i32();
8085 TCGv_i64 fp64
= tcg_temp_new_i64();
8087 gen_load_fpr64(ctx
, fp64
, fs
);
8088 gen_helper_float_truncw_d(fp32
, cpu_env
, fp64
);
8089 tcg_temp_free_i64(fp64
);
8090 gen_store_fpr32(fp32
, fd
);
8091 tcg_temp_free_i32(fp32
);
8096 check_cp1_registers(ctx
, fs
);
8098 TCGv_i32 fp32
= tcg_temp_new_i32();
8099 TCGv_i64 fp64
= tcg_temp_new_i64();
8101 gen_load_fpr64(ctx
, fp64
, fs
);
8102 gen_helper_float_ceilw_d(fp32
, cpu_env
, fp64
);
8103 tcg_temp_free_i64(fp64
);
8104 gen_store_fpr32(fp32
, fd
);
8105 tcg_temp_free_i32(fp32
);
8110 check_cp1_registers(ctx
, fs
);
8112 TCGv_i32 fp32
= tcg_temp_new_i32();
8113 TCGv_i64 fp64
= tcg_temp_new_i64();
8115 gen_load_fpr64(ctx
, fp64
, fs
);
8116 gen_helper_float_floorw_d(fp32
, cpu_env
, fp64
);
8117 tcg_temp_free_i64(fp64
);
8118 gen_store_fpr32(fp32
, fd
);
8119 tcg_temp_free_i32(fp32
);
8124 gen_movcf_d(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8129 int l1
= gen_new_label();
8133 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8135 fp0
= tcg_temp_new_i64();
8136 gen_load_fpr64(ctx
, fp0
, fs
);
8137 gen_store_fpr64(ctx
, fp0
, fd
);
8138 tcg_temp_free_i64(fp0
);
8145 int l1
= gen_new_label();
8149 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8150 fp0
= tcg_temp_new_i64();
8151 gen_load_fpr64(ctx
, fp0
, fs
);
8152 gen_store_fpr64(ctx
, fp0
, fd
);
8153 tcg_temp_free_i64(fp0
);
8160 check_cp1_64bitmode(ctx
);
8162 TCGv_i64 fp0
= tcg_temp_new_i64();
8164 gen_load_fpr64(ctx
, fp0
, fs
);
8165 gen_helper_float_recip_d(fp0
, cpu_env
, fp0
);
8166 gen_store_fpr64(ctx
, fp0
, fd
);
8167 tcg_temp_free_i64(fp0
);
8172 check_cp1_64bitmode(ctx
);
8174 TCGv_i64 fp0
= tcg_temp_new_i64();
8176 gen_load_fpr64(ctx
, fp0
, fs
);
8177 gen_helper_float_rsqrt_d(fp0
, cpu_env
, fp0
);
8178 gen_store_fpr64(ctx
, fp0
, fd
);
8179 tcg_temp_free_i64(fp0
);
8184 check_cp1_64bitmode(ctx
);
8186 TCGv_i64 fp0
= tcg_temp_new_i64();
8187 TCGv_i64 fp1
= tcg_temp_new_i64();
8189 gen_load_fpr64(ctx
, fp0
, fs
);
8190 gen_load_fpr64(ctx
, fp1
, ft
);
8191 gen_helper_float_recip2_d(fp0
, cpu_env
, fp0
, fp1
);
8192 tcg_temp_free_i64(fp1
);
8193 gen_store_fpr64(ctx
, fp0
, fd
);
8194 tcg_temp_free_i64(fp0
);
8199 check_cp1_64bitmode(ctx
);
8201 TCGv_i64 fp0
= tcg_temp_new_i64();
8203 gen_load_fpr64(ctx
, fp0
, fs
);
8204 gen_helper_float_recip1_d(fp0
, cpu_env
, fp0
);
8205 gen_store_fpr64(ctx
, fp0
, fd
);
8206 tcg_temp_free_i64(fp0
);
8211 check_cp1_64bitmode(ctx
);
8213 TCGv_i64 fp0
= tcg_temp_new_i64();
8215 gen_load_fpr64(ctx
, fp0
, fs
);
8216 gen_helper_float_rsqrt1_d(fp0
, cpu_env
, fp0
);
8217 gen_store_fpr64(ctx
, fp0
, fd
);
8218 tcg_temp_free_i64(fp0
);
8223 check_cp1_64bitmode(ctx
);
8225 TCGv_i64 fp0
= tcg_temp_new_i64();
8226 TCGv_i64 fp1
= tcg_temp_new_i64();
8228 gen_load_fpr64(ctx
, fp0
, fs
);
8229 gen_load_fpr64(ctx
, fp1
, ft
);
8230 gen_helper_float_rsqrt2_d(fp0
, cpu_env
, fp0
, fp1
);
8231 tcg_temp_free_i64(fp1
);
8232 gen_store_fpr64(ctx
, fp0
, fd
);
8233 tcg_temp_free_i64(fp0
);
8246 case OPC_CMP_NGLE_D
:
8253 if (ctx
->opcode
& (1 << 6)) {
8254 gen_cmpabs_d(ctx
, func
-48, ft
, fs
, cc
);
8255 opn
= condnames_abs
[func
-48];
8257 gen_cmp_d(ctx
, func
-48, ft
, fs
, cc
);
8258 opn
= condnames
[func
-48];
8262 check_cp1_registers(ctx
, fs
);
8264 TCGv_i32 fp32
= tcg_temp_new_i32();
8265 TCGv_i64 fp64
= tcg_temp_new_i64();
8267 gen_load_fpr64(ctx
, fp64
, fs
);
8268 gen_helper_float_cvts_d(fp32
, cpu_env
, fp64
);
8269 tcg_temp_free_i64(fp64
);
8270 gen_store_fpr32(fp32
, fd
);
8271 tcg_temp_free_i32(fp32
);
8276 check_cp1_registers(ctx
, fs
);
8278 TCGv_i32 fp32
= tcg_temp_new_i32();
8279 TCGv_i64 fp64
= tcg_temp_new_i64();
8281 gen_load_fpr64(ctx
, fp64
, fs
);
8282 gen_helper_float_cvtw_d(fp32
, cpu_env
, fp64
);
8283 tcg_temp_free_i64(fp64
);
8284 gen_store_fpr32(fp32
, fd
);
8285 tcg_temp_free_i32(fp32
);
8290 check_cp1_64bitmode(ctx
);
8292 TCGv_i64 fp0
= tcg_temp_new_i64();
8294 gen_load_fpr64(ctx
, fp0
, fs
);
8295 gen_helper_float_cvtl_d(fp0
, cpu_env
, fp0
);
8296 gen_store_fpr64(ctx
, fp0
, fd
);
8297 tcg_temp_free_i64(fp0
);
8303 TCGv_i32 fp0
= tcg_temp_new_i32();
8305 gen_load_fpr32(fp0
, fs
);
8306 gen_helper_float_cvts_w(fp0
, cpu_env
, fp0
);
8307 gen_store_fpr32(fp0
, fd
);
8308 tcg_temp_free_i32(fp0
);
8313 check_cp1_registers(ctx
, fd
);
8315 TCGv_i32 fp32
= tcg_temp_new_i32();
8316 TCGv_i64 fp64
= tcg_temp_new_i64();
8318 gen_load_fpr32(fp32
, fs
);
8319 gen_helper_float_cvtd_w(fp64
, cpu_env
, fp32
);
8320 tcg_temp_free_i32(fp32
);
8321 gen_store_fpr64(ctx
, fp64
, fd
);
8322 tcg_temp_free_i64(fp64
);
8327 check_cp1_64bitmode(ctx
);
8329 TCGv_i32 fp32
= tcg_temp_new_i32();
8330 TCGv_i64 fp64
= tcg_temp_new_i64();
8332 gen_load_fpr64(ctx
, fp64
, fs
);
8333 gen_helper_float_cvts_l(fp32
, cpu_env
, fp64
);
8334 tcg_temp_free_i64(fp64
);
8335 gen_store_fpr32(fp32
, fd
);
8336 tcg_temp_free_i32(fp32
);
8341 check_cp1_64bitmode(ctx
);
8343 TCGv_i64 fp0
= tcg_temp_new_i64();
8345 gen_load_fpr64(ctx
, fp0
, fs
);
8346 gen_helper_float_cvtd_l(fp0
, cpu_env
, fp0
);
8347 gen_store_fpr64(ctx
, fp0
, fd
);
8348 tcg_temp_free_i64(fp0
);
8353 check_cp1_64bitmode(ctx
);
8355 TCGv_i64 fp0
= tcg_temp_new_i64();
8357 gen_load_fpr64(ctx
, fp0
, fs
);
8358 gen_helper_float_cvtps_pw(fp0
, cpu_env
, fp0
);
8359 gen_store_fpr64(ctx
, fp0
, fd
);
8360 tcg_temp_free_i64(fp0
);
8365 check_cp1_64bitmode(ctx
);
8367 TCGv_i64 fp0
= tcg_temp_new_i64();
8368 TCGv_i64 fp1
= tcg_temp_new_i64();
8370 gen_load_fpr64(ctx
, fp0
, fs
);
8371 gen_load_fpr64(ctx
, fp1
, ft
);
8372 gen_helper_float_add_ps(fp0
, cpu_env
, fp0
, fp1
);
8373 tcg_temp_free_i64(fp1
);
8374 gen_store_fpr64(ctx
, fp0
, fd
);
8375 tcg_temp_free_i64(fp0
);
8380 check_cp1_64bitmode(ctx
);
8382 TCGv_i64 fp0
= tcg_temp_new_i64();
8383 TCGv_i64 fp1
= tcg_temp_new_i64();
8385 gen_load_fpr64(ctx
, fp0
, fs
);
8386 gen_load_fpr64(ctx
, fp1
, ft
);
8387 gen_helper_float_sub_ps(fp0
, cpu_env
, fp0
, fp1
);
8388 tcg_temp_free_i64(fp1
);
8389 gen_store_fpr64(ctx
, fp0
, fd
);
8390 tcg_temp_free_i64(fp0
);
8395 check_cp1_64bitmode(ctx
);
8397 TCGv_i64 fp0
= tcg_temp_new_i64();
8398 TCGv_i64 fp1
= tcg_temp_new_i64();
8400 gen_load_fpr64(ctx
, fp0
, fs
);
8401 gen_load_fpr64(ctx
, fp1
, ft
);
8402 gen_helper_float_mul_ps(fp0
, cpu_env
, fp0
, fp1
);
8403 tcg_temp_free_i64(fp1
);
8404 gen_store_fpr64(ctx
, fp0
, fd
);
8405 tcg_temp_free_i64(fp0
);
8410 check_cp1_64bitmode(ctx
);
8412 TCGv_i64 fp0
= tcg_temp_new_i64();
8414 gen_load_fpr64(ctx
, fp0
, fs
);
8415 gen_helper_float_abs_ps(fp0
, fp0
);
8416 gen_store_fpr64(ctx
, fp0
, fd
);
8417 tcg_temp_free_i64(fp0
);
8422 check_cp1_64bitmode(ctx
);
8424 TCGv_i64 fp0
= tcg_temp_new_i64();
8426 gen_load_fpr64(ctx
, fp0
, fs
);
8427 gen_store_fpr64(ctx
, fp0
, fd
);
8428 tcg_temp_free_i64(fp0
);
8433 check_cp1_64bitmode(ctx
);
8435 TCGv_i64 fp0
= tcg_temp_new_i64();
8437 gen_load_fpr64(ctx
, fp0
, fs
);
8438 gen_helper_float_chs_ps(fp0
, fp0
);
8439 gen_store_fpr64(ctx
, fp0
, fd
);
8440 tcg_temp_free_i64(fp0
);
8445 check_cp1_64bitmode(ctx
);
8446 gen_movcf_ps(ctx
, fs
, fd
, (ft
>> 2) & 0x7, ft
& 0x1);
8450 check_cp1_64bitmode(ctx
);
8452 int l1
= gen_new_label();
8456 tcg_gen_brcondi_tl(TCG_COND_NE
, cpu_gpr
[ft
], 0, l1
);
8457 fp0
= tcg_temp_new_i64();
8458 gen_load_fpr64(ctx
, fp0
, fs
);
8459 gen_store_fpr64(ctx
, fp0
, fd
);
8460 tcg_temp_free_i64(fp0
);
8466 check_cp1_64bitmode(ctx
);
8468 int l1
= gen_new_label();
8472 tcg_gen_brcondi_tl(TCG_COND_EQ
, cpu_gpr
[ft
], 0, l1
);
8473 fp0
= tcg_temp_new_i64();
8474 gen_load_fpr64(ctx
, fp0
, fs
);
8475 gen_store_fpr64(ctx
, fp0
, fd
);
8476 tcg_temp_free_i64(fp0
);
8483 check_cp1_64bitmode(ctx
);
8485 TCGv_i64 fp0
= tcg_temp_new_i64();
8486 TCGv_i64 fp1
= tcg_temp_new_i64();
8488 gen_load_fpr64(ctx
, fp0
, ft
);
8489 gen_load_fpr64(ctx
, fp1
, fs
);
8490 gen_helper_float_addr_ps(fp0
, cpu_env
, fp0
, fp1
);
8491 tcg_temp_free_i64(fp1
);
8492 gen_store_fpr64(ctx
, fp0
, fd
);
8493 tcg_temp_free_i64(fp0
);
8498 check_cp1_64bitmode(ctx
);
8500 TCGv_i64 fp0
= tcg_temp_new_i64();
8501 TCGv_i64 fp1
= tcg_temp_new_i64();
8503 gen_load_fpr64(ctx
, fp0
, ft
);
8504 gen_load_fpr64(ctx
, fp1
, fs
);
8505 gen_helper_float_mulr_ps(fp0
, cpu_env
, fp0
, fp1
);
8506 tcg_temp_free_i64(fp1
);
8507 gen_store_fpr64(ctx
, fp0
, fd
);
8508 tcg_temp_free_i64(fp0
);
8513 check_cp1_64bitmode(ctx
);
8515 TCGv_i64 fp0
= tcg_temp_new_i64();
8516 TCGv_i64 fp1
= tcg_temp_new_i64();
8518 gen_load_fpr64(ctx
, fp0
, fs
);
8519 gen_load_fpr64(ctx
, fp1
, ft
);
8520 gen_helper_float_recip2_ps(fp0
, cpu_env
, fp0
, fp1
);
8521 tcg_temp_free_i64(fp1
);
8522 gen_store_fpr64(ctx
, fp0
, fd
);
8523 tcg_temp_free_i64(fp0
);
8528 check_cp1_64bitmode(ctx
);
8530 TCGv_i64 fp0
= tcg_temp_new_i64();
8532 gen_load_fpr64(ctx
, fp0
, fs
);
8533 gen_helper_float_recip1_ps(fp0
, cpu_env
, fp0
);
8534 gen_store_fpr64(ctx
, fp0
, fd
);
8535 tcg_temp_free_i64(fp0
);
8540 check_cp1_64bitmode(ctx
);
8542 TCGv_i64 fp0
= tcg_temp_new_i64();
8544 gen_load_fpr64(ctx
, fp0
, fs
);
8545 gen_helper_float_rsqrt1_ps(fp0
, cpu_env
, fp0
);
8546 gen_store_fpr64(ctx
, fp0
, fd
);
8547 tcg_temp_free_i64(fp0
);
8552 check_cp1_64bitmode(ctx
);
8554 TCGv_i64 fp0
= tcg_temp_new_i64();
8555 TCGv_i64 fp1
= tcg_temp_new_i64();
8557 gen_load_fpr64(ctx
, fp0
, fs
);
8558 gen_load_fpr64(ctx
, fp1
, ft
);
8559 gen_helper_float_rsqrt2_ps(fp0
, cpu_env
, fp0
, fp1
);
8560 tcg_temp_free_i64(fp1
);
8561 gen_store_fpr64(ctx
, fp0
, fd
);
8562 tcg_temp_free_i64(fp0
);
8567 check_cp1_64bitmode(ctx
);
8569 TCGv_i32 fp0
= tcg_temp_new_i32();
8571 gen_load_fpr32h(ctx
, fp0
, fs
);
8572 gen_helper_float_cvts_pu(fp0
, cpu_env
, fp0
);
8573 gen_store_fpr32(fp0
, fd
);
8574 tcg_temp_free_i32(fp0
);
8579 check_cp1_64bitmode(ctx
);
8581 TCGv_i64 fp0
= tcg_temp_new_i64();
8583 gen_load_fpr64(ctx
, fp0
, fs
);
8584 gen_helper_float_cvtpw_ps(fp0
, cpu_env
, fp0
);
8585 gen_store_fpr64(ctx
, fp0
, fd
);
8586 tcg_temp_free_i64(fp0
);
8591 check_cp1_64bitmode(ctx
);
8593 TCGv_i32 fp0
= tcg_temp_new_i32();
8595 gen_load_fpr32(fp0
, fs
);
8596 gen_helper_float_cvts_pl(fp0
, cpu_env
, fp0
);
8597 gen_store_fpr32(fp0
, fd
);
8598 tcg_temp_free_i32(fp0
);
8603 check_cp1_64bitmode(ctx
);
8605 TCGv_i32 fp0
= tcg_temp_new_i32();
8606 TCGv_i32 fp1
= tcg_temp_new_i32();
8608 gen_load_fpr32(fp0
, fs
);
8609 gen_load_fpr32(fp1
, ft
);
8610 gen_store_fpr32h(ctx
, fp0
, fd
);
8611 gen_store_fpr32(fp1
, fd
);
8612 tcg_temp_free_i32(fp0
);
8613 tcg_temp_free_i32(fp1
);
8618 check_cp1_64bitmode(ctx
);
8620 TCGv_i32 fp0
= tcg_temp_new_i32();
8621 TCGv_i32 fp1
= tcg_temp_new_i32();
8623 gen_load_fpr32(fp0
, fs
);
8624 gen_load_fpr32h(ctx
, fp1
, ft
);
8625 gen_store_fpr32(fp1
, fd
);
8626 gen_store_fpr32h(ctx
, fp0
, fd
);
8627 tcg_temp_free_i32(fp0
);
8628 tcg_temp_free_i32(fp1
);
8633 check_cp1_64bitmode(ctx
);
8635 TCGv_i32 fp0
= tcg_temp_new_i32();
8636 TCGv_i32 fp1
= tcg_temp_new_i32();
8638 gen_load_fpr32h(ctx
, fp0
, fs
);
8639 gen_load_fpr32(fp1
, ft
);
8640 gen_store_fpr32(fp1
, fd
);
8641 gen_store_fpr32h(ctx
, fp0
, fd
);
8642 tcg_temp_free_i32(fp0
);
8643 tcg_temp_free_i32(fp1
);
8648 check_cp1_64bitmode(ctx
);
8650 TCGv_i32 fp0
= tcg_temp_new_i32();
8651 TCGv_i32 fp1
= tcg_temp_new_i32();
8653 gen_load_fpr32h(ctx
, fp0
, fs
);
8654 gen_load_fpr32h(ctx
, fp1
, ft
);
8655 gen_store_fpr32(fp1
, fd
);
8656 gen_store_fpr32h(ctx
, fp0
, fd
);
8657 tcg_temp_free_i32(fp0
);
8658 tcg_temp_free_i32(fp1
);
8665 case OPC_CMP_UEQ_PS
:
8666 case OPC_CMP_OLT_PS
:
8667 case OPC_CMP_ULT_PS
:
8668 case OPC_CMP_OLE_PS
:
8669 case OPC_CMP_ULE_PS
:
8671 case OPC_CMP_NGLE_PS
:
8672 case OPC_CMP_SEQ_PS
:
8673 case OPC_CMP_NGL_PS
:
8675 case OPC_CMP_NGE_PS
:
8677 case OPC_CMP_NGT_PS
:
8678 if (ctx
->opcode
& (1 << 6)) {
8679 gen_cmpabs_ps(ctx
, func
-48, ft
, fs
, cc
);
8680 opn
= condnames_abs
[func
-48];
8682 gen_cmp_ps(ctx
, func
-48, ft
, fs
, cc
);
8683 opn
= condnames
[func
-48];
8688 generate_exception (ctx
, EXCP_RI
);
8691 (void)opn
; /* avoid a compiler warning */
8694 MIPS_DEBUG("%s %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fs
], fregnames
[ft
]);
8697 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fs
], fregnames
[ft
]);
8700 MIPS_DEBUG("%s %s,%s", opn
, fregnames
[fd
], fregnames
[fs
]);
8705 /* Coprocessor 3 (FPU) */
8706 static void gen_flt3_ldst (DisasContext
*ctx
, uint32_t opc
,
8707 int fd
, int fs
, int base
, int index
)
8709 const char *opn
= "extended float load/store";
8711 TCGv t0
= tcg_temp_new();
8714 gen_load_gpr(t0
, index
);
8715 } else if (index
== 0) {
8716 gen_load_gpr(t0
, base
);
8718 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[index
]);
8720 /* Don't do NOP if destination is zero: we must perform the actual
8726 TCGv_i32 fp0
= tcg_temp_new_i32();
8728 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
8729 tcg_gen_trunc_tl_i32(fp0
, t0
);
8730 gen_store_fpr32(fp0
, fd
);
8731 tcg_temp_free_i32(fp0
);
8737 check_cp1_registers(ctx
, fd
);
8739 TCGv_i64 fp0
= tcg_temp_new_i64();
8740 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8741 gen_store_fpr64(ctx
, fp0
, fd
);
8742 tcg_temp_free_i64(fp0
);
8747 check_cp1_64bitmode(ctx
);
8748 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8750 TCGv_i64 fp0
= tcg_temp_new_i64();
8752 tcg_gen_qemu_ld_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8753 gen_store_fpr64(ctx
, fp0
, fd
);
8754 tcg_temp_free_i64(fp0
);
8761 TCGv_i32 fp0
= tcg_temp_new_i32();
8762 gen_load_fpr32(fp0
, fs
);
8763 tcg_gen_qemu_st_i32(fp0
, t0
, ctx
->mem_idx
, MO_TEUL
);
8764 tcg_temp_free_i32(fp0
);
8771 check_cp1_registers(ctx
, fs
);
8773 TCGv_i64 fp0
= tcg_temp_new_i64();
8774 gen_load_fpr64(ctx
, fp0
, fs
);
8775 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8776 tcg_temp_free_i64(fp0
);
8782 check_cp1_64bitmode(ctx
);
8783 tcg_gen_andi_tl(t0
, t0
, ~0x7);
8785 TCGv_i64 fp0
= tcg_temp_new_i64();
8786 gen_load_fpr64(ctx
, fp0
, fs
);
8787 tcg_gen_qemu_st_i64(fp0
, t0
, ctx
->mem_idx
, MO_TEQ
);
8788 tcg_temp_free_i64(fp0
);
8795 (void)opn
; (void)store
; /* avoid compiler warnings */
8796 MIPS_DEBUG("%s %s, %s(%s)", opn
, fregnames
[store
? fs
: fd
],
8797 regnames
[index
], regnames
[base
]);
8800 static void gen_flt3_arith (DisasContext
*ctx
, uint32_t opc
,
8801 int fd
, int fr
, int fs
, int ft
)
8803 const char *opn
= "flt3_arith";
8807 check_cp1_64bitmode(ctx
);
8809 TCGv t0
= tcg_temp_local_new();
8810 TCGv_i32 fp
= tcg_temp_new_i32();
8811 TCGv_i32 fph
= tcg_temp_new_i32();
8812 int l1
= gen_new_label();
8813 int l2
= gen_new_label();
8815 gen_load_gpr(t0
, fr
);
8816 tcg_gen_andi_tl(t0
, t0
, 0x7);
8818 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 0, l1
);
8819 gen_load_fpr32(fp
, fs
);
8820 gen_load_fpr32h(ctx
, fph
, fs
);
8821 gen_store_fpr32(fp
, fd
);
8822 gen_store_fpr32h(ctx
, fph
, fd
);
8825 tcg_gen_brcondi_tl(TCG_COND_NE
, t0
, 4, l2
);
8827 #ifdef TARGET_WORDS_BIGENDIAN
8828 gen_load_fpr32(fp
, fs
);
8829 gen_load_fpr32h(ctx
, fph
, ft
);
8830 gen_store_fpr32h(ctx
, fp
, fd
);
8831 gen_store_fpr32(fph
, fd
);
8833 gen_load_fpr32h(ctx
, fph
, fs
);
8834 gen_load_fpr32(fp
, ft
);
8835 gen_store_fpr32(fph
, fd
);
8836 gen_store_fpr32h(ctx
, fp
, fd
);
8839 tcg_temp_free_i32(fp
);
8840 tcg_temp_free_i32(fph
);
8847 TCGv_i32 fp0
= tcg_temp_new_i32();
8848 TCGv_i32 fp1
= tcg_temp_new_i32();
8849 TCGv_i32 fp2
= tcg_temp_new_i32();
8851 gen_load_fpr32(fp0
, fs
);
8852 gen_load_fpr32(fp1
, ft
);
8853 gen_load_fpr32(fp2
, fr
);
8854 gen_helper_float_madd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8855 tcg_temp_free_i32(fp0
);
8856 tcg_temp_free_i32(fp1
);
8857 gen_store_fpr32(fp2
, fd
);
8858 tcg_temp_free_i32(fp2
);
8864 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8866 TCGv_i64 fp0
= tcg_temp_new_i64();
8867 TCGv_i64 fp1
= tcg_temp_new_i64();
8868 TCGv_i64 fp2
= tcg_temp_new_i64();
8870 gen_load_fpr64(ctx
, fp0
, fs
);
8871 gen_load_fpr64(ctx
, fp1
, ft
);
8872 gen_load_fpr64(ctx
, fp2
, fr
);
8873 gen_helper_float_madd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8874 tcg_temp_free_i64(fp0
);
8875 tcg_temp_free_i64(fp1
);
8876 gen_store_fpr64(ctx
, fp2
, fd
);
8877 tcg_temp_free_i64(fp2
);
8882 check_cp1_64bitmode(ctx
);
8884 TCGv_i64 fp0
= tcg_temp_new_i64();
8885 TCGv_i64 fp1
= tcg_temp_new_i64();
8886 TCGv_i64 fp2
= tcg_temp_new_i64();
8888 gen_load_fpr64(ctx
, fp0
, fs
);
8889 gen_load_fpr64(ctx
, fp1
, ft
);
8890 gen_load_fpr64(ctx
, fp2
, fr
);
8891 gen_helper_float_madd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8892 tcg_temp_free_i64(fp0
);
8893 tcg_temp_free_i64(fp1
);
8894 gen_store_fpr64(ctx
, fp2
, fd
);
8895 tcg_temp_free_i64(fp2
);
8902 TCGv_i32 fp0
= tcg_temp_new_i32();
8903 TCGv_i32 fp1
= tcg_temp_new_i32();
8904 TCGv_i32 fp2
= tcg_temp_new_i32();
8906 gen_load_fpr32(fp0
, fs
);
8907 gen_load_fpr32(fp1
, ft
);
8908 gen_load_fpr32(fp2
, fr
);
8909 gen_helper_float_msub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8910 tcg_temp_free_i32(fp0
);
8911 tcg_temp_free_i32(fp1
);
8912 gen_store_fpr32(fp2
, fd
);
8913 tcg_temp_free_i32(fp2
);
8919 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8921 TCGv_i64 fp0
= tcg_temp_new_i64();
8922 TCGv_i64 fp1
= tcg_temp_new_i64();
8923 TCGv_i64 fp2
= tcg_temp_new_i64();
8925 gen_load_fpr64(ctx
, fp0
, fs
);
8926 gen_load_fpr64(ctx
, fp1
, ft
);
8927 gen_load_fpr64(ctx
, fp2
, fr
);
8928 gen_helper_float_msub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8929 tcg_temp_free_i64(fp0
);
8930 tcg_temp_free_i64(fp1
);
8931 gen_store_fpr64(ctx
, fp2
, fd
);
8932 tcg_temp_free_i64(fp2
);
8937 check_cp1_64bitmode(ctx
);
8939 TCGv_i64 fp0
= tcg_temp_new_i64();
8940 TCGv_i64 fp1
= tcg_temp_new_i64();
8941 TCGv_i64 fp2
= tcg_temp_new_i64();
8943 gen_load_fpr64(ctx
, fp0
, fs
);
8944 gen_load_fpr64(ctx
, fp1
, ft
);
8945 gen_load_fpr64(ctx
, fp2
, fr
);
8946 gen_helper_float_msub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8947 tcg_temp_free_i64(fp0
);
8948 tcg_temp_free_i64(fp1
);
8949 gen_store_fpr64(ctx
, fp2
, fd
);
8950 tcg_temp_free_i64(fp2
);
8957 TCGv_i32 fp0
= tcg_temp_new_i32();
8958 TCGv_i32 fp1
= tcg_temp_new_i32();
8959 TCGv_i32 fp2
= tcg_temp_new_i32();
8961 gen_load_fpr32(fp0
, fs
);
8962 gen_load_fpr32(fp1
, ft
);
8963 gen_load_fpr32(fp2
, fr
);
8964 gen_helper_float_nmadd_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8965 tcg_temp_free_i32(fp0
);
8966 tcg_temp_free_i32(fp1
);
8967 gen_store_fpr32(fp2
, fd
);
8968 tcg_temp_free_i32(fp2
);
8974 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
8976 TCGv_i64 fp0
= tcg_temp_new_i64();
8977 TCGv_i64 fp1
= tcg_temp_new_i64();
8978 TCGv_i64 fp2
= tcg_temp_new_i64();
8980 gen_load_fpr64(ctx
, fp0
, fs
);
8981 gen_load_fpr64(ctx
, fp1
, ft
);
8982 gen_load_fpr64(ctx
, fp2
, fr
);
8983 gen_helper_float_nmadd_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
8984 tcg_temp_free_i64(fp0
);
8985 tcg_temp_free_i64(fp1
);
8986 gen_store_fpr64(ctx
, fp2
, fd
);
8987 tcg_temp_free_i64(fp2
);
8992 check_cp1_64bitmode(ctx
);
8994 TCGv_i64 fp0
= tcg_temp_new_i64();
8995 TCGv_i64 fp1
= tcg_temp_new_i64();
8996 TCGv_i64 fp2
= tcg_temp_new_i64();
8998 gen_load_fpr64(ctx
, fp0
, fs
);
8999 gen_load_fpr64(ctx
, fp1
, ft
);
9000 gen_load_fpr64(ctx
, fp2
, fr
);
9001 gen_helper_float_nmadd_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9002 tcg_temp_free_i64(fp0
);
9003 tcg_temp_free_i64(fp1
);
9004 gen_store_fpr64(ctx
, fp2
, fd
);
9005 tcg_temp_free_i64(fp2
);
9012 TCGv_i32 fp0
= tcg_temp_new_i32();
9013 TCGv_i32 fp1
= tcg_temp_new_i32();
9014 TCGv_i32 fp2
= tcg_temp_new_i32();
9016 gen_load_fpr32(fp0
, fs
);
9017 gen_load_fpr32(fp1
, ft
);
9018 gen_load_fpr32(fp2
, fr
);
9019 gen_helper_float_nmsub_s(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9020 tcg_temp_free_i32(fp0
);
9021 tcg_temp_free_i32(fp1
);
9022 gen_store_fpr32(fp2
, fd
);
9023 tcg_temp_free_i32(fp2
);
9029 check_cp1_registers(ctx
, fd
| fs
| ft
| fr
);
9031 TCGv_i64 fp0
= tcg_temp_new_i64();
9032 TCGv_i64 fp1
= tcg_temp_new_i64();
9033 TCGv_i64 fp2
= tcg_temp_new_i64();
9035 gen_load_fpr64(ctx
, fp0
, fs
);
9036 gen_load_fpr64(ctx
, fp1
, ft
);
9037 gen_load_fpr64(ctx
, fp2
, fr
);
9038 gen_helper_float_nmsub_d(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9039 tcg_temp_free_i64(fp0
);
9040 tcg_temp_free_i64(fp1
);
9041 gen_store_fpr64(ctx
, fp2
, fd
);
9042 tcg_temp_free_i64(fp2
);
9047 check_cp1_64bitmode(ctx
);
9049 TCGv_i64 fp0
= tcg_temp_new_i64();
9050 TCGv_i64 fp1
= tcg_temp_new_i64();
9051 TCGv_i64 fp2
= tcg_temp_new_i64();
9053 gen_load_fpr64(ctx
, fp0
, fs
);
9054 gen_load_fpr64(ctx
, fp1
, ft
);
9055 gen_load_fpr64(ctx
, fp2
, fr
);
9056 gen_helper_float_nmsub_ps(fp2
, cpu_env
, fp0
, fp1
, fp2
);
9057 tcg_temp_free_i64(fp0
);
9058 tcg_temp_free_i64(fp1
);
9059 gen_store_fpr64(ctx
, fp2
, fd
);
9060 tcg_temp_free_i64(fp2
);
9066 generate_exception (ctx
, EXCP_RI
);
9069 (void)opn
; /* avoid a compiler warning */
9070 MIPS_DEBUG("%s %s, %s, %s, %s", opn
, fregnames
[fd
], fregnames
[fr
],
9071 fregnames
[fs
], fregnames
[ft
]);
9074 static void gen_rdhwr(DisasContext
*ctx
, int rt
, int rd
)
9078 #if !defined(CONFIG_USER_ONLY)
9079 /* The Linux kernel will emulate rdhwr if it's not supported natively.
9080 Therefore only check the ISA in system mode. */
9081 check_insn(ctx
, ISA_MIPS32R2
);
9083 t0
= tcg_temp_new();
9087 save_cpu_state(ctx
, 1);
9088 gen_helper_rdhwr_cpunum(t0
, cpu_env
);
9089 gen_store_gpr(t0
, rt
);
9092 save_cpu_state(ctx
, 1);
9093 gen_helper_rdhwr_synci_step(t0
, cpu_env
);
9094 gen_store_gpr(t0
, rt
);
9097 save_cpu_state(ctx
, 1);
9098 gen_helper_rdhwr_cc(t0
, cpu_env
);
9099 gen_store_gpr(t0
, rt
);
9102 save_cpu_state(ctx
, 1);
9103 gen_helper_rdhwr_ccres(t0
, cpu_env
);
9104 gen_store_gpr(t0
, rt
);
9107 #if defined(CONFIG_USER_ONLY)
9108 tcg_gen_ld_tl(t0
, cpu_env
,
9109 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9110 gen_store_gpr(t0
, rt
);
9113 if ((ctx
->hflags
& MIPS_HFLAG_CP0
) ||
9114 (ctx
->hflags
& MIPS_HFLAG_HWRENA_ULR
)) {
9115 tcg_gen_ld_tl(t0
, cpu_env
,
9116 offsetof(CPUMIPSState
, active_tc
.CP0_UserLocal
));
9117 gen_store_gpr(t0
, rt
);
9119 generate_exception(ctx
, EXCP_RI
);
9123 default: /* Invalid */
9124 MIPS_INVAL("rdhwr");
9125 generate_exception(ctx
, EXCP_RI
);
9131 static void handle_delay_slot(DisasContext
*ctx
, int insn_bytes
)
9133 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
9134 int proc_hflags
= ctx
->hflags
& MIPS_HFLAG_BMASK
;
9135 /* Branches completion */
9136 ctx
->hflags
&= ~MIPS_HFLAG_BMASK
;
9137 ctx
->bstate
= BS_BRANCH
;
9138 save_cpu_state(ctx
, 0);
9139 /* FIXME: Need to clear can_do_io. */
9140 switch (proc_hflags
& MIPS_HFLAG_BMASK_BASE
) {
9142 /* unconditional branch */
9143 MIPS_DEBUG("unconditional branch");
9144 if (proc_hflags
& MIPS_HFLAG_BX
) {
9145 tcg_gen_xori_i32(hflags
, hflags
, MIPS_HFLAG_M16
);
9147 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9150 /* blikely taken case */
9151 MIPS_DEBUG("blikely branch taken");
9152 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9155 /* Conditional branch */
9156 MIPS_DEBUG("conditional branch");
9158 int l1
= gen_new_label();
9160 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
9161 gen_goto_tb(ctx
, 1, ctx
->pc
+ insn_bytes
);
9163 gen_goto_tb(ctx
, 0, ctx
->btarget
);
9167 /* unconditional branch to register */
9168 MIPS_DEBUG("branch to register");
9169 if (ctx
->insn_flags
& (ASE_MIPS16
| ASE_MICROMIPS
)) {
9170 TCGv t0
= tcg_temp_new();
9171 TCGv_i32 t1
= tcg_temp_new_i32();
9173 tcg_gen_andi_tl(t0
, btarget
, 0x1);
9174 tcg_gen_trunc_tl_i32(t1
, t0
);
9176 tcg_gen_andi_i32(hflags
, hflags
, ~(uint32_t)MIPS_HFLAG_M16
);
9177 tcg_gen_shli_i32(t1
, t1
, MIPS_HFLAG_M16_SHIFT
);
9178 tcg_gen_or_i32(hflags
, hflags
, t1
);
9179 tcg_temp_free_i32(t1
);
9181 tcg_gen_andi_tl(cpu_PC
, btarget
, ~(target_ulong
)0x1);
9183 tcg_gen_mov_tl(cpu_PC
, btarget
);
9185 if (ctx
->singlestep_enabled
) {
9186 save_cpu_state(ctx
, 0);
9187 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
9192 MIPS_DEBUG("unknown branch");
9198 /* ISA extensions (ASEs) */
9199 /* MIPS16 extension to MIPS32 */
9201 /* MIPS16 major opcodes */
9203 M16_OPC_ADDIUSP
= 0x00,
9204 M16_OPC_ADDIUPC
= 0x01,
9207 M16_OPC_BEQZ
= 0x04,
9208 M16_OPC_BNEQZ
= 0x05,
9209 M16_OPC_SHIFT
= 0x06,
9211 M16_OPC_RRIA
= 0x08,
9212 M16_OPC_ADDIU8
= 0x09,
9213 M16_OPC_SLTI
= 0x0a,
9214 M16_OPC_SLTIU
= 0x0b,
9217 M16_OPC_CMPI
= 0x0e,
9221 M16_OPC_LWSP
= 0x12,
9225 M16_OPC_LWPC
= 0x16,
9229 M16_OPC_SWSP
= 0x1a,
9233 M16_OPC_EXTEND
= 0x1e,
9237 /* I8 funct field */
9256 /* RR funct field */
9290 /* I64 funct field */
9302 /* RR ry field for CNVT */
9304 RR_RY_CNVT_ZEB
= 0x0,
9305 RR_RY_CNVT_ZEH
= 0x1,
9306 RR_RY_CNVT_ZEW
= 0x2,
9307 RR_RY_CNVT_SEB
= 0x4,
9308 RR_RY_CNVT_SEH
= 0x5,
9309 RR_RY_CNVT_SEW
= 0x6,
9312 static int xlat (int r
)
9314 static int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9319 static void gen_mips16_save (DisasContext
*ctx
,
9320 int xsregs
, int aregs
,
9321 int do_ra
, int do_s0
, int do_s1
,
9324 TCGv t0
= tcg_temp_new();
9325 TCGv t1
= tcg_temp_new();
9355 generate_exception(ctx
, EXCP_RI
);
9361 gen_base_offset_addr(ctx
, t0
, 29, 12);
9362 gen_load_gpr(t1
, 7);
9363 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9366 gen_base_offset_addr(ctx
, t0
, 29, 8);
9367 gen_load_gpr(t1
, 6);
9368 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9371 gen_base_offset_addr(ctx
, t0
, 29, 4);
9372 gen_load_gpr(t1
, 5);
9373 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9376 gen_base_offset_addr(ctx
, t0
, 29, 0);
9377 gen_load_gpr(t1
, 4);
9378 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
9381 gen_load_gpr(t0
, 29);
9383 #define DECR_AND_STORE(reg) do { \
9384 tcg_gen_subi_tl(t0, t0, 4); \
9385 gen_load_gpr(t1, reg); \
9386 tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
9450 generate_exception(ctx
, EXCP_RI
);
9466 #undef DECR_AND_STORE
9468 tcg_gen_subi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9473 static void gen_mips16_restore (DisasContext
*ctx
,
9474 int xsregs
, int aregs
,
9475 int do_ra
, int do_s0
, int do_s1
,
9479 TCGv t0
= tcg_temp_new();
9480 TCGv t1
= tcg_temp_new();
9482 tcg_gen_addi_tl(t0
, cpu_gpr
[29], framesize
);
9484 #define DECR_AND_LOAD(reg) do { \
9485 tcg_gen_subi_tl(t0, t0, 4); \
9486 tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
9487 gen_store_gpr(t1, reg); \
9551 generate_exception(ctx
, EXCP_RI
);
9567 #undef DECR_AND_LOAD
9569 tcg_gen_addi_tl(cpu_gpr
[29], cpu_gpr
[29], framesize
);
9574 static void gen_addiupc (DisasContext
*ctx
, int rx
, int imm
,
9575 int is_64_bit
, int extended
)
9579 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9580 generate_exception(ctx
, EXCP_RI
);
9584 t0
= tcg_temp_new();
9586 tcg_gen_movi_tl(t0
, pc_relative_pc(ctx
));
9587 tcg_gen_addi_tl(cpu_gpr
[rx
], t0
, imm
);
9589 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
9595 #if defined(TARGET_MIPS64)
9596 static void decode_i64_mips16 (DisasContext
*ctx
,
9597 int ry
, int funct
, int16_t offset
,
9603 offset
= extended
? offset
: offset
<< 3;
9604 gen_ld(ctx
, OPC_LD
, ry
, 29, offset
);
9608 offset
= extended
? offset
: offset
<< 3;
9609 gen_st(ctx
, OPC_SD
, ry
, 29, offset
);
9613 offset
= extended
? offset
: (ctx
->opcode
& 0xff) << 3;
9614 gen_st(ctx
, OPC_SD
, 31, 29, offset
);
9618 offset
= extended
? offset
: ((int8_t)ctx
->opcode
) << 3;
9619 gen_arith_imm(ctx
, OPC_DADDIU
, 29, 29, offset
);
9622 if (extended
&& (ctx
->hflags
& MIPS_HFLAG_BMASK
)) {
9623 generate_exception(ctx
, EXCP_RI
);
9625 offset
= extended
? offset
: offset
<< 3;
9626 gen_ld(ctx
, OPC_LDPC
, ry
, 0, offset
);
9631 offset
= extended
? offset
: ((int8_t)(offset
<< 3)) >> 3;
9632 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, ry
, offset
);
9636 offset
= extended
? offset
: offset
<< 2;
9637 gen_addiupc(ctx
, ry
, offset
, 1, extended
);
9641 offset
= extended
? offset
: offset
<< 2;
9642 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, 29, offset
);
9648 static int decode_extended_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9650 int extend
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9651 int op
, rx
, ry
, funct
, sa
;
9652 int16_t imm
, offset
;
9654 ctx
->opcode
= (ctx
->opcode
<< 16) | extend
;
9655 op
= (ctx
->opcode
>> 11) & 0x1f;
9656 sa
= (ctx
->opcode
>> 22) & 0x1f;
9657 funct
= (ctx
->opcode
>> 8) & 0x7;
9658 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9659 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9660 offset
= imm
= (int16_t) (((ctx
->opcode
>> 16) & 0x1f) << 11
9661 | ((ctx
->opcode
>> 21) & 0x3f) << 5
9662 | (ctx
->opcode
& 0x1f));
9664 /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9667 case M16_OPC_ADDIUSP
:
9668 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9670 case M16_OPC_ADDIUPC
:
9671 gen_addiupc(ctx
, rx
, imm
, 0, 1);
9674 gen_compute_branch(ctx
, OPC_BEQ
, 4, 0, 0, offset
<< 1);
9675 /* No delay slot, so just process as a normal instruction */
9678 gen_compute_branch(ctx
, OPC_BEQ
, 4, rx
, 0, offset
<< 1);
9679 /* No delay slot, so just process as a normal instruction */
9682 gen_compute_branch(ctx
, OPC_BNE
, 4, rx
, 0, offset
<< 1);
9683 /* No delay slot, so just process as a normal instruction */
9686 switch (ctx
->opcode
& 0x3) {
9688 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9691 #if defined(TARGET_MIPS64)
9693 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9695 generate_exception(ctx
, EXCP_RI
);
9699 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9702 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9706 #if defined(TARGET_MIPS64)
9709 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
);
9713 imm
= ctx
->opcode
& 0xf;
9714 imm
= imm
| ((ctx
->opcode
>> 20) & 0x7f) << 4;
9715 imm
= imm
| ((ctx
->opcode
>> 16) & 0xf) << 11;
9716 imm
= (int16_t) (imm
<< 1) >> 1;
9717 if ((ctx
->opcode
>> 4) & 0x1) {
9718 #if defined(TARGET_MIPS64)
9720 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9722 generate_exception(ctx
, EXCP_RI
);
9725 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9728 case M16_OPC_ADDIU8
:
9729 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9732 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9735 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9740 gen_compute_branch(ctx
, OPC_BEQ
, 4, 24, 0, offset
<< 1);
9743 gen_compute_branch(ctx
, OPC_BNE
, 4, 24, 0, offset
<< 1);
9746 gen_st(ctx
, OPC_SW
, 31, 29, imm
);
9749 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
);
9753 int xsregs
= (ctx
->opcode
>> 24) & 0x7;
9754 int aregs
= (ctx
->opcode
>> 16) & 0xf;
9755 int do_ra
= (ctx
->opcode
>> 6) & 0x1;
9756 int do_s0
= (ctx
->opcode
>> 5) & 0x1;
9757 int do_s1
= (ctx
->opcode
>> 4) & 0x1;
9758 int framesize
= (((ctx
->opcode
>> 20) & 0xf) << 4
9759 | (ctx
->opcode
& 0xf)) << 3;
9761 if (ctx
->opcode
& (1 << 7)) {
9762 gen_mips16_save(ctx
, xsregs
, aregs
,
9763 do_ra
, do_s0
, do_s1
,
9766 gen_mips16_restore(ctx
, xsregs
, aregs
,
9767 do_ra
, do_s0
, do_s1
,
9773 generate_exception(ctx
, EXCP_RI
);
9778 tcg_gen_movi_tl(cpu_gpr
[rx
], (uint16_t) imm
);
9781 tcg_gen_xori_tl(cpu_gpr
[24], cpu_gpr
[rx
], (uint16_t) imm
);
9783 #if defined(TARGET_MIPS64)
9785 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
);
9789 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
9792 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
);
9795 gen_ld(ctx
, OPC_LW
, rx
, 29, offset
);
9798 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
);
9801 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
9804 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
);
9807 gen_ld(ctx
, OPC_LWPC
, rx
, 0, offset
);
9809 #if defined(TARGET_MIPS64)
9811 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
);
9815 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
9818 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
);
9821 gen_st(ctx
, OPC_SW
, rx
, 29, offset
);
9824 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
);
9826 #if defined(TARGET_MIPS64)
9828 decode_i64_mips16(ctx
, ry
, funct
, offset
, 1);
9832 generate_exception(ctx
, EXCP_RI
);
9839 static int decode_mips16_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
9843 int op
, cnvt_op
, op1
, offset
;
9847 op
= (ctx
->opcode
>> 11) & 0x1f;
9848 sa
= (ctx
->opcode
>> 2) & 0x7;
9849 sa
= sa
== 0 ? 8 : sa
;
9850 rx
= xlat((ctx
->opcode
>> 8) & 0x7);
9851 cnvt_op
= (ctx
->opcode
>> 5) & 0x7;
9852 ry
= xlat((ctx
->opcode
>> 5) & 0x7);
9853 op1
= offset
= ctx
->opcode
& 0x1f;
9858 case M16_OPC_ADDIUSP
:
9860 int16_t imm
= ((uint8_t) ctx
->opcode
) << 2;
9862 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 29, imm
);
9865 case M16_OPC_ADDIUPC
:
9866 gen_addiupc(ctx
, rx
, ((uint8_t) ctx
->opcode
) << 2, 0, 0);
9869 offset
= (ctx
->opcode
& 0x7ff) << 1;
9870 offset
= (int16_t)(offset
<< 4) >> 4;
9871 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0, offset
);
9872 /* No delay slot, so just process as a normal instruction */
9875 offset
= cpu_lduw_code(env
, ctx
->pc
+ 2);
9876 offset
= (((ctx
->opcode
& 0x1f) << 21)
9877 | ((ctx
->opcode
>> 5) & 0x1f) << 16
9879 op
= ((ctx
->opcode
>> 10) & 0x1) ? OPC_JALXS
: OPC_JALS
;
9880 gen_compute_branch(ctx
, op
, 4, rx
, ry
, offset
);
9884 gen_compute_branch(ctx
, OPC_BEQ
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9885 /* No delay slot, so just process as a normal instruction */
9888 gen_compute_branch(ctx
, OPC_BNE
, 2, rx
, 0, ((int8_t)ctx
->opcode
) << 1);
9889 /* No delay slot, so just process as a normal instruction */
9892 switch (ctx
->opcode
& 0x3) {
9894 gen_shift_imm(ctx
, OPC_SLL
, rx
, ry
, sa
);
9897 #if defined(TARGET_MIPS64)
9899 gen_shift_imm(ctx
, OPC_DSLL
, rx
, ry
, sa
);
9901 generate_exception(ctx
, EXCP_RI
);
9905 gen_shift_imm(ctx
, OPC_SRL
, rx
, ry
, sa
);
9908 gen_shift_imm(ctx
, OPC_SRA
, rx
, ry
, sa
);
9912 #if defined(TARGET_MIPS64)
9915 gen_ld(ctx
, OPC_LD
, ry
, rx
, offset
<< 3);
9920 int16_t imm
= (int8_t)((ctx
->opcode
& 0xf) << 4) >> 4;
9922 if ((ctx
->opcode
>> 4) & 1) {
9923 #if defined(TARGET_MIPS64)
9925 gen_arith_imm(ctx
, OPC_DADDIU
, ry
, rx
, imm
);
9927 generate_exception(ctx
, EXCP_RI
);
9930 gen_arith_imm(ctx
, OPC_ADDIU
, ry
, rx
, imm
);
9934 case M16_OPC_ADDIU8
:
9936 int16_t imm
= (int8_t) ctx
->opcode
;
9938 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, rx
, imm
);
9943 int16_t imm
= (uint8_t) ctx
->opcode
;
9944 gen_slt_imm(ctx
, OPC_SLTI
, 24, rx
, imm
);
9949 int16_t imm
= (uint8_t) ctx
->opcode
;
9950 gen_slt_imm(ctx
, OPC_SLTIU
, 24, rx
, imm
);
9957 funct
= (ctx
->opcode
>> 8) & 0x7;
9960 gen_compute_branch(ctx
, OPC_BEQ
, 2, 24, 0,
9961 ((int8_t)ctx
->opcode
) << 1);
9964 gen_compute_branch(ctx
, OPC_BNE
, 2, 24, 0,
9965 ((int8_t)ctx
->opcode
) << 1);
9968 gen_st(ctx
, OPC_SW
, 31, 29, (ctx
->opcode
& 0xff) << 2);
9971 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29,
9972 ((int8_t)ctx
->opcode
) << 3);
9976 int do_ra
= ctx
->opcode
& (1 << 6);
9977 int do_s0
= ctx
->opcode
& (1 << 5);
9978 int do_s1
= ctx
->opcode
& (1 << 4);
9979 int framesize
= ctx
->opcode
& 0xf;
9981 if (framesize
== 0) {
9984 framesize
= framesize
<< 3;
9987 if (ctx
->opcode
& (1 << 7)) {
9988 gen_mips16_save(ctx
, 0, 0,
9989 do_ra
, do_s0
, do_s1
, framesize
);
9991 gen_mips16_restore(ctx
, 0, 0,
9992 do_ra
, do_s0
, do_s1
, framesize
);
9998 int rz
= xlat(ctx
->opcode
& 0x7);
10000 reg32
= (((ctx
->opcode
>> 3) & 0x3) << 3) |
10001 ((ctx
->opcode
>> 5) & 0x7);
10002 gen_arith(ctx
, OPC_ADDU
, reg32
, rz
, 0);
10006 reg32
= ctx
->opcode
& 0x1f;
10007 gen_arith(ctx
, OPC_ADDU
, ry
, reg32
, 0);
10010 generate_exception(ctx
, EXCP_RI
);
10017 int16_t imm
= (uint8_t) ctx
->opcode
;
10019 gen_arith_imm(ctx
, OPC_ADDIU
, rx
, 0, imm
);
10024 int16_t imm
= (uint8_t) ctx
->opcode
;
10025 gen_logic_imm(ctx
, OPC_XORI
, 24, rx
, imm
);
10028 #if defined(TARGET_MIPS64)
10030 check_mips_64(ctx
);
10031 gen_st(ctx
, OPC_SD
, ry
, rx
, offset
<< 3);
10035 gen_ld(ctx
, OPC_LB
, ry
, rx
, offset
);
10038 gen_ld(ctx
, OPC_LH
, ry
, rx
, offset
<< 1);
10041 gen_ld(ctx
, OPC_LW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10044 gen_ld(ctx
, OPC_LW
, ry
, rx
, offset
<< 2);
10047 gen_ld(ctx
, OPC_LBU
, ry
, rx
, offset
);
10050 gen_ld(ctx
, OPC_LHU
, ry
, rx
, offset
<< 1);
10053 gen_ld(ctx
, OPC_LWPC
, rx
, 0, ((uint8_t)ctx
->opcode
) << 2);
10055 #if defined (TARGET_MIPS64)
10057 check_mips_64(ctx
);
10058 gen_ld(ctx
, OPC_LWU
, ry
, rx
, offset
<< 2);
10062 gen_st(ctx
, OPC_SB
, ry
, rx
, offset
);
10065 gen_st(ctx
, OPC_SH
, ry
, rx
, offset
<< 1);
10068 gen_st(ctx
, OPC_SW
, rx
, 29, ((uint8_t)ctx
->opcode
) << 2);
10071 gen_st(ctx
, OPC_SW
, ry
, rx
, offset
<< 2);
10075 int rz
= xlat((ctx
->opcode
>> 2) & 0x7);
10078 switch (ctx
->opcode
& 0x3) {
10080 mips32_op
= OPC_ADDU
;
10083 mips32_op
= OPC_SUBU
;
10085 #if defined(TARGET_MIPS64)
10087 mips32_op
= OPC_DADDU
;
10088 check_mips_64(ctx
);
10091 mips32_op
= OPC_DSUBU
;
10092 check_mips_64(ctx
);
10096 generate_exception(ctx
, EXCP_RI
);
10100 gen_arith(ctx
, mips32_op
, rz
, rx
, ry
);
10109 int nd
= (ctx
->opcode
>> 7) & 0x1;
10110 int link
= (ctx
->opcode
>> 6) & 0x1;
10111 int ra
= (ctx
->opcode
>> 5) & 0x1;
10114 op
= nd
? OPC_JALRC
: OPC_JALRS
;
10119 gen_compute_branch(ctx
, op
, 2, ra
? 31 : rx
, 31, 0);
10123 /* XXX: not clear which exception should be raised
10124 * when in debug mode...
10126 check_insn(ctx
, ISA_MIPS32
);
10127 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10128 generate_exception(ctx
, EXCP_DBp
);
10130 generate_exception(ctx
, EXCP_DBp
);
10134 gen_slt(ctx
, OPC_SLT
, 24, rx
, ry
);
10137 gen_slt(ctx
, OPC_SLTU
, 24, rx
, ry
);
10140 generate_exception(ctx
, EXCP_BREAK
);
10143 gen_shift(ctx
, OPC_SLLV
, ry
, rx
, ry
);
10146 gen_shift(ctx
, OPC_SRLV
, ry
, rx
, ry
);
10149 gen_shift(ctx
, OPC_SRAV
, ry
, rx
, ry
);
10151 #if defined (TARGET_MIPS64)
10153 check_mips_64(ctx
);
10154 gen_shift_imm(ctx
, OPC_DSRL
, ry
, ry
, sa
);
10158 gen_logic(ctx
, OPC_XOR
, 24, rx
, ry
);
10161 gen_arith(ctx
, OPC_SUBU
, rx
, 0, ry
);
10164 gen_logic(ctx
, OPC_AND
, rx
, rx
, ry
);
10167 gen_logic(ctx
, OPC_OR
, rx
, rx
, ry
);
10170 gen_logic(ctx
, OPC_XOR
, rx
, rx
, ry
);
10173 gen_logic(ctx
, OPC_NOR
, rx
, ry
, 0);
10176 gen_HILO(ctx
, OPC_MFHI
, 0, rx
);
10180 case RR_RY_CNVT_ZEB
:
10181 tcg_gen_ext8u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10183 case RR_RY_CNVT_ZEH
:
10184 tcg_gen_ext16u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10186 case RR_RY_CNVT_SEB
:
10187 tcg_gen_ext8s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10189 case RR_RY_CNVT_SEH
:
10190 tcg_gen_ext16s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10192 #if defined (TARGET_MIPS64)
10193 case RR_RY_CNVT_ZEW
:
10194 check_mips_64(ctx
);
10195 tcg_gen_ext32u_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10197 case RR_RY_CNVT_SEW
:
10198 check_mips_64(ctx
);
10199 tcg_gen_ext32s_tl(cpu_gpr
[rx
], cpu_gpr
[rx
]);
10203 generate_exception(ctx
, EXCP_RI
);
10208 gen_HILO(ctx
, OPC_MFLO
, 0, rx
);
10210 #if defined (TARGET_MIPS64)
10212 check_mips_64(ctx
);
10213 gen_shift_imm(ctx
, OPC_DSRA
, ry
, ry
, sa
);
10216 check_mips_64(ctx
);
10217 gen_shift(ctx
, OPC_DSLLV
, ry
, rx
, ry
);
10220 check_mips_64(ctx
);
10221 gen_shift(ctx
, OPC_DSRLV
, ry
, rx
, ry
);
10224 check_mips_64(ctx
);
10225 gen_shift(ctx
, OPC_DSRAV
, ry
, rx
, ry
);
10229 gen_muldiv(ctx
, OPC_MULT
, 0, rx
, ry
);
10232 gen_muldiv(ctx
, OPC_MULTU
, 0, rx
, ry
);
10235 gen_muldiv(ctx
, OPC_DIV
, 0, rx
, ry
);
10238 gen_muldiv(ctx
, OPC_DIVU
, 0, rx
, ry
);
10240 #if defined (TARGET_MIPS64)
10242 check_mips_64(ctx
);
10243 gen_muldiv(ctx
, OPC_DMULT
, 0, rx
, ry
);
10246 check_mips_64(ctx
);
10247 gen_muldiv(ctx
, OPC_DMULTU
, 0, rx
, ry
);
10250 check_mips_64(ctx
);
10251 gen_muldiv(ctx
, OPC_DDIV
, 0, rx
, ry
);
10254 check_mips_64(ctx
);
10255 gen_muldiv(ctx
, OPC_DDIVU
, 0, rx
, ry
);
10259 generate_exception(ctx
, EXCP_RI
);
10263 case M16_OPC_EXTEND
:
10264 decode_extended_mips16_opc(env
, ctx
);
10267 #if defined(TARGET_MIPS64)
10269 funct
= (ctx
->opcode
>> 8) & 0x7;
10270 decode_i64_mips16(ctx
, ry
, funct
, offset
, 0);
10274 generate_exception(ctx
, EXCP_RI
);
10281 /* microMIPS extension to MIPS32/MIPS64 */
10284 * microMIPS32/microMIPS64 major opcodes
10286 * 1. MIPS Architecture for Programmers Volume II-B:
10287 * The microMIPS32 Instruction Set (Revision 3.05)
10289 * Table 6.2 microMIPS32 Encoding of Major Opcode Field
10291 * 2. MIPS Architecture For Programmers Volume II-A:
10292 * The MIPS64 Instruction Set (Revision 3.51)
10320 POOL32S
= 0x16, /* MIPS64 */
10321 DADDIU32
= 0x17, /* MIPS64 */
10323 /* 0x1f is reserved */
10332 /* 0x20 is reserved */
10342 /* 0x28 and 0x29 are reserved */
10352 /* 0x30 and 0x31 are reserved */
10359 SD32
= 0x36, /* MIPS64 */
10360 LD32
= 0x37, /* MIPS64 */
10362 /* 0x38 and 0x39 are reserved */
10373 /* POOL32A encoding of minor opcode field */
10376 /* These opcodes are distinguished only by bits 9..6; those bits are
10377 * what are recorded below. */
10403 /* The following can be distinguished by their lower 6 bits. */
10409 /* POOL32AXF encoding of minor opcode field extension */
10412 * 1. MIPS Architecture for Programmers Volume II-B:
10413 * The microMIPS32 Instruction Set (Revision 3.05)
10415 * Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10417 * 2. MIPS Architecture for Programmers VolumeIV-e:
10418 * The MIPS DSP Application-Specific Extension
10419 * to the microMIPS32 Architecture (Revision 2.34)
10421 * Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10436 /* begin of microMIPS32 DSP */
10438 /* bits 13..12 for 0x01 */
10444 /* bits 13..12 for 0x2a */
10450 /* bits 13..12 for 0x32 */
10454 /* end of microMIPS32 DSP */
10456 /* bits 15..12 for 0x2c */
10472 /* bits 15..12 for 0x34 */
10480 /* bits 15..12 for 0x3c */
10482 JR
= 0x0, /* alias */
10487 /* bits 15..12 for 0x05 */
10491 /* bits 15..12 for 0x0d */
10501 /* bits 15..12 for 0x15 */
10507 /* bits 15..12 for 0x1d */
10511 /* bits 15..12 for 0x2d */
10516 /* bits 15..12 for 0x35 */
10523 /* POOL32B encoding of minor opcode field (bits 15..12) */
10539 /* POOL32C encoding of minor opcode field (bits 15..12) */
10547 /* 0xa is reserved */
10554 /* 0x6 is reserved */
10560 /* POOL32F encoding of minor opcode field (bits 5..0) */
10563 /* These are the bit 7..6 values */
10574 /* These are the bit 8..6 values */
10618 CABS_COND_FMT
= 0x1c, /* MIPS3D */
10622 /* POOL32Fxf encoding of minor opcode extension field */
10660 /* POOL32I encoding of minor opcode field (bits 25..21) */
10685 /* These overlap and are distinguished by bit16 of the instruction */
10694 /* POOL16A encoding of minor opcode field */
10701 /* POOL16B encoding of minor opcode field */
10708 /* POOL16C encoding of minor opcode field */
10728 /* POOL16D encoding of minor opcode field */
10735 /* POOL16E encoding of minor opcode field */
10742 static int mmreg (int r
)
10744 static const int map
[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10749 /* Used for 16-bit store instructions. */
10750 static int mmreg2 (int r
)
10752 static const int map
[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10757 #define uMIPS_RD(op) ((op >> 7) & 0x7)
10758 #define uMIPS_RS(op) ((op >> 4) & 0x7)
10759 #define uMIPS_RS2(op) uMIPS_RS(op)
10760 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
10761 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10762 #define uMIPS_RS5(op) (op & 0x1f)
10764 /* Signed immediate */
10765 #define SIMM(op, start, width) \
10766 ((int32_t)(((op >> start) & ((~0U) >> (32-width))) \
10769 /* Zero-extended immediate */
10770 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10772 static void gen_addiur1sp(DisasContext
*ctx
)
10774 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10776 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, 29, ((ctx
->opcode
>> 1) & 0x3f) << 2);
10779 static void gen_addiur2(DisasContext
*ctx
)
10781 static const int decoded_imm
[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10782 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10783 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10785 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, decoded_imm
[ZIMM(ctx
->opcode
, 1, 3)]);
10788 static void gen_addiusp(DisasContext
*ctx
)
10790 int encoded
= ZIMM(ctx
->opcode
, 1, 9);
10793 if (encoded
<= 1) {
10794 decoded
= 256 + encoded
;
10795 } else if (encoded
<= 255) {
10797 } else if (encoded
<= 509) {
10798 decoded
= encoded
- 512;
10800 decoded
= encoded
- 768;
10803 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, decoded
<< 2);
10806 static void gen_addius5(DisasContext
*ctx
)
10808 int imm
= SIMM(ctx
->opcode
, 1, 4);
10809 int rd
= (ctx
->opcode
>> 5) & 0x1f;
10811 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rd
, imm
);
10814 static void gen_andi16(DisasContext
*ctx
)
10816 static const int decoded_imm
[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10817 31, 32, 63, 64, 255, 32768, 65535 };
10818 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
10819 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
10820 int encoded
= ZIMM(ctx
->opcode
, 0, 4);
10822 gen_logic_imm(ctx
, OPC_ANDI
, rd
, rs
, decoded_imm
[encoded
]);
10825 static void gen_ldst_multiple (DisasContext
*ctx
, uint32_t opc
, int reglist
,
10826 int base
, int16_t offset
)
10828 const char *opn
= "ldst_multiple";
10832 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
10833 generate_exception(ctx
, EXCP_RI
);
10837 t0
= tcg_temp_new();
10839 gen_base_offset_addr(ctx
, t0
, base
, offset
);
10841 t1
= tcg_const_tl(reglist
);
10842 t2
= tcg_const_i32(ctx
->mem_idx
);
10844 save_cpu_state(ctx
, 1);
10847 gen_helper_lwm(cpu_env
, t0
, t1
, t2
);
10851 gen_helper_swm(cpu_env
, t0
, t1
, t2
);
10854 #ifdef TARGET_MIPS64
10856 gen_helper_ldm(cpu_env
, t0
, t1
, t2
);
10860 gen_helper_sdm(cpu_env
, t0
, t1
, t2
);
10866 MIPS_DEBUG("%s, %x, %d(%s)", opn
, reglist
, offset
, regnames
[base
]);
10869 tcg_temp_free_i32(t2
);
10873 static void gen_pool16c_insn(DisasContext
*ctx
)
10875 int rd
= mmreg((ctx
->opcode
>> 3) & 0x7);
10876 int rs
= mmreg(ctx
->opcode
& 0x7);
10879 switch (((ctx
->opcode
) >> 4) & 0x3f) {
10884 gen_logic(ctx
, OPC_NOR
, rd
, rs
, 0);
10890 gen_logic(ctx
, OPC_XOR
, rd
, rd
, rs
);
10896 gen_logic(ctx
, OPC_AND
, rd
, rd
, rs
);
10902 gen_logic(ctx
, OPC_OR
, rd
, rd
, rs
);
10909 static const int lwm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10910 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10912 gen_ldst_multiple(ctx
, LWM32
, lwm_convert
[(ctx
->opcode
>> 4) & 0x3],
10921 static const int swm_convert
[] = { 0x11, 0x12, 0x13, 0x14 };
10922 int offset
= ZIMM(ctx
->opcode
, 0, 4);
10924 gen_ldst_multiple(ctx
, SWM32
, swm_convert
[(ctx
->opcode
>> 4) & 0x3],
10931 int reg
= ctx
->opcode
& 0x1f;
10933 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10939 int reg
= ctx
->opcode
& 0x1f;
10941 gen_compute_branch(ctx
, OPC_JR
, 2, reg
, 0, 0);
10942 /* Let normal delay slot handling in our caller take us
10943 to the branch target. */
10955 int reg
= ctx
->opcode
& 0x1f;
10957 gen_compute_branch(ctx
, opc
, 2, reg
, 31, 0);
10962 gen_HILO(ctx
, OPC_MFHI
, 0, uMIPS_RS5(ctx
->opcode
));
10966 gen_HILO(ctx
, OPC_MFLO
, 0, uMIPS_RS5(ctx
->opcode
));
10969 generate_exception(ctx
, EXCP_BREAK
);
10972 /* XXX: not clear which exception should be raised
10973 * when in debug mode...
10975 check_insn(ctx
, ISA_MIPS32
);
10976 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
10977 generate_exception(ctx
, EXCP_DBp
);
10979 generate_exception(ctx
, EXCP_DBp
);
10982 case JRADDIUSP
+ 0:
10983 case JRADDIUSP
+ 1:
10985 int imm
= ZIMM(ctx
->opcode
, 0, 5);
10987 gen_compute_branch(ctx
, OPC_JR
, 2, 31, 0, 0);
10988 gen_arith_imm(ctx
, OPC_ADDIU
, 29, 29, imm
<< 2);
10989 /* Let normal delay slot handling in our caller take us
10990 to the branch target. */
10994 generate_exception(ctx
, EXCP_RI
);
10999 static void gen_ldxs (DisasContext
*ctx
, int base
, int index
, int rd
)
11001 TCGv t0
= tcg_temp_new();
11002 TCGv t1
= tcg_temp_new();
11004 gen_load_gpr(t0
, base
);
11007 gen_load_gpr(t1
, index
);
11008 tcg_gen_shli_tl(t1
, t1
, 2);
11009 gen_op_addr_add(ctx
, t0
, t1
, t0
);
11012 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11013 gen_store_gpr(t1
, rd
);
11019 static void gen_ldst_pair (DisasContext
*ctx
, uint32_t opc
, int rd
,
11020 int base
, int16_t offset
)
11022 const char *opn
= "ldst_pair";
11025 if (ctx
->hflags
& MIPS_HFLAG_BMASK
|| rd
== 31) {
11026 generate_exception(ctx
, EXCP_RI
);
11030 t0
= tcg_temp_new();
11031 t1
= tcg_temp_new();
11033 gen_base_offset_addr(ctx
, t0
, base
, offset
);
11038 generate_exception(ctx
, EXCP_RI
);
11041 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11042 gen_store_gpr(t1
, rd
);
11043 tcg_gen_movi_tl(t1
, 4);
11044 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11045 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TESL
);
11046 gen_store_gpr(t1
, rd
+1);
11050 gen_load_gpr(t1
, rd
);
11051 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11052 tcg_gen_movi_tl(t1
, 4);
11053 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11054 gen_load_gpr(t1
, rd
+1);
11055 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEUL
);
11058 #ifdef TARGET_MIPS64
11061 generate_exception(ctx
, EXCP_RI
);
11064 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11065 gen_store_gpr(t1
, rd
);
11066 tcg_gen_movi_tl(t1
, 8);
11067 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11068 tcg_gen_qemu_ld_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11069 gen_store_gpr(t1
, rd
+1);
11073 gen_load_gpr(t1
, rd
);
11074 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11075 tcg_gen_movi_tl(t1
, 8);
11076 gen_op_addr_add(ctx
, t0
, t0
, t1
);
11077 gen_load_gpr(t1
, rd
+1);
11078 tcg_gen_qemu_st_tl(t1
, t0
, ctx
->mem_idx
, MO_TEQ
);
11083 (void)opn
; /* avoid a compiler warning */
11084 MIPS_DEBUG("%s, %s, %d(%s)", opn
, regnames
[rd
], offset
, regnames
[base
]);
11089 static void gen_pool32axf (CPUMIPSState
*env
, DisasContext
*ctx
, int rt
, int rs
)
11091 int extension
= (ctx
->opcode
>> 6) & 0x3f;
11092 int minor
= (ctx
->opcode
>> 12) & 0xf;
11093 uint32_t mips32_op
;
11095 switch (extension
) {
11097 mips32_op
= OPC_TEQ
;
11100 mips32_op
= OPC_TGE
;
11103 mips32_op
= OPC_TGEU
;
11106 mips32_op
= OPC_TLT
;
11109 mips32_op
= OPC_TLTU
;
11112 mips32_op
= OPC_TNE
;
11114 gen_trap(ctx
, mips32_op
, rs
, rt
, -1);
11116 #ifndef CONFIG_USER_ONLY
11119 check_cp0_enabled(ctx
);
11121 /* Treat as NOP. */
11124 gen_mfc0(ctx
, cpu_gpr
[rt
], rs
, (ctx
->opcode
>> 11) & 0x7);
11128 check_cp0_enabled(ctx
);
11130 TCGv t0
= tcg_temp_new();
11132 gen_load_gpr(t0
, rt
);
11133 gen_mtc0(ctx
, t0
, rs
, (ctx
->opcode
>> 11) & 0x7);
11139 switch (minor
& 3) {
11141 gen_muldiv(ctx
, OPC_MADD
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11144 gen_muldiv(ctx
, OPC_MADDU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11147 gen_muldiv(ctx
, OPC_MSUB
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11150 gen_muldiv(ctx
, OPC_MSUBU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11153 goto pool32axf_invalid
;
11157 switch (minor
& 3) {
11159 gen_muldiv(ctx
, OPC_MULT
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11162 gen_muldiv(ctx
, OPC_MULTU
, (ctx
->opcode
>> 14) & 3, rs
, rt
);
11165 goto pool32axf_invalid
;
11171 gen_bshfl(ctx
, OPC_SEB
, rs
, rt
);
11174 gen_bshfl(ctx
, OPC_SEH
, rs
, rt
);
11177 mips32_op
= OPC_CLO
;
11180 mips32_op
= OPC_CLZ
;
11182 check_insn(ctx
, ISA_MIPS32
);
11183 gen_cl(ctx
, mips32_op
, rt
, rs
);
11186 gen_rdhwr(ctx
, rt
, rs
);
11189 gen_bshfl(ctx
, OPC_WSBH
, rs
, rt
);
11192 mips32_op
= OPC_MULT
;
11195 mips32_op
= OPC_MULTU
;
11198 mips32_op
= OPC_DIV
;
11201 mips32_op
= OPC_DIVU
;
11204 check_insn(ctx
, ISA_MIPS32
);
11205 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11208 mips32_op
= OPC_MADD
;
11211 mips32_op
= OPC_MADDU
;
11214 mips32_op
= OPC_MSUB
;
11217 mips32_op
= OPC_MSUBU
;
11219 check_insn(ctx
, ISA_MIPS32
);
11220 gen_muldiv(ctx
, mips32_op
, 0, rs
, rt
);
11223 goto pool32axf_invalid
;
11234 generate_exception_err(ctx
, EXCP_CpU
, 2);
11237 goto pool32axf_invalid
;
11244 gen_compute_branch (ctx
, OPC_JALR
, 4, rs
, rt
, 0);
11248 gen_compute_branch (ctx
, OPC_JALRS
, 4, rs
, rt
, 0);
11251 goto pool32axf_invalid
;
11257 check_cp0_enabled(ctx
);
11258 check_insn(ctx
, ISA_MIPS32R2
);
11259 gen_load_srsgpr(rt
, rs
);
11262 check_cp0_enabled(ctx
);
11263 check_insn(ctx
, ISA_MIPS32R2
);
11264 gen_store_srsgpr(rt
, rs
);
11267 goto pool32axf_invalid
;
11270 #ifndef CONFIG_USER_ONLY
11274 mips32_op
= OPC_TLBP
;
11277 mips32_op
= OPC_TLBR
;
11280 mips32_op
= OPC_TLBWI
;
11283 mips32_op
= OPC_TLBWR
;
11286 mips32_op
= OPC_WAIT
;
11289 mips32_op
= OPC_DERET
;
11292 mips32_op
= OPC_ERET
;
11294 gen_cp0(env
, ctx
, mips32_op
, rt
, rs
);
11297 goto pool32axf_invalid
;
11303 check_cp0_enabled(ctx
);
11305 TCGv t0
= tcg_temp_new();
11307 save_cpu_state(ctx
, 1);
11308 gen_helper_di(t0
, cpu_env
);
11309 gen_store_gpr(t0
, rs
);
11310 /* Stop translation as we may have switched the execution mode */
11311 ctx
->bstate
= BS_STOP
;
11316 check_cp0_enabled(ctx
);
11318 TCGv t0
= tcg_temp_new();
11320 save_cpu_state(ctx
, 1);
11321 gen_helper_ei(t0
, cpu_env
);
11322 gen_store_gpr(t0
, rs
);
11323 /* Stop translation as we may have switched the execution mode */
11324 ctx
->bstate
= BS_STOP
;
11329 goto pool32axf_invalid
;
11339 generate_exception(ctx
, EXCP_SYSCALL
);
11340 ctx
->bstate
= BS_STOP
;
11343 check_insn(ctx
, ISA_MIPS32
);
11344 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
11345 generate_exception(ctx
, EXCP_DBp
);
11347 generate_exception(ctx
, EXCP_DBp
);
11351 goto pool32axf_invalid
;
11355 switch (minor
& 3) {
11357 gen_HILO(ctx
, OPC_MFHI
, minor
>> 2, rs
);
11360 gen_HILO(ctx
, OPC_MFLO
, minor
>> 2, rs
);
11363 gen_HILO(ctx
, OPC_MTHI
, minor
>> 2, rs
);
11366 gen_HILO(ctx
, OPC_MTLO
, minor
>> 2, rs
);
11369 goto pool32axf_invalid
;
11375 gen_HILO(ctx
, OPC_MFHI
, 0, rs
);
11378 gen_HILO(ctx
, OPC_MFLO
, 0, rs
);
11381 gen_HILO(ctx
, OPC_MTHI
, 0, rs
);
11384 gen_HILO(ctx
, OPC_MTLO
, 0, rs
);
11387 goto pool32axf_invalid
;
11392 MIPS_INVAL("pool32axf");
11393 generate_exception(ctx
, EXCP_RI
);
11398 /* Values for microMIPS fmt field. Variable-width, depending on which
11399 formats the instruction supports. */
11418 static void gen_pool32fxf(DisasContext
*ctx
, int rt
, int rs
)
11420 int extension
= (ctx
->opcode
>> 6) & 0x3ff;
11421 uint32_t mips32_op
;
11423 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11424 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11425 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11427 switch (extension
) {
11428 case FLOAT_1BIT_FMT(CFC1
, 0):
11429 mips32_op
= OPC_CFC1
;
11431 case FLOAT_1BIT_FMT(CTC1
, 0):
11432 mips32_op
= OPC_CTC1
;
11434 case FLOAT_1BIT_FMT(MFC1
, 0):
11435 mips32_op
= OPC_MFC1
;
11437 case FLOAT_1BIT_FMT(MTC1
, 0):
11438 mips32_op
= OPC_MTC1
;
11440 case FLOAT_1BIT_FMT(MFHC1
, 0):
11441 mips32_op
= OPC_MFHC1
;
11443 case FLOAT_1BIT_FMT(MTHC1
, 0):
11444 mips32_op
= OPC_MTHC1
;
11446 gen_cp1(ctx
, mips32_op
, rt
, rs
);
11449 /* Reciprocal square root */
11450 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_S
):
11451 mips32_op
= OPC_RSQRT_S
;
11453 case FLOAT_1BIT_FMT(RSQRT_FMT
, FMT_SD_D
):
11454 mips32_op
= OPC_RSQRT_D
;
11458 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_S
):
11459 mips32_op
= OPC_SQRT_S
;
11461 case FLOAT_1BIT_FMT(SQRT_FMT
, FMT_SD_D
):
11462 mips32_op
= OPC_SQRT_D
;
11466 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_S
):
11467 mips32_op
= OPC_RECIP_S
;
11469 case FLOAT_1BIT_FMT(RECIP_FMT
, FMT_SD_D
):
11470 mips32_op
= OPC_RECIP_D
;
11474 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_S
):
11475 mips32_op
= OPC_FLOOR_L_S
;
11477 case FLOAT_1BIT_FMT(FLOOR_L
, FMT_SD_D
):
11478 mips32_op
= OPC_FLOOR_L_D
;
11480 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_S
):
11481 mips32_op
= OPC_FLOOR_W_S
;
11483 case FLOAT_1BIT_FMT(FLOOR_W
, FMT_SD_D
):
11484 mips32_op
= OPC_FLOOR_W_D
;
11488 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_S
):
11489 mips32_op
= OPC_CEIL_L_S
;
11491 case FLOAT_1BIT_FMT(CEIL_L
, FMT_SD_D
):
11492 mips32_op
= OPC_CEIL_L_D
;
11494 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_S
):
11495 mips32_op
= OPC_CEIL_W_S
;
11497 case FLOAT_1BIT_FMT(CEIL_W
, FMT_SD_D
):
11498 mips32_op
= OPC_CEIL_W_D
;
11502 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_S
):
11503 mips32_op
= OPC_TRUNC_L_S
;
11505 case FLOAT_1BIT_FMT(TRUNC_L
, FMT_SD_D
):
11506 mips32_op
= OPC_TRUNC_L_D
;
11508 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_S
):
11509 mips32_op
= OPC_TRUNC_W_S
;
11511 case FLOAT_1BIT_FMT(TRUNC_W
, FMT_SD_D
):
11512 mips32_op
= OPC_TRUNC_W_D
;
11516 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_S
):
11517 mips32_op
= OPC_ROUND_L_S
;
11519 case FLOAT_1BIT_FMT(ROUND_L
, FMT_SD_D
):
11520 mips32_op
= OPC_ROUND_L_D
;
11522 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_S
):
11523 mips32_op
= OPC_ROUND_W_S
;
11525 case FLOAT_1BIT_FMT(ROUND_W
, FMT_SD_D
):
11526 mips32_op
= OPC_ROUND_W_D
;
11529 /* Integer to floating-point conversion */
11530 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_S
):
11531 mips32_op
= OPC_CVT_L_S
;
11533 case FLOAT_1BIT_FMT(CVT_L
, FMT_SD_D
):
11534 mips32_op
= OPC_CVT_L_D
;
11536 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_S
):
11537 mips32_op
= OPC_CVT_W_S
;
11539 case FLOAT_1BIT_FMT(CVT_W
, FMT_SD_D
):
11540 mips32_op
= OPC_CVT_W_D
;
11543 /* Paired-foo conversions */
11544 case FLOAT_1BIT_FMT(CVT_S_PL
, 0):
11545 mips32_op
= OPC_CVT_S_PL
;
11547 case FLOAT_1BIT_FMT(CVT_S_PU
, 0):
11548 mips32_op
= OPC_CVT_S_PU
;
11550 case FLOAT_1BIT_FMT(CVT_PW_PS
, 0):
11551 mips32_op
= OPC_CVT_PW_PS
;
11553 case FLOAT_1BIT_FMT(CVT_PS_PW
, 0):
11554 mips32_op
= OPC_CVT_PS_PW
;
11557 /* Floating-point moves */
11558 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_S
):
11559 mips32_op
= OPC_MOV_S
;
11561 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_D
):
11562 mips32_op
= OPC_MOV_D
;
11564 case FLOAT_2BIT_FMT(MOV_FMT
, FMT_SDPS_PS
):
11565 mips32_op
= OPC_MOV_PS
;
11568 /* Absolute value */
11569 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_S
):
11570 mips32_op
= OPC_ABS_S
;
11572 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_D
):
11573 mips32_op
= OPC_ABS_D
;
11575 case FLOAT_2BIT_FMT(ABS_FMT
, FMT_SDPS_PS
):
11576 mips32_op
= OPC_ABS_PS
;
11580 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_S
):
11581 mips32_op
= OPC_NEG_S
;
11583 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_D
):
11584 mips32_op
= OPC_NEG_D
;
11586 case FLOAT_2BIT_FMT(NEG_FMT
, FMT_SDPS_PS
):
11587 mips32_op
= OPC_NEG_PS
;
11590 /* Reciprocal square root step */
11591 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_S
):
11592 mips32_op
= OPC_RSQRT1_S
;
11594 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_D
):
11595 mips32_op
= OPC_RSQRT1_D
;
11597 case FLOAT_2BIT_FMT(RSQRT1_FMT
, FMT_SDPS_PS
):
11598 mips32_op
= OPC_RSQRT1_PS
;
11601 /* Reciprocal step */
11602 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_S
):
11603 mips32_op
= OPC_RECIP1_S
;
11605 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_D
):
11606 mips32_op
= OPC_RECIP1_S
;
11608 case FLOAT_2BIT_FMT(RECIP1_FMT
, FMT_SDPS_PS
):
11609 mips32_op
= OPC_RECIP1_PS
;
11612 /* Conversions from double */
11613 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_S
):
11614 mips32_op
= OPC_CVT_D_S
;
11616 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_W
):
11617 mips32_op
= OPC_CVT_D_W
;
11619 case FLOAT_2BIT_FMT(CVT_D
, FMT_SWL_L
):
11620 mips32_op
= OPC_CVT_D_L
;
11623 /* Conversions from single */
11624 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_D
):
11625 mips32_op
= OPC_CVT_S_D
;
11627 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_W
):
11628 mips32_op
= OPC_CVT_S_W
;
11630 case FLOAT_2BIT_FMT(CVT_S
, FMT_DWL_L
):
11631 mips32_op
= OPC_CVT_S_L
;
11633 gen_farith(ctx
, mips32_op
, -1, rs
, rt
, 0);
11636 /* Conditional moves on floating-point codes */
11637 case COND_FLOAT_MOV(MOVT
, 0):
11638 case COND_FLOAT_MOV(MOVT
, 1):
11639 case COND_FLOAT_MOV(MOVT
, 2):
11640 case COND_FLOAT_MOV(MOVT
, 3):
11641 case COND_FLOAT_MOV(MOVT
, 4):
11642 case COND_FLOAT_MOV(MOVT
, 5):
11643 case COND_FLOAT_MOV(MOVT
, 6):
11644 case COND_FLOAT_MOV(MOVT
, 7):
11645 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 1);
11647 case COND_FLOAT_MOV(MOVF
, 0):
11648 case COND_FLOAT_MOV(MOVF
, 1):
11649 case COND_FLOAT_MOV(MOVF
, 2):
11650 case COND_FLOAT_MOV(MOVF
, 3):
11651 case COND_FLOAT_MOV(MOVF
, 4):
11652 case COND_FLOAT_MOV(MOVF
, 5):
11653 case COND_FLOAT_MOV(MOVF
, 6):
11654 case COND_FLOAT_MOV(MOVF
, 7):
11655 gen_movci(ctx
, rt
, rs
, (ctx
->opcode
>> 13) & 0x7, 0);
11658 MIPS_INVAL("pool32fxf");
11659 generate_exception(ctx
, EXCP_RI
);
11664 static void decode_micromips32_opc (CPUMIPSState
*env
, DisasContext
*ctx
,
11669 int rt
, rs
, rd
, rr
;
11671 uint32_t op
, minor
, mips32_op
;
11672 uint32_t cond
, fmt
, cc
;
11674 insn
= cpu_lduw_code(env
, ctx
->pc
+ 2);
11675 ctx
->opcode
= (ctx
->opcode
<< 16) | insn
;
11677 rt
= (ctx
->opcode
>> 21) & 0x1f;
11678 rs
= (ctx
->opcode
>> 16) & 0x1f;
11679 rd
= (ctx
->opcode
>> 11) & 0x1f;
11680 rr
= (ctx
->opcode
>> 6) & 0x1f;
11681 imm
= (int16_t) ctx
->opcode
;
11683 op
= (ctx
->opcode
>> 26) & 0x3f;
11686 minor
= ctx
->opcode
& 0x3f;
11689 minor
= (ctx
->opcode
>> 6) & 0xf;
11692 mips32_op
= OPC_SLL
;
11695 mips32_op
= OPC_SRA
;
11698 mips32_op
= OPC_SRL
;
11701 mips32_op
= OPC_ROTR
;
11703 gen_shift_imm(ctx
, mips32_op
, rt
, rs
, rd
);
11706 goto pool32a_invalid
;
11710 minor
= (ctx
->opcode
>> 6) & 0xf;
11714 mips32_op
= OPC_ADD
;
11717 mips32_op
= OPC_ADDU
;
11720 mips32_op
= OPC_SUB
;
11723 mips32_op
= OPC_SUBU
;
11726 mips32_op
= OPC_MUL
;
11728 gen_arith(ctx
, mips32_op
, rd
, rs
, rt
);
11732 mips32_op
= OPC_SLLV
;
11735 mips32_op
= OPC_SRLV
;
11738 mips32_op
= OPC_SRAV
;
11741 mips32_op
= OPC_ROTRV
;
11743 gen_shift(ctx
, mips32_op
, rd
, rs
, rt
);
11745 /* Logical operations */
11747 mips32_op
= OPC_AND
;
11750 mips32_op
= OPC_OR
;
11753 mips32_op
= OPC_NOR
;
11756 mips32_op
= OPC_XOR
;
11758 gen_logic(ctx
, mips32_op
, rd
, rs
, rt
);
11760 /* Set less than */
11762 mips32_op
= OPC_SLT
;
11765 mips32_op
= OPC_SLTU
;
11767 gen_slt(ctx
, mips32_op
, rd
, rs
, rt
);
11770 goto pool32a_invalid
;
11774 minor
= (ctx
->opcode
>> 6) & 0xf;
11776 /* Conditional moves */
11778 mips32_op
= OPC_MOVN
;
11781 mips32_op
= OPC_MOVZ
;
11783 gen_cond_move(ctx
, mips32_op
, rd
, rs
, rt
);
11786 gen_ldxs(ctx
, rs
, rt
, rd
);
11789 goto pool32a_invalid
;
11793 gen_bitops(ctx
, OPC_INS
, rt
, rs
, rr
, rd
);
11796 gen_bitops(ctx
, OPC_EXT
, rt
, rs
, rr
, rd
);
11799 gen_pool32axf(env
, ctx
, rt
, rs
);
11802 generate_exception(ctx
, EXCP_BREAK
);
11806 MIPS_INVAL("pool32a");
11807 generate_exception(ctx
, EXCP_RI
);
11812 minor
= (ctx
->opcode
>> 12) & 0xf;
11815 check_cp0_enabled(ctx
);
11816 /* Treat as no-op. */
11820 /* COP2: Not implemented. */
11821 generate_exception_err(ctx
, EXCP_CpU
, 2);
11825 #ifdef TARGET_MIPS64
11829 gen_ldst_pair(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11833 #ifdef TARGET_MIPS64
11837 gen_ldst_multiple(ctx
, minor
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
11840 MIPS_INVAL("pool32b");
11841 generate_exception(ctx
, EXCP_RI
);
11846 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
11847 minor
= ctx
->opcode
& 0x3f;
11848 check_cp1_enabled(ctx
);
11851 mips32_op
= OPC_ALNV_PS
;
11854 mips32_op
= OPC_MADD_S
;
11857 mips32_op
= OPC_MADD_D
;
11860 mips32_op
= OPC_MADD_PS
;
11863 mips32_op
= OPC_MSUB_S
;
11866 mips32_op
= OPC_MSUB_D
;
11869 mips32_op
= OPC_MSUB_PS
;
11872 mips32_op
= OPC_NMADD_S
;
11875 mips32_op
= OPC_NMADD_D
;
11878 mips32_op
= OPC_NMADD_PS
;
11881 mips32_op
= OPC_NMSUB_S
;
11884 mips32_op
= OPC_NMSUB_D
;
11887 mips32_op
= OPC_NMSUB_PS
;
11889 gen_flt3_arith(ctx
, mips32_op
, rd
, rr
, rs
, rt
);
11891 case CABS_COND_FMT
:
11892 cond
= (ctx
->opcode
>> 6) & 0xf;
11893 cc
= (ctx
->opcode
>> 13) & 0x7;
11894 fmt
= (ctx
->opcode
>> 10) & 0x3;
11897 gen_cmpabs_s(ctx
, cond
, rt
, rs
, cc
);
11900 gen_cmpabs_d(ctx
, cond
, rt
, rs
, cc
);
11903 gen_cmpabs_ps(ctx
, cond
, rt
, rs
, cc
);
11906 goto pool32f_invalid
;
11910 cond
= (ctx
->opcode
>> 6) & 0xf;
11911 cc
= (ctx
->opcode
>> 13) & 0x7;
11912 fmt
= (ctx
->opcode
>> 10) & 0x3;
11915 gen_cmp_s(ctx
, cond
, rt
, rs
, cc
);
11918 gen_cmp_d(ctx
, cond
, rt
, rs
, cc
);
11921 gen_cmp_ps(ctx
, cond
, rt
, rs
, cc
);
11924 goto pool32f_invalid
;
11928 gen_pool32fxf(ctx
, rt
, rs
);
11932 switch ((ctx
->opcode
>> 6) & 0x7) {
11934 mips32_op
= OPC_PLL_PS
;
11937 mips32_op
= OPC_PLU_PS
;
11940 mips32_op
= OPC_PUL_PS
;
11943 mips32_op
= OPC_PUU_PS
;
11946 mips32_op
= OPC_CVT_PS_S
;
11948 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
11951 goto pool32f_invalid
;
11956 switch ((ctx
->opcode
>> 6) & 0x7) {
11958 mips32_op
= OPC_LWXC1
;
11961 mips32_op
= OPC_SWXC1
;
11964 mips32_op
= OPC_LDXC1
;
11967 mips32_op
= OPC_SDXC1
;
11970 mips32_op
= OPC_LUXC1
;
11973 mips32_op
= OPC_SUXC1
;
11975 gen_flt3_ldst(ctx
, mips32_op
, rd
, rd
, rt
, rs
);
11978 goto pool32f_invalid
;
11983 fmt
= (ctx
->opcode
>> 9) & 0x3;
11984 switch ((ctx
->opcode
>> 6) & 0x7) {
11988 mips32_op
= OPC_RSQRT2_S
;
11991 mips32_op
= OPC_RSQRT2_D
;
11994 mips32_op
= OPC_RSQRT2_PS
;
11997 goto pool32f_invalid
;
12003 mips32_op
= OPC_RECIP2_S
;
12006 mips32_op
= OPC_RECIP2_D
;
12009 mips32_op
= OPC_RECIP2_PS
;
12012 goto pool32f_invalid
;
12016 mips32_op
= OPC_ADDR_PS
;
12019 mips32_op
= OPC_MULR_PS
;
12021 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12024 goto pool32f_invalid
;
12028 /* MOV[FT].fmt and PREFX */
12029 cc
= (ctx
->opcode
>> 13) & 0x7;
12030 fmt
= (ctx
->opcode
>> 9) & 0x3;
12031 switch ((ctx
->opcode
>> 6) & 0x7) {
12035 gen_movcf_s(rs
, rt
, cc
, 0);
12038 gen_movcf_d(ctx
, rs
, rt
, cc
, 0);
12041 gen_movcf_ps(ctx
, rs
, rt
, cc
, 0);
12044 goto pool32f_invalid
;
12050 gen_movcf_s(rs
, rt
, cc
, 1);
12053 gen_movcf_d(ctx
, rs
, rt
, cc
, 1);
12056 gen_movcf_ps(ctx
, rs
, rt
, cc
, 1);
12059 goto pool32f_invalid
;
12065 goto pool32f_invalid
;
12068 #define FINSN_3ARG_SDPS(prfx) \
12069 switch ((ctx->opcode >> 8) & 0x3) { \
12071 mips32_op = OPC_##prfx##_S; \
12074 mips32_op = OPC_##prfx##_D; \
12076 case FMT_SDPS_PS: \
12077 mips32_op = OPC_##prfx##_PS; \
12080 goto pool32f_invalid; \
12083 /* regular FP ops */
12084 switch ((ctx
->opcode
>> 6) & 0x3) {
12086 FINSN_3ARG_SDPS(ADD
);
12089 FINSN_3ARG_SDPS(SUB
);
12092 FINSN_3ARG_SDPS(MUL
);
12095 fmt
= (ctx
->opcode
>> 8) & 0x3;
12097 mips32_op
= OPC_DIV_D
;
12098 } else if (fmt
== 0) {
12099 mips32_op
= OPC_DIV_S
;
12101 goto pool32f_invalid
;
12105 goto pool32f_invalid
;
12110 switch ((ctx
->opcode
>> 6) & 0x3) {
12112 FINSN_3ARG_SDPS(MOVN
);
12115 FINSN_3ARG_SDPS(MOVZ
);
12118 goto pool32f_invalid
;
12122 gen_farith(ctx
, mips32_op
, rt
, rs
, rd
, 0);
12126 MIPS_INVAL("pool32f");
12127 generate_exception(ctx
, EXCP_RI
);
12131 generate_exception_err(ctx
, EXCP_CpU
, 1);
12135 minor
= (ctx
->opcode
>> 21) & 0x1f;
12138 mips32_op
= OPC_BLTZ
;
12141 mips32_op
= OPC_BLTZAL
;
12144 mips32_op
= OPC_BLTZALS
;
12147 mips32_op
= OPC_BGEZ
;
12150 mips32_op
= OPC_BGEZAL
;
12153 mips32_op
= OPC_BGEZALS
;
12156 mips32_op
= OPC_BLEZ
;
12159 mips32_op
= OPC_BGTZ
;
12161 gen_compute_branch(ctx
, mips32_op
, 4, rs
, -1, imm
<< 1);
12166 mips32_op
= OPC_TLTI
;
12169 mips32_op
= OPC_TGEI
;
12172 mips32_op
= OPC_TLTIU
;
12175 mips32_op
= OPC_TGEIU
;
12178 mips32_op
= OPC_TNEI
;
12181 mips32_op
= OPC_TEQI
;
12183 gen_trap(ctx
, mips32_op
, rs
, -1, imm
);
12188 gen_compute_branch(ctx
, minor
== BNEZC
? OPC_BNE
: OPC_BEQ
,
12189 4, rs
, 0, imm
<< 1);
12190 /* Compact branches don't have a delay slot, so just let
12191 the normal delay slot handling take us to the branch
12195 gen_logic_imm(ctx
, OPC_LUI
, rs
, -1, imm
);
12201 /* COP2: Not implemented. */
12202 generate_exception_err(ctx
, EXCP_CpU
, 2);
12205 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1FANY2
: OPC_BC1F
;
12208 mips32_op
= (ctx
->opcode
& (1 << 16)) ? OPC_BC1TANY2
: OPC_BC1T
;
12211 mips32_op
= OPC_BC1FANY4
;
12214 mips32_op
= OPC_BC1TANY4
;
12217 check_insn(ctx
, ASE_MIPS3D
);
12220 gen_compute_branch1(ctx
, mips32_op
,
12221 (ctx
->opcode
>> 18) & 0x7, imm
<< 1);
12225 /* MIPS DSP: not implemented */
12228 MIPS_INVAL("pool32i");
12229 generate_exception(ctx
, EXCP_RI
);
12234 minor
= (ctx
->opcode
>> 12) & 0xf;
12237 mips32_op
= OPC_LWL
;
12240 mips32_op
= OPC_SWL
;
12243 mips32_op
= OPC_LWR
;
12246 mips32_op
= OPC_SWR
;
12248 #if defined(TARGET_MIPS64)
12250 mips32_op
= OPC_LDL
;
12253 mips32_op
= OPC_SDL
;
12256 mips32_op
= OPC_LDR
;
12259 mips32_op
= OPC_SDR
;
12262 mips32_op
= OPC_LWU
;
12265 mips32_op
= OPC_LLD
;
12269 mips32_op
= OPC_LL
;
12272 gen_ld(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12275 gen_st(ctx
, mips32_op
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12278 gen_st_cond(ctx
, OPC_SC
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12280 #if defined(TARGET_MIPS64)
12282 gen_st_cond(ctx
, OPC_SCD
, rt
, rs
, SIMM(ctx
->opcode
, 0, 12));
12286 /* Treat as no-op */
12289 MIPS_INVAL("pool32c");
12290 generate_exception(ctx
, EXCP_RI
);
12295 mips32_op
= OPC_ADDI
;
12298 mips32_op
= OPC_ADDIU
;
12300 gen_arith_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12303 /* Logical operations */
12305 mips32_op
= OPC_ORI
;
12308 mips32_op
= OPC_XORI
;
12311 mips32_op
= OPC_ANDI
;
12313 gen_logic_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12316 /* Set less than immediate */
12318 mips32_op
= OPC_SLTI
;
12321 mips32_op
= OPC_SLTIU
;
12323 gen_slt_imm(ctx
, mips32_op
, rt
, rs
, imm
);
12326 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
12327 gen_compute_branch(ctx
, OPC_JALX
, 4, rt
, rs
, offset
);
12330 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1;
12331 gen_compute_branch(ctx
, OPC_JALS
, 4, rt
, rs
, offset
);
12334 gen_compute_branch(ctx
, OPC_BEQ
, 4, rt
, rs
, imm
<< 1);
12337 gen_compute_branch(ctx
, OPC_BNE
, 4, rt
, rs
, imm
<< 1);
12340 gen_compute_branch(ctx
, OPC_J
, 4, rt
, rs
,
12341 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12344 gen_compute_branch(ctx
, OPC_JAL
, 4, rt
, rs
,
12345 (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 1);
12347 /* Floating point (COP1) */
12349 mips32_op
= OPC_LWC1
;
12352 mips32_op
= OPC_LDC1
;
12355 mips32_op
= OPC_SWC1
;
12358 mips32_op
= OPC_SDC1
;
12360 gen_cop1_ldst(ctx
, mips32_op
, rt
, rs
, imm
);
12364 int reg
= mmreg(ZIMM(ctx
->opcode
, 23, 3));
12365 int offset
= SIMM(ctx
->opcode
, 0, 23) << 2;
12367 gen_addiupc(ctx
, reg
, offset
, 0, 0);
12370 /* Loads and stores */
12372 mips32_op
= OPC_LB
;
12375 mips32_op
= OPC_LBU
;
12378 mips32_op
= OPC_LH
;
12381 mips32_op
= OPC_LHU
;
12384 mips32_op
= OPC_LW
;
12386 #ifdef TARGET_MIPS64
12388 mips32_op
= OPC_LD
;
12391 mips32_op
= OPC_SD
;
12395 mips32_op
= OPC_SB
;
12398 mips32_op
= OPC_SH
;
12401 mips32_op
= OPC_SW
;
12404 gen_ld(ctx
, mips32_op
, rt
, rs
, imm
);
12407 gen_st(ctx
, mips32_op
, rt
, rs
, imm
);
12410 generate_exception(ctx
, EXCP_RI
);
12415 static int decode_micromips_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
12419 /* make sure instructions are on a halfword boundary */
12420 if (ctx
->pc
& 0x1) {
12421 env
->CP0_BadVAddr
= ctx
->pc
;
12422 generate_exception(ctx
, EXCP_AdEL
);
12423 ctx
->bstate
= BS_STOP
;
12427 op
= (ctx
->opcode
>> 10) & 0x3f;
12428 /* Enforce properly-sized instructions in a delay slot */
12429 if (ctx
->hflags
& MIPS_HFLAG_BMASK
) {
12430 int bits
= ctx
->hflags
& MIPS_HFLAG_BMASK_EXT
;
12468 if (bits
& MIPS_HFLAG_BDS16
) {
12469 generate_exception(ctx
, EXCP_RI
);
12470 /* Just stop translation; the user is confused. */
12471 ctx
->bstate
= BS_STOP
;
12496 if (bits
& MIPS_HFLAG_BDS32
) {
12497 generate_exception(ctx
, EXCP_RI
);
12498 /* Just stop translation; the user is confused. */
12499 ctx
->bstate
= BS_STOP
;
12510 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12511 int rs1
= mmreg(uMIPS_RS1(ctx
->opcode
));
12512 int rs2
= mmreg(uMIPS_RS2(ctx
->opcode
));
12515 switch (ctx
->opcode
& 0x1) {
12524 gen_arith(ctx
, opc
, rd
, rs1
, rs2
);
12529 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12530 int rs
= mmreg(uMIPS_RS(ctx
->opcode
));
12531 int amount
= (ctx
->opcode
>> 1) & 0x7;
12533 amount
= amount
== 0 ? 8 : amount
;
12535 switch (ctx
->opcode
& 0x1) {
12544 gen_shift_imm(ctx
, opc
, rd
, rs
, amount
);
12548 gen_pool16c_insn(ctx
);
12552 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12553 int rb
= 28; /* GP */
12554 int16_t offset
= SIMM(ctx
->opcode
, 0, 7) << 2;
12556 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12560 if (ctx
->opcode
& 1) {
12561 generate_exception(ctx
, EXCP_RI
);
12564 int enc_dest
= uMIPS_RD(ctx
->opcode
);
12565 int enc_rt
= uMIPS_RS2(ctx
->opcode
);
12566 int enc_rs
= uMIPS_RS1(ctx
->opcode
);
12567 int rd
, rs
, re
, rt
;
12568 static const int rd_enc
[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12569 static const int re_enc
[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12570 static const int rs_rt_enc
[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12572 rd
= rd_enc
[enc_dest
];
12573 re
= re_enc
[enc_dest
];
12574 rs
= rs_rt_enc
[enc_rs
];
12575 rt
= rs_rt_enc
[enc_rt
];
12577 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12578 gen_arith_imm(ctx
, OPC_ADDIU
, re
, rt
, 0);
12583 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12584 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12585 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12586 offset
= (offset
== 0xf ? -1 : offset
);
12588 gen_ld(ctx
, OPC_LBU
, rd
, rb
, offset
);
12593 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12594 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12595 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12597 gen_ld(ctx
, OPC_LHU
, rd
, rb
, offset
);
12602 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12603 int rb
= 29; /* SP */
12604 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12606 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12611 int rd
= mmreg(uMIPS_RD(ctx
->opcode
));
12612 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12613 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12615 gen_ld(ctx
, OPC_LW
, rd
, rb
, offset
);
12620 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12621 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12622 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4);
12624 gen_st(ctx
, OPC_SB
, rd
, rb
, offset
);
12629 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12630 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12631 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 1;
12633 gen_st(ctx
, OPC_SH
, rd
, rb
, offset
);
12638 int rd
= (ctx
->opcode
>> 5) & 0x1f;
12639 int rb
= 29; /* SP */
12640 int16_t offset
= ZIMM(ctx
->opcode
, 0, 5) << 2;
12642 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12647 int rd
= mmreg2(uMIPS_RD(ctx
->opcode
));
12648 int rb
= mmreg(uMIPS_RS(ctx
->opcode
));
12649 int16_t offset
= ZIMM(ctx
->opcode
, 0, 4) << 2;
12651 gen_st(ctx
, OPC_SW
, rd
, rb
, offset
);
12656 int rd
= uMIPS_RD5(ctx
->opcode
);
12657 int rs
= uMIPS_RS5(ctx
->opcode
);
12659 gen_arith_imm(ctx
, OPC_ADDIU
, rd
, rs
, 0);
12666 switch (ctx
->opcode
& 0x1) {
12676 switch (ctx
->opcode
& 0x1) {
12681 gen_addiur1sp(ctx
);
12686 gen_compute_branch(ctx
, OPC_BEQ
, 2, 0, 0,
12687 SIMM(ctx
->opcode
, 0, 10) << 1);
12691 gen_compute_branch(ctx
, op
== BNEZ16
? OPC_BNE
: OPC_BEQ
, 2,
12692 mmreg(uMIPS_RD(ctx
->opcode
)),
12693 0, SIMM(ctx
->opcode
, 0, 7) << 1);
12697 int reg
= mmreg(uMIPS_RD(ctx
->opcode
));
12698 int imm
= ZIMM(ctx
->opcode
, 0, 7);
12700 imm
= (imm
== 0x7f ? -1 : imm
);
12701 tcg_gen_movi_tl(cpu_gpr
[reg
], imm
);
12711 generate_exception(ctx
, EXCP_RI
);
12714 decode_micromips32_opc (env
, ctx
, op
);
12721 /* SmartMIPS extension to MIPS32 */
12723 #if defined(TARGET_MIPS64)
12725 /* MDMX extension to MIPS64 */
12729 /* MIPSDSP functions. */
12730 static void gen_mipsdsp_ld(DisasContext
*ctx
, uint32_t opc
,
12731 int rd
, int base
, int offset
)
12733 const char *opn
= "ldx";
12737 t0
= tcg_temp_new();
12740 gen_load_gpr(t0
, offset
);
12741 } else if (offset
== 0) {
12742 gen_load_gpr(t0
, base
);
12744 gen_op_addr_add(ctx
, t0
, cpu_gpr
[base
], cpu_gpr
[offset
]);
12749 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_UB
);
12750 gen_store_gpr(t0
, rd
);
12754 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESW
);
12755 gen_store_gpr(t0
, rd
);
12759 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TESL
);
12760 gen_store_gpr(t0
, rd
);
12763 #if defined(TARGET_MIPS64)
12765 tcg_gen_qemu_ld_tl(t0
, t0
, ctx
->mem_idx
, MO_TEQ
);
12766 gen_store_gpr(t0
, rd
);
12771 (void)opn
; /* avoid a compiler warning */
12772 MIPS_DEBUG("%s %s, %s(%s)", opn
,
12773 regnames
[rd
], regnames
[offset
], regnames
[base
]);
12777 static void gen_mipsdsp_arith(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
12778 int ret
, int v1
, int v2
)
12780 const char *opn
= "mipsdsp arith";
12785 /* Treat as NOP. */
12790 v1_t
= tcg_temp_new();
12791 v2_t
= tcg_temp_new();
12793 gen_load_gpr(v1_t
, v1
);
12794 gen_load_gpr(v2_t
, v2
);
12797 /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12798 case OPC_MULT_G_2E
:
12802 gen_helper_adduh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12804 case OPC_ADDUH_R_QB
:
12805 gen_helper_adduh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12808 gen_helper_addqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12810 case OPC_ADDQH_R_PH
:
12811 gen_helper_addqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12814 gen_helper_addqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12816 case OPC_ADDQH_R_W
:
12817 gen_helper_addqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12820 gen_helper_subuh_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12822 case OPC_SUBUH_R_QB
:
12823 gen_helper_subuh_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
12826 gen_helper_subqh_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12828 case OPC_SUBQH_R_PH
:
12829 gen_helper_subqh_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12832 gen_helper_subqh_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12834 case OPC_SUBQH_R_W
:
12835 gen_helper_subqh_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
12839 case OPC_ABSQ_S_PH_DSP
:
12841 case OPC_ABSQ_S_QB
:
12843 gen_helper_absq_s_qb(cpu_gpr
[ret
], v2_t
, cpu_env
);
12845 case OPC_ABSQ_S_PH
:
12847 gen_helper_absq_s_ph(cpu_gpr
[ret
], v2_t
, cpu_env
);
12851 gen_helper_absq_s_w(cpu_gpr
[ret
], v2_t
, cpu_env
);
12853 case OPC_PRECEQ_W_PHL
:
12855 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFF0000);
12856 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12858 case OPC_PRECEQ_W_PHR
:
12860 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0x0000FFFF);
12861 tcg_gen_shli_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], 16);
12862 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
12864 case OPC_PRECEQU_PH_QBL
:
12866 gen_helper_precequ_ph_qbl(cpu_gpr
[ret
], v2_t
);
12868 case OPC_PRECEQU_PH_QBR
:
12870 gen_helper_precequ_ph_qbr(cpu_gpr
[ret
], v2_t
);
12872 case OPC_PRECEQU_PH_QBLA
:
12874 gen_helper_precequ_ph_qbla(cpu_gpr
[ret
], v2_t
);
12876 case OPC_PRECEQU_PH_QBRA
:
12878 gen_helper_precequ_ph_qbra(cpu_gpr
[ret
], v2_t
);
12880 case OPC_PRECEU_PH_QBL
:
12882 gen_helper_preceu_ph_qbl(cpu_gpr
[ret
], v2_t
);
12884 case OPC_PRECEU_PH_QBR
:
12886 gen_helper_preceu_ph_qbr(cpu_gpr
[ret
], v2_t
);
12888 case OPC_PRECEU_PH_QBLA
:
12890 gen_helper_preceu_ph_qbla(cpu_gpr
[ret
], v2_t
);
12892 case OPC_PRECEU_PH_QBRA
:
12894 gen_helper_preceu_ph_qbra(cpu_gpr
[ret
], v2_t
);
12898 case OPC_ADDU_QB_DSP
:
12902 gen_helper_addq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12904 case OPC_ADDQ_S_PH
:
12906 gen_helper_addq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12910 gen_helper_addq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12914 gen_helper_addu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12916 case OPC_ADDU_S_QB
:
12918 gen_helper_addu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12922 gen_helper_addu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12924 case OPC_ADDU_S_PH
:
12926 gen_helper_addu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12930 gen_helper_subq_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12932 case OPC_SUBQ_S_PH
:
12934 gen_helper_subq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12938 gen_helper_subq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12942 gen_helper_subu_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12944 case OPC_SUBU_S_QB
:
12946 gen_helper_subu_s_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12950 gen_helper_subu_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12952 case OPC_SUBU_S_PH
:
12954 gen_helper_subu_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12958 gen_helper_addsc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12962 gen_helper_addwc(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
12966 gen_helper_modsub(cpu_gpr
[ret
], v1_t
, v2_t
);
12968 case OPC_RADDU_W_QB
:
12970 gen_helper_raddu_w_qb(cpu_gpr
[ret
], v1_t
);
12974 case OPC_CMPU_EQ_QB_DSP
:
12976 case OPC_PRECR_QB_PH
:
12978 gen_helper_precr_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12980 case OPC_PRECRQ_QB_PH
:
12982 gen_helper_precrq_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
12984 case OPC_PRECR_SRA_PH_W
:
12987 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12988 gen_helper_precr_sra_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12990 tcg_temp_free_i32(sa_t
);
12993 case OPC_PRECR_SRA_R_PH_W
:
12996 TCGv_i32 sa_t
= tcg_const_i32(v2
);
12997 gen_helper_precr_sra_r_ph_w(cpu_gpr
[ret
], sa_t
, v1_t
,
12999 tcg_temp_free_i32(sa_t
);
13002 case OPC_PRECRQ_PH_W
:
13004 gen_helper_precrq_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13006 case OPC_PRECRQ_RS_PH_W
:
13008 gen_helper_precrq_rs_ph_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13010 case OPC_PRECRQU_S_QB_PH
:
13012 gen_helper_precrqu_s_qb_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13016 #ifdef TARGET_MIPS64
13017 case OPC_ABSQ_S_QH_DSP
:
13019 case OPC_PRECEQ_L_PWL
:
13021 tcg_gen_andi_tl(cpu_gpr
[ret
], v2_t
, 0xFFFFFFFF00000000ull
);
13023 case OPC_PRECEQ_L_PWR
:
13025 tcg_gen_shli_tl(cpu_gpr
[ret
], v2_t
, 32);
13027 case OPC_PRECEQ_PW_QHL
:
13029 gen_helper_preceq_pw_qhl(cpu_gpr
[ret
], v2_t
);
13031 case OPC_PRECEQ_PW_QHR
:
13033 gen_helper_preceq_pw_qhr(cpu_gpr
[ret
], v2_t
);
13035 case OPC_PRECEQ_PW_QHLA
:
13037 gen_helper_preceq_pw_qhla(cpu_gpr
[ret
], v2_t
);
13039 case OPC_PRECEQ_PW_QHRA
:
13041 gen_helper_preceq_pw_qhra(cpu_gpr
[ret
], v2_t
);
13043 case OPC_PRECEQU_QH_OBL
:
13045 gen_helper_precequ_qh_obl(cpu_gpr
[ret
], v2_t
);
13047 case OPC_PRECEQU_QH_OBR
:
13049 gen_helper_precequ_qh_obr(cpu_gpr
[ret
], v2_t
);
13051 case OPC_PRECEQU_QH_OBLA
:
13053 gen_helper_precequ_qh_obla(cpu_gpr
[ret
], v2_t
);
13055 case OPC_PRECEQU_QH_OBRA
:
13057 gen_helper_precequ_qh_obra(cpu_gpr
[ret
], v2_t
);
13059 case OPC_PRECEU_QH_OBL
:
13061 gen_helper_preceu_qh_obl(cpu_gpr
[ret
], v2_t
);
13063 case OPC_PRECEU_QH_OBR
:
13065 gen_helper_preceu_qh_obr(cpu_gpr
[ret
], v2_t
);
13067 case OPC_PRECEU_QH_OBLA
:
13069 gen_helper_preceu_qh_obla(cpu_gpr
[ret
], v2_t
);
13071 case OPC_PRECEU_QH_OBRA
:
13073 gen_helper_preceu_qh_obra(cpu_gpr
[ret
], v2_t
);
13075 case OPC_ABSQ_S_OB
:
13077 gen_helper_absq_s_ob(cpu_gpr
[ret
], v2_t
, cpu_env
);
13079 case OPC_ABSQ_S_PW
:
13081 gen_helper_absq_s_pw(cpu_gpr
[ret
], v2_t
, cpu_env
);
13083 case OPC_ABSQ_S_QH
:
13085 gen_helper_absq_s_qh(cpu_gpr
[ret
], v2_t
, cpu_env
);
13089 case OPC_ADDU_OB_DSP
:
13091 case OPC_RADDU_L_OB
:
13093 gen_helper_raddu_l_ob(cpu_gpr
[ret
], v1_t
);
13097 gen_helper_subq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13099 case OPC_SUBQ_S_PW
:
13101 gen_helper_subq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13105 gen_helper_subq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13107 case OPC_SUBQ_S_QH
:
13109 gen_helper_subq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13113 gen_helper_subu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13115 case OPC_SUBU_S_OB
:
13117 gen_helper_subu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13121 gen_helper_subu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13123 case OPC_SUBU_S_QH
:
13125 gen_helper_subu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13129 gen_helper_subuh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13131 case OPC_SUBUH_R_OB
:
13133 gen_helper_subuh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13137 gen_helper_addq_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13139 case OPC_ADDQ_S_PW
:
13141 gen_helper_addq_s_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13145 gen_helper_addq_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13147 case OPC_ADDQ_S_QH
:
13149 gen_helper_addq_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13153 gen_helper_addu_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13155 case OPC_ADDU_S_OB
:
13157 gen_helper_addu_s_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13161 gen_helper_addu_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13163 case OPC_ADDU_S_QH
:
13165 gen_helper_addu_s_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13169 gen_helper_adduh_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13171 case OPC_ADDUH_R_OB
:
13173 gen_helper_adduh_r_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
13177 case OPC_CMPU_EQ_OB_DSP
:
13179 case OPC_PRECR_OB_QH
:
13181 gen_helper_precr_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13183 case OPC_PRECR_SRA_QH_PW
:
13186 TCGv_i32 ret_t
= tcg_const_i32(ret
);
13187 gen_helper_precr_sra_qh_pw(v2_t
, v1_t
, v2_t
, ret_t
);
13188 tcg_temp_free_i32(ret_t
);
13191 case OPC_PRECR_SRA_R_QH_PW
:
13194 TCGv_i32 sa_v
= tcg_const_i32(ret
);
13195 gen_helper_precr_sra_r_qh_pw(v2_t
, v1_t
, v2_t
, sa_v
);
13196 tcg_temp_free_i32(sa_v
);
13199 case OPC_PRECRQ_OB_QH
:
13201 gen_helper_precrq_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
);
13203 case OPC_PRECRQ_PW_L
:
13205 gen_helper_precrq_pw_l(cpu_gpr
[ret
], v1_t
, v2_t
);
13207 case OPC_PRECRQ_QH_PW
:
13209 gen_helper_precrq_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
13211 case OPC_PRECRQ_RS_QH_PW
:
13213 gen_helper_precrq_rs_qh_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13215 case OPC_PRECRQU_S_OB_QH
:
13217 gen_helper_precrqu_s_ob_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13224 tcg_temp_free(v1_t
);
13225 tcg_temp_free(v2_t
);
13227 (void)opn
; /* avoid a compiler warning */
13228 MIPS_DEBUG("%s", opn
);
13231 static void gen_mipsdsp_shift(DisasContext
*ctx
, uint32_t opc
,
13232 int ret
, int v1
, int v2
)
13235 const char *opn
= "mipsdsp shift";
13241 /* Treat as NOP. */
13246 t0
= tcg_temp_new();
13247 v1_t
= tcg_temp_new();
13248 v2_t
= tcg_temp_new();
13250 tcg_gen_movi_tl(t0
, v1
);
13251 gen_load_gpr(v1_t
, v1
);
13252 gen_load_gpr(v2_t
, v2
);
13255 case OPC_SHLL_QB_DSP
:
13257 op2
= MASK_SHLL_QB(ctx
->opcode
);
13261 gen_helper_shll_qb(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13265 gen_helper_shll_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13269 gen_helper_shll_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13273 gen_helper_shll_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13275 case OPC_SHLL_S_PH
:
13277 gen_helper_shll_s_ph(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13279 case OPC_SHLLV_S_PH
:
13281 gen_helper_shll_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13285 gen_helper_shll_s_w(cpu_gpr
[ret
], t0
, v2_t
, cpu_env
);
13287 case OPC_SHLLV_S_W
:
13289 gen_helper_shll_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13293 gen_helper_shrl_qb(cpu_gpr
[ret
], t0
, v2_t
);
13297 gen_helper_shrl_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13301 gen_helper_shrl_ph(cpu_gpr
[ret
], t0
, v2_t
);
13305 gen_helper_shrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13309 gen_helper_shra_qb(cpu_gpr
[ret
], t0
, v2_t
);
13311 case OPC_SHRA_R_QB
:
13313 gen_helper_shra_r_qb(cpu_gpr
[ret
], t0
, v2_t
);
13317 gen_helper_shra_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13319 case OPC_SHRAV_R_QB
:
13321 gen_helper_shra_r_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13325 gen_helper_shra_ph(cpu_gpr
[ret
], t0
, v2_t
);
13327 case OPC_SHRA_R_PH
:
13329 gen_helper_shra_r_ph(cpu_gpr
[ret
], t0
, v2_t
);
13333 gen_helper_shra_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13335 case OPC_SHRAV_R_PH
:
13337 gen_helper_shra_r_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
13341 gen_helper_shra_r_w(cpu_gpr
[ret
], t0
, v2_t
);
13343 case OPC_SHRAV_R_W
:
13345 gen_helper_shra_r_w(cpu_gpr
[ret
], v1_t
, v2_t
);
13347 default: /* Invalid */
13348 MIPS_INVAL("MASK SHLL.QB");
13349 generate_exception(ctx
, EXCP_RI
);
13354 #ifdef TARGET_MIPS64
13355 case OPC_SHLL_OB_DSP
:
13356 op2
= MASK_SHLL_OB(ctx
->opcode
);
13360 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13364 gen_helper_shll_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13366 case OPC_SHLL_S_PW
:
13368 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13370 case OPC_SHLLV_S_PW
:
13372 gen_helper_shll_s_pw(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13376 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13380 gen_helper_shll_ob(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13384 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13388 gen_helper_shll_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13390 case OPC_SHLL_S_QH
:
13392 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, t0
, cpu_env
);
13394 case OPC_SHLLV_S_QH
:
13396 gen_helper_shll_s_qh(cpu_gpr
[ret
], v2_t
, v1_t
, cpu_env
);
13400 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, t0
);
13404 gen_helper_shra_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13406 case OPC_SHRA_R_OB
:
13408 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, t0
);
13410 case OPC_SHRAV_R_OB
:
13412 gen_helper_shra_r_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13416 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, t0
);
13420 gen_helper_shra_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13422 case OPC_SHRA_R_PW
:
13424 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, t0
);
13426 case OPC_SHRAV_R_PW
:
13428 gen_helper_shra_r_pw(cpu_gpr
[ret
], v2_t
, v1_t
);
13432 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, t0
);
13436 gen_helper_shra_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13438 case OPC_SHRA_R_QH
:
13440 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, t0
);
13442 case OPC_SHRAV_R_QH
:
13444 gen_helper_shra_r_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13448 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, t0
);
13452 gen_helper_shrl_ob(cpu_gpr
[ret
], v2_t
, v1_t
);
13456 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, t0
);
13460 gen_helper_shrl_qh(cpu_gpr
[ret
], v2_t
, v1_t
);
13462 default: /* Invalid */
13463 MIPS_INVAL("MASK SHLL.OB");
13464 generate_exception(ctx
, EXCP_RI
);
13472 tcg_temp_free(v1_t
);
13473 tcg_temp_free(v2_t
);
13474 (void)opn
; /* avoid a compiler warning */
13475 MIPS_DEBUG("%s", opn
);
13478 static void gen_mipsdsp_multiply(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13479 int ret
, int v1
, int v2
, int check_ret
)
13481 const char *opn
= "mipsdsp multiply";
13486 if ((ret
== 0) && (check_ret
== 1)) {
13487 /* Treat as NOP. */
13492 t0
= tcg_temp_new_i32();
13493 v1_t
= tcg_temp_new();
13494 v2_t
= tcg_temp_new();
13496 tcg_gen_movi_i32(t0
, ret
);
13497 gen_load_gpr(v1_t
, v1
);
13498 gen_load_gpr(v2_t
, v2
);
13501 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13502 * the same mask and op1. */
13503 case OPC_MULT_G_2E
:
13507 gen_helper_mul_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13510 gen_helper_mul_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13513 gen_helper_mulq_s_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13515 case OPC_MULQ_RS_W
:
13516 gen_helper_mulq_rs_w(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13520 case OPC_DPA_W_PH_DSP
:
13522 case OPC_DPAU_H_QBL
:
13524 gen_helper_dpau_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13526 case OPC_DPAU_H_QBR
:
13528 gen_helper_dpau_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13530 case OPC_DPSU_H_QBL
:
13532 gen_helper_dpsu_h_qbl(t0
, v1_t
, v2_t
, cpu_env
);
13534 case OPC_DPSU_H_QBR
:
13536 gen_helper_dpsu_h_qbr(t0
, v1_t
, v2_t
, cpu_env
);
13540 gen_helper_dpa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13542 case OPC_DPAX_W_PH
:
13544 gen_helper_dpax_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13546 case OPC_DPAQ_S_W_PH
:
13548 gen_helper_dpaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13550 case OPC_DPAQX_S_W_PH
:
13552 gen_helper_dpaqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13554 case OPC_DPAQX_SA_W_PH
:
13556 gen_helper_dpaqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13560 gen_helper_dps_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13562 case OPC_DPSX_W_PH
:
13564 gen_helper_dpsx_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13566 case OPC_DPSQ_S_W_PH
:
13568 gen_helper_dpsq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13570 case OPC_DPSQX_S_W_PH
:
13572 gen_helper_dpsqx_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13574 case OPC_DPSQX_SA_W_PH
:
13576 gen_helper_dpsqx_sa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13578 case OPC_MULSAQ_S_W_PH
:
13580 gen_helper_mulsaq_s_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13582 case OPC_DPAQ_SA_L_W
:
13584 gen_helper_dpaq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13586 case OPC_DPSQ_SA_L_W
:
13588 gen_helper_dpsq_sa_l_w(t0
, v1_t
, v2_t
, cpu_env
);
13590 case OPC_MAQ_S_W_PHL
:
13592 gen_helper_maq_s_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13594 case OPC_MAQ_S_W_PHR
:
13596 gen_helper_maq_s_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13598 case OPC_MAQ_SA_W_PHL
:
13600 gen_helper_maq_sa_w_phl(t0
, v1_t
, v2_t
, cpu_env
);
13602 case OPC_MAQ_SA_W_PHR
:
13604 gen_helper_maq_sa_w_phr(t0
, v1_t
, v2_t
, cpu_env
);
13606 case OPC_MULSA_W_PH
:
13608 gen_helper_mulsa_w_ph(t0
, v1_t
, v2_t
, cpu_env
);
13612 #ifdef TARGET_MIPS64
13613 case OPC_DPAQ_W_QH_DSP
:
13615 int ac
= ret
& 0x03;
13616 tcg_gen_movi_i32(t0
, ac
);
13621 gen_helper_dmadd(v1_t
, v2_t
, t0
, cpu_env
);
13625 gen_helper_dmaddu(v1_t
, v2_t
, t0
, cpu_env
);
13629 gen_helper_dmsub(v1_t
, v2_t
, t0
, cpu_env
);
13633 gen_helper_dmsubu(v1_t
, v2_t
, t0
, cpu_env
);
13637 gen_helper_dpa_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13639 case OPC_DPAQ_S_W_QH
:
13641 gen_helper_dpaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13643 case OPC_DPAQ_SA_L_PW
:
13645 gen_helper_dpaq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13647 case OPC_DPAU_H_OBL
:
13649 gen_helper_dpau_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13651 case OPC_DPAU_H_OBR
:
13653 gen_helper_dpau_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13657 gen_helper_dps_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13659 case OPC_DPSQ_S_W_QH
:
13661 gen_helper_dpsq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13663 case OPC_DPSQ_SA_L_PW
:
13665 gen_helper_dpsq_sa_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13667 case OPC_DPSU_H_OBL
:
13669 gen_helper_dpsu_h_obl(v1_t
, v2_t
, t0
, cpu_env
);
13671 case OPC_DPSU_H_OBR
:
13673 gen_helper_dpsu_h_obr(v1_t
, v2_t
, t0
, cpu_env
);
13675 case OPC_MAQ_S_L_PWL
:
13677 gen_helper_maq_s_l_pwl(v1_t
, v2_t
, t0
, cpu_env
);
13679 case OPC_MAQ_S_L_PWR
:
13681 gen_helper_maq_s_l_pwr(v1_t
, v2_t
, t0
, cpu_env
);
13683 case OPC_MAQ_S_W_QHLL
:
13685 gen_helper_maq_s_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13687 case OPC_MAQ_SA_W_QHLL
:
13689 gen_helper_maq_sa_w_qhll(v1_t
, v2_t
, t0
, cpu_env
);
13691 case OPC_MAQ_S_W_QHLR
:
13693 gen_helper_maq_s_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13695 case OPC_MAQ_SA_W_QHLR
:
13697 gen_helper_maq_sa_w_qhlr(v1_t
, v2_t
, t0
, cpu_env
);
13699 case OPC_MAQ_S_W_QHRL
:
13701 gen_helper_maq_s_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13703 case OPC_MAQ_SA_W_QHRL
:
13705 gen_helper_maq_sa_w_qhrl(v1_t
, v2_t
, t0
, cpu_env
);
13707 case OPC_MAQ_S_W_QHRR
:
13709 gen_helper_maq_s_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13711 case OPC_MAQ_SA_W_QHRR
:
13713 gen_helper_maq_sa_w_qhrr(v1_t
, v2_t
, t0
, cpu_env
);
13715 case OPC_MULSAQ_S_L_PW
:
13717 gen_helper_mulsaq_s_l_pw(v1_t
, v2_t
, t0
, cpu_env
);
13719 case OPC_MULSAQ_S_W_QH
:
13721 gen_helper_mulsaq_s_w_qh(v1_t
, v2_t
, t0
, cpu_env
);
13727 case OPC_ADDU_QB_DSP
:
13729 case OPC_MULEU_S_PH_QBL
:
13731 gen_helper_muleu_s_ph_qbl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13733 case OPC_MULEU_S_PH_QBR
:
13735 gen_helper_muleu_s_ph_qbr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13737 case OPC_MULQ_RS_PH
:
13739 gen_helper_mulq_rs_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13741 case OPC_MULEQ_S_W_PHL
:
13743 gen_helper_muleq_s_w_phl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13745 case OPC_MULEQ_S_W_PHR
:
13747 gen_helper_muleq_s_w_phr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13749 case OPC_MULQ_S_PH
:
13751 gen_helper_mulq_s_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13755 #ifdef TARGET_MIPS64
13756 case OPC_ADDU_OB_DSP
:
13758 case OPC_MULEQ_S_PW_QHL
:
13760 gen_helper_muleq_s_pw_qhl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13762 case OPC_MULEQ_S_PW_QHR
:
13764 gen_helper_muleq_s_pw_qhr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13766 case OPC_MULEU_S_QH_OBL
:
13768 gen_helper_muleu_s_qh_obl(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13770 case OPC_MULEU_S_QH_OBR
:
13772 gen_helper_muleu_s_qh_obr(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13774 case OPC_MULQ_RS_QH
:
13776 gen_helper_mulq_rs_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
13783 tcg_temp_free_i32(t0
);
13784 tcg_temp_free(v1_t
);
13785 tcg_temp_free(v2_t
);
13787 (void)opn
; /* avoid a compiler warning */
13788 MIPS_DEBUG("%s", opn
);
13792 static void gen_mipsdsp_bitinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
13795 const char *opn
= "mipsdsp Bit/ Manipulation";
13801 /* Treat as NOP. */
13806 t0
= tcg_temp_new();
13807 val_t
= tcg_temp_new();
13808 gen_load_gpr(val_t
, val
);
13811 case OPC_ABSQ_S_PH_DSP
:
13815 gen_helper_bitrev(cpu_gpr
[ret
], val_t
);
13820 target_long result
;
13821 imm
= (ctx
->opcode
>> 16) & 0xFF;
13822 result
= (uint32_t)imm
<< 24 |
13823 (uint32_t)imm
<< 16 |
13824 (uint32_t)imm
<< 8 |
13826 result
= (int32_t)result
;
13827 tcg_gen_movi_tl(cpu_gpr
[ret
], result
);
13832 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13833 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13834 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13835 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13836 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13837 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13842 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13843 imm
= (int16_t)(imm
<< 6) >> 6;
13844 tcg_gen_movi_tl(cpu_gpr
[ret
], \
13845 (target_long
)((int32_t)imm
<< 16 | \
13851 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13852 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13853 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13854 tcg_gen_ext32s_tl(cpu_gpr
[ret
], cpu_gpr
[ret
]);
13858 #ifdef TARGET_MIPS64
13859 case OPC_ABSQ_S_QH_DSP
:
13866 imm
= (ctx
->opcode
>> 16) & 0xFF;
13867 temp
= ((uint64_t)imm
<< 8) | (uint64_t)imm
;
13868 temp
= (temp
<< 16) | temp
;
13869 temp
= (temp
<< 32) | temp
;
13870 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13878 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13879 imm
= (int16_t)(imm
<< 6) >> 6;
13880 temp
= ((target_long
)imm
<< 32) \
13881 | ((target_long
)imm
& 0xFFFFFFFF);
13882 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13890 imm
= (ctx
->opcode
>> 16) & 0x03FF;
13891 imm
= (int16_t)(imm
<< 6) >> 6;
13893 temp
= ((uint64_t)(uint16_t)imm
<< 48) |
13894 ((uint64_t)(uint16_t)imm
<< 32) |
13895 ((uint64_t)(uint16_t)imm
<< 16) |
13896 (uint64_t)(uint16_t)imm
;
13897 tcg_gen_movi_tl(cpu_gpr
[ret
], temp
);
13902 tcg_gen_ext8u_tl(cpu_gpr
[ret
], val_t
);
13903 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 8);
13904 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13905 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13906 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13907 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13908 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13912 tcg_gen_ext32u_i64(cpu_gpr
[ret
], val_t
);
13913 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13914 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13918 tcg_gen_ext16u_tl(cpu_gpr
[ret
], val_t
);
13919 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 16);
13920 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13921 tcg_gen_shli_tl(t0
, cpu_gpr
[ret
], 32);
13922 tcg_gen_or_tl(cpu_gpr
[ret
], cpu_gpr
[ret
], t0
);
13929 tcg_temp_free(val_t
);
13931 (void)opn
; /* avoid a compiler warning */
13932 MIPS_DEBUG("%s", opn
);
13935 static void gen_mipsdsp_add_cmp_pick(DisasContext
*ctx
,
13936 uint32_t op1
, uint32_t op2
,
13937 int ret
, int v1
, int v2
, int check_ret
)
13939 const char *opn
= "mipsdsp add compare pick";
13944 if ((ret
== 0) && (check_ret
== 1)) {
13945 /* Treat as NOP. */
13950 t1
= tcg_temp_new();
13951 v1_t
= tcg_temp_new();
13952 v2_t
= tcg_temp_new();
13954 gen_load_gpr(v1_t
, v1
);
13955 gen_load_gpr(v2_t
, v2
);
13958 case OPC_CMPU_EQ_QB_DSP
:
13960 case OPC_CMPU_EQ_QB
:
13962 gen_helper_cmpu_eq_qb(v1_t
, v2_t
, cpu_env
);
13964 case OPC_CMPU_LT_QB
:
13966 gen_helper_cmpu_lt_qb(v1_t
, v2_t
, cpu_env
);
13968 case OPC_CMPU_LE_QB
:
13970 gen_helper_cmpu_le_qb(v1_t
, v2_t
, cpu_env
);
13972 case OPC_CMPGU_EQ_QB
:
13974 gen_helper_cmpgu_eq_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13976 case OPC_CMPGU_LT_QB
:
13978 gen_helper_cmpgu_lt_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13980 case OPC_CMPGU_LE_QB
:
13982 gen_helper_cmpgu_le_qb(cpu_gpr
[ret
], v1_t
, v2_t
);
13984 case OPC_CMPGDU_EQ_QB
:
13986 gen_helper_cmpgu_eq_qb(t1
, v1_t
, v2_t
);
13987 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13988 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13989 tcg_gen_shli_tl(t1
, t1
, 24);
13990 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
13992 case OPC_CMPGDU_LT_QB
:
13994 gen_helper_cmpgu_lt_qb(t1
, v1_t
, v2_t
);
13995 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
13996 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
13997 tcg_gen_shli_tl(t1
, t1
, 24);
13998 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14000 case OPC_CMPGDU_LE_QB
:
14002 gen_helper_cmpgu_le_qb(t1
, v1_t
, v2_t
);
14003 tcg_gen_mov_tl(cpu_gpr
[ret
], t1
);
14004 tcg_gen_andi_tl(cpu_dspctrl
, cpu_dspctrl
, 0xF0FFFFFF);
14005 tcg_gen_shli_tl(t1
, t1
, 24);
14006 tcg_gen_or_tl(cpu_dspctrl
, cpu_dspctrl
, t1
);
14008 case OPC_CMP_EQ_PH
:
14010 gen_helper_cmp_eq_ph(v1_t
, v2_t
, cpu_env
);
14012 case OPC_CMP_LT_PH
:
14014 gen_helper_cmp_lt_ph(v1_t
, v2_t
, cpu_env
);
14016 case OPC_CMP_LE_PH
:
14018 gen_helper_cmp_le_ph(v1_t
, v2_t
, cpu_env
);
14022 gen_helper_pick_qb(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14026 gen_helper_pick_ph(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14028 case OPC_PACKRL_PH
:
14030 gen_helper_packrl_ph(cpu_gpr
[ret
], v1_t
, v2_t
);
14034 #ifdef TARGET_MIPS64
14035 case OPC_CMPU_EQ_OB_DSP
:
14037 case OPC_CMP_EQ_PW
:
14039 gen_helper_cmp_eq_pw(v1_t
, v2_t
, cpu_env
);
14041 case OPC_CMP_LT_PW
:
14043 gen_helper_cmp_lt_pw(v1_t
, v2_t
, cpu_env
);
14045 case OPC_CMP_LE_PW
:
14047 gen_helper_cmp_le_pw(v1_t
, v2_t
, cpu_env
);
14049 case OPC_CMP_EQ_QH
:
14051 gen_helper_cmp_eq_qh(v1_t
, v2_t
, cpu_env
);
14053 case OPC_CMP_LT_QH
:
14055 gen_helper_cmp_lt_qh(v1_t
, v2_t
, cpu_env
);
14057 case OPC_CMP_LE_QH
:
14059 gen_helper_cmp_le_qh(v1_t
, v2_t
, cpu_env
);
14061 case OPC_CMPGDU_EQ_OB
:
14063 gen_helper_cmpgdu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14065 case OPC_CMPGDU_LT_OB
:
14067 gen_helper_cmpgdu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14069 case OPC_CMPGDU_LE_OB
:
14071 gen_helper_cmpgdu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14073 case OPC_CMPGU_EQ_OB
:
14075 gen_helper_cmpgu_eq_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14077 case OPC_CMPGU_LT_OB
:
14079 gen_helper_cmpgu_lt_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14081 case OPC_CMPGU_LE_OB
:
14083 gen_helper_cmpgu_le_ob(cpu_gpr
[ret
], v1_t
, v2_t
);
14085 case OPC_CMPU_EQ_OB
:
14087 gen_helper_cmpu_eq_ob(v1_t
, v2_t
, cpu_env
);
14089 case OPC_CMPU_LT_OB
:
14091 gen_helper_cmpu_lt_ob(v1_t
, v2_t
, cpu_env
);
14093 case OPC_CMPU_LE_OB
:
14095 gen_helper_cmpu_le_ob(v1_t
, v2_t
, cpu_env
);
14097 case OPC_PACKRL_PW
:
14099 gen_helper_packrl_pw(cpu_gpr
[ret
], v1_t
, v2_t
);
14103 gen_helper_pick_ob(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14107 gen_helper_pick_pw(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14111 gen_helper_pick_qh(cpu_gpr
[ret
], v1_t
, v2_t
, cpu_env
);
14119 tcg_temp_free(v1_t
);
14120 tcg_temp_free(v2_t
);
14122 (void)opn
; /* avoid a compiler warning */
14123 MIPS_DEBUG("%s", opn
);
14126 static void gen_mipsdsp_append(CPUMIPSState
*env
, DisasContext
*ctx
,
14127 uint32_t op1
, int rt
, int rs
, int sa
)
14129 const char *opn
= "mipsdsp append/dappend";
14135 /* Treat as NOP. */
14140 t0
= tcg_temp_new();
14141 gen_load_gpr(t0
, rs
);
14144 case OPC_APPEND_DSP
:
14145 switch (MASK_APPEND(ctx
->opcode
)) {
14148 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 32 - sa
);
14150 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14154 tcg_gen_ext32u_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14155 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14156 tcg_gen_shli_tl(t0
, t0
, 32 - sa
);
14157 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14159 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14163 if (sa
!= 0 && sa
!= 2) {
14164 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14165 tcg_gen_ext32u_tl(t0
, t0
);
14166 tcg_gen_shri_tl(t0
, t0
, 8 * (4 - sa
));
14167 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14169 tcg_gen_ext32s_tl(cpu_gpr
[rt
], cpu_gpr
[rt
]);
14171 default: /* Invalid */
14172 MIPS_INVAL("MASK APPEND");
14173 generate_exception(ctx
, EXCP_RI
);
14177 #ifdef TARGET_MIPS64
14178 case OPC_DAPPEND_DSP
:
14179 switch (MASK_DAPPEND(ctx
->opcode
)) {
14182 tcg_gen_deposit_tl(cpu_gpr
[rt
], t0
, cpu_gpr
[rt
], sa
, 64 - sa
);
14186 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 0x20 | sa
);
14187 tcg_gen_shli_tl(t0
, t0
, 64 - (0x20 | sa
));
14188 tcg_gen_or_tl(cpu_gpr
[rt
], t0
, t0
);
14192 tcg_gen_shri_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], sa
);
14193 tcg_gen_shli_tl(t0
, t0
, 64 - sa
);
14194 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14199 if (sa
!= 0 && sa
!= 2 && sa
!= 4) {
14200 tcg_gen_shli_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], 8 * sa
);
14201 tcg_gen_shri_tl(t0
, t0
, 8 * (8 - sa
));
14202 tcg_gen_or_tl(cpu_gpr
[rt
], cpu_gpr
[rt
], t0
);
14205 default: /* Invalid */
14206 MIPS_INVAL("MASK DAPPEND");
14207 generate_exception(ctx
, EXCP_RI
);
14214 (void)opn
; /* avoid a compiler warning */
14215 MIPS_DEBUG("%s", opn
);
14218 static void gen_mipsdsp_accinsn(DisasContext
*ctx
, uint32_t op1
, uint32_t op2
,
14219 int ret
, int v1
, int v2
, int check_ret
)
14222 const char *opn
= "mipsdsp accumulator";
14229 if ((ret
== 0) && (check_ret
== 1)) {
14230 /* Treat as NOP. */
14235 t0
= tcg_temp_new();
14236 t1
= tcg_temp_new();
14237 v1_t
= tcg_temp_new();
14238 v2_t
= tcg_temp_new();
14240 gen_load_gpr(v1_t
, v1
);
14241 gen_load_gpr(v2_t
, v2
);
14244 case OPC_EXTR_W_DSP
:
14248 tcg_gen_movi_tl(t0
, v2
);
14249 tcg_gen_movi_tl(t1
, v1
);
14250 gen_helper_extr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14253 tcg_gen_movi_tl(t0
, v2
);
14254 tcg_gen_movi_tl(t1
, v1
);
14255 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14257 case OPC_EXTR_RS_W
:
14258 tcg_gen_movi_tl(t0
, v2
);
14259 tcg_gen_movi_tl(t1
, v1
);
14260 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14263 tcg_gen_movi_tl(t0
, v2
);
14264 tcg_gen_movi_tl(t1
, v1
);
14265 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14267 case OPC_EXTRV_S_H
:
14268 tcg_gen_movi_tl(t0
, v2
);
14269 gen_helper_extr_s_h(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14272 tcg_gen_movi_tl(t0
, v2
);
14273 gen_helper_extr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14275 case OPC_EXTRV_R_W
:
14276 tcg_gen_movi_tl(t0
, v2
);
14277 gen_helper_extr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14279 case OPC_EXTRV_RS_W
:
14280 tcg_gen_movi_tl(t0
, v2
);
14281 gen_helper_extr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14284 tcg_gen_movi_tl(t0
, v2
);
14285 tcg_gen_movi_tl(t1
, v1
);
14286 gen_helper_extp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14289 tcg_gen_movi_tl(t0
, v2
);
14290 gen_helper_extp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14293 tcg_gen_movi_tl(t0
, v2
);
14294 tcg_gen_movi_tl(t1
, v1
);
14295 gen_helper_extpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14298 tcg_gen_movi_tl(t0
, v2
);
14299 gen_helper_extpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14302 imm
= (ctx
->opcode
>> 20) & 0x3F;
14303 tcg_gen_movi_tl(t0
, ret
);
14304 tcg_gen_movi_tl(t1
, imm
);
14305 gen_helper_shilo(t0
, t1
, cpu_env
);
14308 tcg_gen_movi_tl(t0
, ret
);
14309 gen_helper_shilo(t0
, v1_t
, cpu_env
);
14312 tcg_gen_movi_tl(t0
, ret
);
14313 gen_helper_mthlip(t0
, v1_t
, cpu_env
);
14316 imm
= (ctx
->opcode
>> 11) & 0x3FF;
14317 tcg_gen_movi_tl(t0
, imm
);
14318 gen_helper_wrdsp(v1_t
, t0
, cpu_env
);
14321 imm
= (ctx
->opcode
>> 16) & 0x03FF;
14322 tcg_gen_movi_tl(t0
, imm
);
14323 gen_helper_rddsp(cpu_gpr
[ret
], t0
, cpu_env
);
14327 #ifdef TARGET_MIPS64
14328 case OPC_DEXTR_W_DSP
:
14332 tcg_gen_movi_tl(t0
, ret
);
14333 gen_helper_dmthlip(v1_t
, t0
, cpu_env
);
14337 int shift
= (ctx
->opcode
>> 19) & 0x7F;
14338 int ac
= (ctx
->opcode
>> 11) & 0x03;
14339 tcg_gen_movi_tl(t0
, shift
);
14340 tcg_gen_movi_tl(t1
, ac
);
14341 gen_helper_dshilo(t0
, t1
, cpu_env
);
14346 int ac
= (ctx
->opcode
>> 11) & 0x03;
14347 tcg_gen_movi_tl(t0
, ac
);
14348 gen_helper_dshilo(v1_t
, t0
, cpu_env
);
14352 tcg_gen_movi_tl(t0
, v2
);
14353 tcg_gen_movi_tl(t1
, v1
);
14355 gen_helper_dextp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14358 tcg_gen_movi_tl(t0
, v2
);
14359 gen_helper_dextp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14362 tcg_gen_movi_tl(t0
, v2
);
14363 tcg_gen_movi_tl(t1
, v1
);
14364 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14367 tcg_gen_movi_tl(t0
, v2
);
14368 gen_helper_dextpdp(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14371 tcg_gen_movi_tl(t0
, v2
);
14372 tcg_gen_movi_tl(t1
, v1
);
14373 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14375 case OPC_DEXTR_R_L
:
14376 tcg_gen_movi_tl(t0
, v2
);
14377 tcg_gen_movi_tl(t1
, v1
);
14378 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14380 case OPC_DEXTR_RS_L
:
14381 tcg_gen_movi_tl(t0
, v2
);
14382 tcg_gen_movi_tl(t1
, v1
);
14383 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14386 tcg_gen_movi_tl(t0
, v2
);
14387 tcg_gen_movi_tl(t1
, v1
);
14388 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14390 case OPC_DEXTR_R_W
:
14391 tcg_gen_movi_tl(t0
, v2
);
14392 tcg_gen_movi_tl(t1
, v1
);
14393 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14395 case OPC_DEXTR_RS_W
:
14396 tcg_gen_movi_tl(t0
, v2
);
14397 tcg_gen_movi_tl(t1
, v1
);
14398 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14400 case OPC_DEXTR_S_H
:
14401 tcg_gen_movi_tl(t0
, v2
);
14402 tcg_gen_movi_tl(t1
, v1
);
14403 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14405 case OPC_DEXTRV_S_H
:
14406 tcg_gen_movi_tl(t0
, v2
);
14407 tcg_gen_movi_tl(t1
, v1
);
14408 gen_helper_dextr_s_h(cpu_gpr
[ret
], t0
, t1
, cpu_env
);
14411 tcg_gen_movi_tl(t0
, v2
);
14412 gen_helper_dextr_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14414 case OPC_DEXTRV_R_L
:
14415 tcg_gen_movi_tl(t0
, v2
);
14416 gen_helper_dextr_r_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14418 case OPC_DEXTRV_RS_L
:
14419 tcg_gen_movi_tl(t0
, v2
);
14420 gen_helper_dextr_rs_l(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14423 tcg_gen_movi_tl(t0
, v2
);
14424 gen_helper_dextr_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14426 case OPC_DEXTRV_R_W
:
14427 tcg_gen_movi_tl(t0
, v2
);
14428 gen_helper_dextr_r_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14430 case OPC_DEXTRV_RS_W
:
14431 tcg_gen_movi_tl(t0
, v2
);
14432 gen_helper_dextr_rs_w(cpu_gpr
[ret
], t0
, v1_t
, cpu_env
);
14441 tcg_temp_free(v1_t
);
14442 tcg_temp_free(v2_t
);
14444 (void)opn
; /* avoid a compiler warning */
14445 MIPS_DEBUG("%s", opn
);
14448 /* End MIPSDSP functions. */
14450 static void decode_opc (CPUMIPSState
*env
, DisasContext
*ctx
)
14453 int rs
, rt
, rd
, sa
;
14454 uint32_t op
, op1
, op2
;
14457 /* make sure instructions are on a word boundary */
14458 if (ctx
->pc
& 0x3) {
14459 env
->CP0_BadVAddr
= ctx
->pc
;
14460 generate_exception(ctx
, EXCP_AdEL
);
14464 /* Handle blikely not taken case */
14465 if ((ctx
->hflags
& MIPS_HFLAG_BMASK_BASE
) == MIPS_HFLAG_BL
) {
14466 int l1
= gen_new_label();
14468 MIPS_DEBUG("blikely condition (" TARGET_FMT_lx
")", ctx
->pc
+ 4);
14469 tcg_gen_brcondi_tl(TCG_COND_NE
, bcond
, 0, l1
);
14470 tcg_gen_movi_i32(hflags
, ctx
->hflags
& ~MIPS_HFLAG_BMASK
);
14471 gen_goto_tb(ctx
, 1, ctx
->pc
+ 4);
14475 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP
| CPU_LOG_TB_OP_OPT
))) {
14476 tcg_gen_debug_insn_start(ctx
->pc
);
14479 op
= MASK_OP_MAJOR(ctx
->opcode
);
14480 rs
= (ctx
->opcode
>> 21) & 0x1f;
14481 rt
= (ctx
->opcode
>> 16) & 0x1f;
14482 rd
= (ctx
->opcode
>> 11) & 0x1f;
14483 sa
= (ctx
->opcode
>> 6) & 0x1f;
14484 imm
= (int16_t)ctx
->opcode
;
14487 op1
= MASK_SPECIAL(ctx
->opcode
);
14489 case OPC_SLL
: /* Shift with immediate */
14491 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14494 switch ((ctx
->opcode
>> 21) & 0x1f) {
14496 /* rotr is decoded as srl on non-R2 CPUs */
14497 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14502 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14505 generate_exception(ctx
, EXCP_RI
);
14509 case OPC_MOVN
: /* Conditional move */
14511 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
|
14512 INSN_LOONGSON2E
| INSN_LOONGSON2F
);
14513 gen_cond_move(ctx
, op1
, rd
, rs
, rt
);
14515 case OPC_ADD
... OPC_SUBU
:
14516 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14518 case OPC_SLLV
: /* Shifts */
14520 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14523 switch ((ctx
->opcode
>> 6) & 0x1f) {
14525 /* rotrv is decoded as srlv on non-R2 CPUs */
14526 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14531 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14534 generate_exception(ctx
, EXCP_RI
);
14538 case OPC_SLT
: /* Set on less than */
14540 gen_slt(ctx
, op1
, rd
, rs
, rt
);
14542 case OPC_AND
: /* Logic*/
14546 gen_logic(ctx
, op1
, rd
, rs
, rt
);
14551 check_insn(ctx
, INSN_VR54XX
);
14552 op1
= MASK_MUL_VR54XX(ctx
->opcode
);
14553 gen_mul_vr54xx(ctx
, op1
, rd
, rs
, rt
);
14555 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14560 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14562 case OPC_JR
... OPC_JALR
:
14563 gen_compute_branch(ctx
, op1
, 4, rs
, rd
, sa
);
14565 case OPC_TGE
... OPC_TEQ
: /* Traps */
14567 gen_trap(ctx
, op1
, rs
, rt
, -1);
14569 case OPC_MFHI
: /* Move from HI/LO */
14571 gen_HILO(ctx
, op1
, rs
& 3, rd
);
14574 case OPC_MTLO
: /* Move to HI/LO */
14575 gen_HILO(ctx
, op1
, rd
& 3, rs
);
14577 case OPC_PMON
: /* Pmon entry point, also R4010 selsl */
14578 #ifdef MIPS_STRICT_STANDARD
14579 MIPS_INVAL("PMON / selsl");
14580 generate_exception(ctx
, EXCP_RI
);
14582 gen_helper_0e0i(pmon
, sa
);
14586 generate_exception(ctx
, EXCP_SYSCALL
);
14587 ctx
->bstate
= BS_STOP
;
14590 generate_exception(ctx
, EXCP_BREAK
);
14593 #ifdef MIPS_STRICT_STANDARD
14594 MIPS_INVAL("SPIM");
14595 generate_exception(ctx
, EXCP_RI
);
14597 /* Implemented as RI exception for now. */
14598 MIPS_INVAL("spim (unofficial)");
14599 generate_exception(ctx
, EXCP_RI
);
14603 /* Treat as NOP. */
14607 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
14608 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
14609 check_cp1_enabled(ctx
);
14610 gen_movci(ctx
, rd
, rs
, (ctx
->opcode
>> 18) & 0x7,
14611 (ctx
->opcode
>> 16) & 1);
14613 generate_exception_err(ctx
, EXCP_CpU
, 1);
14617 #if defined(TARGET_MIPS64)
14618 /* MIPS64 specific opcodes */
14623 check_insn(ctx
, ISA_MIPS3
);
14624 check_mips_64(ctx
);
14625 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14628 switch ((ctx
->opcode
>> 21) & 0x1f) {
14630 /* drotr is decoded as dsrl on non-R2 CPUs */
14631 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14636 check_insn(ctx
, ISA_MIPS3
);
14637 check_mips_64(ctx
);
14638 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14641 generate_exception(ctx
, EXCP_RI
);
14646 switch ((ctx
->opcode
>> 21) & 0x1f) {
14648 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14649 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14654 check_insn(ctx
, ISA_MIPS3
);
14655 check_mips_64(ctx
);
14656 gen_shift_imm(ctx
, op1
, rd
, rt
, sa
);
14659 generate_exception(ctx
, EXCP_RI
);
14663 case OPC_DADD
... OPC_DSUBU
:
14664 check_insn(ctx
, ISA_MIPS3
);
14665 check_mips_64(ctx
);
14666 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14670 check_insn(ctx
, ISA_MIPS3
);
14671 check_mips_64(ctx
);
14672 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14675 switch ((ctx
->opcode
>> 6) & 0x1f) {
14677 /* drotrv is decoded as dsrlv on non-R2 CPUs */
14678 if (ctx
->insn_flags
& ISA_MIPS32R2
) {
14683 check_insn(ctx
, ISA_MIPS3
);
14684 check_mips_64(ctx
);
14685 gen_shift(ctx
, op1
, rd
, rs
, rt
);
14688 generate_exception(ctx
, EXCP_RI
);
14692 case OPC_DMULT
... OPC_DDIVU
:
14693 check_insn(ctx
, ISA_MIPS3
);
14694 check_mips_64(ctx
);
14695 gen_muldiv(ctx
, op1
, 0, rs
, rt
);
14698 default: /* Invalid */
14699 MIPS_INVAL("special");
14700 generate_exception(ctx
, EXCP_RI
);
14705 op1
= MASK_SPECIAL2(ctx
->opcode
);
14707 case OPC_MADD
... OPC_MADDU
: /* Multiply and add/sub */
14708 case OPC_MSUB
... OPC_MSUBU
:
14709 check_insn(ctx
, ISA_MIPS32
);
14710 gen_muldiv(ctx
, op1
, rd
& 3, rs
, rt
);
14713 gen_arith(ctx
, op1
, rd
, rs
, rt
);
14717 check_insn(ctx
, ISA_MIPS32
);
14718 gen_cl(ctx
, op1
, rd
, rs
);
14721 /* XXX: not clear which exception should be raised
14722 * when in debug mode...
14724 check_insn(ctx
, ISA_MIPS32
);
14725 if (!(ctx
->hflags
& MIPS_HFLAG_DM
)) {
14726 generate_exception(ctx
, EXCP_DBp
);
14728 generate_exception(ctx
, EXCP_DBp
);
14730 /* Treat as NOP. */
14733 case OPC_DIVU_G_2F
:
14734 case OPC_MULT_G_2F
:
14735 case OPC_MULTU_G_2F
:
14737 case OPC_MODU_G_2F
:
14738 check_insn(ctx
, INSN_LOONGSON2F
);
14739 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14741 #if defined(TARGET_MIPS64)
14744 check_insn(ctx
, ISA_MIPS64
);
14745 check_mips_64(ctx
);
14746 gen_cl(ctx
, op1
, rd
, rs
);
14748 case OPC_DMULT_G_2F
:
14749 case OPC_DMULTU_G_2F
:
14750 case OPC_DDIV_G_2F
:
14751 case OPC_DDIVU_G_2F
:
14752 case OPC_DMOD_G_2F
:
14753 case OPC_DMODU_G_2F
:
14754 check_insn(ctx
, INSN_LOONGSON2F
);
14755 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14758 default: /* Invalid */
14759 MIPS_INVAL("special2");
14760 generate_exception(ctx
, EXCP_RI
);
14765 op1
= MASK_SPECIAL3(ctx
->opcode
);
14769 check_insn(ctx
, ISA_MIPS32R2
);
14770 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
14773 check_insn(ctx
, ISA_MIPS32R2
);
14774 op2
= MASK_BSHFL(ctx
->opcode
);
14775 gen_bshfl(ctx
, op2
, rt
, rd
);
14778 gen_rdhwr(ctx
, rt
, rd
);
14781 check_insn(ctx
, ASE_MT
);
14783 TCGv t0
= tcg_temp_new();
14784 TCGv t1
= tcg_temp_new();
14786 gen_load_gpr(t0
, rt
);
14787 gen_load_gpr(t1
, rs
);
14788 gen_helper_fork(t0
, t1
);
14794 check_insn(ctx
, ASE_MT
);
14796 TCGv t0
= tcg_temp_new();
14798 save_cpu_state(ctx
, 1);
14799 gen_load_gpr(t0
, rs
);
14800 gen_helper_yield(t0
, cpu_env
, t0
);
14801 gen_store_gpr(t0
, rd
);
14805 case OPC_DIV_G_2E
... OPC_DIVU_G_2E
:
14806 case OPC_MOD_G_2E
... OPC_MODU_G_2E
:
14807 case OPC_MULT_G_2E
... OPC_MULTU_G_2E
:
14808 /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14809 * the same mask and op1. */
14810 if ((ctx
->insn_flags
& ASE_DSPR2
) && (op1
== OPC_MULT_G_2E
)) {
14811 op2
= MASK_ADDUH_QB(ctx
->opcode
);
14814 case OPC_ADDUH_R_QB
:
14816 case OPC_ADDQH_R_PH
:
14818 case OPC_ADDQH_R_W
:
14820 case OPC_SUBUH_R_QB
:
14822 case OPC_SUBQH_R_PH
:
14824 case OPC_SUBQH_R_W
:
14825 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14830 case OPC_MULQ_RS_W
:
14831 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14834 MIPS_INVAL("MASK ADDUH.QB");
14835 generate_exception(ctx
, EXCP_RI
);
14838 } else if (ctx
->insn_flags
& INSN_LOONGSON2E
) {
14839 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
14841 generate_exception(ctx
, EXCP_RI
);
14845 op2
= MASK_LX(ctx
->opcode
);
14847 #if defined(TARGET_MIPS64)
14853 gen_mipsdsp_ld(ctx
, op2
, rd
, rs
, rt
);
14855 default: /* Invalid */
14856 MIPS_INVAL("MASK LX");
14857 generate_exception(ctx
, EXCP_RI
);
14861 case OPC_ABSQ_S_PH_DSP
:
14862 op2
= MASK_ABSQ_S_PH(ctx
->opcode
);
14864 case OPC_ABSQ_S_QB
:
14865 case OPC_ABSQ_S_PH
:
14867 case OPC_PRECEQ_W_PHL
:
14868 case OPC_PRECEQ_W_PHR
:
14869 case OPC_PRECEQU_PH_QBL
:
14870 case OPC_PRECEQU_PH_QBR
:
14871 case OPC_PRECEQU_PH_QBLA
:
14872 case OPC_PRECEQU_PH_QBRA
:
14873 case OPC_PRECEU_PH_QBL
:
14874 case OPC_PRECEU_PH_QBR
:
14875 case OPC_PRECEU_PH_QBLA
:
14876 case OPC_PRECEU_PH_QBRA
:
14877 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14884 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
14887 MIPS_INVAL("MASK ABSQ_S.PH");
14888 generate_exception(ctx
, EXCP_RI
);
14892 case OPC_ADDU_QB_DSP
:
14893 op2
= MASK_ADDU_QB(ctx
->opcode
);
14896 case OPC_ADDQ_S_PH
:
14899 case OPC_ADDU_S_QB
:
14901 case OPC_ADDU_S_PH
:
14903 case OPC_SUBQ_S_PH
:
14906 case OPC_SUBU_S_QB
:
14908 case OPC_SUBU_S_PH
:
14912 case OPC_RADDU_W_QB
:
14913 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14915 case OPC_MULEU_S_PH_QBL
:
14916 case OPC_MULEU_S_PH_QBR
:
14917 case OPC_MULQ_RS_PH
:
14918 case OPC_MULEQ_S_W_PHL
:
14919 case OPC_MULEQ_S_W_PHR
:
14920 case OPC_MULQ_S_PH
:
14921 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14923 default: /* Invalid */
14924 MIPS_INVAL("MASK ADDU.QB");
14925 generate_exception(ctx
, EXCP_RI
);
14930 case OPC_CMPU_EQ_QB_DSP
:
14931 op2
= MASK_CMPU_EQ_QB(ctx
->opcode
);
14933 case OPC_PRECR_SRA_PH_W
:
14934 case OPC_PRECR_SRA_R_PH_W
:
14935 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
14937 case OPC_PRECR_QB_PH
:
14938 case OPC_PRECRQ_QB_PH
:
14939 case OPC_PRECRQ_PH_W
:
14940 case OPC_PRECRQ_RS_PH_W
:
14941 case OPC_PRECRQU_S_QB_PH
:
14942 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
14944 case OPC_CMPU_EQ_QB
:
14945 case OPC_CMPU_LT_QB
:
14946 case OPC_CMPU_LE_QB
:
14947 case OPC_CMP_EQ_PH
:
14948 case OPC_CMP_LT_PH
:
14949 case OPC_CMP_LE_PH
:
14950 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14952 case OPC_CMPGU_EQ_QB
:
14953 case OPC_CMPGU_LT_QB
:
14954 case OPC_CMPGU_LE_QB
:
14955 case OPC_CMPGDU_EQ_QB
:
14956 case OPC_CMPGDU_LT_QB
:
14957 case OPC_CMPGDU_LE_QB
:
14960 case OPC_PACKRL_PH
:
14961 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
14963 default: /* Invalid */
14964 MIPS_INVAL("MASK CMPU.EQ.QB");
14965 generate_exception(ctx
, EXCP_RI
);
14969 case OPC_SHLL_QB_DSP
:
14970 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
14972 case OPC_DPA_W_PH_DSP
:
14973 op2
= MASK_DPA_W_PH(ctx
->opcode
);
14975 case OPC_DPAU_H_QBL
:
14976 case OPC_DPAU_H_QBR
:
14977 case OPC_DPSU_H_QBL
:
14978 case OPC_DPSU_H_QBR
:
14980 case OPC_DPAX_W_PH
:
14981 case OPC_DPAQ_S_W_PH
:
14982 case OPC_DPAQX_S_W_PH
:
14983 case OPC_DPAQX_SA_W_PH
:
14985 case OPC_DPSX_W_PH
:
14986 case OPC_DPSQ_S_W_PH
:
14987 case OPC_DPSQX_S_W_PH
:
14988 case OPC_DPSQX_SA_W_PH
:
14989 case OPC_MULSAQ_S_W_PH
:
14990 case OPC_DPAQ_SA_L_W
:
14991 case OPC_DPSQ_SA_L_W
:
14992 case OPC_MAQ_S_W_PHL
:
14993 case OPC_MAQ_S_W_PHR
:
14994 case OPC_MAQ_SA_W_PHL
:
14995 case OPC_MAQ_SA_W_PHR
:
14996 case OPC_MULSA_W_PH
:
14997 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
14999 default: /* Invalid */
15000 MIPS_INVAL("MASK DPAW.PH");
15001 generate_exception(ctx
, EXCP_RI
);
15006 op2
= MASK_INSV(ctx
->opcode
);
15018 t0
= tcg_temp_new();
15019 t1
= tcg_temp_new();
15021 gen_load_gpr(t0
, rt
);
15022 gen_load_gpr(t1
, rs
);
15024 gen_helper_insv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15030 default: /* Invalid */
15031 MIPS_INVAL("MASK INSV");
15032 generate_exception(ctx
, EXCP_RI
);
15036 case OPC_APPEND_DSP
:
15037 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15039 case OPC_EXTR_W_DSP
:
15040 op2
= MASK_EXTR_W(ctx
->opcode
);
15044 case OPC_EXTR_RS_W
:
15046 case OPC_EXTRV_S_H
:
15048 case OPC_EXTRV_R_W
:
15049 case OPC_EXTRV_RS_W
:
15054 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15057 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15063 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15065 default: /* Invalid */
15066 MIPS_INVAL("MASK EXTR.W");
15067 generate_exception(ctx
, EXCP_RI
);
15071 #if defined(TARGET_MIPS64)
15072 case OPC_DEXTM
... OPC_DEXT
:
15073 case OPC_DINSM
... OPC_DINS
:
15074 check_insn(ctx
, ISA_MIPS64R2
);
15075 check_mips_64(ctx
);
15076 gen_bitops(ctx
, op1
, rt
, rs
, sa
, rd
);
15079 check_insn(ctx
, ISA_MIPS64R2
);
15080 check_mips_64(ctx
);
15081 op2
= MASK_DBSHFL(ctx
->opcode
);
15082 gen_bshfl(ctx
, op2
, rt
, rd
);
15084 case OPC_DDIV_G_2E
... OPC_DDIVU_G_2E
:
15085 case OPC_DMULT_G_2E
... OPC_DMULTU_G_2E
:
15086 case OPC_DMOD_G_2E
... OPC_DMODU_G_2E
:
15087 check_insn(ctx
, INSN_LOONGSON2E
);
15088 gen_loongson_integer(ctx
, op1
, rd
, rs
, rt
);
15090 case OPC_ABSQ_S_QH_DSP
:
15091 op2
= MASK_ABSQ_S_QH(ctx
->opcode
);
15093 case OPC_PRECEQ_L_PWL
:
15094 case OPC_PRECEQ_L_PWR
:
15095 case OPC_PRECEQ_PW_QHL
:
15096 case OPC_PRECEQ_PW_QHR
:
15097 case OPC_PRECEQ_PW_QHLA
:
15098 case OPC_PRECEQ_PW_QHRA
:
15099 case OPC_PRECEQU_QH_OBL
:
15100 case OPC_PRECEQU_QH_OBR
:
15101 case OPC_PRECEQU_QH_OBLA
:
15102 case OPC_PRECEQU_QH_OBRA
:
15103 case OPC_PRECEU_QH_OBL
:
15104 case OPC_PRECEU_QH_OBR
:
15105 case OPC_PRECEU_QH_OBLA
:
15106 case OPC_PRECEU_QH_OBRA
:
15107 case OPC_ABSQ_S_OB
:
15108 case OPC_ABSQ_S_PW
:
15109 case OPC_ABSQ_S_QH
:
15110 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15118 gen_mipsdsp_bitinsn(ctx
, op1
, op2
, rd
, rt
);
15120 default: /* Invalid */
15121 MIPS_INVAL("MASK ABSQ_S.QH");
15122 generate_exception(ctx
, EXCP_RI
);
15126 case OPC_ADDU_OB_DSP
:
15127 op2
= MASK_ADDU_OB(ctx
->opcode
);
15129 case OPC_RADDU_L_OB
:
15131 case OPC_SUBQ_S_PW
:
15133 case OPC_SUBQ_S_QH
:
15135 case OPC_SUBU_S_OB
:
15137 case OPC_SUBU_S_QH
:
15139 case OPC_SUBUH_R_OB
:
15141 case OPC_ADDQ_S_PW
:
15143 case OPC_ADDQ_S_QH
:
15145 case OPC_ADDU_S_OB
:
15147 case OPC_ADDU_S_QH
:
15149 case OPC_ADDUH_R_OB
:
15150 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15152 case OPC_MULEQ_S_PW_QHL
:
15153 case OPC_MULEQ_S_PW_QHR
:
15154 case OPC_MULEU_S_QH_OBL
:
15155 case OPC_MULEU_S_QH_OBR
:
15156 case OPC_MULQ_RS_QH
:
15157 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15159 default: /* Invalid */
15160 MIPS_INVAL("MASK ADDU.OB");
15161 generate_exception(ctx
, EXCP_RI
);
15165 case OPC_CMPU_EQ_OB_DSP
:
15166 op2
= MASK_CMPU_EQ_OB(ctx
->opcode
);
15168 case OPC_PRECR_SRA_QH_PW
:
15169 case OPC_PRECR_SRA_R_QH_PW
:
15170 /* Return value is rt. */
15171 gen_mipsdsp_arith(ctx
, op1
, op2
, rt
, rs
, rd
);
15173 case OPC_PRECR_OB_QH
:
15174 case OPC_PRECRQ_OB_QH
:
15175 case OPC_PRECRQ_PW_L
:
15176 case OPC_PRECRQ_QH_PW
:
15177 case OPC_PRECRQ_RS_QH_PW
:
15178 case OPC_PRECRQU_S_OB_QH
:
15179 gen_mipsdsp_arith(ctx
, op1
, op2
, rd
, rs
, rt
);
15181 case OPC_CMPU_EQ_OB
:
15182 case OPC_CMPU_LT_OB
:
15183 case OPC_CMPU_LE_OB
:
15184 case OPC_CMP_EQ_QH
:
15185 case OPC_CMP_LT_QH
:
15186 case OPC_CMP_LE_QH
:
15187 case OPC_CMP_EQ_PW
:
15188 case OPC_CMP_LT_PW
:
15189 case OPC_CMP_LE_PW
:
15190 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15192 case OPC_CMPGDU_EQ_OB
:
15193 case OPC_CMPGDU_LT_OB
:
15194 case OPC_CMPGDU_LE_OB
:
15195 case OPC_CMPGU_EQ_OB
:
15196 case OPC_CMPGU_LT_OB
:
15197 case OPC_CMPGU_LE_OB
:
15198 case OPC_PACKRL_PW
:
15202 gen_mipsdsp_add_cmp_pick(ctx
, op1
, op2
, rd
, rs
, rt
, 1);
15204 default: /* Invalid */
15205 MIPS_INVAL("MASK CMPU_EQ.OB");
15206 generate_exception(ctx
, EXCP_RI
);
15210 case OPC_DAPPEND_DSP
:
15211 gen_mipsdsp_append(env
, ctx
, op1
, rt
, rs
, rd
);
15213 case OPC_DEXTR_W_DSP
:
15214 op2
= MASK_DEXTR_W(ctx
->opcode
);
15221 case OPC_DEXTR_R_L
:
15222 case OPC_DEXTR_RS_L
:
15224 case OPC_DEXTR_R_W
:
15225 case OPC_DEXTR_RS_W
:
15226 case OPC_DEXTR_S_H
:
15228 case OPC_DEXTRV_R_L
:
15229 case OPC_DEXTRV_RS_L
:
15230 case OPC_DEXTRV_S_H
:
15232 case OPC_DEXTRV_R_W
:
15233 case OPC_DEXTRV_RS_W
:
15234 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rt
, rs
, rd
, 1);
15239 gen_mipsdsp_accinsn(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15241 default: /* Invalid */
15242 MIPS_INVAL("MASK EXTR.W");
15243 generate_exception(ctx
, EXCP_RI
);
15247 case OPC_DPAQ_W_QH_DSP
:
15248 op2
= MASK_DPAQ_W_QH(ctx
->opcode
);
15250 case OPC_DPAU_H_OBL
:
15251 case OPC_DPAU_H_OBR
:
15252 case OPC_DPSU_H_OBL
:
15253 case OPC_DPSU_H_OBR
:
15255 case OPC_DPAQ_S_W_QH
:
15257 case OPC_DPSQ_S_W_QH
:
15258 case OPC_MULSAQ_S_W_QH
:
15259 case OPC_DPAQ_SA_L_PW
:
15260 case OPC_DPSQ_SA_L_PW
:
15261 case OPC_MULSAQ_S_L_PW
:
15262 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15264 case OPC_MAQ_S_W_QHLL
:
15265 case OPC_MAQ_S_W_QHLR
:
15266 case OPC_MAQ_S_W_QHRL
:
15267 case OPC_MAQ_S_W_QHRR
:
15268 case OPC_MAQ_SA_W_QHLL
:
15269 case OPC_MAQ_SA_W_QHLR
:
15270 case OPC_MAQ_SA_W_QHRL
:
15271 case OPC_MAQ_SA_W_QHRR
:
15272 case OPC_MAQ_S_L_PWL
:
15273 case OPC_MAQ_S_L_PWR
:
15278 gen_mipsdsp_multiply(ctx
, op1
, op2
, rd
, rs
, rt
, 0);
15280 default: /* Invalid */
15281 MIPS_INVAL("MASK DPAQ.W.QH");
15282 generate_exception(ctx
, EXCP_RI
);
15286 case OPC_DINSV_DSP
:
15287 op2
= MASK_INSV(ctx
->opcode
);
15299 t0
= tcg_temp_new();
15300 t1
= tcg_temp_new();
15302 gen_load_gpr(t0
, rt
);
15303 gen_load_gpr(t1
, rs
);
15305 gen_helper_dinsv(cpu_gpr
[rt
], cpu_env
, t1
, t0
);
15311 default: /* Invalid */
15312 MIPS_INVAL("MASK DINSV");
15313 generate_exception(ctx
, EXCP_RI
);
15317 case OPC_SHLL_OB_DSP
:
15318 gen_mipsdsp_shift(ctx
, op1
, rd
, rs
, rt
);
15321 default: /* Invalid */
15322 MIPS_INVAL("special3");
15323 generate_exception(ctx
, EXCP_RI
);
15328 op1
= MASK_REGIMM(ctx
->opcode
);
15330 case OPC_BLTZ
... OPC_BGEZL
: /* REGIMM branches */
15331 case OPC_BLTZAL
... OPC_BGEZALL
:
15332 gen_compute_branch(ctx
, op1
, 4, rs
, -1, imm
<< 2);
15334 case OPC_TGEI
... OPC_TEQI
: /* REGIMM traps */
15336 gen_trap(ctx
, op1
, rs
, -1, imm
);
15339 check_insn(ctx
, ISA_MIPS32R2
);
15340 /* Treat as NOP. */
15342 case OPC_BPOSGE32
: /* MIPS DSP branch */
15343 #if defined(TARGET_MIPS64)
15347 gen_compute_branch(ctx
, op1
, 4, -1, -2, (int32_t)imm
<< 2);
15349 default: /* Invalid */
15350 MIPS_INVAL("regimm");
15351 generate_exception(ctx
, EXCP_RI
);
15356 check_cp0_enabled(ctx
);
15357 op1
= MASK_CP0(ctx
->opcode
);
15363 #if defined(TARGET_MIPS64)
15367 #ifndef CONFIG_USER_ONLY
15368 gen_cp0(env
, ctx
, op1
, rt
, rd
);
15369 #endif /* !CONFIG_USER_ONLY */
15371 case OPC_C0_FIRST
... OPC_C0_LAST
:
15372 #ifndef CONFIG_USER_ONLY
15373 gen_cp0(env
, ctx
, MASK_C0(ctx
->opcode
), rt
, rd
);
15374 #endif /* !CONFIG_USER_ONLY */
15377 #ifndef CONFIG_USER_ONLY
15379 TCGv t0
= tcg_temp_new();
15381 op2
= MASK_MFMC0(ctx
->opcode
);
15384 check_insn(ctx
, ASE_MT
);
15385 gen_helper_dmt(t0
);
15386 gen_store_gpr(t0
, rt
);
15389 check_insn(ctx
, ASE_MT
);
15390 gen_helper_emt(t0
);
15391 gen_store_gpr(t0
, rt
);
15394 check_insn(ctx
, ASE_MT
);
15395 gen_helper_dvpe(t0
, cpu_env
);
15396 gen_store_gpr(t0
, rt
);
15399 check_insn(ctx
, ASE_MT
);
15400 gen_helper_evpe(t0
, cpu_env
);
15401 gen_store_gpr(t0
, rt
);
15404 check_insn(ctx
, ISA_MIPS32R2
);
15405 save_cpu_state(ctx
, 1);
15406 gen_helper_di(t0
, cpu_env
);
15407 gen_store_gpr(t0
, rt
);
15408 /* Stop translation as we may have switched the execution mode */
15409 ctx
->bstate
= BS_STOP
;
15412 check_insn(ctx
, ISA_MIPS32R2
);
15413 save_cpu_state(ctx
, 1);
15414 gen_helper_ei(t0
, cpu_env
);
15415 gen_store_gpr(t0
, rt
);
15416 /* Stop translation as we may have switched the execution mode */
15417 ctx
->bstate
= BS_STOP
;
15419 default: /* Invalid */
15420 MIPS_INVAL("mfmc0");
15421 generate_exception(ctx
, EXCP_RI
);
15426 #endif /* !CONFIG_USER_ONLY */
15429 check_insn(ctx
, ISA_MIPS32R2
);
15430 gen_load_srsgpr(rt
, rd
);
15433 check_insn(ctx
, ISA_MIPS32R2
);
15434 gen_store_srsgpr(rt
, rd
);
15438 generate_exception(ctx
, EXCP_RI
);
15442 case OPC_ADDI
: /* Arithmetic with immediate opcode */
15444 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15446 case OPC_SLTI
: /* Set on less than with immediate opcode */
15448 gen_slt_imm(ctx
, op
, rt
, rs
, imm
);
15450 case OPC_ANDI
: /* Arithmetic with immediate opcode */
15454 gen_logic_imm(ctx
, op
, rt
, rs
, imm
);
15456 case OPC_J
... OPC_JAL
: /* Jump */
15457 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15458 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15460 case OPC_BEQ
... OPC_BGTZ
: /* Branch */
15461 case OPC_BEQL
... OPC_BGTZL
:
15462 gen_compute_branch(ctx
, op
, 4, rs
, rt
, imm
<< 2);
15464 case OPC_LB
... OPC_LWR
: /* Load and stores */
15466 gen_ld(ctx
, op
, rt
, rs
, imm
);
15468 case OPC_SB
... OPC_SW
:
15470 gen_st(ctx
, op
, rt
, rs
, imm
);
15473 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15476 check_cp0_enabled(ctx
);
15477 check_insn(ctx
, ISA_MIPS3
| ISA_MIPS32
);
15478 /* Treat as NOP. */
15481 check_insn(ctx
, ISA_MIPS4
| ISA_MIPS32
);
15482 /* Treat as NOP. */
15485 /* Floating point (COP1). */
15490 gen_cop1_ldst(ctx
, op
, rt
, rs
, imm
);
15494 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15495 check_cp1_enabled(ctx
);
15496 op1
= MASK_CP1(ctx
->opcode
);
15500 check_insn(ctx
, ISA_MIPS32R2
);
15505 gen_cp1(ctx
, op1
, rt
, rd
);
15507 #if defined(TARGET_MIPS64)
15510 check_insn(ctx
, ISA_MIPS3
);
15511 gen_cp1(ctx
, op1
, rt
, rd
);
15517 check_insn(ctx
, ASE_MIPS3D
);
15520 gen_compute_branch1(ctx
, MASK_BC1(ctx
->opcode
),
15521 (rt
>> 2) & 0x7, imm
<< 2);
15528 gen_farith(ctx
, ctx
->opcode
& FOP(0x3f, 0x1f), rt
, rd
, sa
,
15533 generate_exception (ctx
, EXCP_RI
);
15537 generate_exception_err(ctx
, EXCP_CpU
, 1);
15546 /* COP2: Not implemented. */
15547 generate_exception_err(ctx
, EXCP_CpU
, 2);
15550 check_insn(ctx
, INSN_LOONGSON2F
);
15551 /* Note that these instructions use different fields. */
15552 gen_loongson_multimedia(ctx
, sa
, rd
, rt
);
15556 if (ctx
->CP0_Config1
& (1 << CP0C1_FP
)) {
15557 check_cp1_enabled(ctx
);
15558 op1
= MASK_CP3(ctx
->opcode
);
15566 gen_flt3_ldst(ctx
, op1
, sa
, rd
, rs
, rt
);
15569 /* Treat as NOP. */
15584 gen_flt3_arith(ctx
, op1
, sa
, rs
, rd
, rt
);
15588 generate_exception (ctx
, EXCP_RI
);
15592 generate_exception_err(ctx
, EXCP_CpU
, 1);
15596 #if defined(TARGET_MIPS64)
15597 /* MIPS64 opcodes */
15599 case OPC_LDL
... OPC_LDR
:
15602 check_insn(ctx
, ISA_MIPS3
);
15603 check_mips_64(ctx
);
15604 gen_ld(ctx
, op
, rt
, rs
, imm
);
15606 case OPC_SDL
... OPC_SDR
:
15608 check_insn(ctx
, ISA_MIPS3
);
15609 check_mips_64(ctx
);
15610 gen_st(ctx
, op
, rt
, rs
, imm
);
15613 check_insn(ctx
, ISA_MIPS3
);
15614 check_mips_64(ctx
);
15615 gen_st_cond(ctx
, op
, rt
, rs
, imm
);
15619 check_insn(ctx
, ISA_MIPS3
);
15620 check_mips_64(ctx
);
15621 gen_arith_imm(ctx
, op
, rt
, rs
, imm
);
15625 check_insn(ctx
, ASE_MIPS16
| ASE_MICROMIPS
);
15626 offset
= (int32_t)(ctx
->opcode
& 0x3FFFFFF) << 2;
15627 gen_compute_branch(ctx
, op
, 4, rs
, rt
, offset
);
15630 check_insn(ctx
, ASE_MDMX
);
15631 /* MDMX: Not implemented. */
15632 default: /* Invalid */
15633 MIPS_INVAL("major opcode");
15634 generate_exception(ctx
, EXCP_RI
);
15640 gen_intermediate_code_internal(MIPSCPU
*cpu
, TranslationBlock
*tb
,
15643 CPUState
*cs
= CPU(cpu
);
15644 CPUMIPSState
*env
= &cpu
->env
;
15646 target_ulong pc_start
;
15647 uint16_t *gen_opc_end
;
15656 qemu_log("search pc %d\n", search_pc
);
15659 gen_opc_end
= tcg_ctx
.gen_opc_buf
+ OPC_MAX_SIZE
;
15662 ctx
.singlestep_enabled
= cs
->singlestep_enabled
;
15663 ctx
.insn_flags
= env
->insn_flags
;
15664 ctx
.CP0_Config1
= env
->CP0_Config1
;
15666 ctx
.bstate
= BS_NONE
;
15667 /* Restore delay slot state from the tb context. */
15668 ctx
.hflags
= (uint32_t)tb
->flags
; /* FIXME: maybe use 64 bits here? */
15669 ctx
.ulri
= env
->CP0_Config3
& (1 << CP0C3_ULRI
);
15670 restore_cpu_state(env
, &ctx
);
15671 #ifdef CONFIG_USER_ONLY
15672 ctx
.mem_idx
= MIPS_HFLAG_UM
;
15674 ctx
.mem_idx
= ctx
.hflags
& MIPS_HFLAG_KSU
;
15677 max_insns
= tb
->cflags
& CF_COUNT_MASK
;
15678 if (max_insns
== 0)
15679 max_insns
= CF_COUNT_MASK
;
15680 LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb
, ctx
.mem_idx
, ctx
.hflags
);
15682 while (ctx
.bstate
== BS_NONE
) {
15683 if (unlikely(!QTAILQ_EMPTY(&cs
->breakpoints
))) {
15684 QTAILQ_FOREACH(bp
, &cs
->breakpoints
, entry
) {
15685 if (bp
->pc
== ctx
.pc
) {
15686 save_cpu_state(&ctx
, 1);
15687 ctx
.bstate
= BS_BRANCH
;
15688 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15689 /* Include the breakpoint location or the tb won't
15690 * be flushed when it must be. */
15692 goto done_generating
;
15698 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15702 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15704 tcg_ctx
.gen_opc_pc
[lj
] = ctx
.pc
;
15705 gen_opc_hflags
[lj
] = ctx
.hflags
& MIPS_HFLAG_BMASK
;
15706 gen_opc_btarget
[lj
] = ctx
.btarget
;
15707 tcg_ctx
.gen_opc_instr_start
[lj
] = 1;
15708 tcg_ctx
.gen_opc_icount
[lj
] = num_insns
;
15710 if (num_insns
+ 1 == max_insns
&& (tb
->cflags
& CF_LAST_IO
))
15713 is_delay
= ctx
.hflags
& MIPS_HFLAG_BMASK
;
15714 if (!(ctx
.hflags
& MIPS_HFLAG_M16
)) {
15715 ctx
.opcode
= cpu_ldl_code(env
, ctx
.pc
);
15717 decode_opc(env
, &ctx
);
15718 } else if (ctx
.insn_flags
& ASE_MICROMIPS
) {
15719 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15720 insn_bytes
= decode_micromips_opc(env
, &ctx
);
15721 } else if (ctx
.insn_flags
& ASE_MIPS16
) {
15722 ctx
.opcode
= cpu_lduw_code(env
, ctx
.pc
);
15723 insn_bytes
= decode_mips16_opc(env
, &ctx
);
15725 generate_exception(&ctx
, EXCP_RI
);
15726 ctx
.bstate
= BS_STOP
;
15730 handle_delay_slot(&ctx
, insn_bytes
);
15732 ctx
.pc
+= insn_bytes
;
15736 /* Execute a branch and its delay slot as a single instruction.
15737 This is what GDB expects and is consistent with what the
15738 hardware does (e.g. if a delay slot instruction faults, the
15739 reported PC is the PC of the branch). */
15740 if (cs
->singlestep_enabled
&& (ctx
.hflags
& MIPS_HFLAG_BMASK
) == 0) {
15744 if ((ctx
.pc
& (TARGET_PAGE_SIZE
- 1)) == 0)
15747 if (tcg_ctx
.gen_opc_ptr
>= gen_opc_end
) {
15751 if (num_insns
>= max_insns
)
15757 if (tb
->cflags
& CF_LAST_IO
) {
15760 if (cs
->singlestep_enabled
&& ctx
.bstate
!= BS_BRANCH
) {
15761 save_cpu_state(&ctx
, ctx
.bstate
== BS_NONE
);
15762 gen_helper_0e0i(raise_exception
, EXCP_DEBUG
);
15764 switch (ctx
.bstate
) {
15766 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15769 save_cpu_state(&ctx
, 0);
15770 gen_goto_tb(&ctx
, 0, ctx
.pc
);
15773 tcg_gen_exit_tb(0);
15781 gen_tb_end(tb
, num_insns
);
15782 *tcg_ctx
.gen_opc_ptr
= INDEX_op_end
;
15784 j
= tcg_ctx
.gen_opc_ptr
- tcg_ctx
.gen_opc_buf
;
15787 tcg_ctx
.gen_opc_instr_start
[lj
++] = 0;
15789 tb
->size
= ctx
.pc
- pc_start
;
15790 tb
->icount
= num_insns
;
15794 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM
)) {
15795 qemu_log("IN: %s\n", lookup_symbol(pc_start
));
15796 log_target_disas(env
, pc_start
, ctx
.pc
- pc_start
, 0);
15802 void gen_intermediate_code (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15804 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, false);
15807 void gen_intermediate_code_pc (CPUMIPSState
*env
, struct TranslationBlock
*tb
)
15809 gen_intermediate_code_internal(mips_env_get_cpu(env
), tb
, true);
15812 static void fpu_dump_state(CPUMIPSState
*env
, FILE *f
, fprintf_function fpu_fprintf
,
15816 int is_fpu64
= !!(env
->hflags
& MIPS_HFLAG_F64
);
15818 #define printfpr(fp) \
15821 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15822 " fd:%13g fs:%13g psu: %13g\n", \
15823 (fp)->w[FP_ENDIAN_IDX], (fp)->d, \
15824 (double)(fp)->fd, \
15825 (double)(fp)->fs[FP_ENDIAN_IDX], \
15826 (double)(fp)->fs[!FP_ENDIAN_IDX]); \
15829 tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX]; \
15830 tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX]; \
15831 fpu_fprintf(f, "w:%08x d:%016" PRIx64 \
15832 " fd:%13g fs:%13g psu:%13g\n", \
15833 tmp.w[FP_ENDIAN_IDX], tmp.d, \
15835 (double)tmp.fs[FP_ENDIAN_IDX], \
15836 (double)tmp.fs[!FP_ENDIAN_IDX]); \
15841 fpu_fprintf(f
, "CP1 FCR0 0x%08x FCR31 0x%08x SR.FR %d fp_status 0x%02x\n",
15842 env
->active_fpu
.fcr0
, env
->active_fpu
.fcr31
, is_fpu64
,
15843 get_float_exception_flags(&env
->active_fpu
.fp_status
));
15844 for (i
= 0; i
< 32; (is_fpu64
) ? i
++ : (i
+= 2)) {
15845 fpu_fprintf(f
, "%3s: ", fregnames
[i
]);
15846 printfpr(&env
->active_fpu
.fpr
[i
]);
15852 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15853 /* Debug help: The architecture requires 32bit code to maintain proper
15854 sign-extended values on 64bit machines. */
15856 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15859 cpu_mips_check_sign_extensions (CPUMIPSState
*env
, FILE *f
,
15860 fprintf_function cpu_fprintf
,
15865 if (!SIGN_EXT_P(env
->active_tc
.PC
))
15866 cpu_fprintf(f
, "BROKEN: pc=0x" TARGET_FMT_lx
"\n", env
->active_tc
.PC
);
15867 if (!SIGN_EXT_P(env
->active_tc
.HI
[0]))
15868 cpu_fprintf(f
, "BROKEN: HI=0x" TARGET_FMT_lx
"\n", env
->active_tc
.HI
[0]);
15869 if (!SIGN_EXT_P(env
->active_tc
.LO
[0]))
15870 cpu_fprintf(f
, "BROKEN: LO=0x" TARGET_FMT_lx
"\n", env
->active_tc
.LO
[0]);
15871 if (!SIGN_EXT_P(env
->btarget
))
15872 cpu_fprintf(f
, "BROKEN: btarget=0x" TARGET_FMT_lx
"\n", env
->btarget
);
15874 for (i
= 0; i
< 32; i
++) {
15875 if (!SIGN_EXT_P(env
->active_tc
.gpr
[i
]))
15876 cpu_fprintf(f
, "BROKEN: %s=0x" TARGET_FMT_lx
"\n", regnames
[i
], env
->active_tc
.gpr
[i
]);
15879 if (!SIGN_EXT_P(env
->CP0_EPC
))
15880 cpu_fprintf(f
, "BROKEN: EPC=0x" TARGET_FMT_lx
"\n", env
->CP0_EPC
);
15881 if (!SIGN_EXT_P(env
->lladdr
))
15882 cpu_fprintf(f
, "BROKEN: LLAddr=0x" TARGET_FMT_lx
"\n", env
->lladdr
);
15886 void mips_cpu_dump_state(CPUState
*cs
, FILE *f
, fprintf_function cpu_fprintf
,
15889 MIPSCPU
*cpu
= MIPS_CPU(cs
);
15890 CPUMIPSState
*env
= &cpu
->env
;
15893 cpu_fprintf(f
, "pc=0x" TARGET_FMT_lx
" HI=0x" TARGET_FMT_lx
15894 " LO=0x" TARGET_FMT_lx
" ds %04x "
15895 TARGET_FMT_lx
" " TARGET_FMT_ld
"\n",
15896 env
->active_tc
.PC
, env
->active_tc
.HI
[0], env
->active_tc
.LO
[0],
15897 env
->hflags
, env
->btarget
, env
->bcond
);
15898 for (i
= 0; i
< 32; i
++) {
15900 cpu_fprintf(f
, "GPR%02d:", i
);
15901 cpu_fprintf(f
, " %s " TARGET_FMT_lx
, regnames
[i
], env
->active_tc
.gpr
[i
]);
15903 cpu_fprintf(f
, "\n");
15906 cpu_fprintf(f
, "CP0 Status 0x%08x Cause 0x%08x EPC 0x" TARGET_FMT_lx
"\n",
15907 env
->CP0_Status
, env
->CP0_Cause
, env
->CP0_EPC
);
15908 cpu_fprintf(f
, " Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx
"\n",
15909 env
->CP0_Config0
, env
->CP0_Config1
, env
->lladdr
);
15910 if (env
->hflags
& MIPS_HFLAG_FPU
)
15911 fpu_dump_state(env
, f
, cpu_fprintf
, flags
);
15912 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15913 cpu_mips_check_sign_extensions(env
, f
, cpu_fprintf
, flags
);
15917 void mips_tcg_init(void)
15922 /* Initialize various static tables. */
15926 cpu_env
= tcg_global_reg_new_ptr(TCG_AREG0
, "env");
15927 TCGV_UNUSED(cpu_gpr
[0]);
15928 for (i
= 1; i
< 32; i
++)
15929 cpu_gpr
[i
] = tcg_global_mem_new(TCG_AREG0
,
15930 offsetof(CPUMIPSState
, active_tc
.gpr
[i
]),
15933 for (i
= 0; i
< 32; i
++) {
15934 int off
= offsetof(CPUMIPSState
, active_fpu
.fpr
[i
]);
15935 fpu_f64
[i
] = tcg_global_mem_new_i64(TCG_AREG0
, off
, fregnames
[i
]);
15938 cpu_PC
= tcg_global_mem_new(TCG_AREG0
,
15939 offsetof(CPUMIPSState
, active_tc
.PC
), "PC");
15940 for (i
= 0; i
< MIPS_DSP_ACC
; i
++) {
15941 cpu_HI
[i
] = tcg_global_mem_new(TCG_AREG0
,
15942 offsetof(CPUMIPSState
, active_tc
.HI
[i
]),
15944 cpu_LO
[i
] = tcg_global_mem_new(TCG_AREG0
,
15945 offsetof(CPUMIPSState
, active_tc
.LO
[i
]),
15947 cpu_ACX
[i
] = tcg_global_mem_new(TCG_AREG0
,
15948 offsetof(CPUMIPSState
, active_tc
.ACX
[i
]),
15951 cpu_dspctrl
= tcg_global_mem_new(TCG_AREG0
,
15952 offsetof(CPUMIPSState
, active_tc
.DSPControl
),
15954 bcond
= tcg_global_mem_new(TCG_AREG0
,
15955 offsetof(CPUMIPSState
, bcond
), "bcond");
15956 btarget
= tcg_global_mem_new(TCG_AREG0
,
15957 offsetof(CPUMIPSState
, btarget
), "btarget");
15958 hflags
= tcg_global_mem_new_i32(TCG_AREG0
,
15959 offsetof(CPUMIPSState
, hflags
), "hflags");
15961 fpu_fcr0
= tcg_global_mem_new_i32(TCG_AREG0
,
15962 offsetof(CPUMIPSState
, active_fpu
.fcr0
),
15964 fpu_fcr31
= tcg_global_mem_new_i32(TCG_AREG0
,
15965 offsetof(CPUMIPSState
, active_fpu
.fcr31
),
15971 #include "translate_init.c"
15973 MIPSCPU
*cpu_mips_init(const char *cpu_model
)
15977 const mips_def_t
*def
;
15979 def
= cpu_mips_find_by_name(cpu_model
);
15982 cpu
= MIPS_CPU(object_new(TYPE_MIPS_CPU
));
15984 env
->cpu_model
= def
;
15986 #ifndef CONFIG_USER_ONLY
15987 mmu_init(env
, def
);
15989 fpu_init(env
, def
);
15990 mvp_init(env
, def
);
15992 object_property_set_bool(OBJECT(cpu
), true, "realized", NULL
);
15997 void cpu_state_reset(CPUMIPSState
*env
)
15999 MIPSCPU
*cpu
= mips_env_get_cpu(env
);
16000 CPUState
*cs
= CPU(cpu
);
16002 /* Reset registers to their default values */
16003 env
->CP0_PRid
= env
->cpu_model
->CP0_PRid
;
16004 env
->CP0_Config0
= env
->cpu_model
->CP0_Config0
;
16005 #ifdef TARGET_WORDS_BIGENDIAN
16006 env
->CP0_Config0
|= (1 << CP0C0_BE
);
16008 env
->CP0_Config1
= env
->cpu_model
->CP0_Config1
;
16009 env
->CP0_Config2
= env
->cpu_model
->CP0_Config2
;
16010 env
->CP0_Config3
= env
->cpu_model
->CP0_Config3
;
16011 env
->CP0_Config4
= env
->cpu_model
->CP0_Config4
;
16012 env
->CP0_Config4_rw_bitmask
= env
->cpu_model
->CP0_Config4_rw_bitmask
;
16013 env
->CP0_Config5
= env
->cpu_model
->CP0_Config5
;
16014 env
->CP0_Config5_rw_bitmask
= env
->cpu_model
->CP0_Config5_rw_bitmask
;
16015 env
->CP0_Config6
= env
->cpu_model
->CP0_Config6
;
16016 env
->CP0_Config7
= env
->cpu_model
->CP0_Config7
;
16017 env
->CP0_LLAddr_rw_bitmask
= env
->cpu_model
->CP0_LLAddr_rw_bitmask
16018 << env
->cpu_model
->CP0_LLAddr_shift
;
16019 env
->CP0_LLAddr_shift
= env
->cpu_model
->CP0_LLAddr_shift
;
16020 env
->SYNCI_Step
= env
->cpu_model
->SYNCI_Step
;
16021 env
->CCRes
= env
->cpu_model
->CCRes
;
16022 env
->CP0_Status_rw_bitmask
= env
->cpu_model
->CP0_Status_rw_bitmask
;
16023 env
->CP0_TCStatus_rw_bitmask
= env
->cpu_model
->CP0_TCStatus_rw_bitmask
;
16024 env
->CP0_SRSCtl
= env
->cpu_model
->CP0_SRSCtl
;
16025 env
->current_tc
= 0;
16026 env
->SEGBITS
= env
->cpu_model
->SEGBITS
;
16027 env
->SEGMask
= (target_ulong
)((1ULL << env
->cpu_model
->SEGBITS
) - 1);
16028 #if defined(TARGET_MIPS64)
16029 if (env
->cpu_model
->insn_flags
& ISA_MIPS3
) {
16030 env
->SEGMask
|= 3ULL << 62;
16033 env
->PABITS
= env
->cpu_model
->PABITS
;
16034 env
->PAMask
= (target_ulong
)((1ULL << env
->cpu_model
->PABITS
) - 1);
16035 env
->CP0_SRSConf0_rw_bitmask
= env
->cpu_model
->CP0_SRSConf0_rw_bitmask
;
16036 env
->CP0_SRSConf0
= env
->cpu_model
->CP0_SRSConf0
;
16037 env
->CP0_SRSConf1_rw_bitmask
= env
->cpu_model
->CP0_SRSConf1_rw_bitmask
;
16038 env
->CP0_SRSConf1
= env
->cpu_model
->CP0_SRSConf1
;
16039 env
->CP0_SRSConf2_rw_bitmask
= env
->cpu_model
->CP0_SRSConf2_rw_bitmask
;
16040 env
->CP0_SRSConf2
= env
->cpu_model
->CP0_SRSConf2
;
16041 env
->CP0_SRSConf3_rw_bitmask
= env
->cpu_model
->CP0_SRSConf3_rw_bitmask
;
16042 env
->CP0_SRSConf3
= env
->cpu_model
->CP0_SRSConf3
;
16043 env
->CP0_SRSConf4_rw_bitmask
= env
->cpu_model
->CP0_SRSConf4_rw_bitmask
;
16044 env
->CP0_SRSConf4
= env
->cpu_model
->CP0_SRSConf4
;
16045 env
->active_fpu
.fcr0
= env
->cpu_model
->CP1_fcr0
;
16046 env
->insn_flags
= env
->cpu_model
->insn_flags
;
16048 #if defined(CONFIG_USER_ONLY)
16049 env
->CP0_Status
= (MIPS_HFLAG_UM
<< CP0St_KSU
);
16050 # ifdef TARGET_MIPS64
16051 /* Enable 64-bit register mode. */
16052 env
->CP0_Status
|= (1 << CP0St_PX
);
16054 # ifdef TARGET_ABI_MIPSN64
16055 /* Enable 64-bit address mode. */
16056 env
->CP0_Status
|= (1 << CP0St_UX
);
16058 /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
16059 hardware registers. */
16060 env
->CP0_HWREna
|= 0x0000000F;
16061 if (env
->CP0_Config1
& (1 << CP0C1_FP
)) {
16062 env
->CP0_Status
|= (1 << CP0St_CU1
);
16064 if (env
->CP0_Config3
& (1 << CP0C3_DSPP
)) {
16065 env
->CP0_Status
|= (1 << CP0St_MX
);
16067 # if defined(TARGET_MIPS64)
16068 /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
16069 if ((env
->CP0_Config1
& (1 << CP0C1_FP
)) &&
16070 (env
->CP0_Status_rw_bitmask
& (1 << CP0St_FR
))) {
16071 env
->CP0_Status
|= (1 << CP0St_FR
);
16075 if (env
->hflags
& MIPS_HFLAG_BMASK
) {
16076 /* If the exception was raised from a delay slot,
16077 come back to the jump. */
16078 env
->CP0_ErrorEPC
= env
->active_tc
.PC
- 4;
16080 env
->CP0_ErrorEPC
= env
->active_tc
.PC
;
16082 env
->active_tc
.PC
= (int32_t)0xBFC00000;
16083 env
->CP0_Random
= env
->tlb
->nb_tlb
- 1;
16084 env
->tlb
->tlb_in_use
= env
->tlb
->nb_tlb
;
16085 env
->CP0_Wired
= 0;
16086 env
->CP0_EBase
= (cs
->cpu_index
& 0x3FF);
16087 if (kvm_enabled()) {
16088 env
->CP0_EBase
|= 0x40000000;
16090 env
->CP0_EBase
|= 0x80000000;
16092 env
->CP0_Status
= (1 << CP0St_BEV
) | (1 << CP0St_ERL
);
16093 /* vectored interrupts not implemented, timer on int 7,
16094 no performance counters. */
16095 env
->CP0_IntCtl
= 0xe0000000;
16099 for (i
= 0; i
< 7; i
++) {
16100 env
->CP0_WatchLo
[i
] = 0;
16101 env
->CP0_WatchHi
[i
] = 0x80000000;
16103 env
->CP0_WatchLo
[7] = 0;
16104 env
->CP0_WatchHi
[7] = 0;
16106 /* Count register increments in debug mode, EJTAG version 1 */
16107 env
->CP0_Debug
= (1 << CP0DB_CNT
) | (0x1 << CP0DB_VER
);
16109 cpu_mips_store_count(env
, 1);
16111 if (env
->CP0_Config3
& (1 << CP0C3_MT
)) {
16114 /* Only TC0 on VPE 0 starts as active. */
16115 for (i
= 0; i
< ARRAY_SIZE(env
->tcs
); i
++) {
16116 env
->tcs
[i
].CP0_TCBind
= cs
->cpu_index
<< CP0TCBd_CurVPE
;
16117 env
->tcs
[i
].CP0_TCHalt
= 1;
16119 env
->active_tc
.CP0_TCHalt
= 1;
16122 if (cs
->cpu_index
== 0) {
16123 /* VPE0 starts up enabled. */
16124 env
->mvp
->CP0_MVPControl
|= (1 << CP0MVPCo_EVP
);
16125 env
->CP0_VPEConf0
|= (1 << CP0VPEC0_MVP
) | (1 << CP0VPEC0_VPA
);
16127 /* TC0 starts up unhalted. */
16129 env
->active_tc
.CP0_TCHalt
= 0;
16130 env
->tcs
[0].CP0_TCHalt
= 0;
16131 /* With thread 0 active. */
16132 env
->active_tc
.CP0_TCStatus
= (1 << CP0TCSt_A
);
16133 env
->tcs
[0].CP0_TCStatus
= (1 << CP0TCSt_A
);
16137 compute_hflags(env
);
16138 cs
->exception_index
= EXCP_NONE
;
16141 void restore_state_to_opc(CPUMIPSState
*env
, TranslationBlock
*tb
, int pc_pos
)
16143 env
->active_tc
.PC
= tcg_ctx
.gen_opc_pc
[pc_pos
];
16144 env
->hflags
&= ~MIPS_HFLAG_BMASK
;
16145 env
->hflags
|= gen_opc_hflags
[pc_pos
];
16146 switch (env
->hflags
& MIPS_HFLAG_BMASK_BASE
) {
16147 case MIPS_HFLAG_BR
:
16149 case MIPS_HFLAG_BC
:
16150 case MIPS_HFLAG_BL
:
16152 env
->btarget
= gen_opc_btarget
[pc_pos
];